Ausgabe der neuen DB Einträge
This commit is contained in:
parent
bad48e1627
commit
cfbbb9ee3d
2399 changed files with 843193 additions and 43 deletions
|
|
@ -0,0 +1,115 @@
|
|||
from zope.interface._compat import _should_attempt_c_optimizations
|
||||
|
||||
|
||||
class OptimizationTestMixin(object):
|
||||
"""
|
||||
Helper for testing that C optimizations are used
|
||||
when appropriate.
|
||||
"""
|
||||
|
||||
def _getTargetClass(self):
|
||||
"""
|
||||
Define this to return the implementation in use,
|
||||
without the 'Py' or 'Fallback' suffix.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def _getFallbackClass(self):
|
||||
"""
|
||||
Define this to return the fallback Python implementation.
|
||||
"""
|
||||
# Is there an algorithmic way to do this? The C
|
||||
# objects all come from the same module so I don't see how we can
|
||||
# get the Python object from that.
|
||||
raise NotImplementedError
|
||||
|
||||
def test_optimizations(self):
|
||||
used = self._getTargetClass()
|
||||
fallback = self._getFallbackClass()
|
||||
|
||||
if _should_attempt_c_optimizations():
|
||||
self.assertIsNot(used, fallback)
|
||||
else:
|
||||
self.assertIs(used, fallback)
|
||||
|
||||
|
||||
class MissingSomeAttrs(object):
|
||||
"""
|
||||
Helper for tests that raises a specific exception
|
||||
for attributes that are missing. This is usually not
|
||||
an AttributeError, and this object is used to test that
|
||||
those errors are not improperly caught and treated like
|
||||
an AttributeError.
|
||||
"""
|
||||
|
||||
def __init__(self, exc_kind, **other_attrs):
|
||||
self.__exc_kind = exc_kind
|
||||
d = object.__getattribute__(self, '__dict__')
|
||||
d.update(other_attrs)
|
||||
|
||||
def __getattribute__(self, name):
|
||||
# Note that we ignore objects found in the class dictionary.
|
||||
d = object.__getattribute__(self, '__dict__')
|
||||
try:
|
||||
return d[name]
|
||||
except KeyError:
|
||||
raise d['_MissingSomeAttrs__exc_kind'](name)
|
||||
|
||||
EXCEPTION_CLASSES = (
|
||||
TypeError,
|
||||
RuntimeError,
|
||||
BaseException,
|
||||
ValueError,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def test_raises(cls, unittest, test_func, expected_missing, **other_attrs):
|
||||
"""
|
||||
Loop through various exceptions, calling *test_func* inside a ``assertRaises`` block.
|
||||
|
||||
:param test_func: A callable of one argument, the instance of this
|
||||
class.
|
||||
:param str expected_missing: The attribute that should fail with the exception.
|
||||
This is used to ensure that we're testing the path we think we are.
|
||||
:param other_attrs: Attributes that should be provided on the test object.
|
||||
Must not contain *expected_missing*.
|
||||
"""
|
||||
assert isinstance(expected_missing, str)
|
||||
assert expected_missing not in other_attrs
|
||||
for exc in cls.EXCEPTION_CLASSES:
|
||||
ob = cls(exc, **other_attrs)
|
||||
with unittest.assertRaises(exc) as ex:
|
||||
test_func(ob)
|
||||
|
||||
unittest.assertEqual(ex.exception.args[0], expected_missing)
|
||||
|
||||
# Now test that the AttributeError for that expected_missing is *not* raised.
|
||||
ob = cls(AttributeError, **other_attrs)
|
||||
try:
|
||||
test_func(ob)
|
||||
except AttributeError as e:
|
||||
unittest.assertNotIn(expected_missing, str(e))
|
||||
except Exception: # pylint:disable=broad-except
|
||||
pass
|
||||
|
||||
# Be sure cleanup functionality is available; classes that use the adapter hook
|
||||
# need to be sure to subclass ``CleanUp``.
|
||||
#
|
||||
# If zope.component is installed and imported when we run our tests
|
||||
# (import chain:
|
||||
# zope.testrunner->zope.security->zope.location->zope.component.api)
|
||||
# it adds an adapter hook that uses its global site manager. That can cause
|
||||
# leakage from one test to another unless its cleanup hooks are run. The symptoms can
|
||||
# be odd, especially if one test used C objects and the next used the Python
|
||||
# implementation. (For example, you can get strange TypeErrors or find inexplicable
|
||||
# comparisons being done.)
|
||||
try:
|
||||
from zope.testing import cleanup
|
||||
except ImportError:
|
||||
class CleanUp(object):
|
||||
def cleanUp(self):
|
||||
pass
|
||||
|
||||
setUp = tearDown = cleanUp
|
||||
else:
|
||||
CleanUp = cleanup.CleanUp
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
import sys
|
||||
|
||||
from zope.interface.advice import addClassAdvisor
|
||||
from zope.interface.advice import getFrameInfo
|
||||
|
||||
my_globals = globals()
|
||||
|
||||
def ping(log, value):
|
||||
|
||||
def pong(klass):
|
||||
log.append((value,klass))
|
||||
return [klass]
|
||||
|
||||
addClassAdvisor(pong)
|
||||
|
||||
try:
|
||||
from types import ClassType
|
||||
|
||||
class ClassicClass:
|
||||
__metaclass__ = ClassType
|
||||
classLevelFrameInfo = getFrameInfo(sys._getframe())
|
||||
except ImportError:
|
||||
ClassicClass = None
|
||||
|
||||
class NewStyleClass:
|
||||
__metaclass__ = type
|
||||
classLevelFrameInfo = getFrameInfo(sys._getframe())
|
||||
|
||||
moduleLevelFrameInfo = getFrameInfo(sys._getframe())
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
""" Dummy Module
|
||||
"""
|
||||
from zope.interface import moduleProvides
|
||||
from zope.interface.tests.idummy import IDummyModule
|
||||
|
||||
moduleProvides(IDummyModule)
|
||||
|
||||
def bar(baz):
|
||||
# Note: no 'self', because the module provides the interface directly.
|
||||
raise NotImplementedError()
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
""" Interface describing API of zope.interface.tests.dummy test module
|
||||
"""
|
||||
from zope.interface import Interface
|
||||
|
||||
class IDummyModule(Interface):
|
||||
""" Dummy interface for unit tests.
|
||||
"""
|
||||
def bar(baz):
|
||||
""" Just a note.
|
||||
"""
|
||||
21
venv/lib/python3.9/site-packages/zope/interface/tests/m1.py
Normal file
21
venv/lib/python3.9/site-packages/zope/interface/tests/m1.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Test module that declares an interface
|
||||
"""
|
||||
from zope.interface import Interface, moduleProvides
|
||||
|
||||
class I1(Interface): pass
|
||||
class I2(Interface): pass
|
||||
|
||||
moduleProvides(I1, I2)
|
||||
128
venv/lib/python3.9/site-packages/zope/interface/tests/odd.py
Normal file
128
venv/lib/python3.9/site-packages/zope/interface/tests/odd.py
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Odd meta class that doesn't subclass type.
|
||||
|
||||
This is used for testing support for ExtensionClass in new interfaces.
|
||||
|
||||
>>> class A(object):
|
||||
... __metaclass__ = MetaClass
|
||||
... a = 1
|
||||
...
|
||||
>>> A.__name__
|
||||
'A'
|
||||
>>> A.__bases__ == (object,)
|
||||
True
|
||||
>>> class B(object):
|
||||
... __metaclass__ = MetaClass
|
||||
... b = 1
|
||||
...
|
||||
>>> class C(A, B): pass
|
||||
...
|
||||
>>> C.__name__
|
||||
'C'
|
||||
>>> int(C.__bases__ == (A, B))
|
||||
1
|
||||
>>> a = A()
|
||||
>>> aa = A()
|
||||
>>> a.a
|
||||
1
|
||||
>>> aa.a
|
||||
1
|
||||
>>> aa.a = 2
|
||||
>>> a.a
|
||||
1
|
||||
>>> aa.a
|
||||
2
|
||||
>>> c = C()
|
||||
>>> c.a
|
||||
1
|
||||
>>> c.b
|
||||
1
|
||||
>>> c.b = 2
|
||||
>>> c.b
|
||||
2
|
||||
>>> C.c = 1
|
||||
>>> c.c
|
||||
1
|
||||
>>> import sys
|
||||
>>> if sys.version[0] == '2': # This test only makes sense under Python 2.x
|
||||
... from types import ClassType
|
||||
... assert not isinstance(C, (type, ClassType))
|
||||
|
||||
>>> int(C.__class__.__class__ is C.__class__)
|
||||
1
|
||||
"""
|
||||
|
||||
# class OddClass is an odd meta class
|
||||
|
||||
class MetaMetaClass(type):
|
||||
|
||||
def __getattribute__(cls, name):
|
||||
if name == '__class__':
|
||||
return cls
|
||||
# Under Python 3.6, __prepare__ gets requested
|
||||
return type.__getattribute__(cls, name)
|
||||
|
||||
|
||||
class MetaClass(object):
|
||||
"""Odd classes
|
||||
"""
|
||||
|
||||
def __init__(self, name, bases, dict):
|
||||
self.__name__ = name
|
||||
self.__bases__ = bases
|
||||
self.__dict__.update(dict)
|
||||
|
||||
def __call__(self):
|
||||
return OddInstance(self)
|
||||
|
||||
def __getattr__(self, name):
|
||||
for b in self.__bases__:
|
||||
v = getattr(b, name, self)
|
||||
if v is not self:
|
||||
return v
|
||||
raise AttributeError(name)
|
||||
|
||||
def __repr__(self): # pragma: no cover
|
||||
return "<odd class %s at %s>" % (self.__name__, hex(id(self)))
|
||||
|
||||
|
||||
MetaClass = MetaMetaClass('MetaClass',
|
||||
MetaClass.__bases__,
|
||||
{k: v for k, v in MetaClass.__dict__.items()
|
||||
if k not in ('__dict__',)})
|
||||
|
||||
class OddInstance(object):
|
||||
|
||||
def __init__(self, cls):
|
||||
self.__dict__['__class__'] = cls
|
||||
|
||||
def __getattribute__(self, name):
|
||||
dict = object.__getattribute__(self, '__dict__')
|
||||
if name == '__dict__':
|
||||
return dict
|
||||
v = dict.get(name, self)
|
||||
if v is not self:
|
||||
return v
|
||||
return getattr(dict['__class__'], name)
|
||||
|
||||
def __setattr__(self, name, v):
|
||||
self.__dict__[name] = v
|
||||
|
||||
def __delattr__(self, name):
|
||||
raise NotImplementedError()
|
||||
|
||||
def __repr__(self): # pragma: no cover
|
||||
return "<odd %s instance at %s>" % (
|
||||
self.__class__.__name__, hex(id(self)))
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,355 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Tests for advice
|
||||
|
||||
This module was adapted from 'protocols.tests.advice', part of the Python
|
||||
Enterprise Application Kit (PEAK). Please notify the PEAK authors
|
||||
(pje@telecommunity.com and tsarna@sarna.org) if bugs are found or
|
||||
Zope-specific changes are required, so that the PEAK version of this module
|
||||
can be kept in sync.
|
||||
|
||||
PEAK is a Python application framework that interoperates with (but does
|
||||
not require) Zope 3 and Twisted. It provides tools for manipulating UML
|
||||
models, object-relational persistence, aspect-oriented programming, and more.
|
||||
Visit the PEAK home page at http://peak.telecommunity.com for more information.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
from zope.interface._compat import _skip_under_py2
|
||||
from zope.interface._compat import _skip_under_py3k
|
||||
|
||||
|
||||
class FrameInfoTest(unittest.TestCase):
|
||||
|
||||
def test_w_module(self):
|
||||
from zope.interface.tests import advisory_testing
|
||||
(kind, module,
|
||||
f_locals, f_globals) = advisory_testing.moduleLevelFrameInfo
|
||||
self.assertEqual(kind, "module")
|
||||
for d in module.__dict__, f_locals, f_globals:
|
||||
self.assertTrue(d is advisory_testing.my_globals)
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_w_ClassicClass(self):
|
||||
from zope.interface.tests import advisory_testing
|
||||
(kind,
|
||||
module,
|
||||
f_locals,
|
||||
f_globals) = advisory_testing.ClassicClass.classLevelFrameInfo
|
||||
self.assertEqual(kind, "class")
|
||||
|
||||
self.assertTrue(
|
||||
f_locals is advisory_testing.ClassicClass.__dict__) # ???
|
||||
for d in module.__dict__, f_globals:
|
||||
self.assertTrue(d is advisory_testing.my_globals)
|
||||
|
||||
def test_w_NewStyleClass(self):
|
||||
from zope.interface.tests import advisory_testing
|
||||
(kind,
|
||||
module,
|
||||
f_locals,
|
||||
f_globals) = advisory_testing.NewStyleClass.classLevelFrameInfo
|
||||
self.assertEqual(kind, "class")
|
||||
|
||||
for d in module.__dict__, f_globals:
|
||||
self.assertTrue(d is advisory_testing.my_globals)
|
||||
|
||||
def test_inside_function_call(self):
|
||||
from zope.interface.advice import getFrameInfo
|
||||
kind, module, f_locals, f_globals = getFrameInfo(sys._getframe())
|
||||
self.assertEqual(kind, "function call")
|
||||
self.assertTrue(f_locals is locals()) # ???
|
||||
for d in module.__dict__, f_globals:
|
||||
self.assertTrue(d is globals())
|
||||
|
||||
def test_inside_exec(self):
|
||||
from zope.interface.advice import getFrameInfo
|
||||
_globals = {'getFrameInfo': getFrameInfo}
|
||||
_locals = {}
|
||||
exec(_FUNKY_EXEC, _globals, _locals)
|
||||
self.assertEqual(_locals['kind'], "exec")
|
||||
self.assertTrue(_locals['f_locals'] is _locals)
|
||||
self.assertTrue(_locals['module'] is None)
|
||||
self.assertTrue(_locals['f_globals'] is _globals)
|
||||
|
||||
|
||||
_FUNKY_EXEC = """\
|
||||
import sys
|
||||
kind, module, f_locals, f_globals = getFrameInfo(sys._getframe())
|
||||
"""
|
||||
|
||||
class AdviceTests(unittest.TestCase):
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_order(self):
|
||||
from zope.interface.tests.advisory_testing import ping
|
||||
log = []
|
||||
class Foo(object):
|
||||
ping(log, 1)
|
||||
ping(log, 2)
|
||||
ping(log, 3)
|
||||
|
||||
# Strip the list nesting
|
||||
for i in 1, 2, 3:
|
||||
self.assertTrue(isinstance(Foo, list))
|
||||
Foo, = Foo
|
||||
|
||||
self.assertEqual(log, [(1, Foo), (2, [Foo]), (3, [[Foo]])])
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_single_explicit_meta(self):
|
||||
from zope.interface.tests.advisory_testing import ping
|
||||
|
||||
class Metaclass(type):
|
||||
pass
|
||||
|
||||
class Concrete(Metaclass):
|
||||
__metaclass__ = Metaclass
|
||||
ping([],1)
|
||||
|
||||
Concrete, = Concrete
|
||||
self.assertTrue(Concrete.__class__ is Metaclass)
|
||||
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_mixed_metas(self):
|
||||
from zope.interface.tests.advisory_testing import ping
|
||||
|
||||
class Metaclass1(type):
|
||||
pass
|
||||
|
||||
class Metaclass2(type):
|
||||
pass
|
||||
|
||||
class Base1:
|
||||
__metaclass__ = Metaclass1
|
||||
|
||||
class Base2:
|
||||
__metaclass__ = Metaclass2
|
||||
|
||||
try:
|
||||
class Derived(Base1, Base2):
|
||||
ping([], 1)
|
||||
self.fail("Should have gotten incompatibility error")
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
class Metaclass3(Metaclass1, Metaclass2):
|
||||
pass
|
||||
|
||||
class Derived(Base1, Base2):
|
||||
__metaclass__ = Metaclass3
|
||||
ping([], 1)
|
||||
|
||||
self.assertTrue(isinstance(Derived, list))
|
||||
Derived, = Derived
|
||||
self.assertTrue(isinstance(Derived, Metaclass3))
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_meta_no_bases(self):
|
||||
from zope.interface.tests.advisory_testing import ping
|
||||
from types import ClassType
|
||||
class Thing:
|
||||
ping([], 1)
|
||||
klass, = Thing # unpack list created by pong
|
||||
self.assertEqual(type(klass), ClassType)
|
||||
|
||||
|
||||
class Test_isClassAdvisor(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, *args, **kw):
|
||||
from zope.interface.advice import isClassAdvisor
|
||||
return isClassAdvisor(*args, **kw)
|
||||
|
||||
def test_w_non_function(self):
|
||||
self.assertEqual(self._callFUT(self), False)
|
||||
|
||||
def test_w_normal_function(self):
|
||||
def foo():
|
||||
raise NotImplementedError()
|
||||
self.assertEqual(self._callFUT(foo), False)
|
||||
|
||||
def test_w_advisor_function(self):
|
||||
def bar():
|
||||
raise NotImplementedError()
|
||||
bar.previousMetaclass = object()
|
||||
self.assertEqual(self._callFUT(bar), True)
|
||||
|
||||
|
||||
class Test_determineMetaclass(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, *args, **kw):
|
||||
from zope.interface.advice import determineMetaclass
|
||||
return determineMetaclass(*args, **kw)
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_empty(self):
|
||||
from types import ClassType
|
||||
self.assertEqual(self._callFUT(()), ClassType)
|
||||
|
||||
def test_empty_w_explicit_metatype(self):
|
||||
class Meta(type):
|
||||
pass
|
||||
self.assertEqual(self._callFUT((), Meta), Meta)
|
||||
|
||||
def test_single(self):
|
||||
class Meta(type):
|
||||
pass
|
||||
self.assertEqual(self._callFUT((Meta,)), type)
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_meta_of_class(self):
|
||||
class Metameta(type):
|
||||
pass
|
||||
|
||||
class Meta(type):
|
||||
__metaclass__ = Metameta
|
||||
|
||||
self.assertEqual(self._callFUT((Meta, type)), Metameta)
|
||||
|
||||
@_skip_under_py2
|
||||
def test_meta_of_class_py3k(self):
|
||||
# Work around SyntaxError under Python2.
|
||||
EXEC = '\n'.join([
|
||||
'class Metameta(type):',
|
||||
' pass',
|
||||
'class Meta(type, metaclass=Metameta):',
|
||||
' pass',
|
||||
])
|
||||
globs = {}
|
||||
exec(EXEC, globs)
|
||||
Meta = globs['Meta']
|
||||
Metameta = globs['Metameta']
|
||||
|
||||
self.assertEqual(self._callFUT((Meta, type)), Metameta)
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_multiple_in_hierarchy(self):
|
||||
class Meta_A(type):
|
||||
pass
|
||||
class Meta_B(Meta_A):
|
||||
pass
|
||||
class A(type):
|
||||
__metaclass__ = Meta_A
|
||||
class B(type):
|
||||
__metaclass__ = Meta_B
|
||||
self.assertEqual(self._callFUT((A, B,)), Meta_B)
|
||||
|
||||
@_skip_under_py2
|
||||
def test_multiple_in_hierarchy_py3k(self):
|
||||
# Work around SyntaxError under Python2.
|
||||
EXEC = '\n'.join([
|
||||
'class Meta_A(type):',
|
||||
' pass',
|
||||
'class Meta_B(Meta_A):',
|
||||
' pass',
|
||||
'class A(type, metaclass=Meta_A):',
|
||||
' pass',
|
||||
'class B(type, metaclass=Meta_B):',
|
||||
' pass',
|
||||
])
|
||||
globs = {}
|
||||
exec(EXEC, globs)
|
||||
Meta_A = globs['Meta_A']
|
||||
Meta_B = globs['Meta_B']
|
||||
A = globs['A']
|
||||
B = globs['B']
|
||||
self.assertEqual(self._callFUT((A, B)), Meta_B)
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_multiple_not_in_hierarchy(self):
|
||||
class Meta_A(type):
|
||||
pass
|
||||
class Meta_B(type):
|
||||
pass
|
||||
class A(type):
|
||||
__metaclass__ = Meta_A
|
||||
class B(type):
|
||||
__metaclass__ = Meta_B
|
||||
self.assertRaises(TypeError, self._callFUT, (A, B,))
|
||||
|
||||
@_skip_under_py2
|
||||
def test_multiple_not_in_hierarchy_py3k(self):
|
||||
# Work around SyntaxError under Python2.
|
||||
EXEC = '\n'.join([
|
||||
'class Meta_A(type):',
|
||||
' pass',
|
||||
'class Meta_B(type):',
|
||||
' pass',
|
||||
'class A(type, metaclass=Meta_A):',
|
||||
' pass',
|
||||
'class B(type, metaclass=Meta_B):',
|
||||
' pass',
|
||||
])
|
||||
globs = {}
|
||||
exec(EXEC, globs)
|
||||
Meta_A = globs['Meta_A']
|
||||
Meta_B = globs['Meta_B']
|
||||
A = globs['A']
|
||||
B = globs['B']
|
||||
self.assertRaises(TypeError, self._callFUT, (A, B))
|
||||
|
||||
|
||||
class Test_minimalBases(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, klasses):
|
||||
from zope.interface.advice import minimalBases
|
||||
return minimalBases(klasses)
|
||||
|
||||
def test_empty(self):
|
||||
self.assertEqual(self._callFUT([]), [])
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_w_oldstyle_meta(self):
|
||||
class C:
|
||||
pass
|
||||
self.assertEqual(self._callFUT([type(C)]), [])
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_w_oldstyle_class(self):
|
||||
class C:
|
||||
pass
|
||||
self.assertEqual(self._callFUT([C]), [C])
|
||||
|
||||
def test_w_newstyle_meta(self):
|
||||
self.assertEqual(self._callFUT([type]), [type])
|
||||
|
||||
def test_w_newstyle_class(self):
|
||||
class C(object):
|
||||
pass
|
||||
self.assertEqual(self._callFUT([C]), [C])
|
||||
|
||||
def test_simple_hierarchy_skips_implied(self):
|
||||
class A(object):
|
||||
pass
|
||||
class B(A):
|
||||
pass
|
||||
class C(B):
|
||||
pass
|
||||
class D(object):
|
||||
pass
|
||||
self.assertEqual(self._callFUT([A, B, C]), [C])
|
||||
self.assertEqual(self._callFUT([A, C]), [C])
|
||||
self.assertEqual(self._callFUT([B, C]), [C])
|
||||
self.assertEqual(self._callFUT([A, B]), [B])
|
||||
self.assertEqual(self._callFUT([D, B, D]), [B, D])
|
||||
|
||||
def test_repeats_kicked_to_end_of_queue(self):
|
||||
class A(object):
|
||||
pass
|
||||
class B(object):
|
||||
pass
|
||||
self.assertEqual(self._callFUT([A, B, A]), [B, A])
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,505 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Documentation tests.
|
||||
"""
|
||||
import unittest
|
||||
|
||||
|
||||
class Test_asStructuredText(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, iface):
|
||||
from zope.interface.document import asStructuredText
|
||||
return asStructuredText(iface)
|
||||
|
||||
def test_asStructuredText_no_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"INoDocstring",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
""
|
||||
])
|
||||
class INoDocstring(Interface):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(INoDocstring), EXPECTED)
|
||||
|
||||
def test_asStructuredText_empty_with_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"IEmpty",
|
||||
" This is an empty interface.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
""
|
||||
])
|
||||
class IEmpty(Interface):
|
||||
""" This is an empty interface.
|
||||
"""
|
||||
self.assertEqual(self._callFUT(IEmpty), EXPECTED)
|
||||
|
||||
def test_asStructuredText_empty_with_multiline_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n'.join([
|
||||
"IEmpty",
|
||||
"",
|
||||
" This is an empty interface.",
|
||||
" ",
|
||||
(" It can be used to annotate any class or object, "
|
||||
"because it promises"),
|
||||
" nothing.",
|
||||
"",
|
||||
" Attributes:",
|
||||
"",
|
||||
" Methods:",
|
||||
"",
|
||||
""
|
||||
])
|
||||
class IEmpty(Interface):
|
||||
""" This is an empty interface.
|
||||
|
||||
It can be used to annotate any class or object, because it promises
|
||||
nothing.
|
||||
"""
|
||||
self.assertEqual(self._callFUT(IEmpty), EXPECTED)
|
||||
|
||||
def test_asStructuredText_with_attribute_no_docstring(self):
|
||||
from zope.interface import Attribute
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"IHasAttribute",
|
||||
" This interface has an attribute.",
|
||||
" Attributes:",
|
||||
" an_attribute -- no documentation",
|
||||
" Methods:",
|
||||
""
|
||||
])
|
||||
class IHasAttribute(Interface):
|
||||
""" This interface has an attribute.
|
||||
"""
|
||||
an_attribute = Attribute('an_attribute')
|
||||
|
||||
self.assertEqual(self._callFUT(IHasAttribute), EXPECTED)
|
||||
|
||||
def test_asStructuredText_with_attribute_with_docstring(self):
|
||||
from zope.interface import Attribute
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"IHasAttribute",
|
||||
" This interface has an attribute.",
|
||||
" Attributes:",
|
||||
" an_attribute -- This attribute is documented.",
|
||||
" Methods:",
|
||||
""
|
||||
])
|
||||
class IHasAttribute(Interface):
|
||||
""" This interface has an attribute.
|
||||
"""
|
||||
an_attribute = Attribute('an_attribute',
|
||||
'This attribute is documented.')
|
||||
|
||||
self.assertEqual(self._callFUT(IHasAttribute), EXPECTED)
|
||||
|
||||
def test_asStructuredText_with_method_no_args_no_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"IHasMethod",
|
||||
" This interface has a method.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
" aMethod() -- no documentation",
|
||||
""
|
||||
])
|
||||
class IHasMethod(Interface):
|
||||
""" This interface has a method.
|
||||
"""
|
||||
def aMethod():
|
||||
pass
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asStructuredText_with_method_positional_args_no_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"IHasMethod",
|
||||
" This interface has a method.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
" aMethod(first, second) -- no documentation",
|
||||
""
|
||||
])
|
||||
class IHasMethod(Interface):
|
||||
""" This interface has a method.
|
||||
"""
|
||||
def aMethod(first, second):
|
||||
pass
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asStructuredText_with_method_starargs_no_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"IHasMethod",
|
||||
" This interface has a method.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
" aMethod(first, second, *rest) -- no documentation",
|
||||
""
|
||||
])
|
||||
class IHasMethod(Interface):
|
||||
""" This interface has a method.
|
||||
"""
|
||||
def aMethod(first, second, *rest):
|
||||
pass
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asStructuredText_with_method_kwargs_no_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"IHasMethod",
|
||||
" This interface has a method.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
" aMethod(first, second, **kw) -- no documentation",
|
||||
""
|
||||
])
|
||||
class IHasMethod(Interface):
|
||||
""" This interface has a method.
|
||||
"""
|
||||
def aMethod(first, second, **kw):
|
||||
pass
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asStructuredText_with_method_with_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"IHasMethod",
|
||||
" This interface has a method.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
" aMethod() -- This method is documented.",
|
||||
""
|
||||
])
|
||||
class IHasMethod(Interface):
|
||||
""" This interface has a method.
|
||||
"""
|
||||
def aMethod():
|
||||
"""This method is documented.
|
||||
"""
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asStructuredText_derived_ignores_base(self):
|
||||
from zope.interface import Attribute
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"IDerived",
|
||||
" IDerived doc",
|
||||
" This interface extends:",
|
||||
" o IBase",
|
||||
" Attributes:",
|
||||
" attr1 -- no documentation",
|
||||
" attr2 -- attr2 doc",
|
||||
" Methods:",
|
||||
" method3() -- method3 doc",
|
||||
" method4() -- no documentation",
|
||||
" method5() -- method5 doc",
|
||||
"",
|
||||
])
|
||||
|
||||
class IBase(Interface):
|
||||
def method1():
|
||||
pass
|
||||
def method2():
|
||||
pass
|
||||
|
||||
class IDerived(IBase):
|
||||
"IDerived doc"
|
||||
attr1 = Attribute('attr1')
|
||||
attr2 = Attribute('attr2', 'attr2 doc')
|
||||
|
||||
def method3():
|
||||
"method3 doc"
|
||||
def method4():
|
||||
pass
|
||||
def method5():
|
||||
"method5 doc"
|
||||
|
||||
self.assertEqual(self._callFUT(IDerived), EXPECTED)
|
||||
|
||||
|
||||
class Test_asReStructuredText(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, iface):
|
||||
from zope.interface.document import asReStructuredText
|
||||
return asReStructuredText(iface)
|
||||
|
||||
def test_asReStructuredText_no_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"``INoDocstring``",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
""
|
||||
])
|
||||
class INoDocstring(Interface):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(INoDocstring), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_empty_with_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"``IEmpty``",
|
||||
" This is an empty interface.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
""
|
||||
])
|
||||
class IEmpty(Interface):
|
||||
""" This is an empty interface.
|
||||
"""
|
||||
self.assertEqual(self._callFUT(IEmpty), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_empty_with_multiline_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n'.join([
|
||||
"``IEmpty``",
|
||||
"",
|
||||
" This is an empty interface.",
|
||||
" ",
|
||||
(" It can be used to annotate any class or object, "
|
||||
"because it promises"),
|
||||
" nothing.",
|
||||
"",
|
||||
" Attributes:",
|
||||
"",
|
||||
" Methods:",
|
||||
"",
|
||||
""
|
||||
])
|
||||
class IEmpty(Interface):
|
||||
""" This is an empty interface.
|
||||
|
||||
It can be used to annotate any class or object, because it promises
|
||||
nothing.
|
||||
"""
|
||||
self.assertEqual(self._callFUT(IEmpty), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_with_attribute_no_docstring(self):
|
||||
from zope.interface import Attribute
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"``IHasAttribute``",
|
||||
" This interface has an attribute.",
|
||||
" Attributes:",
|
||||
" ``an_attribute`` -- no documentation",
|
||||
" Methods:",
|
||||
""
|
||||
])
|
||||
class IHasAttribute(Interface):
|
||||
""" This interface has an attribute.
|
||||
"""
|
||||
an_attribute = Attribute('an_attribute')
|
||||
|
||||
self.assertEqual(self._callFUT(IHasAttribute), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_with_attribute_with_docstring(self):
|
||||
from zope.interface import Attribute
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"``IHasAttribute``",
|
||||
" This interface has an attribute.",
|
||||
" Attributes:",
|
||||
" ``an_attribute`` -- This attribute is documented.",
|
||||
" Methods:",
|
||||
""
|
||||
])
|
||||
class IHasAttribute(Interface):
|
||||
""" This interface has an attribute.
|
||||
"""
|
||||
an_attribute = Attribute('an_attribute',
|
||||
'This attribute is documented.')
|
||||
|
||||
self.assertEqual(self._callFUT(IHasAttribute), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_with_method_no_args_no_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"``IHasMethod``",
|
||||
" This interface has a method.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
" ``aMethod()`` -- no documentation",
|
||||
""
|
||||
])
|
||||
class IHasMethod(Interface):
|
||||
""" This interface has a method.
|
||||
"""
|
||||
def aMethod():
|
||||
pass
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_with_method_positional_args_no_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"``IHasMethod``",
|
||||
" This interface has a method.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
" ``aMethod(first, second)`` -- no documentation",
|
||||
""
|
||||
])
|
||||
class IHasMethod(Interface):
|
||||
""" This interface has a method.
|
||||
"""
|
||||
def aMethod(first, second):
|
||||
pass
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_with_method_starargs_no_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"``IHasMethod``",
|
||||
" This interface has a method.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
" ``aMethod(first, second, *rest)`` -- no documentation",
|
||||
""
|
||||
])
|
||||
class IHasMethod(Interface):
|
||||
""" This interface has a method.
|
||||
"""
|
||||
def aMethod(first, second, *rest):
|
||||
pass
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_with_method_kwargs_no_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"``IHasMethod``",
|
||||
" This interface has a method.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
" ``aMethod(first, second, **kw)`` -- no documentation",
|
||||
""
|
||||
])
|
||||
class IHasMethod(Interface):
|
||||
""" This interface has a method.
|
||||
"""
|
||||
def aMethod(first, second, **kw):
|
||||
pass
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_with_method_with_docstring(self):
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"``IHasMethod``",
|
||||
" This interface has a method.",
|
||||
" Attributes:",
|
||||
" Methods:",
|
||||
" ``aMethod()`` -- This method is documented.",
|
||||
""
|
||||
])
|
||||
class IHasMethod(Interface):
|
||||
""" This interface has a method.
|
||||
"""
|
||||
def aMethod():
|
||||
"""This method is documented.
|
||||
"""
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_derived_ignores_base(self):
|
||||
from zope.interface import Attribute
|
||||
from zope.interface import Interface
|
||||
EXPECTED = '\n\n'.join([
|
||||
"``IDerived``",
|
||||
" IDerived doc",
|
||||
" This interface extends:",
|
||||
" o ``IBase``",
|
||||
" Attributes:",
|
||||
" ``attr1`` -- no documentation",
|
||||
" ``attr2`` -- attr2 doc",
|
||||
" Methods:",
|
||||
" ``method3()`` -- method3 doc",
|
||||
" ``method4()`` -- no documentation",
|
||||
" ``method5()`` -- method5 doc",
|
||||
"",
|
||||
])
|
||||
|
||||
class IBase(Interface):
|
||||
def method1():
|
||||
pass
|
||||
def method2():
|
||||
pass
|
||||
|
||||
class IDerived(IBase):
|
||||
"IDerived doc"
|
||||
attr1 = Attribute('attr1')
|
||||
attr2 = Attribute('attr2', 'attr2 doc')
|
||||
|
||||
def method3():
|
||||
"method3 doc"
|
||||
def method4():
|
||||
pass
|
||||
def method5():
|
||||
"method5 doc"
|
||||
|
||||
self.assertEqual(self._callFUT(IDerived), EXPECTED)
|
||||
|
||||
|
||||
class Test__justify_and_indent(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, text, level, **kw):
|
||||
from zope.interface.document import _justify_and_indent
|
||||
return _justify_and_indent(text, level, **kw)
|
||||
|
||||
def test_simple_level_0(self):
|
||||
LINES = ['Three blind mice', 'See how they run']
|
||||
text = '\n'.join(LINES)
|
||||
self.assertEqual(self._callFUT(text, 0), text)
|
||||
|
||||
def test_simple_level_1(self):
|
||||
LINES = ['Three blind mice', 'See how they run']
|
||||
text = '\n'.join(LINES)
|
||||
self.assertEqual(self._callFUT(text, 1),
|
||||
'\n'.join([' ' + line for line in LINES]))
|
||||
|
||||
def test_simple_level_2(self):
|
||||
LINES = ['Three blind mice', 'See how they run']
|
||||
text = '\n'.join(LINES)
|
||||
self.assertEqual(self._callFUT(text, 1),
|
||||
'\n'.join([' ' + line for line in LINES]))
|
||||
|
||||
def test_simple_w_CRLF(self):
|
||||
LINES = ['Three blind mice', 'See how they run']
|
||||
text = '\r\n'.join(LINES)
|
||||
self.assertEqual(self._callFUT(text, 1),
|
||||
'\n'.join([' ' + line for line in LINES]))
|
||||
|
||||
def test_with_munge(self):
|
||||
TEXT = ("This is a piece of text longer than 15 characters, \n"
|
||||
"and split across multiple lines.")
|
||||
EXPECTED = (" This is a piece\n"
|
||||
" of text longer\n"
|
||||
" than 15 characters,\n"
|
||||
" and split across\n"
|
||||
" multiple lines.\n"
|
||||
" ")
|
||||
self.assertEqual(self._callFUT(TEXT, 1, munge=1, width=15), EXPECTED)
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Test Element meta-class.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from zope.interface.interface import Element
|
||||
|
||||
class TestElement(unittest.TestCase):
|
||||
|
||||
def test_taggedValues(self):
|
||||
"""Test that we can update tagged values of more than one element
|
||||
"""
|
||||
|
||||
e1 = Element("foo")
|
||||
e2 = Element("bar")
|
||||
e1.setTaggedValue("x", 1)
|
||||
e2.setTaggedValue("x", 2)
|
||||
self.assertEqual(e1.getTaggedValue("x"), 1)
|
||||
self.assertEqual(e2.getTaggedValue("x"), 2)
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2010 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
""" zope.interface.exceptions unit tests
|
||||
"""
|
||||
import unittest
|
||||
|
||||
def _makeIface():
|
||||
from zope.interface import Interface
|
||||
class IDummy(Interface):
|
||||
pass
|
||||
return IDummy
|
||||
|
||||
class DoesNotImplementTests(unittest.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.exceptions import DoesNotImplement
|
||||
return DoesNotImplement
|
||||
|
||||
def _makeOne(self, *args):
|
||||
iface = _makeIface()
|
||||
return self._getTargetClass()(iface, *args)
|
||||
|
||||
def test___str__(self):
|
||||
dni = self._makeOne()
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"An object has failed to implement interface "
|
||||
"<InterfaceClass zope.interface.tests.test_exceptions.IDummy>: "
|
||||
"Does not declaratively implement the interface."
|
||||
)
|
||||
|
||||
def test___str__w_candidate(self):
|
||||
dni = self._makeOne('candidate')
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"The object 'candidate' has failed to implement interface "
|
||||
"<InterfaceClass zope.interface.tests.test_exceptions.IDummy>: "
|
||||
"Does not declaratively implement the interface."
|
||||
)
|
||||
|
||||
|
||||
class BrokenImplementationTests(unittest.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.exceptions import BrokenImplementation
|
||||
return BrokenImplementation
|
||||
|
||||
def _makeOne(self, *args):
|
||||
iface = _makeIface()
|
||||
return self._getTargetClass()(iface, 'missing', *args)
|
||||
|
||||
def test___str__(self):
|
||||
dni = self._makeOne()
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
'An object has failed to implement interface '
|
||||
'<InterfaceClass zope.interface.tests.test_exceptions.IDummy>: '
|
||||
"The 'missing' attribute was not provided.")
|
||||
|
||||
def test___str__w_candidate(self):
|
||||
dni = self._makeOne('candidate')
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
'The object \'candidate\' has failed to implement interface '
|
||||
'<InterfaceClass zope.interface.tests.test_exceptions.IDummy>: '
|
||||
"The 'missing' attribute was not provided.")
|
||||
|
||||
|
||||
def broken_function():
|
||||
"""
|
||||
This is a global function with a simple argument list.
|
||||
|
||||
It exists to be able to report the same information when
|
||||
formatting signatures under Python 2 and Python 3.
|
||||
"""
|
||||
|
||||
|
||||
class BrokenMethodImplementationTests(unittest.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
return BrokenMethodImplementation
|
||||
|
||||
message = 'I said so'
|
||||
|
||||
def _makeOne(self, *args):
|
||||
return self._getTargetClass()('aMethod', self.message, *args)
|
||||
|
||||
def test___str__(self):
|
||||
dni = self._makeOne()
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"An object has failed to implement interface <Unknown>: "
|
||||
"The contract of 'aMethod' is violated because I said so."
|
||||
)
|
||||
|
||||
def test___str__w_candidate_no_implementation(self):
|
||||
dni = self._makeOne('some_function', '<IFoo>', 'candidate')
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"The object 'candidate' has failed to implement interface <IFoo>: "
|
||||
"The contract of 'aMethod' is violated because I said so."
|
||||
)
|
||||
|
||||
def test___str__w_candidate_w_implementation(self):
|
||||
self.message = 'implementation is wonky'
|
||||
dni = self._makeOne(broken_function, '<IFoo>', 'candidate')
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"The object 'candidate' has failed to implement interface <IFoo>: "
|
||||
"The contract of 'aMethod' is violated because "
|
||||
"'broken_function()' is wonky."
|
||||
)
|
||||
|
||||
def test___str__w_candidate_w_implementation_not_callable(self):
|
||||
self.message = 'implementation is not callable'
|
||||
dni = self._makeOne(42, '<IFoo>', 'candidate')
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"The object 'candidate' has failed to implement interface <IFoo>: "
|
||||
"The contract of 'aMethod' is violated because "
|
||||
"'42' is not callable."
|
||||
)
|
||||
|
||||
def test___repr__w_candidate(self):
|
||||
dni = self._makeOne(None, 'candidate')
|
||||
self.assertEqual(
|
||||
repr(dni),
|
||||
"BrokenMethodImplementation('aMethod', 'I said so', None, 'candidate')"
|
||||
)
|
||||
|
||||
|
||||
class MultipleInvalidTests(unittest.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.exceptions import MultipleInvalid
|
||||
return MultipleInvalid
|
||||
|
||||
def _makeOne(self, excs):
|
||||
iface = _makeIface()
|
||||
return self._getTargetClass()(iface, 'target', excs)
|
||||
|
||||
def test__str__(self):
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
excs = [
|
||||
BrokenMethodImplementation('aMethod', 'I said so'),
|
||||
Exception("Regular exception")
|
||||
]
|
||||
dni = self._makeOne(excs)
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"The object 'target' has failed to implement interface "
|
||||
"<InterfaceClass zope.interface.tests.test_exceptions.IDummy>:\n"
|
||||
" The contract of 'aMethod' is violated because I said so\n"
|
||||
" Regular exception"
|
||||
)
|
||||
|
||||
def test__repr__(self):
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
excs = [
|
||||
BrokenMethodImplementation('aMethod', 'I said so'),
|
||||
# Use multiple arguments to normalize repr; versions of Python
|
||||
# prior to 3.7 add a trailing comma if there's just one.
|
||||
Exception("Regular", "exception")
|
||||
]
|
||||
dni = self._makeOne(excs)
|
||||
self.assertEqual(
|
||||
repr(dni),
|
||||
"MultipleInvalid(<InterfaceClass zope.interface.tests.test_exceptions.IDummy>,"
|
||||
" 'target',"
|
||||
" (BrokenMethodImplementation('aMethod', 'I said so'),"
|
||||
" Exception('Regular', 'exception')))"
|
||||
)
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,128 @@
|
|||
import unittest
|
||||
|
||||
|
||||
class _ConformsToIObjectEvent(object):
|
||||
|
||||
def _makeOne(self, target=None):
|
||||
if target is None:
|
||||
target = object()
|
||||
return self._getTargetClass()(target)
|
||||
|
||||
def test_class_conforms_to_IObjectEvent(self):
|
||||
from zope.interface.interfaces import IObjectEvent
|
||||
from zope.interface.verify import verifyClass
|
||||
verifyClass(IObjectEvent, self._getTargetClass())
|
||||
|
||||
def test_instance_conforms_to_IObjectEvent(self):
|
||||
from zope.interface.interfaces import IObjectEvent
|
||||
from zope.interface.verify import verifyObject
|
||||
verifyObject(IObjectEvent, self._makeOne())
|
||||
|
||||
|
||||
class _ConformsToIRegistrationEvent(_ConformsToIObjectEvent):
|
||||
|
||||
def test_class_conforms_to_IRegistrationEvent(self):
|
||||
from zope.interface.interfaces import IRegistrationEvent
|
||||
from zope.interface.verify import verifyClass
|
||||
verifyClass(IRegistrationEvent, self._getTargetClass())
|
||||
|
||||
def test_instance_conforms_to_IRegistrationEvent(self):
|
||||
from zope.interface.interfaces import IRegistrationEvent
|
||||
from zope.interface.verify import verifyObject
|
||||
verifyObject(IRegistrationEvent, self._makeOne())
|
||||
|
||||
|
||||
class ObjectEventTests(unittest.TestCase, _ConformsToIObjectEvent):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.interfaces import ObjectEvent
|
||||
return ObjectEvent
|
||||
|
||||
def test_ctor(self):
|
||||
target = object()
|
||||
event = self._makeOne(target)
|
||||
self.assertTrue(event.object is target)
|
||||
|
||||
|
||||
class RegistrationEventTests(unittest.TestCase,
|
||||
_ConformsToIRegistrationEvent):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.interfaces import RegistrationEvent
|
||||
return RegistrationEvent
|
||||
|
||||
def test___repr__(self):
|
||||
target = object()
|
||||
event = self._makeOne(target)
|
||||
r = repr(event)
|
||||
self.assertEqual(r.splitlines(),
|
||||
['RegistrationEvent event:', repr(target)])
|
||||
|
||||
|
||||
class RegisteredTests(unittest.TestCase,
|
||||
_ConformsToIRegistrationEvent):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.interfaces import Registered
|
||||
return Registered
|
||||
|
||||
def test_class_conforms_to_IRegistered(self):
|
||||
from zope.interface.interfaces import IRegistered
|
||||
from zope.interface.verify import verifyClass
|
||||
verifyClass(IRegistered, self._getTargetClass())
|
||||
|
||||
def test_instance_conforms_to_IRegistered(self):
|
||||
from zope.interface.interfaces import IRegistered
|
||||
from zope.interface.verify import verifyObject
|
||||
verifyObject(IRegistered, self._makeOne())
|
||||
|
||||
|
||||
class UnregisteredTests(unittest.TestCase,
|
||||
_ConformsToIRegistrationEvent):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.interfaces import Unregistered
|
||||
return Unregistered
|
||||
|
||||
def test_class_conforms_to_IUnregistered(self):
|
||||
from zope.interface.interfaces import IUnregistered
|
||||
from zope.interface.verify import verifyClass
|
||||
verifyClass(IUnregistered, self._getTargetClass())
|
||||
|
||||
def test_instance_conforms_to_IUnregistered(self):
|
||||
from zope.interface.interfaces import IUnregistered
|
||||
from zope.interface.verify import verifyObject
|
||||
verifyObject(IUnregistered, self._makeOne())
|
||||
|
||||
|
||||
class InterfaceClassTests(unittest.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.interface import InterfaceClass
|
||||
return InterfaceClass
|
||||
|
||||
def _getTargetInterface(self):
|
||||
from zope.interface.interfaces import IInterface
|
||||
return IInterface
|
||||
|
||||
def _makeOne(self):
|
||||
from zope.interface.interface import Interface
|
||||
return Interface
|
||||
|
||||
def test_class_conforms(self):
|
||||
from zope.interface.verify import verifyClass
|
||||
verifyClass(self._getTargetInterface(), self._getTargetClass())
|
||||
|
||||
def test_instance_conforms(self):
|
||||
from zope.interface.verify import verifyObject
|
||||
verifyObject(self._getTargetInterface(), self._makeOne())
|
||||
|
||||
def test_instance_consistent__iro__(self):
|
||||
from zope.interface import ro
|
||||
self.assertTrue(ro.is_consistent(self._getTargetInterface()))
|
||||
|
||||
def test_class_consistent__iro__(self):
|
||||
from zope.interface import ro
|
||||
from zope.interface import implementedBy
|
||||
|
||||
self.assertTrue(ro.is_consistent(implementedBy(self._getTargetClass())))
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Test interface declarations against ExtensionClass-like classes.
|
||||
|
||||
These tests are to make sure we do something sane in the presence of
|
||||
classic ExtensionClass classes and instances.
|
||||
"""
|
||||
import unittest
|
||||
|
||||
from zope.interface.tests import odd
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface import directlyProvides
|
||||
from zope.interface import providedBy
|
||||
from zope.interface import directlyProvidedBy
|
||||
from zope.interface import classImplements
|
||||
from zope.interface import classImplementsOnly
|
||||
from zope.interface import implementedBy
|
||||
from zope.interface._compat import _skip_under_py3k
|
||||
|
||||
class I1(Interface): pass
|
||||
class I2(Interface): pass
|
||||
class I3(Interface): pass
|
||||
class I31(I3): pass
|
||||
class I4(Interface): pass
|
||||
class I5(Interface): pass
|
||||
|
||||
class Odd(object):
|
||||
pass
|
||||
Odd = odd.MetaClass('Odd', Odd.__bases__, {})
|
||||
|
||||
|
||||
class B(Odd): __implemented__ = I2
|
||||
|
||||
|
||||
# TODO: We are going to need more magic to make classProvides work with odd
|
||||
# classes. This will work in the next iteration. For now, we'll use
|
||||
# a different mechanism.
|
||||
|
||||
# from zope.interface import classProvides
|
||||
class A(Odd):
|
||||
pass
|
||||
classImplements(A, I1)
|
||||
|
||||
class C(A, B):
|
||||
pass
|
||||
classImplements(C, I31)
|
||||
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_ObjectSpecification(self):
|
||||
c = C()
|
||||
directlyProvides(c, I4)
|
||||
self.assertEqual([i.getName() for i in providedBy(c)],
|
||||
['I4', 'I31', 'I1', 'I2']
|
||||
)
|
||||
self.assertEqual([i.getName() for i in providedBy(c).flattened()],
|
||||
['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
|
||||
)
|
||||
self.assertTrue(I1 in providedBy(c))
|
||||
self.assertFalse(I3 in providedBy(c))
|
||||
self.assertTrue(providedBy(c).extends(I3))
|
||||
self.assertTrue(providedBy(c).extends(I31))
|
||||
self.assertFalse(providedBy(c).extends(I5))
|
||||
|
||||
class COnly(A, B):
|
||||
pass
|
||||
classImplementsOnly(COnly, I31)
|
||||
|
||||
class D(COnly):
|
||||
pass
|
||||
classImplements(D, I5)
|
||||
|
||||
classImplements(D, I5)
|
||||
|
||||
c = D()
|
||||
directlyProvides(c, I4)
|
||||
self.assertEqual([i.getName() for i in providedBy(c)],
|
||||
['I4', 'I5', 'I31'])
|
||||
self.assertEqual([i.getName() for i in providedBy(c).flattened()],
|
||||
['I4', 'I5', 'I31', 'I3', 'Interface'])
|
||||
self.assertFalse(I1 in providedBy(c))
|
||||
self.assertFalse(I3 in providedBy(c))
|
||||
self.assertTrue(providedBy(c).extends(I3))
|
||||
self.assertFalse(providedBy(c).extends(I1))
|
||||
self.assertTrue(providedBy(c).extends(I31))
|
||||
self.assertTrue(providedBy(c).extends(I5))
|
||||
|
||||
class COnly(A, B): __implemented__ = I31
|
||||
class D(COnly):
|
||||
pass
|
||||
classImplements(D, I5)
|
||||
|
||||
classImplements(D, I5)
|
||||
c = D()
|
||||
directlyProvides(c, I4)
|
||||
self.assertEqual([i.getName() for i in providedBy(c)],
|
||||
['I4', 'I5', 'I31'])
|
||||
self.assertEqual([i.getName() for i in providedBy(c).flattened()],
|
||||
['I4', 'I5', 'I31', 'I3', 'Interface'])
|
||||
self.assertFalse(I1 in providedBy(c))
|
||||
self.assertFalse(I3 in providedBy(c))
|
||||
self.assertTrue(providedBy(c).extends(I3))
|
||||
self.assertFalse(providedBy(c).extends(I1))
|
||||
self.assertTrue(providedBy(c).extends(I31))
|
||||
self.assertTrue(providedBy(c).extends(I5))
|
||||
|
||||
def test_classImplements(self):
|
||||
|
||||
@implementer(I3)
|
||||
class A(Odd):
|
||||
pass
|
||||
|
||||
@implementer(I4)
|
||||
class B(Odd):
|
||||
pass
|
||||
|
||||
class C(A, B):
|
||||
pass
|
||||
classImplements(C, I1, I2)
|
||||
self.assertEqual([i.getName() for i in implementedBy(C)],
|
||||
['I1', 'I2', 'I3', 'I4'])
|
||||
classImplements(C, I5)
|
||||
self.assertEqual([i.getName() for i in implementedBy(C)],
|
||||
['I1', 'I2', 'I5', 'I3', 'I4'])
|
||||
|
||||
def test_classImplementsOnly(self):
|
||||
@implementer(I3)
|
||||
class A(Odd):
|
||||
pass
|
||||
|
||||
@implementer(I4)
|
||||
class B(Odd):
|
||||
pass
|
||||
|
||||
class C(A, B):
|
||||
pass
|
||||
classImplementsOnly(C, I1, I2)
|
||||
self.assertEqual([i.__name__ for i in implementedBy(C)],
|
||||
['I1', 'I2'])
|
||||
|
||||
|
||||
def test_directlyProvides(self):
|
||||
class IA1(Interface): pass
|
||||
class IA2(Interface): pass
|
||||
class IB(Interface): pass
|
||||
class IC(Interface): pass
|
||||
class A(Odd):
|
||||
pass
|
||||
classImplements(A, IA1, IA2)
|
||||
|
||||
class B(Odd):
|
||||
pass
|
||||
classImplements(B, IB)
|
||||
|
||||
class C(A, B):
|
||||
pass
|
||||
classImplements(C, IC)
|
||||
|
||||
|
||||
ob = C()
|
||||
directlyProvides(ob, I1, I2)
|
||||
self.assertTrue(I1 in providedBy(ob))
|
||||
self.assertTrue(I2 in providedBy(ob))
|
||||
self.assertTrue(IA1 in providedBy(ob))
|
||||
self.assertTrue(IA2 in providedBy(ob))
|
||||
self.assertTrue(IB in providedBy(ob))
|
||||
self.assertTrue(IC in providedBy(ob))
|
||||
|
||||
directlyProvides(ob, directlyProvidedBy(ob)-I2)
|
||||
self.assertTrue(I1 in providedBy(ob))
|
||||
self.assertFalse(I2 in providedBy(ob))
|
||||
self.assertFalse(I2 in providedBy(ob))
|
||||
directlyProvides(ob, directlyProvidedBy(ob), I2)
|
||||
self.assertTrue(I2 in providedBy(ob))
|
||||
|
||||
@_skip_under_py3k
|
||||
def test_directlyProvides_fails_for_odd_class(self):
|
||||
self.assertRaises(TypeError, directlyProvides, C, I5)
|
||||
|
||||
# see above
|
||||
#def TODO_test_classProvides_fails_for_odd_class(self):
|
||||
# try:
|
||||
# class A(Odd):
|
||||
# classProvides(I1)
|
||||
# except TypeError:
|
||||
# pass # Sucess
|
||||
# self.assert_(False,
|
||||
# "Shouldn't be able to use directlyProvides on odd class."
|
||||
# )
|
||||
|
||||
def test_implementedBy(self):
|
||||
class I2(I1): pass
|
||||
|
||||
class C1(Odd):
|
||||
pass
|
||||
classImplements(C1, I2)
|
||||
|
||||
class C2(C1):
|
||||
pass
|
||||
classImplements(C2, I3)
|
||||
|
||||
self.assertEqual([i.getName() for i in implementedBy(C2)],
|
||||
['I3', 'I2'])
|
||||
|
||||
def test_odd_metaclass_that_doesnt_subclass_type(self):
|
||||
# This was originally a doctest in odd.py.
|
||||
# It verifies that the metaclass the rest of these tests use
|
||||
# works as expected.
|
||||
|
||||
# This is used for testing support for ExtensionClass in new interfaces.
|
||||
|
||||
class A(object):
|
||||
a = 1
|
||||
|
||||
A = odd.MetaClass('A', A.__bases__, A.__dict__)
|
||||
|
||||
class B(object):
|
||||
b = 1
|
||||
|
||||
B = odd.MetaClass('B', B.__bases__, B.__dict__)
|
||||
|
||||
class C(A, B):
|
||||
pass
|
||||
|
||||
self.assertEqual(C.__bases__, (A, B))
|
||||
|
||||
a = A()
|
||||
aa = A()
|
||||
self.assertEqual(a.a, 1)
|
||||
self.assertEqual(aa.a, 1)
|
||||
|
||||
aa.a = 2
|
||||
self.assertEqual(a.a, 1)
|
||||
self.assertEqual(aa.a, 2)
|
||||
|
||||
c = C()
|
||||
self.assertEqual(c.a, 1)
|
||||
self.assertEqual(c.b, 1)
|
||||
|
||||
c.b = 2
|
||||
self.assertEqual(c.b, 2)
|
||||
|
||||
C.c = 1
|
||||
self.assertEqual(c.c, 1)
|
||||
c.c
|
||||
|
||||
try:
|
||||
from types import ClassType
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
# This test only makes sense under Python 2.x
|
||||
assert not isinstance(C, (type, ClassType))
|
||||
|
||||
self.assertIs(C.__class__.__class__, C.__class__)
|
||||
File diff suppressed because it is too large
Load diff
426
venv/lib/python3.9/site-packages/zope/interface/tests/test_ro.py
Normal file
426
venv/lib/python3.9/site-packages/zope/interface/tests/test_ro.py
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2014 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Resolution ordering utility tests"""
|
||||
import unittest
|
||||
|
||||
# pylint:disable=blacklisted-name,protected-access,attribute-defined-outside-init
|
||||
|
||||
class Test__mergeOrderings(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, orderings):
|
||||
from zope.interface.ro import _legacy_mergeOrderings
|
||||
return _legacy_mergeOrderings(orderings)
|
||||
|
||||
def test_empty(self):
|
||||
self.assertEqual(self._callFUT([]), [])
|
||||
|
||||
def test_single(self):
|
||||
self.assertEqual(self._callFUT(['a', 'b', 'c']), ['a', 'b', 'c'])
|
||||
|
||||
def test_w_duplicates(self):
|
||||
self.assertEqual(self._callFUT([['a'], ['b', 'a']]), ['b', 'a'])
|
||||
|
||||
def test_suffix_across_multiple_duplicates(self):
|
||||
O1 = ['x', 'y', 'z']
|
||||
O2 = ['q', 'z']
|
||||
O3 = [1, 3, 5]
|
||||
O4 = ['z']
|
||||
self.assertEqual(self._callFUT([O1, O2, O3, O4]),
|
||||
['x', 'y', 'q', 1, 3, 5, 'z'])
|
||||
|
||||
|
||||
class Test__flatten(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, ob):
|
||||
from zope.interface.ro import _legacy_flatten
|
||||
return _legacy_flatten(ob)
|
||||
|
||||
def test_w_empty_bases(self):
|
||||
class Foo(object):
|
||||
pass
|
||||
foo = Foo()
|
||||
foo.__bases__ = ()
|
||||
self.assertEqual(self._callFUT(foo), [foo])
|
||||
|
||||
def test_w_single_base(self):
|
||||
class Foo(object):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Foo), [Foo, object])
|
||||
|
||||
def test_w_bases(self):
|
||||
class Foo(object):
|
||||
pass
|
||||
class Bar(Foo):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Bar), [Bar, Foo, object])
|
||||
|
||||
def test_w_diamond(self):
|
||||
class Foo(object):
|
||||
pass
|
||||
class Bar(Foo):
|
||||
pass
|
||||
class Baz(Foo):
|
||||
pass
|
||||
class Qux(Bar, Baz):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Qux),
|
||||
[Qux, Bar, Foo, object, Baz, Foo, object])
|
||||
|
||||
|
||||
class Test_ro(unittest.TestCase):
|
||||
maxDiff = None
|
||||
def _callFUT(self, ob, **kwargs):
|
||||
from zope.interface.ro import _legacy_ro
|
||||
return _legacy_ro(ob, **kwargs)
|
||||
|
||||
def test_w_empty_bases(self):
|
||||
class Foo(object):
|
||||
pass
|
||||
foo = Foo()
|
||||
foo.__bases__ = ()
|
||||
self.assertEqual(self._callFUT(foo), [foo])
|
||||
|
||||
def test_w_single_base(self):
|
||||
class Foo(object):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Foo), [Foo, object])
|
||||
|
||||
def test_w_bases(self):
|
||||
class Foo(object):
|
||||
pass
|
||||
class Bar(Foo):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Bar), [Bar, Foo, object])
|
||||
|
||||
def test_w_diamond(self):
|
||||
class Foo(object):
|
||||
pass
|
||||
class Bar(Foo):
|
||||
pass
|
||||
class Baz(Foo):
|
||||
pass
|
||||
class Qux(Bar, Baz):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Qux),
|
||||
[Qux, Bar, Baz, Foo, object])
|
||||
|
||||
def _make_IOErr(self):
|
||||
# This can't be done in the standard C3 ordering.
|
||||
class Foo(object):
|
||||
def __init__(self, name, *bases):
|
||||
self.__name__ = name
|
||||
self.__bases__ = bases
|
||||
def __repr__(self): # pragma: no cover
|
||||
return self.__name__
|
||||
|
||||
# Mimic what classImplements(IOError, IIOError)
|
||||
# does.
|
||||
IEx = Foo('IEx')
|
||||
IStdErr = Foo('IStdErr', IEx)
|
||||
IEnvErr = Foo('IEnvErr', IStdErr)
|
||||
IIOErr = Foo('IIOErr', IEnvErr)
|
||||
IOSErr = Foo('IOSErr', IEnvErr)
|
||||
|
||||
IOErr = Foo('IOErr', IEnvErr, IIOErr, IOSErr)
|
||||
return IOErr, [IOErr, IIOErr, IOSErr, IEnvErr, IStdErr, IEx]
|
||||
|
||||
def test_non_orderable(self):
|
||||
IOErr, bases = self._make_IOErr()
|
||||
|
||||
self.assertEqual(self._callFUT(IOErr), bases)
|
||||
|
||||
def test_mixed_inheritance_and_implementation(self):
|
||||
# https://github.com/zopefoundation/zope.interface/issues/8
|
||||
# This test should fail, but doesn't, as described in that issue.
|
||||
# pylint:disable=inherit-non-class
|
||||
from zope.interface import implementer
|
||||
from zope.interface import Interface
|
||||
from zope.interface import providedBy
|
||||
from zope.interface import implementedBy
|
||||
|
||||
class IFoo(Interface):
|
||||
pass
|
||||
|
||||
@implementer(IFoo)
|
||||
class ImplementsFoo(object):
|
||||
pass
|
||||
|
||||
class ExtendsFoo(ImplementsFoo):
|
||||
pass
|
||||
|
||||
class ImplementsNothing(object):
|
||||
pass
|
||||
|
||||
class ExtendsFooImplementsNothing(ExtendsFoo, ImplementsNothing):
|
||||
pass
|
||||
|
||||
self.assertEqual(
|
||||
self._callFUT(providedBy(ExtendsFooImplementsNothing())),
|
||||
[implementedBy(ExtendsFooImplementsNothing),
|
||||
implementedBy(ExtendsFoo),
|
||||
implementedBy(ImplementsFoo),
|
||||
IFoo,
|
||||
Interface,
|
||||
implementedBy(ImplementsNothing),
|
||||
implementedBy(object)])
|
||||
|
||||
|
||||
class C3Setting(object):
|
||||
|
||||
def __init__(self, setting, value):
|
||||
self._setting = setting
|
||||
self._value = value
|
||||
|
||||
def __enter__(self):
|
||||
from zope.interface import ro
|
||||
setattr(ro.C3, self._setting.__name__, self._value)
|
||||
|
||||
def __exit__(self, t, v, tb):
|
||||
from zope.interface import ro
|
||||
setattr(ro.C3, self._setting.__name__, self._setting)
|
||||
|
||||
class Test_c3_ro(Test_ro):
|
||||
|
||||
def setUp(self):
|
||||
Test_ro.setUp(self)
|
||||
from zope.testing.loggingsupport import InstalledHandler
|
||||
self.log_handler = handler = InstalledHandler('zope.interface.ro')
|
||||
self.addCleanup(handler.uninstall)
|
||||
|
||||
def _callFUT(self, ob, **kwargs):
|
||||
from zope.interface.ro import ro
|
||||
return ro(ob, **kwargs)
|
||||
|
||||
def test_complex_diamond(self, base=object):
|
||||
# https://github.com/zopefoundation/zope.interface/issues/21
|
||||
O = base
|
||||
class F(O):
|
||||
pass
|
||||
class E(O):
|
||||
pass
|
||||
class D(O):
|
||||
pass
|
||||
class C(D, F):
|
||||
pass
|
||||
class B(D, E):
|
||||
pass
|
||||
class A(B, C):
|
||||
pass
|
||||
|
||||
if hasattr(A, 'mro'):
|
||||
self.assertEqual(A.mro(), self._callFUT(A))
|
||||
|
||||
return A
|
||||
|
||||
def test_complex_diamond_interface(self):
|
||||
from zope.interface import Interface
|
||||
|
||||
IA = self.test_complex_diamond(Interface)
|
||||
|
||||
self.assertEqual(
|
||||
[x.__name__ for x in IA.__iro__],
|
||||
['A', 'B', 'C', 'D', 'E', 'F', 'Interface']
|
||||
)
|
||||
|
||||
def test_complex_diamond_use_legacy_argument(self):
|
||||
from zope.interface import Interface
|
||||
|
||||
A = self.test_complex_diamond(Interface)
|
||||
legacy_A_iro = self._callFUT(A, use_legacy_ro=True)
|
||||
self.assertNotEqual(A.__iro__, legacy_A_iro)
|
||||
|
||||
# And logging happened as a side-effect.
|
||||
self._check_handler_complex_diamond()
|
||||
|
||||
def test_complex_diamond_compare_legacy_argument(self):
|
||||
from zope.interface import Interface
|
||||
|
||||
A = self.test_complex_diamond(Interface)
|
||||
computed_A_iro = self._callFUT(A, log_changed_ro=True)
|
||||
# It matches, of course, but we did log a warning.
|
||||
self.assertEqual(tuple(computed_A_iro), A.__iro__)
|
||||
self._check_handler_complex_diamond()
|
||||
|
||||
def _check_handler_complex_diamond(self):
|
||||
handler = self.log_handler
|
||||
self.assertEqual(1, len(handler.records))
|
||||
record = handler.records[0]
|
||||
|
||||
self.assertEqual('\n'.join(l.rstrip() for l in record.getMessage().splitlines()), """\
|
||||
Object <InterfaceClass zope.interface.tests.test_ro.A> has different legacy and C3 MROs:
|
||||
Legacy RO (len=7) C3 RO (len=7; inconsistent=no)
|
||||
====================================================================================================
|
||||
<InterfaceClass zope.interface.tests.test_ro.A> <InterfaceClass zope.interface.tests.test_ro.A>
|
||||
<InterfaceClass zope.interface.tests.test_ro.B> <InterfaceClass zope.interface.tests.test_ro.B>
|
||||
- <InterfaceClass zope.interface.tests.test_ro.E>
|
||||
<InterfaceClass zope.interface.tests.test_ro.C> <InterfaceClass zope.interface.tests.test_ro.C>
|
||||
<InterfaceClass zope.interface.tests.test_ro.D> <InterfaceClass zope.interface.tests.test_ro.D>
|
||||
+ <InterfaceClass zope.interface.tests.test_ro.E>
|
||||
<InterfaceClass zope.interface.tests.test_ro.F> <InterfaceClass zope.interface.tests.test_ro.F>
|
||||
<InterfaceClass zope.interface.Interface> <InterfaceClass zope.interface.Interface>""")
|
||||
|
||||
def test_ExtendedPathIndex_implement_thing_implementedby_super(self):
|
||||
# See https://github.com/zopefoundation/zope.interface/pull/182#issuecomment-598754056
|
||||
from zope.interface import ro
|
||||
# pylint:disable=inherit-non-class
|
||||
class _Based(object):
|
||||
__bases__ = ()
|
||||
|
||||
def __init__(self, name, bases=(), attrs=None):
|
||||
self.__name__ = name
|
||||
self.__bases__ = bases
|
||||
|
||||
def __repr__(self):
|
||||
return self.__name__
|
||||
|
||||
Interface = _Based('Interface', (), {})
|
||||
|
||||
class IPluggableIndex(Interface):
|
||||
pass
|
||||
|
||||
class ILimitedResultIndex(IPluggableIndex):
|
||||
pass
|
||||
|
||||
class IQueryIndex(IPluggableIndex):
|
||||
pass
|
||||
|
||||
class IPathIndex(Interface):
|
||||
pass
|
||||
|
||||
# A parent class who implements two distinct interfaces whose
|
||||
# only common ancestor is Interface. An easy case.
|
||||
# @implementer(IPathIndex, IQueryIndex)
|
||||
# class PathIndex(object):
|
||||
# pass
|
||||
obj = _Based('object')
|
||||
PathIndex = _Based('PathIndex', (IPathIndex, IQueryIndex, obj))
|
||||
|
||||
# Child class that tries to put an interface the parent declares
|
||||
# later ahead of the parent.
|
||||
# @implementer(ILimitedResultIndex, IQueryIndex)
|
||||
# class ExtendedPathIndex(PathIndex):
|
||||
# pass
|
||||
ExtendedPathIndex = _Based('ExtendedPathIndex',
|
||||
(ILimitedResultIndex, IQueryIndex, PathIndex))
|
||||
|
||||
# We were able to resolve it, and in exactly the same way as
|
||||
# the legacy RO did, even though it is inconsistent.
|
||||
result = self._callFUT(ExtendedPathIndex, log_changed_ro=True, strict=False)
|
||||
self.assertEqual(result, [
|
||||
ExtendedPathIndex,
|
||||
ILimitedResultIndex,
|
||||
PathIndex,
|
||||
IPathIndex,
|
||||
IQueryIndex,
|
||||
IPluggableIndex,
|
||||
Interface,
|
||||
obj])
|
||||
|
||||
record, = self.log_handler.records
|
||||
self.assertIn('used the legacy', record.getMessage())
|
||||
|
||||
with self.assertRaises(ro.InconsistentResolutionOrderError):
|
||||
self._callFUT(ExtendedPathIndex, strict=True)
|
||||
|
||||
def test_OSError_IOError(self):
|
||||
if OSError is not IOError:
|
||||
# Python 2
|
||||
self.skipTest("Requires Python 3 IOError == OSError")
|
||||
from zope.interface.common import interfaces
|
||||
from zope.interface import providedBy
|
||||
|
||||
self.assertEqual(
|
||||
list(providedBy(OSError()).flattened()),
|
||||
[
|
||||
interfaces.IOSError,
|
||||
interfaces.IIOError,
|
||||
interfaces.IEnvironmentError,
|
||||
interfaces.IStandardError,
|
||||
interfaces.IException,
|
||||
interfaces.Interface,
|
||||
])
|
||||
|
||||
def test_non_orderable(self):
|
||||
import warnings
|
||||
from zope.interface import ro
|
||||
try:
|
||||
# If we've already warned, we must reset that state.
|
||||
del ro.__warningregistry__
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('error')
|
||||
with C3Setting(ro.C3.WARN_BAD_IRO, True), C3Setting(ro.C3.STRICT_IRO, False):
|
||||
with self.assertRaises(ro.InconsistentResolutionOrderWarning):
|
||||
super(Test_c3_ro, self).test_non_orderable()
|
||||
|
||||
IOErr, _ = self._make_IOErr()
|
||||
with self.assertRaises(ro.InconsistentResolutionOrderError):
|
||||
self._callFUT(IOErr, strict=True)
|
||||
|
||||
with C3Setting(ro.C3.TRACK_BAD_IRO, True), C3Setting(ro.C3.STRICT_IRO, False):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
self._callFUT(IOErr)
|
||||
self.assertIn(IOErr, ro.C3.BAD_IROS)
|
||||
|
||||
iro = self._callFUT(IOErr, strict=False)
|
||||
legacy_iro = self._callFUT(IOErr, use_legacy_ro=True, strict=False)
|
||||
self.assertEqual(iro, legacy_iro)
|
||||
|
||||
|
||||
class TestC3(unittest.TestCase):
|
||||
def _makeOne(self, C, strict=False, base_mros=None):
|
||||
from zope.interface.ro import C3
|
||||
return C3.resolver(C, strict, base_mros)
|
||||
|
||||
def test_base_mros_given(self):
|
||||
c3 = self._makeOne(type(self), base_mros={unittest.TestCase: unittest.TestCase.__mro__})
|
||||
memo = c3.memo
|
||||
self.assertIn(unittest.TestCase, memo)
|
||||
# We used the StaticMRO class
|
||||
self.assertIsNone(memo[unittest.TestCase].had_inconsistency)
|
||||
|
||||
def test_one_base_optimization(self):
|
||||
c3 = self._makeOne(type(self))
|
||||
# Even though we didn't call .mro() yet, the MRO has been
|
||||
# computed.
|
||||
self.assertIsNotNone(c3._C3__mro) # pylint:disable=no-member
|
||||
c3._merge = None
|
||||
self.assertEqual(c3.mro(), list(type(self).__mro__))
|
||||
|
||||
|
||||
class Test_ROComparison(unittest.TestCase):
|
||||
|
||||
class MockC3(object):
|
||||
direct_inconsistency = False
|
||||
bases_had_inconsistency = False
|
||||
|
||||
def _makeOne(self, c3=None, c3_ro=(), legacy_ro=()):
|
||||
from zope.interface.ro import _ROComparison
|
||||
return _ROComparison(c3 or self.MockC3(), c3_ro, legacy_ro)
|
||||
|
||||
def test_inconsistent_label(self):
|
||||
comp = self._makeOne()
|
||||
self.assertEqual('no', comp._inconsistent_label)
|
||||
|
||||
comp.c3.direct_inconsistency = True
|
||||
self.assertEqual("direct", comp._inconsistent_label)
|
||||
|
||||
comp.c3.bases_had_inconsistency = True
|
||||
self.assertEqual("direct+bases", comp._inconsistent_label)
|
||||
|
||||
comp.c3.direct_inconsistency = False
|
||||
self.assertEqual('bases', comp._inconsistent_label)
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Test interface sorting
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from zope.interface import Interface
|
||||
|
||||
class I1(Interface): pass
|
||||
class I2(I1): pass
|
||||
class I3(I1): pass
|
||||
class I4(Interface): pass
|
||||
class I5(I4): pass
|
||||
class I6(I2): pass
|
||||
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test(self):
|
||||
l = [I1, I3, I5, I6, I4, I2]
|
||||
l.sort()
|
||||
self.assertEqual(l, [I1, I2, I3, I4, I5, I6])
|
||||
|
||||
def test_w_None(self):
|
||||
l = [I1, None, I3, I5, I6, I4, I2]
|
||||
l.sort()
|
||||
self.assertEqual(l, [I1, I2, I3, I4, I5, I6, None])
|
||||
|
||||
def test_w_equal_names(self):
|
||||
# interfaces with equal names but different modules should sort by
|
||||
# module name
|
||||
from zope.interface.tests.m1 import I1 as m1_I1
|
||||
l = [I1, m1_I1]
|
||||
l.sort()
|
||||
self.assertEqual(l, [m1_I1, I1])
|
||||
|
||||
def test_I1_I2(self):
|
||||
self.assertLess(I1.__name__, I2.__name__)
|
||||
self.assertEqual(I1.__module__, I2.__module__)
|
||||
self.assertEqual(I1.__module__, __name__)
|
||||
self.assertLess(I1, I2)
|
||||
|
||||
def _makeI1(self):
|
||||
class I1(Interface):
|
||||
pass
|
||||
return I1
|
||||
|
||||
def test_nested(self):
|
||||
nested_I1 = self._makeI1()
|
||||
self.assertEqual(I1, nested_I1)
|
||||
self.assertEqual(nested_I1, I1)
|
||||
self.assertEqual(hash(I1), hash(nested_I1))
|
||||
|
|
@ -0,0 +1,656 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
""" zope.interface.verify unit tests
|
||||
"""
|
||||
import unittest
|
||||
|
||||
# pylint:disable=inherit-non-class,no-method-argument,no-self-argument
|
||||
|
||||
class Test_verifyClass(unittest.TestCase):
|
||||
|
||||
verifier = None
|
||||
|
||||
def setUp(self):
|
||||
self.verifier = self._get_FUT()
|
||||
|
||||
@classmethod
|
||||
def _get_FUT(cls):
|
||||
from zope.interface.verify import verifyClass
|
||||
return verifyClass
|
||||
|
||||
_adjust_object_before_verify = lambda self, x: x
|
||||
|
||||
def _callFUT(self, iface, klass, **kwargs):
|
||||
return self.verifier(iface,
|
||||
self._adjust_object_before_verify(klass),
|
||||
**kwargs)
|
||||
|
||||
def test_class_doesnt_implement(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface.exceptions import DoesNotImplement
|
||||
|
||||
class ICurrent(Interface):
|
||||
pass
|
||||
|
||||
class Current(object):
|
||||
pass
|
||||
|
||||
self.assertRaises(DoesNotImplement, self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_class_doesnt_implement_but_classImplements_later(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import classImplements
|
||||
|
||||
class ICurrent(Interface):
|
||||
pass
|
||||
|
||||
class Current(object):
|
||||
pass
|
||||
|
||||
classImplements(Current, ICurrent)
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_class_doesnt_have_required_method_simple(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
def method():
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
pass
|
||||
|
||||
self.assertRaises(BrokenImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_class_has_required_method_simple(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
def method():
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_class_doesnt_have_required_method_derived(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenImplementation
|
||||
|
||||
class IBase(Interface):
|
||||
def method():
|
||||
pass
|
||||
|
||||
class IDerived(IBase):
|
||||
pass
|
||||
|
||||
@implementer(IDerived)
|
||||
class Current(object):
|
||||
pass
|
||||
|
||||
self.assertRaises(BrokenImplementation,
|
||||
self._callFUT, IDerived, Current)
|
||||
|
||||
def test_class_has_required_method_derived(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class IBase(Interface):
|
||||
def method():
|
||||
pass
|
||||
|
||||
class IDerived(IBase):
|
||||
pass
|
||||
|
||||
@implementer(IDerived)
|
||||
class Current(object):
|
||||
|
||||
def method(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(IDerived, Current)
|
||||
|
||||
def test_method_takes_wrong_arg_names_but_OK(self):
|
||||
# We no longer require names to match.
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, b):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_not_enough_args(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_doesnt_take_required_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(*args):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_doesnt_take_required_only_kwargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(**kw):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_takes_extra_arg(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, a, b):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_takes_extra_arg_with_default(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, a, b=None):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_only_positional_args(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, *args):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_only_kwargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, **kw):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_takes_extra_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, a, *args):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_extra_starargs_and_kwargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, a, *args, **kw):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_doesnt_take_required_positional_and_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a, *args):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, a):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_takes_required_positional_and_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a, *args):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, a, *args):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_only_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a, *args):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, *args):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_required_kwargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(**kwargs):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, **kw):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_positional_plus_required_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(*args):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, a, *args):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
|
||||
def test_method_doesnt_take_required_kwargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(**kwargs):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
def method(self, a):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
|
||||
def test_class_has_method_for_iface_attr(self):
|
||||
from zope.interface import Attribute
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
attr = Attribute("The foo Attribute")
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def attr(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_class_has_nonmethod_for_method(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
def method():
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
method = 1
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_class_has_attribute_for_attribute(self):
|
||||
from zope.interface import Attribute
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
attr = Attribute("The foo Attribute")
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
attr = 1
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_class_misses_attribute_for_attribute(self):
|
||||
# This check *passes* for verifyClass
|
||||
from zope.interface import Attribute
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
attr = Attribute("The foo Attribute")
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
pass
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_w_callable_non_func_method(self):
|
||||
from zope.interface.interface import Method
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class QuasiMethod(Method):
|
||||
def __call__(self, *args, **kw):
|
||||
raise NotImplementedError()
|
||||
|
||||
class QuasiCallable(object):
|
||||
def __call__(self, *args, **kw):
|
||||
raise NotImplementedError()
|
||||
|
||||
class ICurrent(Interface):
|
||||
attr = QuasiMethod('This is callable')
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
attr = QuasiCallable()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
|
||||
def test_w_decorated_method(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
def decorator(func):
|
||||
# this is, in fact, zope.proxy.non_overridable
|
||||
return property(lambda self: func.__get__(self))
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
pass
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current(object):
|
||||
|
||||
@decorator
|
||||
def method(self, a):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_dict_IFullMapping(self):
|
||||
# A dict should be an IFullMapping, but this exposes two
|
||||
# issues. First, on CPython, methods of builtin types are
|
||||
# "method_descriptor" objects, and are harder to introspect.
|
||||
# Second, on PyPy, the signatures can be just plain wrong,
|
||||
# specifying as required arguments that are actually optional.
|
||||
# See https://github.com/zopefoundation/zope.interface/issues/118
|
||||
from zope.interface.common.mapping import IFullMapping
|
||||
self._callFUT(IFullMapping, dict, tentative=True)
|
||||
|
||||
def test_list_ISequence(self):
|
||||
# As for test_dict_IFullMapping
|
||||
from zope.interface.common.sequence import ISequence
|
||||
self._callFUT(ISequence, list, tentative=True)
|
||||
|
||||
def test_tuple_IReadSequence(self):
|
||||
# As for test_dict_IFullMapping
|
||||
from zope.interface.common.sequence import IReadSequence
|
||||
self._callFUT(IReadSequence, tuple, tentative=True)
|
||||
|
||||
|
||||
def test_multiple_invalid(self):
|
||||
from zope.interface.exceptions import MultipleInvalid
|
||||
from zope.interface.exceptions import DoesNotImplement
|
||||
from zope.interface.exceptions import BrokenImplementation
|
||||
from zope.interface import Interface
|
||||
from zope.interface import classImplements
|
||||
|
||||
class ISeveralMethods(Interface):
|
||||
def meth1(arg1):
|
||||
"Method 1"
|
||||
def meth2(arg1):
|
||||
"Method 2"
|
||||
|
||||
class SeveralMethods(object):
|
||||
pass
|
||||
|
||||
with self.assertRaises(MultipleInvalid) as exc:
|
||||
self._callFUT(ISeveralMethods, SeveralMethods)
|
||||
|
||||
ex = exc.exception
|
||||
self.assertEqual(3, len(ex.exceptions))
|
||||
self.assertIsInstance(ex.exceptions[0], DoesNotImplement)
|
||||
self.assertIsInstance(ex.exceptions[1], BrokenImplementation)
|
||||
self.assertIsInstance(ex.exceptions[2], BrokenImplementation)
|
||||
|
||||
# If everything else is correct, only the single error is raised without
|
||||
# the wrapper.
|
||||
classImplements(SeveralMethods, ISeveralMethods)
|
||||
SeveralMethods.meth1 = lambda self, arg1: "Hi"
|
||||
|
||||
with self.assertRaises(BrokenImplementation):
|
||||
self._callFUT(ISeveralMethods, SeveralMethods)
|
||||
|
||||
class Test_verifyObject(Test_verifyClass):
|
||||
|
||||
@classmethod
|
||||
def _get_FUT(cls):
|
||||
from zope.interface.verify import verifyObject
|
||||
return verifyObject
|
||||
|
||||
def _adjust_object_before_verify(self, target):
|
||||
if isinstance(target, (type, type(OldSkool))):
|
||||
target = target()
|
||||
return target
|
||||
|
||||
def test_class_misses_attribute_for_attribute(self):
|
||||
# This check *fails* for verifyObject
|
||||
from zope.interface import Attribute
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
attr = Attribute("The foo Attribute")
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
pass
|
||||
|
||||
self.assertRaises(BrokenImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_module_hit(self):
|
||||
from zope.interface.tests.idummy import IDummyModule
|
||||
from zope.interface.tests import dummy
|
||||
|
||||
self._callFUT(IDummyModule, dummy)
|
||||
|
||||
def test_module_miss(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface.tests import dummy
|
||||
from zope.interface.exceptions import DoesNotImplement
|
||||
|
||||
# same name, different object
|
||||
class IDummyModule(Interface):
|
||||
pass
|
||||
|
||||
self.assertRaises(DoesNotImplement,
|
||||
self._callFUT, IDummyModule, dummy)
|
||||
|
||||
def test_staticmethod_hit_on_class(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import provider
|
||||
from zope.interface.verify import verifyObject
|
||||
|
||||
class IFoo(Interface):
|
||||
|
||||
def bar(a, b):
|
||||
"The bar method"
|
||||
|
||||
@provider(IFoo)
|
||||
class Foo(object):
|
||||
|
||||
@staticmethod
|
||||
def bar(a, b):
|
||||
raise AssertionError("We're never actually called")
|
||||
|
||||
# Don't use self._callFUT, we don't want to instantiate the
|
||||
# class.
|
||||
verifyObject(IFoo, Foo)
|
||||
|
||||
class OldSkool:
|
||||
pass
|
||||
Loading…
Add table
Add a link
Reference in a new issue