A
Andreas Otto
Hi,
I have the following example:
1. I create a new type in "C" with it's own tp_new called "PyMqS_new"
2. I use this type as basis-class for a python class called "Server".
class Server(pymsgque.MqS):
-> I checked: self.__class__.__bases__: (<class 'pymsgque.PyMqS'>,)
from a "Server" startup code and the base is available
....
3. A object of "Server" should create a new object of class "Server" in
the "C" code of MqS using the following statement
context->self = PyObject_GC_New(PyObject,(PyTypeObject*)context->class);
"class" is the "Server" but the "PyMqS_new" is *not* called as expected
-> Why ?
4. I checked the code with a debugger and I find out that the python
ServerObject create with "PyObject_GC_New" has the right pointer
-> "ServerObject->ob_type->tp_new" has a pointer to "PyMqS_new"
-> this seems to be fine
I checked the tp_basicsize and this has a size of 40 seems ok
from: http://docs.python.org/3.0/extending/newtypes.html
If you want your type to be subclassable from Python, and your type has the
same tp_basicsize as its base type, you may have problems with multiple
inheritance. A Python subclass of your type will have to list your type
first in its __bases__, or else it will not be able to call your type’s
__new__() method without getting an error. You can avoid this problem by
ensuring that your type has a larger value for tp_basicsize than its base
type does. Most of the time, this will be true anyway, because either your
base type will be object, or else you will be adding data members to your
base type, and therefore increasing its size.
An other aspect from your docu (same link as above):
If you are creating a co-operative tp_new (one that calls a base type’s
tp_new or __new__()), you must not try to determine what method to call
using method resolution order at runtime. Always statically determine what
type you are going to call, and call its tp_new directly, or via
type->tp_base->tp_new. If you do not do this, Python subclasses of your
type that also inherit from other Python-defined classes may not work
correctly. (Specifically, you may not be able to create instances of such
subclasses without getting a TypeError.)
This I don't understand because the "tp_base" of "MqS" is "Object"
and if I call the "Object" tp_new from my new
static PyObject *
PyMqS_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
M0
?? type->tp_base->tp_new(....
PyMqS_Obj *self = (PyMqS_Obj *)type->tp_alloc(type, 0);
self->msgque = NULL;
return (PyObject *)self;
}
mfg
Andreas Otto
I have the following example:
1. I create a new type in "C" with it's own tp_new called "PyMqS_new"
2. I use this type as basis-class for a python class called "Server".
class Server(pymsgque.MqS):
-> I checked: self.__class__.__bases__: (<class 'pymsgque.PyMqS'>,)
from a "Server" startup code and the base is available
....
3. A object of "Server" should create a new object of class "Server" in
the "C" code of MqS using the following statement
context->self = PyObject_GC_New(PyObject,(PyTypeObject*)context->class);
"class" is the "Server" but the "PyMqS_new" is *not* called as expected
-> Why ?
4. I checked the code with a debugger and I find out that the python
ServerObject create with "PyObject_GC_New" has the right pointer
-> "ServerObject->ob_type->tp_new" has a pointer to "PyMqS_new"
-> this seems to be fine
I checked the tp_basicsize and this has a size of 40 seems ok
from: http://docs.python.org/3.0/extending/newtypes.html
If you want your type to be subclassable from Python, and your type has the
same tp_basicsize as its base type, you may have problems with multiple
inheritance. A Python subclass of your type will have to list your type
first in its __bases__, or else it will not be able to call your type’s
__new__() method without getting an error. You can avoid this problem by
ensuring that your type has a larger value for tp_basicsize than its base
type does. Most of the time, this will be true anyway, because either your
base type will be object, or else you will be adding data members to your
base type, and therefore increasing its size.
An other aspect from your docu (same link as above):
If you are creating a co-operative tp_new (one that calls a base type’s
tp_new or __new__()), you must not try to determine what method to call
using method resolution order at runtime. Always statically determine what
type you are going to call, and call its tp_new directly, or via
type->tp_base->tp_new. If you do not do this, Python subclasses of your
type that also inherit from other Python-defined classes may not work
correctly. (Specifically, you may not be able to create instances of such
subclasses without getting a TypeError.)
This I don't understand because the "tp_base" of "MqS" is "Object"
and if I call the "Object" tp_new from my new
static PyObject *
PyMqS_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
M0
?? type->tp_base->tp_new(....
PyMqS_Obj *self = (PyMqS_Obj *)type->tp_alloc(type, 0);
self->msgque = NULL;
return (PyObject *)self;
}
mfg
Andreas Otto