summaryrefslogtreecommitdiff
path: root/src/zope/security
diff options
context:
space:
mode:
Diffstat (limited to 'src/zope/security')
-rw-r--r--src/zope/security/checker.py35
-rw-r--r--src/zope/security/tests/test_checker.py52
2 files changed, 58 insertions, 29 deletions
diff --git a/src/zope/security/checker.py b/src/zope/security/checker.py
index 3187afc..344428c 100644
--- a/src/zope/security/checker.py
+++ b/src/zope/security/checker.py
@@ -770,6 +770,27 @@ if PYTHON2:
_default_checkers[type({}.iterkeys())] = _iteratorChecker
_default_checkers[type({}.itervalues())] = _iteratorChecker
+def _fixup_dictlike(dict_type):
+ empty_dict = dict_type()
+ populated_dict = dict_type({1: 2})
+ for dictlike in (empty_dict, populated_dict):
+ for attr in ('__iter__', 'keys', 'items', 'values'):
+ obj = getattr(dictlike, attr)()
+ o_type = type(obj)
+ if o_type not in _default_checkers:
+ _default_checkers[o_type] = _iteratorChecker
+
+def _fixup_odict():
+ # OrderedDicts have three different implementations: Python 2 (pure
+ # python, returns generators and lists), Python <=3.4 (pure Python,
+ # uses view classes) and CPython 3.5+ (implemented in C). These should
+ # all be iterable.
+ from collections import OrderedDict
+ _fixup_dictlike(OrderedDict)
+
+_fixup_odict()
+del _fixup_odict
+
try:
import BTrees
except ImportError: # pragma: no cover
@@ -794,20 +815,14 @@ else:
for name in ('IF', 'II', 'IO', 'OI', 'OO'):
for family_name in ('family32', 'family64'):
family = getattr(BTrees, family_name)
- btree = getattr(family, name).BTree()
-
- empty_type = type(btree.items())
- if empty_type not in _default_checkers:
- _default_checkers[empty_type] = _iteratorChecker
-
- btree[1] = 1
- populated_type = type(btree.items())
- if populated_type not in _default_checkers:
- _default_checkers[populated_type] = _iteratorChecker
+ btree = getattr(family, name).BTree
+ _fixup_dictlike(btree)
_fixup_btrees()
del _fixup_btrees
+del _fixup_dictlike
+
def _clear():
_checkers.clear()
_checkers.update(_default_checkers)
diff --git a/src/zope/security/tests/test_checker.py b/src/zope/security/tests/test_checker.py
index ceda502..03a8883 100644
--- a/src/zope/security/tests/test_checker.py
+++ b/src/zope/security/tests/test_checker.py
@@ -391,34 +391,48 @@ class CheckerTestsBase(object):
finally:
_clear()
- @_skip_if_no_btrees
- def test_iteration_of_btree_items(self):
- # iteration of BTree.items() is allowed by default.
+ def _check_iteration_of_dict_like(self, dict_like):
from zope.security.proxy import Proxy
from zope.security.checker import Checker
- from zope.security.checker import CheckerPublic
- import BTrees
+ from zope.security.checker import _default_checkers
+
+ checker = _default_checkers[dict]
+
+ proxy = Proxy(dict_like, checker)
+ # empty
+ self.assertEqual([], list(proxy.items()))
+ self.assertEqual([], list(proxy.keys()))
+ self.assertEqual([], list(proxy.values()))
+ self.assertEqual([], list(proxy))
- checker = Checker({'items': CheckerPublic,
- 'keys': CheckerPublic,
- 'values': CheckerPublic})
+ # With an object
+ dict_like[1] = 2
+ self.assertEqual([(1, 2)], list(proxy.items()))
+ self.assertEqual([1], list(proxy.keys()))
+ self.assertEqual([1], list(proxy))
+ self.assertEqual([2], list(proxy.values()))
+
+ @_skip_if_no_btrees
+ def test_iteration_of_btree_items_keys_values(self):
+ # iteration of BTree.items() is allowed by default.
+ import BTrees
for name in ('IF', 'II', 'IO', 'OI', 'OO'):
for family_name in ('family32', 'family64'):
family = getattr(BTrees, family_name)
btree = getattr(family, name).BTree()
- proxy = Proxy(btree, checker)
- # empty
- self.assertEqual([], list(proxy.items()))
- self.assertEqual([], list(proxy.keys()))
- self.assertEqual([], list(proxy.values()))
-
- # With an object
- btree[1] = 2
- self.assertEqual([(1, 2)], list(proxy.items()))
- self.assertEqual([1], list(proxy.keys()))
- self.assertEqual([2], list(proxy.values()))
+ self._check_iteration_of_dict_like(btree)
+
+ def test_iteration_of_odict_items_keys_values(self):
+ # iteration of OrderedDict.items() is allowed by default.
+ from collections import OrderedDict
+
+ odict = OrderedDict()
+ self._check_iteration_of_dict_like(odict)
+ def test_iteration_of_dict_items_keys_values(self):
+ # iteration of regular dict is allowed by default
+ self._check_iteration_of_dict_like(dict())
class CheckerPyTests(unittest.TestCase, CheckerTestsBase):