mirror of
https://github.com/magic-wormhole/magic-wormhole.git
synced 2024-08-18 02:24:35 +03:00
incorporate attrs code for zope-interface
This commit is contained in:
73
src/wormhole/test/test_util_attrs_zope.py
Normal file
73
src/wormhole/test/test_util_attrs_zope.py
Normal 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)
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user