[issue25731] Assigning and deleting __new__ attr on the class does not allow to create instances of this class

Eryk Sun report at bugs.python.org
Wed Nov 25 12:47:18 EST 2015


Eryk Sun added the comment:

For "del X.__new__", type_setattro in Objects/typeobject.c indirectly calls update_one_slot. This finds object.__new__ fom the base object class when it looks up __new__ on the type. Since __new__ for built-in types is special-cased to be a built-in method instead of a slot wrapper, update_one_slot takes the branch for "Py_TYPE(descr) == &PyCFunction_Type", which assigns the existing tp_new to "specific". In this case that's slot_tp_new instead of object_new due to the previous assignment of the "new" function to X.__new__.  

slot_tp_new looks up and calls __new__, which in this case, as noted above, is object.__new__. This built-in method calls tp_new_wrapper, which calls the wrapped tp_new function. In this case that's object_new. If the type's tp_init is object_init (i.e. not overridden) or tp_new is not object_new (i.e. overridden), then object_new raises a TypeError when called with arguments. The problem in this case is that __new__ isn't overridden anymore. 

It seems to me that update_one_slot needs to install the tp_new that tp_new_wrapper would call, e.g. 

    specific = (void *)(
                 (PyTypeObject *)PyCFunction_GET_SELF(descr))->tp_new;

In this case that's object_new. Thus after "del X.__new__", X would be restored as if __new__ was never overridden.

----------
nosy: +eryksun
versions: +Python 2.7, Python 3.4, Python 3.6

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue25731>
_______________________________________


More information about the Python-bugs-list mailing list