[Python-Dev] Why is nb_inplace_add copied to sq_inplace_concat? (original) (raw)
Matt Newell newellm at blur.com
Fri May 17 01:17:20 CEST 2013
- Previous message: [Python-Dev] [RELEASED] Python 3.2.5 and Python 3.3.2
- Next message: [Python-Dev] Why is nb_inplace_add copied to sq_inplace_concat?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
I have encountered what I believe to be a bug but I'm sure there is some reason things are done as they are and I am hoping someone can shed some light or confirm it is indeed a bug.
As a bit of background I have a c++ class that I use sip to generate python bindings. The potential python bug manifests itself as:
rl = RecordList() rl += [] rl NotImplemented
The bindings fill in nb_inplace_add which appears to be implemented properly, returning a new reference to Py_NotImplemented if the right hand argument is not as expected.
Where things appear to go wrong is that PyNumber_InPlaceAdd, after getting a NotImplemented return value from nb_inplace_add, then attempts to call sq_inplace_concat. From reading the code it appears that sq_inplace_concat is not supposed to return NotImplemented, instead it should set an exception and return null if the right hand arg is not supported. In my case sq_inplace_concat ends up being the same function as nb_inplace_add, which results in the buggy behavior.
When I figured this out I tried to find out why sq_inplace_concat was set to the same function as nb_inplace_add, and ended up having to set a watchpoint in gdb which finally gave me the answer that python itself is setting sq_inplace_concat during type creation in the various functions in typeobject.c. Stack trace is below.
I don't really understand what the fixup_slot_dispatchers function is doing, but it does seem like there must be a bug either in what it's doing, or in PyNumber_InPlaceAdd's handling of a NotImplemented return value from sq_inplace_concat.
Thanks, Matt
Python 2.7.3 (default, Jan 2 2013, 13:56:14) [GCC 4.7.2] on linux2
Stack trace where a watch on sq->sq_inplace_concat reveals the change:
Hardware watchpoint 5: *(binaryfunc *) 0xcf6f88
Old value = (binaryfunc) 0 New value = (binaryfunc) 0x7ffff4d41c78 <slot_RecordList___iadd__(PyObject*, PyObject*)>
#0 update_one_slot.25588 (type=type at entry=0xcf6c70, p=0x86ba90) at ../Objects/typeobject.c:6203 #1 0x00000000004b96d0 in fixup_slot_dispatchers (type=0xcf6c70) at ../Objects/typeobject.c:6299 #2 type_new.part.40 (kwds=, args=0x0, metatype=) at ../Objects/typeobject.c:2464 #3 type_new.25999 (metatype=, args=0x0, kwds=) at ../Objects/typeobject.c:2048 #4 0x0000000000463c08 in type_call.25547 (type=0x7ffff65953a0, args=('RecordList', (<sip.wrappertype at remote 0x7ffff5201080>,), {'module': 'blur.Stone'}), kwds=0x0) at ../Objects/typeobject.c:721 #5 0x00000000004644eb in PyObject_Call (func=<type at remote 0x7ffff65953a0>, arg=, kw=) at ../Objects/abstract.c:2529
- Previous message: [Python-Dev] [RELEASED] Python 3.2.5 and Python 3.3.2
- Next message: [Python-Dev] Why is nb_inplace_add copied to sq_inplace_concat?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]