summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Lebedev <andrey@lebedev.lt>2013-02-19 19:07:25 +0200
committerAndrey Lebedev <andrey@lebedev.lt>2013-02-19 19:07:25 +0200
commit67e4c91acc5d16e1408696189d31771be73d311e (patch)
treeb26882d8e014a081d5f3e6a74791a54187b244d1
parente1d5f7cf375ccdfb8f6207c2bf813ca64c1d7bda (diff)
parentaad857434f77e494a9c1ea1ba90f95bb1cc60551 (diff)
downloadzope-security-67e4c91acc5d16e1408696189d31771be73d311e.tar.gz
Merge branch 'moretests'
-rw-r--r--docs/api/checker.rst113
-rw-r--r--docs/api/decorator.rst25
-rw-r--r--docs/api/permission.rst10
-rw-r--r--docs/api/zcml.rst14
-rw-r--r--setup.py17
-rw-r--r--src/zope/security/checker.py8
-rw-r--r--src/zope/security/testing.py19
-rw-r--r--tox.ini3
8 files changed, 99 insertions, 110 deletions
diff --git a/docs/api/checker.rst b/docs/api/checker.rst
index 8b321db..58d3595 100644
--- a/docs/api/checker.rst
+++ b/docs/api/checker.rst
@@ -82,8 +82,7 @@ directly, or via interface:
>>> context = AContext()
>>> allow(context, attributes=['foo', 'bar'], interface=[I1, I2])
- >>> context.actions.sort(
- ... lambda a, b: cmp(a['discriminator'], b['discriminator']))
+ >>> context.actions.sort(key=lambda a: a['discriminator'])
>>> pprint(context.actions)
[{'args': ('testmodule', 'a', 'zope.Public'),
'callable': 1,
@@ -136,8 +135,7 @@ directly, or via interface:
>>> require(context, attributes=['foo', 'bar'],
... interface=[I1, I2], permission='p')
- >>> context.actions.sort(
- ... lambda a, b: cmp(a['discriminator'], b['discriminator']))
+ >>> context.actions.sort(key=lambda a: a['discriminator'])
>>> pprint(context.actions)
[{'args': ('testmodule', 'a', 'p'),
'callable': 1,
@@ -182,26 +180,26 @@ Protections for standard objects
... from zope.security.interfaces import ForbiddenAttribute
... try:
... return getattr(object, attr)
- ... except ForbiddenAttribute, e:
- ... return 'ForbiddenAttribute: %s' % e[0]
+ ... except ForbiddenAttribute as e:
+ ... return 'ForbiddenAttribute: %s' % e.args[0]
>>> def check_forbidden_setitem(object, item, value):
... from zope.security.interfaces import ForbiddenAttribute
... try:
... object[item] = value
- ... except ForbiddenAttribute, e:
- ... return 'ForbiddenAttribute: %s' % e[0]
+ ... except ForbiddenAttribute as e:
+ ... return 'ForbiddenAttribute: %s' % e.args[0]
>>> def check_forbidden_delitem(object, item):
... from zope.security.interfaces import ForbiddenAttribute
... try:
... del object[item]
- ... except ForbiddenAttribute, e:
- ... return 'ForbiddenAttribute: %s' % e[0]
+ ... except ForbiddenAttribute as e:
+ ... return 'ForbiddenAttribute: %s' % e.args[0]
>>> def check_forbidden_call(callable, *args): # **
... from zope.security.interfaces import ForbiddenAttribute
... try:
... return callable(*args) # **
- ... except ForbiddenAttribute, e:
- ... return 'ForbiddenAttribute: %s' % e[0]
+ ... except ForbiddenAttribute as e:
+ ... return 'ForbiddenAttribute: %s' % e.args[0]
Rocks
#####
@@ -217,16 +215,12 @@ Rocks are immuatle, non-callable objects without interesting methods. They
1
>>> int(type(ProxyFactory( 1.0 )) is float)
1
- >>> int(type(ProxyFactory( 1l )) is long)
- 1
>>> int(type(ProxyFactory( 1j )) is complex)
1
>>> int(type(ProxyFactory( None )) is type(None))
1
>>> int(type(ProxyFactory( 'xxx' )) is str)
1
- >>> int(type(ProxyFactory( u'xxx' )) is unicode)
- 1
>>> int(type(ProxyFactory( True )) is type(True))
1
@@ -270,18 +264,18 @@ We can do everything we expect to be able to do with proxied dicts.
1
>>> len(d)
2
- >>> list(d)
+ >>> sorted(list(d))
['a', 'b']
>>> d.get('a')
1
- >>> int(d.has_key('a'))
+ >>> int('a' in d)
1
>>> c = d.copy()
>>> check_forbidden_get(c, 'clear')
'ForbiddenAttribute: clear'
>>> int(str(c) in ("{'a': 1, 'b': 2}", "{'b': 2, 'a': 1}"))
1
- >>> int(`c` in ("{'a': 1, 'b': 2}", "{'b': 2, 'a': 1}"))
+ >>> int(repr(c) in ("{'a': 1, 'b': 2}", "{'b': 2, 'a': 1}"))
1
>>> def sorted(x):
... x = list(x)
@@ -293,27 +287,12 @@ We can do everything we expect to be able to do with proxied dicts.
[1, 2]
>>> sorted(d.items())
[('a', 1), ('b', 2)]
- >>> sorted(d.iterkeys())
- ['a', 'b']
- >>> sorted(d.itervalues())
- [1, 2]
- >>> sorted(d.iteritems())
- [('a', 1), ('b', 2)]
-Always available:
+Always available (note, that dicts in python-3.x are not orderable, so we are
+not checking that under python > 2):
.. doctest::
- >>> int(d < d)
- 0
- >>> int(d > d)
- 0
- >>> int(d <= d)
- 1
- >>> int(d >= d)
- 1
- >>> int(d == d)
- 1
>>> int(d != d)
0
>>> int(bool(d))
@@ -351,7 +330,7 @@ We can do everything we expect to be able to do with proxied lists.
1
>>> str(l)
'[1, 2]'
- >>> `l`
+ >>> repr(l)
'[1, 2]'
>>> l + l
[1, 2, 1, 2]
@@ -398,7 +377,7 @@ We can do everything we expect to be able to do with proxied tuples.
1
>>> str(l)
'(1, 2)'
- >>> `l`
+ >>> repr(l)
'(1, 2)'
>>> l + l
(1, 2, 1, 2)
@@ -607,8 +586,8 @@ we can do everything we expect to be able to do with proxied frozensets.
... from zope.security.interfaces import ForbiddenAttribute
... try:
... return getattr(object, attr)
- ... except ForbiddenAttribute, e:
- ... return 'ForbiddenAttribute: %s' % e[0]
+ ... except ForbiddenAttribute as e:
+ ... return 'ForbiddenAttribute: %s' % e.args[0]
>>> from zope.security.checker import ProxyFactory
>>> from zope.security.interfaces import ForbiddenAttribute
>>> us = frozenset((1, 2))
@@ -779,6 +758,8 @@ iterators
.. doctest::
+ >>> [a for a in ProxyFactory(iter([1, 2]))]
+ [1, 2]
>>> list(ProxyFactory(iter([1, 2])))
[1, 2]
>>> list(ProxyFactory(iter((1, 2))))
@@ -815,7 +796,7 @@ We can iterate over sequences
>>> from zope.security.checker import NamesChecker
>>> from zope.security.checker import ProxyFactory
- >>> c = NamesChecker(['__getitem__'])
+ >>> c = NamesChecker(['__getitem__', '__len__'])
>>> p = ProxyFactory(x, c)
Even if they are proxied
@@ -856,7 +837,7 @@ New-style classes
>>> check_forbidden_get(C, '__dict__')
'ForbiddenAttribute: __dict__'
>>> s = str(C)
- >>> s = `C`
+ >>> s = repr(C)
>>> int(C.__module__ == __name__)
1
>>> len(C.__bases__)
@@ -868,14 +849,6 @@ Always available:
.. doctest::
- >>> int(C < C)
- 0
- >>> int(C > C)
- 0
- >>> int(C <= C)
- 1
- >>> int(C >= C)
- 1
>>> int(C == C)
1
>>> int(C != C)
@@ -907,14 +880,6 @@ Always available:
.. doctest::
- >>> int(c < c)
- 0
- >>> int(c > c)
- 0
- >>> int(c <= c)
- 1
- >>> int(c >= c)
- 1
>>> int(c == c)
1
>>> int(c != c)
@@ -938,24 +903,16 @@ Classic Classes
>>> check_forbidden_get(C, '__dict__')
'ForbiddenAttribute: __dict__'
>>> s = str(C)
- >>> s = `C`
+ >>> s = repr(C)
>>> int(C.__module__ == __name__)
1
>>> len(C.__bases__)
- 0
+ 1
Always available:
.. doctest::
- >>> int(C < C)
- 0
- >>> int(C > C)
- 0
- >>> int(C <= C)
- 1
- >>> int(C >= C)
- 1
>>> int(C == C)
1
>>> int(C != C)
@@ -984,14 +941,6 @@ Always available:
.. doctest::
- >>> int(c < c)
- 0
- >>> int(c > c)
- 0
- >>> int(c <= c)
- 1
- >>> int(c >= c)
- 1
>>> int(c == c)
1
>>> int(c != c)
@@ -1055,7 +1004,7 @@ We work with the ABCMeta meta class:
>>> check_forbidden_get(PBar, '__dict__')
'ForbiddenAttribute: __dict__'
>>> s = str(PBar)
- >>> s = `PBar`
+ >>> s = repr(PBar)
>>> int(PBar.__module__ == __name__)
1
>>> len(PBar.__bases__)
@@ -1065,19 +1014,11 @@ Always available:
.. doctest::
- >>> int(PBar < PBar)
- 0
- >>> int(PBar > PBar)
- 0
- >>> int(PBar <= PBar)
- 1
- >>> int(PBar >= PBar)
- 1
>>> int(PBar == PBar)
1
>>> int(PBar != PBar)
0
>>> int(bool(PBar))
1
- >>> int(PBar.__class__ == abc.ABCMeta)
+ >>> int(PBar.__class__ == type)
1
diff --git a/docs/api/decorator.rst b/docs/api/decorator.rst
index c4741b9..c05c692 100644
--- a/docs/api/decorator.rst
+++ b/docs/api/decorator.rst
@@ -48,13 +48,16 @@ Using `selectChecker()`, we can confirm that a `Foo` object uses
.. doctest::
>>> from zope.security.checker import selectChecker
+ >>> from zope.security.interfaces import ForbiddenAttribute
>>> foo = Foo()
>>> selectChecker(foo) is fooChecker
True
>>> fooChecker.check(foo, 'a')
- >>> fooChecker.check(foo, 'b') # doctest: +ELLIPSIS
- Traceback (most recent call last):
- ForbiddenAttribute: ('b', <zope.security.decorator.Foo object ...>)
+ >>> try:
+ ... fooChecker.check(foo, 'b') # doctest: +ELLIPSIS
+ ... except ForbiddenAttribute as e:
+ ... e
+ ForbiddenAttribute('b', <Foo object ...>)
and that a `Wrapper` object uses `wrappeChecker`:
@@ -64,9 +67,11 @@ and that a `Wrapper` object uses `wrappeChecker`:
>>> selectChecker(wrapper) is wrapperChecker
True
>>> wrapperChecker.check(wrapper, 'b')
- >>> wrapperChecker.check(wrapper, 'a') # doctest: +ELLIPSIS
- Traceback (most recent call last):
- ForbiddenAttribute: ('a', <zope.security.decorator.Foo object ...>)
+ >>> try:
+ ... wrapperChecker.check(wrapper, 'a') # doctest: +ELLIPSIS
+ ... except ForbiddenAttribute as e:
+ ... e
+ ForbiddenAttribute('a', <Foo object ...>)
(Note that the object description says `Foo` because the object is a
proxy and generally looks and acts like the object it's proxying.)
@@ -94,9 +99,11 @@ illustrate, we'll proxify `foo`:
>>> secure_foo = ProxyFactory(foo)
>>> secure_foo.a
'a'
- >>> secure_foo.b # doctest: +ELLIPSIS
- Traceback (most recent call last):
- ForbiddenAttribute: ('b', <zope.security.decorator.Foo object ...>)
+ >>> try:
+ ... secure_foo.b # doctest: +ELLIPSIS
+ ... except ForbiddenAttribute as e:
+ ... e
+ ForbiddenAttribute('b', <Foo object ...>)
when we wrap the secured `foo`:
diff --git a/docs/api/permission.rst b/docs/api/permission.rst
index 64a4250..819cc90 100644
--- a/docs/api/permission.rst
+++ b/docs/api/permission.rst
@@ -48,7 +48,7 @@ The :data:`zope.security.checker.CheckerPublic` permission always exists:
>>> ids = list(allPermissions(None))
>>> ids.sort()
>>> ids
- [u'x', u'y']
+ ['x', 'y']
.. autofunction:: zope.security.permission.PermissionsVocabulary
@@ -100,9 +100,9 @@ The non-public permissions 'x' and 'y' are string values:
.. doctest::
>>> vocab.getTermByToken('x').value
- u'x'
+ 'x'
>>> vocab.getTermByToken('y').value
- u'y'
+ 'y'
However, the public permission value is CheckerPublic:
@@ -116,7 +116,7 @@ and its title is shortened:
.. doctest::
>>> vocab.getTermByToken('zope.Public').title
- u'Public'
+ 'Public'
The terms are sorted by title except for the public permission, which is
listed first:
@@ -124,7 +124,7 @@ listed first:
.. doctest::
>>> [term.title for term in vocab]
- [u'Public', u'x', u'y']
+ ['Public', 'x', 'y']
.. testcleanup::
diff --git a/docs/api/zcml.rst b/docs/api/zcml.rst
index 5fdc3a0..a23075a 100644
--- a/docs/api/zcml.rst
+++ b/docs/api/zcml.rst
@@ -11,8 +11,9 @@ a couple of permissions:
>>> from zope.component import getGlobalSiteManager
>>> from zope.configuration.xmlconfig import XMLConfig
+ >>> from zope.component.testing import setUp
>>> import zope.security
-
+ >>> setUp() # clear global component registry
>>> XMLConfig('permissions.zcml', zope.security)()
>>> len(list(getGlobalSiteManager().registeredUtilities()))
@@ -64,10 +65,13 @@ Now let's see whether validation works alright
>>> field._validate('zope.ManageCode')
>>> context._actions[0]['args']
(None, 'zope.foo')
- >>> field._validate('3 foo')
- Traceback (most recent call last):
- ...
- InvalidId: 3 foo
+
+ >>> from zope.schema.interfaces import InvalidId
+ >>> try:
+ ... field._validate('3 foo')
+ ... except InvalidId as e:
+ ... e
+ InvalidId('3 foo')
zope.Public is always valid
>>> field._validate('zope.Public')
diff --git a/setup.py b/setup.py
index 90d54da..91c43d4 100644
--- a/setup.py
+++ b/setup.py
@@ -32,6 +32,21 @@ TESTS_REQUIRE = [
'zope.location',
]
+def alltests():
+ import os
+ import sys
+ import unittest
+ # use the zope.testrunner machinery to find all the
+ # test suites we've put under ourselves
+ import zope.testrunner.find
+ import zope.testrunner.options
+ here = os.path.abspath(os.path.join(os.path.dirname(__file__), 'src'))
+ args = sys.argv[:]
+ defaults = ["--test-path", here]
+ options = zope.testrunner.options.get_options(args, defaults)
+ suites = list(zope.testrunner.find.find_suites(options))
+ return unittest.TestSuite(suites)
+
here = os.path.abspath(os.path.dirname(__file__))
def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
@@ -130,7 +145,7 @@ setup(name='zope.security',
'zope.proxy >= 4.1.0',
'zope.schema',
],
- test_suite = 'zope.security',
+ test_suite = '__main__.alltests',
tests_require=TESTS_REQUIRE,
extras_require = dict(
pytz=["pytz"],
diff --git a/src/zope/security/checker.py b/src/zope/security/checker.py
index e5f88dc..5f1d7df 100644
--- a/src/zope/security/checker.py
+++ b/src/zope/security/checker.py
@@ -595,7 +595,7 @@ _typeChecker = NamesChecker(
'__implemented__'])
_namedChecker = NamesChecker(['__name__'])
-_iteratorChecker = NamesChecker(['next', '__iter__'])
+_iteratorChecker = NamesChecker(['next', '__iter__', '__len__'])
_setChecker = NamesChecker(['__iter__', '__len__', '__str__', '__contains__',
'copy', 'difference', 'intersection', 'issubset',
@@ -642,9 +642,13 @@ _basic_types = {
datetime.time: NoProxy,
datetime.tzinfo: NoProxy,
}
-if PYTHON2:
+if PYTHON2:
_basic_types[long] = NoProxy
_basic_types[unicode] = NoProxy
+else: #pragma NO COVER
+ _basic_types[type({}.values())] = NoProxy
+ _basic_types[type({}.keys())] = NoProxy
+ _basic_types[type({}.items())] = NoProxy
try:
import pytz
diff --git a/src/zope/security/testing.py b/src/zope/security/testing.py
index 53d1ebe..ee13db8 100644
--- a/src/zope/security/testing.py
+++ b/src/zope/security/testing.py
@@ -15,13 +15,30 @@
This module provides some helper/stub objects for setting up interactions.
"""
+import sys
+import re
from zope import interface, component
from zope.security import interfaces
from zope.security.permission import Permission
import contextlib
import zope.security.management
-
+from zope.testing import renormalizing
+
+PY2 = sys.version_info[0] == 2
+
+if PY2:
+ _u = unicode
+ rules = [(re.compile("b('.*?')"), r"\1"),
+ (re.compile('b(".*?")'), r"\1"),
+ ]
+ output_checker = renormalizing.RENormalizing(rules)
+else:
+ _u = str
+ rules = [(re.compile("u('.*?')"), r"\1"),
+ (re.compile('u(".*?")'), r"\1"),
+ ]
+ output_checker = renormalizing.RENormalizing(rules)
@interface.implementer(interfaces.IPrincipal)
class Principal:
diff --git a/tox.ini b/tox.ini
index ea5bc87..ee015f0 100644
--- a/tox.ini
+++ b/tox.ini
@@ -13,6 +13,7 @@ deps =
zope.component
zope.location
zope.proxy
+ zope.testrunner
commands =
python setup.py test -q
@@ -40,7 +41,7 @@ deps =
[testenv:docs]
basepython =
- python2.6
+ python3.3
commands =
sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest