Opened 6 years ago

Closed 5 years ago

#287 closed defect (fixed)

incorrect C code generated on method assignment

Reported by: rmurri Owned by: dalcinl
Priority: minor Milestone: 0.11.2
Component: Code Generation Keywords:
Cc:

Description

As of Cython 0.11.1, compiling the following class generates incorrect C code:

$ cat r.pyx
 cdef class r(object):
      cdef long long n
      cdef long long d

      def __init__(self, long long n, long long d):
          self.n = n
          self.d = d

      def __int__(self):
          return (self.n // self.d)

      __long__ = __int__

 $ cython -v r.pyx
 Compiling /tmp/r.pyx

 $ gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall
-Wstrict-prototypes -fPIC -I/usr/include/python2.5 -c r.c -o r.o
 r.c:487: error: ‘None’ undeclared here (not in a function)

 $ sed -e '484,490!d;488i^^^^^^^^^^^^^^^^^^^^^^^^ up here' r.c
   0, /*nb_coerce*/
   #endif
   __pyx_pf_1r_1r___int__, /*nb_int*/
   None, /*nb_long*/
 ^^^^^^^^^^^^^^^^^^^^^^^^ up here
   0, /*nb_float*/
   #if PY_MAJOR_VERSION < 3
   0, /*nb_oct*/

Related discussion on the mailing list:

http://codespeak.net/pipermail/cython-dev/2009-April/004898.html

Attachments (1)

type_slots_int_long.diff (4.4 KB) - added by dalcinl 6 years ago.

Download all attachments as: .zip

Change History (6)

comment:1 Changed 6 years ago by rmurri

  • Component changed from Build System to Code Generation
  • Milestone wishlist deleted
  • Priority changed from major to minor

comment:2 Changed 6 years ago by dagss

  • Milestone set to 0.11.2

Changed 6 years ago by dalcinl

comment:3 Changed 6 years ago by dalcinl

  • Cc dalcinl added

Just attached a tentative patch. I could lead to some controversy, but take into account I've spent a full day diving into CPython sources from 2.3 to 3.0 to decide on this.

Python 3


  • 'nb_long' (actually called 'nb_reserved') is now always set to '0'.
  • if 'int()' is defined, it is used for filling 'nb_int'.
  • if 'long()' is defined, it is used for filling 'nb_int'.
  • if both 'int()' and 'long()' are defined, then 'int()' is used for filling 'nb_int'.

Python 2


  • if if both 'int()' and 'long()' are defined, both are honoured to fill 'nb_int' and 'nb_long'.
  • If 'int()' is defined, it is used for filling 'nb_int'. If not, 'long()' is lookup and used if defined.
  • If 'long()' is defined, it is used for filling 'nb_long'. If not, 'int()' is lookup and used if defined.
  • As a consequence of the previous two, if only one of 'int()'/'long', that one is used for filling both 'nb_int' and 'nb_long'
  • Finally, I've modified _Pyx_PyNumber_Int() to unconditionally prefer 'nb_int' over 'nb_long'.

comment:4 Changed 5 years ago by dalcinl

  • Cc dalcinl removed
  • Owner changed from somebody to dalcinl
  • Status changed from new to assigned

comment:5 Changed 5 years ago by dalcinl

  • Resolution set to fixed
  • Status changed from assigned to closed
Note: See TracTickets for help on using tickets.