4
Test Python def functions without extern types
7
cy = __import__("cython")
11
int __Pyx_CyFunction_Check(object)
13
cdef class Base(object):
15
return type(self).__name__
18
cdef class ExtClassA(Base):
21
cdef class ExtClassB(Base):
31
ctypedef fused fused_t:
41
ctypedef ExtClassA xxxlast
42
ctypedef ExtClassB aaafirst
45
ctypedef fused fused_with_object:
57
def opt_func(fused_t obj, cython.floating myf = 1.2, cython.integral myi = 7,
58
another_opt = 2, yet_another_opt=3):
60
Test runtime dispatch, indexing of various kinds and optional arguments.
61
Use 5 arguments because at one point the optional argument from the
62
5th argument was overwriting that of the __pyx_fused dispatcher.
63
https://github.com/cython/cython/issues/3511
65
>>> opt_func("spam", f, i)
66
str object double long
68
>>> opt_func("spam", f, myi=i)
69
str object double long
71
>>> opt_func("spam", myf=f, myi=i)
72
str object double long
74
>>> opt_func[str, float, int]("spam", f, i)
77
>>> opt_func[str, cy.double, cy.long]("spam", f, i)
78
str object double long
80
>>> opt_func[str, cy.double, cy.long]("spam", f, myi=i)
81
str object double long
83
>>> opt_func[str, float, cy.int]("spam", f, i)
88
>>> opt_func(ExtClassA(), f, i)
90
ExtClassA 5.60 9 5.60 9
91
>>> opt_func[ExtClassA, float, int](ExtClassA(), f, i)
93
ExtClassA 5.60 9 5.60 9
94
>>> opt_func[ExtClassA, cy.double, cy.long](ExtClassA(), f, i)
96
ExtClassA 5.60 9 5.60 9
98
>>> opt_func(ExtClassB(), f, i)
100
ExtClassB 5.60 9 5.60 9
101
>>> opt_func[ExtClassB, cy.double, cy.long](ExtClassB(), f, i)
102
ExtClassB double long
103
ExtClassB 5.60 9 5.60 9
108
>>> opt_func[int, float, int](10, f)
112
>>> opt_func(10 + 2j, myf = 2.6)
113
double complex double long
114
(10+2j) 2.60 7 5.60 9
115
>>> opt_func[cy.py_complex, float, int](10 + 2j, myf = 2.6)
116
double complex float int
117
(10+2j) 2.60 7 5.60 9
118
>>> opt_func[cy.doublecomplex, cy.float, cy.int](10 + 2j, myf = 2.6)
119
double complex float int
120
(10+2j) 2.60 7 5.60 9
122
>>> opt_func(object(), f)
123
Traceback (most recent call last):
124
TypeError: Function call with ambiguous argument types
126
Traceback (most recent call last):
127
TypeError: Expected at least 1 argument, got 0
128
>>> opt_func("abc", f, i, 5, 5, 5) # doctest: +ELLIPSIS
129
Traceback (most recent call last):
130
TypeError: ...at most 5...
131
>>> opt_func[ExtClassA, cy.float, cy.long](object(), f)
132
Traceback (most recent call last):
133
TypeError: Argument 'obj' has incorrect type (expected fused_def.ExtClassA, got object)
135
print cython.typeof(obj), cython.typeof(myf), cython.typeof(myi)
136
print obj, "%.2f" % myf, myi, "%.2f" % f, i
138
def non_fused_opt(fused_t obj, value=5):
140
PyObject constants as parts of fused functions weren't being created correctly
141
which would lead this to crash
144
>>> non_fused_opt("str", 10)
149
def run_cyfunction_check():
151
tp_base of the fused function was being set incorrectly meaning
152
it wasn't being identified as a CyFunction
153
>>> run_cyfunction_check()
154
fused_cython_function
157
print(type(opt_func).__name__.rsplit('.', 1)[-1])
158
print(__Pyx_CyFunction_Check(opt_func)) # should be True
163
str object double long
166
opt_func("ham", f, entry4)
169
def test_opt_func_introspection():
171
>>> opt_func.__defaults__
173
>>> opt_func.__kwdefaults__
174
>>> opt_func.__annotations__
177
>>> opt_func[str, float, int].__defaults__
179
>>> opt_func[str, float, int].__kwdefaults__
180
>>> opt_func[str, float, int].__annotations__
183
>>> opt_func[str, cy.double, cy.long].__defaults__
185
>>> opt_func[str, cy.double, cy.long].__kwdefaults__
186
>>> opt_func[str, cy.double, cy.long].__annotations__
191
def func_with_object(fused_with_object obj, cython.integral myi = 7):
193
>>> func_with_object(1)
196
>>> func_with_object(1, 3)
199
>>> func_with_object['int', 'int'](1, 3)
202
>>> func_with_object(1j, 3)
205
>>> func_with_object('abc', 3)
208
>>> func_with_object(ExtClassA(), 3)
211
>>> func_with_object(ExtClassB(), 3)
214
>>> func_with_object['object', 'long'](ExtClassA(), 3)
217
>>> func_with_object['object', 'long'](ExtClassB(), 3)
221
print cython.typeof(obj), cython.typeof(myi)
226
def args_kwargs(fused_t obj, cython.floating myf = 1.2, *args, **kwargs):
228
>>> args_kwargs("foo")
232
>>> args_kwargs("eggs", f, 1, 2, [], d={})
234
eggs 5.60 5.60 (1, 2, []) {'d': {}}
236
>>> args_kwargs[str, float]("eggs", f, 1, 2, [], d={})
238
eggs 5.60 5.60 (1, 2, []) {'d': {}}
241
print cython.typeof(obj), cython.typeof(myf)
242
print obj, "%.2f" % myf, "%.2f" % f, args, kwargs
245
class BaseClass(object):
247
Test fused class/static/normal methods and super() without args
251
def mystaticmethod(cython.integral arg1):
252
print cython.typeof(arg1), arg1
255
def myclassmethod(cls, cython.integral arg1):
256
print cls, cython.typeof(arg1), arg1
258
def normalmethod(self, cython.integral arg1):
259
print self, cython.typeof(arg1), arg1
262
return "<%s.%s object>" % (__name__, type(self).__name__)
264
class SubClass(BaseClass):
267
def mystaticmethod(self, cython.integral arg1):
268
print cython.typeof(arg1), arg1
269
super().mystaticmethod(arg1 + 1)
272
def myclassmethod(cls, cython.integral arg1):
273
print cls, cython.typeof(arg1), arg1
274
super().myclassmethod(arg1 + 1)
276
def normalmethod(self, cython.integral arg1):
277
print self, cython.typeof(arg1), arg1
278
super().normalmethod(arg1 + 1)
280
class SubSubClass(SubClass):
283
def test_fused_def_super():
285
>>> test_fused_def_super()
294
<class 'fused_def.SubClass'> long 14
295
<class 'fused_def.SubClass'> long 15
296
<class 'fused_def.SubClass'> long 15
297
<class 'fused_def.SubClass'> long 16
298
<class 'fused_def.SubClass'> short 16
299
<class 'fused_def.SubClass'> long 17
300
<class 'fused_def.SubClass'> short 17
301
<class 'fused_def.SubClass'> long 18
302
<fused_def.SubClass object> long 18
303
<fused_def.SubClass object> long 19
304
<fused_def.SubClass object> long 19
305
<fused_def.SubClass object> long 20
306
<fused_def.SubClass object> short 20
307
<fused_def.SubClass object> long 21
308
<fused_def.SubClass object> short 21
309
<fused_def.SubClass object> long 22
314
obj.mystaticmethod(obj, 10)
315
cls.mystaticmethod(obj, 11)
316
obj.mystaticmethod[cy.short](obj, 12)
317
cls.mystaticmethod[cy.short](obj, 13)
319
obj.myclassmethod(14)
320
cls.myclassmethod(15)
321
obj.myclassmethod[cy.short](16)
322
cls.myclassmethod[cy.short](17)
325
cls.normalmethod(obj, 19)
326
obj.normalmethod[cy.short](20)
327
cls.normalmethod[cy.short](obj, 21)
329
def test_fused_def_classmethod():
331
>>> test_fused_def_classmethod()
332
<class 'fused_def.SubSubClass'> long 10
333
<class 'fused_def.SubSubClass'> long 11
334
<class 'fused_def.SubSubClass'> long 11
335
<class 'fused_def.SubSubClass'> long 12
336
<class 'fused_def.SubSubClass'> short 12
337
<class 'fused_def.SubSubClass'> long 13
338
<class 'fused_def.SubSubClass'> short 13
339
<class 'fused_def.SubSubClass'> long 14
341
SubSubClass().myclassmethod(10)
342
SubSubClass.myclassmethod(11)
344
SubSubClass().myclassmethod[cy.short](12)
345
SubSubClass.myclassmethod[cy.short](13)
347
cdef class CBaseClass(object):
349
Test fused def and cpdef methods in cdef classes.
351
>>> import cython as cy
352
>>> obj = CBaseClass()
355
>>> obj.mystaticmethod(10)
357
>>> obj.mystaticmethod[cy.short](10)
359
>>> cls.mystaticmethod(10)
361
>>> cls.mystaticmethod[cy.short](10)
364
>>> obj.myclassmethod(10)
366
>>> obj.myclassmethod[cy.short](10)
368
>>> cls.myclassmethod(10)
370
>>> cls.myclassmethod[cy.short](10)
373
>>> obj.normalmethod(10, 11, 12)
374
<fused_def.CBaseClass object> long 10 11 12
375
>>> obj.normalmethod[cy.short](10, 11, 12)
376
<fused_def.CBaseClass object> short 10 11 12
377
>>> cls.normalmethod(obj, 10, 11, 12)
378
<fused_def.CBaseClass object> long 10 11 12
379
>>> cls.normalmethod[cy.short](obj, 10, 11, 12)
380
<fused_def.CBaseClass object> short 10 11 12
382
>>> obj.cpdefmethod(10)
383
<fused_def.CBaseClass object> long 10
384
>>> obj.cpdefmethod[cy.short](10)
385
<fused_def.CBaseClass object> short 10
386
>>> cls.cpdefmethod(obj, 10)
387
<fused_def.CBaseClass object> long 10
388
>>> cls.cpdefmethod[cy.short](obj, 10)
389
<fused_def.CBaseClass object> short 10
393
def mystaticmethod(cython.integral arg1):
394
print cython.typeof(arg1), arg1
397
def myclassmethod(cls, cython.integral arg1):
398
print cls.__name__, cython.typeof(arg1), arg1
400
def normalmethod(self, cython.integral arg1, arg2, arg3):
401
print self, cython.typeof(arg1), arg1, arg2, arg3
403
cpdef cpdefmethod(self, cython.integral arg1):
404
print self, cython.typeof(arg1), arg1
407
return "<%s.%s object>" % (__name__, type(self).__name__)
410
return getattr(func, '__code__', None) or func.func_code
412
def test_code_object(cython.floating dummy = 2.0):
414
A test for default arguments is in cyfunction_defaults
416
>>> test_code_object.__code__ is not test_code_object[float].__code__
420
def create_dec(value):
422
if not hasattr(f, 'order'):
424
f.order.append(value)
431
def test_decorators(cython.floating arg):
433
>>> test_decorators.order
438
def bind_me(self, cython.floating a=1.):
443
Using default arguments of bound specialized fused functions used to cause a segfault
444
https://github.com/cython/cython/issues/3370
445
>>> inst = HasBound()
450
>>> inst.func_fused()
452
>>> inst.func_fused(2.)
454
>>> bind_me.__defaults__
456
>>> inst.func.__defaults__
458
>>> inst.func_fused.__defaults__
461
func = bind_me[float]