summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephan Richter <stephan.richter@gmail.com>2013-03-11 11:33:16 -0400
committerStephan Richter <stephan.richter@gmail.com>2013-03-11 11:33:16 -0400
commit928658355be5bec8fa7a722b132a672e9ac6afaa (patch)
tree51ee357dbe37f36cf814bd90de553c1a18ffef28 /src
parent82fd54dca53bbd7b8700f5a240bde13bf3c41984 (diff)
downloadzope-security-928658355be5bec8fa7a722b132a672e9ac6afaa.tar.gz
- Make sure that __str__ and __repr__ never fail by catching all exceptions
and using the custom fallback. (This is equivalent to the C Proxy behavior.) - Allow __getslice__ and __setslice__ to access the original object's implementation instead of always falling back to __getitem__ and __setitem__. Do we really want to support this or just remove the test? (It is deprecated this Python 2.0!) - Make sure that Checker.set_permissions is set initiated as an empty dict, if not provided. While not immediately obvious, this is the C-based checker behavior as well. Oh yeah, all tests pass now on py26, py27, py32, py33, and pypy!
Diffstat (limited to 'src')
-rw-r--r--src/zope/security/_compat.py2
-rw-r--r--src/zope/security/checker.py2
-rw-r--r--src/zope/security/protectclass.py1
-rw-r--r--src/zope/security/proxy.py28
-rw-r--r--src/zope/security/tests/test_proxy.py4
5 files changed, 22 insertions, 15 deletions
diff --git a/src/zope/security/_compat.py b/src/zope/security/_compat.py
index 6de4758..f3e441f 100644
--- a/src/zope/security/_compat.py
+++ b/src/zope/security/_compat.py
@@ -14,11 +14,13 @@
""" Python 2 / 3 compatibility
"""
import platform
+import os
import sys
import types
py_impl = getattr(platform, 'python_implementation', lambda: None)
PYPY = py_impl() == 'PyPy'
+PURE_PYTHON = os.environ.get('PURE_PYTHON', False)
if sys.version_info[0] < 3: #pragma NO COVER
diff --git a/src/zope/security/checker.py b/src/zope/security/checker.py
index 061cc44..89ae214 100644
--- a/src/zope/security/checker.py
+++ b/src/zope/security/checker.py
@@ -177,6 +177,8 @@ class CheckerPy(object):
if set_permissions is not None:
if not isinstance(set_permissions, dict):
raise TypeError('set_permissions must be a dict')
+ else:
+ set_permissions = {}
self.set_permissions = set_permissions
def permission_id(self, name):
diff --git a/src/zope/security/protectclass.py b/src/zope/security/protectclass.py
index 57effb3..7e91f22 100644
--- a/src/zope/security/protectclass.py
+++ b/src/zope/security/protectclass.py
@@ -38,7 +38,6 @@ def protectName(class_, name, permission):
def protectSetAttribute(class_, name, permission):
"""Set a permission on a particular name."""
-
checker = getCheckerForInstancesOf(class_)
if checker is None:
checker = Checker({}, {})
diff --git a/src/zope/security/proxy.py b/src/zope/security/proxy.py
index 974b923..7f7d626 100644
--- a/src/zope/security/proxy.py
+++ b/src/zope/security/proxy.py
@@ -114,13 +114,19 @@ class ProxyPy(PyProxyBase):
@_check_name
def __getslice__(self, start, end):
- getitem = PyProxyBase.__getattribute__(self, '__getitem__')
- return getitem(slice(start, end))
+ try:
+ return self._wrapped.__getslice__(start, end)
+ except:
+ getitem = PyProxyBase.__getattribute__(self, '__getitem__')
+ return getitem(slice(start, end))
@_check_name
def __setslice__(self, i, j, value):
- setitem = PyProxyBase.__getattribute__(self, '__setitem__')
- return setitem(slice(i, j), value)
+ try:
+ return self._wrapped.__setslice__(i, j, value)
+ except:
+ setitem = PyProxyBase.__getattribute__(self, '__setitem__')
+ return setitem(slice(i, j), value)
def __cmp__(self, other):
# no check
@@ -172,17 +178,14 @@ class ProxyPy(PyProxyBase):
# For some reason _check_name does not work for coerce()
wrapped = super(PyProxyBase, self).__getattribute__('_wrapped')
checker = super(PyProxyBase, self).__getattribute__('_checker')
- checker.check_getattr(wrapped, '__coerce__')
- # Re-implement __coerce__(), so we do not depend on self._wrapped
- left, right = coerce(wrapped, other)
- if left == wrapped and type(left) is type(wrapped):
- left = self
- return left, right
+ checker.check(wrapped, '__coerce__')
+ return super(ProxyPy, self).__coerce__(other)
def __str__(self):
try:
return _check_name(PyProxyBase.__str__)(self)
- except ForbiddenAttribute:
+ except:
+ # The C implementation catches all exceptions.
wrapped = super(PyProxyBase, self).__getattribute__('_wrapped')
return '<security proxied %s.%s instance at %s>' %(
wrapped.__class__.__module__, wrapped.__class__.__name__,
@@ -191,7 +194,8 @@ class ProxyPy(PyProxyBase):
def __repr__(self):
try:
return _check_name(PyProxyBase.__repr__)(self)
- except ForbiddenAttribute:
+ except:
+ # The C implementation catches all exceptions.
wrapped = super(PyProxyBase, self).__getattribute__('_wrapped')
return '<security proxied %s.%s instance at %s>' %(
wrapped.__class__.__module__, wrapped.__class__.__name__,
diff --git a/src/zope/security/tests/test_proxy.py b/src/zope/security/tests/test_proxy.py
index 974c26f..f73990d 100644
--- a/src/zope/security/tests/test_proxy.py
+++ b/src/zope/security/tests/test_proxy.py
@@ -16,7 +16,7 @@
import unittest
import sys
-from zope.security._compat import PYTHON2, PYPY
+from zope.security._compat import PYTHON2, PYPY, PURE_PYTHON
def _skip_if_not_Py2(testfunc):
from functools import update_wrapper
@@ -1946,6 +1946,6 @@ def test_suite():
unittest.makeSuite(ProxyTests),
unittest.makeSuite(LocationProxySecurityCheckerTests),
))
- if not PYPY:
+ if not (PYPY or PURE_PYTHON):
suite.addTest(unittest.makeSuite(ProxyCTests))
return suite