summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Henstridge <james@daa.com.au>2001-09-28 23:43:47 +0000
committerJames Henstridge <jamesh@src.gnome.org>2001-09-28 23:43:47 +0000
commite0ef227e050134d9b0d9397865dd3c5053ba8d8f (patch)
tree1da46f929fc547582755dfc50cde016f04245299
parentc6a29df6dd65bbede61d2253637886789bebda51 (diff)
downloadpygtk-e0ef227e050134d9b0d9397865dd3c5053ba8d8f.tar.gz
use pyg_type_from_object instead. Based on patch from Elliot.
2001-09-29 James Henstridge <james@daa.com.au> * gtk/pygtktreemodel.c (pygtk_tree_model_get_column_type): use pyg_type_from_object instead. Based on patch from Elliot. * gtk/gtk.override (_wrap_gtk_selection_data__get_data): convert getter to a function to match codegen changes. * : merge in python22-branch (see changelog entries below).
-rw-r--r--ChangeLog139
-rw-r--r--ExtensionClass.c3490
-rw-r--r--ExtensionClass.h471
-rw-r--r--ExtensionClass.stx714
-rw-r--r--Makefile.am11
-rw-r--r--codegen/codegen.py223
-rw-r--r--configure.in18
-rw-r--r--gobject/gobjectmodule.c536
-rw-r--r--gobject/pygobject.h17
-rw-r--r--gobjectmodule.c536
-rw-r--r--gtk/__init__.py4
-rw-r--r--gtk/gdk.override114
-rw-r--r--gtk/gtk-types.c4
-rw-r--r--gtk/gtk.override270
-rw-r--r--gtk/libglade.override8
-rw-r--r--gtk/libglademodule.c1
-rw-r--r--gtk/pygtk.h2
-rw-r--r--gtk/pygtktreemodel.c2
-rw-r--r--pango.override15
-rw-r--r--pygobject.h17
20 files changed, 986 insertions, 5606 deletions
diff --git a/ChangeLog b/ChangeLog
index b5404b82..0d8f752a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,142 @@
+2001-09-29 James Henstridge <james@daa.com.au>
+
+ * gtk/pygtktreemodel.c (pygtk_tree_model_get_column_type): use
+ pyg_type_from_object instead. Based on patch from Elliot.
+
+ * gtk/gtk.override (_wrap_gtk_selection_data__get_data): convert
+ getter to a function to match codegen changes.
+
+ * : merge in python22-branch (see changelog entries below).
+
+2001-09-25 James Henstridge <james@daa.com.au>
+
+ * gobjectmodule.c (pygobject_get_dict): getter for __dict__ on
+ GObject wrappers.
+ (PyGObject_Type): include getsets list.
+
+ * codegen/codegen.py (write_getsets): change "struct getsets" to
+ PyGetSetDef to match recent changes in python.
+
+ * gtk/gdk.override (_wrap_gdk_device__get_axes): change to getter.
+ (_wrap_gdk_device__get_keys): turn into a getter.
+ (_wrap_gdk_drag_context__get_targets): same here.
+
+ * gtk/gtk.override (_wrap_gtk_clist__get_selection): turn into a
+ getter.
+ (_wrap_gtk_ctree__get_selection): turn into a getter.
+
+ * codegen/codegen.py (write_getsets): rename to write_getsets, and
+ don't allow overriding the whole routine, as it is implemented as
+ a number of smaller routines now.
+ (gettertmpl): rename from getattrtmpl. Refactor for handling
+ single attribute.
+ (write_getsets): finish conversion over to using getsets.
+ (write_class): call write_getsets instead.
+ (typetmpl): substitute %(getsets)s rather than %(getattr)s.
+
+2001-09-23 James Henstridge <james@daa.com.au>
+
+ * gtk/__init__.py: don't import ExtensionClass.
+
+ * gobjectmodule.c (object_gc_free): new function to free an GC
+ managed object.
+ (PyGObject_Type): use object_gc_free for the tp_free slot.
+
+ * codegen/codegen.py (write_class): don't write getattr routine.
+ This is a temporary hack to see if things work.
+
+ * gobjectmodule.c (pygobject_dealloc): handle case of destruction
+ when self->obj == NULL.
+
+ * gtk/gtk.override (_wrap_gtk_clist_new_with_titles): return an
+ int.
+ (_wrap_gtk_tree_view_get_path_at_pos): same here.
+ (_wrap_gtk_button_new): same here.
+ (_wrap_gtk_toggle_button_new): same here.
+ (_wrap_gtk_check_button_new): same here.
+ (_wrap_gtk_radio_button_new): same here.
+ (_wrap_gtk_list_item_new): same here.
+ (_wrap_gtk_menu_item_new): same here.
+ (_wrap_gtk_check_menu_item_new): same here.
+ (_wrap_gtk_radio_menu_item_new): same here.
+ (_wrap_gtk_ctree_new_with_titles): same here.
+ (_wrap_gtk_dialog_new_with_buttons): same here.
+ (_wrap_gtk_message_dialog_new): same here.
+ (_wrap_gtk_message_dialog_new): same here.
+
+ * gtk/gdk.override (_wrap_gdk_cursor_new): return an int.
+
+ * pango.override (_wrap_pango_font_description_new): constructors
+ return ints.
+
+ * codegen/codegen.py (write_constructor): small hack to convert
+ "return NULL;" to "return -1;" in constructors, as they should
+ return ints.
+ (write_boxed_constructor): same here.
+
+2001-09-22 James Henstridge <james@daa.com.au>
+
+ * gtk/pygtk.h: remove traces of ExtensionClass.
+
+ * gtk/libglade.override: s/PyExtensionClass/PyTypeObject/.
+
+ * gtk/gtk-types.c (_pygtk_register_boxed_types): get rid of
+ mentions of ExtensionClass.
+
+ * gtk/gdk.override: s/PyExtensionClass/PyTypeObject/.
+
+ * gtk/gtk.override: s/PyExtensionClass/PyTypeObject/.
+
+ * gobjectmodule.c (pygobject_traverse): implement a traverse
+ function for PyGObject.
+ (PyGObject_Type): add GC support.
+ (object_free): use PyObject_GC_Del to delete the memory.
+ (pygobject_dealloc): stop GC tracking the object here.
+ (pygobject_register_class): set a few more type fields here.
+ (pygobject_new): use PyObject_GC_New to allocate the object here.
+ (pygobject_dealloc): readd the 1-1 object/wrapper hack. It should
+ work as expected since adding GC support.
+
+ * pango.override: s/PyExtensionClass/PyTypeObject/
+
+ * codegen/codegen.py (consttmpl): constructor template returns an
+ int.
+ (noconstructor): return int rather than PyObject.
+ (typetmpl): change def to be a PyTypeObject, with extra fields.
+ (interfacetypetmpl): same here.
+ (boxedconsttmpl): return int rather than pyobject.
+ (boxedtmpl): change def to PyTypeObject.
+ (write_class): put the constructor in the right place.
+ (write_boxed): put the constructor in the right place.
+ (write_source): don't include ExtensionClass.h, forward declare
+ type objects as PyTypeObjects, rather than PyExtensionClasses.
+
+ * gobjectmodule.c (pygobject_register_class): set type->ob_type.
+ (pyg_register_boxed): same here.
+ (pyg_register_interface): same here.
+ (initgobject): set the ob_type member of PyGInterface_Type and
+ PyGBoxed_Type.
+ (pygobject__gobject_init__): add __gobject_init__ method, that
+ just calls pygobject_init.
+ (pygobject_methods): readd __gobject_init__ method.
+
+2001-09-21 James Henstridge <james@daa.com.au>
+
+ * gobjectmodule.c (pygobject_register_class): convert to use
+ PyTypeObjects instead of ExtensionClass.
+ (pygobject_new): don't need to set inst_dict. Python takes care
+ of that for us.
+ (pyg_register_boxed): convert to 2.2.
+ (pyg_boxed_new): convert to 2.2.
+ (pyg_value_from_pyobject): get rid of ExtensionClass calls.
+ (pygobject_init): convert to 2.2.
+
+ * pygobject.h: don't include ExtensionClass.h
+
+ * configure.in (AM_PATH_PYTHON): require python 2.2.
+
+ * Makefile.am: remove ExtensionClass.
+
2001-09-28 Matt Wilson <msw@redhat.com>
* gtk/gtk.defs (gtk_progress_bar_new_with_adjustment): mark as
diff --git a/ExtensionClass.c b/ExtensionClass.c
deleted file mode 100644
index d444ed10..00000000
--- a/ExtensionClass.c
+++ /dev/null
@@ -1,3490 +0,0 @@
-/*
-
- Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- o Redistributions of source code must retain the above copyright
- notice, this list of conditions, and the disclaimer that follows.
-
- o Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions, and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
- o Neither the name of Digital Creations nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-
- THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
- IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
- CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- DAMAGE.
-
- $Id$
-
- If you have questions regarding this software,
- contact:
-
- Digital Creations L.C.
- info@digicool.com
-
- (540) 371-6909
-
-*/
-
-static char ExtensionClass_module_documentation[] =
-"ExtensionClass - Classes implemented in c\n"
-"\n"
-"Built-in C classes are like Built-in types except that\n"
-"they provide some of the behavior of Python classes:\n"
-"\n"
-" - They provide access to unbound methods,\n"
-" - They can be called to create instances.\n"
-"\n"
-"$Id$\n"
-;
-
-#include <stdio.h>
-#include "ExtensionClass.h"
-
-static void
-PyVar_Assign(PyObject **v, PyObject *e)
-{
- Py_XDECREF(*v);
- *v=e;
-}
-
-#define ASSIGN(V,E) PyVar_Assign(&(V),(E))
-#define UNLESS(E) if (!(E))
-#define UNLESS_ASSIGN(V,E) ASSIGN(V,E); UNLESS(V)
-#define OBJECT(O) ((PyObject*)O)
-
-/* Declarations for objects of type ExtensionClass */
-
-staticforward PyExtensionClass ECType;
-
-#define ExtensionClass_Check(O) ((O)->ob_type == (PyTypeObject*)&ECType)
-#define ExtensionInstance_Check(O) \
- ((O)->ob_type->ob_type == (PyTypeObject*)&ECType)
-#define AsExtensionClass(O) ((PyExtensionClass*)(O))
-#define ExtensionClassOf(O) ((PyExtensionClass*)((O)->ob_type))
-#define AsPyObject(O) ((PyObject*)(O))
-#define NeedsToBeBound(O) \
- ((O)->ob_type->ob_type == (PyTypeObject*)&ECType && \
- (((PyExtensionClass*)((O)->ob_type))->class_flags & \
- EXTENSIONCLASS_BINDABLE_FLAG))
-#define HasMethodHook(O) \
- ((O)->ob_type->ob_type == (PyTypeObject*)&ECType && \
- (((PyExtensionClass*)((O)->ob_type))->class_flags & \
- EXTENSIONCLASS_METHODHOOK_FLAG))
-
-#define ALLOC_FREE(T) \
- if (free ## T) { \
- self=free ## T; \
- free ## T=(T*)self->self; \
- self->ob_refcnt=1; \
- } \
- else UNLESS(self = PyObject_NEW(T, & T ## Type)) return NULL;
-
-#define METH_BY_NAME (2 << 16)
-
-static PyObject *py__add__, *py__sub__, *py__mul__, *py__div__,
- *py__mod__, *py__pow__, *py__divmod__, *py__lshift__, *py__rshift__,
- *py__and__, *py__or__, *py__xor__, *py__coerce__, *py__neg__,
- *py__pos__, *py__abs__, *py__nonzero__, *py__inv__, *py__int__,
- *py__long__, *py__float__, *py__oct__, *py__hex__,
- *py__of__, *py__call__, *py__call_method__,
- *py__getitem__, *py__setitem__, *py__delitem__,
- *py__getslice__, *py__setslice__, *py__delslice__, *py__len__,
- *py__getattr__, *py__setattr__, *py__delattr__,
- *py__del__, *py__repr__, *py__str__, *py__class__, *py__name__,
- *py__hash__, *py__cmp__, *py__var_size__, *py__init__, *py__getinitargs__,
- *py__getstate__, *py__setstate__, *py__dict__, *pyclass_,
- *py__module__;
-
-static PyObject *concat_fmt=0;
-static PyObject *subclass_watcher=0; /* Object that subclass events */
-
-static void
-init_py_names()
-{
-#define INIT_PY_NAME(N) py ## N = PyString_FromString(#N)
- INIT_PY_NAME(__add__);
- INIT_PY_NAME(__sub__);
- INIT_PY_NAME(__mul__);
- INIT_PY_NAME(__div__);
- INIT_PY_NAME(__mod__);
- INIT_PY_NAME(__pow__);
- INIT_PY_NAME(__divmod__);
- INIT_PY_NAME(__lshift__);
- INIT_PY_NAME(__rshift__);
- INIT_PY_NAME(__and__);
- INIT_PY_NAME(__or__);
- INIT_PY_NAME(__xor__);
- INIT_PY_NAME(__coerce__);
- INIT_PY_NAME(__neg__);
- INIT_PY_NAME(__pos__);
- INIT_PY_NAME(__abs__);
- INIT_PY_NAME(__nonzero__);
- INIT_PY_NAME(__inv__);
- INIT_PY_NAME(__int__);
- INIT_PY_NAME(__long__);
- INIT_PY_NAME(__float__);
- INIT_PY_NAME(__oct__);
- INIT_PY_NAME(__hex__);
- INIT_PY_NAME(__getitem__);
- INIT_PY_NAME(__setitem__);
- INIT_PY_NAME(__delitem__);
- INIT_PY_NAME(__getslice__);
- INIT_PY_NAME(__setslice__);
- INIT_PY_NAME(__delslice__);
- INIT_PY_NAME(__len__);
- INIT_PY_NAME(__of__);
- INIT_PY_NAME(__call__);
- INIT_PY_NAME(__call_method__);
- INIT_PY_NAME(__getattr__);
- INIT_PY_NAME(__setattr__);
- INIT_PY_NAME(__delattr__);
- INIT_PY_NAME(__del__);
- INIT_PY_NAME(__repr__);
- INIT_PY_NAME(__str__);
- INIT_PY_NAME(__class__);
- INIT_PY_NAME(__name__);
- INIT_PY_NAME(__hash__);
- INIT_PY_NAME(__cmp__);
- INIT_PY_NAME(__var_size__);
- INIT_PY_NAME(__init__);
- INIT_PY_NAME(__getinitargs__);
- INIT_PY_NAME(__getstate__);
- INIT_PY_NAME(__setstate__);
- INIT_PY_NAME(__dict__);
- INIT_PY_NAME(class_);
- INIT_PY_NAME(__module__);
-
-#undef INIT_PY_NAME
-}
-
-static PyObject *
-CallMethodO(PyObject *self, PyObject *name,
- PyObject *args, PyObject *kw)
-{
- if (! args && PyErr_Occurred()) return NULL;
- UNLESS(name=PyObject_GetAttr(self,name)) return NULL;
- ASSIGN(name,PyEval_CallObjectWithKeywords(name,args,kw));
- if (args) Py_DECREF(args);
- return name;
-}
-
-#define Build Py_BuildValue
-
-/* CMethod objects: */
-
-typedef struct {
- PyObject_HEAD
- PyTypeObject *type;
- PyObject *self;
- char *name;
- PyCFunction meth;
- int flags;
- char *doc;
-} CMethod;
-
-staticforward PyTypeObject CMethodType;
-
-#define CMethod_Check(O) ((O)->ob_type==&CMethodType)
-#define UnboundCMethod_Check(O) \
- ((O)->ob_type==&CMethodType && ! ((CMethod*)(O))->self)
-#define AsCMethod(O) ((CMethod*)(O))
-#define CMETHOD(O) ((CMethod*)(O))
-
-
-#define PMethod PyECMethodObject
-#define PMethodType PyECMethodObjectType
-
-staticforward PyTypeObject PMethodType;
-
-#define PMethod_Check(O) ((O)->ob_type==&PMethodType)
-#define UnboundPMethod_Check(O) \
- ((O)->ob_type==&PMethodType && ! ((PMethod*)(O))->self)
-
-#define UnboundEMethod_Check(O) \
- (((O)->ob_type==&PMethodType ||(O)->ob_type==&CMethodType) \
- && ! ((PMethod*)(O))->self)
-
-#define PMETHOD(O) ((PMethod*)(O))
-
-
-
-static PyObject *
-#ifdef HAVE_STDARG_PROTOTYPES
-/* VARARGS 2 */
-JimErr_Format(PyObject *ErrType, char *stringformat, char *format, ...)
-#else
-/* VARARGS */
-JimErr_Format(va_alist) va_dcl
-#endif
-{
- va_list va;
- PyObject *args=0, *retval=0;
-#ifdef HAVE_STDARG_PROTOTYPES
- va_start(va, format);
-#else
- PyObject *ErrType;
- char *stringformat, *format;
- va_start(va);
- ErrType = va_arg(va, PyObject *);
- stringformat = va_arg(va, char *);
- format = va_arg(va, char *);
-#endif
-
- if (format) args = Py_VaBuildValue(format, va);
- va_end(va);
- if (format && ! args) return NULL;
- if (stringformat && !(retval=PyString_FromString(stringformat))) return NULL;
-
- if (retval)
- {
- if (args)
- {
- PyObject *v;
- v=PyString_Format(retval, args);
- Py_DECREF(retval);
- Py_DECREF(args);
- if (! v) return NULL;
- retval=v;
- }
- }
- else
- if (args) retval=args;
- else
- {
- PyErr_SetObject(ErrType,Py_None);
- return NULL;
- }
- PyErr_SetObject(ErrType,retval);
- Py_DECREF(retval);
- return NULL;
-}
-
-
-static PyObject *
-#ifdef HAVE_STDARG_PROTOTYPES
-/* VARARGS 2 */
-JimString_Build(char *out_format, char *build_format, ...)
-#else
-/* VARARGS */
-JimString_Build(va_alist) va_dcl
-#endif
-{
- va_list va;
- PyObject *args, *retval, *fmt;
-#ifdef HAVE_STDARG_PROTOTYPES
- va_start(va, build_format);
-#else
- char *build_format;
- char *out_format;
- va_start(va);
- out_format = va_arg(va, char *);
- build_format = va_arg(va, char *);
-#endif
-
- if (build_format)
- args = Py_VaBuildValue(build_format, va);
- else
- args = PyTuple_New(0);
-
- va_end(va);
-
- if (! args)
- return NULL;
-
- if (! PyTuple_Check(args))
- {
- PyObject *a;
-
- a=PyTuple_New(1);
- if (! a)
- return NULL;
-
- if (PyTuple_SetItem(a,0,args) == -1)
- return NULL;
-
- args=a;
- }
-
- fmt = PyString_FromString(out_format);
-
- retval = PyString_Format(fmt, args);
-
- Py_DECREF(args);
- Py_DECREF(fmt);
-
- return retval;
-}
-
-
-
-static int
-CMethod_issubclass(PyExtensionClass *sub, PyExtensionClass *type)
-{
- int i,l;
- PyObject *t;
-
- if (sub==type) return 1;
- if (! sub->bases) return 0;
- l=PyTuple_Size(sub->bases);
- for (i=0; i < l; i++)
- {
- t=PyTuple_GET_ITEM(sub->bases, i);
- if (t==(PyObject*)type) return 1;
- if (ExtensionClass_Check(t)
- && AsExtensionClass(t)->bases
- && CMethod_issubclass(AsExtensionClass(t),type)
- ) return 1;
- }
- return 0;
-}
-
-#define Subclass_Check(C1,C2) \
- CMethod_issubclass((PyExtensionClass *)(C1), (PyExtensionClass *)(C2))
-
-#define SubclassInstance_Check(C1,C2) \
- CMethod_issubclass((PyExtensionClass *)((C1)->ob_type), \
- (PyExtensionClass *)(C2))
-
-
-static CMethod *freeCMethod=0;
-
-static PyObject *
-newCMethod(PyExtensionClass *type, PyObject *inst,
- char *name, PyCFunction meth, int flags, char *doc)
-{
- CMethod *self;
-
- ALLOC_FREE(CMethod);
-
- Py_INCREF(type);
- Py_XINCREF(inst);
- self->type=(PyTypeObject*)type;
- self->self=inst;
- self->name=name;
- self->meth=meth;
- self->flags=flags;
- self->doc=doc;
- return (PyObject*)self;
-}
-
-static CMethod *
-bindCMethod(CMethod *m, PyObject *inst)
-{
- CMethod *self;
-
- UNLESS(inst->ob_type==m->type
- || (ExtensionInstance_Check(inst)
- && SubclassInstance_Check(inst,m->type))
- || ((m->flags & METH_CLASS_METHOD) && ExtensionClass_Check(inst))
- )
- {
- Py_INCREF(m);
- return m;
- }
-
- ALLOC_FREE(CMethod);
-
- Py_INCREF(inst);
- Py_INCREF(m->type);
- self->type=m->type;
- self->self=inst;
- self->name=m->name;
- self->meth=m->meth;
- self->flags=m->flags;
- self->doc=m->doc;
- return self;
-}
-
-static void
-CMethod_dealloc(CMethod *self)
-{
-#ifdef TRACE_DEALLOC
- fprintf(stderr,"Deallocating C method %s\n", self->name);
-#endif
- Py_XDECREF(self->type);
- Py_XDECREF(self->self);
- self->self=(PyObject*)freeCMethod;
- freeCMethod=self;
-}
-
-typedef PyObject *(*call_by_name_type)(PyObject*,PyObject*,PyObject*,
- PyTypeObject*);
-typedef PyObject *(*by_name_type)(PyObject*,PyObject*,
- PyTypeObject*);
-static PyObject *
-call_cmethod(CMethod *self, PyObject *inst, PyObject *args, PyObject *kw)
-{
- if (!(self->flags & METH_VARARGS))
- {
- int size = PyTuple_Size(args);
- if (size == 1) args = PyTuple_GET_ITEM(args, 0);
- else if (size == 0) args = NULL;
- }
- if (self->flags & METH_KEYWORDS)
- {
- if (self->flags & METH_BY_NAME)
- return (*(call_by_name_type)self->meth)(inst, args, kw,
- self->type);
- else
- return (*(PyCFunctionWithKeywords)self->meth)(inst, args, kw);
- }
- else if (self->flags & METH_BY_NAME)
- return (*(by_name_type)self->meth)(inst, args, self->type);
- else
- {
- if (kw != NULL && PyDict_Size(kw) != 0)
- {
- PyErr_SetString(PyExc_TypeError,
- "this function takes no keyword arguments");
- return NULL;
- }
- return (*self->meth)(inst, args);
- }
-}
-
-static char *hook_mark="C method being called through a hook.";
-
-static PyObject *
-callCMethodWithHook(CMethod *self, PyObject *inst,
- PyObject *args, PyObject *kw)
-{
- PyObject *hook, *m;
-
- UNLESS(m=newCMethod(AsExtensionClass(self->type),
- inst, self->name, self->meth,
- self->flags, hook_mark)) return NULL;
-
- if ((hook=PyObject_GetAttr(inst,py__call_method__)))
- {
- if ((CMethod_Check(hook) && CMETHOD(hook)->meth==self->meth)
- ||
- (PMethod_Check(hook)
- && CMethod_Check(PMETHOD(hook)->meth)
- && CMETHOD(PMETHOD(hook)->meth)->meth==self->meth)
- )
- {
- /* Oops, we are already calling the hook! */
- Py_DECREF(hook);
- return PyEval_CallObjectWithKeywords(m,args,kw);
- }
- if (kw)
- ASSIGN(hook,PyObject_CallFunction(hook,"OOO",m,args,kw));
- else
- ASSIGN(hook,PyObject_CallFunction(hook,"OO",m,args));
- }
- else
- {
- PyErr_Clear();
- hook=PyEval_CallObjectWithKeywords(m,args,kw);
- }
-
- Py_DECREF(m);
- return hook;
-}
-
-static PyObject *
-CMethod_call(CMethod *self, PyObject *args, PyObject *kw)
-{
- int size;
-
- if (self->self)
- {
- if (HasMethodHook(self->self) &&
- self->doc != hook_mark /* This check prevents infinite recursion */
- )
- return callCMethodWithHook(self,self->self,args,kw);
- return call_cmethod(self,self->self,args,kw);
- }
-
- if ((size=PyTuple_Size(args)) > 0)
- {
- PyObject *first=0;
-
- UNLESS(first=PyTuple_GET_ITEM(args, 0)) return NULL;
- if (
- first->ob_type==self->type
- ||
- (ExtensionInstance_Check(first)
- &&
- CMethod_issubclass(ExtensionClassOf(first),
- AsExtensionClass(self->type))
- )
- )
- {
- PyObject *rest=0;
- if (HasMethodHook(first) &&
- self->doc != hook_mark /* This check prevents infinite recursion */
- )
- return callCMethodWithHook(self,first,args,kw);
- UNLESS(rest=PySequence_GetSlice(args,1,size)) return NULL;
- ASSIGN(rest,call_cmethod(self,first,rest,kw));
- return rest;
- }
- }
-
- return JimErr_Format(PyExc_TypeError,
- "unbound C method must be called with %s 1st argument",
- "s", self->type->tp_name);
-}
-
-static PyObject *
-CMethod_getattro(CMethod *self, PyObject *oname)
-{
- PyObject *r;
-
- if (PyString_Check(oname))
- {
- char *name;
-
- UNLESS(name=PyString_AsString(oname)) return NULL;
-
- if (name[0] != '_' && name[0] && name[1] != '_' &&
- PyEval_GetRestricted())
- {
- PyErr_SetString(PyExc_RuntimeError,
- "function attributes not accessible in restricted mode");
- return NULL;
- }
-
- if (strcmp(name,"__name__")==0 || strcmp(name,"func_name")==0 )
- return PyString_FromString(self->name);
- if (strcmp(name,"func_code")==0 ||
- strcmp(name,"im_func")==0)
- {
- Py_INCREF(self);
- return (PyObject *)self;
- }
- if (strcmp(name,"__doc__")==0 ||
- strcmp(name,"func_doc")==0)
- {
- if (self->doc)
- return PyString_FromString(self->doc);
- else
- return PyString_FromString("");
- }
- if (strcmp(name,"im_class")==0)
- {
- Py_INCREF(self->type);
- return (PyObject *)self->type;
- }
- if (strcmp(name,"im_self")==0)
- {
- if (self->self) r=self->self;
- else r=Py_None;
- Py_INCREF(r);
- return r;
- }
- }
-
- if (self->self) /* Psuedo attributes */
- {
- UNLESS(oname=Py_BuildValue("sO", self->name, oname)) return NULL;
- UNLESS_ASSIGN(oname,PyString_Format(concat_fmt, oname)) return NULL;
- r=PyObject_GetAttr(self->self, oname);
- Py_DECREF(oname);
- return r;
- }
-
- PyErr_SetObject(PyExc_AttributeError, oname);
- return NULL;
-}
-
-static int
-CMethod_setattro(CMethod *self, PyObject *oname, PyObject *v)
-{
- int r;
-
- if (self->self && ! PyEval_GetRestricted()) /* Psuedo attributes */
- {
- UNLESS(oname=Py_BuildValue("sO", self->name, oname)) return -1;
- UNLESS_ASSIGN(oname,PyString_Format(concat_fmt, oname)) return -1;
- r=PyObject_SetAttr(self->self, oname, v);
- Py_DECREF(oname);
- return r;
- }
-
- PyErr_SetObject(PyExc_AttributeError, oname);
- return -1;
-}
-
-static PyTypeObject CMethodType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "CMethod", /*tp_name*/
- sizeof(CMethod), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)CMethod_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- 0, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)CMethod_call, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- (getattrofunc)CMethod_getattro, /* tp_getattro */
- (setattrofunc)CMethod_setattro, /* tp_setattro */
-
- /* Space for future expansion */
- 0L,0L,
- "Storage manager for unbound C function PyObject data"
- /* Documentation string */
-};
-
-/* PMethod objects: */
-
-static PMethod *freePMethod=0;
-
-static PyObject *
-newPMethod(PyExtensionClass *type, PyObject *meth)
-{
- PMethod *self;
-
- ALLOC_FREE(PMethod);
-
- Py_INCREF(type);
- Py_INCREF(meth);
- self->type=(PyTypeObject*)type;
- self->self=NULL;
- self->meth=meth;
- return (PyObject*)self;
-}
-
-static PyObject *
-bindPMethod(PMethod *m, PyObject *inst)
-{
- PMethod *self;
-
- if (NeedsToBeBound(m->meth))
- return CallMethodO(m->meth, py__of__, Build("(O)", inst), NULL);
- if (m->ob_refcnt==1)
- {
- Py_INCREF(inst);
- ASSIGN(m->self, inst);
- Py_INCREF(m);
- return (PyObject*)m;
- }
-
- ALLOC_FREE(PMethod);
-
- Py_INCREF(inst);
- Py_INCREF(m->type);
- self->type=m->type;
- self->self=inst;
- self->meth=m->meth;
- return (PyObject*)self;
-}
-
-static PyObject *
-PMethod_New(PyObject *meth, PyObject *inst)
-{
- if (PMethod_Check(meth)) return bindPMethod((PMethod*)meth,inst);
- UNLESS(ExtensionInstance_Check(inst))
- return JimErr_Format(PyExc_TypeError,
- "Attempt to use %s as method for %s, which is "
- "not an extension class instance.",
- "OO",meth,inst);
- if ((meth=newPMethod(ExtensionClassOf(inst), meth)))
- UNLESS_ASSIGN(((PMethod*)meth)->self,inst) return NULL;
- Py_INCREF(inst);
- return meth;
-}
-
-static void
-PMethod_dealloc(PMethod *self)
-{
-#ifdef TRACE_DEALLOC
- fprintf(stderr,"Deallocating PM ... ");
-#endif
- Py_XDECREF(self->type);
- Py_XDECREF(self->self);
- self->self=(PyObject*)freePMethod;
- freePMethod=self;
-#ifdef TRACE_DEALLOC
- fprintf(stderr," Done Deallocating PM\n");
-#endif
-}
-
-static PyObject *
-callMethodWithPossibleHook(PyObject *inst,
- PyObject *meth, PyObject *args, PyObject *kw)
-{
- if (HasMethodHook(inst))
- {
- PyObject *hook;
- if ((hook=PyObject_GetAttr(inst,py__call_method__)))
- {
- if (PMethod_Check(hook) && ((PMethod*)hook)->meth==meth)
- {
- /* Oops, we are already calling the hook! */
- Py_DECREF(hook);
- return PyEval_CallObjectWithKeywords(meth,args,kw);
- }
- if (kw)
- ASSIGN(hook,PyObject_CallFunction(hook,"OOO",meth,args,kw));
- else
- ASSIGN(hook,PyObject_CallFunction(hook,"OO",meth,args));
- return hook;
- }
- PyErr_Clear();
- }
- return PyEval_CallObjectWithKeywords(meth,args,kw);
-}
-
-static PyObject *
-call_PMethod(PMethod *self, PyObject *inst, PyObject *args, PyObject *kw)
-{
- PyObject *a;
-
- if (CMethod_Check(self->meth)
- && CMETHOD(self->meth)->type->tp_basicsize == sizeof(PyPureMixinObject)
- && ! (CMETHOD(self->meth)->self)
- )
- {
- /* Special HACK^H^H^Hcase:
- we are wrapping an abstract unbound CMethod */
- if (HasMethodHook(inst) &&
- /* This check prevents infinite recursion: */
- CMETHOD(self->meth)->doc != hook_mark
- )
- return callCMethodWithHook(CMETHOD(self->meth),inst,args,kw);
- return call_cmethod(CMETHOD(self->meth),inst,args,kw);
-
- }
- else
- {
- a=Py_BuildValue("(O)",inst);
- if (a) ASSIGN(a,PySequence_Concat(a,args));
- if (a) ASSIGN(a,callMethodWithPossibleHook(inst,self->meth,a,kw));
- return a;
- }
-}
-
-static PyObject *
-PMethod_call(PMethod *self, PyObject *args, PyObject *kw)
-{
- int size;
-
- if (self->self) return call_PMethod(self,self->self,args,kw);
-
- if ((size=PyTuple_Size(args)) > 0)
- {
- PyObject *first=0, *ftype=0;
- UNLESS(first=PyTuple_GET_ITEM(args, 0)) return NULL;
- if (! self->type ||
- ((ftype=PyObject_GetAttr(first,py__class__)) &&
- (ftype==(PyObject*)self->type ||
- (ExtensionClass_Check(ftype) &&
- CMethod_issubclass(AsExtensionClass(ftype),
- AsExtensionClass(self->type))
- )
- )
- )
- )
- {
- if (NeedsToBeBound(self->meth))
- {
- PyObject *r, *rest;
- UNLESS(r=CallMethodO(self->meth,py__of__,Build("(O)", first),
- NULL))
- return NULL;
- UNLESS(rest=PySequence_GetSlice(args,1,size))
- {
- Py_DECREF(r);
- return NULL;
- }
- ASSIGN(r,callMethodWithPossibleHook(first,r,rest,kw));
- Py_DECREF(rest);
- return r;
- }
- Py_DECREF(ftype);
- return callMethodWithPossibleHook(first,self->meth,args,kw);
- }
- Py_XDECREF(ftype);
- }
-
- return JimErr_Format(PyExc_TypeError,
- "unbound Python method must be called with %s"
- " 1st argument",
- "s", self->type->tp_name);
-}
-
-static PyObject *
-PMethod_getattro(PMethod *self, PyObject *oname)
-{
- PyObject *r;
-
- if (PyString_Check(oname))
- {
- char *name;
-
- UNLESS(name=PyString_AsString(oname)) return NULL;
-
- if (name[0]=='_' && name[1]=='_')
- {
- if (strcmp(name+2,"name__")==0)
- return PyObject_GetAttrString(self->meth,"__name__");
- if (strcmp(name+2,"doc__")==0)
- return PyObject_GetAttrString(self->meth,"__doc__");
- }
- else if (PyEval_GetRestricted())
- {
- PyErr_SetString(PyExc_RuntimeError,
- "function attributes not accessible in restricted mode");
- return NULL;
- }
- else if (name[0]=='f' && name[1]=='u' && name[2]=='n' && name[3]=='c'
- && name[4]=='_')
- {
- if (strcmp(name+5,"name")==0 )
- return PyObject_GetAttrString(self->meth,"__name__");
- if (strcmp(name+5,"doc")==0)
- return PyObject_GetAttrString(self->meth,"__doc__");
- }
-
- if (*name++=='i' && *name++=='m' && *name++=='_')
- {
- if (strcmp(name,"func")==0)
- {
- Py_INCREF(self->meth);
- return self->meth;
- }
- if (strcmp(name,"class")==0)
- {
- Py_INCREF(self->type);
- return (PyObject *)self->type;
- }
- if (strcmp(name,"self")==0)
- {
- if (self->self) r=self->self;
- else r=Py_None;
- Py_INCREF(r);
- return r;
- }
- }
- }
-
- if (self->meth)
- {
- if ((r=PyObject_GetAttr(self->meth, oname))) return r;
- PyErr_Clear();
-
- if (self->self) /* Psuedo attrs */
- {
- PyObject *myname;
-
- UNLESS(myname=PyObject_GetAttr(self->meth, py__name__)) return NULL;
- oname=Py_BuildValue("OO", myname, oname);
- Py_DECREF(myname);
- UNLESS(oname) return NULL;
- UNLESS_ASSIGN(oname,PyString_Format(concat_fmt, oname)) return NULL;
- r=PyObject_GetAttr(self->self, oname);
- Py_DECREF(oname);
- return r;
- }
- }
-
- PyErr_SetObject(PyExc_AttributeError, oname);
- return NULL;
-
- return PyObject_GetAttr(self->meth, oname);
-}
-
-static int
-PMethod_setattro(PMethod *self, PyObject *oname, PyObject *v)
-{
- int r;
- PyObject *spam;
-
- if (self->meth)
- {
- if ((spam=PyObject_GetAttr(self->meth, oname)))
- {
- Py_DECREF(spam);
- PyErr_SetString(PyExc_TypeError,
- "Attempt to overwrite shared method attribute");
- return -1;
- }
- else PyErr_Clear();
-
- if (self->self && ! PyEval_GetRestricted()) /* Psuedo attrs */
- {
- PyObject *myname;
-
- UNLESS(myname=PyObject_GetAttr(self->meth, py__name__)) return -1;
- oname=Py_BuildValue("OO", myname, oname);
- Py_DECREF(myname);
- UNLESS(oname) return -1;
- UNLESS_ASSIGN(oname,PyString_Format(concat_fmt, oname)) return -1;
- r=PyObject_SetAttr(self->self, oname, v);
- Py_DECREF(oname);
- return r;
- }
- }
-
- PyErr_SetObject(PyExc_AttributeError, oname);
- return -1;
-}
-
-static PyTypeObject PMethodType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "Python Method", /*tp_name*/
- sizeof(PMethod), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)PMethod_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- 0, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)PMethod_call, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- (getattrofunc)PMethod_getattro, /*tp_getattro*/
- (setattrofunc)PMethod_setattro, /* tp_setattro */
-
- /* Space for future expansion */
- 0L,0L,
- "Storage manager for unbound C function PyObject data"
- /* Documentation string */
-};
-
-static PyObject *CCL_getattr(PyExtensionClass*,PyObject*,int);
-
-/* Special Methods */
-
-#define UNARY_OP(OP) \
-static PyObject * \
-OP ## _by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type) { \
- UNLESS(PyArg_ParseTuple(args,"")) return NULL; \
- return ob_type->tp_ ## OP(self); \
-}
-
-UNARY_OP(repr)
-UNARY_OP(str)
-
-static PyObject *
-hash_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type) {
- long r;
- UNLESS(PyArg_ParseTuple(args,"")) return NULL;
- UNLESS(-1 != (r=ob_type->tp_hash(self))) return NULL;
- return PyInt_FromLong(r);
-}
-
-static PyObject *
-call_by_name(PyObject *self, PyObject *args, PyObject *kw,
- PyTypeObject *ob_type)
-{
- return ob_type->tp_call(self,args,kw);
-}
-
-static PyObject *
-compare_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- PyObject *other;
-
- UNLESS(PyArg_ParseTuple(args,"O", &other)) return NULL;
- return PyInt_FromLong(ob_type->tp_compare(self,other));
-}
-
-static PyObject *
-getattr_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- char *name;
- UNLESS(PyArg_ParseTuple(args,"s",&name)) return NULL;
- return ob_type->tp_getattr(self,name);
-}
-
-static PyObject *
-setattr_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- char *name;
- PyObject *v;
- UNLESS(PyArg_ParseTuple(args,"sO",&name,&v)) return NULL;
- UNLESS(-1 != ob_type->tp_setattr(self,name,v)) return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *
-getattro_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- PyObject *name;
- UNLESS(PyArg_ParseTuple(args,"O",&name)) return NULL;
- return ob_type->tp_getattro(self,name);
-}
-
-static PyObject *
-setattro_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- PyObject *name;
- PyObject *v;
- UNLESS(PyArg_ParseTuple(args,"OO",&name,&v)) return NULL;
- UNLESS(-1 != ob_type->tp_setattro(self,name,v)) return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *
-length_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- long r;
- UNLESS(PyArg_ParseTuple(args,"")) return NULL;
- if (ob_type->tp_as_sequence)
- {
- UNLESS(-1 != (r=ob_type->tp_as_sequence->sq_length(self)))
- return NULL;
- }
- else
- {
- UNLESS(-1 != (r=ob_type->tp_as_mapping->mp_length(self)))
- return NULL;
- }
- return PyInt_FromLong(r);
-}
-
-static PyObject *
-getitem_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- PyObject *key;
-
- UNLESS(PyArg_ParseTuple(args,"O",&key)) return NULL;
- if (ob_type->tp_as_mapping)
- return ob_type->tp_as_mapping->mp_subscript(self,key);
- else
- {
- int index;
- UNLESS(-1 != (index=PyInt_AsLong(key))) return NULL;
- return ob_type->tp_as_sequence->sq_item(self,index);
- }
-}
-
-static PyCFunction item_by_name=(PyCFunction)getitem_by_name;
-static PyCFunction subscript_by_name=(PyCFunction)getitem_by_name;
-
-static PyObject *
-setitem_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- PyObject *key, *v;
- long r;
-
- UNLESS(PyArg_ParseTuple(args,"OO",&key,&v)) return NULL;
- if (ob_type->tp_as_mapping)
- r=ob_type->tp_as_mapping->mp_ass_subscript(self,key,v);
- else
- {
- int index;
- UNLESS(-1 != (index=PyInt_AsLong(key))) return NULL;
- r=ob_type->tp_as_sequence->sq_ass_item(self,index,v);
- }
- if (r < 0) return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyCFunction ass_item_by_name=(PyCFunction)setitem_by_name;
-static PyCFunction ass_subscript_by_name=(PyCFunction)setitem_by_name;
-
-static PyObject *
-slice_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- int i1,i2;
-
- UNLESS(PyArg_ParseTuple(args,"ii",&i1,&i2)) return NULL;
- return ob_type->tp_as_sequence->sq_slice(self,i1,i2);
-}
-
-static PyObject *
-ass_slice_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- int i1,i2;
- PyObject *v;
- long r;
-
- UNLESS(PyArg_ParseTuple(args,"iiO",&i1,&i2,&v)) return NULL;
- r=ob_type->tp_as_sequence->sq_ass_slice(self,i1,i2,v);
- if (r<0) return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *
-concat_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- PyObject *other;
- UNLESS(PyArg_ParseTuple(args,"O",&other)) return NULL;
- return ob_type->tp_as_sequence->sq_concat(self,other);
-}
-
-static PyObject *
-repeat_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- int r;
- UNLESS(PyArg_ParseTuple(args,"i",&r)) return NULL;
- return ob_type->tp_as_sequence->sq_repeat(self,r);
-}
-
-#define BINOP(OP,AOP) \
-static PyObject * \
-OP ## _by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type) { \
- PyObject *v; \
- UNLESS(PyArg_ParseTuple(args,"O",&v)) return NULL; \
- return ob_type->tp_as_number->nb_ ## OP(self, v); \
-}
-
-BINOP(add,Add)
-BINOP(subtract,Subtract)
-BINOP(multiply,Multiply)
-BINOP(divide,Divide)
-BINOP(remainder,Remainder)
-BINOP(divmod,Divmod)
-
-static PyObject *
-power_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- PyObject *v, *z=NULL;
- UNLESS(PyArg_ParseTuple(args,"O|O",&v,&z)) return NULL;
- return ob_type->tp_as_number->nb_power(self,v,z);
-}
-
-#define UNOP(OP) \
-static PyObject * \
-OP ## _by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type) { \
- UNLESS(PyArg_ParseTuple(args,"")) return NULL; \
- return ob_type->tp_as_number->nb_ ## OP(self); \
-}
-
-UNOP(negative)
-UNOP(positive)
-UNOP(absolute)
-
-static PyObject *
-nonzero_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type) {
- long r;
- UNLESS(PyArg_ParseTuple(args,"")) return NULL;
- UNLESS(-1 != (r=ob_type->tp_as_number->nb_nonzero(self))) return NULL;
- return PyInt_FromLong(r);
-}
-
-UNOP(invert)
-
-BINOP(lshift,Lshift)
-BINOP(rshift,Rshift)
-BINOP(and,And)
-BINOP(or,Or)
-BINOP(xor,Xor)
-
-static PyObject *
-coerce_by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type)
-{
- PyObject *v;
- int r;
- UNLESS(PyArg_ParseTuple(args,"O", &v)) return NULL;
- UNLESS(-1 != (r=ob_type->tp_as_number->nb_coerce(&self,&v)))
- {
- Py_INCREF(Py_None);
- return Py_None;
- }
- args=Py_BuildValue("OO",self,v);
- Py_DECREF(self);
- Py_DECREF(v);
- return args;
-}
-
-UNOP(long)
-UNOP(int)
-UNOP(float)
-UNOP(oct)
-UNOP(hex)
-
-#define FILLENTRY(T,MN,N,F,D) if (T ## _ ## MN) { \
- UNLESS(-1 != PyMapping_SetItemString(dict,"__" # N "__", \
- newCMethod(type, NULL, "__" # N "__", \
- (PyCFunction)MN ## _by_name, F | METH_BY_NAME, # D))) \
- goto err; }
-
-static PyObject *
-getBaseDictionary(PyExtensionClass *type)
-{
- PyNumberMethods *nm;
- PySequenceMethods *sm;
- PyMappingMethods *mm;
- PyObject *dict;
-
- UNLESS(dict=type->class_dictionary)
- UNLESS(dict=PyDict_New()) return NULL;
-
- FILLENTRY(type->tp, repr, repr, METH_VARARGS,
- "convert to an expression string");
- FILLENTRY(type->tp, hash, hash, METH_VARARGS, "compute a hash value");
- FILLENTRY(type->tp, call, call, METH_VARARGS | METH_KEYWORDS,
- "call as a function");
- FILLENTRY(type->tp, compare, comp, METH_VARARGS,
- "compare with another object");
- FILLENTRY(type->tp, getattr, getattr, METH_VARARGS, "Get an attribute");
- FILLENTRY(type->tp, setattr, setattr, METH_VARARGS, "Set an attribute");
- FILLENTRY(type->tp, getattro, getattr, METH_VARARGS, "Get an attribute");
- FILLENTRY(type->tp, setattro, setattr, METH_VARARGS, "Set an attribute");
-
- if ((sm=type->tp_as_sequence))
- {
- FILLENTRY(sm->sq, length, len, METH_VARARGS, "Get the object length");
- FILLENTRY(sm->sq, repeat, mul, METH_VARARGS,
- "Get a new object that is the object repeated.");
- FILLENTRY(sm->sq, item, getitem, METH_VARARGS, "Get an item");
- FILLENTRY(sm->sq, slice, getslice, METH_VARARGS, "Get a slice");
- FILLENTRY(sm->sq, ass_item, setitem, METH_VARARGS, "Assign an item");
- FILLENTRY(sm->sq, ass_slice, setslice, METH_VARARGS, "Assign a slice");
- }
-
- if ((mm=type->tp_as_mapping))
- {
- FILLENTRY(mm->mp, length, len, METH_VARARGS, "Get the object length");
- FILLENTRY(mm->mp, subscript, getitem, METH_VARARGS, "Get an item");
- FILLENTRY(mm->mp, ass_subscript, setitem, METH_VARARGS,
- "Assign an item");
- }
-
- if ((nm=type->tp_as_number) != NULL)
- {
- FILLENTRY(nm->nb, add, add, METH_VARARGS, "Add to another");
- FILLENTRY(nm->nb, subtract, sub, METH_VARARGS, "Subtract another");
- FILLENTRY(nm->nb, multiply, mul, METH_VARARGS, "Multiple by another");
- FILLENTRY(nm->nb, divide, div, METH_VARARGS, "Divide by another");
- FILLENTRY(nm->nb, remainder, mod, METH_VARARGS, "Compute a remainder");
- FILLENTRY(nm->nb, power, pow, METH_VARARGS, "Raise to a power");
- FILLENTRY(nm->nb, divmod, divmod, METH_VARARGS,
- "Compute the whole result and remainder of dividing\n"
- "by another");
- FILLENTRY(nm->nb, negative, neg, METH_VARARGS,
- "Get the negative value.");
- FILLENTRY(nm->nb, positive, pos, METH_VARARGS, "Compute positive value");
- FILLENTRY(nm->nb, absolute, abs, METH_VARARGS, "Compute absolute value");
- FILLENTRY(nm->nb, nonzero, nonzero, METH_VARARGS,
- "Determine whether nonzero");
- FILLENTRY(nm->nb, invert, inv, METH_VARARGS, "Compute inverse");
- FILLENTRY(nm->nb, lshift, lshift, METH_VARARGS, "Shist left");
- FILLENTRY(nm->nb, rshift, rshift, METH_VARARGS, "Shist right");
- FILLENTRY(nm->nb, and, and, METH_VARARGS, "bitwize logical and");
- FILLENTRY(nm->nb, or, or, METH_VARARGS, "bitwize logical or");
- FILLENTRY(nm->nb, xor, xor, METH_VARARGS, "bitwize logical excusive or");
- FILLENTRY(nm->nb, coerce, coerce, METH_VARARGS,
- "Coerce woth another to a common type");
- FILLENTRY(nm->nb, int, int, METH_VARARGS, "Convert to an integer");
- FILLENTRY(nm->nb, long, long, METH_VARARGS,
- "Convert to an infinite-precision integer");
- FILLENTRY(nm->nb, float, float, METH_VARARGS,
- "Convert to floating point number");
- FILLENTRY(nm->nb, oct, oct, METH_VARARGS, "Convert to an octal string");
- FILLENTRY(nm->nb, hex, hex, METH_VARARGS,
- "Convert to a hexadecimal string");
- }
-
- if ((sm=type->tp_as_sequence))
- {
- FILLENTRY(sm->sq, concat, add, METH_VARARGS,
- "Concatinate the object with another");
- }
-
- return dict;
-err:
- Py_DECREF(dict);
- return NULL;
-}
-
-#undef UNARY_OP
-#undef BINOP
-#undef UNOP
-#undef FILLENTRY
-
-PyObject *
-EC_reduce(PyObject *self, PyObject *args)
-{
- PyObject *state=0;
-
- if ((args=PyObject_GetAttr(self,py__getinitargs__)))
- {
- UNLESS_ASSIGN(args,PyEval_CallObject(args,NULL)) return NULL;
- UNLESS_ASSIGN(args,PySequence_Tuple(args)) return NULL;
- }
- else
- {
- PyErr_Clear();
- if (ExtensionClassOf(self)->class_flags & EXTENSIONCLASS_BASICNEW_FLAG)
- {
- args=Py_None;
- Py_INCREF(args);
- }
- else args=PyTuple_New(0);
- }
-
- if ((state=PyObject_GetAttr(self,py__getstate__)))
- {
- UNLESS_ASSIGN(state,PyEval_CallObject(state,NULL)) goto err;
- ASSIGN(args,Py_BuildValue("OOO", self->ob_type, args, state));
- Py_DECREF(state);
- }
- else
- {
- PyErr_Clear();
-
- if ((state=PyObject_GetAttr(self, py__dict__)))
- {
- ASSIGN(args,Py_BuildValue("OOO", self->ob_type, args, state));
- Py_DECREF(state);
- }
- else
- {
- PyErr_Clear();
- ASSIGN(args, Py_BuildValue("OO", self->ob_type, args));
- }
- }
-
- return args;
-
-err:
- Py_DECREF(args);
- return NULL;
-}
-
-static PyObject *
-inheritedAttribute(PyExtensionClass *self, PyObject *args)
-{
- PyObject *name;
-
- UNLESS(PyArg_ParseTuple(args,"O!",&PyString_Type, &name)) return NULL;
-
- return CCL_getattr(AsExtensionClass(self),name,1);
-}
-
-static PyObject *
-basicnew(PyExtensionClass *self, PyObject *args)
-{
- PyObject *inst=0;
- typedef struct { PyObject_VAR_HEAD } PyVarObject__;
-
- if (! self->tp_dealloc)
- {
- PyErr_SetString(PyExc_TypeError,
- "Attempt to create instance of an abstract type");
- return NULL;
- }
-
- UNLESS(self->class_flags & EXTENSIONCLASS_BASICNEW_FLAG)
- return PyObject_CallObject(OBJECT(self), NULL);
-
- if (self->tp_itemsize)
- {
- /* We have a variable-sized object, we need to get it's size */
- PyObject *var_size;
- int size;
-
- UNLESS(var_size=CCL_getattr(self, py__var_size__, 0)) return NULL;
- UNLESS_ASSIGN(var_size,PyObject_CallObject(var_size,NULL)) return NULL;
- size=PyInt_AsLong(var_size);
- if (PyErr_Occurred()) return NULL;
- UNLESS(inst=PyObject_NEW_VAR(PyObject,(PyTypeObject *)self, size))
- return NULL;
- memset(inst,0,self->tp_basicsize+self->tp_itemsize*size);
- ((PyVarObject__*)inst)->ob_size=size;
- }
- else
- {
- UNLESS(inst=PyObject_NEW(PyObject,(PyTypeObject *)self)) return NULL;
- memset(inst,0,self->tp_basicsize);
- }
-
- inst->ob_refcnt=1;
- inst->ob_type=(PyTypeObject *)self;
- Py_INCREF(self);
-
- if (ClassHasInstDict(self))
- UNLESS(INSTANCE_DICT(inst)=PyDict_New()) goto err;
-
- if (self->bases && subclass_watcher &&
- ! PyObject_CallMethod(subclass_watcher,"created","O",inst))
- PyErr_Clear();
-
- return inst;
-
-err:
- Py_DECREF(inst);
- return NULL;
-}
-
-struct PyMethodDef ECI_methods[] = {
- {"__reduce__",(PyCFunction)EC_reduce, METH_VARARGS,
- "__reduce__() -- Reduce an instance into it's class and creation data"
- },
- {"inheritedAttribute",(PyCFunction)inheritedAttribute,
- METH_VARARGS | METH_CLASS_METHOD,
- "inheritedAttribute(class,name) -- Get an inherited attribute\n\n"
- "Get an attribute that would be inherited if the given (extension)\n"
- "class did not define it. This method is used when overriding\n"
- "inherited methods. It provides 2 advantages over accessing\n"
- "\n"
- "attributes directly through a superclass:\n"
- "\n"
- "1. The superclass need not be known,\n"
- "\n"
- "2. The superclass may be a Python class. Without this method, it would\n"
- " be possible to override methods inherited from python classes because\n"
- " unbound methods gotten from Python classes cannot be called with \n"
- " extension class instances. \n"
- },
- {"__basicnew__",(PyCFunction)basicnew,
- METH_VARARGS | METH_CLASS_METHOD,
- "__basicnew__() -- return a new uninitialized instance"
- },
- {NULL, NULL} /* sentinel */
-};
-
-static PyObject *
-initializeBaseExtensionClass(PyExtensionClass *self)
-{
- static PyMethodChain top = { ECI_methods, NULL };
- PyMethodChain *chain;
- PyObject *dict;
- int abstract;
-
- /* Is this an abstract, or at least a dataless, class? */
- abstract=self->tp_basicsize == sizeof(PyPureMixinObject);
-
- self->ob_type=(PyTypeObject*)&ECType;
- Py_INCREF(self->ob_type);
-
- UNLESS(dict=self->class_dictionary=getBaseDictionary(self)) return NULL;
-
- if (self->tp_name)
- {
- PyObject *name;
-
- UNLESS(name=PyString_FromString(self->tp_name)) goto err;
- if (0 > PyMapping_SetItemString(dict,"__doc__",name)) goto err;
- Py_DECREF(name);
- }
- else if (0 > PyMapping_SetItemString(dict,"__doc__",Py_None)) goto err;
-
- if (&self->methods) chain=&(self->methods);
- else chain=&top;
-
- while (1)
- {
- PyMethodDef *ml = chain->methods;
-
- for (; ml && ml->ml_name != NULL; ml++)
- {
- if (ml->ml_meth)
- {
- if (! PyMapping_HasKeyString(dict,ml->ml_name))
- {
- PyObject *m;
-
- /* Note that we create a circular reference here.
- I suppose that this isn't so bad, since this is
- probably a static thing anyway. Still, it is a
- bit troubling. Oh well.
- */
- if (ml->ml_flags & METH_CLASS_METHOD)
- {
- UNLESS(m=newCMethod(
- AsExtensionClass(self->ob_type), NULL,
- ml->ml_name, ml->ml_meth,
- ml->ml_flags, ml->ml_doc))
- return NULL;
- }
- else
- {
- UNLESS(m=newCMethod(self, NULL, ml->ml_name, ml->ml_meth,
- ml->ml_flags, ml->ml_doc))
- return NULL;
-
- if (abstract)
- UNLESS_ASSIGN(m, newPMethod(self, m))
- return NULL;
- }
-
- if (PyMapping_SetItemString(dict,ml->ml_name,m) < 0)
- return NULL;
- }
- }
- else if (ml->ml_doc && *(ml->ml_doc))
- {
- /* No actual meth, this is probably to hook a doc string
- onto a special method. */
- PyObject *m;
-
- if ((m=PyMapping_GetItemString(dict,ml->ml_name)))
- {
- if (m->ob_type==&CMethodType)
- ((CMethod *)(m))->doc=ml->ml_doc;
- }
- else
- PyErr_Clear();
- }
- }
-
- if (chain == &top) break;
-
- UNLESS(chain=chain->link) chain=&top;
- }
- return (PyObject*)self;
-
-err:
- Py_DECREF(dict);
- return NULL;
-}
-
-static void
-CCL_dealloc(PyExtensionClass *self)
-{
-#ifdef TRACE_DEALLOC
- fprintf(stderr,"Deallocating %s\n", self->tp_name);
-#endif
- Py_XDECREF(self->class_dictionary);
- /* if this ExtensionClass was subclassed in python, free this info */
- if ((self->class_flags & EXTENSIONCLASS_PYSUBCLASS_FLAG) != 0)
- {
- /* If we are a subclass, then we strduped our name */
- free(self->tp_name);
-
- /* And we allocated our own protocol structures */
- if (self->tp_as_number) free(self->tp_as_number);
- if (self->tp_as_sequence) free(self->tp_as_sequence);
- if (self->tp_as_mapping) free(self->tp_as_mapping);
- }
- Py_XDECREF(self->bases);
- if (((PyExtensionClass*)self->ob_type) != self) Py_XDECREF(self->ob_type);
- PyMem_DEL(self);
-}
-
-static PyObject *
-ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname,
- char *name)
-{
- /* Look up an attribute for an instance from:
-
- The instance dictionary,
- The class dictionary, or
- The base objects.
- */
- PyObject *r=0;
- PyExtensionClass *self;
-
- if (! name) return NULL;
-
- self=(PyExtensionClass*)(inst->ob_type);
-
- if (*name=='_' && name[1]=='_')
- {
- char *n=name+2;
- if (*n == 'c' && strcmp(n,"class__")==0)
- {
- Py_INCREF(self);
- return (PyObject*)self;
- }
- if (ClassHasInstDict(self) && *n=='d' && strcmp(n,"dict__")==0)
- {
- r = INSTANCE_DICT(inst);
- Py_INCREF(r);
- return r;
- }
- }
-
- if (ClassHasInstDict(self))
- {
- r= INSTANCE_DICT(inst);
- if ((r = PyObject_GetItem(r,oname)) && NeedsToBeBound(r))
- {
- ASSIGN(r, CallMethodO(r, py__of__, Build("(O)", inst), NULL));
- UNLESS(r) return NULL;
- }
- }
- UNLESS(r)
- {
- if (*name=='_' && name[1]=='_' && name[2]=='b' &&
- strcmp(name+2,"bases__")==0)
- {
- PyErr_SetObject(PyExc_AttributeError, oname);
- return NULL;
- }
-
- PyErr_Clear();
-
- UNLESS(r=CCL_getattr(self,oname,0)) return NULL;
-
- /* We got something from our class, maybe its an unbound method. */
- if (UnboundCMethod_Check(r))
- ASSIGN(r,(PyObject*)bindCMethod((CMethod*)r,inst));
- else if (UnboundPMethod_Check(r))
- ASSIGN(r,bindPMethod((PMethod*)r,inst));
- }
-
- return r;
-}
-
-static PyObject *
-EC_findiattrs(PyObject *self, char *name)
-{
- PyObject *s, *r;
-
- UNLESS(s=PyString_FromString(name)) return NULL;
- r=ExtensionClass_FindInstanceAttribute(self,s,name);
- Py_DECREF(s);
- return r;
-}
-
-static PyObject *
-EC_findiattro(PyObject *self, PyObject *name)
-{
- return ExtensionClass_FindInstanceAttribute(self,name,
- PyString_AsString(name));
-}
-
-static int
-subclass_simple_setattr(PyObject *self, char *name, PyObject *v);
-
-static PyObject *
-CCL_getattr(PyExtensionClass *self, PyObject *oname, int look_super)
-{
- PyObject *r=0;
-
- if (! look_super) r=PyObject_GetItem(self->class_dictionary,oname);
- UNLESS(r)
- {
- if (self->bases)
- {
- int n, i;
- PyObject *c;
-
- n=PyTuple_Size(self->bases);
- for (i=0; i < n; i++)
- {
- PyErr_Clear();
- c=PyTuple_GET_ITEM(self->bases, i);
- if (ExtensionClass_Check(c))
- r=CCL_getattr(AsExtensionClass(c),oname,0);
- else
- r=PyObject_GetAttr(c,oname);
- if (r) break;
- }
- }
- UNLESS(r)
- {
- PyObject *t, *v, *tb;
-
- PyErr_Fetch(&t,&v,&tb);
- if (t==PyExc_KeyError && PyObject_Compare(v,oname) == 0)
- {
- Py_DECREF(t);
- t=PyExc_AttributeError;
- Py_INCREF(t);
- }
- PyErr_Restore(t,v,tb);
- return NULL;
- }
- }
-
- if (PyFunction_Check(r) || NeedsToBeBound(r))
- ASSIGN(r,newPMethod(self,r));
- else if (PyMethod_Check(r) && ! PyMethod_Self(r))
- ASSIGN(r,newPMethod(self, PyMethod_Function(r)));
-
- return r;
-}
-
-static PyObject *
-CCL_reduce(PyExtensionClass *self, PyObject *args)
-{
- return PyString_FromString(self->tp_name);
-}
-
-PyObject *
-CCL_getattro(PyExtensionClass *self, PyObject *name)
-{
- char *n, *nm=0;
- PyObject *r;
-
- if (PyString_Check(name) && (n=nm=PyString_AS_STRING((PyStringObject*)name)))
- {
- if (*n=='_' && *++n=='_')
- {
- switch (*++n)
- {
- case 's':
- if (strcmp(n,"safe_for_unpickling__")==0)
- return PyInt_FromLong(1);
- break;
- case 'n':
- if (strcmp(n,"name__")==0)
- return PyString_FromString(self->tp_name);
- break;
- case 'b':
- if (strcmp(n,"bases__")==0)
- {
- if (self->bases)
- {
- Py_INCREF(self->bases);
- return self->bases;
- }
- else
- return PyTuple_New(0);
- }
- break;
- case 'r':
- if (strcmp(n,"reduce__")==0)
- return newCMethod(self,(PyObject*)self,
- "__reduce__",(PyCFunction)CCL_reduce,0,
- "__reduce__() -- Reduce the class to a class name");
- break;
- case 'd':
- if (strcmp(n,"dict__")==0)
- {
- Py_INCREF(self->class_dictionary);
- return self->class_dictionary;
- }
- break;
- case 'c':
- if (strcmp(n,"class__")==0)
- {
- Py_INCREF(self->ob_type);
- return OBJECT(self->ob_type);
- }
- break;
- }
- }
- }
-
- if ((r=CCL_getattr(self,name,0)))
- {
- if (UnboundCMethod_Check(r) && (AsCMethod(r)->flags & METH_CLASS_METHOD))
- ASSIGN(r,(PyObject*)bindCMethod((CMethod*)r,OBJECT(self)));
- }
-
- return r;
-}
-
-static int
-CCL_setattro(PyExtensionClass *self, PyObject *name, PyObject *v)
-{
- if (! v) return PyObject_DelItem(self->class_dictionary, name);
-
- if (v && UnboundCMethod_Check(v) &&
- ! (self->class_flags & EXTENSIONCLASS_METHODHOOK_FLAG)
- )
- {
- char *n;
- PyNumberMethods *nm;
- PySequenceMethods *s, *ms;
- PyMappingMethods *m, *mm;
-
- UNLESS(n=PyString_AsString(name)) return -1;
- if (*n++=='_' && *n++=='_')
- {
-#define SET_SPECIAL(C,P) \
- if (strcmp(n,#P "__")==0 \
- && AsCMethod(v)->meth==(PyCFunction)C ## _by_name \
- && Subclass_Check(self,AsCMethod(v)->type)) { \
- self->tp_ ## C=AsCMethod(v)->type->tp_ ## C; \
- return PyObject_SetItem(self->class_dictionary, name, v); }
- /*
- SET_SPECIAL(setattr,setattr);
- SET_SPECIAL(setattro,setattr);
- */
- SET_SPECIAL(compare,cmp);
- SET_SPECIAL(hash,hash);
- SET_SPECIAL(repr,repr);
- SET_SPECIAL(call,call);
- SET_SPECIAL(str,str);
-#undef SET_SPECIAL
-
-#define SET_SPECIAL(C,P) \
- if (strcmp(n,#P "__")==0 \
- && AsCMethod(v)->meth==(PyCFunction)C ## _by_name \
- && Subclass_Check(self,AsCMethod(v)->type) \
- && (nm=self->tp_as_number)) { \
- nm->nb_ ## C=AsCMethod(v)->type->tp_as_number->nb_ ## C; \
- return PyObject_SetItem(self->class_dictionary, name, v); }
-
- SET_SPECIAL(add,add);
- SET_SPECIAL(subtract,sub);
- SET_SPECIAL(multiply,mult);
- SET_SPECIAL(divide,div);
- SET_SPECIAL(remainder,mod);
- SET_SPECIAL(power,pow);
- SET_SPECIAL(divmod,divmod);
- SET_SPECIAL(lshift,lshift);
- SET_SPECIAL(rshift,rshift);
- SET_SPECIAL(and,and);
- SET_SPECIAL(or,or);
- SET_SPECIAL(xor,xor);
- SET_SPECIAL(coerce,coerce);
- SET_SPECIAL(negative,neg);
- SET_SPECIAL(positive,pos);
- SET_SPECIAL(absolute,abs);
- SET_SPECIAL(nonzero,nonzero);
- SET_SPECIAL(invert,inv);
- SET_SPECIAL(int,int);
- SET_SPECIAL(long,long);
- SET_SPECIAL(float,float);
- SET_SPECIAL(oct,oct);
- SET_SPECIAL(hex,hex);
-#undef SET_SPECIAL
-
- if (strcmp(n,"len__")==0
- && AsCMethod(v)->meth==(PyCFunction)length_by_name
- && Subclass_Check(self,AsCMethod(v)->type))
- {
- if ((s=self->tp_as_sequence) &&
- (ms=AsCMethod(v)->type->tp_as_sequence) &&
- ms->sq_length)
- s->sq_length=ms->sq_length;
- if ((m=self->tp_as_mapping) &&
- (mm=AsCMethod(v)->type->tp_as_mapping) &&
- mm->mp_length)
- m->mp_length=mm->mp_length;
- return PyObject_SetItem(self->class_dictionary, name, v);
- }
-
- if (strcmp(n,"getitem__")==0
- && AsCMethod(v)->meth==(PyCFunction)getitem_by_name
- && Subclass_Check(self,AsCMethod(v)->type))
- {
- if ((s=self->tp_as_sequence) &&
- (ms=AsCMethod(v)->type->tp_as_sequence) &&
- ms->sq_item)
- s->sq_item=ms->sq_item;
- if ((m=self->tp_as_mapping) &&
- (mm=AsCMethod(v)->type->tp_as_mapping) &&
- mm->mp_subscript)
- m->mp_subscript=mm->mp_subscript;
- return PyObject_SetItem(self->class_dictionary, name, v);
- }
-
- if (strcmp(n,"setitem__")==0 &&
- AsCMethod(v)->meth==(PyCFunction)setitem_by_name
- && Subclass_Check(self,AsCMethod(v)->type))
- {
- if ((s=self->tp_as_sequence) &&
- (ms=AsCMethod(v)->type->tp_as_sequence) &&
- ms->sq_ass_item)
- s->sq_ass_item=ms->sq_ass_item;
- if ((m=self->tp_as_mapping) &&
- (mm=AsCMethod(v)->type->tp_as_mapping) &&
- mm->mp_ass_subscript)
- m->mp_ass_subscript=mm->mp_ass_subscript;
- return PyObject_SetItem(self->class_dictionary, name, v);
- }
-
-#define SET_SPECIAL(C,P) \
- if (strcmp(n,#P "__")==0 \
- && AsCMethod(v)->meth==(PyCFunction)C ## _by_name \
- && Subclass_Check(self,AsCMethod(v)->type) \
- && (s=self->tp_as_sequence)) { \
- s->sq_ ## C=AsCMethod(v)->type->tp_as_sequence->sq_ ## C; \
- return PyObject_SetItem(self->class_dictionary, name, v); }
- SET_SPECIAL(slice,getslice);
- SET_SPECIAL(ass_slice,setslice);
- SET_SPECIAL(concat,concat);
- SET_SPECIAL(repeat,repeat);
-#undef SET_SPECIAL
-
- }
- }
- return PyObject_SetItem(self->class_dictionary, name, v);
-}
-
-static PyObject *
-CCL_call(PyExtensionClass *self, PyObject *arg, PyObject *kw)
-{
- PyObject *inst=0, *init=0, *args=0;
- typedef struct { PyObject_VAR_HEAD } PyVarObject__;
-
- if (! self->tp_dealloc)
- {
- PyErr_SetString(PyExc_TypeError,
- "Attempt to create instance of an abstract type");
- return NULL;
- }
-
- if (self->tp_itemsize)
- {
- /* We have a variable-sized object, we need to get it's size */
- PyObject *var_size;
- int size;
-
- if ((var_size=CCL_getattr(self,py__var_size__, 0)))
- {
- UNLESS_ASSIGN(var_size,PyObject_CallObject(var_size,arg))
- return NULL;
- size=PyInt_AsLong(var_size);
- if (PyErr_Occurred()) return NULL;
- }
- else
- {
- UNLESS(-1 != (size=PyTuple_Size(arg))) return NULL;
- if (size > 0)
- {
- var_size=PyTuple_GET_ITEM(arg, 0);
- if (PyInt_Check(var_size))
- size=PyInt_AsLong(var_size);
- else
- size=-1;
- }
- else
- size=-1;
- if (size < 0)
- {
- PyErr_SetString(PyExc_TypeError,
- "object size expected as first argument");
- return NULL;
- }
- }
- UNLESS(inst=PyObject_NEW_VAR(PyObject,(PyTypeObject *)self, size))
- return NULL;
- memset(inst,0,self->tp_basicsize+self->tp_itemsize*size);
- ((PyVarObject__*)inst)->ob_size=size;
- }
- else
- {
- UNLESS(inst=PyObject_NEW(PyObject,(PyTypeObject *)self)) return NULL;
- memset(inst,0,self->tp_basicsize);
- }
-
- inst->ob_refcnt=1;
- inst->ob_type=(PyTypeObject *)self;
- Py_INCREF(self);
-
- if (ClassHasInstDict(self))
- UNLESS(INSTANCE_DICT(inst)=PyDict_New()) goto err;
-
- if ((init=CCL_getattr(self,py__init__,0)))
- {
- UNLESS(args=Py_BuildValue("(O)",inst)) goto err;
- if (arg) UNLESS_ASSIGN(args,PySequence_Concat(args,arg)) goto err;
- UNLESS_ASSIGN(args,PyEval_CallObjectWithKeywords(init,args,kw)) goto err;
- Py_DECREF(args);
- Py_DECREF(init);
- }
- else PyErr_Clear();
-
- if (self->bases && subclass_watcher &&
- ! PyObject_CallMethod(subclass_watcher,"created","O",inst))
- PyErr_Clear();
-
- return inst;
-err:
- Py_DECREF(inst);
- Py_XDECREF(init);
- Py_XDECREF(args);
- return NULL;
-}
-
-static PyObject *
-CCL_repr(PyExtensionClass *self)
-{
- char p[128], *pp;
- PyObject *m;
-
- if ((m=PyObject_GetAttr(OBJECT(self), py__module__)))
- {
- if (! PyObject_IsTrue(m))
- {
- Py_DECREF(m);
- m=0;
- }
- }
- else PyErr_Clear();
-
- sprintf(p,"%p",self);
- if (*p=='0' && p[1]=='x') pp=p+2;
- else pp=p;
-
-
- if (m) ASSIGN(m, JimString_Build("<extension class %s.%s at %s>","Oss",
- m, self->tp_name, pp));
- else m= JimString_Build("<extension class %s at %s>","ss",
- self->tp_name, pp);
-
- return m;
-}
-
-static PyTypeObject ECTypeType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "ExtensionClass Class", /*tp_name*/
- sizeof(PyExtensionClass), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)CCL_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)0, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)CCL_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)CCL_call, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- (getattrofunc)CCL_getattro, /*tp_getattr with object key*/
- (setattrofunc)CCL_setattro, /*tp_setattr with object key*/
- /* Space for future expansion */
- 0L,0L,
- "Class of C classes" /* Documentation string */
-};
-
-/* End of code for ExtensionClass objects */
-/* -------------------------------------------------------- */
-
-/* subclassing code: */
-
-static PyObject *
-subclass_getspecial(PyObject *inst, PyObject *oname)
-{
- PyObject *r=0;
- PyExtensionClass *self;
-
- self=(PyExtensionClass*)(inst->ob_type);
- if (HasInstDict(inst))
- {
- r= INSTANCE_DICT(inst);
- r = PyObject_GetItem(r,oname);
- UNLESS(r)
- {
- PyErr_Clear();
- r=CCL_getattr(self,oname,0);
- }
- }
- else r=CCL_getattr(self,oname,0);
-
- return r;
-}
-
-static PyObject *
-subclass_getattro(PyObject *self, PyObject *name)
-{
- PyObject *r;
-
- if (! name) return NULL;
- UNLESS(r=EC_findiattro(self,name))
- {
- PyErr_Clear();
- r=EC_findiattro(self,py__getattr__);
- if (r) ASSIGN(r,PyObject_CallFunction(r,"O",name));
- if (r && NeedsToBeBound(r))
- ASSIGN(r, CallMethodO(r, py__of__, Build("(O)", self), NULL));
- }
- return r;
-}
-
-static int
-subclass_simple_setattro(PyObject *self, PyObject *name, PyObject *v)
-{
- if (! HasInstDict(self))
- {
- PyErr_SetObject(PyExc_AttributeError, name);
- return -1;
- }
- if (v)
- return PyDict_SetItem(INSTANCE_DICT(self),name,v);
- else
- return PyDict_DelItem(INSTANCE_DICT(self),name);
-}
-
-static int
-subclass_simple_setattr(PyObject *self, char *name, PyObject *v)
-{
- if (! HasInstDict(self))
- {
- PyErr_SetString(PyExc_AttributeError, name);
- return -1;
- }
- if (v)
- return PyDict_SetItemString(INSTANCE_DICT(self),name,v);
- else
- return PyDict_DelItemString(INSTANCE_DICT(self),name);
-}
-
-static int
-subclass_setattr(PyObject *self, PyObject *oname, char *name, PyObject *v)
-{
- PyObject *m=0, *et, *ev, *etb;
-
- if (! name) return -1;
-
- if (!v && (m=subclass_getspecial(self,py__delattr__)))
- {
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OO",self,oname)) return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",oname)) return -1;
- Py_DECREF(m);
- return 0;
- }
-
- UNLESS(m=subclass_getspecial(self,py__setattr__))
- goto default_setattr;
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)setattr_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type))
- {
- UNLESS(-1 != AsCMethod(m)->type->tp_setattr(self,name,v))
- goto dictionary_setattr;
- return 0;
- }
- else
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)setattro_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type))
- {
- UNLESS(-1 != AsCMethod(m)->type->tp_setattro(self,oname,v))
- goto dictionary_setattr;
- return 0;
- }
- if (! v) goto default_setattr;
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OOO",self,oname,v)) return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OO",oname,v)) return -1;
- Py_DECREF(m);
- return 0;
-
-dictionary_setattr:
-
- Py_XDECREF(m);
-
- PyErr_Fetch(&et, &ev, &etb);
- if (et==PyExc_AttributeError)
- {
- char *s;
-
- if (ev && PyString_Check(ev) && (s=PyString_AsString(ev)) &&
- strcmp(s,name)==0)
- {
- Py_XDECREF(et);
- Py_XDECREF(ev);
- Py_XDECREF(etb);
- et=0;
- }
- }
- if (et)
- {
- PyErr_Restore(et,ev,etb);
- return -1;
- }
-
-default_setattr:
-
- PyErr_Clear();
-
- return subclass_simple_setattro(self, oname, v);
-}
-
-static int
-subclass_setattro(PyObject *self, PyObject *name, PyObject *v)
-{
- return subclass_setattr(self,name,PyString_AsString(name),v);
-}
-
-
-static int
-subclass_compare(PyObject *self, PyObject *v)
-{
- PyObject *m;
- long r;
-
- UNLESS(m=subclass_getspecial(self,py__cmp__))
- {
- PyErr_Clear();
- return self-v;
- }
-
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)compare_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- r=AsCMethod(m)->type->tp_compare(self,v);
- else
- {
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OO",self,v))
- return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",v)) return -1;
- r=PyInt_AsLong(m);
- }
- Py_DECREF(m);
- return r;
-}
-
-static long
-subclass_hash(PyObject *self)
-{
- PyObject *m;
- long r;
-
- UNLESS(m=subclass_getspecial(self,py__hash__)) return -1;
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)hash_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- r=AsCMethod(m)->type->tp_hash(self);
- else
- {
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",self))
- return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"")) return -1;
- r=PyInt_AsLong(m);
- }
- Py_DECREF(m);
- return r;
-}
-
-static PyObject *
-default_subclass_repr(PyObject *self)
-{
- char p[128], *pp;
-
- PyErr_Clear();
- sprintf(p,"%p",self);
- if (*p=='0' && p[1]=='x') pp=p+2;
- else pp=p;
- return JimString_Build("<%s instance at %s>","ss",
- self->ob_type->tp_name, pp);
-}
-
-static PyObject *
-subclass_repr(PyObject *self)
-{
- PyObject *m;
-
- UNLESS(m=subclass_getspecial(self,py__repr__))
- return default_subclass_repr(self);
-
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)repr_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- ASSIGN(m,AsCMethod(m)->type->tp_repr(self));
- else if (UnboundEMethod_Check(m))
- ASSIGN(m,PyObject_CallFunction(m,"O",self));
- else
- ASSIGN(m,PyObject_CallFunction(m,""));
- return m;
-}
-
-static PyObject *
-subclass_call(PyObject *self, PyObject *args, PyObject *kw)
-{
- PyObject *m;
-
- UNLESS(m=subclass_getspecial(self,py__call__)) return NULL;
- if (UnboundCMethod_Check(m) && AsCMethod(m)->meth==(PyCFunction)call_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- ASSIGN(m,AsCMethod(m)->type->tp_call(self,args,kw));
- else
- {
- if (UnboundEMethod_Check(m))
- {
- PyObject *a;
- a=Py_BuildValue("(O)",self);
- if (a) ASSIGN(a,PySequence_Concat(a,args));
- if (a) ASSIGN(m,PyEval_CallObjectWithKeywords(m,a,kw));
- else ASSIGN(m,NULL);
- Py_XDECREF(a);
- }
- else
- ASSIGN(m,PyEval_CallObjectWithKeywords(m,args,kw));
- }
- return m;
-}
-
-static PyObject *
-subclass_str(PyObject *self)
-{
- PyObject *m;
-
- UNLESS(m=subclass_getspecial(self,py__str__))
- {
- PyErr_Clear();
- return subclass_repr(self);
- }
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)str_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- ASSIGN(m,AsCMethod(m)->type->tp_str(self));
- else if (UnboundEMethod_Check(m))
- ASSIGN(m,PyObject_CallFunction(m,"O",self));
- else
- ASSIGN(m,PyObject_CallFunction(m,""));
- return m;
-}
-
-#define BINSUB(M,N,A) \
-static PyObject * \
-subclass_ ## M(PyObject *self, PyObject *v) \
-{ \
- PyObject *m; \
- UNLESS(m=subclass_getspecial(self,py__ ## N ## __)) return NULL; \
- if (UnboundCMethod_Check(m) \
- && AsCMethod(m)->meth==(PyCFunction)M ## _by_name \
- && SubclassInstance_Check(self,AsCMethod(m)->type) \
- && ! HasMethodHook(self)) \
- ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_ ## M(self,v)); \
- else if (UnboundEMethod_Check(m)) \
- ASSIGN(m,PyObject_CallFunction(m,"OO",self,v)); \
- else \
- ASSIGN(m,PyObject_CallFunction(m,"O",v)); \
- return m; \
-}
-
-static PyObject *
-subclass_add(PyObject *self, PyObject *v)
-{
- PyObject *m;
-
- UNLESS(m=subclass_getspecial(self,py__add__)) return NULL;
-
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)concat_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- ASSIGN(m,AsCMethod(m)->type->tp_as_sequence->sq_concat(self,v));
- else if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)add_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_add(self,v));
- else if (UnboundEMethod_Check(m))
- ASSIGN(m,PyObject_CallFunction(m,"OO",self,v));
- else
- ASSIGN(m,PyObject_CallFunction(m,"O",v));
-
- return m;
-}
-
-BINSUB(subtract,sub,Subtract)
-
-static PyObject *
-subclass_multiply(PyObject *self, PyObject *v)
-{
- PyObject *m;
-
- UNLESS(m=subclass_getspecial(self,py__mul__)) return NULL;
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)repeat_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- {
- int i;
-
- i=PyInt_AsLong(v);
- if (i==-1 && PyErr_Occurred()) return NULL;
- ASSIGN(m,AsCMethod(m)->type->tp_as_sequence->sq_repeat(self,i));
- }
- else if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)multiply_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_multiply(self,v));
- else if (UnboundEMethod_Check(m))
- ASSIGN(m,PyObject_CallFunction(m,"OO",self,v));
- else
- ASSIGN(m,PyObject_CallFunction(m,"O",v));
- return m;
-}
-
-BINSUB(divide,div,Divide)
-BINSUB(remainder,mod,Remainder)
-
-static PyObject *
-subclass_power(PyObject *self, PyObject *v, PyObject *w)
-{
- PyObject *m;
- UNLESS(m=subclass_getspecial(self,py__pow__)) return NULL;
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)power_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_power(self,v,w));
- else if (UnboundEMethod_Check(m))
- ASSIGN(m,PyObject_CallFunction(m,"OOO",self,v,w));
- else
- ASSIGN(m,PyObject_CallFunction(m,"OO",v,w));
- return m;
-}
-
-BINSUB(divmod,divmod,Divmod)
-BINSUB(lshift,lshift,Lshift)
-BINSUB(rshift,rshift,Rshift)
-BINSUB(and,and,And)
-BINSUB(or,or,Or)
-BINSUB(xor,xor,Xor)
-
-
-static int
-subclass_coerce(PyObject **self, PyObject **v)
-{
- PyObject *m;
- int r;
-
- UNLESS(m=subclass_getspecial(*self,py__coerce__))
- {
- PyErr_Clear();
- Py_INCREF(*self);
- Py_INCREF(*v);
- return 0;
- }
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)coerce_by_name
- && SubclassInstance_Check(*self,AsCMethod(m)->type)
- && ! HasMethodHook(*self))
- r=AsCMethod(m)->type->tp_as_number->nb_coerce(self,v);
- else
- {
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OO",*self,*v)) return -1;
- }
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",*v)) return -1;
- if (m==Py_None) r=-1;
- else
- {
- PyArg_ParseTuple(m,"OO",self,v);
- Py_INCREF(*self);
- Py_INCREF(*v);
- r=0;
- }
- }
- Py_DECREF(m);
- return r;
-}
-
-#define UNSUB(M,N) \
-static PyObject * \
-subclass_ ## M(PyObject *self) \
-{ \
- PyObject *m; \
- UNLESS(m=subclass_getspecial(self,py__ ## N ## __)) return NULL; \
- if (UnboundCMethod_Check(m) \
- && AsCMethod(m)->meth==(PyCFunction)M ## _by_name \
- && SubclassInstance_Check(self,AsCMethod(m)->type) \
- && ! HasMethodHook(self)) \
- ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_ ## M(self)); \
- else if (UnboundEMethod_Check(m)) \
- ASSIGN(m,PyObject_CallFunction(m,"O",self)); \
- else \
- ASSIGN(m,PyObject_CallFunction(m,"")); \
- return m; \
-}
-
-UNSUB(negative, neg)
-UNSUB(positive, pos)
-UNSUB(absolute, abs)
-
-static int
-subclass_nonzero(PyObject *self)
-{
- PyObject *m;
- long r;
-
- UNLESS(m=subclass_getspecial(self,py__nonzero__))
- { /* We are being asked is we are true
- Check out len, and if that fails, say we are true.
- */
- PyErr_Clear();
- UNLESS(m=subclass_getspecial(self,py__len__))
- {
- PyErr_Clear();
- return 1;
- }
- }
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)nonzero_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- r=AsCMethod(m)->type->tp_as_number->nb_nonzero(self);
- else
- {
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",self))
- return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"")) return -1;
- r=PyInt_AsLong(m);
- }
- Py_DECREF(m);
- return r;
-}
-
-UNSUB(invert, inv)
-UNSUB(int, int)
-UNSUB(long, long)
-UNSUB(float, float)
-UNSUB(oct, oct)
-UNSUB(hex, hex)
-
-#undef UNSUB
-#undef BINSUB
-
-
-static PyNumberMethods subclass_as_number = {
- (binaryfunc)subclass_add, /*nb_add*/
- (binaryfunc)subclass_subtract, /*nb_subtract*/
- (binaryfunc)subclass_multiply, /*nb_multiply*/
- (binaryfunc)subclass_divide, /*nb_divide*/
- (binaryfunc)subclass_remainder, /*nb_remainder*/
- (binaryfunc)subclass_divmod, /*nb_divmod*/
- (ternaryfunc)subclass_power, /*nb_power*/
- (unaryfunc)subclass_negative, /*nb_negative*/
- (unaryfunc)subclass_positive, /*nb_positive*/
- (unaryfunc)subclass_absolute, /*nb_absolute*/
- (inquiry)subclass_nonzero, /*nb_nonzero*/
- (unaryfunc)subclass_invert, /*nb_invert*/
- (binaryfunc)subclass_lshift, /*nb_lshift*/
- (binaryfunc)subclass_rshift, /*nb_rshift*/
- (binaryfunc)subclass_and, /*nb_and*/
- (binaryfunc)subclass_xor, /*nb_xor*/
- (binaryfunc)subclass_or, /*nb_or*/
- (coercion)subclass_coerce, /*nb_coerce*/
- (unaryfunc)subclass_int, /*nb_int*/
- (unaryfunc)subclass_long, /*nb_long*/
- (unaryfunc)subclass_float, /*nb_float*/
- (unaryfunc)subclass_oct, /*nb_oct*/
- (unaryfunc)subclass_hex, /*nb_hex*/
-};
-
-static long
-subclass_length(PyObject *self)
-{
- PyObject *m;
- long r;
- PyExtensionClass *t;
-
- UNLESS(m=subclass_getspecial(self,py__len__))
- {
- /* Hm. Maybe we are being checked to see if we are true.
-
- Check to see if we have a __getitem__. If we don't, then
- answer that we are true.
- */
- PyErr_Clear();
- if ((m=subclass_getspecial(self,py__getitem__)))
- {
- /* Hm, we have getitem, must be error */
- Py_DECREF(m);
- PyErr_SetObject(PyExc_AttributeError, py__len__);
- return -1;
- }
- PyErr_Clear();
- return subclass_nonzero(self);
- }
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)length_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- {
- t=(PyExtensionClass*)AsCMethod(m)->type;
- Py_DECREF(m);
- if (t->tp_as_sequence)
- return t->tp_as_sequence->sq_length(self);
- else
- return t->tp_as_mapping->mp_length(self);
- }
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",self)) return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"")) return -1;
- r=PyInt_AsLong(m);
- Py_DECREF(m);
- return r;
-}
-
-static PyObject *
-subclass_item(PyObject *self, int index)
-{
- PyObject *m;
- PyExtensionClass *t;
-
- UNLESS(m=subclass_getspecial(self,py__getitem__)) return NULL;
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)getitem_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- {
- t=(PyExtensionClass*)AsCMethod(m)->type;
- if (t->tp_as_sequence && t->tp_as_sequence->sq_item)
- {
- Py_DECREF(m);
- return t->tp_as_sequence->sq_item(self,index);
- }
- }
- if (UnboundEMethod_Check(m))
- ASSIGN(m,PyObject_CallFunction(m,"Oi",self,index));
- else
- ASSIGN(m,PyObject_CallFunction(m,"i",index));
- return m;
-}
-
-static PyObject *
-subclass_slice(PyObject *self, int i1, int i2)
-{
- PyObject *m;
-
- UNLESS(m=subclass_getspecial(self,py__getslice__)) return NULL;
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)slice_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- ASSIGN(m,AsCMethod(m)->type->tp_as_sequence->sq_slice(self,i1,i2));
- else if (UnboundEMethod_Check(m))
- ASSIGN(m,PyObject_CallFunction(m,"Oii",self,i1,i2));
- else
- ASSIGN(m,PyObject_CallFunction(m,"ii",i1,i2));
- return m;
-}
-
-static long
-subclass_ass_item(PyObject *self, int index, PyObject *v)
-{
- PyObject *m;
- PyExtensionClass *t;
-
- if (! v && (m=subclass_getspecial(self,py__delitem__)))
- {
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"Oi",self,index)) return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"i",index)) return -1;
- Py_DECREF(m);
- return 0;
- }
-
- UNLESS(m=subclass_getspecial(self,py__setitem__)) return -1;
- if (UnboundCMethod_Check(m) &&
- AsCMethod(m)->meth==(PyCFunction)setitem_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- {
- t=(PyExtensionClass*)AsCMethod(m)->type;
- if (t->tp_as_sequence && t->tp_as_sequence->sq_ass_item)
- {
- Py_DECREF(m);
- return t->tp_as_sequence->sq_ass_item(self,index,v);
- }
- }
- if (! v)
- {
- PyErr_SetObject(PyExc_AttributeError, py__delitem__);
- return -1;
- }
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OiO",self,index,v)) return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"iO",index,v)) return -1;
- Py_DECREF(m);
- return 0;
-}
-
-static int
-subclass_ass_slice(PyObject *self, int i1, int i2, PyObject *v)
-{
- PyObject *m;
- long r;
-
- if (! v && (m=subclass_getspecial(self,py__delslice__)))
- {
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"Oii",self,i1,i2)) return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"ii",i1,i2)) return -1;
- Py_DECREF(m);
- return 0;
- }
-
- UNLESS(m=subclass_getspecial(self,py__setslice__)) return -1;
- if (UnboundCMethod_Check(m) &&
- AsCMethod(m)->meth==(PyCFunction)ass_slice_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- {
- r=AsCMethod(m)->type->tp_as_sequence->sq_ass_slice(self,i1,i2,v);
- Py_DECREF(m);
- return r;
- }
-
- if (! v)
- {
- PyErr_SetObject(PyExc_AttributeError, py__delslice__);
- return -1;
- }
-
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OiiO",self,i1,i2,v))
- return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"iiO",i1,i2,v)) return -1;
- Py_DECREF(m);
- return 0;
-}
-
-static PyObject *
-subclass_repeat(PyObject *self, int v)
-{
- PyObject *m;
-
- UNLESS(m=subclass_getspecial(self,py__mul__)) return NULL;
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)repeat_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- ASSIGN(m,AsCMethod(m)->type->tp_as_sequence->sq_repeat(self,v));
- else if (UnboundEMethod_Check(m))
- ASSIGN(m,PyObject_CallFunction(m,"Oi",self,v));
- else
- ASSIGN(m,PyObject_CallFunction(m,"i",v));
- return m;
-}
-
-PySequenceMethods subclass_as_sequence = {
- (inquiry)subclass_length, /*sq_length*/
- (binaryfunc)subclass_add, /*sq_concat*/
- (intargfunc)subclass_repeat, /*sq_repeat*/
- (intargfunc)subclass_item, /*sq_item*/
- (intintargfunc)subclass_slice, /*sq_slice*/
- (intobjargproc)subclass_ass_item, /*sq_ass_item*/
- (intintobjargproc)subclass_ass_slice, /*sq_ass_slice*/
-};
-
-static PyObject *
-subclass_subscript(PyObject *self, PyObject *key)
-{
- PyObject *m;
- PyExtensionClass *t;
-
- UNLESS(m=subclass_getspecial(self,py__getitem__)) return NULL;
- if (UnboundCMethod_Check(m) &&
- AsCMethod(m)->meth==(PyCFunction)getitem_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- {
- t=(PyExtensionClass*)AsCMethod(m)->type;
- if (t->tp_as_mapping && t->tp_as_mapping->mp_subscript)
- {
- Py_DECREF(m);
- return t->tp_as_mapping->mp_subscript(self,key);
- }
- else if (t->tp_as_sequence && t->tp_as_sequence->sq_item)
- {
- int i, l;
-
- Py_DECREF(m);
-
- UNLESS(PyInt_Check(key))
- {
- PyErr_SetString(PyExc_TypeError, "sequence subscript not int");
- return NULL;
- }
- i=PyInt_AsLong(key);
- if (i < 0)
- {
- if ((l=PyObject_Length(self)) < 0) return NULL;
- i+=l;
- }
- return t->tp_as_sequence->sq_item(self,i);
- }
- }
- if (UnboundEMethod_Check(m))
- ASSIGN(m,PyObject_CallFunction(m,"OO",self,key));
- else
- ASSIGN(m,PyObject_CallFunction(m,"O",key));
- return m;
-}
-
-static long
-subclass_ass_subscript(PyObject *self, PyObject *index, PyObject *v)
-{
- PyObject *m;
- PyExtensionClass *t;
-
- if (! v && (m=subclass_getspecial(self,py__delitem__)))
- {
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OO",self,index)) return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",index)) return -1;
- Py_DECREF(m);
- return 0;
- }
-
- UNLESS(m=subclass_getspecial(self,py__setitem__)) return -1;
- if (UnboundCMethod_Check(m) &&
- AsCMethod(m)->meth==(PyCFunction)setitem_by_name
- && SubclassInstance_Check(self,AsCMethod(m)->type)
- && ! HasMethodHook(self))
- {
- t=(PyExtensionClass*)AsCMethod(m)->type;
- if (t->tp_as_mapping && t->tp_as_mapping->mp_ass_subscript)
- {
- Py_DECREF(m);
- return t->tp_as_mapping->mp_ass_subscript(self,index,v);
- }
- else if (t->tp_as_sequence && t->tp_as_sequence->sq_ass_item)
- {
- int i, l;
-
- Py_DECREF(m);
-
- UNLESS(PyInt_Check(index))
- {
- PyErr_SetString(PyExc_TypeError, "sequence subscript not int");
- return -1;
- }
- i=PyInt_AsLong(index);
- if (i < 0)
- {
- if ((l=PyObject_Length(self)) < 0) return -1;
- i+=l;
- }
- return t->tp_as_sequence->sq_ass_item(self,i,v);
- }
- }
- if (! v)
- {
- PyErr_SetObject(PyExc_AttributeError, py__delitem__);
- return -1;
- }
- if (UnboundEMethod_Check(m))
- {
- UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OOO",self,index,v)) return -1;
- }
- else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OO",index,v)) return -1;
- Py_DECREF(m);
- return 0;
-}
-
-PyMappingMethods subclass_as_mapping = {
- (inquiry)subclass_length, /*mp_length*/
- (binaryfunc)subclass_subscript, /*mp_subscript*/
- (objobjargproc)subclass_ass_subscript, /*mp_ass_subscript*/
-};
-
-static int
-dealloc_base(PyObject *inst, PyExtensionClass* self)
-{
- int i,l;
- PyObject *t;
-
- l=PyTuple_Size(self->bases);
- for (i=0; i < l; i++)
- {
- t=PyTuple_GET_ITEM(self->bases, i);
- if (ExtensionClass_Check(t))
- {
- if (AsExtensionClass(t)->bases)
- {
- if (dealloc_base(inst,AsExtensionClass(t))) return 1;
- }
- else
- {
- if (((PyExtensionClass*)t)->tp_dealloc)
- {
- ((PyExtensionClass*)t)->tp_dealloc(inst);
- return 1;
- }
- }
- }
- }
- return 0;
-}
-
-static void
-subclass_dealloc(PyObject *self)
-{
- PyObject *m, *t, *v, *tb;
- int base_dealloced;
-
-#ifdef TRACE_DEALLOC
- fprintf(stderr,"Deallocating a %s\n", self->ob_type->tp_name);
-#endif
-
- PyErr_Fetch(&t,&v,&tb);
- Py_INCREF(self); /* Give us a new lease on life */
-
- if (subclass_watcher &&
- ! PyObject_CallMethod(subclass_watcher,"destroying","O",self))
- PyErr_Clear();
-
-
- if ((m=subclass_getspecial(self,py__del__)))
- {
- if (UnboundEMethod_Check(m))
- ASSIGN(m,PyObject_CallFunction(m,"O",self));
- else
- ASSIGN(m,PyObject_CallFunction(m,""));
- Py_XDECREF(m);
- }
-
- PyErr_Clear();
-
- if (--self->ob_refcnt > 0)
- {
- PyErr_Restore(t,v,tb);
- return; /* we added a reference; don't delete now */
- }
-
- if (HasInstDict(self)) Py_XDECREF(INSTANCE_DICT(self));
-
- /* See if there was a dealloc handler in a (C) base class.
- If there was, then it deallocates the object and we
- get a true value back.
-
- Note that if there *is* a base class dealloc, then
- *it* should decref the class.
- */
- base_dealloced=dealloc_base(self,(PyExtensionClass*)self->ob_type);
-
- /* We only deallocate ourselves if a base class didn't */
- UNLESS(base_dealloced)
- {
- Py_DECREF(self->ob_type);
- PyMem_DEL(self);
- }
-
- PyErr_Restore(t,v,tb);
-}
-
-static void
-datafull_baseclassesf(PyExtensionClass *type, PyObject **c1, PyObject **c2)
-{
- /* Find the number of classes that have data and return them.
- There should be no more than one.
- */
- int l, i;
- PyObject *base;
-
- l=PyTuple_Size(type->bases);
- for (i=0; i < l && ! (*c1 && *c2); i++)
- {
- base=PyTuple_GET_ITEM(type->bases, i);
- if (ExtensionClass_Check(base))
- {
- if (AsExtensionClass(base)->bases)
- datafull_baseclassesf(AsExtensionClass(base),c1,c2);
- else
- {
- if (AsExtensionClass(base)->tp_basicsize >
- sizeof(PyPureMixinObject) ||
- AsExtensionClass(base)->tp_itemsize > 0)
- {
- if (! *c1)
- *c1=base;
- else if (*c1 != base)
- *c2=base;
- }
- }
- }
- }
-}
-
-static int
-datafull_baseclasses(PyExtensionClass *type)
-{
- PyObject *c1=0, *c2=0;
- datafull_baseclassesf(type, &c1, &c2);
- if (c2) return 2;
- if (c1) return 1;
- return 0;
-}
-
-static PyObject *
-datafull_baseclass(PyExtensionClass *type)
-{
- /* Find the baseclass that has data and. There should be only one. */
- int l, i;
- PyObject *base, *dbase;
-
- l=PyTuple_Size(type->bases);
- for (i=0; i < l; i++)
- {
- base=PyTuple_GET_ITEM(type->bases, i);
- if (ExtensionClass_Check(base))
- {
- if (AsExtensionClass(base)->bases)
- {
- if ((dbase=datafull_baseclass(AsExtensionClass(base))))
- return dbase;
- }
- else
- {
- if (AsExtensionClass(base)->tp_basicsize >
- sizeof(PyPureMixinObject) ||
- AsExtensionClass(base)->tp_itemsize > 0)
- return base;
- }
- }
- }
- return NULL;
-}
-
-static PyObject *
-extension_baseclass(PyExtensionClass *type)
-{
- /* Find the first immediate base class that is an extension class */
- int l, i;
- PyObject *base;
-
- l=PyTuple_Size(type->bases);
- for (i=0; i < l; i++)
- {
- base=PyTuple_GET_ITEM(type->bases, i);
- if (ExtensionClass_Check(base)) return base;
- }
- return JimErr_Format(PyExc_TypeError,
- "No extension class found in subclass", NULL);
-}
-
-static int
-subclass_hasattr(PyExtensionClass *type, PyObject *name)
-{
- PyObject *o;
-
- if ((o=CCL_getattro(type,name)))
- {
- Py_DECREF(o);
- return 1;
- }
- PyErr_Clear();
- return 0;
-}
-
-static void
-subclass_init_getattr(PyExtensionClass *self, PyObject *methods)
-{
- PyObject *m;
-
- if ((m=CCL_getattr(self,py__getattr__,0)))
- {
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)getattr_by_name
- && Subclass_Check(self,AsCMethod(m)->type))
- {
- self->tp_getattr=AsCMethod(m)->type->tp_getattr;
- }
- else if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)getattro_by_name
- && Subclass_Check(self,AsCMethod(m)->type))
- {
- self->tp_getattro=AsCMethod(m)->type->tp_getattro;
- }
- else
- {
- PyObject_SetItem(methods,py__getattr__,m);
- self->tp_getattro=subclass_getattro;
- }
- Py_DECREF(m);
- }
- else
- {
- PyErr_Clear();
- self->tp_getattro=EC_findiattro;
- }
-}
-
-static void
-subclass_init_setattr(PyExtensionClass *self, PyObject *methods)
-{
- PyObject *m;
-
- if ((m=CCL_getattr(self,py__setattr__,0)))
- {
- if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)setattr_by_name
- && Subclass_Check(self,AsCMethod(m)->type))
- {
- self->tp_setattr=AsCMethod(m)->type->tp_setattr;
- }
- else if (UnboundCMethod_Check(m)
- && AsCMethod(m)->meth==(PyCFunction)setattro_by_name
- && Subclass_Check(self,AsCMethod(m)->type))
- {
- self->tp_setattro=AsCMethod(m)->type->tp_setattro;
- }
- else
- {
- PyObject_SetItem(methods,py__setattr__,m);
- self->tp_setattro=subclass_setattro;
- }
- Py_DECREF(m);
- }
- else
- {
- PyErr_Clear();
- self->tp_setattro=subclass_simple_setattro;
- }
-}
-
-static PyObject *
-CopyMethods(PyExtensionClass *type, PyObject *base_methods)
-{
- PyObject *methods, *key, *v;
- int pos;
-
- UNLESS(type->class_dictionary && PyDict_Check(base_methods) &&
- ExtensionInstance_Check(type->class_dictionary))
- {
- Py_INCREF(base_methods);
- return base_methods;
- }
-
- UNLESS(methods=
- PyObject_CallObject((PyObject*)type->class_dictionary->ob_type, NULL))
- return NULL;
-
- for (pos=0; PyDict_Next(base_methods, &pos, &key, &v); )
- UNLESS(0 <= PyObject_SetItem(methods,key,v)) goto err;
-
- return methods;
-
-err:
- Py_DECREF(methods);
- return NULL;
-}
-
-/* Constructor for building subclasses of C classes.
-
- That is, we want to build a C class object that described a
- subclass of a built-in type.
- */
-static PyObject *
-subclass__init__(PyExtensionClass *self, PyObject *args)
-{
- PyObject *bases, *methods, *class_init;
- PyExtensionClass *type;
- char *name, *p;
- int l;
-
- UNLESS(PyArg_ParseTuple(args,"sOO", &name, &bases, &methods)) return NULL;
- l=strlen(name)+1;
- UNLESS(p=(char*)malloc(l*sizeof(char))) return PyErr_NoMemory();
- memcpy(p,name,l);
- name=p;
-
- UNLESS(PyTuple_Check(bases) && PyTuple_Size(bases))
- {
- PyErr_SetString
- (PyExc_TypeError,
- "second argument must be a tuple of 1 or more base classes");
- }
-
- self->bases=bases;
- Py_INCREF(bases);
-
- if (datafull_baseclasses(self) > 1)
- {
- PyErr_SetString(PyExc_TypeError, "too many datafull base classes");
- return NULL;
- }
- UNLESS(type=(PyExtensionClass *)datafull_baseclass(self))
- UNLESS(type=(PyExtensionClass *)extension_baseclass(self)) return NULL;
-
- self->tp_name=name;
-
- UNLESS(self->class_dictionary=CopyMethods(type,methods)) return NULL;
-
-#define copy_member(M) self->M=type->M
- copy_member(ob_size);
- copy_member(class_flags);
- /* mark subclass as a python one, so subclass structures are freed on
- * deallocation */
- self->class_flags |= EXTENSIONCLASS_PYSUBCLASS_FLAG;
-
- copy_member(tp_itemsize);
- copy_member(tp_print);
- self->tp_dealloc=subclass_dealloc;
-
- subclass_init_getattr(self,methods);
- subclass_init_setattr(self,methods);
-
-#define subclass_set(OP,N) \
- self->tp_ ##OP = subclass_ ##OP
-
- subclass_set(compare,cmp);
- subclass_set(repr,repr);
-
- if (subclass_hasattr(self,py__of__))
- self->class_flags |= EXTENSIONCLASS_BINDABLE_FLAG;
-
- if (subclass_hasattr(self,py__call_method__))
- self->class_flags |= EXTENSIONCLASS_METHODHOOK_FLAG;
-
- UNLESS(self->class_flags & EXTENSIONCLASS_NOINSTDICT_FLAG)
- self->class_flags |= EXTENSIONCLASS_INSTDICT_FLAG;
-
- if (type->bases || ! ClassHasInstDict(self))
- copy_member(tp_basicsize);
- else
- {
- self->tp_basicsize=type->tp_basicsize/sizeof(PyObject*)*sizeof(PyObject*);
- if (self->tp_basicsize < type->tp_basicsize)
- self->tp_basicsize += sizeof(PyObject*); /* To align on PyObject */
- self->tp_basicsize += sizeof(PyObject*); /* For instance dictionary */
- }
-
-
- self->tp_as_number=(PyNumberMethods*)malloc(sizeof(PyNumberMethods));
- UNLESS(self->tp_as_number) return PyErr_NoMemory();
- *(self->tp_as_number)=subclass_as_number;
-
- self->tp_as_sequence=
- (PySequenceMethods*)malloc(sizeof(PySequenceMethods));
- UNLESS(self->tp_as_sequence) return PyErr_NoMemory();
- *(self->tp_as_sequence)=subclass_as_sequence;
-
- self->tp_as_mapping=(PyMappingMethods*)malloc(sizeof(PyMappingMethods));
- UNLESS(self->tp_as_mapping) return PyErr_NoMemory();
- *(self->tp_as_mapping)=subclass_as_mapping;
-
- subclass_set(hash,hash);
- subclass_set(call,call);
- subclass_set(str,str);
- self->tp_doc=0;
-
- /* Implement __module__=__name__ */
- if (PyDict_GetItem(methods, py__module__) == NULL)
- {
- PyObject *globals = PyEval_GetGlobals();
- if (globals != NULL)
- {
- PyObject *modname = PyDict_GetItem(globals, py__name__);
- if (modname != NULL) {
- if (PyDict_SetItem(methods, py__module__, modname) < 0)
- return NULL;
- }
- }
- }
-
- /* Check for and use __class_init__ */
- if ((class_init=PyObject_GetAttrString(AsPyObject(self),"__class_init__")))
- {
- UNLESS_ASSIGN(class_init,PyObject_GetAttrString(class_init,"im_func"))
- return NULL;
- UNLESS_ASSIGN(class_init,PyObject_CallFunction(class_init,"O",self))
- return NULL;
- Py_DECREF(class_init);
- }
- else
- PyErr_Clear();
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-struct PyMethodDef ExtensionClass_methods[] = {
- {"__init__",(PyCFunction)subclass__init__,1,""},
- {NULL, NULL} /* sentinel */
-};
-
-static PyExtensionClass ECType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "ExtensionClass", /*tp_name*/
- sizeof(PyExtensionClass), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)CCL_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)0, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)CCL_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)CCL_call, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- (getattrofunc)CCL_getattro, /*tp_getattr with object key*/
- (setattrofunc)CCL_setattro, /*tp_setattr with object key*/
- /* Space for future expansion */
- 0L,0L,
- "C classes", /* Documentation string */
- METHOD_CHAIN(ExtensionClass_methods)
-};
-
-/* List of methods defined in the module */
-
-static PyObject *
-set_subclass_watcher(PyObject *ignored, PyObject *args)
-{
- PyObject *old, *sw=0;
-
- UNLESS(PyArg_ParseTuple(args,"|O",&sw)) return NULL;
- old=subclass_watcher;
- subclass_watcher=sw;
- if (sw) Py_INCREF(sw);
- if (old) return old;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static struct PyMethodDef CC_methods[] = {
- {"subclass_watcher", (PyCFunction)set_subclass_watcher, 1,
- "subclass_watcher(ob) -- "
- "Register an object to watch subclass instance events"
- },
- {NULL, NULL} /* sentinel */
-};
-
-static int
-export_type(PyObject *dict, char *name, PyExtensionClass *typ)
-{
- initializeBaseExtensionClass(typ);
-
- if (PyErr_Occurred()) return -1;
-
- if (PyDict_GetItem(typ->class_dictionary, py__module__) == NULL)
- {
- PyObject *modname = PyDict_GetItem(dict, py__name__);
- if (modname != NULL) {
- if (PyDict_SetItem(typ->class_dictionary, py__module__, modname) < 0)
- return -1;
- }
- }
- PyErr_Clear();
-
- return PyMapping_SetItemString(dict,name,(PyObject*)typ);
-}
-
-/* bases is a tuple of base classes. This function absorbs the reference */
-static int
-export_subclassed_type(PyObject *dict, char *name, PyExtensionClass *typ,
- PyObject *bases)
-{
- initializeBaseExtensionClass(typ);
-
- if (PyErr_Occurred()) return -1;
-
- /* set this up as a subclassed ExtensionClass */
- UNLESS (bases && PyTuple_Check(bases) && PyTuple_Size(bases)) {
- PyErr_SetString(PyExc_TypeError,
- "second argument must be a tuple of 1 or more base classes");
- return -1;
- }
- typ->bases = bases;
-
- if (PyDict_GetItem(typ->class_dictionary, py__module__) == NULL)
- {
- PyObject *modname = PyDict_GetItem(dict, py__name__);
- if (modname != NULL) {
- if (PyDict_SetItem(typ->class_dictionary, py__module__, modname) < 0)
- return -1;
- }
- }
- PyErr_Clear();
-
- return PyMapping_SetItemString(dict,name,(PyObject*)typ);
-}
-
-static struct ExtensionClassCAPIstruct
-TrueExtensionClassCAPI = {
- export_type,
- EC_findiattrs,
- EC_findiattro,
- subclass_simple_setattr,
- subclass_simple_setattro,
- (PyObject*)&ECType,
- (PyObject*)&PMethodType,
- PMethod_New,
- CMethod_issubclass,
- export_subclassed_type,
-};
-
-void
-initExtensionClass()
-{
- PyObject *m, *d;
- char *rev="$Revision$";
- PURE_MIXIN_CLASS(Base, "Minimalbase class for Extension Classes", NULL);
-
- PMethodType.ob_type=&PyType_Type;
- CMethodType.ob_type=&PyType_Type;
- ECTypeType.ob_type=&PyType_Type;
- ECType.ob_type=&ECTypeType;
-
- UNLESS(concat_fmt=PyString_FromString("%s%s"));
-
- m = Py_InitModule4("ExtensionClass", CC_methods,
- ExtensionClass_module_documentation,
- (PyObject*)NULL,PYTHON_API_VERSION);
-
- d = PyModule_GetDict(m);
- PyDict_SetItemString(d,"__version__",
- PyString_FromStringAndSize(rev+11,strlen(rev+11)-2));
-
- init_py_names();
-
- if (0) PyCObject_Import14("this will go away", "in 1.5 :-)");
-
- initializeBaseExtensionClass(&ECType);
- PyDict_SetItemString(d, "ExtensionClass", (PyObject*)&ECType);
-
- initializeBaseExtensionClass(&BaseType);
- PyDict_SetItemString(d, "Base", (PyObject*)&BaseType);
-
- PyDict_SetItemString(d, "PythonMethodType", (PyObject*)&PMethodType);
- PyDict_SetItemString(d, "ExtensionMethodType", (PyObject*)&CMethodType);
-
- /* Export C attribute lookup API */
- PyExtensionClassCAPI=&TrueExtensionClassCAPI;
- PyDict_SetItemString(d, "CAPI",
- PyCObject_FromVoidPtr(PyExtensionClassCAPI,NULL));
-
- CHECK_FOR_ERRORS("can't initialize module ExtensionClass");
-}
diff --git a/ExtensionClass.h b/ExtensionClass.h
deleted file mode 100644
index 7a6af6ca..00000000
--- a/ExtensionClass.h
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
-
- $Id$
-
- Extension Class Definitions
-
- Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- o Redistributions of source code must retain the above copyright
- notice, this list of conditions, and the disclaimer that follows.
-
- o Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions, and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
- o Neither the name of Digital Creations nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-
- THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
- IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
- CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- DAMAGE.
-
- Implementing base extension classes
-
- A base extension class is implemented in much the same way that an
- extension type is implemented, except:
-
- - The include file, 'ExtensionClass.h', must be included.
-
- - The type structure is declared to be of type
- 'PyExtensionClass', rather than of type 'PyTypeObject'.
-
- - The type structure has an additional member that must be defined
- after the documentation string. This extra member is a method chain
- ('PyMethodChain') containing a linked list of method definition
- ('PyMethodDef') lists. Method chains can be used to implement
- method inheritance in C. Most extensions don't use method chains,
- but simply define method lists, which are null-terminated arrays
- of method definitions. A macro, 'METHOD_CHAIN' is defined in
- 'ExtensionClass.h' that converts a method list to a method chain.
- (See the example below.)
-
- - Module functions that create new instances must be replaced by an
- '__init__' method that initializes, but does not create storage for
- instances.
-
- - The extension class must be initialized and exported to the module
- with::
-
- PyExtensionClass_Export(d,"name",type);
-
- where 'name' is the module name and 'type' is the extension class
- type object.
-
- Attribute lookup
-
- Attribute lookup is performed by calling the base extension class
- 'getattr' operation for the base extension class that includes C
- data, or for the first base extension class, if none of the base
- extension classes include C data. 'ExtensionClass.h' defines a
- macro 'Py_FindAttrString' that can be used to find an object's
- attributes that are stored in the object's instance dictionary or
- in the object's class or base classes::
-
- v = Py_FindAttrString(self,name);
-
- In addition, a macro is provided that replaces 'Py_FindMethod'
- calls with logic to perform the same sort of lookup that is
- provided by 'Py_FindAttrString'.
-
- Linking
-
- The extension class mechanism was designed to be useful with
- dynamically linked extension modules. Modules that implement
- extension classes do not have to be linked against an extension
- 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@digicool.com
-
- (540) 371-6909
-
-*/
-
-#ifndef EXTENSIONCLASS_H
-#define EXTENSIONCLASS_H
-
-#include "Python.h"
-#include "import.h"
-
-/* Declarations for objects of type ExtensionClass */
-
-typedef struct {
- PyObject_VAR_HEAD
- char *tp_name; /* For printing */
- int tp_basicsize, tp_itemsize; /* For allocation */
-
- /* Methods to implement standard operations */
-
- destructor tp_dealloc;
- printfunc tp_print;
- getattrfunc tp_getattr;
- setattrfunc tp_setattr;
- cmpfunc tp_compare;
- reprfunc tp_repr;
-
- /* Method suites for standard classes */
-
- PyNumberMethods *tp_as_number;
- PySequenceMethods *tp_as_sequence;
- PyMappingMethods *tp_as_mapping;
-
- /* More standard operations (at end for binary compatibility) */
-
- hashfunc tp_hash;
- ternaryfunc tp_call;
- reprfunc tp_str;
- getattrofunc tp_getattro;
- setattrofunc tp_setattro;
- /* Space for future expansion */
- long tp_xxx3;
- long tp_xxx4;
-
- char *tp_doc; /* Documentation string */
-
-#ifdef COUNT_ALLOCS
- /* these must be last */
- int tp_alloc;
- int tp_free;
- int tp_maxalloc;
- struct _typeobject *tp_next;
-#endif
-
- /* Here's the juicy stuff: */
-
- /* Put your method chain here. If you just have a method
- list, you can use the METHON_CHAIN macro to make a chain.
- */
- PyMethodChain methods;
-
- /* You may set certain flags here. */
- long class_flags;
-
- /* 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_PYSUBCLASS_FLAG 1 << 7
-
- /* 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
-
- /* This is the class dictionary, which is normally created for you.
- If you wish, you can provide your own class dictionary object.
- If you do provide your own class dictionary, it *must* be
- a mapping object. If the object given is also an extension
- instance, then sub-class instance dictionaries will be created
- by calling the class dictionary's class with zero argumemts.
- Otherwise, subclass dictionaries will be of the default type.
- */
- PyObject *class_dictionary;
-
- /* You should not set the remaining members. */
- PyObject *bases;
- PyObject *reserved;
-} PyExtensionClass;
-
-/* 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 Py_FindMethod(M,SELF,NAME) \
- (PyExtensionClassCAPI->getattrs((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) \
- (PyExtensionClassCAPI->getattrs((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) (PyExtensionClassCAPI->getattro((SELF),(NAME)))
-
-/* Do method or attribute assignment for an attribute name given by a
- C string using extension class meta-data.
-
- This macro is used in base class implementations of tp_setattr 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.
-
- Note that in Python 1.4, a setattr operation may be provided that
- uses an object argument. Classes that support this new operation
- should use PyEC_SetAttr.
- */
-#define PyEC_SetAttrString(SELF,NAME,V) \
- (PyExtensionClassCAPI->setattrs((SELF),(NAME),(V)))
-
-/* 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) \
- (PyExtensionClassCAPI->setattro((SELF),(NAME),(V)))
-
-/* Import the ExtensionClass CAPI */
-#define ExtensionClassImported \
- (PyExtensionClassCAPI=PyCObject_Import("ExtensionClass","CAPI"))
-
-/* Make sure the C interface has been imported and import it if necessary.
- This can be used in an if.
- */
-#define MakeSureExtensionClassImported \
- (PyExtensionClassCAPI || \
- (PyExtensionClassCAPI=PyCObject_Import("ExtensionClass","CAPI")))
-
-
-/* Export an Extension Base class in a given module dictionary with a
- given name and ExtensionClass structure.
- */
-#define PyExtensionClass_Export(D,N,T) \
- if(PyExtensionClassCAPI || \
- (PyExtensionClassCAPI= (struct ExtensionClassCAPIstruct*) \
- PyCObject_Import("ExtensionClass","CAPI"))) \
- { PyExtensionClassCAPI->Export(D,N,&T); }
-
-/* Export an Extension Subclass class in a given module dictionary with a
- given name, ExtensionClass structure and set of base classes. It is
- up to the programmer to make sure that the instance structures of the
- base classes are compatible with that of the new class.
- */
-#define PyExtensionClass_ExportSubclass(D,N,T,B) \
- if(PyExtensionClassCAPI || \
- (PyExtensionClassCAPI= (struct ExtensionClassCAPIstruct*) \
- PyCObject_Import("ExtensionClass","CAPI"))) \
- { PyExtensionClassCAPI->ExportSubclass(D,N,&T,B); }
-
-/* Export an Extension Subclass class in a given module dictionary with a
- given name, ExtensionClass structure and single base class. It is up to
- the programmer to make sure that the instance structures of the base
- classes are compatible with that of the new class.
- */
-#define PyExtensionClass_ExportSubclassSingle(D,N,T,B) \
- PyExtensionClass_ExportSubclass(D, N, T, Py_BuildValue("(O)",(PyObject*)&B))
-
-/* Convert a method list to a method chain. */
-#define METHOD_CHAIN(DEF) { DEF, NULL }
-
-/* The following macro checks whether a type is an extension class: */
-#define PyExtensionClass_Check(TYPE) \
- ((PyObject*)(TYPE)->ob_type==PyExtensionClassCAPI->ExtensionClassType)
-
-/* The following macro checks whether an instance is an extension instance: */
-#define PyExtensionInstance_Check(INST) \
- ((PyObject*)(INST)->ob_type->ob_type== \
- PyExtensionClassCAPI->ExtensionClassType)
-
-/* The following macro checks for errors and prints out an error
- message that is more informative than the one given by Python when
- an extension module initialization fails.
- */
-#define CHECK_FOR_ERRORS(MESS) \
-if(PyErr_Occurred()) { \
- PyObject *__sys_exc_type, *__sys_exc_value, *__sys_exc_traceback; \
- PyErr_Fetch( &__sys_exc_type, &__sys_exc_value, \
- &__sys_exc_traceback); \
- fprintf(stderr, # MESS ":\n\t"); \
- PyObject_Print(__sys_exc_type, stderr,0); \
- fprintf(stderr,", "); \
- PyObject_Print(__sys_exc_value, stderr,0); \
- fprintf(stderr,"\n"); \
- fflush(stderr); \
- Py_FatalError(# 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, sizeof(PyPureMixinObject), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, DOC, {METHODS, NULL}, \
- EXTENSIONCLASS_BASICNEW_FLAG}
-
-/* The following macros provide limited access to extension-class
- method facilities. */
-
-/* Test for an ExtensionClass method: */
-#define PyECMethod_Check(O) \
- ((PyObject*)(O)->ob_type==PyExtensionClassCAPI->MethodType)
-
-/* 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->Method_New(CALLABLE,INST))
-
-/* Return the instance that is bound by an extension class method. */
-#define PyECMethod_Self(M) (((PyECMethodObject*)M)->self)
-
-/* 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 == \
- (PyTypeObject*)PyExtensionClassCAPI->ExtensionClassType && \
- (((PyExtensionClass*)((O)->ob_type))->class_flags & \
- EXTENSIONCLASS_BINDABLE_FLAG))
-
-/* The following macros are used to check whether an instance
- or a class' instanses have instance dictionaries: */
-#define HasInstDict(O) \
- ((((PyExtensionClass*)((O)->ob_type))->class_flags & \
- EXTENSIONCLASS_INSTDICT_FLAG))
-#define ClassHasInstDict(O) (O->class_flags & EXTENSIONCLASS_INSTDICT_FLAG)
-
-/* Get an object's instance dictionary. Use with caution */
-#define INSTANCE_DICT(inst) \
-*(((PyObject**)inst) + (inst->ob_type->tp_basicsize/sizeof(PyObject*) - 1))
-
-/* Test whether an ExtensionClass, S, is a subclass of ExtensionClass C. */
-#define ExtensionClassSubclass_Check(S,C) ( \
- ((PyObject*)(S)->ob_type==PyExtensionClassCAPI->ExtensionClassType) && \
- ((PyObject*)(C)->ob_type==PyExtensionClassCAPI->ExtensionClassType) && \
- (PyExtensionClassCAPI->issubclass((PyExtensionClass *)(S), \
- (PyExtensionClass *)(C))))
-
-/* Test whether an ExtensionClass instance , I, is a subclass of
- ExtensionClass C. */
-#define ExtensionClassSubclassInstance_Check(I,C) ( \
- ((PyObject*)(I)->ob_type->ob_type== \
- PyExtensionClassCAPI->ExtensionClassType) && \
- ((PyObject*)(C)->ob_type==PyExtensionClassCAPI->ExtensionClassType) && \
- (PyExtensionClassCAPI->issubclass((PyExtensionClass *)((I)->ob_type), \
- (PyExtensionClass *)(C))))
-
-/* This let's you define built-in class methods. */
-#define METH_CLASS_METHOD (2 << 17)
-
-/*****************************************************************************
-
- WARNING: EVERYTHING BELOW HERE IS PRIVATE TO THE EXTENSION CLASS INTERFACE
- IMPLEMENTATION AND IS SUBJECT TO CHANGE !!!
-
- *****************************************************************************/
-
-static struct ExtensionClassCAPIstruct {
- int (*Export)(PyObject *dict, char *name, PyExtensionClass *ob_type);
- PyObject *(*getattrs)(PyObject *, char *);
- PyObject *(*getattro)(PyObject *, PyObject *);
- int (*setattrs)(PyObject *, char *, PyObject *);
- int (*setattro)(PyObject *, PyObject *, PyObject *);
- PyObject *ExtensionClassType;
- PyObject *MethodType;
- PyObject *(*Method_New)(PyObject *callable, PyObject *inst);
- int (*issubclass)(PyExtensionClass *sub, PyExtensionClass *type);
- int (*ExportSubclass)(PyObject *dict, char *name,
- PyExtensionClass *ob_type, PyObject *bases);
-} *PyExtensionClassCAPI = NULL;
-
-typedef struct { PyObject_HEAD } PyPureMixinObject;
-
-typedef struct {
- PyObject_HEAD
- PyTypeObject *type;
- PyObject *self;
- PyObject *meth;
-} PyECMethodObject;
-
-/* The following is to avoid whining from 1.5 :-) */
-#define PyCObject_Import PyCObject_Import14
-
-static void *
-PyCObject_Import14(char *module_name, char *name)
-{
- PyObject *m, *c;
- void *r=NULL;
-
- if((m=PyImport_ImportModule(module_name)))
- {
- if((c=PyObject_GetAttrString(m,name)))
- {
- r=PyCObject_AsVoidPtr(c);
- Py_DECREF(c);
- }
- Py_DECREF(m);
- }
-
- return r;
-}
-
-#endif
-
-
diff --git a/ExtensionClass.stx b/ExtensionClass.stx
deleted file mode 100644
index cab7e46b..00000000
--- a/ExtensionClass.stx
+++ /dev/null
@@ -1,714 +0,0 @@
-Extension Classes, Python Extension Types Become Classes
-
- Jim Fulton, Digital Creations, Inc.
- jim@digicool.com
-
- "Copyright (C) 1996-1998, Digital Creations":COPYRIGHT.html.
-
- Abstract
-
- A lightweight mechanism has been developed for making Python
- extension types more class-like. Classes can be developed in an
- extension language, such as C or C++, and these classes can be
- treated like other python classes:
-
- - They can be sub-classed in python,
-
- - They provide access to method documentation strings, and
-
- - They can be used to directly create new instances.
-
- An example class shows how extension classes are implemented and how
- they differ from extension types.
-
- Extension classes provide additional extensions to class and
- instance semantics, including:
-
- - A protocol for accessing subobjects "in the context of" their
- containers. This is used to implement custom method types
- and "environmental acquisition":Acquisition.html.
-
- - A protocol for overriding method call semantics. This is used
- to implement "synchonized" classes and could be used to
- implement argument type checking.
-
- - A protocol for class initialization that supports execution of a
- special '__class_init__' method after a class has been
- initialized.
-
- Extension classes illustrate how the Python class mechanism can be
- extended and may provide a basis for improved or specialized class
- models.
-
- Releases
-
- To find out what's changed in this release,
- see the "release notes":release.html.
-
- Problem
-
- Currently, Python provides two ways of defining new kinds of objects:
-
- - Python classes
-
- - Extension types
-
- Each approach has it's strengths. Extension types provide much greater
- control to the programmer and, generally, better performance. Because
- extension types are written in C, the programmer has greater access to
- external resources. (Note that Python's use of the term type has
- little to do with the notion of type as a formal specification.)
-
- Classes provide a higher level of abstraction and are generally much
- easier to develop. Classes provide full inheritance support, while
- support for inheritance when developing extension types is very
- limited. Classes provide run-time meta-data, such as method documentation
- strings, that are useful for documentation and discovery. Classes
- act as factories for creating instances, while separate functions
- must be provided to create instances of types.
-
- It would be useful to combine the features of the two approaches. It
- would be useful to be able to have better support for inheritance for
- types, or to be able to subclass from types in Python. It would be
- useful to be able to have class-like meta-data support for types and
- the ability to construct instances directly from types.
-
- Our software is developed in Python. When necessary, we convert
- debugged Python routines and classes to C for improved
- performance. In most cases, a small number of methods in a class
- is responsible for most of the computation. It should be possible
- to convert only these methods to C, while leaving the other method
- in Python. A natural way to approach this is to create a base
- class in C that contains only the performance-critical aspects of
- a class' implementation and mix this base class into a Python
- class.
-
- We have need, in a number of projects, for semantics that are
- slightly different than the usual class and instance semantics,
- yet we don't want to do most of our development in C. For
- example, we have developed a persistence mechanism [1] that
- redefines '__getattr__' and '__setattr__' to take storage-related
- actions when object state is accessed or modified. We want to be
- able to take certain actions on *every* attribute reference, but
- for python class instances, '__getattr__' is only called when
- attribute lookup fails by normal means.
-
- As another example, we would like to have greater control over how
- methods are bound. Currently, when accessing a class
- instance attribute, the attribute value is bound together with the
- instance in a method object *if and only if* the attribute value is a
- python function. For some applications, we might also want to be
- able to bind extension functions, or other types of callable
- objects, such as HTML document templates [2]. Furthermore,
- we might want to have greater control over how objects are bound.
- For example, we might want to bind instances and callable objects
- with special method objects that assure that no more than one thread
- accesses the object or method at one time.
-
- We can provide these special semantics in extension types, but we
- wish to provide them for classes developed in Python.
-
- Background
-
- At the first Python Workshop, Don Beaudry presented work [3] done
- at V.I. Corp to integrate Python with C++ frameworks. This system
- provided a number of important features, including:
-
- - Definition of extension types that provide class-like meta-data
- and that can be called to create instances.
-
- - Ability to subclass in python from C types.
-
- - Ability to define classes in python who's data are stored as
- C structures rather than in dictionaries to better interface to
- C and C++ libraries, and for better performance.
-
- - Less dynamic data structures. In particular, the data structure
- for a class is declared during class definition.
-
- - Support for enumeration types.
-
- This work was not released, initially.
-
- Shortly after the workshop, changes were made to Python to support
- the sub-classing features described in [3]. These changes were not
- documented until the fourth Python Workshop [4].
-
- At the third Python workshop, I presented some work I had done on
- generating module documentation for extension types. Based on the
- discussion at this workshop, I developed a meta-type proposal [5].
- This meta-type proposal was for an object that simply stored
- meta-information for a type, for the purpose of generating module
- documentation.
-
- In the summer of 1996, Don Beaudry released the system described in
- [3] under the name MESS [6]. MESS addresses a number of needs but
- has a few drawbacks:
-
- - Only single inheritance is supported.
-
- - The mechanisms for defining MESS extension types is very different
- from and more complicated than the standard Python type creation
- mechanism.
-
- - Defining MESS types requires the use of an extensive C
- applications programming interface. This presents problems for
- configuring dynamically-loaded extension modules unless the MESS
- library is linked into the Python interpreter.
-
- - Because the system tries to do a number of different things, it is
- fairly large, about 15,000 lines.
-
- - There is very little documentation, especially for the C
- programming interface.
-
- - The system is a work in progress, with a number of outstanding
- bugs.
-
- As MESS matures, we expect most of these problems to be addressed.
-
- Extension Classes
-
- To meet short term needs for a C-based persistence mechanism [1], an
- extension class module was developed using the mechanism described
- in [4] and building on ideas from MESS [6]. The extension class module
- recasts extension types as "extension classes" by seeking to
- eliminate, or at least reduce semantic differences between types and
- classes. The module was designed to meet the following goal:
-
- - Provide class-like behavior for extension types, including
- interfaces for meta information and for constructing instances.
-
- - Support sub-classing in Python from extension classes, with support
- for multiple inheritance.
-
- - Provide a small hardened implementation that can be used for
- current products.
-
- - Provide a mechanism that requires minimal modification to existing
- extension types.
-
- - Provide a basis for research on alternative semantics for classes
- and inheritance.
-
- **Note:** I use *non-standard* terminology here. By standard
- *python* terminology, only standard python classes can be called
- classes. ExtensionClass "classes" are technically just "types"
- that happen to swim, walk and quack like python classes.
-
- Base extension classes and extension subclasses
-
- Base extension classes are implemented in C. Extension subclasses
- are implemented in Python and inherit, directly or indirectly from
- one or more base extension classes. An extension subclass may
- inherit from base extension classes, extension subclasses, and
- ordinary python classes. The usual inheritance order rules
- apply. Currently, extension subclasses must conform to the
- following two rules:
-
- - The first super class listed in the class statement defining an
- extension subclass must be either a base extension class or an
- extension subclass. This restriction will be removed in
- Python-1.5.
-
- - At most one base extension direct or indirect super class may
- define C data members. If an extension subclass inherits from
- multiple base extension classes, then all but one must be mix-in
- classes that provide extension methods but no data.
-
- Meta Information
-
- Like standard python classes, extension classes have the following
- attributes containing meta-data:
-
- '__doc__' -- a documentation string for the class,
-
- '__name__' -- the class name,
-
- '__bases__' -- a sequence of base classes,
-
- '__dict__' -- a class dictionary, and
-
- '__module__' -- the name of the module in which the class was
- defined.
-
- The class dictionary provides access to unbound methods and their
- documentation strings, including extension methods and special
- methods, such as methods that implement sequence and numeric
- protocols. Unbound methods can be called with instance first
- arguments.
-
- Subclass instance data
-
- Extension subclass instances have instance dictionaries, just
- like Python class instances do. When fetching attribute values,
- extension class instances will first try to obtain data from the
- base extension class data structure, then from the instance
- dictionary, then from the class dictionary, and finally from base
- classes. When setting attributes, extension classes first attempt
- to use extension base class attribute setting operations, and if
- these fail, then data are placed in the instance dictionary.
-
- Implementing base extension classes
-
- A base extension class is implemented in much the same way that an
- extension type is implemented, except:
-
- - The include file, 'ExtensionClass.h', must be included.
-
- - The type structure is declared to be of type 'PyExtensionClass', rather
- than of type 'PyTypeObject'.
-
- - The type structure has an additional member that must be defined
- after the documentation string. This extra member is a method chain
- ('PyMethodChain') containing a linked list of method definition
- ('PyMethodDef') lists. Method chains can be used to implement
- method inheritance in C. Most extensions don't use method chains,
- but simply define method lists, which are null-terminated arrays
- of method definitions. A macro, 'METHOD_CHAIN' is defined in
- 'ExtensionClass.h' that converts a method list to a method chain.
- (See the example below.)
-
- - Module functions that create new instances must be replaced by
- '__init__' methods that initialize, but does not create storage for
- instances.
-
- - The extension class must be initialized and exported to the module
- with::
-
- PyExtensionClass_Export(d,"name",type);
-
- where 'name' is the module name and 'type' is the extension class
- type object.
-
- Attribute lookup
-
- Attribute lookup is performed by calling the base extension class
- 'getattr' operation for the base extension class that includes C
- data, or for the first base extension class, if none of the base
- extension classes include C data. 'ExtensionClass.h' defines a
- macro 'Py_FindAttrString' that can be used to find an object's
- attributes that are stored in the object's instance dictionary or
- in the object's class or base classes::
-
- v = Py_FindAttrString(self,name);
-
- where 'name' is a C string containing the attribute name.
-
- In addition, a macro is provided that replaces 'Py_FindMethod'
- calls with logic to perform the same sort of lookup that is
- provided by 'Py_FindAttrString'.
-
- If an attribute name is contained in a Python string object,
- rather than a C string object, then the macro 'Py_FindAttr' should
- be used to look up an attribute value.
-
- Linking
-
- The extension class mechanism was designed to be useful with
- dynamically linked extension modules. Modules that implement
- extension classes do not have to be linked against an extension
- 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.
-
- Example: MultiMapping objects
-
- An "example":MultiMapping.html, is provided that illustrates the
- changes needed to convert an existing type to an ExtensionClass.
-
- Implementing base extension class constructors
-
- Some care should be taken when implementing or overriding base
- class constructors. When a Python class overrides a base class
- constructor and fails to call the base class constructor, a
- program using the class may fail, but it will not crash the
- interpreter. On the other hand, an extension subclass that
- overrides a constructor in an extension base class must call the
- extension base class constructor or risk crashing the interpreter.
- This is because the base class constructor may set C pointers that,
- if not set properly, will cause the interpreter to crash when
- accessed. This is the case with the 'MultiMapping' extension base
- class shown in the example above.
-
- If no base class constructor is provided, extension class instance
- memory will be initialized to 0. It is a good idea to design
- extension base classes so that instance methods check for
- uninitialized memory and perform initialialization if necessary.
- This was not done above to simplify the example.
-
- Overriding methods inherited from Python base classes
-
- A problem occurs when trying to overide methods inherited from
- Python base classes. Consider the following example::
-
- from ExtensionClass import Base
-
- class Spam:
-
- def __init__(self, name):
- self.name=name
-
- class ECSpam(Base, Spam):
-
- def __init__(self, name, favorite_color):
- Spam.__init__(self,name)
- self.favorite_color=favorite_color
-
- This implementation will fail when an 'ECSpam' object is
- instantiated. The problem is that 'ECSpam.__init__' calls
- 'Spam.__init__', and 'Spam.__init__' can only be called with a
- Python instance (an object of type '"instance"') as the first
- argument. The first argument passed to 'Spam.__init__' will be an
- 'ECSpam' instance (an object of type 'ECSPam').
-
- To overcome this problem, extension classes provide a class method
- 'inheritedAttribute' that can be used to obtain an inherited
- attribute that is suitable for calling with an extension class
- instance. Using the 'inheritedAttribute' method, the above
- example can be rewritten as::
-
- from ExtensionClass import Base
-
- class Spam:
-
- def __init__(self, name):
- self.name=name
-
- class ECSpam(Base, Spam):
-
- def __init__(self, name, favorite_color):
- ECSpam.inheritedAttribute('__init__')(self,name)
- self.favorite_color=favorite_color
-
- This isn't as pretty but does provide the desired result.
-
- New class and instance semantics
-
- Context Wrapping
-
- It is sometimes useful to be able to wrap up an object together
- with a containing object. I call this "context wrapping"
- because an object is accessed in the context of the object it is
- accessed through.
-
- We have found many applications for this, including:
-
- - User-defined method objects,
-
- - "Acquisition":Acquisition.html, and
-
- - Computed attributes
-
- User-defined method objects
-
- Python classes wrap Python function attributes into methods. When a
- class has a function attribute that is accessed as an instance
- attribute, a method object is created and returned that contains
- references to the original function and instance. When the method
- is called, the original function is called with the instance as the
- first argument followed by any arguments passed to the method.
-
- Extension classes provide a similar mechanism for attributes that
- are Python functions or inherited extension functions. In
- addition, if an extension class attribute is an instance of an
- extension class that defines an '__of__' method, then when the
- attribute is accessed through an instance, it's '__of__' method
- will be called to create a bound method.
-
- Consider the following example::
-
- import ExtensionClass
-
- class CustomMethod(ExtensionClass.Base):
-
- def __call__(self,ob):
- print 'a %s was called' % ob.__class__.__name__
-
- class wrapper:
-
- def __init__(self,m,o): self.meth, self.ob=m,o
-
- def __call__(self): self.meth(self.ob)
-
- def __of__(self,o): return self.wrapper(self,o)
-
- class bar(ExtensionClass.Base):
- hi=CustomMethod()
-
- x=bar()
- hi=x.hi()
-
- Note that 'ExtensionClass.Base' is a base extension class that
- provides very basic ExtensionClass behavior.
-
- When run, this program outputs: 'a bar was called'.
-
- Computed Attributes
-
- It is not uncommon to wish to expose information via the
- attribute interface without affecting implementation data
- structures. One can use a custom '__getattr__' method to
- implement computed attributes, however, this can be a bit
- cumbersome and can interfere with other uses of '__getattr__',
- such as for persistence.
-
- The '__of__' protocol provides a convenient way to implement
- computed attributes. First, we define a ComputedAttribute
- class. a ComputedAttribute is constructed with a function to
- be used to compute an attribute, and calls the function when
- it's '__of__' method is called:
-
- import ExtensionClass
-
- class ComputedAttribute(ExtensionClass.Base):
-
- def __init__(self, func): self.func=func
-
- def __of__(self, parent): return self.func(parent)
-
- Then we can use this class to create computed attributes. In the
- example below, we create a computed attribute, 'radius':
-
- from math import sqrt
-
- class Point(ExtensionClass.Base):
-
- def __init__(self, x, y): self.x, self.y = x, y
-
- radius=ComputedAttribute(lambda self: sqrt(self.x**2+self.y**2))
-
- which we can use just like an ordinary attribute:
-
- p=Point(2,2)
- print p.radius
-
- Overriding method calls
-
- Normally, when a method is called, the function wrapped by the
- method is called directly by the method. In some cases, it is
- useful for user-defined logic to participate in the actual
- function call. Extension classes introduce a new protocol that
- provides extension classes greater control over how their
- methods are called. If an extension class defines a special
- method, '__call_method__', then this method will be called to
- call the functions (or other callable object) wrapped by the
- method. The method. '__call_method__' should provide the same
- interface as provided by the Python builtin 'apply' function.
-
- For example, consider the expression: 'x.meth(arg1, arg2)'. The
- expression is evaluated by first computing a method object that
- wraps 'x' and the attribute of 'x' stored under the name 'meth'.
- Assuming that 'x' has a '__call_method__' method defined, then
- the '__call_method__' method of 'x' will be called with two
- arguments, the attribute of 'x' stored under the name 'meth',
- and a tuple containing 'x', 'arg1', and 'arg2'.
-
- To see how this feature may be used, see the Python module,
- 'Syn.py', which is included in the ExtensionClass distribution.
- This module provides a mix-in class that provides Java-like
- "synchonized" classes that limit access to their methods to one
- thread at a time.
-
- An interesting application of this mechanism would be to
- implement interface checking on method calls.
-
- Method attributes
-
- Methods of ExtensionClass instances can have user-defined
- attributes, which are stored in their associated instances.
-
- For example::
-
- class C(ExtensionClass.Base):
-
- def f(self):
- "Get a secret"
- ....
-
- c=C()
-
- c.f.__roles__=['Trusted People']
-
- print c.f.__roles__ # outputs ['Trusted People']
- print c.f__roles__ # outputs ['Trusted People']
-
- print C.f.__roles__ # fails, unbound method
-
- A bound method attribute is set by setting an attribute in it's
- instance with a name consisting of the concatination of the
- method's '__name__' attribute and the attribute name.
- Attributes cannot be set on unbound methods.
-
- Class initialization
-
- Normal Python class initialization is similar to but subtley
- different from instance initialization. An instance '__init__'
- function is called on an instance immediately *after* it is
- created. An instance '__init__' function can use instance
- information, like it's class and can pass the instance to other
- functions. On the other hand, the code in class statements is
- executed immediately *before* the class is created. This means
- that the code in a class statement cannot use class attributes,
- like '__bases__', or pass the class to functions.
-
- Extension classes provide a mechanism for specifying code to be
- run *after* a class has been created. If a class or one of it's
- base classes defines a '__class_init__' method, then this method
- will be called just after a class has been created. The one
- argument passed to the method will be the class, *not* an
- instance of the class.
-
- Useful macros defined in ExtensionClass.h
-
- A number of useful macros are defined in ExtensionClass.h.
- These are documented in 'ExtensionClass.h'.
-
- Pickleability
-
- Classes created with ExtensionClass, including extension base
- classes are automatically pickleable. The usual gymnastics
- necessary to pickle 'non-standard' types are not necessray for
- types that have been modified to be extension base classes.
-
- Status
-
- The current release of the extension class module is "1.1",
- http://www.digicool.com/releases/ExtensionClass/ExtensionClass-1.1.tar.gz.
- The core implementation has less than four thousand lines of code,
- including comments. This release requires Python 1.4 or higher.
-
- To find out what's changed in this release, see the
- "release notes":release.html.
-
- "Installation instructions":Installation.html, are provided.
-
- Issues
-
- There are a number of issues that came up in the course of this work
- and that deserve mention.
-
- - In Python 1.4, the class extension mechanism described in [4] required
- that the first superclass in a list of super-classes must be of the
- extended class type. This may not be convenient if mix-in
- behavior is desired. If a list of base classes starts with a
- standard python class, but includes an extension class, then an
- error was raised. It would be more useful if, when a list of base
- classes contains one or more objects that are not python classes,
- the first such object was used to control the extended class
- definition. To get around this, the 'ExtensionClass' module exports
- a base extension class, 'Base', that can be used as the first base
- class in a list of base classes to assure that an extension
- subclass is created.
-
- Python 1.5 allows the class extension even if the first non-class
- object in the list of base classes is not the first object in
- the list. This issue appears to go away in Python 1.5, however,
- the restriction that the first non-class object in a list of
- base classes must be the first in the list may reappear in later
- versions of Python.
-
- - Currently, only one base extension class can define any data in
- C. The data layout of subclasses-instances is the same as for the
- base class that defines data in C, except that the data structure
- is extended to hold an instance dictionary. The data structure
- begins with a standard python header, and extension methods expect
- the C instance data to occur immediately after the object header. If
- two or more base classes defined C data, the methods for the
- different base classes would expect their data to be in the same
- location. A solution might be to allocate base class instances and
- store pointers to these instances in the subclass data structure.
- The method binding mechanism would have to be a more complicated
- to make sure that methods were bound to the correct base data
- structure. Alternatively, the signature of C methods could be
- expanded to allow pointers to expected class data to be passed
- in addition to object pointers.
-
- - There is currently no support for sub-classing in C, beyond that
- provided by method chains.
-
- - Rules for mixed-type arithmetic are different for python class
- instances than they are for extension type instances. Python
- classes can define right and left versions of numeric binary
- operators, or they can define a coercion operator for converting
- binary operator operands to a common type. For extension types,
- only the latter, coercion-based, approach is supported. The
- coercion-based approach does not work well for many data types for
- which coercion rules depend on the operator. Because extension
- classes are based on extension types, they are currently limited
- to the coercion-based approach. It should be possible to
- extend the extension class implementation to allow both types of
- mixed-type arithmetic control.
-
- - I considered making extension classes immutable, meaning that
- class attributes could not be set after class creation. I also
- considered making extension subclasses cache inherited
- attributes. Both of these are related and attractive for some
- applications, however, I decided that it would be better to retain
- standard class instance semantics and provide these features as
- options at a later time.
-
- - The extension class module defines new method types to bind C and
- python methods to extension class instances. It would be useful
- for these method objects to provide access to function call
- information, such as the number and names of arguments and the
- number of defaults, by parsing extension function documentation
- strings.
-
- Applications
-
- Aside from test and demonstration applications, the extension class
- mechanism has been used to provide an extension-based implementation
- of the persistence mechanism described in [1]. We have developed
- this further to provide features such as automatic deactivation of
- objects not used after some period of time and to provide more
- efficient persistent-object cache management.
-
- Acquisition has been heavily used in our recent products.
- Synchonized classes have also been used in recent products.
-
- Summary
-
- The extension-class mechanism described here provides a way to add
- class services to extension types. It allows:
-
- - Sub-classing extension classes in Python,
-
- - Construction of extension class instances by calling extension
- classes,
-
- - Extension classes to provide meta-data, such as unbound methods
- and their documentation string.
-
- In addition, the extension class module provides a relatively
- concise example of the use of mechanisms that were added to Python
- to support MESS [6], and that were described at the fourth Python
- Workshop [4]. It is hoped that this will spur research in improved
- and specialized models for class implementation in Python.
-
- References
-
-.. [1] Fulton, J., "Providing Persistence for World-Wide-Web Applications",
- http://www.digicool.com/papers/Persistence.html,
- Proceedings of the 5th Python Workshop.
-
-.. [2] Page, R. and Cropper, S., "Document Template",
- http://www.digicool.com/papers/DocumentTemplate.html,
- Proceedings of the 5th Python Workshop.
-
-.. [3] Beaudry, D., "Deriving Built-In Classes in Python",
- http://www.python.org/workshops/1994-11/BuiltInClasses/BuiltInClasses_1.html,
- Proceedings of the First International Python Workshop.
-
-.. [4] Van Rossum, G., "Don Beaudry Hack - MESS",
- http://www.python.org/workshops/1996-06/notes/thursday.html,
- presented in the Developer's Future Enhancements session of the
- 4th Python Workshop.
-
-.. [5] Fulton, J., "Meta-Type Object",
- http://www.digicool.com/jim/MetaType.c,
- This is a small proposal, the text of which is contained in a
- sample implementation source file,
-
-.. [6] Beaudry, D., and Ascher, D., "The Meta-Extension Set",
- http://starship.skyport.net/~da/mess/.
diff --git a/Makefile.am b/Makefile.am
index 7112f40b..039246c8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,13 +5,7 @@ SUBDIRS = codegen gtk
INCLUDES = $(PYTHON_INCLUDES) $(GLIB_CFLAGS) $(PANGO_CFLAGS)
-pyexec_LTLIBRARIES = ExtensionClass.la gobjectmodule.la pangomodule.la
-
-ExtensionClass_la_LDFLAGS = -module -avoid-version \
- -export-symbols-regex initExtensionClass
-ExtensionClass_la_SOURCES = \
- ExtensionClass.h \
- ExtensionClass.c
+pyexec_LTLIBRARIES = gobjectmodule.la pangomodule.la
gobjectmodule_la_LDFLAGS = -module -avoid-version \
-export-symbols-regex initgobject
@@ -36,7 +30,7 @@ $(srcdir)/pango.c: $(srcdir)/pango.defs $(srcdir)/pango.override
&& cp gen-pango.c pango.c \
&& rm -f gen-pango.c
-pkginclude_HEADERS = pygobject.h ExtensionClass.h
+pkginclude_HEADERS = pygobject.h
noinst_PYTHON = ltihooks.py
@@ -53,7 +47,6 @@ EXTRA_DIST = \
pygtk.spec \
pygtk-2.0.pc.in \
MAPPING \
- ExtensionClass.stx \
pango.defs \
pango.override \
examples/gobject/signal.py \
diff --git a/codegen/codegen.py b/codegen/codegen.py
index bbb7e99b..4a5c28b3 100644
--- a/codegen/codegen.py
+++ b/codegen/codegen.py
@@ -29,49 +29,43 @@ methtmpl = 'static PyObject *\n' + \
'}\n\n'
methcalltmpl = '%(cname)s(%(cast)s(self->obj)%(arglist)s)'
-consttmpl = 'static PyObject *\n' + \
+consttmpl = 'static int\n' + \
'_wrap_%(cname)s(PyGObject *self, PyObject *args, PyObject *kwargs)\n' + \
'{\n' + \
'%(varlist)s' + \
' if (!PyArg_ParseTupleAndKeywords(args, kwargs, "%(typecodes)s:%(class)s.__init__"%(parselist)s))\n' + \
- ' return NULL;\n' + \
+ ' return -1;\n' + \
'%(extracode)s\n' + \
' self->obj = (GObject *)%(cname)s(%(arglist)s);\n' + \
' if (!self->obj) {\n' + \
' PyErr_SetString(PyExc_RuntimeError, "could not create %(class)s object");\n' + \
- ' return NULL;\n' + \
+ ' return -1;\n' + \
' }\n' + \
'%(gtkobjectsink)s' + \
' pygobject_register_wrapper((PyObject *)self);\n' + \
- ' Py_INCREF(Py_None);\n' + \
- ' return Py_None;\n' + \
+ ' return 0;\n' + \
'}\n\n'
methdeftmpl = ' { "%(name)s", (PyCFunction)%(cname)s, %(flags)s },\n'
-getattrtmpl = 'static PyObject *\n' + \
- '%(getattr)s(PyGObject *self, char *attr)\n' + \
- '{\n' + \
- '%(attrchecks)s' + \
- ' PyErr_SetString(PyExc_AttributeError, attr);\n' + \
- ' return NULL;\n' + \
- '}\n\n'
-attrchecktmpl = ' if (!strcmp(attr, "%(attr)s")) {\n' + \
- '%(varlist)s' + \
- '%(code)s\n' + \
- ' }\n'
+gettertmpl = 'static PyObject *\n' + \
+ '%(funcname)s(PyGObject *self, void *closure)\n' + \
+ '{\n' + \
+ '%(varlist)s' + \
+ '%(code)s\n' + \
+ '}\n\n'
-noconstructor = 'static PyObject *\n' + \
- 'pygobject_no_constructor(PyObject *self, PyObject *args)\n' +\
+noconstructor = 'static int\n' + \
+ 'pygobject_no_constructor(PyObject *self, PyObject *args, PyObject *kwargs)\n' +\
'{\n' + \
' gchar buf[512];\n' + \
'\n' + \
' g_snprintf(buf, sizeof(buf), "%s is an abstract widget", self->ob_type->tp_name);\n' + \
' PyErr_SetString(PyExc_NotImplementedError, buf);\n' + \
- ' return NULL;\n' + \
+ ' return -1;\n' + \
'}\n\n'
-typetmpl = 'PyExtensionClass Py%(class)s_Type = {\n' + \
+typetmpl = 'PyTypeObject Py%(class)s_Type = {\n' + \
' PyObject_HEAD_INIT(NULL)\n' + \
' 0, /* ob_size */\n' + \
' "%(classname)s", /* tp_name */\n' + \
@@ -80,7 +74,7 @@ typetmpl = 'PyExtensionClass Py%(class)s_Type = {\n' + \
' /* methods */\n' + \
' (destructor)0, /* tp_dealloc */\n' + \
' (printfunc)0, /* tp_print */\n' + \
- ' (getattrfunc)%(getattr)s, /* tp_getattr */\n' + \
+ ' (getattrfunc)0, /* tp_getattr */\n' + \
' (setattrfunc)0, /* tp_setattr */\n' + \
' (cmpfunc)0, /* tp_compare */\n' + \
' (reprfunc)0, /* tp_repr */\n' + \
@@ -92,18 +86,31 @@ typetmpl = 'PyExtensionClass Py%(class)s_Type = {\n' + \
' (reprfunc)0, /* tp_str */\n' + \
' (getattrofunc)0, /* tp_getattro */\n' + \
' (setattrofunc)0, /* tp_setattro */\n' + \
- ' /* Space for future expansion */\n' + \
- ' 0L, 0L,\n' + \
+ ' 0, /* tp_as_buffer */\n' + \
+ ' Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */\n' + \
' NULL, /* Documentation string */\n' + \
- ' %(methods)s,\n' + \
- ' EXTENSIONCLASS_INSTDICT_FLAG,\n' + \
+ ' (traverseproc)0, /* tp_traverse */\n' + \
+ ' (inquiry)0, /* tp_clear */\n' + \
+ ' (richcmpfunc)0, /* tp_richcompare */\n' + \
+ ' offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */\n' +\
+ ' (getiterfunc)0, /* tp_iter */\n' + \
+ ' (iternextfunc)0, /* tp_iternext */\n' + \
+ ' %(methods)s, /* tp_methods */\n' + \
+ ' 0, /* tp_members */\n' + \
+ ' %(getsets)s, /* tp_getset */\n' + \
+ ' NULL, /* tp_base */\n' + \
+ ' NULL, /* tp_dict */\n' + \
+ ' (descrgetfunc)0, /* tp_descr_get */\n' + \
+ ' (descrsetfunc)0, /* tp_descr_set */\n' + \
+ ' offsetof(PyGObject, inst_dict), /* tp_dictoffset */\n' + \
+ ' (initproc)%(initfunc)s, /* tp_init */\n' + \
'};\n\n'
-interfacetypetmpl = 'PyExtensionClass Py%(class)s_Type = {\n' + \
+interfacetypetmpl = 'PyTypeObject Py%(class)s_Type = {\n' + \
' PyObject_HEAD_INIT(NULL)\n' + \
' 0, /* ob_size */\n' + \
' "%(classname)s", /* tp_name */\n' + \
- ' sizeof(PyPureMixinObject), /* tp_basicsize */\n' + \
+ ' sizeof(PyObject), /* tp_basicsize */\n' + \
' 0, /* tp_itemsize */\n' + \
' /* methods */\n' + \
' (destructor)0, /* tp_dealloc */\n' + \
@@ -120,11 +127,24 @@ interfacetypetmpl = 'PyExtensionClass Py%(class)s_Type = {\n' + \
' (reprfunc)0, /* tp_str */\n' + \
' (getattrofunc)0, /* tp_getattro */\n' + \
' (setattrofunc)0, /* tp_setattro */\n' + \
- ' /* Space for future expansion */\n' + \
- ' 0L, 0L,\n' + \
+ ' 0, /* tp_as_buffer */\n' + \
+ ' Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */\n' + \
' NULL, /* Documentation string */\n' + \
- ' %(methods)s,\n' + \
- ' 0,\n' + \
+ ' (traverseproc)0, /* tp_traverse */\n' + \
+ ' (inquiry)0, /* tp_clear */\n' + \
+ ' (richcmpfunc)0, /* tp_richcompare */\n' + \
+ ' 0, /* tp_weaklistoffset */\n' +\
+ ' (getiterfunc)0, /* tp_iter */\n' + \
+ ' (iternextfunc)0, /* tp_iternext */\n' + \
+ ' %(methods)s, /* tp_methods */\n' + \
+ ' 0, /* tp_members */\n' + \
+ ' 0, /* tp_getset */\n' + \
+ ' NULL, /* tp_base */\n' + \
+ ' NULL, /* tp_dict */\n' + \
+ ' (descrgetfunc)0, /* tp_descr_get */\n' + \
+ ' (descrsetfunc)0, /* tp_descr_set */\n' + \
+ ' 0, /* tp_dictoffset */\n' + \
+ ' (initproc)0, /* tp_init */\n' + \
'};\n\n'
boxedmethtmpl = 'static PyObject *\n' + \
@@ -138,23 +158,22 @@ boxedmethtmpl = 'static PyObject *\n' + \
'}\n\n'
boxedmethcalltmpl = '%(cname)s(pyg_boxed_get(self, %(typename)s)%(arglist)s)'
-boxedconsttmpl = 'static PyObject *\n' + \
+boxedconsttmpl = 'static int\n' + \
'_wrap_%(cname)s(PyGBoxed *self, PyObject *args, PyObject *kwargs)\n' + \
'{\n' + \
'%(varlist)s' + \
' if (!PyArg_ParseTupleAndKeywords(args, kwargs, "%(typecodes)s:%(typename)s.__init__"%(parselist)s))\n' + \
- ' return NULL;\n' + \
+ ' return -1;\n' + \
'%(extracode)s\n' + \
' self->gtype = %(typecode)s;\n' + \
' self->free_on_dealloc = FALSE;\n' + \
' self->boxed = %(cname)s(%(arglist)s);\n' + \
' if (!self->boxed) {\n' + \
' PyErr_SetString(PyExc_RuntimeError, "could not create %(typename)s object");\n' + \
- ' return NULL;\n' + \
+ ' return -1;\n' + \
' }\n' + \
' self->free_on_dealloc = TRUE;\n' + \
- ' Py_INCREF(Py_None);\n' + \
- ' return Py_None;\n' + \
+ ' return 0;\n' + \
'}\n\n'
boxedgetattrtmpl = 'static PyObject *\n' + \
@@ -164,8 +183,12 @@ boxedgetattrtmpl = 'static PyObject *\n' + \
' PyErr_SetString(PyExc_AttributeError, attr);\n' + \
' return NULL;\n' + \
'}\n\n'
+attrchecktmpl = ' if (!strcmp(attr, "%(attr)s")) {\n' + \
+ '%(varlist)s' + \
+ '%(code)s\n' + \
+ ' }\n'
-boxedtmpl = 'PyExtensionClass Py%(typename)s_Type = {\n' + \
+boxedtmpl = 'PyTypeObject Py%(typename)s_Type = {\n' + \
' PyObject_HEAD_INIT(NULL)\n' + \
' 0, /* ob_size */\n' + \
' "%(typename)s", /* tp_name */\n' + \
@@ -186,11 +209,24 @@ boxedtmpl = 'PyExtensionClass Py%(typename)s_Type = {\n' + \
' (reprfunc)0, /* tp_str */\n' + \
' (getattrofunc)0, /* tp_getattro */\n' + \
' (setattrofunc)0, /* tp_setattro */\n' + \
- ' /* Space for future expansion */\n' + \
- ' 0L, 0L,\n' + \
+ ' 0, /* tp_as_buffer */\n' + \
+ ' Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */\n' +\
' NULL, /* Documentation string */\n' + \
- ' %(methods)s,\n' + \
- ' 0,\n' + \
+ ' (traverseproc)0, /* tp_traverse */\n' + \
+ ' (inquiry)0, /* tp_clear */\n' + \
+ ' (richcmpfunc)0, /* tp_richcompare */\n' + \
+ ' 0, /* tp_weaklistoffset */\n' +\
+ ' (getiterfunc)0, /* tp_iter */\n' + \
+ ' (iternextfunc)0, /* tp_iternext */\n' + \
+ ' %(methods)s, /* tp_methods */\n' + \
+ ' 0, /* tp_members */\n' + \
+ ' 0, /* tp_getset */\n' + \
+ ' NULL, /* tp_base */\n' + \
+ ' NULL, /* tp_dict */\n' + \
+ ' (descrgetfunc)0, /* tp_descr_get */\n' + \
+ ' (descrsetfunc)0, /* tp_descr_set */\n' + \
+ ' 0, /* tp_dictoffset */\n' + \
+ ' (initproc)%(initfunc)s, /* tp_init */\n' + \
'};\n\n'
def fixname(name):
@@ -317,70 +353,67 @@ def write_constructor(objname, castmacro, funcobj, fp=sys.stdout):
extracode, arglist)
dict['typecodes'] = parsestr
dict['parselist'] = string.join(parselist, ', ')
- dict['extracode'] = string.join(extracode, '')
+ dict['extracode'] = string.replace(string.join(extracode, ''),
+ 'return NULL;', 'return -1;')
dict['arglist'] = string.join(arglist, ', ')
fp.write(consttmpl % dict)
-def write_getattr(parser, objobj, castmacro, overrides, fp=sys.stdout):
- funcname = '_wrap_' + string.lower(castmacro) + '_getattr'
+def write_getsets(parser, objobj, castmacro, overrides, fp=sys.stdout):
+ getsets_name = string.lower(castmacro) + '_getsets'
+ funcprefix = '_wrap_' + string.lower(castmacro) + '__get_'
- if overrides.is_overriden(funcname[6:]):
- fp.write(overrides.override(funcname[6:]))
- fp.write('\n\n')
- return funcname
-
# no overrides for the whole function. If no fields, don't write a func
if not objobj.fields:
return '0'
- attrchecks = ''
+ getsets = []
for ftype, fname in objobj.fields:
+ funcname = funcprefix + fname
attrname = objobj.c_name + '.' + fname
if overrides.attr_is_overriden(attrname):
code = overrides.attr_override(attrname)
- code = ' ' + string.replace(code, '\n', '\n ')
- attrchecks = attrchecks + attrchecktmpl % { 'attr': fixname(fname),
- 'varlist': '',
- 'code': code }
+ fp.write(code)
+ getsets.append(' { "%s", (getter)%s, (setter)0 },\n' %
+ (fixname(fname), funcname))
continue
try:
varlist = argtypes.VarList()
handler = argtypes.matcher.get(ftype)
code = handler.write_return(ftype, varlist) % \
{'func': castmacro + '(self->obj)->' + fname}
- if code:
- # indent code ...
- code = ' ' + string.replace(code, '\n', '\n ')
- attrchecks = attrchecks + attrchecktmpl % { 'attr': fixname(fname),
- 'varlist': varlist,
- 'code': code }
+ fp.write(gettertmpl % { 'funcname': funcname,
+ 'attr': fname,
+ 'varlist': varlist,
+ 'code': code })
+ getsets.append(' { "%s", (getter)%s, (setter)0 },\n' %
+ (fixname(fname), funcname))
except:
sys.stderr.write("couldn't write check for " + objobj.c_name +
'.' + fname + '\n')
#traceback.print_exc()
- fp.write(getattrtmpl % {'getattr': funcname,
- 'attrchecks': attrchecks })
- return funcname
+ if not getsets:
+ return '0'
+ fp.write('static PyGetSetDef %s[] = {\n' % getsets_name)
+ for getset in getsets:
+ fp.write(getset)
+ fp.write(' { NULL, (getter)0, (setter)0 },\n')
+ fp.write('};\n\n')
+
+ return getsets_name
def write_class(parser, objobj, overrides, fp=sys.stdout):
fp.write('\n/* ----------- ' + objobj.c_name + ' ----------- */\n\n')
constructor = parser.find_constructor(objobj, overrides)
methods = []
castmacro = string.replace(objobj.typecode, '_TYPE_', '_', 1)
+ initfunc = '0'
if constructor:
try:
- methtype = 'METH_VARARGS'
if overrides.is_overriden(constructor.c_name):
fp.write(overrides.override(constructor.c_name))
fp.write('\n\n')
- if overrides.wants_kwargs(constructor.c_name):
- methtype = methtype + '|METH_KEYWORDS'
else:
write_constructor(objobj.c_name, castmacro, constructor, fp)
- methtype = methtype + '|METH_KEYWORDS'
- methods.append(methdeftmpl %
- { 'name': '__init__',
- 'cname': '_wrap_' + constructor.c_name,
- 'flags': methtype})
+ initfunc = '_wrap_' + constructor.c_name
except:
sys.stderr.write('Could not write constructor for ' +
objobj.c_name + '\n')
@@ -389,19 +422,13 @@ def write_class(parser, objobj, overrides, fp=sys.stdout):
if not hasattr(overrides, 'no_constructor_written'):
fp.write(noconstructor)
overrides.no_constructor_written = 1
- methods.append(methdeftmpl %
- { 'name': '__init__',
- 'cname': 'pygobject_no_constructor',
- 'flags': 'METH_VARARGS'})
+ initfunc = 'pygobject_no_constructor'
else:
# this is a hack ...
if not hasattr(overrides, 'no_constructor_written'):
fp.write(noconstructor)
overrides.no_constructor_written = 1
- methods.append(methdeftmpl %
- { 'name': '__init__',
- 'cname': 'pygobject_no_constructor',
- 'flags': 'METH_VARARGS'})
+ initfunc = 'pygobject_no_constructor'
for meth in parser.find_methods(objobj):
if overrides.is_ignored(meth.c_name):
continue
@@ -430,9 +457,13 @@ def write_class(parser, objobj, overrides, fp=sys.stdout):
fp.write('};\n\n')
# write the type template
- dict = { 'class': objobj.c_name, 'classname': objobj.name }
- dict['getattr'] = write_getattr(parser, objobj, castmacro, overrides, fp)
- dict['methods'] = 'METHOD_CHAIN(_Py' + dict['class'] + '_methods)'
+ dict = {
+ 'class': objobj.c_name,
+ 'classname': objobj.name,
+ 'initfunc': initfunc
+ }
+ dict['getsets'] = write_getsets(parser, objobj, castmacro, overrides, fp)
+ dict['methods'] = '_Py' + dict['class'] + '_methods'
fp.write(typetmpl % dict)
def write_interface(parser, interface, overrides, fp=sys.stdout):
@@ -469,7 +500,7 @@ def write_interface(parser, interface, overrides, fp=sys.stdout):
# write the type template
dict = { 'class': interface.c_name, 'classname': interface.name,
'getattr': '0' }
- dict['methods'] = 'METHOD_CHAIN(_Py' + dict['class'] + '_methods)'
+ dict['methods'] = '_Py' + dict['class'] + '_methods'
fp.write(interfacetypetmpl % dict)
## boxed types ...
@@ -546,7 +577,8 @@ def write_boxed_constructor(objname, typecode, funcobj, fp=sys.stdout):
extracode, arglist)
dict['typecodes'] = parsestr
dict['parselist'] = string.join(parselist, ', ')
- dict['extracode'] = string.join(extracode, '')
+ dict['extracode'] = string.replace(string.join(extracode, ''),
+ 'return NULL;', 'return -1;')
dict['arglist'] = string.join(arglist, ', ')
fp.write(boxedconsttmpl % dict)
@@ -597,22 +629,16 @@ def write_boxed(parser, boxedobj, overrides, fp=sys.stdout):
fp.write('\n/* ----------- ' + boxedobj.c_name + ' ----------- */\n\n')
constructor = parser.find_constructor(boxedobj, overrides)
methods = []
+ initfunc = '0'
if constructor:
try:
- methtype = 'METH_VARARGS'
if overrides.is_overriden(constructor.c_name):
fp.write(overrides.override(constructor.c_name))
fp.write('\n\n')
- if overrides.wants_kwargs(constructor.c_name):
- methtype = methtype + '|METH_KEYWORDS'
else:
write_boxed_constructor(boxedobj.c_name, boxedobj.typecode,
constructor, fp)
- methtype = methtype + '|METH_KEYWORDS'
- methods.append(methdeftmpl %
- { 'name': '__init__',
- 'cname': '_wrap_' + constructor.c_name,
- 'flags': methtype})
+ initfunc = '_wrap_' + constructor.c_name
except:
sys.stderr.write('Could not write constructor for ' +
boxedobj.c_name + '\n')
@@ -645,9 +671,9 @@ def write_boxed(parser, boxedobj, overrides, fp=sys.stdout):
fp.write('};\n\n')
# write the type template
- dict = { 'typename': boxedobj.c_name }
+ dict = { 'typename': boxedobj.c_name, 'initfunc': initfunc }
dict['getattr'] = write_boxed_getattr(parser, boxedobj, overrides, fp)
- dict['methods'] = 'METHOD_CHAIN(_Py' + dict['typename'] + '_methods)'
+ dict['methods'] = '_Py' + dict['typename'] + '_methods'
fp.write(boxedtmpl % dict)
@@ -695,16 +721,16 @@ def write_enums(parser, prefix, fp=sys.stdout):
def write_source(parser, overrides, prefix, fp=sys.stdout):
fp.write('/* -*- Mode: C; c-basic-offset: 4 -*- */\n\n')
- fp.write('#include <Python.h>\n#include <ExtensionClass.h>\n\n')
+ fp.write('#include <Python.h>\n\n\n')
fp.write(overrides.get_headers())
fp.write('\n\n')
fp.write('/* ---------- forward type declarations ---------- */\n')
for obj in parser.boxes:
- fp.write('PyExtensionClass Py' + obj.c_name + '_Type;\n')
+ fp.write('PyTypeObject Py' + obj.c_name + '_Type;\n')
for obj in parser.objects:
- fp.write('PyExtensionClass Py' + obj.c_name + '_Type;\n')
+ fp.write('PyTypeObject Py' + obj.c_name + '_Type;\n')
for interface in parser.interfaces:
- fp.write('PyExtensionClass Py' + interface.c_name + '_Type;\n')
+ fp.write('PyTypeObject Py' + interface.c_name + '_Type;\n')
fp.write('\n')
for boxed in parser.boxes:
write_boxed(parser, boxed, overrides, fp)
@@ -722,7 +748,6 @@ def write_source(parser, overrides, prefix, fp=sys.stdout):
fp.write('/* intialise stuff extension classes */\n')
fp.write('void\n' + prefix + '_register_classes(PyObject *d)\n{\n')
- fp.write(' ExtensionClassImported;\n')
fp.write(overrides.get_init() + '\n')
for boxed in parser.boxes:
diff --git a/configure.in b/configure.in
index eee9d7bf..8783ea3a 100644
--- a/configure.in
+++ b/configure.in
@@ -11,7 +11,23 @@ ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS"
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
-AM_PATH_PYTHON(2.0)
+dnl AM_PATH_PYTHON(2.2)
+AM_PATH_PYTHON
+AC_MSG_CHECKING(for python >= 2.2)
+prog="
+import sys, string
+minver = (2,2,0)
+if sys.version_info < minver:
+ sys.exit(1)
+sys.exit(0)"
+if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC
+then
+ AC_MSG_RESULT(okay)
+else
+ AC_MSG_ERROR(too old)
+fi
+
+
AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)])
AC_ARG_ENABLE(thread,
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index 8bf83d0c..14fe42ee 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -7,13 +7,21 @@ static GHashTable *class_hash;
static GQuark pygobject_wrapper_key = 0;
static GQuark pygobject_ownedref_key = 0;
-staticforward PyExtensionClass PyGObject_Type;
-static void pygobject_dealloc(PyGObject *self);
-static PyObject *pygobject_getattro(PyGObject *self, PyObject *attro);
-static int pygobject_setattr(PyGObject *self, char *attr, PyObject *val);
-static int pygobject_compare(PyGObject *self, PyGObject *v);
-static long pygobject_hash(PyGObject *self);
-static PyObject *pygobject_repr(PyGObject *self);
+staticforward PyTypeObject PyGObject_Type;
+static void pygobject_dealloc(PyGObject *self);
+static int pygobject_traverse(PyGObject *self, visitproc visit, void *arg);
+
+static void
+object_free(PyObject *op)
+{
+ PyObject_FREE(op);
+}
+
+static void
+object_gc_free(PyObject *op)
+{
+ PyObject_GC_Del(op);
+}
/* -------------- __gtype__ objects ---------------------------- */
@@ -103,7 +111,7 @@ pygobject_destroy_notify(gpointer user_data)
static void
pygobject_register_class(PyObject *dict, const gchar *type_name,
- GType type, PyExtensionClass *ec,
+ GType gtype, PyTypeObject *type,
PyObject *bases)
{
PyObject *o;
@@ -112,28 +120,35 @@ pygobject_register_class(PyObject *dict, const gchar *type_name,
if (!class_hash)
class_hash = g_hash_table_new(g_str_hash, g_str_equal);
- class_name = ec->tp_name;
- /* set standard pyobject class functions if they aren't already set */
- if (!ec->tp_dealloc) ec->tp_dealloc = (destructor)pygobject_dealloc;
- if (!ec->tp_getattro) ec->tp_getattro = (getattrofunc)pygobject_getattro;
- if (!ec->tp_setattr) ec->tp_setattr = (setattrfunc)pygobject_setattr;
- if (!ec->tp_compare) ec->tp_compare = (cmpfunc)pygobject_compare;
- if (!ec->tp_repr) ec->tp_repr = (reprfunc)pygobject_repr;
- if (!ec->tp_hash) ec->tp_hash = (hashfunc)pygobject_hash;
+ class_name = type->tp_name;
+ type->ob_type = &PyType_Type;
if (bases) {
- PyExtensionClass_ExportSubclass(dict, (char *)class_name,
- *ec, bases);
- } else {
- PyExtensionClass_Export(dict, (char *)class_name, *ec);
+ type->tp_bases = bases;
+ type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
}
- if (type) {
- o = pyg_type_wrapper_new(type);
- PyDict_SetItemString(ec->class_dictionary, "__gtype__", o);
+ type->tp_dealloc = (destructor)pygobject_dealloc;
+ type->tp_traverse = (traverseproc)pygobject_traverse;
+ type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+ type->tp_weaklistoffset = offsetof(PyGObject, weakreflist);
+ type->tp_dictoffset = offsetof(PyGObject, inst_dict);
+
+ if (PyType_Ready(type) < 0) {
+ g_warning ("couldn't make the type `%s' ready", type->tp_name);
+ return;
+ }
+
+ if (gtype) {
+ o = pyg_type_wrapper_new(gtype);
+ PyDict_SetItemString(type->tp_dict, "__gtype__", o);
+ PyDict_SetItemString(type->tp_defined, "__gtype__", o);
Py_DECREF(o);
}
- g_hash_table_insert(class_hash, g_strdup(type_name), ec);
+
+ g_hash_table_insert(class_hash, g_strdup(type_name), type);
+
+ PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
}
void
@@ -145,17 +160,17 @@ pygobject_register_wrapper(PyObject *self)
g_object_set_qdata(obj, pygobject_wrapper_key, self);
}
-static PyExtensionClass *
-pygobject_lookup_class(GType type)
+static PyTypeObject *
+pygobject_lookup_class(GType gtype)
{
- PyExtensionClass *ec;
+ PyTypeObject *type;
/* find the python type for this object. If not found, use parent. */
- while ((ec = g_hash_table_lookup(class_hash, g_type_name(type))) == NULL
- && type != 0)
- type = g_type_parent(type);
- g_assert(ec != NULL);
- return ec;
+ while ((type = g_hash_table_lookup(class_hash, g_type_name(gtype))) == NULL
+ && gtype != 0)
+ gtype = g_type_parent(gtype);
+ g_assert(type != NULL);
+ return type;
}
static PyObject *
@@ -181,8 +196,8 @@ pygobject_new(GObject *obj)
return (PyObject *)self;
}
- tp = (PyTypeObject *)pygobject_lookup_class(G_TYPE_FROM_INSTANCE(obj));
- self = PyObject_NEW(PyGObject, tp);
+ tp = pygobject_lookup_class(G_TYPE_FROM_INSTANCE(obj));
+ self = PyObject_GC_New(PyGObject, tp);
if (self == NULL)
return NULL;
@@ -190,7 +205,6 @@ pygobject_new(GObject *obj)
g_object_ref(obj);
/* save wrapper pointer so we can access it later */
g_object_set_qdata(obj, pygobject_wrapper_key, self);
- self->inst_dict = PyDict_New();
return (PyObject *)self;
}
@@ -221,7 +235,8 @@ pyg_boxed_dealloc(PyGBoxed *self)
{
if (self->free_on_dealloc && self->boxed)
g_boxed_free(self->gtype, self->boxed);
- PyMem_DEL(self);
+
+ self->ob_type->tp_free((PyObject *)self);
}
static int
@@ -248,46 +263,13 @@ pyg_boxed_repr(PyGBoxed *self)
return PyString_FromString(buf);
}
-static PyObject *
-pyg_boxed_getattro(PyGBoxed *self, PyObject *attro)
-{
- char *attr;
- PyObject *ret;
-
- attr = PyString_AsString(attro);
-
- ret = Py_FindAttrString((PyObject *)self, attr);
- if (ret)
- return ret;
- PyErr_Clear();
-
- if (self->ob_type->tp_getattr)
- return (* self->ob_type->tp_getattr)((PyObject *)self, attr);
-
- PyErr_SetString(PyExc_AttributeError, attr);
- return NULL;
-}
-
-static PyObject *
-pyg_boxed__class_init__(PyObject *self, PyObject *args)
-{
- PyExtensionClass *subclass;
-
- if (!PyArg_ParseTuple(args, "O:GBoxed.__class_init__", &subclass))
- return NULL;
-
- g_message("subclassing GBoxed types is bad m'kay");
- PyErr_SetString(PyExc_TypeError, "attempt to subclass a boxed type");
- return NULL;
-}
-
-static PyObject *
-pyg_boxed_init(PyGBoxed *self, PyObject *args)
+static int
+pyg_boxed_init(PyGBoxed *self, PyObject *args, PyObject *kwargs)
{
gchar buf[512];
if (!PyArg_ParseTuple(args, ":GBoxed.__init__"))
- return NULL;
+ return -1;
self->boxed = NULL;
self->gtype = 0;
@@ -295,16 +277,10 @@ pyg_boxed_init(PyGBoxed *self, PyObject *args)
g_snprintf(buf, sizeof(buf), "%s can not be constructed", self->ob_type->tp_name);
PyErr_SetString(PyExc_NotImplementedError, buf);
- return NULL;
+ return -1;
}
-static PyMethodDef pyg_boxed_methods[] = {
- {"__class_init__",pyg_boxed__class_init__, METH_VARARGS|METH_CLASS_METHOD},
- {"__init__", (PyCFunction)pyg_boxed_init, METH_VARARGS},
- {NULL,NULL,0}
-};
-
-static PyExtensionClass PyGBoxed_Type = {
+static PyTypeObject PyGBoxed_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"GBoxed", /* tp_name */
@@ -323,43 +299,64 @@ static PyExtensionClass PyGBoxed_Type = {
(hashfunc)pyg_boxed_hash, /* tp_hash */
(ternaryfunc)0, /* tp_call */
(reprfunc)0, /* tp_str */
- (getattrofunc)pyg_boxed_getattro, /* tp_getattro */
+ (getattrofunc)0, /* tp_getattro */
(setattrofunc)0, /* tp_setattro */
- /* Space for future expansion */
- 0L, 0L,
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
NULL, /* Documentation string */
- METHOD_CHAIN(pyg_boxed_methods),
- 0,
+ (traverseproc)0, /* tp_traverse */
+ (inquiry)0, /* tp_clear */
+ (richcmpfunc)0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)0, /* tp_iter */
+ (iternextfunc)0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ (PyTypeObject *)0, /* tp_base */
+ (PyObject *)0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)pyg_boxed_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ object_free, /* tp_free */
+ (PyObject *)0, /* tp_bases */
};
static GHashTable *boxed_types = NULL;
static void
pyg_register_boxed(PyObject *dict, const gchar *class_name,
- GType boxed_type, PyExtensionClass *ec)
+ GType boxed_type, PyTypeObject *type)
{
PyObject *o;
g_return_if_fail(dict != NULL);
g_return_if_fail(class_name != NULL);
g_return_if_fail(boxed_type != 0);
- g_return_if_fail(ec != NULL);
if (!boxed_types)
boxed_types = g_hash_table_new(g_direct_hash, g_direct_equal);
- if (!ec->tp_dealloc) ec->tp_dealloc = (destructor)pyg_boxed_dealloc;
- if (!ec->tp_compare) ec->tp_compare = (cmpfunc)pyg_boxed_compare;
- if (!ec->tp_hash) ec->tp_hash = (hashfunc)pyg_boxed_hash;
- if (!ec->tp_repr) ec->tp_repr = (reprfunc)pyg_boxed_repr;
- if (!ec->tp_getattro) ec->tp_getattro = (getattrofunc)pyg_boxed_getattro;
+ if (!type->tp_dealloc) type->tp_dealloc = (destructor)pyg_boxed_dealloc;
- PyExtensionClass_ExportSubclassSingle(dict, (char *)class_name, *ec,
- PyGBoxed_Type);
- PyDict_SetItemString(ec->class_dictionary, "__gtype__",
+ type->ob_type = &PyType_Type;
+ type->tp_base = &PyGBoxed_Type;
+
+ if (PyType_Ready(type) < 0) {
+ g_warning("could not get type `%s' ready", type->tp_name);
+ return;
+ }
+
+ PyDict_SetItemString(type->tp_dict, "__gtype__",
o=pyg_type_wrapper_new(boxed_type));
+ PyDict_SetItemString(type->tp_defined, "__gtype__", o);
Py_DECREF(o);
- g_hash_table_insert(boxed_types, GUINT_TO_POINTER(boxed_type), ec);
+ g_hash_table_insert(boxed_types, GUINT_TO_POINTER(boxed_type), type);
+
+ PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
}
static PyObject *
@@ -641,8 +638,8 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
break;
case G_TYPE_OBJECT:
{
- PyExtensionClass *ec =pygobject_lookup_class(G_VALUE_TYPE(value));
- if (!ExtensionClassSubclassInstance_Check(obj, ec)) {
+ PyTypeObject *type =pygobject_lookup_class(G_VALUE_TYPE(value));
+ if (!PyObject_TypeCheck(obj, type)) {
return -1;
}
g_value_set_object(value, pygobject_get(obj));
@@ -670,7 +667,7 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT)) {
g_value_set_boxed(value, obj);
- } else if (ExtensionClassSubclassInstance_Check(obj, &PyGBoxed_Type) &&
+ } else if (PyObject_TypeCheck(obj, &PyGBoxed_Type) &&
G_VALUE_HOLDS(value, ((PyGBoxed *)obj)->gtype)) {
g_value_set_boxed(value, pyg_boxed_get(obj, gpointer));
} else if ((bm = pyg_boxed_lookup(G_VALUE_TYPE(value))) != NULL) {
@@ -955,89 +952,36 @@ pyg_signal_class_closure_get(void)
}
/* -------------- PyGObject behaviour ----------------- */
+
static void
pygobject_dealloc(PyGObject *self)
{
GObject *obj = self->obj;
- if (obj && !(((PyExtensionClass *)self->ob_type)->class_flags &
- EXTENSIONCLASS_PYSUBCLASS_FLAG)) {
- /* save reference to python wrapper if there are still
- * references to the GObject in such a way that it will be
- * freed when the GObject is destroyed, so is the python
- * wrapper, but if a python wrapper can be */
- if (obj->ref_count > 1) {
- Py_INCREF(self); /* grab a reference on the wrapper */
- self->hasref = TRUE;
- g_object_set_qdata_full(obj, pygobject_ownedref_key,
- self, pygobject_destroy_notify);
- g_object_unref(obj);
- return;
- }
- if (!self->hasref) /* don't unref the GObject if it owns us */
- g_object_unref(obj);
- }
- /* subclass_dealloc (ExtensionClass.c) does this for us for python
- * subclasses */
- if (self->inst_dict &&
- !(((PyExtensionClass *)self->ob_type)->class_flags &
- EXTENSIONCLASS_PYSUBCLASS_FLAG)) {
- Py_DECREF(self->inst_dict);
- }
- PyMem_DEL(self);
-}
-
-/* standard getattr method */
-static PyObject *
-check_bases(PyGObject *self, PyExtensionClass *class, char *attr)
-{
- PyObject *ret;
-
- if (class->tp_getattr) {
- ret = (* class->tp_getattr)((PyObject *)self, attr);
- if (ret)
- return ret;
- else
- PyErr_Clear();
+ /* save reference to python wrapper if there are still
+ * references to the GObject in such a way that it will be
+ * freed when the GObject is destroyed, so is the python
+ * wrapper, but if a python wrapper can be */
+ if (obj && obj->ref_count > 1) {
+ Py_INCREF(self); /* grab a reference on the wrapper */
+ self->hasref = TRUE;
+ g_object_set_qdata_full(obj, pygobject_ownedref_key,
+ self, pygobject_destroy_notify);
+ g_object_unref(obj);
+ return;
}
- if (PyExtensionClass_Check(class) && class->bases) {
- guint i, len = PyTuple_Size(class->bases);
+ if (obj && !self->hasref) /* don't unref the GObject if it owns us */
+ g_object_unref(obj);
- for (i = 0; i < len; i++) {
- PyExtensionClass *base = (PyExtensionClass *)PyTuple_GetItem(
- class->bases, i);
-
- ret = check_bases(self, base, attr);
- if (ret)
- return ret;
- }
- }
- return NULL;
-}
-static PyObject *
-pygobject_getattro(PyGObject *self, PyObject *attro)
-{
- char *attr;
- PyObject *ret;
+ PyObject_ClearWeakRefs((PyObject *)self);
- attr = PyString_AsString(attro);
+ PyObject_GC_UnTrack((PyObject *)self);
- ret = Py_FindAttrString((PyObject *)self, attr);
- if (ret)
- return ret;
- PyErr_Clear();
- ret = check_bases(self, (PyExtensionClass *)self->ob_type, attr);
- if (ret)
- return ret;
- PyErr_SetString(PyExc_AttributeError, attr);
- return NULL;
-}
+ if (self->inst_dict)
+ Py_DECREF(self->inst_dict);
+ self->inst_dict = NULL;
-static int
-pygobject_setattr(PyGObject *self, char *attr, PyObject *value)
-{
- PyDict_SetItemString(INSTANCE_DICT(self), attr, value);
- return 0;
+ self->ob_type->tp_free((PyObject *)self);
}
static int
@@ -1064,90 +1008,43 @@ pygobject_repr(PyGObject *self)
return PyString_FromString(buf);
}
-/* ---------------- PyGObject methods ----------------- */
-static destructor real_subclass_dealloc = NULL;
-static void
-pygobject_subclass_dealloc(PyGObject *self)
+static int
+pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
{
- GObject *obj = self->obj;
-
- if (obj) {
- /* save reference to python wrapper if there are still
- * references to the GObject in such a way that it will be
- * freed when the GObject is destroyed, so is the python
- * wrapper, but if a python wrapper can be */
- if (obj->ref_count > 1) {
- Py_INCREF(self); /* grab a reference on the wrapper */
- self->hasref = TRUE;
- g_object_set_qdata_full(obj, pygobject_ownedref_key,
- self, pygobject_destroy_notify);
- g_object_unref(obj);
- return;
- }
- if (!self->hasref) /* don't unref the GObject if it owns us */
- g_object_unref(obj);
- }
- if (real_subclass_dealloc)
- (* real_subclass_dealloc)((PyObject *)self);
+ if (self->inst_dict)
+ return visit(self->inst_dict, arg);
+ return 0;
}
-/* more hackery to stop segfaults caused by multi deallocs on a subclass
- * (which happens quite regularly in pygobject) */
-static PyObject *
-pygobject__class_init__(PyObject *something, PyObject *args)
-{
- PyExtensionClass *subclass;
- GTypeInfo type_info = {
- 0, /* class_size */
- (GBaseInitFunc) 0,
- (GBaseFinalizeFunc) 0,
- (GClassInitFunc) 0,
- (GClassFinalizeFunc) 0,
- NULL, /* class_data */
-
- 0, /* instance_size */
- 0, /* n_preallocs */
- (GInstanceInitFunc) 0
- };
-
- if (!PyArg_ParseTuple(args, "O:GObject.__class_init__", &subclass))
- return NULL;
- g_message("__class_init__ called for %s", subclass->tp_name);
-
- /* make sure ExtensionClass doesn't screw up our dealloc hack */
- if ((subclass->class_flags & EXTENSIONCLASS_PYSUBCLASS_FLAG) &&
- subclass->tp_dealloc != (destructor)pygobject_subclass_dealloc) {
- real_subclass_dealloc = subclass->tp_dealloc;
- subclass->tp_dealloc = (destructor)pygobject_subclass_dealloc;
- }
-
- /* put code in here to create a new GType for this subclass, using
- * __module__.__name__ as the name for the type. Then we can add
- * the code needed for adding signals to the subclass. The actual
- * implementation will have to wait for a g_type_query function */
-
- Py_INCREF(Py_None);
- return Py_None;
-}
+/* ---------------- PyGObject methods ----------------- */
-static PyObject *
-pygobject__init__(PyGObject *self, PyObject *args)
+static int
+pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
{
GType object_type;
if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
- return NULL;
+ return -1;
object_type = pyg_type_from_object((PyObject *)self);
if (!object_type)
- return NULL;
+ return -1;
self->obj = g_object_new(object_type, NULL);
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create object");
- return NULL;
+ return -1;
}
pygobject_register_wrapper((PyObject *)self);
+
+ return 0;
+}
+
+static PyObject *
+pygobject__gobject_init__(PyGObject *self, PyObject *args, PyObject *kwargs)
+{
+ if (pygobject_init(self, args, kwargs) < 0)
+ return NULL;
Py_INCREF(Py_None);
return Py_None;
}
@@ -1552,9 +1449,8 @@ pygobject_stop_emission(PyGObject *self, PyObject *args)
}
static PyMethodDef pygobject_methods[] = {
- { "__class_init__", (PyCFunction)pygobject__class_init__, METH_VARARGS|METH_CLASS_METHOD },
- { "__init__", (PyCFunction)pygobject__init__, METH_VARARGS },
- { "__gobject_init__", (PyCFunction)pygobject__init__, METH_VARARGS },
+ { "__gobject_init__", (PyCFunction)pygobject__gobject_init__,
+ METH_VARARGS|METH_KEYWORDS },
{ "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
{ "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
{ "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS },
@@ -1576,7 +1472,24 @@ static PyMethodDef pygobject_methods[] = {
{ NULL, NULL, 0 }
};
-static PyExtensionClass PyGObject_Type = {
+static PyObject *
+pygobject_get_dict(PyGObject *self, void *closure)
+{
+ if (self->inst_dict == NULL) {
+ self->inst_dict = PyDict_New();
+ if (self->inst_dict == NULL)
+ return NULL;
+ }
+ Py_INCREF(self->inst_dict);
+ return self->inst_dict;
+}
+
+static PyGetSetDef pygobject_getsets[] = {
+ { "__dict__", (getter)pygobject_get_dict, (setter)0 },
+ { NULL, 0, 0 }
+};
+
+static PyTypeObject PyGObject_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"GObject", /* tp_name */
@@ -1586,7 +1499,7 @@ static PyExtensionClass PyGObject_Type = {
(destructor)pygobject_dealloc, /* tp_dealloc */
(printfunc)0, /* tp_print */
(getattrfunc)0, /* tp_getattr */
- (setattrfunc)pygobject_setattr, /* tp_setattr */
+ (setattrfunc)0, /* tp_setattr */
(cmpfunc)pygobject_compare, /* tp_compare */
(reprfunc)pygobject_repr, /* tp_repr */
0, /* tp_as_number */
@@ -1597,53 +1510,51 @@ static PyExtensionClass PyGObject_Type = {
(reprfunc)0, /* tp_str */
(getattrofunc)0, /* tp_getattro */
(setattrofunc)0, /* tp_setattro */
- /* Space for future expansion */
- 0L, 0L,
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC, /* tp_flags */
NULL, /* Documentation string */
- METHOD_CHAIN(pygobject_methods),
- EXTENSIONCLASS_INSTDICT_FLAG,
+ (traverseproc)pygobject_traverse, /* tp_traverse */
+ (inquiry)0, /* tp_clear */
+ (richcmpfunc)0, /* tp_richcompare */
+ offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */
+ (getiterfunc)0, /* tp_iter */
+ (iternextfunc)0, /* tp_iternext */
+ pygobject_methods, /* tp_methods */
+ 0, /* tp_members */
+ pygobject_getsets, /* tp_getset */
+ (PyTypeObject *)0, /* tp_base */
+ (PyObject *)0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof(PyGObject, inst_dict), /* tp_dictoffset */
+ (initproc)pygobject_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ object_gc_free, /* tp_free */
+ (PyObject *)0, /* tp_bases */
};
/* ---------------- GInterface functions -------------------- */
-static PyObject *
-pyg_interface__class_init__(PyObject *self, PyObject *args)
-{
- PyExtensionClass *subclass;
-
- if (!PyArg_ParseTuple(args, "O:GInterface.__class_init__", &subclass))
- return NULL;
-
- g_message("subclassing GInterface types is bad m'kay");
- PyErr_SetString(PyExc_TypeError, "attempt to subclass an interface");
- return NULL;
-}
-
-static PyObject *
-pyg_interface_init(PyObject *self, PyObject *args)
+static int
+pyg_interface_init(PyObject *self, PyObject *args, PyObject *kwargs)
{
gchar buf[512];
if (!PyArg_ParseTuple(args, ":GInterface.__init__"))
- return NULL;
+ return -1;
g_snprintf(buf, sizeof(buf), "%s can not be constructed", self->ob_type->tp_name);
PyErr_SetString(PyExc_NotImplementedError, buf);
- return NULL;
+ return -1;
}
-static PyMethodDef pyg_interface_methods[] = {
- {"__class_init__", pyg_interface__class_init__,
- METH_VARARGS|METH_CLASS_METHOD},
- {"__init__", pyg_interface_init, METH_VARARGS},
- {NULL,NULL,0}
-};
-
-static PyExtensionClass PyGInterface_Type = {
+static PyTypeObject PyGInterface_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"GInterface", /* tp_name */
- sizeof(PyPureMixinObject), /* tp_basicsize */
+ sizeof(PyObject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)0, /* tp_dealloc */
@@ -1660,27 +1571,52 @@ static PyExtensionClass PyGInterface_Type = {
(reprfunc)0, /* tp_str */
(getattrofunc)0, /* tp_getattro */
(setattrofunc)0, /* tp_setattro */
- /* Space for future expansion */
- 0L, 0L,
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
NULL, /* Documentation string */
- METHOD_CHAIN(pyg_interface_methods),
- 0,
+ (traverseproc)0, /* tp_traverse */
+ (inquiry)0, /* tp_clear */
+ (richcmpfunc)0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)0, /* tp_iter */
+ (iternextfunc)0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ (PyTypeObject *)0, /* tp_base */
+ (PyObject *)0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)pyg_interface_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ object_free, /* tp_free */
+ (PyObject *)0, /* tp_bases */
};
static void
pyg_register_interface(PyObject *dict, const gchar *class_name,
- GType type, PyExtensionClass *ec)
+ GType gtype, PyTypeObject *type)
{
PyObject *o;
- PyExtensionClass_ExportSubclassSingle(dict, (char *)class_name,
- *ec, PyGInterface_Type);
+ type->ob_type = &PyType_Type;
+ type->tp_base = &PyGInterface_Type;
+
+ if (PyType_Ready(type) < 0) {
+ g_warning("could not ready `%s'", type->tp_name);
+ return;
+ }
- if (type) {
- o = pyg_type_wrapper_new(type);
- PyDict_SetItemString(ec->class_dictionary, "__gtype__", o);
+ if (gtype) {
+ o = pyg_type_wrapper_new(gtype);
+ PyDict_SetItemString(type->tp_dict, "__gtype__", o);
+ PyDict_SetItemString(type->tp_defined, "__gtype__", o);
Py_DECREF(o);
}
+
+ PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
}
@@ -1806,7 +1742,8 @@ pyg_type_interfaces (PyObject *self, PyObject *args)
static PyObject *
pyg_type_register(PyObject *self, PyObject *args)
{
- PyObject *class, *gtype, *module;
+ PyObject *gtype, *module;
+ PyTypeObject *class;
GType parent_type, instance_type;
gchar *type_name = NULL;
gint i;
@@ -1828,28 +1765,28 @@ pyg_type_register(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O:gobject.type_register", &class))
return NULL;
- if (!ExtensionClassSubclass_Check(class, &PyGObject_Type)) {
+ if (!PyType_IsSubtype(class, &PyGObject_Type)) {
PyErr_SetString(PyExc_TypeError,"argument must be a GObject subclass");
return NULL;
}
/* find the GType of the parent */
- parent_type = pyg_type_from_object(class);
+ parent_type = pyg_type_from_object((PyObject *)class);
if (!parent_type) {
return NULL;
}
/* make name for new widget */
- module = PyObject_GetAttrString(class, "__module__");
+ module = PyObject_GetAttrString((PyObject *)class, "__module__");
if (module && PyString_Check(module)) {
type_name = g_strconcat(PyString_AsString(module), ".",
- ((PyExtensionClass *)class)->tp_name, NULL);
+ class->tp_name, NULL);
} else {
if (module)
Py_DECREF(module);
else
PyErr_Clear();
- type_name = g_strdup(((PyExtensionClass *)class)->tp_name);
+ type_name = g_strdup(class->tp_name);
}
/* convert '.' in type name to '+', which isn't banned (grumble) */
for (i = 0; type_name[i] != '\0'; i++)
@@ -1872,7 +1809,8 @@ pyg_type_register(PyObject *self, PyObject *args)
/* set new value of __gtype__ on class */
gtype = pyg_type_wrapper_new(instance_type);
- PyObject_SetAttrString(class, "__gtype__", gtype);
+ PyDict_SetItemString(class->tp_dict, "__gtype__", gtype);
+ PyDict_SetItemString(class->tp_defined, "__gtype__", gtype);
Py_DECREF(gtype);
Py_INCREF(Py_None);
@@ -2159,14 +2097,22 @@ initgobject(void)
pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
&PyGObject_Type, NULL);
- PyExtensionClass_Export(d, "GInterface", PyGInterface_Type);
- PyDict_SetItemString(PyGInterface_Type.class_dictionary, "__gtype__",
+ PyGInterface_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&PyGInterface_Type))
+ return;
+ PyDict_SetItemString(d, "GInterface", (PyObject *)&PyGInterface_Type);
+ PyDict_SetItemString(PyGInterface_Type.tp_dict, "__gtype__",
o=pyg_type_wrapper_new(G_TYPE_INTERFACE));
+ PyDict_SetItemString(PyGInterface_Type.tp_defined, "__gtype__", o);
Py_DECREF(o);
- PyExtensionClass_Export(d, "GBoxed", PyGBoxed_Type);
- PyDict_SetItemString(PyGBoxed_Type.class_dictionary, "__gtype__",
+ PyGBoxed_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&PyGBoxed_Type))
+ return;
+ PyDict_SetItemString(d, "GBoxed", (PyObject *)&PyGBoxed_Type);
+ PyDict_SetItemString(PyGBoxed_Type.tp_dict, "__gtype__",
o=pyg_type_wrapper_new(G_TYPE_BOXED));
+ PyDict_SetItemString(PyGBoxed_Type.tp_defined, "__gtype__", o);
Py_DECREF(o);
boxed_marshalers = g_hash_table_new(g_direct_hash, g_direct_equal);
diff --git a/gobject/pygobject.h b/gobject/pygobject.h
index 2b031a13..4be17b9a 100644
--- a/gobject/pygobject.h
+++ b/gobject/pygobject.h
@@ -3,7 +3,6 @@
#define _PYGOBJECT_H_
#include <Python.h>
-#include <ExtensionClass.h>
#include <glib.h>
#include <glib-object.h>
@@ -13,10 +12,11 @@ typedef struct {
GObject *obj;
gboolean hasref; /* the GObject owns this reference */
PyObject *inst_dict; /* the instance dictionary -- must be last */
+ PyObject *weakreflist; /* list of weak references */
} PyGObject;
#define pygobject_get(v) (((PyGObject *)(v))->obj)
-#define pygobject_check(v,base) (ExtensionClassSubclassInstance_Check(v,base))
+#define pygobject_check(v,base) (PyObject_TypeCheck(v,base))
typedef struct {
PyObject_HEAD
@@ -26,13 +26,13 @@ typedef struct {
} PyGBoxed;
#define pyg_boxed_get(v,t) ((t *)((PyGBoxed *)(v))->boxed)
-#define pyg_boxed_check(v,typecode) (ExtensionClassSubclassInstance_Check(v, &PyGBoxed_Type) && ((PyGBoxed *)(v))->gtype == typecode)
+#define pyg_boxed_check(v,typecode) (PyObject_TypeCheck(v, &PyGBoxed_Type) && ((PyGBoxed *)(v))->gtype == typecode)
struct _PyGObject_Functions {
void (* register_class)(PyObject *dict, const gchar *class_name,
- GType type, PyExtensionClass *ec, PyObject *bases);
+ GType gtype, PyTypeObject *type, PyObject *bases);
void (* register_wrapper)(PyObject *self);
- PyExtensionClass *(* lookup_class)(GType type);
+ PyTypeObject *(* lookup_class)(GType type);
PyObject *(* newgobj)(GObject *obj);
GClosure *(* closure_new)(PyObject *callback, PyObject *extra_args,
PyObject *swap_data);
@@ -49,11 +49,11 @@ struct _PyGObject_Functions {
PyObject *(* value_as_pyobject)(const GValue *value);
void (* register_interface)(PyObject *dict, const gchar *class_name,
- GType type, PyExtensionClass *ec);
+ GType gtype, PyTypeObject *type);
- PyExtensionClass *boxed_type;
+ PyTypeObject *boxed_type;
void (* register_boxed)(PyObject *dict, const gchar *class_name,
- GType boxed_type, PyExtensionClass *ec);
+ GType boxed_type, PyTypeObject *type);
PyObject *(* boxed_new)(GType boxed_type, gpointer boxed,
gboolean copy_boxed, gboolean own_ref);
@@ -105,7 +105,6 @@ struct _PyGObject_Functions *_PyGObject_API;
Py_FatalError("could not import gobject"); \
return; \
} \
- ExtensionClassImported; \
}
#endif /* !_INSIDE_PYGOBJECT_ */
diff --git a/gobjectmodule.c b/gobjectmodule.c
index 8bf83d0c..14fe42ee 100644
--- a/gobjectmodule.c
+++ b/gobjectmodule.c
@@ -7,13 +7,21 @@ static GHashTable *class_hash;
static GQuark pygobject_wrapper_key = 0;
static GQuark pygobject_ownedref_key = 0;
-staticforward PyExtensionClass PyGObject_Type;
-static void pygobject_dealloc(PyGObject *self);
-static PyObject *pygobject_getattro(PyGObject *self, PyObject *attro);
-static int pygobject_setattr(PyGObject *self, char *attr, PyObject *val);
-static int pygobject_compare(PyGObject *self, PyGObject *v);
-static long pygobject_hash(PyGObject *self);
-static PyObject *pygobject_repr(PyGObject *self);
+staticforward PyTypeObject PyGObject_Type;
+static void pygobject_dealloc(PyGObject *self);
+static int pygobject_traverse(PyGObject *self, visitproc visit, void *arg);
+
+static void
+object_free(PyObject *op)
+{
+ PyObject_FREE(op);
+}
+
+static void
+object_gc_free(PyObject *op)
+{
+ PyObject_GC_Del(op);
+}
/* -------------- __gtype__ objects ---------------------------- */
@@ -103,7 +111,7 @@ pygobject_destroy_notify(gpointer user_data)
static void
pygobject_register_class(PyObject *dict, const gchar *type_name,
- GType type, PyExtensionClass *ec,
+ GType gtype, PyTypeObject *type,
PyObject *bases)
{
PyObject *o;
@@ -112,28 +120,35 @@ pygobject_register_class(PyObject *dict, const gchar *type_name,
if (!class_hash)
class_hash = g_hash_table_new(g_str_hash, g_str_equal);
- class_name = ec->tp_name;
- /* set standard pyobject class functions if they aren't already set */
- if (!ec->tp_dealloc) ec->tp_dealloc = (destructor)pygobject_dealloc;
- if (!ec->tp_getattro) ec->tp_getattro = (getattrofunc)pygobject_getattro;
- if (!ec->tp_setattr) ec->tp_setattr = (setattrfunc)pygobject_setattr;
- if (!ec->tp_compare) ec->tp_compare = (cmpfunc)pygobject_compare;
- if (!ec->tp_repr) ec->tp_repr = (reprfunc)pygobject_repr;
- if (!ec->tp_hash) ec->tp_hash = (hashfunc)pygobject_hash;
+ class_name = type->tp_name;
+ type->ob_type = &PyType_Type;
if (bases) {
- PyExtensionClass_ExportSubclass(dict, (char *)class_name,
- *ec, bases);
- } else {
- PyExtensionClass_Export(dict, (char *)class_name, *ec);
+ type->tp_bases = bases;
+ type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
}
- if (type) {
- o = pyg_type_wrapper_new(type);
- PyDict_SetItemString(ec->class_dictionary, "__gtype__", o);
+ type->tp_dealloc = (destructor)pygobject_dealloc;
+ type->tp_traverse = (traverseproc)pygobject_traverse;
+ type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+ type->tp_weaklistoffset = offsetof(PyGObject, weakreflist);
+ type->tp_dictoffset = offsetof(PyGObject, inst_dict);
+
+ if (PyType_Ready(type) < 0) {
+ g_warning ("couldn't make the type `%s' ready", type->tp_name);
+ return;
+ }
+
+ if (gtype) {
+ o = pyg_type_wrapper_new(gtype);
+ PyDict_SetItemString(type->tp_dict, "__gtype__", o);
+ PyDict_SetItemString(type->tp_defined, "__gtype__", o);
Py_DECREF(o);
}
- g_hash_table_insert(class_hash, g_strdup(type_name), ec);
+
+ g_hash_table_insert(class_hash, g_strdup(type_name), type);
+
+ PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
}
void
@@ -145,17 +160,17 @@ pygobject_register_wrapper(PyObject *self)
g_object_set_qdata(obj, pygobject_wrapper_key, self);
}
-static PyExtensionClass *
-pygobject_lookup_class(GType type)
+static PyTypeObject *
+pygobject_lookup_class(GType gtype)
{
- PyExtensionClass *ec;
+ PyTypeObject *type;
/* find the python type for this object. If not found, use parent. */
- while ((ec = g_hash_table_lookup(class_hash, g_type_name(type))) == NULL
- && type != 0)
- type = g_type_parent(type);
- g_assert(ec != NULL);
- return ec;
+ while ((type = g_hash_table_lookup(class_hash, g_type_name(gtype))) == NULL
+ && gtype != 0)
+ gtype = g_type_parent(gtype);
+ g_assert(type != NULL);
+ return type;
}
static PyObject *
@@ -181,8 +196,8 @@ pygobject_new(GObject *obj)
return (PyObject *)self;
}
- tp = (PyTypeObject *)pygobject_lookup_class(G_TYPE_FROM_INSTANCE(obj));
- self = PyObject_NEW(PyGObject, tp);
+ tp = pygobject_lookup_class(G_TYPE_FROM_INSTANCE(obj));
+ self = PyObject_GC_New(PyGObject, tp);
if (self == NULL)
return NULL;
@@ -190,7 +205,6 @@ pygobject_new(GObject *obj)
g_object_ref(obj);
/* save wrapper pointer so we can access it later */
g_object_set_qdata(obj, pygobject_wrapper_key, self);
- self->inst_dict = PyDict_New();
return (PyObject *)self;
}
@@ -221,7 +235,8 @@ pyg_boxed_dealloc(PyGBoxed *self)
{
if (self->free_on_dealloc && self->boxed)
g_boxed_free(self->gtype, self->boxed);
- PyMem_DEL(self);
+
+ self->ob_type->tp_free((PyObject *)self);
}
static int
@@ -248,46 +263,13 @@ pyg_boxed_repr(PyGBoxed *self)
return PyString_FromString(buf);
}
-static PyObject *
-pyg_boxed_getattro(PyGBoxed *self, PyObject *attro)
-{
- char *attr;
- PyObject *ret;
-
- attr = PyString_AsString(attro);
-
- ret = Py_FindAttrString((PyObject *)self, attr);
- if (ret)
- return ret;
- PyErr_Clear();
-
- if (self->ob_type->tp_getattr)
- return (* self->ob_type->tp_getattr)((PyObject *)self, attr);
-
- PyErr_SetString(PyExc_AttributeError, attr);
- return NULL;
-}
-
-static PyObject *
-pyg_boxed__class_init__(PyObject *self, PyObject *args)
-{
- PyExtensionClass *subclass;
-
- if (!PyArg_ParseTuple(args, "O:GBoxed.__class_init__", &subclass))
- return NULL;
-
- g_message("subclassing GBoxed types is bad m'kay");
- PyErr_SetString(PyExc_TypeError, "attempt to subclass a boxed type");
- return NULL;
-}
-
-static PyObject *
-pyg_boxed_init(PyGBoxed *self, PyObject *args)
+static int
+pyg_boxed_init(PyGBoxed *self, PyObject *args, PyObject *kwargs)
{
gchar buf[512];
if (!PyArg_ParseTuple(args, ":GBoxed.__init__"))
- return NULL;
+ return -1;
self->boxed = NULL;
self->gtype = 0;
@@ -295,16 +277,10 @@ pyg_boxed_init(PyGBoxed *self, PyObject *args)
g_snprintf(buf, sizeof(buf), "%s can not be constructed", self->ob_type->tp_name);
PyErr_SetString(PyExc_NotImplementedError, buf);
- return NULL;
+ return -1;
}
-static PyMethodDef pyg_boxed_methods[] = {
- {"__class_init__",pyg_boxed__class_init__, METH_VARARGS|METH_CLASS_METHOD},
- {"__init__", (PyCFunction)pyg_boxed_init, METH_VARARGS},
- {NULL,NULL,0}
-};
-
-static PyExtensionClass PyGBoxed_Type = {
+static PyTypeObject PyGBoxed_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"GBoxed", /* tp_name */
@@ -323,43 +299,64 @@ static PyExtensionClass PyGBoxed_Type = {
(hashfunc)pyg_boxed_hash, /* tp_hash */
(ternaryfunc)0, /* tp_call */
(reprfunc)0, /* tp_str */
- (getattrofunc)pyg_boxed_getattro, /* tp_getattro */
+ (getattrofunc)0, /* tp_getattro */
(setattrofunc)0, /* tp_setattro */
- /* Space for future expansion */
- 0L, 0L,
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
NULL, /* Documentation string */
- METHOD_CHAIN(pyg_boxed_methods),
- 0,
+ (traverseproc)0, /* tp_traverse */
+ (inquiry)0, /* tp_clear */
+ (richcmpfunc)0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)0, /* tp_iter */
+ (iternextfunc)0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ (PyTypeObject *)0, /* tp_base */
+ (PyObject *)0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)pyg_boxed_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ object_free, /* tp_free */
+ (PyObject *)0, /* tp_bases */
};
static GHashTable *boxed_types = NULL;
static void
pyg_register_boxed(PyObject *dict, const gchar *class_name,
- GType boxed_type, PyExtensionClass *ec)
+ GType boxed_type, PyTypeObject *type)
{
PyObject *o;
g_return_if_fail(dict != NULL);
g_return_if_fail(class_name != NULL);
g_return_if_fail(boxed_type != 0);
- g_return_if_fail(ec != NULL);
if (!boxed_types)
boxed_types = g_hash_table_new(g_direct_hash, g_direct_equal);
- if (!ec->tp_dealloc) ec->tp_dealloc = (destructor)pyg_boxed_dealloc;
- if (!ec->tp_compare) ec->tp_compare = (cmpfunc)pyg_boxed_compare;
- if (!ec->tp_hash) ec->tp_hash = (hashfunc)pyg_boxed_hash;
- if (!ec->tp_repr) ec->tp_repr = (reprfunc)pyg_boxed_repr;
- if (!ec->tp_getattro) ec->tp_getattro = (getattrofunc)pyg_boxed_getattro;
+ if (!type->tp_dealloc) type->tp_dealloc = (destructor)pyg_boxed_dealloc;
- PyExtensionClass_ExportSubclassSingle(dict, (char *)class_name, *ec,
- PyGBoxed_Type);
- PyDict_SetItemString(ec->class_dictionary, "__gtype__",
+ type->ob_type = &PyType_Type;
+ type->tp_base = &PyGBoxed_Type;
+
+ if (PyType_Ready(type) < 0) {
+ g_warning("could not get type `%s' ready", type->tp_name);
+ return;
+ }
+
+ PyDict_SetItemString(type->tp_dict, "__gtype__",
o=pyg_type_wrapper_new(boxed_type));
+ PyDict_SetItemString(type->tp_defined, "__gtype__", o);
Py_DECREF(o);
- g_hash_table_insert(boxed_types, GUINT_TO_POINTER(boxed_type), ec);
+ g_hash_table_insert(boxed_types, GUINT_TO_POINTER(boxed_type), type);
+
+ PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
}
static PyObject *
@@ -641,8 +638,8 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
break;
case G_TYPE_OBJECT:
{
- PyExtensionClass *ec =pygobject_lookup_class(G_VALUE_TYPE(value));
- if (!ExtensionClassSubclassInstance_Check(obj, ec)) {
+ PyTypeObject *type =pygobject_lookup_class(G_VALUE_TYPE(value));
+ if (!PyObject_TypeCheck(obj, type)) {
return -1;
}
g_value_set_object(value, pygobject_get(obj));
@@ -670,7 +667,7 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT)) {
g_value_set_boxed(value, obj);
- } else if (ExtensionClassSubclassInstance_Check(obj, &PyGBoxed_Type) &&
+ } else if (PyObject_TypeCheck(obj, &PyGBoxed_Type) &&
G_VALUE_HOLDS(value, ((PyGBoxed *)obj)->gtype)) {
g_value_set_boxed(value, pyg_boxed_get(obj, gpointer));
} else if ((bm = pyg_boxed_lookup(G_VALUE_TYPE(value))) != NULL) {
@@ -955,89 +952,36 @@ pyg_signal_class_closure_get(void)
}
/* -------------- PyGObject behaviour ----------------- */
+
static void
pygobject_dealloc(PyGObject *self)
{
GObject *obj = self->obj;
- if (obj && !(((PyExtensionClass *)self->ob_type)->class_flags &
- EXTENSIONCLASS_PYSUBCLASS_FLAG)) {
- /* save reference to python wrapper if there are still
- * references to the GObject in such a way that it will be
- * freed when the GObject is destroyed, so is the python
- * wrapper, but if a python wrapper can be */
- if (obj->ref_count > 1) {
- Py_INCREF(self); /* grab a reference on the wrapper */
- self->hasref = TRUE;
- g_object_set_qdata_full(obj, pygobject_ownedref_key,
- self, pygobject_destroy_notify);
- g_object_unref(obj);
- return;
- }
- if (!self->hasref) /* don't unref the GObject if it owns us */
- g_object_unref(obj);
- }
- /* subclass_dealloc (ExtensionClass.c) does this for us for python
- * subclasses */
- if (self->inst_dict &&
- !(((PyExtensionClass *)self->ob_type)->class_flags &
- EXTENSIONCLASS_PYSUBCLASS_FLAG)) {
- Py_DECREF(self->inst_dict);
- }
- PyMem_DEL(self);
-}
-
-/* standard getattr method */
-static PyObject *
-check_bases(PyGObject *self, PyExtensionClass *class, char *attr)
-{
- PyObject *ret;
-
- if (class->tp_getattr) {
- ret = (* class->tp_getattr)((PyObject *)self, attr);
- if (ret)
- return ret;
- else
- PyErr_Clear();
+ /* save reference to python wrapper if there are still
+ * references to the GObject in such a way that it will be
+ * freed when the GObject is destroyed, so is the python
+ * wrapper, but if a python wrapper can be */
+ if (obj && obj->ref_count > 1) {
+ Py_INCREF(self); /* grab a reference on the wrapper */
+ self->hasref = TRUE;
+ g_object_set_qdata_full(obj, pygobject_ownedref_key,
+ self, pygobject_destroy_notify);
+ g_object_unref(obj);
+ return;
}
- if (PyExtensionClass_Check(class) && class->bases) {
- guint i, len = PyTuple_Size(class->bases);
+ if (obj && !self->hasref) /* don't unref the GObject if it owns us */
+ g_object_unref(obj);
- for (i = 0; i < len; i++) {
- PyExtensionClass *base = (PyExtensionClass *)PyTuple_GetItem(
- class->bases, i);
-
- ret = check_bases(self, base, attr);
- if (ret)
- return ret;
- }
- }
- return NULL;
-}
-static PyObject *
-pygobject_getattro(PyGObject *self, PyObject *attro)
-{
- char *attr;
- PyObject *ret;
+ PyObject_ClearWeakRefs((PyObject *)self);
- attr = PyString_AsString(attro);
+ PyObject_GC_UnTrack((PyObject *)self);
- ret = Py_FindAttrString((PyObject *)self, attr);
- if (ret)
- return ret;
- PyErr_Clear();
- ret = check_bases(self, (PyExtensionClass *)self->ob_type, attr);
- if (ret)
- return ret;
- PyErr_SetString(PyExc_AttributeError, attr);
- return NULL;
-}
+ if (self->inst_dict)
+ Py_DECREF(self->inst_dict);
+ self->inst_dict = NULL;
-static int
-pygobject_setattr(PyGObject *self, char *attr, PyObject *value)
-{
- PyDict_SetItemString(INSTANCE_DICT(self), attr, value);
- return 0;
+ self->ob_type->tp_free((PyObject *)self);
}
static int
@@ -1064,90 +1008,43 @@ pygobject_repr(PyGObject *self)
return PyString_FromString(buf);
}
-/* ---------------- PyGObject methods ----------------- */
-static destructor real_subclass_dealloc = NULL;
-static void
-pygobject_subclass_dealloc(PyGObject *self)
+static int
+pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
{
- GObject *obj = self->obj;
-
- if (obj) {
- /* save reference to python wrapper if there are still
- * references to the GObject in such a way that it will be
- * freed when the GObject is destroyed, so is the python
- * wrapper, but if a python wrapper can be */
- if (obj->ref_count > 1) {
- Py_INCREF(self); /* grab a reference on the wrapper */
- self->hasref = TRUE;
- g_object_set_qdata_full(obj, pygobject_ownedref_key,
- self, pygobject_destroy_notify);
- g_object_unref(obj);
- return;
- }
- if (!self->hasref) /* don't unref the GObject if it owns us */
- g_object_unref(obj);
- }
- if (real_subclass_dealloc)
- (* real_subclass_dealloc)((PyObject *)self);
+ if (self->inst_dict)
+ return visit(self->inst_dict, arg);
+ return 0;
}
-/* more hackery to stop segfaults caused by multi deallocs on a subclass
- * (which happens quite regularly in pygobject) */
-static PyObject *
-pygobject__class_init__(PyObject *something, PyObject *args)
-{
- PyExtensionClass *subclass;
- GTypeInfo type_info = {
- 0, /* class_size */
- (GBaseInitFunc) 0,
- (GBaseFinalizeFunc) 0,
- (GClassInitFunc) 0,
- (GClassFinalizeFunc) 0,
- NULL, /* class_data */
-
- 0, /* instance_size */
- 0, /* n_preallocs */
- (GInstanceInitFunc) 0
- };
-
- if (!PyArg_ParseTuple(args, "O:GObject.__class_init__", &subclass))
- return NULL;
- g_message("__class_init__ called for %s", subclass->tp_name);
-
- /* make sure ExtensionClass doesn't screw up our dealloc hack */
- if ((subclass->class_flags & EXTENSIONCLASS_PYSUBCLASS_FLAG) &&
- subclass->tp_dealloc != (destructor)pygobject_subclass_dealloc) {
- real_subclass_dealloc = subclass->tp_dealloc;
- subclass->tp_dealloc = (destructor)pygobject_subclass_dealloc;
- }
-
- /* put code in here to create a new GType for this subclass, using
- * __module__.__name__ as the name for the type. Then we can add
- * the code needed for adding signals to the subclass. The actual
- * implementation will have to wait for a g_type_query function */
-
- Py_INCREF(Py_None);
- return Py_None;
-}
+/* ---------------- PyGObject methods ----------------- */
-static PyObject *
-pygobject__init__(PyGObject *self, PyObject *args)
+static int
+pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
{
GType object_type;
if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
- return NULL;
+ return -1;
object_type = pyg_type_from_object((PyObject *)self);
if (!object_type)
- return NULL;
+ return -1;
self->obj = g_object_new(object_type, NULL);
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create object");
- return NULL;
+ return -1;
}
pygobject_register_wrapper((PyObject *)self);
+
+ return 0;
+}
+
+static PyObject *
+pygobject__gobject_init__(PyGObject *self, PyObject *args, PyObject *kwargs)
+{
+ if (pygobject_init(self, args, kwargs) < 0)
+ return NULL;
Py_INCREF(Py_None);
return Py_None;
}
@@ -1552,9 +1449,8 @@ pygobject_stop_emission(PyGObject *self, PyObject *args)
}
static PyMethodDef pygobject_methods[] = {
- { "__class_init__", (PyCFunction)pygobject__class_init__, METH_VARARGS|METH_CLASS_METHOD },
- { "__init__", (PyCFunction)pygobject__init__, METH_VARARGS },
- { "__gobject_init__", (PyCFunction)pygobject__init__, METH_VARARGS },
+ { "__gobject_init__", (PyCFunction)pygobject__gobject_init__,
+ METH_VARARGS|METH_KEYWORDS },
{ "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
{ "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
{ "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS },
@@ -1576,7 +1472,24 @@ static PyMethodDef pygobject_methods[] = {
{ NULL, NULL, 0 }
};
-static PyExtensionClass PyGObject_Type = {
+static PyObject *
+pygobject_get_dict(PyGObject *self, void *closure)
+{
+ if (self->inst_dict == NULL) {
+ self->inst_dict = PyDict_New();
+ if (self->inst_dict == NULL)
+ return NULL;
+ }
+ Py_INCREF(self->inst_dict);
+ return self->inst_dict;
+}
+
+static PyGetSetDef pygobject_getsets[] = {
+ { "__dict__", (getter)pygobject_get_dict, (setter)0 },
+ { NULL, 0, 0 }
+};
+
+static PyTypeObject PyGObject_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"GObject", /* tp_name */
@@ -1586,7 +1499,7 @@ static PyExtensionClass PyGObject_Type = {
(destructor)pygobject_dealloc, /* tp_dealloc */
(printfunc)0, /* tp_print */
(getattrfunc)0, /* tp_getattr */
- (setattrfunc)pygobject_setattr, /* tp_setattr */
+ (setattrfunc)0, /* tp_setattr */
(cmpfunc)pygobject_compare, /* tp_compare */
(reprfunc)pygobject_repr, /* tp_repr */
0, /* tp_as_number */
@@ -1597,53 +1510,51 @@ static PyExtensionClass PyGObject_Type = {
(reprfunc)0, /* tp_str */
(getattrofunc)0, /* tp_getattro */
(setattrofunc)0, /* tp_setattro */
- /* Space for future expansion */
- 0L, 0L,
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC, /* tp_flags */
NULL, /* Documentation string */
- METHOD_CHAIN(pygobject_methods),
- EXTENSIONCLASS_INSTDICT_FLAG,
+ (traverseproc)pygobject_traverse, /* tp_traverse */
+ (inquiry)0, /* tp_clear */
+ (richcmpfunc)0, /* tp_richcompare */
+ offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */
+ (getiterfunc)0, /* tp_iter */
+ (iternextfunc)0, /* tp_iternext */
+ pygobject_methods, /* tp_methods */
+ 0, /* tp_members */
+ pygobject_getsets, /* tp_getset */
+ (PyTypeObject *)0, /* tp_base */
+ (PyObject *)0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof(PyGObject, inst_dict), /* tp_dictoffset */
+ (initproc)pygobject_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ object_gc_free, /* tp_free */
+ (PyObject *)0, /* tp_bases */
};
/* ---------------- GInterface functions -------------------- */
-static PyObject *
-pyg_interface__class_init__(PyObject *self, PyObject *args)
-{
- PyExtensionClass *subclass;
-
- if (!PyArg_ParseTuple(args, "O:GInterface.__class_init__", &subclass))
- return NULL;
-
- g_message("subclassing GInterface types is bad m'kay");
- PyErr_SetString(PyExc_TypeError, "attempt to subclass an interface");
- return NULL;
-}
-
-static PyObject *
-pyg_interface_init(PyObject *self, PyObject *args)
+static int
+pyg_interface_init(PyObject *self, PyObject *args, PyObject *kwargs)
{
gchar buf[512];
if (!PyArg_ParseTuple(args, ":GInterface.__init__"))
- return NULL;
+ return -1;
g_snprintf(buf, sizeof(buf), "%s can not be constructed", self->ob_type->tp_name);
PyErr_SetString(PyExc_NotImplementedError, buf);
- return NULL;
+ return -1;
}
-static PyMethodDef pyg_interface_methods[] = {
- {"__class_init__", pyg_interface__class_init__,
- METH_VARARGS|METH_CLASS_METHOD},
- {"__init__", pyg_interface_init, METH_VARARGS},
- {NULL,NULL,0}
-};
-
-static PyExtensionClass PyGInterface_Type = {
+static PyTypeObject PyGInterface_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"GInterface", /* tp_name */
- sizeof(PyPureMixinObject), /* tp_basicsize */
+ sizeof(PyObject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)0, /* tp_dealloc */
@@ -1660,27 +1571,52 @@ static PyExtensionClass PyGInterface_Type = {
(reprfunc)0, /* tp_str */
(getattrofunc)0, /* tp_getattro */
(setattrofunc)0, /* tp_setattro */
- /* Space for future expansion */
- 0L, 0L,
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
NULL, /* Documentation string */
- METHOD_CHAIN(pyg_interface_methods),
- 0,
+ (traverseproc)0, /* tp_traverse */
+ (inquiry)0, /* tp_clear */
+ (richcmpfunc)0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)0, /* tp_iter */
+ (iternextfunc)0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ (PyTypeObject *)0, /* tp_base */
+ (PyObject *)0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)pyg_interface_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ object_free, /* tp_free */
+ (PyObject *)0, /* tp_bases */
};
static void
pyg_register_interface(PyObject *dict, const gchar *class_name,
- GType type, PyExtensionClass *ec)
+ GType gtype, PyTypeObject *type)
{
PyObject *o;
- PyExtensionClass_ExportSubclassSingle(dict, (char *)class_name,
- *ec, PyGInterface_Type);
+ type->ob_type = &PyType_Type;
+ type->tp_base = &PyGInterface_Type;
+
+ if (PyType_Ready(type) < 0) {
+ g_warning("could not ready `%s'", type->tp_name);
+ return;
+ }
- if (type) {
- o = pyg_type_wrapper_new(type);
- PyDict_SetItemString(ec->class_dictionary, "__gtype__", o);
+ if (gtype) {
+ o = pyg_type_wrapper_new(gtype);
+ PyDict_SetItemString(type->tp_dict, "__gtype__", o);
+ PyDict_SetItemString(type->tp_defined, "__gtype__", o);
Py_DECREF(o);
}
+
+ PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
}
@@ -1806,7 +1742,8 @@ pyg_type_interfaces (PyObject *self, PyObject *args)
static PyObject *
pyg_type_register(PyObject *self, PyObject *args)
{
- PyObject *class, *gtype, *module;
+ PyObject *gtype, *module;
+ PyTypeObject *class;
GType parent_type, instance_type;
gchar *type_name = NULL;
gint i;
@@ -1828,28 +1765,28 @@ pyg_type_register(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O:gobject.type_register", &class))
return NULL;
- if (!ExtensionClassSubclass_Check(class, &PyGObject_Type)) {
+ if (!PyType_IsSubtype(class, &PyGObject_Type)) {
PyErr_SetString(PyExc_TypeError,"argument must be a GObject subclass");
return NULL;
}
/* find the GType of the parent */
- parent_type = pyg_type_from_object(class);
+ parent_type = pyg_type_from_object((PyObject *)class);
if (!parent_type) {
return NULL;
}
/* make name for new widget */
- module = PyObject_GetAttrString(class, "__module__");
+ module = PyObject_GetAttrString((PyObject *)class, "__module__");
if (module && PyString_Check(module)) {
type_name = g_strconcat(PyString_AsString(module), ".",
- ((PyExtensionClass *)class)->tp_name, NULL);
+ class->tp_name, NULL);
} else {
if (module)
Py_DECREF(module);
else
PyErr_Clear();
- type_name = g_strdup(((PyExtensionClass *)class)->tp_name);
+ type_name = g_strdup(class->tp_name);
}
/* convert '.' in type name to '+', which isn't banned (grumble) */
for (i = 0; type_name[i] != '\0'; i++)
@@ -1872,7 +1809,8 @@ pyg_type_register(PyObject *self, PyObject *args)
/* set new value of __gtype__ on class */
gtype = pyg_type_wrapper_new(instance_type);
- PyObject_SetAttrString(class, "__gtype__", gtype);
+ PyDict_SetItemString(class->tp_dict, "__gtype__", gtype);
+ PyDict_SetItemString(class->tp_defined, "__gtype__", gtype);
Py_DECREF(gtype);
Py_INCREF(Py_None);
@@ -2159,14 +2097,22 @@ initgobject(void)
pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
&PyGObject_Type, NULL);
- PyExtensionClass_Export(d, "GInterface", PyGInterface_Type);
- PyDict_SetItemString(PyGInterface_Type.class_dictionary, "__gtype__",
+ PyGInterface_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&PyGInterface_Type))
+ return;
+ PyDict_SetItemString(d, "GInterface", (PyObject *)&PyGInterface_Type);
+ PyDict_SetItemString(PyGInterface_Type.tp_dict, "__gtype__",
o=pyg_type_wrapper_new(G_TYPE_INTERFACE));
+ PyDict_SetItemString(PyGInterface_Type.tp_defined, "__gtype__", o);
Py_DECREF(o);
- PyExtensionClass_Export(d, "GBoxed", PyGBoxed_Type);
- PyDict_SetItemString(PyGBoxed_Type.class_dictionary, "__gtype__",
+ PyGBoxed_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&PyGBoxed_Type))
+ return;
+ PyDict_SetItemString(d, "GBoxed", (PyObject *)&PyGBoxed_Type);
+ PyDict_SetItemString(PyGBoxed_Type.tp_dict, "__gtype__",
o=pyg_type_wrapper_new(G_TYPE_BOXED));
+ PyDict_SetItemString(PyGBoxed_Type.tp_defined, "__gtype__", o);
Py_DECREF(o);
boxed_marshalers = g_hash_table_new(g_direct_hash, g_direct_equal);
diff --git a/gtk/__init__.py b/gtk/__init__.py
index f8e2bc7d..dcb6b8f8 100644
--- a/gtk/__init__.py
+++ b/gtk/__init__.py
@@ -11,10 +11,6 @@ except ImportError:
FALSE = 0
TRUE = 1
-# hack so that ltihooks is used when importing ExtensionClass ...
-import ExtensionClass
-del ExtensionClass
-
import gobject
del gobject
diff --git a/gtk/gdk.override b/gtk/gdk.override
index 8d0d9955..45d67625 100644
--- a/gtk/gdk.override
+++ b/gtk/gdk.override
@@ -11,17 +11,17 @@ headers
#undef gdk_window_get_type
#define gdk_window_get_type gdk_window_object_get_type
-static PyExtensionClass *_PyGObject_Type;
+static PyTypeObject *_PyGObject_Type;
#define PyGObject_Type (*_PyGObject_Type)
-static PyExtensionClass *_PyPangoContext_Type;
+static PyTypeObject *_PyPangoContext_Type;
#define PyPangoContext_Type (*_PyPangoContext_Type)
-static PyExtensionClass *_PyPangoFont_Type;
+static PyTypeObject *_PyPangoFont_Type;
#define PyPangoFont_Type (*_PyPangoFont_Type)
-static PyExtensionClass *_PyPangoLayout_Type;
+static PyTypeObject *_PyPangoLayout_Type;
#define PyPangoLayout_Type (*_PyPangoLayout_Type)
-extern PyExtensionClass PyGtkWidget_Type;
+extern PyTypeObject PyGtkWidget_Type;
%%
init
@@ -32,8 +32,8 @@ init
if (pygobject != NULL) {
PyObject *module_dict = PyModule_GetDict(pygobject);
- _PyGObject_Type = (PyExtensionClass *)PyDict_GetItemString(module_dict,
- "GObject");
+ _PyGObject_Type = (PyTypeObject *)PyDict_GetItemString(module_dict,
+ "GObject");
} else {
Py_FatalError("could not import gobject");
return;
@@ -43,14 +43,11 @@ init
PyObject *module_dict = PyModule_GetDict(pypango);
_PyPangoContext_Type =
- (PyExtensionClass *)PyDict_GetItemString(module_dict,
- "Context");
+ (PyTypeObject *)PyDict_GetItemString(module_dict, "Context");
_PyPangoFont_Type =
- (PyExtensionClass *)PyDict_GetItemString(module_dict,
- "Font");
+ (PyTypeObject *)PyDict_GetItemString(module_dict, "Font");
_PyPangoLayout_Type =
- (PyExtensionClass *)PyDict_GetItemString(module_dict,
- "Layout");
+ (PyTypeObject *)PyDict_GetItemString(module_dict, "Layout");
} else {
Py_FatalError("could not import pango");
return;
@@ -515,7 +512,7 @@ _wrap_gdk_pixmap_colormap_create_from_xpm_d(PyObject *self, PyObject *args,
ignore gdk_cursor_new_from_pixmap
%%
override gdk_cursor_new kwargs
-static PyObject *
+static int
_wrap_gdk_cursor_new(PyGBoxed *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist1[] = { "cursor_type", NULL };
@@ -531,12 +528,12 @@ _wrap_gdk_cursor_new(PyGBoxed *self, PyObject *args, PyObject *kwargs)
if (pyg_enum_get_value(GDK_TYPE_CURSOR_TYPE, py_cursor_type,
(gint *)&cursor_type))
- return NULL;
+ return -1;
self->boxed = gdk_cursor_new(cursor_type);
if (!self->boxed) {
PyErr_SetString(PyExc_RuntimeError,
"could not create GdkCursor object");
- return NULL;
+ return -1;
}
self->free_on_dealloc = TRUE;
} else {
@@ -548,22 +545,22 @@ _wrap_gdk_cursor_new(PyGBoxed *self, PyObject *args, PyObject *kwargs)
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"OOOOii:GdkCursor.__init__", kwlist2,
&source, &mask, &fg, &bg, &x, &y))
- return NULL;
+ return -1;
if (!pygobject_check(source, &PyGdkPixmap_Type)) {
PyErr_SetString(PyExc_TypeError, "source should be a GdkPixmap");
- return NULL;
+ return -1;
}
if (!pygobject_check(mask, &PyGdkPixmap_Type)) {
PyErr_SetString(PyExc_TypeError, "mask should be a GdkPixmap");
- return NULL;
+ return -1;
}
if (!pyg_boxed_check(fg, GDK_TYPE_COLOR)) {
PyErr_SetString(PyExc_TypeError, "fg should be a GdkColor");
- return NULL;
+ return -1;
}
if (!pyg_boxed_check(bg, GDK_TYPE_COLOR)) {
PyErr_SetString(PyExc_TypeError, "bg should be a GdkColor");
- return NULL;
+ return -1;
}
self->boxed = gdk_cursor_new_from_pixmap(GDK_PIXMAP(source->obj),
GDK_PIXMAP(mask->obj),
@@ -573,12 +570,11 @@ _wrap_gdk_cursor_new(PyGBoxed *self, PyObject *args, PyObject *kwargs)
if (!self->boxed) {
PyErr_SetString(PyExc_RuntimeError,
"could not create GdkCursor object");
- return NULL;
+ return -1;
}
self->free_on_dealloc = TRUE;
}
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
override gdk_event_getattr
@@ -821,29 +817,37 @@ _wrap_gdk_event_getattr(PyObject *self, char *attr)
}
%%
override-attr GdkDevice.axes
-GdkDevice *device = GDK_DEVICE(self->obj);
-PyObject *ret;
-gint i;
+static PyObject *
+_wrap_gdk_device__get_axes(PyGObject *self, void *closure)
+{
+ GdkDevice *device = GDK_DEVICE(self->obj);
+ PyObject *ret;
+ gint i;
-ret = PyTuple_New(device->num_axes);
-for (i = 0; i < device->num_axes; i++)
- PyTuple_SetItem(ret, i, Py_BuildValue("(idd)",
- device->axes[i].use,
- device->axes[i].min,
- device->axes[i].max));
-return ret;
+ ret = PyTuple_New(device->num_axes);
+ for (i = 0; i < device->num_axes; i++)
+ PyTuple_SetItem(ret, i, Py_BuildValue("(idd)",
+ device->axes[i].use,
+ device->axes[i].min,
+ device->axes[i].max));
+ return ret;
+}
%%
override-attr GdkDevice.keys
-GdkDevice *device = GDK_DEVICE(self->obj);
-PyObject *ret;
-gint i;
+static PyObject *
+_wrap_gdk_device__get_keys(PyGObject *self, void *closure)
+{
+ GdkDevice *device = GDK_DEVICE(self->obj);
+ PyObject *ret;
+ gint i;
-ret = PyTuple_New(device->num_keys);
-for (i = 0; i < device->num_keys; i++)
- PyTuple_SetItem(ret, i, Py_BuildValue("(ii)",
- device->keys[i].keyval,
- device->keys[i].modifiers));
-return ret;
+ ret = PyTuple_New(device->num_keys);
+ for (i = 0; i < device->num_keys; i++)
+ PyTuple_SetItem(ret, i, Py_BuildValue("(ii)",
+ device->keys[i].keyval,
+ device->keys[i].modifiers));
+ return ret;
+}
%%
override gdk_device_get_state kwargs
static PyObject *
@@ -981,19 +985,23 @@ _wrap_gdk_drag_find_window(PyGObject *self, PyObject *args, PyObject *kwargs)
}
%%
override-attr GdkDragContext.targets
-PyObject *atom, *ret = PyList_New(0);
-GList *tmp;
-if (ret == NULL)
- return NULL;
-for (tmp = GDK_DRAG_CONTEXT(self->obj)->targets; tmp; tmp = tmp->next) {
- if ((atom = PyGdkAtom_New(GPOINTER_TO_INT(tmp->data))) == NULL) {
- Py_DECREF(ret);
+static PyObject *
+_wrap_gdk_drag_context__get_targets(PyGObject *self, void *closure)
+{
+ PyObject *atom, *ret = PyList_New(0);
+ GList *tmp;
+ if (ret == NULL)
return NULL;
+ for (tmp = GDK_DRAG_CONTEXT(self->obj)->targets; tmp; tmp = tmp->next) {
+ if ((atom = PyGdkAtom_New(GPOINTER_TO_INT(tmp->data))) == NULL) {
+ Py_DECREF(ret);
+ return NULL;
+ }
+ PyList_Append(ret, atom);
+ Py_DECREF(atom);
}
- PyList_Append(ret, atom);
- Py_DECREF(atom);
+ return ret;
}
-return ret;
%%
override gdk_gc_new_with_values kwargs
static PyObject *
diff --git a/gtk/gtk-types.c b/gtk/gtk-types.c
index ac28b5f5..d82635f3 100644
--- a/gtk/gtk-types.c
+++ b/gtk/gtk-types.c
@@ -3,9 +3,6 @@
#include "pygtk-private.h"
#include <structmember.h>
-/* these aren't ExtensionClass's */
-#undef Py_FindMethod
-
#if 0
PyObject *
PyGtkStyle_New(GtkStyle *obj)
@@ -1451,7 +1448,6 @@ _pygtk_register_boxed_types(PyObject *moddict)
PyDict_SetItemString(moddict, #x "Type", (PyObject *)&Py##x##_Type); \
pyg_register_boxed_custom(tp, Py##x##_from_value, Py##x##_to_value)
- ExtensionClassImported;
#if 0
register_tp(GtkStyle);
PyGtkStyleHelper_Type.ob_type = &PyType_Type;
diff --git a/gtk/gtk.override b/gtk/gtk.override
index 3e01b432..2c8a295c 100644
--- a/gtk/gtk.override
+++ b/gtk/gtk.override
@@ -8,25 +8,25 @@ headers
#include "pygtk-private.h"
#include "pygtktreemodel.h"
-static PyExtensionClass *_PyGObject_Type;
+static PyTypeObject *_PyGObject_Type;
#define PyGObject_Type (*_PyGObject_Type)
-static PyExtensionClass *_PyPangoContext_Type;
+static PyTypeObject *_PyPangoContext_Type;
#define PyPangoContext_Type (*_PyPangoContext_Type)
-static PyExtensionClass *_PyPangoFont_Type;
+static PyTypeObject *_PyPangoFont_Type;
#define PyPangoFont_Type (*_PyPangoFont_Type)
-static PyExtensionClass *_PyPangoLayout_Type;
+static PyTypeObject *_PyPangoLayout_Type;
#define PyPangoLayout_Type (*_PyPangoLayout_Type)
/* from the gdk portion ... */
-extern PyExtensionClass PyGdkColormap_Type;
-extern PyExtensionClass PyGdkGC_Type;
-extern PyExtensionClass PyGdkWindow_Type;
-extern PyExtensionClass PyGdkPixmap_Type;
-extern PyExtensionClass PyGdkImage_Type;
-extern PyExtensionClass PyGdkPixbuf_Type;
-extern PyExtensionClass PyGdkPixbufAnimation_Type;
-extern PyExtensionClass PyGdkDragContext_Type;
+extern PyTypeObject PyGdkColormap_Type;
+extern PyTypeObject PyGdkGC_Type;
+extern PyTypeObject PyGdkWindow_Type;
+extern PyTypeObject PyGdkPixmap_Type;
+extern PyTypeObject PyGdkImage_Type;
+extern PyTypeObject PyGdkPixbuf_Type;
+extern PyTypeObject PyGdkPixbufAnimation_Type;
+extern PyTypeObject PyGdkDragContext_Type;
%%
@@ -38,8 +38,8 @@ init
if (pygobject != NULL) {
PyObject *module_dict = PyModule_GetDict(pygobject);
- _PyGObject_Type = (PyExtensionClass *)PyDict_GetItemString(module_dict,
- "GObject");
+ _PyGObject_Type = (PyTypeObject *)PyDict_GetItemString(module_dict,
+ "GObject");
} else {
Py_FatalError("could not import gobject");
return;
@@ -49,14 +49,11 @@ init
PyObject *module_dict = PyModule_GetDict(pypango);
_PyPangoContext_Type =
- (PyExtensionClass *)PyDict_GetItemString(module_dict,
- "Context");
+ (PyTypeObject *)PyDict_GetItemString(module_dict, "Context");
_PyPangoFont_Type =
- (PyExtensionClass *)PyDict_GetItemString(module_dict,
- "Font");
+ (PyTypeObject *)PyDict_GetItemString(module_dict, "Font");
_PyPangoLayout_Type =
- (PyExtensionClass *)PyDict_GetItemString(module_dict,
- "Layout");
+ (PyTypeObject *)PyDict_GetItemString(module_dict, "Layout");
} else {
Py_FatalError("could not import pango");
return;
@@ -67,13 +64,17 @@ init
ignore gtk_selection_data_copy gtk_selection_data_free
%%
override-attr GtkSelectionData.data
-if (pyg_boxed_get(self, GtkSelectionData)->length >= 0) {
- return PyString_FromStringAndSize(
+static PyObject *
+_wrap_gtk_selection_data__get_data(PyGObject *self, void *closure)
+{
+ if (pyg_boxed_get(self, GtkSelectionData)->length >= 0) {
+ return PyString_FromStringAndSize(
pyg_boxed_get(self, GtkSelectionData)->data,
pyg_boxed_get(self, GtkSelectionData)->length);
-} else {
- Py_INCREF(Py_None);
- return Py_None;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
}
%%
override gtk_selection_data_set kwargs
@@ -337,7 +338,7 @@ _wrap_gtk_box_query_child_packing(PyGObject *self, PyObject *args,
ignore gtk_clist_new
%%
override gtk_clist_new_with_titles kwargs
-static PyObject *
+static int
_wrap_gtk_clist_new_with_titles(PyGObject *self, PyObject *args,
PyObject *kwargs)
{
@@ -347,17 +348,17 @@ _wrap_gtk_clist_new_with_titles(PyGObject *self, PyObject *args,
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:GtkCList.__init__",
kwlist, &count, &py_list))
- return NULL;
+ return -1;
if (py_list) {
gchar **list;
if (!PySequence_Check(py_list)) {
PyErr_SetString(PyExc_TypeError,"2nd argument not a sequence");
- return NULL;
+ return -1;
}
if (PySequence_Length(py_list) < count) {
PyErr_SetString(PyExc_TypeError, "sequence not long enough");
- return NULL;
+ return -1;
}
list = g_new(gchar *, count);
for (i = 0; i < count; i++) {
@@ -367,7 +368,7 @@ _wrap_gtk_clist_new_with_titles(PyGObject *self, PyObject *args,
if (!PyString_Check(item)) {
PyErr_SetString(PyExc_TypeError, "sequence item not a string");
g_free(list);
- return NULL;
+ return -1;
}
list[i] = PyString_AsString(item);
}
@@ -377,13 +378,12 @@ _wrap_gtk_clist_new_with_titles(PyGObject *self, PyObject *args,
self->obj = (GObject *)gtk_clist_new(count);
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError,"could not create GtkCList object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
override gtk_clist_get_text kwargs
@@ -637,28 +637,32 @@ _wrap_gtk_clist_get_selection_info(PyGObject *self, PyObject *args,
}
%%
override-attr GtkCList.selection
-guint row;
-GList *selection;
-PyObject *py_int, *ret = PyList_New(0);
+static PyObject *
+_wrap_gtk_clist__get_selection(PyGObject *self, void *closure)
+{
+ guint row;
+ GList *selection;
+ PyObject *py_int, *ret = PyList_New(0);
-if (ret == NULL)
- return NULL;
+ if (ret == NULL)
+ return NULL;
-for (selection = GTK_CLIST(self->obj)->selection; selection != NULL;
- selection = selection->next) {
- row = GPOINTER_TO_UINT(selection->data);
+ for (selection = GTK_CLIST(self->obj)->selection; selection != NULL;
+ selection = selection->next) {
+ row = GPOINTER_TO_UINT(selection->data);
- py_int = PyInt_FromLong(row);
+ py_int = PyInt_FromLong(row);
- if (!py_int) {
- Py_DECREF(ret);
- return NULL;
- }
+ if (!py_int) {
+ Py_DECREF(ret);
+ return NULL;
+ }
- PyList_Append(ret, py_int);
- Py_DECREF(py_int);
+ PyList_Append(ret, py_int);
+ Py_DECREF(py_int);
+ }
+ return ret;
}
-return ret;
%%
override gtk_combo_set_popdown_strings kwargs
static PyObject *
@@ -1179,7 +1183,7 @@ ignore
gtk_tree_view_column_new_with_attributes
%%
override gtk_tree_view_column_new kwargs
-static PyObject *
+static int
_wrap_gtk_tree_view_column_new(PyGObject *self, PyObject*args, PyObject*kwargs)
{
PyObject *py_cell = NULL, *key, *item;
@@ -1190,14 +1194,14 @@ _wrap_gtk_tree_view_column_new(PyGObject *self, PyObject*args, PyObject*kwargs)
if (!PyArg_ParseTuple(args, "|zO:GtkTreeViewColumn.__init__", &title,
&py_cell))
- return NULL;
+ return -1;
if (py_cell != NULL) {
if (pygobject_check(py_cell, &PyGtkCellRenderer_Type))
cell = GTK_CELL_RENDERER(pygobject_get(py_cell));
else if (py_cell != Py_None) {
PyErr_SetString(PyExc_TypeError,
"cell must be a GtkCellRenderer or None");
- return NULL;
+ return -1;
}
}
tvc = gtk_tree_view_column_new();
@@ -1215,7 +1219,7 @@ _wrap_gtk_tree_view_column_new(PyGObject *self, PyObject*args, PyObject*kwargs)
"%s must be an integer column number", attr);
PyErr_SetString(PyExc_TypeError, err);
g_object_unref(G_OBJECT(tvc));
- return NULL;
+ return -1;
}
gtk_tree_view_column_add_attribute(tvc, cell, attr,
PyInt_AsLong(item));
@@ -1225,8 +1229,7 @@ _wrap_gtk_tree_view_column_new(PyGObject *self, PyObject*args, PyObject*kwargs)
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
override gtk_tree_view_get_path_at_pos kwargs
@@ -1887,7 +1890,7 @@ _wrap_gtk_pixmap_get(PyGObject *self, PyObject *args)
ignore gtk_button_new_with_label gtk_button_new_from_stock gtk_button_new_with_mnemonic
%%
override gtk_button_new kwargs
-static PyObject *
+static int
_wrap_gtk_button_new(PyGObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "label", "stock", NULL };
@@ -1895,7 +1898,7 @@ _wrap_gtk_button_new(PyGObject *self, PyObject *args, PyObject *kwargs)
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zz:GtkButton.__init__",
kwlist, &text, &stock))
- return NULL;
+ return -1;
if (stock)
self->obj = (GObject *)gtk_button_new_from_stock(stock);
else if (text)
@@ -1904,19 +1907,18 @@ _wrap_gtk_button_new(PyGObject *self, PyObject *args, PyObject *kwargs)
self->obj = (GObject *)gtk_button_new();
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create GtkButton object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
ignore gtk_toggle_button_new_with_label gtk_toggle_button_new_with_mnemonic
%%
override gtk_toggle_button_new kwargs
-static PyObject *
+static int
_wrap_gtk_toggle_button_new(PyGObject *self, PyObject*args, PyObject*kwargs)
{
static char *kwlist[] = { "label", NULL };
@@ -1925,26 +1927,25 @@ _wrap_gtk_toggle_button_new(PyGObject *self, PyObject*args, PyObject*kwargs)
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|z:GtkToggleButton.__init__", kwlist,
&text))
- return NULL;
+ return -1;
if (text)
self->obj = (GObject *)gtk_toggle_button_new_with_mnemonic(text);
else
self->obj = (GObject *)gtk_toggle_button_new();
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create GtkToggleButton object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
ignore gtk_check_button_new_with_label gtk_check_button_new_with_mnemonic
%%
override gtk_check_button_new kwargs
-static PyObject *
+static int
_wrap_gtk_check_button_new(PyGObject *self, PyObject *args, PyObject*kwargs)
{
static char *kwlist[] = { "label", NULL };
@@ -1952,26 +1953,25 @@ _wrap_gtk_check_button_new(PyGObject *self, PyObject *args, PyObject*kwargs)
if (!PyArg_ParseTupleAndKeywords(args, kwargs,"|z:GtkCheckButton.__init__",
kwlist, &text))
- return NULL;
+ return -1;
if (text)
self->obj = (GObject *)gtk_check_button_new_with_mnemonic(text);
else
self->obj = (GObject *)gtk_check_button_new();
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create GtkCheckButton object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
ignore-glob gtk_radio_button_new_*
%%
override gtk_radio_button_new kwargs
-static PyObject *
+static int
_wrap_gtk_radio_button_new(PyGObject *self, PyObject *args, PyObject*kwargs)
{
static char *kwlist[] = { "group", "label", NULL };
@@ -1981,7 +1981,7 @@ _wrap_gtk_radio_button_new(PyGObject *self, PyObject *args, PyObject*kwargs)
if (!PyArg_ParseTupleAndKeywords(args,kwargs,"|Oz:GtkRadioButton.__init__",
kwlist, &py_group, &label))
- return NULL;
+ return -1;
if (py_group == Py_None)
group = NULL;
else if (pygobject_check(py_group, &PyGtkRadioButton_Type))
@@ -1989,7 +1989,7 @@ _wrap_gtk_radio_button_new(PyGObject *self, PyObject *args, PyObject*kwargs)
else {
PyErr_SetString(PyExc_TypeError,
"first argument must be a GtkRadioButton or None");
- return NULL;
+ return -1;
}
/* various configs for create radio buttons ... */
if (label == NULL) {
@@ -2006,19 +2006,18 @@ _wrap_gtk_radio_button_new(PyGObject *self, PyObject *args, PyObject*kwargs)
}
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create GtkRadioButton object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
ignore gtk_list_item_new_with_label
%%
override gtk_list_item_new kwargs
-static PyObject *
+static int
_wrap_gtk_list_item_new(PyGObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "label", NULL };
@@ -2026,26 +2025,25 @@ _wrap_gtk_list_item_new(PyGObject *self, PyObject *args, PyObject *kwargs)
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|z:GtkListItem.__init__",
kwlist, &text))
- return NULL;
+ return -1;
if (text)
self->obj = (GObject *)gtk_list_item_new_with_label(text);
else
self->obj = (GObject *)gtk_list_item_new();
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create GtkListItem object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
ignore gtk_menu_item_new_with_label gtk_menu_item_new_with_mnemonic
%%
override gtk_menu_item_new kwargs
-static PyObject *
+static int
_wrap_gtk_menu_item_new(PyGObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "label", NULL };
@@ -2053,26 +2051,25 @@ _wrap_gtk_menu_item_new(PyGObject *self, PyObject *args, PyObject *kwargs)
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|z:GtkMenuItem.__init__",
kwlist, &text))
- return NULL;
+ return -1;
if (text)
self->obj = (GObject *)gtk_menu_item_new_with_mnemonic(text);
else
self->obj = (GObject *)gtk_menu_item_new();
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create GtkMenuItem object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
ignore gtk_check_menu_item_new_with_label gtk_check_menu_item_new_with_mnemonic
%%
override gtk_check_menu_item_new kwargs
-static PyObject *
+static int
_wrap_gtk_check_menu_item_new(PyGObject *self, PyObject *args,
PyObject *kwargs)
{
@@ -2082,26 +2079,25 @@ _wrap_gtk_check_menu_item_new(PyGObject *self, PyObject *args,
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|z:GtkCheckMenuItem.__init__", kwlist,
&text))
- return NULL;
+ return -1;
if (text)
self->obj = (GObject *)gtk_check_menu_item_new_with_mnemonic(text);
else
self->obj = (GObject *)gtk_check_menu_item_new();
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create GtkCheckMenuItem object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
ignore gtk_radio_menu_item_new_with_label gtk_radio_menu_item_new_with_mnemonic
%%
override gtk_radio_menu_item_new kwargs
-static PyObject *
+static int
_wrap_gtk_radio_menu_item_new(PyGObject *self, PyObject *args,
PyObject *kwargs)
{
@@ -2113,7 +2109,7 @@ _wrap_gtk_radio_menu_item_new(PyGObject *self, PyObject *args,
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|Oz:GtkRadioMenuItem.__init__", kwlist,
&py_group, &text))
- return NULL;
+ return -1;
if (py_group == Py_None)
group = NULL;
else if (pygobject_check(py_group, &PyGtkRadioMenuItem_Type))
@@ -2121,7 +2117,7 @@ _wrap_gtk_radio_menu_item_new(PyGObject *self, PyObject *args,
else {
PyErr_SetString(PyExc_TypeError,
"first argument must be a GtkRadioMenuItem or None");
- return NULL;
+ return -1;
}
/* various configs for create radio buttons ... */
if (text == NULL) {
@@ -2139,13 +2135,12 @@ _wrap_gtk_radio_menu_item_new(PyGObject *self, PyObject *args,
}
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create GtkRadioMenuItem object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
ignore gtk_ctree_construct
@@ -2160,26 +2155,30 @@ ignore gtk_ctree_construct
ignore gtk_ctree_new
%%
override-attr GtkCTree.selection
-GList *selection;
-GtkCTreeNode *node;
-PyObject *ret, *py_node;
-if ((ret = PyList_New(0)) == NULL)
- return NULL;
+static PyObject *
+_wrap_gtk_ctree__get_selection(PyGObject *self, void *closure)
+{
+ GList *selection;
+ GtkCTreeNode *node;
+ PyObject *ret, *py_node;
+ if ((ret = PyList_New(0)) == NULL)
+ return NULL;
-for (selection = GTK_CLIST(self->obj)->selection; selection != NULL;
- selection = selection->next) {
- node = selection->data;
- if ((py_node = pyg_boxed_new(GTK_TYPE_CTREE_NODE, node, TRUE, TRUE)) == NULL) {
- Py_DECREF(ret);
- return NULL;
+ for (selection = GTK_CLIST(self->obj)->selection; selection != NULL;
+ selection = selection->next) {
+ node = selection->data;
+ if ((py_node = pyg_boxed_new(GTK_TYPE_CTREE_NODE, node, TRUE, TRUE)) == NULL) {
+ Py_DECREF(ret);
+ return NULL;
+ }
+ PyList_Append(ret, py_node);
+ Py_DECREF(py_node);
}
- PyList_Append(ret, py_node);
- Py_DECREF(py_node);
+ return ret;
}
-return ret;
%%
override gtk_ctree_new_with_titles kwargs
-static PyObject*
+static int
_wrap_gtk_ctree_new_with_titles(PyGObject *self, PyObject *args,
PyObject *kwargs)
{
@@ -2190,18 +2189,18 @@ _wrap_gtk_ctree_new_with_titles(PyGObject *self, PyObject *args,
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiO:GtkCTree.__init__",
kwlist, &columns, &tree_column,
&py_titles))
- return NULL;
+ return -1;
if (py_titles) {
gchar **titles;
gint i;
if (!PySequence_Check(py_titles)) {
PyErr_SetString(PyExc_TypeError, "titles must be a sequence");
- return NULL;
+ return -1;
}
if (PySequence_Length(py_titles) < columns) {
PyErr_SetString(PyExc_TypeError, "titles too short");
- return NULL;
+ return -1;
}
titles = g_new(gchar *, columns);
for (i = 0; i < columns; i++) {
@@ -2211,7 +2210,7 @@ _wrap_gtk_ctree_new_with_titles(PyGObject *self, PyObject *args,
if (!PyString_Check(item)) {
PyErr_SetString(PyExc_TypeError, "sequence item not a string");
g_free(titles);
- return NULL;
+ return -1;
}
titles[i] = PyString_AsString(item);
}
@@ -2222,13 +2221,12 @@ _wrap_gtk_ctree_new_with_titles(PyGObject *self, PyObject *args,
self->obj = (GObject *)gtk_ctree_new(columns, tree_column);
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError,"could not create GtkCTree object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
override gtk_ctree_base_nodes
@@ -3686,7 +3684,7 @@ _wrap_gtk_text_buffer_get_iter_at_mark(PyGObject *self, PyObject *args, PyObject
ignore gtk_dialog_new
%%
override gtk_dialog_new_with_buttons kwargs
-static PyObject *
+static int
_wrap_gtk_dialog_new_with_buttons(PyGObject *self, PyObject *args, PyObject *kwargs)
{
gchar *title = NULL;
@@ -3701,12 +3699,12 @@ _wrap_gtk_dialog_new_with_buttons(PyGObject *self, PyObject *args, PyObject *kwa
"|sOdO!:GtkDialog.__init__", kwlist,
&title, &py_window, &flags,
&PyTuple_Type, &py_buttons))
- return NULL;
+ return -1;
if (py_window != NULL && py_window != (PyGObject *) Py_None
&& !pygobject_check(py_window, &PyGtkWindow_Type)) {
PyErr_SetString(PyExc_TypeError, "window must be a GtkWindow or None");
- return NULL;
+ return -1;
}
if (py_buttons != Py_None)
@@ -3716,7 +3714,7 @@ _wrap_gtk_dialog_new_with_buttons(PyGObject *self, PyObject *args, PyObject *kwa
if (len % 2) {
PyErr_SetString(PyExc_RuntimeError, "buttons tuple must contain text/response id pairs");
- return NULL;
+ return -1;
}
self->obj = (GObject *)
@@ -3726,7 +3724,7 @@ _wrap_gtk_dialog_new_with_buttons(PyGObject *self, PyObject *args, PyObject *kwa
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create GtkDialog object");
- return NULL;
+ return -1;
}
for (i = 0; i < len; i += 2) {
@@ -3736,13 +3734,13 @@ _wrap_gtk_dialog_new_with_buttons(PyGObject *self, PyObject *args, PyObject *kwa
gtk_object_destroy(GTK_OBJECT(self->obj));
self->obj = NULL;
PyErr_SetString(PyExc_RuntimeError, "first member of each text/response id pair must be a string");
- return NULL;
+ return -1;
}
if (!PyInt_Check(id)) {
gtk_object_destroy(GTK_OBJECT(self->obj));
self->obj = NULL;
PyErr_SetString(PyExc_RuntimeError, "second member of each text/response id pair must be a number");
- return NULL;
+ return -1;
}
gtk_dialog_add_button(GTK_DIALOG(self->obj), PyString_AsString(text),
PyInt_AsLong(id));
@@ -3751,12 +3749,11 @@ _wrap_gtk_dialog_new_with_buttons(PyGObject *self, PyObject *args, PyObject *kwa
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
override gtk_message_dialog_new kwargs
-static PyObject *
+static int
_wrap_gtk_message_dialog_new(PyGObject *self, PyObject *args, PyObject *kwargs)
{
GtkButtonsType buttons = GTK_BUTTONS_NONE;
@@ -3769,32 +3766,31 @@ _wrap_gtk_message_dialog_new(PyGObject *self, PyObject *args, PyObject *kwargs)
char *message_format = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOOz:GtkMessageDialog.__init__", kwlist, &py_parent, &py_flags, &py_type, &py_buttons, &message_format))
- return NULL;
+ return -1;
if ((PyObject *)py_parent == Py_None)
parent = NULL;
else if (py_parent && pygobject_check(py_parent, &PyGtkWindow_Type))
parent = GTK_WINDOW(py_parent->obj);
else if (py_parent) {
PyErr_SetString(PyExc_TypeError, "parent should be a GtkWindow or None");
- return NULL;
+ return -1;
}
if (pyg_enum_get_value(GTK_TYPE_DIALOG_FLAGS, py_flags, (gint *)&flags))
- return NULL;
+ return -1;
if (pyg_enum_get_value(GTK_TYPE_MESSAGE_TYPE, py_type, (gint *)&type))
- return NULL;
+ return -1;
if (pyg_enum_get_value(GTK_TYPE_BUTTONS_TYPE, py_buttons, (gint *)&buttons))
- return NULL;
+ return -1;
self->obj = (GObject *)gtk_message_dialog_new(parent, flags, type, buttons, "%s", message_format);
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create GtkMessageDialog object");
- return NULL;
+ return -1;
}
gtk_object_ref(GTK_OBJECT(self->obj));
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
%%
ignore gtk_progress_bar_new
diff --git a/gtk/libglade.override b/gtk/libglade.override
index 14bd1752..39442025 100644
--- a/gtk/libglade.override
+++ b/gtk/libglade.override
@@ -4,9 +4,9 @@ headers
#include <pygobject.h>
#include <glade/glade.h>
-static PyExtensionClass *_PyGObject_Type;
+static PyTypeObject *_PyGObject_Type;
#define PyGObject_Type (*_PyGObject_Type)
-static PyExtensionClass *_PyGtkWidget_Type;
+static PyTypeObject *_PyGtkWidget_Type;
#define PyGtkWidget_Type (*_PyGtkWidget_Type)
%%
init
@@ -16,7 +16,7 @@ init
if ((module = PyImport_ImportModule("gobject")) != NULL) {
PyObject *module_dict = PyModule_GetDict(module);
- _PyGObject_Type = (PyExtensionClass *)
+ _PyGObject_Type = (PyTypeObject *)
PyDict_GetItemString(module_dict, "GObject");
} else {
Py_FatalError("could not import gobject");
@@ -25,7 +25,7 @@ init
if ((module = PyImport_ImportModule("gtk._gtk")) != NULL) {
PyObject *module_dict = PyModule_GetDict(module);
- _PyGtkWidget_Type = (PyExtensionClass *)
+ _PyGtkWidget_Type = (PyTypeObject *)
PyDict_GetItemString(module_dict, "Widget");
} else {
Py_FatalError("could not import gtk._gtk");
diff --git a/gtk/libglademodule.c b/gtk/libglademodule.c
index 3943c6f1..47679a28 100644
--- a/gtk/libglademodule.c
+++ b/gtk/libglademodule.c
@@ -8,7 +8,6 @@
void pylibglade_register_classes(PyObject *d);
extern PyMethodDef pylibglade_functions[];
-extern PyExtensionClass PyGladeXML_Type;
DL_EXPORT(void)
initglade(void)
diff --git a/gtk/pygtk.h b/gtk/pygtk.h
index f46949f0..a0daa650 100644
--- a/gtk/pygtk.h
+++ b/gtk/pygtk.h
@@ -5,7 +5,6 @@
#define NO_IMPORT_PYGOBJECT
#include <pygobject.h>
#include <Python.h>
-#include <ExtensionClass.h>
#include <gtk/gtk.h>
struct _PyGtk_FunctionStruct {
@@ -78,7 +77,6 @@ struct _PyGtk_FunctionStruct *_PyGtk_API;
Py_FatalError("could not import _gtk"); \
return; \
} \
- ExtensionClassImported; \
}
#endif
diff --git a/gtk/pygtktreemodel.c b/gtk/pygtktreemodel.c
index 91dfdc74..92b7dd0f 100644
--- a/gtk/pygtktreemodel.c
+++ b/gtk/pygtktreemodel.c
@@ -188,7 +188,7 @@ pygtk_tree_model_get_column_type(GtkTreeModel *tree_model, gint index)
py_ret = PyObject_CallMethod(self, METHOD_PREFIX "get_column_type",
"(i)", index);
if (py_ret) {
- GType ret = PyInt_AsLong(py_ret);
+ GType ret = pyg_type_from_object(py_ret);
Py_DECREF(py_ret);
return ret;
diff --git a/pango.override b/pango.override
index 5ed77ee4..c3c0636d 100644
--- a/pango.override
+++ b/pango.override
@@ -5,7 +5,7 @@ headers
#include <pygobject.h>
#include <pango/pango.h>
-static PyExtensionClass *_PyGObject_Type;
+static PyTypeObject *_PyGObject_Type;
#define PyGObject_Type (*_PyGObject_Type)
%%
@@ -16,8 +16,8 @@ init
if (pygobject != NULL) {
PyObject *module_dict = PyModule_GetDict(pygobject);
- _PyGObject_Type = (PyExtensionClass *)PyDict_GetItemString(module_dict,
- "GObject");
+ _PyGObject_Type = (PyTypeObject *)PyDict_GetItemString(module_dict,
+ "GObject");
} else {
Py_FatalError("could not import gobject");
return;
@@ -49,7 +49,7 @@ ignore
ignore pango_font_description_from_string
%%
override pango_font_description_new kwargs
-static PyObject *
+static int
_wrap_pango_font_description_new(PyGBoxed *self, PyObject *args,
PyObject *kwargs)
{
@@ -59,7 +59,7 @@ _wrap_pango_font_description_new(PyGBoxed *self, PyObject *args,
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|z:PangoFontDescription.__init__",
kwlist, &str))
- return NULL;
+ return -1;
self->gtype = PANGO_TYPE_FONT_DESCRIPTION;
self->free_on_dealloc = FALSE;
@@ -70,9 +70,8 @@ _wrap_pango_font_description_new(PyGBoxed *self, PyObject *args,
if (!self->boxed) {
PyErr_SetString(PyExc_RuntimeError,
"could not create PangoFontDescription object");
- return NULL;
+ return -1;
}
self->free_on_dealloc = TRUE;
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
diff --git a/pygobject.h b/pygobject.h
index 2b031a13..4be17b9a 100644
--- a/pygobject.h
+++ b/pygobject.h
@@ -3,7 +3,6 @@
#define _PYGOBJECT_H_
#include <Python.h>
-#include <ExtensionClass.h>
#include <glib.h>
#include <glib-object.h>
@@ -13,10 +12,11 @@ typedef struct {
GObject *obj;
gboolean hasref; /* the GObject owns this reference */
PyObject *inst_dict; /* the instance dictionary -- must be last */
+ PyObject *weakreflist; /* list of weak references */
} PyGObject;
#define pygobject_get(v) (((PyGObject *)(v))->obj)
-#define pygobject_check(v,base) (ExtensionClassSubclassInstance_Check(v,base))
+#define pygobject_check(v,base) (PyObject_TypeCheck(v,base))
typedef struct {
PyObject_HEAD
@@ -26,13 +26,13 @@ typedef struct {
} PyGBoxed;
#define pyg_boxed_get(v,t) ((t *)((PyGBoxed *)(v))->boxed)
-#define pyg_boxed_check(v,typecode) (ExtensionClassSubclassInstance_Check(v, &PyGBoxed_Type) && ((PyGBoxed *)(v))->gtype == typecode)
+#define pyg_boxed_check(v,typecode) (PyObject_TypeCheck(v, &PyGBoxed_Type) && ((PyGBoxed *)(v))->gtype == typecode)
struct _PyGObject_Functions {
void (* register_class)(PyObject *dict, const gchar *class_name,
- GType type, PyExtensionClass *ec, PyObject *bases);
+ GType gtype, PyTypeObject *type, PyObject *bases);
void (* register_wrapper)(PyObject *self);
- PyExtensionClass *(* lookup_class)(GType type);
+ PyTypeObject *(* lookup_class)(GType type);
PyObject *(* newgobj)(GObject *obj);
GClosure *(* closure_new)(PyObject *callback, PyObject *extra_args,
PyObject *swap_data);
@@ -49,11 +49,11 @@ struct _PyGObject_Functions {
PyObject *(* value_as_pyobject)(const GValue *value);
void (* register_interface)(PyObject *dict, const gchar *class_name,
- GType type, PyExtensionClass *ec);
+ GType gtype, PyTypeObject *type);
- PyExtensionClass *boxed_type;
+ PyTypeObject *boxed_type;
void (* register_boxed)(PyObject *dict, const gchar *class_name,
- GType boxed_type, PyExtensionClass *ec);
+ GType boxed_type, PyTypeObject *type);
PyObject *(* boxed_new)(GType boxed_type, gpointer boxed,
gboolean copy_boxed, gboolean own_ref);
@@ -105,7 +105,6 @@ struct _PyGObject_Functions *_PyGObject_API;
Py_FatalError("could not import gobject"); \
return; \
} \
- ExtensionClassImported; \
}
#endif /* !_INSIDE_PYGOBJECT_ */