sometype.__new__ and C subclasses

Carl Banks pavlovevidence at gmail.com
Sun May 2 05:34:54 EDT 2010


On May 1, 11:03 pm, James Porter <port... at alum.rit.edu> wrote:
> I've been trying to write a Python C extension module that uses NumPy
> and has a subtype of numpy.ndarray written in C. However, I've run into
> a snag: calling numpy.ndarray.__new__(mysubtype, ...) triggers an
> exception in the bowels of Python (this is necessary for a handful of
> NumPy features). I'm posting to this list to try to figure out why this
> exception exists in the first place, and what (if anything) I can do to
> work around it.
>
> The exception in question happens in Objects/typeobject.c in
> tp_new_wrapper. Here's the comment for the block:
>
>         /* Check that the use doesn't do something silly and unsafe like
>            object.__new__(dict).  To do this, we check that the
>            most derived base that's not a heap type is this type. */
>
> The code has the end effect that basetype.__new__(subtype, ...) fails
> whenever subtype is a statically-defined type (i.e. a normal C extension
> type object). Why is this necessary in general? I can see why it might
> be bad for a limited number of core Python types, but it seems
> unnecessarily limiting for Python C extensions.

Why don't you use mysubtype.__new__(mysubtype,...)?

If you wrote mysubtype in C, and defined a different tp_new than
ndarray, then this exception will trigger.  And it ought to; you don't
want to use ndarray's tp_new to create an object of your subclass, if
you've defined a different tp_new.


> On a more practical note, is there a way (short of rewriting the subtype
> in Python) to work around this? It seems that I could call the type
> metaclass to create a heap type in C, but I'm not sure of all the
> implications of that.

It should work if you use mysubtype.__new__(mysubtype,...).

If it doesn't do what you want, then there's probably something wrong
with the way you subclassed ndarray.


Carl Banks



More information about the Python-list mailing list