Commit 8aedb60c authored by Lisandro Dalcin's avatar Lisandro Dalcin

fixes int/long type slots in Py2/Py3 (ticket #287)

parent e49d3c7a
......@@ -1741,14 +1741,14 @@ static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
return Py_INCREF(x), x;
m = Py_TYPE(x)->tp_as_number;
#if PY_VERSION_HEX < 0x03000000
if (m && m->nb_long) {
name = "long";
res = PyNumber_Long(x);
}
else if (m && m->nb_int) {
if (m && m->nb_int) {
name = "int";
res = PyNumber_Int(x);
}
else if (m && m->nb_long) {
name = "long";
res = PyNumber_Long(x);
}
#else
if (m && m->nb_int) {
name = "int";
......
......@@ -154,7 +154,14 @@ class SlotDescriptor(object):
code.putln("#if PY_MAJOR_VERSION >= 3")
if flag:
code.putln("#if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & %s)" % flag)
if py3k == '<RESERVED>':
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln("0, /*reserved*/")
code.putln("#else")
code.putln("%s, /*%s*/" % (value, self.slot_name))
if py3k == '<RESERVED>':
code.putln("#endif")
if flag or (not py3k or not py2) or self.ifdef:
code.putln("#endif")
......@@ -212,10 +219,13 @@ class MethodSlot(SlotDescriptor):
def slot_code(self, scope):
entry = scope.lookup_here(self.method_name)
if entry:
if entry and entry.func_cname:
return entry.func_cname
else:
return "0"
if self.default is not None:
entry = scope.lookup_here(self.default)
if entry and entry.func_cname:
return entry.func_cname
return "0"
class InternalMethodSlot(SlotDescriptor):
......@@ -557,8 +567,8 @@ PyNumberMethods = (
MethodSlot(binaryfunc, "nb_xor", "__xor__"),
MethodSlot(binaryfunc, "nb_or", "__or__"),
EmptySlot("nb_coerce", py3k = False),
MethodSlot(unaryfunc, "nb_int", "__int__"),
MethodSlot(unaryfunc, "nb_long", "__long__"),
MethodSlot(unaryfunc, "nb_int", "__int__", default="__long__"),
MethodSlot(unaryfunc, "nb_long", "__long__", default="__int__", py3k = "<RESERVED>"),
MethodSlot(unaryfunc, "nb_float", "__float__"),
MethodSlot(unaryfunc, "nb_oct", "__oct__", py3k = False),
MethodSlot(unaryfunc, "nb_hex", "__hex__", py3k = False),
......
......@@ -666,6 +666,17 @@ class MyBadInt(MyInt):
def __int__(self):
return u"%s" % self.value
class MyInt2:
def __init__(self, value):
self.value = value
def __int__(self):
print(u"MyInt.__int__()")
return self.value
class MyBadInt2(MyInt2):
def __int__(self):
return u"%s" % self.value
def test_convert_pyint(x):
u"""
>>> test_convert_pyint(None)
......
__doc__ = u"""
>>> print( "%d" % Int() )
2
>>> print( "%d" % Long() )
3
>>> print( "%d" % IntLongA() )
2
>>> print( "%d" % IntLongB() )
2
>>> print( "%d" % IntLongC() )
3
>>> getint( Int() )
2
>>> getint( Long() )
3
>>> getint( IntLongA() )
2
>>> getint( IntLongB() )
2
>>> getint( IntLongC() )
3
>>> getlong( Int() )
2
>>> getlong( Long() )
3
>>> getlong( IntLongA() )
2
>>> getlong( IntLongB() )
2
>>> getlong( IntLongC() )
3
"""
def getint(int i):
return i
def getlong(long long i):
return <int>i
cdef class Int:
def __int__(self):
return 2
cdef class Long:
def __long__(self):
return 3
cdef class IntLongA:
def __int__(self):
return 2
def __long__(self):
return 3
cdef class IntLongB:
def __int__(self):
return 2
__long__ = __int__
cdef class IntLongC:
def __long__(self):
return 3
__int__ = __long__
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment