[Zope3-checkins] CVS: Zope3/src/zope/interface - _zope_interface_ospec.c:1.6 declarations.py:1.9
Jim Fulton
jim@zope.com
Sat, 31 May 2003 18:12:18 -0400
Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv21784/src/zope/interface
Modified Files:
_zope_interface_ospec.c declarations.py
Log Message:
Refactored the way object specifications get created to make it easier
to create nested object specifications, to support things like
wrapper-object specifications.
Moved some more code to C.
=== Zope3/src/zope/interface/_zope_interface_ospec.c 1.5 => 1.6 === (485/585 lines abridged)
--- Zope3/src/zope/interface/_zope_interface_ospec.c:1.5 Wed May 28 12:44:59 2003
+++ Zope3/src/zope/interface/_zope_interface_ospec.c Sat May 31 18:12:17 2003
@@ -17,8 +17,10 @@
#include "structmember.h"
static PyObject *str___provides__, *str___implements__, *str___class__;
-static PyObject *str___dict__, *str___signature__;
+static PyObject *str___dict__, *str___signature__, *str_flattened;
static PyObject *_implements_reg, *classImplements, *proxySig, *oldSpecSig;
+static PyObject *combinedSpec, *str_extends, *declarations;
+static PyObject *str___providedBy__, *str_only;
#define TYPE(O) ((PyTypeObject*)(O))
#define OBJECT(O) ((PyObject*)(O))
@@ -67,7 +69,9 @@
/* tp_getattro */ (getattrofunc)0,
/* tp_setattro */ (setattrofunc)0,
/* tp_as_buffer */ 0,
- /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /* tp_flags */ Py_TPFLAGS_DEFAULT
+ | Py_TPFLAGS_BASETYPE
+ ,
/* tp_doc */ ISBtype__doc__,
/* tp_traverse */ (traverseproc)0,
/* tp_clear */ (inquiry)0,
@@ -90,42 +94,58 @@
typedef struct {
PyObject_HEAD
- PyObject *ob;
+ PyObject *provides;
+ PyObject *cls;
+ PyObject *spec;
} OSpec;
+static PyTypeObject OSpecType;
+
static int
OSpec_init(OSpec *self, PyObject *args, PyObject *kwds)
{
- static char *kwlist[] = {"ob", NULL};
- PyObject *ob;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist,
- &ob))
- return 0;
+ static char *kwlist[] = {"provides", "cls", NULL};
+ PyObject *provides, *cls;
- Py_INCREF(ob);
[-=- -=- -=- 485 lines omitted -=- -=- -=-]
- oldSpecSig = PyObject_GetAttrString(module, "oldSpecSig");
+ oldSpecSig = PyObject_GetAttrString(declarations, "oldSpecSig");
if (oldSpecSig == NULL)
return;
- Py_DECREF(module);
+ combinedSpec = PyObject_GetAttrString(declarations, "combinedSpec");
+ if (combinedSpec == NULL)
+ return;
- OSpecType.tp_new = PyType_GenericNew;
- ISBType.tp_new = PyType_GenericNew;
/* Initialize types: */
+
+ ISBType.tp_new = PyType_GenericNew;
if (PyType_Ready(&ISBType) < 0)
return;
+
+
+ OSpecType.tp_new = PyType_GenericNew;
+ OSpecType.tp_free = _PyObject_GC_Del;
if (PyType_Ready(&OSpecType) < 0)
return;
+ if (OSpecType.tp_dict &&
+ PyMapping_SetItemString(OSpecType.tp_dict, "only", Py_True) < 0
+ )
+ return;
+
+
+ OSpecDescrType.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&OSpecDescrType) < 0)
+ return;
/* Create the module and add the functions */
@@ -445,8 +707,11 @@
if (PyModule_AddObject(module, "InterfaceSpecificationBase",
(PyObject *)&ISBType) < 0)
return;
- if (PyModule_AddObject(module, "ObjectSpecificationBase",
+ if (PyModule_AddObject(module, "ObjectSpecification",
(PyObject *)&OSpecType) < 0)
+ return;
+ if (PyModule_AddObject(module, "ObjectSpecificationDescriptor",
+ (PyObject *)&OSpecDescrType) < 0)
return;
if (PyModule_AddObject(module, "_implements_reg", _implements_reg) < 0)
return;
=== Zope3/src/zope/interface/declarations.py 1.8 => 1.9 === (520/620 lines abridged)
--- Zope3/src/zope/interface/declarations.py:1.8 Wed May 21 13:26:39 2003
+++ Zope3/src/zope/interface/declarations.py Sat May 31 18:12:17 2003
@@ -146,63 +146,137 @@
return implements.__signature__
# This is overridden by _zope_interface_ospec.
-class ObjectSpecificationBase:
- __slots__ = ['ob']
+def combinedSpec(provides, cls):
+ if provides is not None:
+ result = [provides]
+ else:
+ result = []
+
+ _gatherSpecs(cls, result)
- def __init__(self, ob):
- self.ob = ob
+ return InterfaceSpecification(*result)
+
+class ObjectSpecification_py:
+ """Provide object specifications
+
+ These combine information for the object and for it's classes.
+
+ For example::
+
+ >>> from zope.interface import Interface
+ >>> 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 A: implements(I1)
+ ...
+ >>> class B: __implements__ = I2
+ ...
+ >>> class C(A, B): implements(I31)
+ ...
+ >>> c = C()
+ >>> directlyProvides(c, I4)
+ >>> [i.__name__ for i in providedBy(c)]
[-=- -=- -=- 520 lines omitted -=- -=- -=-]
+ for c in mro:
+ pb = c.__dict__.get("__providedBy__", c)
+ if pb is not c:
+ break
+ else: # no break
+ pb = None
+
+ if not isinstance(pb, ObjectSpecificationDescriptor):
+ raise TypeError(
+ cls,
+ "has a __providedBy__ descriptor of the wrong type",
+ pb)
- """
- try:
- # catch bad spec by seeing if we can iterate over it
- ispecs = iter(specs)
- except TypeError:
- # Must be a bad spec
- raise exceptions.BadImplements(specs)
+ if "__providedBy__" not in cls.__dict__:
+ cls.__providedBy__ = pb
- for spec in ispecs:
- # We do this rather than isinstance because it works w proxies classes
- if InterfaceClass in spec.__class__.__mro__:
- if spec not in result:
- result.append(spec)
- elif spec is specs:
- # Try to avoid an infinate loop by getting a string!
- raise TypeError("Bad interface specification", spec)
- else:
- _flattenSpecs(spec, result)
+ else:
+ _implements_reg[cls] = v
- return result
+ v.setClass(cls)
def _getmro(C, r):
if C not in r: r.append(C)
@@ -1310,8 +1376,6 @@
_gatherSpecs(b, result)
return result
-
-_empty = InterfaceSpecification()
# DocTest: