summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Madden <jamadden@gmail.com>2017-09-12 08:49:43 -0500
committerJason Madden <jamadden@gmail.com>2017-09-12 08:49:43 -0500
commit673974bf6c0c13a737d53bac40fd1037fa5a0392 (patch)
tree51a67969ed3db5a822b11497db59ad6e855dc063 /src
parent12ce0b541c080b286673f314df517ee0fd135257 (diff)
downloadzope-security-673974bf6c0c13a737d53bac40fd1037fa5a0392.tar.gz
Coverage for get/setslice, length_hint, and comparison methods in proxy.py
Diffstat (limited to 'src')
-rw-r--r--src/zope/security/proxy.py46
-rw-r--r--src/zope/security/tests/test_proxy.py110
2 files changed, 134 insertions, 22 deletions
diff --git a/src/zope/security/proxy.py b/src/zope/security/proxy.py
index 9e7333d..3416419 100644
--- a/src/zope/security/proxy.py
+++ b/src/zope/security/proxy.py
@@ -17,7 +17,8 @@ import functools
import sys
from zope.proxy import PyProxyBase
-from zope.security._compat import PYPY, PURE_PYTHON
+from zope.security._compat import PURE_PYTHON
+from zope.security._compat import _BUILTINS
from zope.security.interfaces import ForbiddenAttribute
def _check_name(meth, wrap_result=True):
@@ -139,19 +140,21 @@ class ProxyPy(PyProxyBase):
@_check_name
def __getslice__(self, start, end):
+ wrapped = object.__getattribute__(self, '_wrapped')
try:
- return self._wrapped.__getslice__(start, end)
- except:
- getitem = PyProxyBase.__getattribute__(self, '__getitem__')
- return getitem(slice(start, end))
+ getslice = wrapped.__getslice__
+ except AttributeError:
+ return wrapped.__getitem__(slice(start, end))
+ return getslice(start, end)
@_check_name
- def __setslice__(self, i, j, value):
+ def __setslice__(self, start, end, value):
+ wrapped = object.__getattribute__(self, '_wrapped')
try:
- return self._wrapped.__setslice__(i, j, value)
- except:
- setitem = PyProxyBase.__getattribute__(self, '__setitem__')
- return setitem(slice(i, j), value)
+ setslice = wrapped.__setslice__
+ except AttributeError:
+ return wrapped.__setitem__(slice(start, end), value)
+ return setslice(start, end, value)
def __cmp__(self, other):
# no check
@@ -311,8 +314,9 @@ for name in ['__call__',
meth = getattr(PyProxyBase, name)
setattr(ProxyPy, name, _check_name(meth))
-for name in ['__len__',
- ]:
+for name in (
+ '__len__',
+):
meth = getattr(PyProxyBase, name)
setattr(ProxyPy, name, _check_name(meth, False))
@@ -336,16 +340,15 @@ for name in ['__iadd__',
def getCheckerPy(proxy):
return super(PyProxyBase, proxy).__getattribute__('_checker')
-if PYPY:
- _builtin_isinstance = __builtins__.isinstance
-else:
- _builtin_isinstance = __builtins__['isinstance']
+
+_builtin_isinstance = sys.modules[_BUILTINS].isinstance
def getObjectPy(proxy):
if not _builtin_isinstance(proxy, ProxyPy):
return proxy
return super(PyProxyBase, proxy).__getattribute__('_wrapped')
+
_c_available = not PURE_PYTHON
if _c_available:
try:
@@ -353,11 +356,12 @@ if _c_available:
except (ImportError, AttributeError): #pragma NO COVER PyPy / PURE_PYTHON
_c_available = False
-if not _c_available:
- getChecker = getCheckerPy
- getObject = getObjectPy
- Proxy = ProxyPy
-else: #pragma NO COVER CPython
+
+getChecker = getCheckerPy
+getObject = getObjectPy
+Proxy = ProxyPy
+
+if _c_available:
from zope.security._proxy import getChecker
from zope.security._proxy import getObject
Proxy = _Proxy
diff --git a/src/zope/security/tests/test_proxy.py b/src/zope/security/tests/test_proxy.py
index ee9200f..077023f 100644
--- a/src/zope/security/tests/test_proxy.py
+++ b/src/zope/security/tests/test_proxy.py
@@ -38,6 +38,8 @@ class AbstractProxyTestBase(object):
idiv = itruediv
div = '__truediv__' if not PYTHON2 else '__div__'
truediv = div
+ getslice = '__getitem__' if not PYTHON2 else '__getslice__'
+ setslice = '__setitem__' if not PYTHON2 else '__setslice__'
def _getTargetClass(self):
raise NotImplementedError("Subclass responsibility")
@@ -278,6 +280,24 @@ class AbstractProxyTestBase(object):
o_proxy = self._makeOne(target, checker)
self.assertEqual(cmp(proxy, o_proxy), 0)
+ def test__le__(self):
+ target = 1
+ checker = object() # checker not consulted
+ proxy = self._makeOne(target, checker)
+ self.assertTrue(proxy <= 1)
+
+ def test__ne__(self):
+ target = 1
+ checker = object() # checker not consulted
+ proxy = self._makeOne(target, checker)
+ self.assertFalse(proxy != 1)
+
+ def test__ge__(self):
+ target = 1
+ checker = object() # checker not consulted
+ proxy = self._makeOne(target, checker)
+ self.assertTrue(proxy >= 1)
+
def test___hash___w_self(self):
target = object()
checker = object() # checker not consulted
@@ -1169,6 +1189,20 @@ class AbstractProxyTestBase(object):
self.assertRaises(ForbiddenAttribute, len, proxy)
self.assertEqual(checker._checked, '__len__')
+ def test__length_hint_w_checker_allows(self):
+ target = iter([0, 1, 2])
+ checker = DummyChecker()
+ proxy = self._makeOne(target, checker)
+ hint = object.__getattribute__(proxy, '__length_hint__')
+ self.assertEqual(3, hint())
+
+ def test__length_hint_dne(self):
+ target = object()
+ checker = DummyChecker()
+ proxy = self._makeOne(target, checker)
+ hint = object.__getattribute__(proxy, '__length_hint__')
+ self.assertEqual(NotImplemented, hint())
+
def test___contains___hit_w_checker_allows(self):
target = [0, 1, 2]
checker = DummyChecker()
@@ -1246,7 +1280,46 @@ class AbstractProxyTestBase(object):
checker = DummyChecker()
proxy = self._makeOne(target, checker)
self.assertEqual(proxy[1:3], [1, 2])
- self.assertEqual(checker._checked, '__getslice__')
+ self.assertEqual(checker._checked, self.getslice)
+
+ @_skip_if_not_Py2
+ def test___getslice___error_propagates(self):
+ # This is currently broken on Python 3 because
+ # https://github.com/zopefoundation/zope.proxy/issues/21
+ class Missing(Exception):
+ pass
+ class Get(object):
+ def __getitem__(self, x):
+ raise Missing('__getitem__')
+ def __getslice__(self, start, stop):
+ raise Missing("__getslice__")
+ target = Get()
+ checker = DummyChecker()
+ proxy = self._makeOne(target, checker)
+ with self.assertRaisesRegexp(Missing,
+ self.getslice):
+ proxy[1:2]
+
+ self.assertEqual(checker._checked, self.getslice)
+
+ @_skip_if_not_Py2
+ def test___getslice___dne_uses_getitem(self):
+ # This is currently broken on Python 3 because
+ # https://github.com/zopefoundation/zope.proxy/issues/21
+ class Missing(Exception):
+ pass
+ class Get(object):
+ def __getitem__(self, x):
+ raise Missing('__getitem__')
+
+ target = Get()
+ checker = DummyChecker()
+ proxy = self._makeOne(target, checker)
+ with self.assertRaisesRegexp(Missing,
+ '__getitem__'):
+ proxy[1:2]
+
+ self.assertEqual(checker._checked, self.getslice)
@_skip_if_not_Py2
def test___getslice___w_checker_forbids(self):
@@ -1277,6 +1350,41 @@ class AbstractProxyTestBase(object):
self.assertRaises(ForbiddenAttribute, _try)
self.assertEqual(checker._checked, '__setslice__')
+ def test___setslice___error_propagates(self):
+ class Missing(Exception):
+ pass
+ class Set(object):
+ def __setitem__(self, k, v):
+ raise Missing('__setitem__')
+ def __setslice__(self, start, stop, value):
+ raise Missing("__setslice__")
+ target = Set()
+ checker = DummyChecker()
+ proxy = self._makeOne(target, checker)
+ with self.assertRaisesRegexp(Missing,
+ self.setslice):
+ proxy[1:2] = 1
+
+ self.assertEqual(checker._checked, self.setslice)
+
+ def test___setslice___dne_uses_getitem(self):
+ # This is currently broken on Python 3 because
+ # https://github.com/zopefoundation/zope.proxy/issues/21
+ class Missing(Exception):
+ pass
+ class Set(object):
+ def __setitem__(self, k, v):
+ raise Missing('__setitem__')
+
+ target = Set()
+ checker = DummyChecker()
+ proxy = self._makeOne(target, checker)
+ with self.assertRaisesRegexp(Missing,
+ '__setitem__'):
+ proxy[1:2] = 1
+
+ self.assertEqual(checker._checked, self.setslice)
+
def test___getitem___mapping_hit_w_checker_allows(self):
target = {'a': 0, 'b': 1, 'c': 2}
checker = DummyChecker()