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 <rep...@bugs.python.org> <http://bugs.python.org/issue25731> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com