Commit 0e061044 authored by Stefan Behnel's avatar Stefan Behnel

merge

parents 05808083 55445737
......@@ -7499,12 +7499,12 @@ PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *mod
op->func.m_self = self;
Py_XINCREF(module);
op->func.m_module = module;
_PyObject_GC_TRACK(op);
PyObject_GC_Track(op);
return (PyObject *)op;
}
static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
_PyObject_GC_UNTRACK(m);
PyObject_GC_UnTrack(m);
Py_XDECREF(m->func.m_self);
Py_XDECREF(m->func.m_module);
PyObject_GC_Del(m);
......
......@@ -571,6 +571,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
#endif
#if PY_MAJOR_VERSION >= 3
#define PyBoolObject PyLongObject
#endif
""")
code.put("""
......@@ -932,8 +937,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_getitem_int_function(scope, code)
if scope.defines_any(["__setitem__", "__delitem__"]):
self.generate_ass_subscript_function(scope, code)
if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]):
warning(self.pos, "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, use __getitem__, __setitem__, and __delitem__ instead", 1)
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.")
code.putln("#endif")
if scope.defines_any(["__setslice__", "__delslice__"]):
warning(self.pos, "__setslice__ and __delslice__ are not supported by Python 3, use __setitem__ and __getitem__ instead", 1)
self.generate_ass_slice_function(scope, code)
if scope.defines_any(["__getattr__","__getattribute__"]):
self.generate_getattro_function(scope, code)
......@@ -1260,9 +1269,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# Setting and deleting a slice are both done through
# the ass_slice method, so we dispatch to user's __setslice__
# or __delslice__, or raise an exception.
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln("#error __setslice__ and __delslice__ not supported in Python 3.")
code.putln("#endif")
base_type = scope.parent_type.base_type
set_entry = scope.lookup_here("__setslice__")
del_entry = scope.lookup_here("__delslice__")
......@@ -2035,6 +2041,29 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"if (PyType_Ready(&%s) < 0) %s" % (
typeobj_cname,
code.error_goto(entry.pos)))
# Fix special method docstrings. This is a bit of a hack, but
# unless we let PyType_Ready create the slot wrappers we have
# a significant performance hit. (See trac #561.)
for func in entry.type.scope.pyfunc_entries:
if func.is_special and func.wrapperbase_cname:
code.putln("{");
code.putln(
'PyObject *wrapper = PyObject_GetAttrString((PyObject *)&%s, "%s"); %s' % (
typeobj_cname,
func.name,
code.error_goto_if_null('wrapper', entry.pos)));
code.putln(
"if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {");
code.putln(
"%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % (
func.wrapperbase_cname));
code.putln(
"%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname));
code.putln(
"((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % (
func.wrapperbase_cname));
code.putln("}");
code.putln("}");
if type.vtable_cname:
code.putln(
"if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
......
......@@ -35,6 +35,7 @@ prop_set_prefix = pyrex_prefix + "setprop_"
type_prefix = pyrex_prefix + "t_"
typeobj_prefix = pyrex_prefix + "type_"
var_prefix = pyrex_prefix + "v_"
wrapperbase_prefix= pyrex_prefix + "wrapperbase_"
bufstruct_prefix = pyrex_prefix + "bstruct_"
bufstride_prefix = pyrex_prefix + "bstride_"
bufshape_prefix = pyrex_prefix + "bshape_"
......
......@@ -2110,6 +2110,11 @@ class DefNode(FuncDefNode):
entry.doc = embed_position(self.pos, self.doc)
entry.doc_cname = \
Naming.funcdoc_prefix + prefix + name
if entry.is_special:
if entry.name in TypeSlots.invisible or not entry.doc:
entry.wrapperbase_cname = None
else:
entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
else:
entry.doc = None
......@@ -2224,10 +2229,8 @@ class DefNode(FuncDefNode):
if proto_only:
return
if (Options.docstrings and self.entry.doc and
(not self.entry.is_special or
self.entry.signature.method_flags()) and
not self.entry.scope.is_property_scope
):
not self.entry.scope.is_property_scope and
(not self.entry.is_special or self.entry.wrapperbase_cname)):
docstr = self.entry.doc
if docstr.is_unicode:
docstr = docstr.utf8encode()
......@@ -2235,6 +2238,9 @@ class DefNode(FuncDefNode):
'static char %s[] = "%s";' % (
self.entry.doc_cname,
split_string_literal(escape_byte_string(docstr))))
if self.entry.is_special:
code.putln(
"struct wrapperbase %s;" % self.entry.wrapperbase_cname)
if with_pymethdef:
code.put(
"static PyMethodDef %s = " %
......
......@@ -8,6 +8,9 @@ import PyrexTypes
import StringEncoding
import sys
invisible = ['__cinit__', '__dealloc__', '__richcmp__',
'__nonzero__', '__bool__']
class Signature(object):
# Method slot signature descriptor.
#
......
version = '0.13.beta0'
version = '0.13.beta1'
......@@ -59,9 +59,15 @@ VER_DEP_MODULES = {
(2,6) : (operator.lt, lambda x: x in ['run.print_function',
'run.cython3',
]),
# The next line should start (3,); but this is a dictionary, so
# we can only have one (3,) key. Since 2.7 is supposed to be the
# last 2.x release, things would have to change drastically for this
# to be unsafe...
(2,999): (operator.lt, lambda x: x in ['run.special_methods_T561_py3']),
(3,): (operator.ge, lambda x: x in ['run.non_future_division',
'compile.extsetslice',
'compile.extdelslice']),
'compile.extdelslice',
'run.special_methods_T561_py2']),
}
INCLUDE_DIRS = [ d for d in os.getenv('INCLUDE', '').split(os.pathsep) if d ]
......
......@@ -83,9 +83,9 @@ def return_range_sum_squares(int N):
>>> return_range_sum_squares(10)
285
>>> sum([i*i for i in range(10000)])
>>> print(sum([i*i for i in range(10000)]))
333283335000
>>> return_range_sum_squares(10000)
>>> print(return_range_sum_squares(10000))
333283335000
"""
return sum(i*i for i in range(N))
......@@ -101,9 +101,9 @@ def return_sum_squares(seq):
>>> return_sum_squares(range(10))
285
>>> sum([i*i for i in range(10000)])
>>> print(sum([i*i for i in range(10000)]))
333283335000
>>> return_sum_squares(range(10000))
>>> print(return_sum_squares(range(10000)))
333283335000
"""
return sum(i*i for i in seq)
......@@ -119,9 +119,9 @@ def return_sum_squares_start(seq, int start):
>>> return_sum_squares_start(range(10), -1)
284
>>> sum([i*i for i in range(10000)], 9)
>>> print(sum([i*i for i in range(10000)], 9))
333283335009
>>> return_sum_squares_start(range(10000), 9)
>>> print(return_sum_squares_start(range(10000), 9))
333283335009
"""
return sum((i*i for i in seq), start)
......@@ -140,9 +140,9 @@ def return_typed_sum_squares_start(seq, int start):
>>> return_typed_sum_squares_start(range(10), -1)
284
>>> sum([i*i for i in range(1000)], 9)
>>> print(sum([i*i for i in range(1000)], 9))
332833509
>>> return_typed_sum_squares_start(range(1000), 9)
>>> print(return_typed_sum_squares_start(range(1000), 9))
332833509
"""
cdef int i
......
cdef class A:
"""
>>> A.__init__.__doc__
'A.__init__ docstring'
>>> A.__len__.__doc__
'A.__len__ docstring'
>>> A.__add__.__doc__
'A.__add__ docstring'
"""
def __init__(self):
"A.__init__ docstring"
def __len__(self):
"A.__len__ docstring"
def __add__(self, other):
"A.__add__ docstring"
cdef class B(A):
"""
>>> B.__init__.__doc__
'A.__init__ docstring'
>>> B.__len__.__doc__
'B.__len__ docstring'
>>> B.__add__.__doc__
'A.__add__ docstring'
"""
def __len__(self):
"B.__len__ docstring"
class C(A):
"""
>>> C.__init__.__doc__
'A.__init__ docstring'
>>> C.__len__.__doc__
'C.__len__ docstring'
>>> C.__add__.__doc__
'A.__add__ docstring'
"""
def __len__(self):
"C.__len__ docstring"
......@@ -6,6 +6,11 @@
# To test this, we go through and verify that each affected special
# method works as a bound method.
# Special methods that are treated the same under Python 2 and 3 are
# tested here; see also special_methods_T561_py2.pyx and
# special_methods_T561_py3.pyx for tests of the differences between
# Python 2 and 3.
__doc__ = u"""
>>> vs0 = VerySpecial(0)
VS __init__ 0
......@@ -20,9 +25,6 @@ __doc__ = u"""
>>> vs0_mul = vs0.__mul__
>>> vs0_mul(vs1)
VS __mul__ 0 1
>>> vs0_div = vs0.__div__
>>> vs0_div(vs1)
VS __div__ 0 1
>>> vs0_mod = vs0.__mod__
>>> vs0_mod(vs1)
VS __mod__ 0 1
......@@ -43,10 +45,6 @@ __doc__ = u"""
>>> vs0_abs = vs0.__abs__
>>> vs0_abs()
VS __abs__ 0
>>> vs0_nonzero = vs0.__nonzero__
>>> vs0_nonzero()
VS __nonzero__ 0
False
>>> vs0_invert = vs0.__invert__
>>> vs0_invert()
VS __invert__ 0
......@@ -68,18 +66,9 @@ __doc__ = u"""
>>> vs0_int = vs0.__int__
>>> vs0_int()
VS __int__ 0
>>> vs0_long = vs0.__long__
>>> vs0_long()
VS __long__ 0
>>> vs0_float = vs0.__float__
>>> vs0_float()
VS __float__ 0
>>> vs0_oct = vs0.__oct__
>>> vs0_oct()
VS __oct__ 0
>>> vs0_hex = vs0.__hex__
>>> vs0_hex()
VS __hex__ 0
>>> vs0_iadd = vs0.__iadd__
>>> vs0_iadd(vs1)
VS __iadd__ 0 += 1
......@@ -89,9 +78,6 @@ __doc__ = u"""
>>> vs0_imul = vs0.__imul__
>>> vs0_imul(vs1)
VS __imul__ 0 *= 1
>>> vs0_idiv = vs0.__idiv__
>>> vs0_idiv(vs1)
VS __idiv__ 0 /= 1
>>> vs0_imod = vs0.__imod__
>>> vs0_imod(vs1)
VS __imod__ 0 %= 1
......@@ -136,9 +122,6 @@ __doc__ = u"""
>>> vs0_rmul = vs0.__rmul__
>>> vs0_rmul(vs1)
VS __mul__ 1 0
>>> vs0_rdiv = vs0.__rdiv__
>>> vs0_rdiv(vs1)
VS __div__ 1 0
>>> vs0_rmod = vs0.__rmod__
>>> vs0_rmod(vs1)
VS __mod__ 1 0
......@@ -175,33 +158,6 @@ __doc__ = u"""
>>> vs0_getitem = vs0.__getitem__
>>> vs0_getitem('foo')
VS __getitem__ 0['foo']
>>> vs0_getslice = vs0.__getslice__
>>> vs0_getslice(13, 42)
VS __getslice__ 0 13 42
>>> # If you define either setslice or delslice, you get wrapper objects
>>> # for both methods. (This behavior is unchanged by #561.)
>>> ss_setslice = SetSlice().__setslice__
>>> ss_setslice(13, 42, 'foo')
SetSlice setslice 13 42 'foo'
>>> ss_delslice = SetSlice().__delslice__
>>> ss_delslice(13, 42)
Traceback (most recent call last):
...
NotImplementedError: 2-element slice deletion not supported by special_methods_T561.SetSlice
>>> ds_setslice = DelSlice().__setslice__
>>> ds_setslice(13, 42, 'foo')
Traceback (most recent call last):
...
NotImplementedError: 2-element slice assignment not supported by special_methods_T561.DelSlice
>>> ds_delslice = DelSlice().__delslice__
>>> ds_delslice(13, 42)
DelSlice delslice 13 42
>>> sds_setslice = SetDelSlice().__setslice__
>>> sds_setslice(13, 42, 'foo')
SetDelSlice setslice 13 42 'foo'
>>> sds_delslice = SetDelSlice().__delslice__
>>> sds_delslice(13, 42)
SetDelSlice delslice 13 42
>>> vs0_contains = vs0.__contains__
>>> vs0_contains(vs1)
VS __contains__ 0 1
......@@ -234,10 +190,6 @@ __doc__ = u"""
>>> sdi_delitem = SetDelItem().__delitem__
>>> sdi_delitem('foo')
SetDelItem delitem 'foo'
>>> vs0_cmp = vs0.__cmp__
>>> vs0_cmp(vs1)
VS __cmp__ 0 1
0
>>> vs0_repr = vs0.__repr__
>>> vs0_repr()
VS __repr__ 0
......@@ -317,14 +269,9 @@ __doc__ = u"""
>>> vs0_iter = vs0.__iter__
>>> vs0_iter()
VS __iter__ 0
>>> # If you define __next__, you get both __next__ and next (this behavior
>>> # is unchanged by T561)
>>> vs0_next = vs0.__next__
>>> vs0_next()
VS next/__next__ 0
>>> vs0_next2 = vs0.next
>>> vs0_next2()
VS next/__next__ 0
>>> vs0_get = vs0.__get__
>>> vs0_get('instance', 'owner')
VS __get__ 0 'instance' 'owner'
......@@ -355,11 +302,8 @@ __doc__ = u"""
>>> vs0_init = vs0.__init__
>>> vs0_init(0)
VS __init__ 0
>>> # If you define __long__, you also get a wrapper object for __int__.
>>> # If you define __long__, you get a wrapper object for __int__.
>>> # (This behavior is unchanged by #561.)
>>> Ll = Long().__long__
>>> Ll()
Long __long__
>>> Li = Long().__int__
>>> Li()
Long __long__
......@@ -491,9 +435,6 @@ cdef class VerySpecial:
def __getitem__(self, index):
print "VS __getitem__ %d[%r]" % (self.value, index)
def __getslice__(self, a, b):
print "VS __getslice__ %d %d %d" % (self.value, a, b)
def __contains__(self, other):
print "VS __contains__ %d %d" % (self.value, other.value)
......@@ -528,21 +469,6 @@ cdef class VerySpecial:
def __get__(self, inst, own):
print "VS __get__ %d %r %r" % (self.value, inst, own)
cdef class SetSlice:
def __setslice__(self, a, b, value):
print "SetSlice setslice %d %d %r" % (a, b, value)
cdef class DelSlice:
def __delslice__(self, a, b):
print "DelSlice delslice %d %d" % (a, b)
cdef class SetDelSlice:
def __setslice__(self, a, b, value):
print "SetDelSlice setslice %d %d %r" % (a, b, value)
def __delslice__(self, a, b):
print "SetDelSlice delslice %d %d" % (a, b)
cdef class SetItem:
def __setitem__(self, index, value):
print "SetItem setitem %r %r" % (index, value)
......
# This file tests the behavior of special methods under Python 2
# after #561. (Only methods whose behavior differs between Python 2 and 3
# are tested here; see special_methods_T561.pyx for the rest of the tests.)
__doc__ = u"""
>>> vs0 = VerySpecial(0)
VS __init__ 0
>>> vs1 = VerySpecial(1)
VS __init__ 1
>>> # Python 3 does not use __cmp__.
>>> vs0_cmp = vs0.__cmp__
>>> vs0_cmp(vs1)
VS __cmp__ 0 1
0
>>> # Python 3 does not use __div__ or __idiv__.
>>> vs0_div = vs0.__div__
>>> vs0_div(vs1)
VS __div__ 0 1
>>> vs0_idiv = vs0.__idiv__
>>> vs0_idiv(vs1)
VS __idiv__ 0 /= 1
>>> vs0_rdiv = vs0.__rdiv__
>>> vs0_rdiv(vs1)
VS __div__ 1 0
>>> # Python 3 does not use __oct__ or __hex__.
>>> vs0_oct = vs0.__oct__
>>> vs0_oct()
VS __oct__ 0
>>> vs0_hex = vs0.__hex__
>>> vs0_hex()
VS __hex__ 0
>>> # Python 3 does not use __nonzero__; if you define a __nonzero__
>>> # method, Cython for Python 3 would give you a __bool__ method
>>> # instead.
>>> vs0_nonzero = vs0.__nonzero__
>>> vs0_nonzero()
VS __nonzero__ 0
False
>>> # If you define __next__, you get both __next__ and next (this behavior
>>> # is unchanged by T561, but only happens in Python 2)
>>> vs0_next = vs0.__next__
>>> vs0_next()
VS next/__next__ 0
>>> vs0_next2 = vs0.next
>>> vs0_next2()
VS next/__next__ 0
>>> # Cython supports getslice only for Python 2.
>>> vs0_getslice = vs0.__getslice__
>>> vs0_getslice(13, 42)
VS __getslice__ 0 13 42
>>> # Cython supports setslice and delslice only for Python 2.
>>> # If you define either setslice or delslice, you get wrapper objects
>>> # for both methods. (This behavior is unchanged by #561.)
>>> ss_setslice = SetSlice().__setslice__
>>> ss_setslice(13, 42, 'foo')
SetSlice setslice 13 42 'foo'
>>> ss_delslice = SetSlice().__delslice__
>>> ss_delslice(13, 42)
Traceback (most recent call last):
...
NotImplementedError: 2-element slice deletion not supported by special_methods_T561_py2.SetSlice
>>> ds_setslice = DelSlice().__setslice__
>>> ds_setslice(13, 42, 'foo')
Traceback (most recent call last):
...
NotImplementedError: 2-element slice assignment not supported by special_methods_T561_py2.DelSlice
>>> ds_delslice = DelSlice().__delslice__
>>> ds_delslice(13, 42)
DelSlice delslice 13 42
>>> sds_setslice = SetDelSlice().__setslice__
>>> sds_setslice(13, 42, 'foo')
SetDelSlice setslice 13 42 'foo'
>>> sds_delslice = SetDelSlice().__delslice__
>>> sds_delslice(13, 42)
SetDelSlice delslice 13 42
>>> # Python 3 does not use __long__.
>>> Ll = Long().__long__
>>> Ll()
Long __long__
"""
cdef class VerySpecial:
cdef readonly int value
def __init__(self, v):
self.value = v
print "VS __init__ %d" % self.value
def __getslice__(self, a, b):
print "VS __getslice__ %d %d %d" % (self.value, a, b)
def __next__(self):
print "VS next/__next__ %d" % self.value
def __nonzero__(self):
print "VS __nonzero__ %d" % self.value
def __oct__(self):
print "VS __oct__ %d" % self.value
def __hex__(self):
print "VS __hex__ %d" % self.value
def __cmp__(self, other):
print "VS __cmp__ %d %d" % (self.value, other.value)
def __div__(self, other):
print "VS __div__ %d %d" % (self.value, other.value)
def __idiv__(self, other):
print "VS __idiv__ %d /= %d" % (self.value, other.value)
cdef class SetSlice:
def __setslice__(self, a, b, value):
print "SetSlice setslice %d %d %r" % (a, b, value)
cdef class DelSlice:
def __delslice__(self, a, b):
print "DelSlice delslice %d %d" % (a, b)
cdef class SetDelSlice:
def __setslice__(self, a, b, value):
print "SetDelSlice setslice %d %d %r" % (a, b, value)
def __delslice__(self, a, b):
print "SetDelSlice delslice %d %d" % (a, b)
cdef class Long:
def __long__(self):
print "Long __long__"
# This file tests the behavior of special methods under Python 3
# after #561. (Only methods whose behavior differs between Python 2 and 3
# are tested here; see special_methods_T561.pyx for the rest of the tests.)
__doc__ = u"""
>>> vs0 = VerySpecial(0)
VS __init__ 0
>>> # Python 3 does not use __cmp__, so any provided __cmp__ method is
>>> # discarded under Python 3.
>>> vs0_cmp = vs0.__cmp__
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__cmp__'
>>> # Python 3 does not use __div__ or __idiv__, so these methods are
>>> # discarded under Python 3.
>>> vs0_div = vs0.__div__
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__div__'
>>> vs0_rdiv = vs0.__rdiv__
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__rdiv__'
>>> vs0_idiv = vs0.__idiv__
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__idiv__'
>>> # Python 3 does not use __oct__ or __hex__, so these methods are
>>> # discarded under Python 3.
>>> vs0_oct = vs0.__oct__
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__oct__'
>>> vs0_hex = vs0.__hex__
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__hex__'
>>> # Python 3 does not use __long__; if you define __long__ but not
>>> # __int__, the __long__ definition will be used for __int__.
>>> Ll = Long().__long__
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561_py3.Long' object has no attribute '__long__'
>>> Li = Long().__int__
>>> Li()
Long __long__
>>> # As of Python 3, defining __nonzero__ gives you a __bool__ method
>>> # instead.
>>> vs0_bool = vs0.__bool__
>>> vs0_bool()
VS __nonzero__ 0
False
"""
cdef class VerySpecial:
cdef readonly int value
def __init__(self, v):
self.value = v
print "VS __init__ %d" % self.value
def __nonzero__(self):
print "VS __nonzero__ %d" % self.value
def __oct__(self):
print "VS __oct__ %d" % self.value
def __hex__(self):
print "VS __hex__ %d" % self.value
def __cmp__(self, other):
print "VS __cmp__ %d %d" % (self.value, other.value)
def __div__(self, other):
print "VS __div__ %d %d" % (self.value, other.value)
def __idiv__(self, other):
print "VS __idiv__ %d /= %d" % (self.value, other.value)
cdef class Long:
def __long__(self):
print "Long __long__"
# The patch in #561 changes code generation for most special methods
# to remove the Cython-generated wrapper and let PyType_Ready()
# generate its own wrapper. (This wrapper would be used, for instance,
# when using the special method as a bound method.)
# To test this, we go through and verify that each affected special
# method works as a bound method.
__doc__ = u"""
>>> vs0 = VerySpecial(0)
VS __init__ 0
>>> vs1 = VerySpecial(1)
VS __init__ 1
>>> vs0_add = vs0.__add__
>>> vs0_add(vs1)
VS __add__ 0 1
>>> vs0_sub = vs0.__sub__
>>> vs0_sub(vs1)
VS __sub__ 0 1
>>> vs0_mul = vs0.__mul__
>>> vs0_mul(vs1)
VS __mul__ 0 1
>>> vs0_div = vs0.__div__
>>> vs0_div(vs1)
VS __div__ 0 1
>>> vs0_mod = vs0.__mod__
>>> vs0_mod(vs1)
VS __mod__ 0 1
>>> vs0_divmod = vs0.__divmod__
>>> vs0_divmod(vs1)
VS __divmod__ 0 1
>>> vs0_pow = vs0.__pow__
>>> vs0_pow(vs1)
VS __pow__ pow(0, 1, None)
>>> vs0_pow(vs1, 13)
VS __pow__ pow(0, 1, 13)
>>> vs0_neg = vs0.__neg__
>>> vs0_neg()
VS __neg__ 0
>>> vs0_pos = vs0.__pos__
>>> vs0_pos()
VS __pos__ 0
>>> vs0_abs = vs0.__abs__
>>> vs0_abs()
VS __abs__ 0
>>> vs0_nonzero = vs0.__nonzero__
>>> vs0_nonzero()
VS __nonzero__ 0
False
>>> vs0_invert = vs0.__invert__
>>> vs0_invert()
VS __invert__ 0
>>> vs0_lshift = vs0.__lshift__
>>> vs0_lshift(vs1)
VS __lshift__ 0 << 1
>>> vs0_rshift = vs0.__rshift__
>>> vs0_rshift(vs1)
VS __rshift__ 0 >> 1
>>> vs0_and = vs0.__and__
>>> vs0_and(vs1)
VS __and__ 0 & 1
>>> vs0_xor = vs0.__xor__
>>> vs0_xor(vs1)
VS __xor__ 0 ^ 1
>>> vs0_or = vs0.__or__
>>> vs0_or(vs1)
VS __or__ 0 | 1
>>> vs0_int = vs0.__int__
>>> vs0_int()
VS __int__ 0
>>> vs0_long = vs0.__long__
>>> vs0_long()
VS __long__ 0
>>> vs0_float = vs0.__float__
>>> vs0_float()
VS __float__ 0
>>> vs0_oct = vs0.__oct__
>>> vs0_oct()
VS __oct__ 0
>>> vs0_hex = vs0.__hex__
>>> vs0_hex()
VS __hex__ 0
>>> vs0_iadd = vs0.__iadd__
>>> vs0_iadd(vs1)
VS __iadd__ 0 += 1
>>> vs0_isub = vs0.__isub__
>>> vs0_isub(vs1)
VS __isub__ 0 -= 1
>>> vs0_imul = vs0.__imul__
>>> vs0_imul(vs1)
VS __imul__ 0 *= 1
>>> vs0_idiv = vs0.__idiv__
>>> vs0_idiv(vs1)
VS __idiv__ 0 /= 1
>>> vs0_imod = vs0.__imod__
>>> vs0_imod(vs1)
VS __imod__ 0 %= 1
>>> vs0_ipow = vs0.__ipow__
>>> vs0_ipow(vs1)
VS __ipow__ 0 1
>>> vs0_ilshift = vs0.__ilshift__
>>> vs0_ilshift(vs1)
VS __ilshift__ 0 <<= 1
>>> vs0_irshift = vs0.__irshift__
>>> vs0_irshift(vs1)
VS __irshift__ 0 >>= 1
>>> vs0_iand = vs0.__iand__
>>> vs0_iand(vs1)
VS __iand__ 0 &= 1
>>> vs0_ixor = vs0.__ixor__
>>> vs0_ixor(vs1)
VS __ixor__ 0 ^= 1
>>> vs0_ior = vs0.__ior__
>>> vs0_ior(vs1)
VS __ior__ 0 |= 1
>>> vs0_floordiv = vs0.__floordiv__
>>> vs0_floordiv(vs1)
VS __floordiv__ 0 / 1
>>> vs0_truediv = vs0.__truediv__
>>> vs0_truediv(vs1)
VS __truediv__ 0 / 1
>>> vs0_ifloordiv = vs0.__ifloordiv__
>>> vs0_ifloordiv(vs1)
VS __ifloordiv__ 0 /= 1
>>> vs0_itruediv = vs0.__itruediv__
>>> vs0_itruediv(vs1)
VS __itruediv__ 0 /= 1
>>> # If you define an arithmetic method, you get wrapper objects for
>>> # the reversed version as well. (This behavior is unchanged by #561.)
>>> vs0_radd = vs0.__radd__
>>> vs0_radd(vs1)
VS __add__ 1 0
>>> vs0_rsub = vs0.__rsub__
>>> vs0_rsub(vs1)
VS __sub__ 1 0
>>> vs0_rmul = vs0.__rmul__
>>> vs0_rmul(vs1)
VS __mul__ 1 0
>>> vs0_rdiv = vs0.__rdiv__
>>> vs0_rdiv(vs1)
VS __div__ 1 0
>>> vs0_rmod = vs0.__rmod__
>>> vs0_rmod(vs1)
VS __mod__ 1 0
>>> vs0_rdivmod = vs0.__rdivmod__
>>> vs0_rdivmod(vs1)
VS __divmod__ 1 0
>>> vs0_rpow = vs0.__rpow__
>>> vs0_rpow(vs1)
VS __pow__ pow(1, 0, None)
>>> vs0_rlshift = vs0.__rlshift__
>>> vs0_rlshift(vs1)
VS __lshift__ 1 << 0
>>> vs0_rrshift = vs0.__rrshift__
>>> vs0_rrshift(vs1)
VS __rshift__ 1 >> 0
>>> vs0_rand = vs0.__rand__
>>> vs0_rand(vs1)
VS __and__ 1 & 0
>>> vs0_rxor = vs0.__rxor__
>>> vs0_rxor(vs1)
VS __xor__ 1 ^ 0
>>> vs0_ror = vs0.__ror__
>>> vs0_ror(vs1)
VS __or__ 1 | 0
>>> vs0_rfloordiv = vs0.__rfloordiv__
>>> vs0_rfloordiv(vs1)
VS __floordiv__ 1 / 0
>>> vs0_rtruediv = vs0.__rtruediv__
>>> vs0_rtruediv(vs1)
VS __truediv__ 1 / 0
>>> vs0_index = vs0.__index__
>>> vs0_index()
VS __index__ 0
>>> vs0_getitem = vs0.__getitem__
>>> vs0_getitem('foo')
VS __getitem__ 0['foo']
>>> vs0_getslice = vs0.__getslice__
>>> vs0_getslice(13, 42)
VS __getslice__ 0 13 42
>>> # If you define either setslice or delslice, you get wrapper objects
>>> # for both methods. (This behavior is unchanged by #561.)
>>> ss_setslice = SetSlice().__setslice__
>>> ss_setslice(13, 42, 'foo')
SetSlice setslice 13 42 'foo'
>>> ss_delslice = SetSlice().__delslice__
>>> ss_delslice(13, 42)
Traceback (most recent call last):
...
NotImplementedError: 2-element slice deletion not supported by special_methods_T561.SetSlice
>>> ds_setslice = DelSlice().__setslice__
>>> ds_setslice(13, 42, 'foo')
Traceback (most recent call last):
...
NotImplementedError: 2-element slice assignment not supported by special_methods_T561.DelSlice
>>> ds_delslice = DelSlice().__delslice__
>>> ds_delslice(13, 42)
DelSlice delslice 13 42
>>> sds_setslice = SetDelSlice().__setslice__
>>> sds_setslice(13, 42, 'foo')
SetDelSlice setslice 13 42 'foo'
>>> sds_delslice = SetDelSlice().__delslice__
>>> sds_delslice(13, 42)
SetDelSlice delslice 13 42
>>> vs0_contains = vs0.__contains__
>>> vs0_contains(vs1)
VS __contains__ 0 1
False
>>> vs0_len = vs0.__len__
>>> vs0_len()
VS __len__ 0
0
>>> # If you define either setitem or delitem, you get wrapper objects
>>> # for both methods. (This behavior is unchanged by #561.)
>>> si_setitem = SetItem().__setitem__
>>> si_setitem('foo', 'bar')
SetItem setitem 'foo' 'bar'
>>> si_delitem = SetItem().__delitem__
>>> si_delitem('foo')
Traceback (most recent call last):
...
NotImplementedError: Subscript deletion not supported by special_methods_T561.SetItem
>>> di_setitem = DelItem().__setitem__
>>> di_setitem('foo', 'bar')
Traceback (most recent call last):
...
NotImplementedError: Subscript assignment not supported by special_methods_T561.DelItem
>>> di_delitem = DelItem().__delitem__
>>> di_delitem('foo')
DelItem delitem 'foo'
>>> sdi_setitem = SetDelItem().__setitem__
>>> sdi_setitem('foo', 'bar')
SetDelItem setitem 'foo' 'bar'
>>> sdi_delitem = SetDelItem().__delitem__
>>> sdi_delitem('foo')
SetDelItem delitem 'foo'
>>> vs0_cmp = vs0.__cmp__
>>> vs0_cmp(vs1)
VS __cmp__ 0 1
0
>>> vs0_repr = vs0.__repr__
>>> vs0_repr()
VS __repr__ 0
>>> vs0_hash = vs0.__hash__
>>> vs0_hash()
VS __hash__ 0
1000
>>> vs0_call = vs0.__call__
>>> vs0_call(vs1)
VS __call__ 0(1)
>>> vs0_str = vs0.__str__
>>> vs0_str()
VS __str__ 0
>>> # If you define either a __getattr__ or a __getattribute__, you get
>>> # only a __getattribute__ method. (Without #561, defining __getattr__
>>> # would give you both __getattr__ and __getattribute__.)
>>> g00 = object.__getattribute__(GetAttr(), '__getattr__')
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561.GetAttr' object has no attribute '__getattr__'
>>> g01 = object.__getattribute__(GetAttr(), '__getattribute__')
>>> g01('attr')
GetAttr getattr 'attr'
>>> g10 = object.__getattribute__(GetAttribute(), '__getattr__')
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561.GetAttribute' object has no attribute '__getattr__'
>>> g11 = object.__getattribute__(GetAttribute(), '__getattribute__')
>>> g11('attr')
GetAttribute getattribute 'attr'
>>> # If you define either setattr or delattr, you get wrapper objects
>>> # for both methods. (This behavior is unchanged by #561.)
>>> sa_setattr = SetAttr().__setattr__
>>> sa_setattr('foo', 'bar')
SetAttr setattr 'foo' 'bar'
>>> sa_delattr = SetAttr().__delattr__
>>> sa_delattr('foo')
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561.SetAttr' object has no attribute 'foo'
>>> da_setattr = DelAttr().__setattr__
>>> da_setattr('foo', 'bar')
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561.DelAttr' object has no attribute 'foo'
>>> da_delattr = DelAttr().__delattr__
>>> da_delattr('foo')
DelAttr delattr 'foo'
>>> sda_setattr = SetDelAttr().__setattr__
>>> sda_setattr('foo', 'bar')
SetDelAttr setattr 'foo' 'bar'
>>> sda_delattr = SetDelAttr().__delattr__
>>> sda_delattr('foo')
SetDelAttr delattr 'foo'
>>> # If you define __richcmp__, you get all of __lt__, __le__,
>>> # __eq__, __ne__, __gt__, __ge__ (this behavior is unchanged by #561).
>>> # (you don't get a __richcmp__ method, because it doesn't have a
>>> # Python signature)
>>> vs0_lt = vs0.__lt__
>>> vs0_lt(vs1)
VS richcmp 0 1 (kind=0)
>>> vs0_le = vs0.__le__
>>> vs0_le(vs1)
VS richcmp 0 1 (kind=1)
>>> vs0_eq = vs0.__eq__
>>> vs0_eq(vs1)
VS richcmp 0 1 (kind=2)
>>> vs0_ne = vs0.__ne__
>>> vs0_ne(vs1)
VS richcmp 0 1 (kind=3)
>>> vs0_gt = vs0.__gt__
>>> vs0_gt(vs1)
VS richcmp 0 1 (kind=4)
>>> vs0_ge = vs0.__ge__
>>> vs0_ge(vs1)
VS richcmp 0 1 (kind=5)
>>> vs0_iter = vs0.__iter__
>>> vs0_iter()
VS __iter__ 0
>>> # If you define __next__, you get both __next__ and next (this behavior
>>> # is unchanged by T561)
>>> vs0_next = vs0.__next__
>>> vs0_next()
VS next/__next__ 0
>>> vs0_next2 = vs0.next
>>> vs0_next2()
VS next/__next__ 0
>>> vs0_get = vs0.__get__
>>> vs0_get('instance', 'owner')
VS __get__ 0 'instance' 'owner'
>>> # If you define either set or delete, you get wrapper objects
>>> # for both methods. (This behavior is unchanged by #561.)
>>> s_set = Set().__set__
>>> s_set('instance', 'val')
Set set 'instance' 'val'
>>> s_delete = Set().__delete__
>>> s_delete('instance')
Traceback (most recent call last):
...
NotImplementedError: __delete__
>>> d_set = Delete().__set__
>>> d_set('instance', 'val')
Traceback (most recent call last):
...
NotImplementedError: __set__
>>> d_delete = Delete().__delete__
>>> d_delete('instance')
Delete delete 'instance'
>>> sd_set = SetDelete().__set__
>>> sd_set('instance', 'val')
SetDelete set 'instance' 'val'
>>> sd_delete = SetDelete().__delete__
>>> sd_delete('instance')
SetDelete delete 'instance'
>>> vs0_init = vs0.__init__
>>> vs0_init(0)
VS __init__ 0
>>> # If you define __long__, you also get a wrapper object for __int__.
>>> # (This behavior is unchanged by #561.)
>>> Ll = Long().__long__
>>> Ll()
Long __long__
>>> Li = Long().__int__
>>> Li()
Long __long__
"""
cdef class VerySpecial:
cdef readonly int value
def __init__(self, v):
"__init__"
self.value = v
print "VS __init__ %d" % self.value
def __add__(self, other):
"__add__"
print "VS __add__ %d %d" % (self.value, other.value)
def __sub__(self, other):
"__sub__"
print "VS __sub__ %d %d" % (self.value, other.value)
def __mul__(self, other):
"__mul__"
print "VS __mul__ %d %d" % (self.value, other.value)
def __div__(self, other):
"__div__"
print "VS __div__ %d %d" % (self.value, other.value)
def __mod__(self, other):
"__mod__"
print "VS __mod__ %d %d" % (self.value, other.value)
def __divmod__(self, other):
"__divmod__"
print "VS __divmod__ %d %d" % (self.value, other.value)
def __pow__(self, other, mod):
"__pow__"
print "VS __pow__ pow(%d, %d, %r)" % (self.value, other.value, mod)
def __lshift__(self, other):
"__lshift__"
print "VS __lshift__ %d << %d" % (self.value, other.value)
def __rshift__(self, other):
"__rshift__"
print "VS __rshift__ %d >> %d" % (self.value, other.value)
def __and__(self, other):
"__and__"
print "VS __and__ %d & %d" % (self.value, other.value)
def __xor__(self, other):
"__xor__"
print "VS __xor__ %d ^ %d" % (self.value, other.value)
def __or__(self, other):
"__or__"
print "VS __or__ %d | %d" % (self.value, other.value)
def __floordiv__(self, other):
"__floordiv__"
print "VS __floordiv__ %d / %d" % (self.value, other.value)
def __truediv__(self, other):
"__truediv__"
print "VS __truediv__ %d / %d" % (self.value, other.value)
def __neg__(self):
"__neg__"
print "VS __neg__ %d" % self.value
def __pos__(self):
"__pos__"
print "VS __pos__ %d" % self.value
def __abs__(self):
"__abs__"
print "VS __abs__ %d" % self.value
def __nonzero__(self):
"__nonzero__"
print "VS __nonzero__ %d" % self.value
def __invert__(self):
"__invert__"
print "VS __invert__ %d" % self.value
def __int__(self):
"__int__"
print "VS __int__ %d" % self.value
def __long__(self):
"__long__"
print "VS __long__ %d" % self.value
def __float__(self):
"__float__"
print "VS __float__ %d" % self.value
def __oct__(self):
"__oct__"
print "VS __oct__ %d" % self.value
def __hex__(self):
"__hex__"
print "VS __hex__ %d" % self.value
def __iadd__(self, other):
"__iadd__"
print "VS __iadd__ %d += %d" % (self.value, other.value)
def __isub__(self, other):
"__isub__"
print "VS __isub__ %d -= %d" % (self.value, other.value)
def __imul__(self, other):
"__imul__"
print "VS __imul__ %d *= %d" % (self.value, other.value)
def __idiv__(self, other):
"__idiv__"
print "VS __idiv__ %d /= %d" % (self.value, other.value)
def __imod__(self, other):
"__imod__"
print "VS __imod__ %d %%= %d" % (self.value, other.value)
def __ipow__(self, other, mod):
"__ipow__"
# We must declare mod as an argument, but we must not touch it
# or we'll get a segfault. See #562
print "VS __ipow__ %d %d" % (self.value, other.value)
def __ilshift__(self, other):
"__ilshift__"
print "VS __ilshift__ %d <<= %d" % (self.value, other.value)
def __irshift__(self, other):
"__irshift__"
print "VS __irshift__ %d >>= %d" % (self.value, other.value)
def __iand__(self, other):
"__iand__"
print "VS __iand__ %d &= %d" % (self.value, other.value)
def __ixor__(self, other):
"__ixor__"
print "VS __ixor__ %d ^= %d" % (self.value, other.value)
def __ior__(self, other):
"__ior__"
print "VS __ior__ %d |= %d" % (self.value, other.value)
def __ifloordiv__(self, other):
"__ifloordiv__"
print "VS __ifloordiv__ %d /= %d" % (self.value, other.value)
def __itruediv__(self, other):
"__itruediv__"
print "VS __itruediv__ %d /= %d" % (self.value, other.value)
def __index__(self):
"__index__"
print "VS __index__ %d" % self.value
def __getitem__(self, index):
"__getitem__"
print "VS __getitem__ %d[%r]" % (self.value, index)
def __getslice__(self, a, b):
"__getslice__"
print "VS __getslice__ %d %d %d" % (self.value, a, b)
def __contains__(self, other):
"__contains__"
print "VS __contains__ %d %d" % (self.value, other.value)
def __len__(self):
"__len__"
print "VS __len__ %d" % (self.value)
def __cmp__(self, other):
"__cmp__"
print "VS __cmp__ %d %d" % (self.value, other.value)
def __repr__(self):
"__repr__"
print "VS __repr__ %d" % self.value
def __hash__(self):
"__hash__"
print "VS __hash__ %d" % self.value
return self.value + 1000
def __call__(self, other):
"__call__"
print "VS __call__ %d(%d)" % (self.value, other.value)
def __str__(self):
"__str__"
print "VS __str__ %d" % self.value
def __richcmp__(self, other, kind):
"__richcmp__"
print "VS richcmp %d %d (kind=%r)" % (self.value, other.value, kind)
def __iter__(self):
"__iter__"
print "VS __iter__ %d" % self.value
def __next__(self):
"__next__"
print "VS next/__next__ %d" % self.value
def __get__(self, inst, own):
print "VS __get__ %d %r %r" % (self.value, inst, own)
cdef class SetSlice:
def __setslice__(self, a, b, value):
"__setslice__"
print "SetSlice setslice %d %d %r" % (a, b, value)
cdef class DelSlice:
def __delslice__(self, a, b):
"__delslice__"
print "DelSlice delslice %d %d" % (a, b)
cdef class SetDelSlice:
def __setslice__(self, a, b, value):
"__setslice__"
print "SetDelSlice setslice %d %d %r" % (a, b, value)
def __delslice__(self, a, b):
"__delslice__"
print "SetDelSlice delslice %d %d" % (a, b)
cdef class GetAttr:
def __getattr__(self, attr):
"__getattr__"
print "GetAttr getattr %r" % attr
cdef class GetAttribute:
def __getattribute__(self, attr):
"__getattribute__"
print "GetAttribute getattribute %r" % attr
cdef class SetAttr:
def __setattr__(self, attr, val):
"__setattr__"
print "SetAttr setattr %r %r" % (attr, val)
cdef class DelAttr:
def __delattr__(self, attr):
"__delattr__"
print "DelAttr delattr %r" % attr
cdef class SetDelAttr:
def __setattr__(self, attr, val):
"__setattr__"
print "SetDelAttr setattr %r %r" % (attr, val)
def __delattr__(self, attr):
"__delattr__"
print "SetDelAttr delattr %r" % attr
cdef class Set:
def __set__(self, inst, val):
"__set__"
print "Set set %r %r" % (inst, val)
cdef class Delete:
def __delete__(self, inst):
"__delete__"
print "Delete delete %r" % inst
cdef class SetDelete:
def __set__(self, inst, val):
"__set__"
print "SetDelete set %r %r" % (inst, val)
def __delete__(self, inst):
"__delete__"
print "SetDelete delete %r" % inst
cdef class Long:
def __long__(self):
"__long__"
print "Long __long__"
......@@ -7,8 +7,6 @@ __doc__ = u"""
2
>>> print( "%d" % IntLongB() )
2
>>> print( "%d" % IntLongC() )
3
"""
......@@ -23,8 +21,6 @@ def getint(int i):
2
>>> getint( IntLongB() )
2
>>> getint( IntLongC() )
3
"""
return i
......@@ -38,8 +34,6 @@ def getlong(long long i):
2
>>> getlong( IntLongB() )
2
>>> getlong( IntLongC() )
3
"""
return <int>i
......@@ -62,8 +56,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