Ticket #284 (closed defect: fixed)

Opened 5 years ago

Last modified 5 years ago

"cdef list" variable generates incorrect PyList_SetItem code

Reported by: ksmith Owned by: robertwb
Priority: major Milestone: 0.11.2
Component: Code Generation Keywords:

Description (last modified by scoder) (diff)

The first function below "in_range" works fine (the last line generates a call to PyObject_SetItem) but the "out_of_range" function does not. The last line in it generates a call to PyList_SetItem as it should, but the 'ob' PyObject is not converted to a Py_ssize_t.

[590]$ cat _out_of_range.pyx
def in_range():
   lst = range(11)
   ob = 10
   lst[ob] = -10

def out_of_range():
   cdef list lst = range(11)
   ob = 10
   lst[ob] = -10

Compiling raises a warning, as it should:

[591]$ python setup.py build_ext --inplace
running build_ext
cythoning _out_of_range.pyx to _out_of_range.c
building '_out_of_range' extension
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall
-Wstrict-prototypes -fPIC -I/usr/include/python2.5 -c _out_of_range.c
-o build/temp.linux-x86_64-2.5/_out_of_range.o
_out_of_range.c: In function ‘__pyx_pf_13_out_of_range_out_of_range’:
_out_of_range.c:429: warning: passing argument 2 of ‘PyList_SetItem’
makes integer from pointer without a cast
gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions
build/temp.linux-x86_64-2.5/_out_of_range.o -o _out_of_range.so

And calling it raises the exception:

[592]$ python out_of_range.py
after in_range
Traceback (most recent call last):
 File "out_of_range.py", line 5, in <module>
 File "_out_of_range.pyx", line 9, in _out_of_range.out_of_range
   lst[ob] = -10
IndexError: list assignment index out of range

This can be fixed easily with a wrapper around the index variable in the PyList_SetItem generated code in ExprNodes.py:generate_setitem_code

Change History

Changed 5 years ago by scoder

  • priority changed from trivial to major
  • description modified (diff)
  • milestone changed from wishlist to 0.11.2

Clearly a bug, looks like we need to coerce the index to Py_ssize_t first.

Changed 5 years ago by robertwb

Coercing to a Py_ssize_t will raise the wrong kind of exception.

Changed 5 years ago by robertwb

  • status changed from new to closed
  • resolution set to fixed
Note: See TracTickets for help on using tickets.