Here is a proposed diff file.
Note that this change doesn't actually change the object layout, it merely
changes the header definition of PyHeapTypeObject.
Thinking about the problem, I don't see that there is a binary incompatibility
between stackless and objects built against vanilla python27. The extra
"slpflags" is always at the end, and in the case of PyTypeObject padded so far
that tthis type has the same size as PyHeapTypeObject. It is only present if
the "stackless" flag is present in the type.
So, I think that PyQT and PySide, if compiled against vanilla python, would
work against stackelss. This proposed change makes the convenient change that
these extensions can be compiled against stackless headers as well, if need be.
K
________________________________________
Frá: [email protected] [[email protected]] fyrir
hönd Kristján Valur Jónsson [[email protected]]
Sent: 5. apríl 2012 22:01
To: The Stackless Python Mailing List
Efni: Re: [Stackless]
http://www.stackless.com/pipermail/stackless/2007-April/000142.html
Ah, and PySide has the same problem as PyQT since wrt. PyHeapTypeObject....
K
________________________________________
Frá: [email protected] [[email protected]] fyrir
hönd Richard Tew [[email protected]]
Sent: 4. apríl 2012 19:53
To: The Stackless Python Mailing List
Efni: Re: [Stackless]
http://www.stackless.com/pipermail/stackless/2007-April/000142.html
On Wed, Apr 4, 2012 at 9:28 PM, Kristján Valur Jónsson
<[email protected]> wrote:
> I wonder,
>
> Why does stackless redefine PyHeapTypeObject?
>
> Is there any reason to? Can we fix that so that compatibility with stuff
> such as PyQT is maintained?
Yes, this has been a long time known problem. We extend the object
structure with Stackless-specific fields, and so does SIP which is
what PyQT uses for its bindings. However, the number of complaints
about this since Christian and I last discussed it number exactly zero
:-)
If PyQT is the only problem, then I am not sure we need to fix it.
Other problems with PyQT which I am not familiar with have
precipitated the development of PySide. PySide, as I understand it,
can be interchanged with PyQT with minor changes.
It might be sufficient to encourage people to switch to PySide.
Of course, if you can see a way to easily remove the redefinition, we
should probably look at doing that anyway.
Cheers,
Richard.
_______________________________________________
Stackless mailing list
[email protected]
http://www.stackless.com/mailman/listinfo/stackless
_______________________________________________
Stackless mailing list
[email protected]
http://www.stackless.com/mailman/listinfo/stackless
diff --git a/Include/object.h b/Include/object.h
--- a/Include/object.h
+++ b/Include/object.h
@@ -413,7 +413,11 @@
struct _typeobject *tp_next;
#endif
#ifdef STACKLESS
- /* we need the extended structure right here */
+ /* we need this stuff from PyHeapTypeObject
+ * here in PyTypeObject so that the offset of
+ * the slpflags from the start is the same for PyTypeObject
+ * and PyHeapTypeObject
+ */
PyNumberMethods as_number;
PyMappingMethods as_mapping;
PySequenceMethods as_sequence; /* as_sequence comes after as_mapping,
@@ -423,25 +427,112 @@
see add_operators() in typeobject.c . */
PyBufferProcs as_buffer;
PyObject *ht_name, *ht_slots;
+ /* add this at the end, for binary compatibility */
slp_methodflags slpflags;
#endif
} PyTypeObject;
+#ifdef STACKLESS
+/* need the un-extended type here to be part of the PyHeapTypeObject */
+typedef struct _basetypeobject {
+ PyObject_VAR_HEAD
+ const char *tp_name; /* For printing, in format "<module>.<name>" */
+ Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
-#ifdef STACKLESS
+ /* Methods to implement standard operations */
-/* in Stackless, this is just a synonym */
-#define PyHeapTypeObject PyTypeObject
+ destructor tp_dealloc;
+ printfunc tp_print;
+ getattrfunc tp_getattr;
+ setattrfunc tp_setattr;
+ cmpfunc tp_compare;
+ reprfunc tp_repr;
-#define PyHeapType_GET_MEMBERS(etype) \
- ((PyMemberDef *)(((char *)etype) + (etype)->ob_type->tp_basicsize))
-#else
+ /* Method suites for standard classes */
+
+ PyNumberMethods *tp_as_number;
+ PySequenceMethods *tp_as_sequence;
+ PyMappingMethods *tp_as_mapping;
+
+ /* More standard operations (here for binary compatibility) */
+
+ hashfunc tp_hash;
+ ternaryfunc tp_call;
+ reprfunc tp_str;
+ getattrofunc tp_getattro;
+ setattrofunc tp_setattro;
+
+ /* Functions to access object as input/output buffer */
+ PyBufferProcs *tp_as_buffer;
+
+ /* Flags to define presence of optional/expanded features */
+ long tp_flags;
+
+ const char *tp_doc; /* Documentation string */
+
+ /* Assigned meaning in release 2.0 */
+ /* call function for all accessible objects */
+ traverseproc tp_traverse;
+
+ /* delete references to contained objects */
+ inquiry tp_clear;
+
+ /* Assigned meaning in release 2.1 */
+ /* rich comparisons */
+ richcmpfunc tp_richcompare;
+
+ /* weak reference enabler */
+ Py_ssize_t tp_weaklistoffset;
+
+ /* Added in release 2.2 */
+ /* Iterators */
+ getiterfunc tp_iter;
+ iternextfunc tp_iternext;
+
+ /* Attribute descriptor and subclassing stuff */
+ struct PyMethodDef *tp_methods;
+ struct PyMemberDef *tp_members;
+ struct PyGetSetDef *tp_getset;
+ struct _typeobject *tp_base;
+ PyObject *tp_dict;
+ descrgetfunc tp_descr_get;
+ descrsetfunc tp_descr_set;
+ Py_ssize_t tp_dictoffset;
+ initproc tp_init;
+ allocfunc tp_alloc;
+ newfunc tp_new;
+ freefunc tp_free; /* Low-level free-memory routine */
+ inquiry tp_is_gc; /* For PyObject_IS_GC */
+ PyObject *tp_bases;
+ PyObject *tp_mro; /* method resolution order */
+ PyObject *tp_cache;
+ PyObject *tp_subclasses;
+ PyObject *tp_weaklist;
+ destructor tp_del;
+
+ /* Type attribute cache version tag. Added in version 2.6 */
+ unsigned int tp_version_tag;
+
+#ifdef COUNT_ALLOCS
+ /* these must be last and never explicitly initialized */
+ Py_ssize_t tp_allocs;
+ Py_ssize_t tp_frees;
+ Py_ssize_t tp_maxalloc;
+ struct _typeobject *tp_prev;
+ struct _typeobject *tp_next;
+#endif
+}PyBaseTypeObject;
+#endif /* STACKLESS */
/* The *real* layout of a type object when allocated on the heap */
typedef struct _heaptypeobject {
/* Note: there's a dependency on the order of these members
in slotptr() in typeobject.c . */
+#ifdef STACKLESS
+ PyBaseTypeObject ht_type;
+#else
PyTypeObject ht_type;
+#endif
PyNumberMethods as_number;
PyMappingMethods as_mapping;
PySequenceMethods as_sequence; /* as_sequence comes after as_mapping,
@@ -451,6 +542,9 @@
see add_operators() in typeobject.c . */
PyBufferProcs as_buffer;
PyObject *ht_name, *ht_slots;
+#ifdef STACKLESS
+ slp_methodflags slpflags;
+#endif
/* here are optional user slots, followed by the members. */
} PyHeapTypeObject;
@@ -458,8 +552,6 @@
#define PyHeapType_GET_MEMBERS(etype) \
((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize))
-#endif
-
/* Generic type check */
PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *);
#define PyObject_TypeCheck(ob, tp) \
_______________________________________________
Stackless mailing list
[email protected]
http://www.stackless.com/mailman/listinfo/stackless