# ticket: 808
cimport cython
cdef class MyType:
cdef public args, kwargs
def __cinit__(self, *args, **kwargs):
self.args, self.kwargs = args, kwargs
print "CINIT"
def __init__(self, *args, **kwargs):
print "INIT"
cdef class MySubType(MyType):
def __cinit__(self, *args, **kwargs):
self.args, self.kwargs = args, kwargs
print "CINIT(SUB)"
def __init__(self, *args, **kwargs):
print "INIT"
class MyClass(object):
def __cinit__(self, *args, **kwargs):
self.args, self.kwargs = args, kwargs
print "CINIT"
def __init__(self, *args, **kwargs):
print "INIT"
class MyTypeSubClass(MyType):
def __cinit__(self, *args, **kwargs):
# not called: Python class!
print "CINIT(PYSUB)"
def __init__(self, *args, **kwargs):
print "INIT"
# See ticket T808, vtab must be set even if there is no __cinit__.
cdef class Base(object):
pass
cdef class Derived(Base):
cpdef int f(self):
return 42
def test_derived_vtab():
"""
>>> test_derived_vtab()
42
"""
cdef Derived d = Derived.__new__(Derived)
return d.f()
# only these can be safely optimised:
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists(
'//SimpleCallNode/AttributeNode',
'//PyMethodCallNode',
)
def make_new():
"""
>>> isinstance(make_new(), MyType)
CINIT
True
"""
m = MyType.__new__(MyType)
return m
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists(
'//SimpleCallNode/AttributeNode',
'//PyMethodCallNode',
)
def make_new_typed_target():
"""
>>> isinstance(make_new_typed_target(), MyType)
CINIT
True
"""
cdef MyType m
m = MyType.__new__(MyType)
return m
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists(
'//SimpleCallNode/AttributeNode',
'//PyMethodCallNode',
)
def make_new_with_args():
"""
>>> isinstance(make_new_with_args(), MyType)
CINIT
(1, 2, 3)
{}
True
"""
m = MyType.__new__(MyType, 1, 2 ,3)
print m.args
print m.kwargs
return m
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists(
'//SimpleCallNode/AttributeNode',
'//PyMethodCallNode',
)
def make_new_with_args_kwargs():
"""
>>> isinstance(make_new_with_args_kwargs(), MyType)
CINIT
(1, 2, 3)
{'a': 4}
True
"""
m = MyType.__new__(MyType, 1, 2 ,3, a=4)
print m.args
print m.kwargs
return m
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists(
'//SimpleCallNode/AttributeNode',
'//PyMethodCallNode',
)
def make_new_builtin():
"""
>>> isinstance(make_new_builtin(), tuple)
True
"""
m = dict.__new__(dict)
m = list.__new__(list)
m = tuple.__new__(tuple)
return m
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists(
'//SimpleCallNode/AttributeNode',
'//PyMethodCallNode',
)
def make_new_none(type t=None):
"""
>>> make_new_none() # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ... is not a type object (NoneType)
"""
m = t.__new__(t)
return m
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists(
'//SimpleCallNode/AttributeNode',
'//PyMethodCallNode',
)
def make_new_kwargs(type t=None):
"""
>>> m = make_new_kwargs(MyType)
CINIT
>>> isinstance(m, MyType)
True
>>> m.args
(1, 2, 3)
>>> m.kwargs
{'a': 5}
"""
m = t.__new__(t, 1, 2, 3, a=5)
return m
# these cannot:
@cython.test_assert_path_exists('//PyMethodCallNode/AttributeNode')
@cython.test_fail_if_path_exists('//PythonCapiCallNode')
def make_new_pyclass():
"""
>>> isinstance(make_new_pyclass(), MyTypeSubClass)
CINIT
True
"""
m = MyClass.__new__(MyClass)
m = MyTypeSubClass.__new__(MyTypeSubClass)
return m
@cython.test_assert_path_exists('//PyMethodCallNode/AttributeNode')
@cython.test_fail_if_path_exists('//PythonCapiCallNode')
def make_new_args(type t1=None, type t2=None):
"""
>>> isinstance(make_new_args(), MyType)
CINIT
True
>>> isinstance(make_new_args(MyType), MyType)
CINIT
True
>>> isinstance(make_new_args(MyType, MyType), MyType)
CINIT
True
>>> isinstance(make_new_args(MyType, MySubType), MySubType)
Traceback (most recent call last):
TypeError: tp_new.MyType.__new__(tp_new.MySubType) is not safe, use tp_new.MySubType.__new__()
>>> isinstance(make_new_args(MySubType, MyType), MyType)
Traceback (most recent call last):
TypeError: tp_new.MySubType.__new__(tp_new.MyType): tp_new.MyType is not a subtype of tp_new.MySubType
"""
if t1 is None:
t1 = MyType
if t2 is None:
t2 = MyType
m = t1.__new__(t2)
return m
@cython.test_assert_path_exists('//PyMethodCallNode/AttributeNode')
@cython.test_fail_if_path_exists('//PythonCapiCallNode')
def make_new_none_typed(tuple t=None):
"""
>>> make_new_none_typed() # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ... is not a type object (NoneType)
"""
m = t.__new__(t)
return m
@cython.test_assert_path_exists('//PyMethodCallNode/AttributeNode')
@cython.test_fail_if_path_exists('//PythonCapiCallNode')
def make_new_untyped(t):
"""
>>> make_new_untyped(None) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ... is not a type object (NoneType)
"""
m = t.__new__(t)
return m