diff options
author | Jason Madden <jamadden@gmail.com> | 2020-02-06 06:09:29 -0600 |
---|---|---|
committer | Jason Madden <jamadden@gmail.com> | 2020-02-06 06:09:29 -0600 |
commit | fb5fa208565a462470f7884c6d9cf73adad886c5 (patch) | |
tree | 0aafb30c4d99d06475d6ecbf62205704084f8e1a /src/zope | |
parent | 944e79ae6ec5214323372e518b8198d9540ed992 (diff) | |
download | zope-security-fb5fa208565a462470f7884c6d9cf73adad886c5.tar.gz |
Let interfaces be iterated on Python 3
Fixes https://github.com/zopefoundation/zope.interface/issues/141
Diffstat (limited to 'src/zope')
-rw-r--r-- | src/zope/security/checker.py | 10 | ||||
-rw-r--r-- | src/zope/security/tests/test_proxy.py | 27 |
2 files changed, 32 insertions, 5 deletions
diff --git a/src/zope/security/checker.py b/src/zope/security/checker.py index f5541a7..8fbf3ec 100644 --- a/src/zope/security/checker.py +++ b/src/zope/security/checker.py @@ -858,8 +858,14 @@ _default_checkers = { type(f()): _iteratorChecker, type(Interface): InterfaceChecker( IInterface, - __str__=CheckerPublic, _implied=CheckerPublic, subscribe=CheckerPublic, - ), + __str__=CheckerPublic, + _implied=CheckerPublic, + subscribe=CheckerPublic, + # To iterate, Python calls __len__ as a hint. + # Python 2 ignores AttributeErrors, but Python 3 + # lets them pass. + __len__=CheckerPublic, + ), zope.interface.interface.Method: InterfaceChecker( zope.interface.interfaces.IMethod), zope.interface.declarations.ProvidesClass: _Declaration_checker, diff --git a/src/zope/security/tests/test_proxy.py b/src/zope/security/tests/test_proxy.py index 55d6d43..cecac86 100644 --- a/src/zope/security/tests/test_proxy.py +++ b/src/zope/security/tests/test_proxy.py @@ -27,6 +27,7 @@ if not PYTHON2: # pragma: no cover (Python 3) raise NotImplementedError("Not on Python 3") cmp = coerce long = int + unicode = str class AbstractProxyTestBase(object): @@ -1770,7 +1771,7 @@ class Something: return x == 42 -class ProxyTests(unittest.TestCase): +class ProxyFactoryTests(unittest.TestCase): def setUp(self): from zope.security.proxy import ProxyFactory @@ -1958,6 +1959,11 @@ class ProxyTests(unittest.TestCase): if PYTHON2: unops.append("long(x)") + def _make_eval(self, expr, locs): + def _eval(*args): + eval(expr, globals(), locs) + return _eval + def test_unops(self): # We want the starting value of the expressions to be a proxy, # but we don't want to create new proxies as a result of @@ -1968,6 +1974,7 @@ class ProxyTests(unittest.TestCase): self.c.unproxied_types = {str, int, float} if PYTHON2: self.c.unproxied_types.add(long) + for expr in self.unops: x = 1 y = eval(expr) @@ -1976,7 +1983,7 @@ class ProxyTests(unittest.TestCase): z = eval(expr) self.assertEqual(removeSecurityProxy(z), y, "x=%r; expr=%r" % (x, expr)) - self.shouldFail(lambda x: eval(expr), x) + self.shouldFail(self._make_eval(expr, locals()), x) @_skip_if_not_Py2 def test_odd_unops(self): @@ -2007,7 +2014,7 @@ class ProxyTests(unittest.TestCase): else: self.assertEqual(removeSecurityProxy(eval(expr)), z, "x=%r; y=%r; expr=%r" % (x, y, expr)) - self.shouldFail(lambda x, y: eval(expr), x, y) + self.shouldFail(self._make_eval(expr, locals()), x, y) def test_inplace(self): # TODO: should test all inplace operators... @@ -2101,6 +2108,20 @@ class ProxyTests(unittest.TestCase): self.assertIs(type(removeSecurityProxy(a)), float) self.assertIs(b, y) + def test_iterate_interface(self): + # This used to work on Python 2, but fail on Python 3. + # See https://github.com/zopefoundation/zope.interface/issues/141 + from zope.interface import Interface + from zope.security.proxy import ProxyFactory + + class IFoo(Interface): + def x(): + """A method""" + + proxy = ProxyFactory(IFoo) + self.assertEqual(list(IFoo), ['x']) + self.assertEqual(list(proxy), list(IFoo)) + def test_using_mapping_slots_hack(): """The security proxy will use mapping slots, on the checker to go faster |