diff options
| author | Wolfgang Schnerring <wosc@wosc.de> | 2009-12-08 08:29:06 +0000 |
|---|---|---|
| committer | Wolfgang Schnerring <wosc@wosc.de> | 2009-12-08 08:29:06 +0000 |
| commit | b32c2b903da738387a5b29b3f5049362cdc8dec2 (patch) | |
| tree | 6607151c45f20e8a38113abb284e884e83003a9e | |
| parent | 20af1ea9ef24a918389cdbfd5e4392caef44fe93 (diff) | |
| download | zope-interface-b32c2b903da738387a5b29b3f5049362cdc8dec2.tar.gz | |
Fix an edge case: make providedBy() work when a class has '__provides__' in
its __slots__ (see http://thread.gmane.org/gmane.comp.web.zope.devel/22490)
| -rw-r--r-- | CHANGES.txt | 3 | ||||
| -rw-r--r-- | src/zope/interface/_zope_interface_coptimizations.c | 2 | ||||
| -rw-r--r-- | src/zope/interface/declarations.py | 4 | ||||
| -rw-r--r-- | src/zope/interface/tests/test_declarations.py | 17 |
4 files changed, 23 insertions, 3 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 59943a9..31d0202 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,7 +5,8 @@ CHANGES 3.5.3 (unreleased) ================== -... +- Fix an edge case: make providedBy() work when a class has '__provides__' in + its __slots__ (see http://thread.gmane.org/gmane.comp.web.zope.devel/22490) ================== diff --git a/src/zope/interface/_zope_interface_coptimizations.c b/src/zope/interface/_zope_interface_coptimizations.c index a6ef2dc..7eaf219 100644 --- a/src/zope/interface/_zope_interface_coptimizations.c +++ b/src/zope/interface/_zope_interface_coptimizations.c @@ -149,7 +149,7 @@ getObjectSpecification(PyObject *ignored, PyObject *ob) PyObject *cls, *result; result = PyObject_GetAttr(ob, str__provides__); - if (result != NULL) + if (result != NULL && PyObject_TypeCheck(result, &SpecType)) return result; PyErr_Clear(); diff --git a/src/zope/interface/declarations.py b/src/zope/interface/declarations.py index 3bc28a7..44a40e2 100644 --- a/src/zope/interface/declarations.py +++ b/src/zope/interface/declarations.py @@ -31,6 +31,7 @@ __docformat__ = 'restructuredtext' import sys import weakref from zope.interface.interface import InterfaceClass, Specification +from zope.interface.interface import SpecificationBase from ro import mergeOrderings, ro import exceptions from types import ClassType, ModuleType @@ -1248,7 +1249,8 @@ def getObjectSpecification(ob): provides = getattr(ob, '__provides__', None) if provides is not None: - return provides + if isinstance(provides, SpecificationBase): + return provides try: cls = ob.__class__ diff --git a/src/zope/interface/tests/test_declarations.py b/src/zope/interface/tests/test_declarations.py index 8831009..de09f1c 100644 --- a/src/zope/interface/tests/test_declarations.py +++ b/src/zope/interface/tests/test_declarations.py @@ -402,6 +402,23 @@ def test_picklability_of_implements_specifications(): """ +def test_provided_by_with_slots(): + """ + + This is an edge case: if the __slots__ of a class contain '__provides__', + using providedBy() on that class should still work (this occurs, for + example, when providing an adapter for a concrete class.) + + >>> import zope.interface + >>> class Slotted(object): + ... __slots__ = ('__provides__') + >>> class IFoo(zope.interface.Interface): + ... pass + >>> IFoo.providedBy(Slotted) + False + + """ + def test_suite(): suite = unittest.TestSuite() |
