Commit f31aac14 authored by Lisandro Dalcin's avatar Lisandro Dalcin

Py3: __cmp__ is gone, __bool__ instead of __nonzero__

parent 3b44dbd8
...@@ -11,7 +11,8 @@ import Symtab ...@@ -11,7 +11,8 @@ import Symtab
class AutoTestDictTransform(ScopeTrackingTransform): class AutoTestDictTransform(ScopeTrackingTransform):
# Handles autotestdict directive # Handles autotestdict directive
blacklist = ['__cinit__', '__dealloc__', '__richcmp__', '__nonzero__', blacklist = ['__cinit__', '__dealloc__', '__richcmp__',
'__nonzero__', '__bool__',
'__len__', '__contains__'] '__len__', '__contains__']
def visit_ModuleNode(self, node): def visit_ModuleNode(self, node):
......
...@@ -126,16 +126,17 @@ class SlotDescriptor(object): ...@@ -126,16 +126,17 @@ class SlotDescriptor(object):
# slot_name string Member name of the slot in the type object # slot_name string Member name of the slot in the type object
# is_initialised_dynamically Is initialised by code in the module init function # is_initialised_dynamically Is initialised by code in the module init function
# flag Py_TPFLAGS_XXX value indicating presence of slot # flag Py_TPFLAGS_XXX value indicating presence of slot
# py3k Indicates presence of slot in Python 3 # py3 Indicates presence of slot in Python 3
# py2 Indicates presence of slot in Python 2 # py2 Indicates presence of slot in Python 2
# ifdef Full #ifdef string that slot is wrapped in. Using this causes py3k, py2 and flags to be ignored.) # ifdef Full #ifdef string that slot is wrapped in. Using this causes py3, py2 and flags to be ignored.)
def __init__(self, slot_name, dynamic = 0, flag = None, py3k = True, py2 = True, ifdef = None): def __init__(self, slot_name, dynamic=0,
flag=None, py3=True, py2=True, ifdef=None):
self.slot_name = slot_name self.slot_name = slot_name
self.is_initialised_dynamically = dynamic self.is_initialised_dynamically = dynamic
self.flag = flag self.flag = flag
self.py3k = py3k self.py3 = py3
self.py2 = py2 self.py2 = py2
self.ifdef = ifdef self.ifdef = ifdef
def generate(self, scope, code): def generate(self, scope, code):
...@@ -144,26 +145,26 @@ class SlotDescriptor(object): ...@@ -144,26 +145,26 @@ class SlotDescriptor(object):
else: else:
value = self.slot_code(scope) value = self.slot_code(scope)
flag = self.flag flag = self.flag
py3k = self.py3k py3 = self.py3
py2 = self.py2 py2 = self.py2
if self.ifdef: if self.ifdef:
code.putln("#if %s" % self.ifdef) code.putln("#if %s" % self.ifdef)
else: else:
if not py3k: if not py3:
code.putln("#if PY_MAJOR_VERSION < 3") code.putln("#if PY_MAJOR_VERSION < 3")
elif not py2: elif not py2:
code.putln("#if PY_MAJOR_VERSION >= 3") code.putln("#if PY_MAJOR_VERSION >= 3")
if flag: if flag:
code.putln("#if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & %s)" % flag) code.putln("#if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & %s)" % flag)
if py3k == '<RESERVED>': if py3 == '<RESERVED>':
code.putln("#if PY_MAJOR_VERSION >= 3") code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln("0, /*reserved*/") code.putln("0, /*reserved*/")
code.putln("#else") code.putln("#else")
code.putln("%s, /*%s*/" % (value, self.slot_name)) code.putln("%s, /*%s*/" % (value, self.slot_name))
if py3k == '<RESERVED>': if py3 == '<RESERVED>':
code.putln("#endif") code.putln("#endif")
if flag or (not py3k or not py2) or self.ifdef: if flag or (not py3 or not py2) or self.ifdef:
code.putln("#endif") code.putln("#endif")
# Some C implementations have trouble statically # Some C implementations have trouble statically
...@@ -188,8 +189,8 @@ class FixedSlot(SlotDescriptor): ...@@ -188,8 +189,8 @@ class FixedSlot(SlotDescriptor):
# #
# value string # value string
def __init__(self, slot_name, value, py3k=True, py2=True, ifdef=None): def __init__(self, slot_name, value, flag=None, py3=True, py2=True, ifdef=None):
SlotDescriptor.__init__(self, slot_name, py3k=py3k, py2=py2, ifdef=ifdef) SlotDescriptor.__init__(self, slot_name, flag=flag, py3=py3, py2=py2, ifdef=ifdef)
self.value = value self.value = value
def slot_code(self, scope): def slot_code(self, scope):
...@@ -199,8 +200,8 @@ class FixedSlot(SlotDescriptor): ...@@ -199,8 +200,8 @@ class FixedSlot(SlotDescriptor):
class EmptySlot(FixedSlot): class EmptySlot(FixedSlot):
# Descriptor for a type slot whose value is always 0. # Descriptor for a type slot whose value is always 0.
def __init__(self, slot_name, py3k=True, py2=True, ifdef=None): def __init__(self, slot_name, flag=None, py3=True, py2=True, ifdef=None):
FixedSlot.__init__(self, slot_name, "0", py3k=py3k, py2=py2, ifdef=ifdef) FixedSlot.__init__(self, slot_name, "0", flag=flag, py3=py3, py2=py2, ifdef=ifdef)
class MethodSlot(SlotDescriptor): class MethodSlot(SlotDescriptor):
...@@ -208,22 +209,31 @@ class MethodSlot(SlotDescriptor): ...@@ -208,22 +209,31 @@ class MethodSlot(SlotDescriptor):
# #
# signature Signature # signature Signature
# method_name string The __xxx__ name of the method # method_name string The __xxx__ name of the method
# default string or None Default value of the slot # alternatives [string] Alternative list of __xxx__ names for the method
def __init__(self, signature, slot_name, method_name, default = None, flag = None, py3k=True, py2=True, ifdef=None): def __init__(self, signature, slot_name, method_name, fallback=None,
SlotDescriptor.__init__(self, slot_name, flag = flag, py3k = py3k, py2=py2, ifdef=ifdef) flag=None, py3=True, py2=True, ifdef=None):
SlotDescriptor.__init__(self, slot_name, flag=flag, py3=py3, py2=py2, ifdef=ifdef)
self.signature = signature self.signature = signature
self.slot_name = slot_name self.slot_name = slot_name
self.method_name = method_name self.method_name = method_name
self.default = default self.alternatives = []
method_name_to_slot[method_name] = self method_name_to_slot[method_name] = self
#
if fallback:
self.alternatives.append(fallback)
for alt in (self.py2, self.py3):
if isinstance(alt, (tuple, list)):
slot_name, method_name = alt
self.alternatives.append(method_name)
method_name_to_slot[method_name] = self
def slot_code(self, scope): def slot_code(self, scope):
entry = scope.lookup_here(self.method_name) entry = scope.lookup_here(self.method_name)
if entry and entry.func_cname: if entry and entry.func_cname:
return entry.func_cname return entry.func_cname
if self.default is not None: for method_name in self.alternatives:
entry = scope.lookup_here(self.default) entry = scope.lookup_here(method_name)
if entry and entry.func_cname: if entry and entry.func_cname:
return entry.func_cname return entry.func_cname
return "0" return "0"
...@@ -235,8 +245,8 @@ class InternalMethodSlot(SlotDescriptor): ...@@ -235,8 +245,8 @@ class InternalMethodSlot(SlotDescriptor):
# #
# slot_name string Member name of the slot in the type object # slot_name string Member name of the slot in the type object
def __init__(self, slot_name, py2 = True): def __init__(self, slot_name, **kargs):
SlotDescriptor.__init__(self, slot_name, py2 = py2) SlotDescriptor.__init__(self, slot_name, **kargs)
def slot_code(self, scope): def slot_code(self, scope):
return scope.mangle_internal(self.slot_name) return scope.mangle_internal(self.slot_name)
...@@ -246,8 +256,8 @@ class GCDependentSlot(InternalMethodSlot): ...@@ -246,8 +256,8 @@ class GCDependentSlot(InternalMethodSlot):
# Descriptor for a slot whose value depends on whether # Descriptor for a slot whose value depends on whether
# the type participates in GC. # the type participates in GC.
def __init__(self, slot_name): def __init__(self, slot_name, **kargs):
InternalMethodSlot.__init__(self, slot_name) InternalMethodSlot.__init__(self, slot_name, **kargs)
def slot_code(self, scope): def slot_code(self, scope):
if not scope.needs_gc(): if not scope.needs_gc():
...@@ -267,8 +277,8 @@ class GCDependentSlot(InternalMethodSlot): ...@@ -267,8 +277,8 @@ class GCDependentSlot(InternalMethodSlot):
class ConstructorSlot(InternalMethodSlot): class ConstructorSlot(InternalMethodSlot):
# Descriptor for tp_new and tp_dealloc. # Descriptor for tp_new and tp_dealloc.
def __init__(self, slot_name, method): def __init__(self, slot_name, method, **kargs):
InternalMethodSlot.__init__(self, slot_name) InternalMethodSlot.__init__(self, slot_name, **kargs)
self.method = method self.method = method
def slot_code(self, scope): def slot_code(self, scope):
...@@ -294,8 +304,8 @@ class SyntheticSlot(InternalMethodSlot): ...@@ -294,8 +304,8 @@ class SyntheticSlot(InternalMethodSlot):
# alternative default value will be placed in the type # alternative default value will be placed in the type
# slot. # slot.
def __init__(self, slot_name, user_methods, default_value, py2 = True): def __init__(self, slot_name, user_methods, default_value, **kargs):
InternalMethodSlot.__init__(self, slot_name, py2 = py2) InternalMethodSlot.__init__(self, slot_name, **kargs)
self.user_methods = user_methods self.user_methods = user_methods
self.default_value = default_value self.default_value = default_value
...@@ -550,32 +560,32 @@ PyNumberMethods = ( ...@@ -550,32 +560,32 @@ PyNumberMethods = (
MethodSlot(binaryfunc, "nb_add", "__add__"), MethodSlot(binaryfunc, "nb_add", "__add__"),
MethodSlot(binaryfunc, "nb_subtract", "__sub__"), MethodSlot(binaryfunc, "nb_subtract", "__sub__"),
MethodSlot(binaryfunc, "nb_multiply", "__mul__"), MethodSlot(binaryfunc, "nb_multiply", "__mul__"),
MethodSlot(binaryfunc, "nb_divide", "__div__", py3k = False), MethodSlot(binaryfunc, "nb_divide", "__div__", py3 = False),
MethodSlot(binaryfunc, "nb_remainder", "__mod__"), MethodSlot(binaryfunc, "nb_remainder", "__mod__"),
MethodSlot(binaryfunc, "nb_divmod", "__divmod__"), MethodSlot(binaryfunc, "nb_divmod", "__divmod__"),
MethodSlot(ternaryfunc, "nb_power", "__pow__"), MethodSlot(ternaryfunc, "nb_power", "__pow__"),
MethodSlot(unaryfunc, "nb_negative", "__neg__"), MethodSlot(unaryfunc, "nb_negative", "__neg__"),
MethodSlot(unaryfunc, "nb_positive", "__pos__"), MethodSlot(unaryfunc, "nb_positive", "__pos__"),
MethodSlot(unaryfunc, "nb_absolute", "__abs__"), MethodSlot(unaryfunc, "nb_absolute", "__abs__"),
MethodSlot(inquiry, "nb_nonzero", "__nonzero__"), MethodSlot(inquiry, "nb_nonzero", "__nonzero__", py3 = ("nb_bool", "__bool__")),
MethodSlot(unaryfunc, "nb_invert", "__invert__"), MethodSlot(unaryfunc, "nb_invert", "__invert__"),
MethodSlot(binaryfunc, "nb_lshift", "__lshift__"), MethodSlot(binaryfunc, "nb_lshift", "__lshift__"),
MethodSlot(binaryfunc, "nb_rshift", "__rshift__"), MethodSlot(binaryfunc, "nb_rshift", "__rshift__"),
MethodSlot(binaryfunc, "nb_and", "__and__"), MethodSlot(binaryfunc, "nb_and", "__and__"),
MethodSlot(binaryfunc, "nb_xor", "__xor__"), MethodSlot(binaryfunc, "nb_xor", "__xor__"),
MethodSlot(binaryfunc, "nb_or", "__or__"), MethodSlot(binaryfunc, "nb_or", "__or__"),
EmptySlot("nb_coerce", py3k = False), EmptySlot("nb_coerce", py3 = False),
MethodSlot(unaryfunc, "nb_int", "__int__", default="__long__"), MethodSlot(unaryfunc, "nb_int", "__int__", fallback="__long__"),
MethodSlot(unaryfunc, "nb_long", "__long__", default="__int__", py3k = "<RESERVED>"), MethodSlot(unaryfunc, "nb_long", "__long__", fallback="__int__", py3 = "<RESERVED>"),
MethodSlot(unaryfunc, "nb_float", "__float__"), MethodSlot(unaryfunc, "nb_float", "__float__"),
MethodSlot(unaryfunc, "nb_oct", "__oct__", py3k = False), MethodSlot(unaryfunc, "nb_oct", "__oct__", py3 = False),
MethodSlot(unaryfunc, "nb_hex", "__hex__", py3k = False), MethodSlot(unaryfunc, "nb_hex", "__hex__", py3 = False),
# Added in release 2.0 # Added in release 2.0
MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__"), MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__"),
MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__"), MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__"),
MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__"), MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__"),
MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__", py3k = False), MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__", py3 = False),
MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__"), MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__"),
MethodSlot(ternaryfunc, "nb_inplace_power", "__ipow__"), # NOT iternaryfunc!!! MethodSlot(ternaryfunc, "nb_inplace_power", "__ipow__"), # NOT iternaryfunc!!!
MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__"), MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__"),
...@@ -615,10 +625,10 @@ PyMappingMethods = ( ...@@ -615,10 +625,10 @@ PyMappingMethods = (
) )
PyBufferProcs = ( PyBufferProcs = (
MethodSlot(getreadbufferproc, "bf_getreadbuffer", "__getreadbuffer__", py3k = False), MethodSlot(getreadbufferproc, "bf_getreadbuffer", "__getreadbuffer__", py3 = False),
MethodSlot(getwritebufferproc, "bf_getwritebuffer", "__getwritebuffer__", py3k = False), MethodSlot(getwritebufferproc, "bf_getwritebuffer", "__getwritebuffer__", py3 = False),
MethodSlot(getsegcountproc, "bf_getsegcount", "__getsegcount__", py3k = False), MethodSlot(getsegcountproc, "bf_getsegcount", "__getsegcount__", py3 = False),
MethodSlot(getcharbufferproc, "bf_getcharbuffer", "__getcharbuffer__", py3k = False), MethodSlot(getcharbufferproc, "bf_getcharbuffer", "__getcharbuffer__", py3 = False),
MethodSlot(getbufferproc, "bf_getbuffer", "__getbuffer__", ifdef = "PY_VERSION_HEX >= 0x02060000"), MethodSlot(getbufferproc, "bf_getbuffer", "__getbuffer__", ifdef = "PY_VERSION_HEX >= 0x02060000"),
MethodSlot(releasebufferproc, "bf_releasebuffer", "__releasebuffer__", ifdef = "PY_VERSION_HEX >= 0x02060000") MethodSlot(releasebufferproc, "bf_releasebuffer", "__releasebuffer__", ifdef = "PY_VERSION_HEX >= 0x02060000")
...@@ -637,7 +647,7 @@ slot_table = ( ...@@ -637,7 +647,7 @@ slot_table = (
EmptySlot("tp_print"), #MethodSlot(printfunc, "tp_print", "__print__"), EmptySlot("tp_print"), #MethodSlot(printfunc, "tp_print", "__print__"),
EmptySlot("tp_getattr"), EmptySlot("tp_getattr"),
EmptySlot("tp_setattr"), EmptySlot("tp_setattr"),
MethodSlot(cmpfunc, "tp_compare", "__cmp__"), MethodSlot(cmpfunc, "tp_compare", "__cmp__", py3 = '<RESERVED>'),
MethodSlot(reprfunc, "tp_repr", "__repr__"), MethodSlot(reprfunc, "tp_repr", "__repr__"),
SuiteSlot(PyNumberMethods, "PyNumberMethods", "tp_as_number"), SuiteSlot(PyNumberMethods, "PyNumberMethods", "tp_as_number"),
......
...@@ -126,4 +126,20 @@ cdef class MyCdefClass: ...@@ -126,4 +126,20 @@ cdef class MyCdefClass:
False False
""" """
cdef class MyOtherCdefClass:
"""
Needs no hack
>>> True
True
"""
def __bool__(self):
"""
Should not be included, as it can't be looked up with getattr in Py 2
>>> True
False
"""
cdeffunc() cdeffunc()
__doc__ = """
>>> not not BoolA(0)
False
>>> not not BoolA(1)
True
>>> not not BoolB(0)
False
>>> not not BoolB(1)
True
>>> not not BoolX(0)
False
>>> not not BoolX(1)
True
>>> not not BoolY(0)
False
>>> not not BoolY(1)
True
"""
cdef class BoolA:
cdef bint value
def __cinit__(self, bint value):
self.value = value
def __nonzero__(self):
return self.value
cdef class BoolB:
cdef bint value
def __cinit__(self, bint value):
self.value = value
def __bool__(self):
return self.value
cdef class BoolX(BoolA):
pass
cdef class BoolY(BoolB):
pass
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