incorporate attrs code for zope-interface

This commit is contained in:
meejah
2024-05-29 16:42:49 -06:00
parent 0d246cf9c8
commit 947bb85fa4
2 changed files with 113 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
import zope.interface
from twisted.trial import unittest
from attr import Attribute
from attr._make import NOTHING
from wormhole.util import provides
class IFoo(zope.interface.Interface):
"""
An interface.
"""
def f():
"""
A function called f.
"""
def simple_attr(name):
return Attribute(
name=name,
default=NOTHING,
validator=None,
repr=True,
cmp=None,
eq=True,
hash=None,
init=True,
converter=None,
kw_only=False,
inherited=False,
)
class TestProvides(unittest.TestCase):
"""
Tests for `provides`.
"""
def test_success(self):
"""
Nothing happens if value provides requested interface.
"""
@zope.interface.implementer(IFoo)
class C(object):
def f(self):
pass
v = provides(IFoo)
v(None, simple_attr("x"), C())
def test_fail(self):
"""
Raises `TypeError` if interfaces isn't provided by value.
"""
value = object()
a = simple_attr("x")
v = provides(IFoo)
with self.assertRaises(TypeError):
v(None, a, value)
def test_repr(self):
"""
Returned validator has a useful `__repr__`.
"""
v = provides(IFoo)
assert (
"<provides validator for interface {interface!r}>".format(
interface=IFoo
)
) == repr(v)

View File

@@ -5,6 +5,7 @@ import unicodedata
from binascii import hexlify, unhexlify
from cryptography.hazmat.primitives.kdf import hkdf
from cryptography.hazmat.primitives import hashes
from attr import attrs, attrib
def HKDF(skm, outlen, salt=None, CTXinfo=b""):
@@ -77,3 +78,42 @@ def estimate_free_space(target):
return s.f_frsize * s.f_bfree
except AttributeError:
return None
@attrs(repr=False, slots=True, hash=True)
class _ProvidesValidator:
interface = attrib()
def __call__(self, inst, attr, value):
"""
We use a callable class to be able to change the ``__repr__``.
"""
if not self.interface.providedBy(value):
msg = "'{name}' must provide {interface!r} which {value!r} doesn't.".format(
name=attr.name, interface=self.interface, value=value
)
raise TypeError(
msg,
attr,
self.interface,
value,
)
def __repr__(self):
return f"<provides validator for interface {self.interface!r}>"
def provides(interface):
"""
A validator that raises a `TypeError` if the initializer is called
with an object that does not provide the requested *interface* (checks are
performed using ``interface.providedBy(value)``.
:param interface: The interface to check for.
:type interface: ``zope.interface.Interface``
:raises TypeError: With a human readable error message, the attribute
(of type `attrs.Attribute`), the expected interface, and the
value it got.
"""
return _ProvidesValidator(interface)