From 3ba1ec9433b7926c57def1d449d532c74487c60c Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 13 Aug 2010 14:13:42 +0200 Subject: [PATCH] new test case for doctests in special methods --HG-- rename : tests/run/special_methods_T561.pyx => tests/run/special_methods_doctests_T561.pyx --- tests/run/special_methods_doctests_T561.pyx | 652 ++++++++++++++++++++ 1 file changed, 652 insertions(+) create mode 100644 tests/run/special_methods_doctests_T561.pyx diff --git a/tests/run/special_methods_doctests_T561.pyx b/tests/run/special_methods_doctests_T561.pyx new file mode 100644 index 00000000..4b93fd38 --- /dev/null +++ b/tests/run/special_methods_doctests_T561.pyx @@ -0,0 +1,652 @@ +# 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__" -- 2.26.2