[Python-Dev] 2.6 object.__init__ & deling __new__
Nick Coghlan
ncoghlan at gmail.com
Wed Jul 15 15:41:40 CEST 2009
Dino Viehland wrote:
> Based upon the behavior I'm seeing it seems to me that the
> presence of __new__ / __init__ must be getting cached somewhere
> and the deletion isn't updating the cache and that's specifically
> what struck me as odd here.
Digging through typeobject.c, it isn't clear to me why this wouldn't be
getting picked up.
If all is working correctly:
1. When the class is created, tp_new and tp_init are copied from the
base class (see inherit_special and inherit_slots)
2. When object_new and object_init are called they compare the values
stored in the tp_new and tp_init slots with their own function addresses
to decide whether or not to raise the warning
3. When either of those is deleted, the update_slots call in
type_setattro should fix up the slot inheritance, and hence affect
future calls to __new__ and __init__
That said, the following comments in update_one_slot() are leading me to
wonder if Guido might owe Dino a beer:
{
/* The __new__ wrapper is not a wrapper descriptor,
so must be special-cased differently.
If we don't do this, creating an instance will
always use slot_tp_new which will look up
__new__ in the MRO which will call tp_new_wrapper
which will look through the base classes looking
for a static base and call its tp_new (usually
PyType_GenericNew), after performing various
sanity checks and constructing a new argument
list. Cut all that nonsense short -- this speeds
up instance creation tremendously. */
specific = (void *)type->tp_new;
/* XXX I'm not 100% sure that there isn't a hole
in this reasoning that requires additional
sanity checks. I'll buy the first person to
point out a bug in this reasoning a beer. */
}
I *think* this logic may be getting confused when update_one_slot() is
called immediately after the "del x.__new__" call has stuffed a NULL
into the tp_new slot. In the normal class creation case the tp_new
method will have been copied down from the parent class so the
conditions when update_one_slot() gets called are different (ditto for
when you actually *set* x.__new__ rather than delete it).
If nobody else gets anywhere with this I should have a chance to
actually play with it (rather than just reading code) tomorrow evening.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
More information about the Python-Dev
mailing list