who is calling the base class __new__ method

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
 
A

Andreas Otto

Hi,

found a solution ....

- "PyObject_GC_New" seems not to be *not* the right function to
create a new Python object with a base class included

- "PyType_GenericNew" is the right one ...
but this one is not documented ....

from: http://docs.python.org/3.0/c-api/type.html
=================================================
PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject
*kwds)¶
Return value: New reference.

XXX: Document.
=================================================

Question: What is the difference between these both functions
and why is one working and the other not ?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top