sometype.__new__ and C subclasses

Robert Kern robert.kern at gmail.com
Sun May 2 16:51:19 EDT 2010


On 2010-05-02 15:28 , Carl Banks wrote:
> On May 2, 10:48 am, James Porter<port... at alum.rit.edu>  wrote:
>> On 5/2/2010 4:34 AM, Carl Banks wrote:
>>
>>> 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.
>>
>> Unfortunately, I can't do that, since that call is in NumPy itself and
>> it's part of their "standard" way of making instances of subclasses of
>> ndarray. Functions like numpy.zeros_like use ndarray.__new__(subtype,
>> ...) to create new arrays based on the shape of other arrays.
>>
>> The Python version of the subclass is shown here:
>> <http://docs.scipy.org/doc/numpy/user/basics.subclassing.html#slightly...>,
>> and I'm trying to write something pretty similar in C. I'm trying to
>> stay in C since everything else is in C, so it's easier to stay in C
>> then to jump back and forth all the time.
>>
>> Maybe the real answer to this question is "NumPy is doing it wrong" and
>> I should be on their list; still, it seems strange that the behavior is
>> different between Python and C.
>
> I would say numpy is wrong here, so I suggest filing a bug report.
>
> In fact I can't think of any benefit to EVER calling X.__new__(Y)
> where X is not Y.  Maybe old-style classes?  Someone who wants to
> ensure they're getting an instance of a certain type can check
> issubclass(Y,X) then call Y.__new__(Y).

Well, the Y.__new__(Y) may call X.__new__(Y) (and we certainly do this 
successfully in other Python subclasses of ndarray; this also appears in the 
Python regression tests). I'm not sure why this would be permitted there and not 
in a regular function (numpy.zeros_like() seems to be the function that does 
this and fails for the OP). The reason we do it there instead of calling the 
subclass's constructor is because the subclass's constructor may have different 
arguments.

I'm happy to concede that this might be a bug in numpy, but I don't understand 
why this is allowed for Python subclasses but not C subtypes.

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco




More information about the Python-list mailing list