[Zodb-checkins] CVS: Zope3/src/zope/interface -
_zope_interface_coptimizations.c:1.3 declarations.py:1.19
Jim Fulton
jim at zope.com
Wed Jan 21 16:58:49 EST 2004
Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv21701/src/zope/interface
Modified Files:
_zope_interface_coptimizations.c declarations.py
Log Message:
Changed the way providedBy worked to fix a bug in handling old-style
extension classes.
Note that the test is actually in Packages3/Interfaces, the facade
that emulated Z2 interfaces using Z3 interfaces. It was easier
to write the test there, because I could actually write it using
extension class. :) My attempts at simulating EC failed and are too
hard to understand, at least today.
=== Zope3/src/zope/interface/_zope_interface_coptimizations.c 1.2 => 1.3 ===
--- Zope3/src/zope/interface/_zope_interface_coptimizations.c:1.2 Fri Nov 21 12:11:43 2003
+++ Zope3/src/zope/interface/_zope_interface_coptimizations.c Wed Jan 21 16:58:47 2004
@@ -169,23 +169,68 @@
static PyObject *
providedBy(PyObject *ignored, PyObject *ob)
{
- PyObject *result;
+ PyObject *result, *cls, *cp;
result = PyObject_GetAttr(ob, str__providedBy__);
- if (result != NULL)
+ if (result == NULL)
{
- /* We want to make sure we have a spec. We can't do a type check
- because we may have a proxy, so we'll just try to get the
- only attribute.
+ PyErr_Clear();
+ return getObjectSpecification(NULL, ob);
+ }
+
+
+ /* We want to make sure we have a spec. We can't do a type check
+ because we may have a proxy, so we'll just try to get the
+ only attribute.
+ */
+ if (PyObject_HasAttr(result, strextends))
+ return result;
+
+ /*
+ The object's class doesn't understand descriptors.
+ Sigh. We need to get an object descriptor, but we have to be
+ careful. We want to use the instance's __provides__,l if
+ there is one, but only if it didn't come from the class.
+ */
+ Py_DECREF(result);
+
+ cls = PyObject_GetAttr(ob, str__class__);
+ if (cls == NULL)
+ return NULL;
+
+ result = PyObject_GetAttr(ob, str__provides__);
+ if (result == NULL)
+ {
+ /* No __provides__, so just fall back to implementedBy */
+ PyErr_Clear();
+ result = implementedBy(NULL, cls);
+ Py_DECREF(cls);
+ return result;
+ }
+
+ cp = PyObject_GetAttr(cls, str__provides__);
+ if (cp == NULL)
+ {
+ /* The the class has no provides, assume we're done: */
+ PyErr_Clear();
+ Py_DECREF(cls);
+ return result;
+ }
+
+ if (cp == result)
+ {
+ /*
+ Oops, we got the provides from the class. This means
+ the object doesn't have it's own. We should use implementedBy
*/
- if (PyObject_HasAttr(result, strextends))
- return result;
Py_DECREF(result);
+ result = implementedBy(NULL, cls);
}
- PyErr_Clear();
+ Py_DECREF(cls);
+ Py_DECREF(cp);
- return getObjectSpecification(NULL, ob);
+ return result;
}
static PyObject *
=== Zope3/src/zope/interface/declarations.py 1.18 => 1.19 ===
--- Zope3/src/zope/interface/declarations.py:1.18 Fri Nov 21 12:11:43 2003
+++ Zope3/src/zope/interface/declarations.py Wed Jan 21 16:58:47 2004
@@ -1138,9 +1138,15 @@
# Here we have either a special object, an old-style declaration
# or a descriptor
+ # Try to get __providedBy__
try:
r = ob.__providedBy__
+ except AttributeError:
+ # Not set yet. Fall back to lower-level thing that computes it
+ return getObjectSpecification(ob)
+
+ try:
# We might have gotten a descriptor from an instance of a
# class (like an ExtensionClass) that doesn't support
# descriptors. We'll make sure we got one by trying to get
@@ -1148,8 +1154,33 @@
r.extends
except AttributeError:
- # No descriptor, so fall back to a plain object spec
- r = getObjectSpecification(ob)
+
+ # The object's class doesn't understand descriptors.
+ # Sigh. We need to get an object descriptor, but we have to be
+ # careful. We want to use the instance's __provides__,l if
+ # there is one, but only if it didn't come from the class.
+
+ try:
+ r = ob.__provides__
+ except AttributeError:
+ # No __provides__, so just fall back to implementedBy
+ return implementedBy(ob.__class__)
+
+ # We need to make sure we got the __provides__ from the
+ # instance. We'll do this by making sure we don't get the same
+ # thing from the class:
+
+ try:
+ cp = ob.__class__.__provides__
+ except AttributeError:
+ # The ob doesn't have a class or the class has no
+ # provides, assume we're done:
+ return r
+
+ if r is cp:
+ # Oops, we got the provides from the class. This means
+ # the object doesn't have it's own. We should use implementedBy
+ return implementedBy(ob.__class__)
return r
More information about the Zodb-checkins
mailing list