[Zope-Checkins] CVS: Zope/lib/python/ExtensionClass -
tests.py:1.1.2.1 ExtensionClass.h:1.1.2.2
_ExtensionClass.c:1.1.2.2 __init__.py:1.1.2.2 setup.py:1.1.2.2
Jim Fulton
cvs-admin at zope.org
Thu Oct 23 09:03:36 EDT 2003
Update of /cvs-repository/Zope/lib/python/ExtensionClass
In directory cvs.zope.org:/tmp/cvs-serv17283/lib/python/ExtensionClass
Modified Files:
Tag: zodb33-devel-branch
ExtensionClass.h _ExtensionClass.c __init__.py setup.py
Added Files:
Tag: zodb33-devel-branch
tests.py
Log Message:
Updated substantially in the course of getting Acquisition, Missing,
and MethodObject.
=== Added File Zope/lib/python/ExtensionClass/tests.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""
$Id: tests.py,v 1.1.2.1 2003/10/23 13:03:04 jim Exp $
"""
from doctest import DocTestSuite
import unittest
def test_basic():
"""
>>> from ExtensionClass import *
Test creating basic classes and objects and test that class_init is called
>>> class C(Base):
... def __class_init__(self):
... print 'class init called'
... print self.__name__
... def bar(self): pass
...
class init called
C
>>> c = C()
>>> int(c.__class__ is C)
1
>>> int(c.__class__ is type(c))
1
Test that __of__ works
>>> class O(Base):
... def __of__(*a):
... return a
...
>>> o1 = O()
>>> o2 = O()
>>> C.o1 = o1
>>> c.o2 = o2
>>> int(c.o1 == (o1, c))
1
>>> int(c.o2 == (o2, c))
1
Test inherited attribute:
>>> class O2(O):
... def __of__(*a):
... return O2.inheritedAttribute('__of__')(*a), 42
...
>>> o2 = O2()
>>> c.o2 = o2
>>> int(c.o2 == ((o2, c), 42))
1
Test working with a classic class
>>> class Classic:
... def x(self):
... return 42
...
>>> class O2(Classic, O):
... def __of__(*a):
... return (O2.inheritedAttribute('__of__')(*a),
... O2.inheritedAttribute('x')(a[0]))
...
>>> o2 = O2()
>>> c.o2 = o2
>>> int(c.o2 == ((o2, c), 42))
1
Test working with a ew style
>>> class Modern(object):
... def x(self):
... return 42
...
>>> class O2(Modern, O):
... def __of__(*a):
... return (O2.inheritedAttribute('__of__')(*a),
... O2.inheritedAttribute('x')(a[0]))
...
>>> o2 = O2()
>>> c.o2 = o2
>>> int(c.o2 == ((o2, c), 42))
1
"""
def test_class_creation_under_stress():
"""
>>> from ExtensionClass import Base
>>> for i in range(100):
... class B(Base):
... print i,
... if i and i%20 == 0:
... print
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
>>> import gc
>>> x = gc.collect()
"""
def old_test_add():
"""test_add.py from old EC
>>> from ExtensionClass import Base
>>> class foo(Base):
... def __add__(self,other): print 'add called'
>>> foo()+foo()
add called
"""
def proper_error_on_deleattr():
"""
Florent Guillaume wrote:
...
Excellent.
Will it also fix this particularity of ExtensionClass:
>>> from ExtensionClass import Base
>>> class A(Base):
... def foo(self):
... self.gee
... def bar(self):
... del self.gee
>>> a=A()
>>> a.foo()
Traceback (most recent call last):
...
AttributeError: gee
>>> a.bar()
Traceback (most recent call last):
...
AttributeError: 'A' object has no attribute 'gee'
I.e., the fact that KeyError is raised whereas a normal class would
raise AttributeError.
"""
def test_suite():
return DocTestSuite()
if __name__ == '__main__': unittest.main()
=== Zope/lib/python/ExtensionClass/ExtensionClass.h 1.1.2.1 => 1.1.2.2 ===
--- Zope/lib/python/ExtensionClass/ExtensionClass.h:1.1.2.1 Sun Oct 19 17:25:41 2003
+++ Zope/lib/python/ExtensionClass/ExtensionClass.h Thu Oct 23 09:03:04 2003
@@ -74,18 +74,6 @@
class library. The macro 'PyExtensionClass_Export' imports the
'ExtensionClass' module and uses objects imported from this module
to initialize an extension class with necessary behavior.
-
- If you have questions regarding this software,
- contact:
-
-
- If you have questions regarding this software,
- contact:
-
- Digital Creations L.C.
- info at digicool.com
-
- (540) 371-6909
*/
@@ -97,41 +85,156 @@
/* Declarations for objects of type ExtensionClass */
+#define EC PyTypeObject
+#define PyExtensionClass PyTypeObject
+
typedef struct {
- PyHeapTypeObject tp;
- long class_flags;
-} PyExtensionClass;
+ PyObject_HEAD
+} _emptyobject;
-#define EC PyExtensionClass
+static struct ExtensionClassCAPIstruct {
+ PyObject *(*EC_findiattrs_)(PyObject *self, char *cname);
+ int (*PyExtensionClass_Export_)(PyObject *dict, char *name,
+ PyTypeObject *typ);
+ PyObject *(*PyECMethod_New_)(PyObject *callable, PyObject *inst);
+ PyExtensionClass *ECBaseType_;
+ PyExtensionClass *ECExtensionClassType_;
+} *PyExtensionClassCAPI = NULL;
+
+#define ECBaseType (PyExtensionClassCAPI->ECBaseType_)
+#define ECExtensionClassType (PyExtensionClassCAPI->ECExtensionClassType_)
+
+/* Following are macros that are needed or useful for defining extension
+ classes:
+ */
+
+/* This macro redefines Py_FindMethod to do attribute for an attribute
+ name given by a C string lookup using extension class meta-data.
+ This is used by older getattr implementations.
+
+ This macro is used in base class implementations of tp_getattr to
+ lookup methods or attributes that are not managed by the base type
+ directly. The macro is generally used to search for attributes
+ after other attribute searches have failed.
+
+ Note that in Python 1.4, a getattr operation may be provided that
+ uses an object argument. Classes that support this new operation
+ should use Py_FindAttr.
+ */
+
+#define EC_findiattrs(O, N) PyExtensionClassCAPI->EC_findiattrs_((O),(N))
+
+#define Py_FindMethod(M,SELF,NAME) (EC_findiattrs((SELF),(NAME)))
+
+/* Do method or attribute lookup for an attribute name given by a C
+ string using extension class meta-data.
+
+ This macro is used in base class implementations of tp_getattro to
+ lookup methods or attributes that are not managed by the base type
+ directly. The macro is generally used to search for attributes
+ after other attribute searches have failed.
+
+ Note that in Python 1.4, a getattr operation may be provided that
+ uses an object argument. Classes that support this new operation
+ should use Py_FindAttr.
+ */
+#define Py_FindAttrString(SELF,NAME) (EC_findiattrs((SELF),(NAME)))
+
+/* Do method or attribute lookup using extension class meta-data.
+
+ This macro is used in base class implementations of tp_getattr to
+ lookup methods or attributes that are not managed by the base type
+ directly. The macro is generally used to search for attributes
+ after other attribute searches have failed. */
+#define Py_FindAttr(SELF,NAME) (ECBaseType->tp_getattro(SELF, NAME))
+
+/* Do attribute assignment for an attribute.
+
+ This macro is used in base class implementations of tp_setattro to
+ set attributes that are not managed by the base type directly. The
+ macro is generally used to assign attributes after other attribute
+ attempts to assign attributes have failed.
+ */
+#define PyEC_SetAttr(SELF,NAME,V) (ECBaseType->tp_setattro(SELF, NAME, V))
- /* The following flags are used by ExtensionClass */
-#define EXTENSIONCLASS_DYNAMIC_FLAG 1 << 0
#define EXTENSIONCLASS_BINDABLE_FLAG 1 << 2
-#define EXTENSIONCLASS_METHODHOOK_FLAG 1 << 3
-#define EXTENSIONCLASS_INSTDICT_FLAG 1 << 4
-#define EXTENSIONCLASS_NOINSTDICT_FLAG 1 << 5
-#define EXTENSIONCLASS_BASICNEW_FLAG 1 << 6
-#define EXTENSIONCLASS_PYTHONICATTR_FLAG 1 << 7
-#define EXTENSIONCLASS_USERGETATTR_FLAG 1 << 8
-#define EXTENSIONCLASS_USERSETATTR_FLAG 1 << 9
-#define EXTENSIONCLASS_USERDELATTR_FLAG 1 << 10
-
- /* The following flags are for use by extension class developers. */
-#define EXTENSIONCLASS_USER_FLAG1 1 << 16
-#define EXTENSIONCLASS_USER_FLAG2 1 << 17
-#define EXTENSIONCLASS_USER_FLAG3 1 << 18
-#define EXTENSIONCLASS_USER_FLAG4 1 << 19
-#define EXTENSIONCLASS_USER_FLAG5 1 << 20
-#define EXTENSIONCLASS_USER_FLAG6 1 << 21
-#define EXTENSIONCLASS_USER_FLAG7 1 << 22
-#define EXTENSIONCLASS_USER_FLAG8 1 << 23
-#define EXTENSIONCLASS_USER_FLAG9 1 << 24
-#define EXTENSIONCLASS_USER_FLAG10 1 << 25
-#define EXTENSIONCLASS_USER_FLAG11 1 << 26
-#define EXTENSIONCLASS_USER_FLAG12 1 << 27
-#define EXTENSIONCLASS_USER_FLAG13 1 << 28
-#define EXTENSIONCLASS_USER_FLAG14 1 << 29
-#define EXTENSIONCLASS_USER_FLAG15 1 << 30
-#define EXTENSIONCLASS_USER_FLAG16 1 << 31
+
+
+
+/* Convert a method list to a method chain. */
+#define METHOD_CHAIN(DEF) (traverseproc)(DEF)
+
+/* The following macro checks whether a type is an extension class: */
+#define PyExtensionClass_Check(TYPE) \
+ ((PyObject*)(TYPE)->ob_type == ECExtensionClassType)
+
+/* The following macro checks whether an instance is an extension instance: */
+#define PyExtensionInstance_Check(INST) \
+ (((PyObject*)(INST))->ob_type->ob_type == ECExtensionClassType)
+
+#define CHECK_FOR_ERRORS(MESS)
+
+/* The following macro can be used to define an extension base class
+ that only provides method and that is used as a pure mix-in class. */
+#define PURE_MIXIN_CLASS(NAME,DOC,METHODS) \
+static PyExtensionClass NAME ## Type = { PyObject_HEAD_INIT(NULL) 0, # NAME, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0 , DOC, (traverseproc)METHODS, }
+
+/* The following macros provide limited access to extension-class
+ method facilities. */
+
+/* Test for an ExtensionClass method: */
+#define PyECMethod_Check(O) PyMethod_Check((O))
+
+/* Create a method object that wraps a callable object and an
+ instance. Note that if the callable object is an extension class
+ method, then the new method will wrap the callable object that is
+ wrapped by the extension class method. Also note that if the
+ callable object is an extension class method with a reference
+ count of 1, then the callable object will be rebound to the
+ instance and returned with an incremented reference count.
+ */
+#define PyECMethod_New(CALLABLE, INST) \
+ PyExtensionClassCAPI->PyECMethod_New_((CALLABLE),(INST))
+
+/* Return the instance that is bound by an extension class method. */
+#define PyECMethod_Self(M) \
+(PyMethod_Check((M)) ? ((PyMethodObject*)(M))->im_self : NULL)
+
+/* Check whether an object has an __of__ method for returning itself
+ in the context of it's container. */
+#define has__of__(O) ((O)->ob_type->ob_type == ECExtensionClassType \
+ && (O)->ob_type->tp_descr_get != NULL)
+
+/* The following macros are used to check whether an instance
+ or a class' instanses have instance dictionaries: */
+#define HasInstDict(O) (_PyObject_GetDictPtr(O) != NULL)
+
+#define ClassHasInstDict(C) ((C)->tp_dictoffset > 0))
+
+/* Get an object's instance dictionary. Use with caution */
+#define INSTANCE_DICT(inst) (_PyObject_GetDictPtr(O))
+
+/* Test whether an ExtensionClass, S, is a subclass of ExtensionClass C. */
+#define ExtensionClassSubclass_Check(S,C) PyType_IsSubtype((S), (C))
+
+/* Test whether an ExtensionClass instance , I, is a subclass of
+ ExtensionClass C. */
+#define ExtensionClassSubclassInstance_Check(I,C) PyObject_TypeCheck((I), (C))
+
+
+/* Export an Extension Base class in a given module dictionary with a
+ given name and ExtensionClass structure.
+ */
+
+#define PyExtensionClass_Export(D,N,T) \
+ if (! ExtensionClassImported || \
+ PyExtensionClassCAPI->PyExtensionClass_Export_((D),(N),&(T)) < 0) return;
+
+
+#define ExtensionClassImported \
+ ((PyExtensionClassCAPI != NULL) || \
+ (PyExtensionClassCAPI = PyCObject_Import("ExtensionClass","CAPI2")))
#endif /* EXTENSIONCLASS_H */
=== Zope/lib/python/ExtensionClass/_ExtensionClass.c 1.1.2.1 => 1.1.2.2 ===
--- Zope/lib/python/ExtensionClass/_ExtensionClass.c:1.1.2.1 Sun Oct 19 17:25:41 2003
+++ Zope/lib/python/ExtensionClass/_ExtensionClass.c Thu Oct 23 09:03:04 2003
@@ -19,12 +19,15 @@
#include "ExtensionClass.h"
-static PyObject *str__of__, *str__get__, *str__class_init__;
+#define EC PyTypeObject
+
+static PyObject *str__of__, *str__get__, *str__class_init__, *str__init__;
#define OBJECT(O) ((PyObject *)(O))
#define TYPE(O) ((PyTypeObject *)(O))
extern PyTypeObject ExtensionClassType;
+extern PyTypeObject BaseType;
static PyObject *
of_get(PyObject *self, PyObject *inst, PyObject *cls)
@@ -138,11 +141,10 @@
If the tp_descr_get of res is of_get,
then call it. */
- if (PyType_HasFeature(res->ob_type,
- Py_TPFLAGS_HAVE_CLASS)
- && res->ob_type->tp_descr_get == of_get
- )
- res = of_get(res, obj, NULL);
+ if (res->ob_type->ob_type == &ExtensionClassType
+ && res->ob_type->tp_descr_get != NULL)
+ res = res->ob_type->tp_descr_get(
+ res, obj, OBJECT(&BaseType));
else
Py_INCREF(res);
goto done;
@@ -161,20 +163,13 @@
goto done;
}
- PyErr_Format(PyExc_AttributeError,
- "'%.50s' object has no attribute '%.400s'",
- tp->tp_name, PyString_AS_STRING(name));
+ PyErr_SetObject(PyExc_AttributeError, name);
done:
Py_DECREF(name);
return res;
}
-
-
-
static EC BaseType = {
- {
- {
PyObject_HEAD_INIT(NULL)
/* ob_size */ 0,
/* tp_name */ "ExtensionClass."
@@ -197,18 +192,15 @@
/* tp_setattro */ (setattrofunc)0,
/* tp_as_buffer */ 0,
/* tp_flags */ Py_TPFLAGS_DEFAULT
- | Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_BASETYPE
,
/* tp_doc */ "Standard ExtensionClass base type",
- },
- },
};
static PyObject *
EC_new(PyTypeObject *self, PyObject *args, PyObject *kw)
{
- PyObject *name, *bases=NULL, *dict=NULL, *__class_init__;
+ PyObject *name, *bases=NULL, *dict=NULL;
PyObject *new_bases=NULL, *new_args, *result;
int have_base = 0, i;
@@ -223,19 +215,6 @@
&PyTuple_Type, &bases, &PyDict_Type, &dict))
return NULL;
- /* Handle __class_init__ */
- if (dict)
- {
- __class_init__ = PyDict_GetItem(dict, str__class_init__);
- if (__class_init__)
- { /* Convert to class meth */
- __class_init__ = PyClassMethod_New(__class_init__);
- if (! __class_init__)
- return NULL;
- PyDict_SetItem(dict, str__class_init__, __class_init__);
- }
- }
-
/* Make sure Base is in bases */
if (bases)
{
@@ -320,21 +299,29 @@
/* Call __class_init__ */
__class_init__ = PyObject_GetAttr(OBJECT(self), str__class_init__);
- if (__class_init__)
+ if (__class_init__ == NULL)
{
- r = PyObject_CallFunctionObjArgs(__class_init__, NULL);
- Py_DECREF(__class_init__);
+ PyErr_Clear();
+ return 0;
+ }
- if (r)
- {
- Py_DECREF(r);
- }
- else
- return -1;
+ if (! (PyMethod_Check(__class_init__)
+ && PyMethod_GET_FUNCTION(__class_init__)
+ )
+ )
+ {
+ Py_DECREF(__class_init__);
+ PyErr_SetString(PyExc_TypeError, "Invalid type for __class_init__");
+ return -1;
}
- else
- PyErr_Clear();
+ r = PyObject_CallFunctionObjArgs(PyMethod_GET_FUNCTION(__class_init__),
+ OBJECT(self), NULL);
+ Py_DECREF(__class_init__);
+ if (! r)
+ return -1;
+ Py_DECREF(r);
+
return 0;
}
@@ -367,7 +354,7 @@
/* ob_size */ 0,
/* tp_name */ "ExtensionClass."
"ExtensionClass",
- /* tp_basicsize */ sizeof(EC),
+ /* tp_basicsize */ 0,
/* tp_itemsize */ 0,
/* tp_dealloc */ (destructor)0,
/* tp_print */ (printfunc)0,
@@ -416,7 +403,6 @@
return Py_None;
}
-
/* List of methods defined in the module */
static struct PyMethodDef ec_methods[] = {
@@ -424,13 +410,202 @@
{NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
};
+
+static PyObject *
+EC_findiattrs_(PyObject *self, char *cname)
+{
+ PyObject *name, *r;
+
+ name = PyString_FromString(cname);
+ if (name == NULL)
+ return NULL;
+ r = ECBaseType->tp_getattro(self, name);
+ Py_DECREF(name);
+ return r;
+}
+
+static PyObject *
+ec_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ /* This is for EC's that have deallocs. For these, we need to
+ incref the type when we create an instance, because the deallocs
+ will decref the type.
+ */
+
+ PyObject *r;
+
+ r = PyType_GenericNew(type, args, kw);
+ if (r)
+ {
+ Py_INCREF(type);
+ }
+ return r;
+}
+
+static int
+ec_init(PyObject *self, PyObject *args, PyObject *kw)
+{
+ PyObject *r, *__init__;
+
+ __init__ = PyObject_GetAttr(self, str__init__);
+ if (__init__ == NULL)
+ return -1;
+
+ r = PyObject_Call(__init__, args, kw);
+ Py_DECREF(__init__);
+ if (r == NULL)
+ return -1;
+
+ Py_DECREF(r);
+ return 0;
+}
+
+static int
+PyExtensionClass_Export_(PyObject *dict, char *name, PyTypeObject *typ)
+{
+ int ecflags;
+ PyMethodDef *pure_methods = NULL, *mdef = NULL;
+ PyObject *m;
+
+ if (typ->tp_flags == 0)
+ {
+ /* Old-style EC */
+
+ if (typ->tp_traverse)
+ {
+ /* ExtensionClasses stick there methods in the tp_traverse slot */
+ mdef = (PyMethodDef *)typ->tp_traverse;
+
+ if (typ->tp_basicsize <= sizeof(_emptyobject))
+ /* Pure mixin. We want rebindable methods */
+ pure_methods = mdef;
+ else
+ typ->tp_methods = mdef;
+
+ typ->tp_traverse = NULL;
+
+ /* Look for __init__ method */
+ for (; mdef->ml_name; mdef++)
+ {
+ if (strcmp(mdef->ml_name, "__init__") == 0)
+ {
+ /* we have an old-style __init__, install a special slot */
+ typ->tp_init = ec_init;
+ break;
+ }
+ }
+ }
+
+ if (typ->tp_clear)
+ {
+ /* ExtensionClasses stick there flags in the tp_clear slot */
+ ecflags = (int)(typ->tp_clear);
+
+ /* Some old-style flags were set */
+
+ if ((ecflags & EXTENSIONCLASS_BINDABLE_FLAG)
+ && typ->tp_descr_get == NULL)
+ /* We have __of__-style binding */
+ typ->tp_descr_get = of_get;
+ }
+ typ->tp_clear = NULL;
+ typ->tp_flags = Py_TPFLAGS_DEFAULT
+ | Py_TPFLAGS_BASETYPE;
+
+ if (typ->tp_dealloc != NULL)
+ typ->tp_new = ec_new;
+ }
+
+ typ->ob_type = ECExtensionClassType;
+ typ->tp_base = ECBaseType;
+ if (typ->tp_new == NULL)
+ typ->tp_new = PyType_GenericNew;
+
+ if (PyType_Ready(typ) < 0)
+ return -1;
+
+ if (pure_methods)
+ {
+ /* We had pure methods. We want to be able to rebind these, so
+ we'll make them ordinary method wrappers around method descrs
+ */
+ for (; pure_methods->ml_name; pure_methods++)
+ {
+ m = PyDescr_NewMethod(ECBaseType, pure_methods);
+ if (! m)
+ return -1;
+ m = PyMethod_New((PyObject *)m, NULL, (PyObject *)ECBaseType);
+ if (! m)
+ return -1;
+ if (PyDict_SetItemString(typ->tp_dict, pure_methods->ml_name, m)
+ < 0)
+ return -1;
+ }
+ }
+ else if (mdef && mdef->ml_name)
+ {
+ /* Blast, we have to stick __init__ in the dict ourselves
+ because PyType_Ready probably stuck a wrapper for ec_init in
+ instead.
+ */
+ m = PyDescr_NewMethod(typ, mdef);
+ if (! m)
+ return -1;
+ if (PyDict_SetItemString(typ->tp_dict, mdef->ml_name, m) < 0)
+ return -1;
+ }
+
+ if (PyMapping_SetItemString(dict, name, (PyObject*)typ) < 0)
+ return -1;
+
+ return 0;
+}
+
+PyObject *
+PyECMethod_New_(PyObject *callable, PyObject *inst)
+{
+ if (! PyExtensionInstance_Check(inst))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "Can't bind non-ExtensionClass instance.");
+ return NULL;
+ }
+
+ if (PyMethod_Check(callable))
+ {
+ if (callable->ob_refcnt == 1)
+ {
+ Py_XDECREF(((PyMethodObject*)callable)->im_self);
+ Py_INCREF(inst);
+ ((PyMethodObject*)callable)->im_self = inst;
+ Py_INCREF(callable);
+ return callable;
+ }
+ else
+ return callable->ob_type->tp_descr_get(
+ callable, inst,
+ ((PyMethodObject*)callable)->im_class);
+ }
+ else
+ return PyMethod_New(callable, inst, (PyObject*)(ECBaseType));
+}
+
+static struct ExtensionClassCAPIstruct
+TrueExtensionClassCAPI = {
+ EC_findiattrs_,
+ PyExtensionClass_Export_,
+ PyECMethod_New_,
+ &BaseType,
+ &ExtensionClassType,
+};
+
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
init_ExtensionClass(void)
{
- PyObject *m;
+ PyObject *m, *s;
#define DEFINE_STRING(S) \
if(! (str ## S = PyString_FromString(# S))) return
@@ -438,6 +613,9 @@
DEFINE_STRING(__of__);
DEFINE_STRING(__get__);
DEFINE_STRING(__class_init__);
+ DEFINE_STRING(__init__);
+
+ PyExtensionClassCAPI = &TrueExtensionClassCAPI;
ExtensionClassType.ob_type = &PyType_Type;
ExtensionClassType.tp_base = &PyType_Type;
@@ -449,7 +627,6 @@
return;
- TYPE(&BaseType)->tp_basicsize = PyBaseObject_Type.tp_basicsize;
TYPE(&BaseType)->ob_type = &ExtensionClassType;
TYPE(&BaseType)->tp_base = &PyBaseObject_Type;
TYPE(&BaseType)->tp_new = PyType_GenericNew;
@@ -464,6 +641,9 @@
if (m == NULL)
return;
+ s = PyCObject_FromVoidPtr(PyExtensionClassCAPI, NULL);
+ if (PyModule_AddObject(m, "CAPI2", s) < 0)
+ return;
/* Add types: */
if (PyModule_AddObject(m, "ExtensionClass",
=== Zope/lib/python/ExtensionClass/__init__.py 1.1.2.1 => 1.1.2.2 ===
--- Zope/lib/python/ExtensionClass/__init__.py:1.1.2.1 Sun Oct 19 17:25:41 2003
+++ Zope/lib/python/ExtensionClass/__init__.py Thu Oct 23 09:03:04 2003
@@ -16,4 +16,4 @@
$Id$
"""
-from _ExtensionClass import ExtensionClass, Base
+from _ExtensionClass import *
=== Zope/lib/python/ExtensionClass/setup.py 1.1.2.1 => 1.1.2.2 ===
--- Zope/lib/python/ExtensionClass/setup.py:1.1.2.1 Sun Oct 19 17:25:41 2003
+++ Zope/lib/python/ExtensionClass/setup.py Thu Oct 23 09:03:04 2003
@@ -1,6 +1,8 @@
from distutils.core import setup, Extension
setup(name="ExtensionClass", version="2.0",
ext_modules=[
- Extension("_ExtensionClass", ["_ExtensionClass.c"]),
+ Extension("_ExtensionClass", ["_ExtensionClass.c"],
+ depends = ["ExtensionClass.h"],
+ ),
])
More information about the Zope-Checkins
mailing list