summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/zope/interface/_zope_interface_coptimizations.c2
-rw-r--r--src/zope/interface/declarations.py4
-rw-r--r--src/zope/interface/tests/test_declarations.py17
3 files changed, 21 insertions, 2 deletions
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()