1
# cython: infer_types = True
2
# cython: language_level=3
4
# Also see type_inference_ll2.pyx for the same tests with language_level=2
7
from cython cimport typeof, infer_types
8
from cpython cimport bool
10
assert typeof(1 / 2) in ('long', 'double')
11
IS_LANGUAGE_LEVEL_3 = typeof(1 / 2) == 'double'
13
##################################################
14
# type inference tests in 'full' mode (infer_types=True)
24
assert typeof(i) == "long", typeof(i)
26
assert typeof(x) == "double", typeof(x)
28
assert typeof(xptr) == "double *", typeof(xptr)
30
assert typeof(xptrptr) == "double **", typeof(xptrptr)
32
assert typeof(b) == "bytes object", typeof(b)
34
assert typeof(s) == "str object", typeof(s)
36
assert typeof(u) == "str object", typeof(u)
38
assert typeof(L) == "list object", typeof(L)
40
assert typeof(t) == "tuple object", typeof(t)
42
assert typeof(t2) == "(long, double, long)", typeof(t)
49
assert typeof(b) == "bytes object", typeof(b)
51
assert typeof(s) == "str object", typeof(u)
52
u = unicode() # legacy name is still available
53
assert typeof(u) == "str object", typeof(u)
55
assert typeof(L) == "list object", typeof(L)
57
assert typeof(t) == "tuple object", typeof(t)
59
assert typeof(d) == "dict object", typeof(d)
61
assert typeof(B) == "bool", typeof(B)
68
assert typeof(b) == "bytes object", typeof(b)
70
assert typeof(b1) == "bytes object", typeof(b1)
72
assert typeof(b2) == "bytes object", typeof(b2)
75
assert typeof(u) == "str object", typeof(u)
77
assert typeof(u1) == "str object", typeof(u1)
79
assert typeof(u2) == "str object", typeof(u2)
82
assert typeof(s) == "str object", typeof(s)
84
assert typeof(s1) == "str object", typeof(s1)
86
assert typeof(s2) == "str object", typeof(s2)
89
assert typeof(L) == "list object", typeof(L)
91
assert typeof(L1) == "list object", typeof(L1)
93
assert typeof(L2) == "list object", typeof(L2)
96
assert typeof(t) == "tuple object", typeof(t)
98
assert typeof(t1) == "tuple object", typeof(t1)
100
assert typeof(t2) == "tuple object", typeof(t2)
108
assert typeof(b) == "bytes object", typeof(b)
110
assert typeof(b1) == "Python object", typeof(b1)
113
assert typeof(u) == "str object", typeof(u)
115
assert typeof(u1) == "Py_UCS4", typeof(u1)
118
assert typeof(s) == "str object", typeof(s)
120
assert typeof(s1) == "Py_UCS4", typeof(s1)
123
assert typeof(L) == "list object", typeof(L)
125
assert typeof(L1) == "Python object", typeof(L1)
128
assert typeof(t) == "tuple object", typeof(t)
130
assert typeof(t1) == "long", typeof(t1)
132
t2 = ('abc', 'def', 'ghi')
133
assert typeof(t2) == "tuple object", typeof(t2)
135
assert typeof(t2_1) == "str object", typeof(t2_1)
137
assert typeof(t2_2) == "str object", typeof(t2_2)
139
t5 = (b'abc', 'def', u'ghi')
141
assert typeof(t5_0) == "bytes object", typeof(t5_0)
143
assert typeof(t5_1) == "str object", typeof(t5_1)
145
assert typeof(t5_2) == "str object", typeof(t5_2)
147
assert typeof(t5_3) == "Python object", typeof(t5_3)
150
def multiple_assignments():
152
>>> multiple_assignments()
157
assert typeof(a) == "long", typeof(a)
161
assert typeof(b) == "double", typeof(b)
165
assert typeof(c) == "Python object", typeof(c)
170
assert typeof(d) == "bytes object", typeof(d)
178
assert typeof(a) == "long", typeof(a)
180
assert typeof(b) == "double", typeof(b)
182
assert typeof(c) == "Python object", typeof(c)
184
assert typeof(d) == "double", typeof(d)
186
assert typeof(e) == ("double" if IS_LANGUAGE_LEVEL_3 else "long"), typeof(e)
188
assert typeof(f) == "long", typeof(f)
190
assert typeof(g) == "long", typeof(g)
192
assert typeof(h) == "double", typeof(h)
194
assert typeof(h) == "double", typeof(h)
196
assert typeof(j) == "double", typeof(j)
198
assert typeof(k) == "double", typeof(k)
200
cdef class some_class:
203
def unary_operators():
205
>>> unary_operators()
208
assert typeof(~x) == "int", typeof(~x)
210
assert typeof(~obj) == "Python object", typeof(~obj)
212
assert typeof(a) == "int object", typeof(a)
214
assert typeof(b) == "bint", typeof(b)
216
assert typeof(c) == "int object", typeof(c)
218
assert typeof(d) == "int object", typeof(d)
220
assert typeof(e) == "int object", typeof(e)
223
def builtin_type_operations():
225
>>> builtin_type_operations()
230
assert typeof(b1) == "bytes object", typeof(b1)
232
assert typeof(b2) == "bytes object", typeof(b2)
236
assert typeof(u1) == "str object", typeof(u1)
238
assert typeof(u2) == "str object", typeof(u2)
241
assert typeof(u3) == "str object", typeof(u3)
245
assert typeof(s1) == "str object", (typeof(s1), "str object")
247
assert typeof(s2) == "str object", (typeof(s2), "str object")
249
s3 = "abc %s" * 10 * 10
250
s3 = 10 * "abc %s" * 10
251
assert typeof(s3) == "str object", (typeof(s3), "str object")
255
assert typeof(f1) == ("double" if IS_LANGUAGE_LEVEL_3 else "Python object"), typeof(f1)
257
assert typeof(i1) == "int object", typeof(i1)
259
assert typeof(i2) == "int object", typeof(i2)
262
assert typeof(L1) == "list object", typeof(L1)
264
assert typeof(L2) == "list object", typeof(L2)
266
assert typeof(T1) == "tuple object", typeof(T1)
268
assert typeof(T2) == "tuple object", typeof(T2)
271
def builtin_type_methods():
273
>>> builtin_type_methods()
276
assert typeof(l) == 'list object', typeof(l)
278
assert typeof(append) == 'Python object', typeof(append)
280
assert l == [1], str(l)
284
assert typeof(split) == 'list object', typeof(split)
286
str_result1 = u.upper()
287
assert typeof(str_result1) == "str object", typeof(str_result1)
288
str_result2 = u.upper().lower()
289
assert typeof(str_result2) == "str object", typeof(str_result2)
290
str_result3 = u.upper().lower().strip()
291
assert typeof(str_result3) == "str object", typeof(str_result3)
292
str_result4 = u.upper().lower().strip().lstrip()
293
assert typeof(str_result4) == "str object", typeof(str_result4)
294
str_result5 = u.upper().lower().strip().lstrip().rstrip()
295
assert typeof(str_result5) == "str object", typeof(str_result5)
296
str_result6 = u.upper().lower().strip().lstrip().rstrip().center(20)
297
assert typeof(str_result6) == "str object", typeof(str_result6)
298
str_result7 = u.upper().lower().strip().lstrip().rstrip().center(20).format()
299
assert typeof(str_result7) == "str object", typeof(str_result7)
300
str_result8 = u.upper().lower().strip().lstrip().rstrip().center(20).format().expandtabs(4)
301
assert typeof(str_result8) == "str object", typeof(str_result8)
302
str_result9 = u.upper().lower().strip().lstrip().rstrip().center(20).format().expandtabs(4).swapcase()
303
assert typeof(str_result9) == "str object", typeof(str_result9)
305
predicate1 = u.isupper()
306
assert typeof(predicate1) == 'bint', typeof(predicate1)
307
predicate2 = u.istitle()
308
assert typeof(predicate2) == 'bint', typeof(predicate2)
311
cdef int cfunc(int x):
319
assert typeof(f) == 'int (*)(int) except? -1', typeof(f)
322
def builtin_functions():
324
>>> _abs, _getattr = builtin_functions()
329
>>> class o(object): pass
337
print(typeof(_getattr))
338
return _abs, _getattr
348
assert typeof(d) == "double"
350
assert typeof(e) == "double"
352
def cascaded_assignment():
354
>>> cascaded_assignment()
357
assert typeof(a) == "double"
358
assert typeof(b) == "double"
359
assert typeof(c) == "double"
360
assert typeof(d) == "double"
362
assert typeof(e) == "double"
369
a, b, c, (d, e) = x, 1, 2.0, [3, [5, 6]]
370
assert typeof(a) == "Python object", typeof(a)
371
assert typeof(b) == "long", typeof(b)
372
assert typeof(c) == "double", typeof(c)
373
assert typeof(d) == "long", typeof(d)
374
assert typeof(e) == "list object", typeof(e)
377
def star_unpacking(*x):
379
>>> star_unpacking(1, 2)
384
*g, g = x # re-assignment
385
assert typeof(a) == "Python object", typeof(a)
386
assert typeof(b) == "Python object", typeof(b)
387
assert typeof(c) == "Python object", typeof(c)
388
assert typeof(d) == "list object", typeof(d)
389
assert typeof(e) == "list object", typeof(e)
390
assert typeof(f) == "Python object", typeof(f)
391
assert typeof(g) == "Python object", typeof(f)
400
assert typeof(a) == "long"
408
assert typeof(a) == "long"
413
assert typeof(b) == "double"
415
for c from 0 <= c < 10 by .5:
417
assert typeof(c) == "double"
419
for d in range(0, 10L, 2):
421
assert typeof(a) == "long"
423
def loop_over_charptr():
425
>>> print( loop_over_charptr() )
428
cdef char* char_ptr_string = 'abcdefg'
429
for c in char_ptr_string:
433
def loop_over_bytes_literal():
435
>>> print( loop_over_bytes_literal() )
442
def loop_over_bytes():
444
>>> print( loop_over_bytes() )
447
cdef bytes bytes_string = b'abcdefg'
448
# bytes in Py2, int in Py3
449
for c in bytes_string:
457
cdef str string = 'abcdefg'
458
# str (bytes) in Py2, str (unicode) in Py3
461
assert typeof(c) == 'Py_UCS4', typeof(c)
463
def loop_over_unicode():
465
>>> print( loop_over_unicode() )
468
cdef unicode ustring = u'abcdefg'
469
# Py_UCS4 can represent any Unicode character
470
for uchar in ustring:
474
def loop_over_unicode_literal():
476
>>> print( loop_over_unicode_literal() )
479
# Py_UCS4 can represent any Unicode character
480
for uchar in u'abcdefg':
484
def loop_over_int_array():
486
>>> print( loop_over_int_array() )
489
cdef int[10] int_array
497
def loop_over_struct_ptr():
499
>>> print( loop_over_struct_ptr() )
502
cdef MyStruct[10] a_list
503
cdef MyStruct *a_ptr = a_list
504
for i in a_list[:10]:
516
>>> conditional(True)
517
(True, 'Python object')
518
>>> conditional(False)
519
(False, 'Python object')
525
return type(a) is unicode, typeof(a)
527
##################################################
528
# type inference tests that work in 'safe' mode
531
def double_inference():
533
>>> values, types = double_inference()
534
>>> values == (1.0, 1.0*2, 1.0*2.0+2.0*2.0, 1.0*2.0)
537
('double', 'double', 'double', 'Python object')
541
d_c = d_a * float(some_float_value()) + d_b * float(some_float_value())
542
o_d = d_a * some_float_value()
543
return (d_a,d_b,d_c,o_d), (typeof(d_a), typeof(d_b), typeof(d_c), typeof(o_d))
545
cdef object some_float_value():
550
@cython.test_fail_if_path_exists('//DefNode//NameNode[@type.is_pyobject = True]')
551
@cython.test_assert_path_exists('//DefNode//NameNode[@type.is_pyobject]',
552
'//DefNode//NameNode[@type.is_pyobject = False]')
555
>>> double_loop() == 1.0 * 10
570
assert typeof(a) == "double", typeof(a)
572
assert typeof(b) == "long", typeof(b)
574
assert typeof(c) == "MyType", typeof(c)
575
for i in range(10): pass
576
assert typeof(i) == "long", typeof(i)
579
assert typeof(d) == "long", typeof(d)
582
div_res = pyint_val / 7
583
assert typeof(div_res) == ("double" if IS_LANGUAGE_LEVEL_3 else "Python object"), typeof(div_res)
586
assert typeof(s) == "str object", (typeof(s), "str object")
588
assert typeof(t) == "str object", (typeof(t), "str object")
590
# potentially overflowing arithmetic
593
assert typeof(e) == "Python object", typeof(e)
596
assert typeof(f) == "Python object", typeof(f)
599
assert typeof(g) == "Python object", typeof(g)
602
assert typeof(j) == "Python object", typeof(j)
605
assert typeof(h) == "Python object", typeof(h)
607
assert typeof(abs(c_int)) == "int", typeof(abs(c_int))
609
# float can be inferred
612
assert typeof(from_fl) == "float", typeof(from_fl)
616
def safe_c_functions():
618
>>> safe_c_functions()
621
assert typeof(f) == 'int (*)(int) except? -1', typeof(f)
631
assert typeof(a_ptr) == "int *", typeof(a_ptr)
633
assert typeof(a_ptr_ptr) == "int **", typeof(a_ptr_ptr)
636
assert typeof(b_ref) == "int *", typeof(b_ref)
639
assert typeof(ptr) == "int *", typeof(ptr)
641
def const_types(const double x, double y, double& z):
643
>>> const_types(1, 1, 1)
648
assert typeof(a) == "double", typeof(a)
651
def args_tuple_keywords(*args, **kwargs):
653
>>> args_tuple_keywords(1,2,3, a=1, b=2)
655
assert typeof(args) == "tuple object", typeof(args)
656
assert typeof(kwargs) == "dict object", typeof(kwargs)
659
def args_tuple_keywords_reassign_same(*args, **kwargs):
661
>>> args_tuple_keywords_reassign_same(1,2,3, a=1, b=2)
663
assert typeof(args) == "tuple object", typeof(args)
664
assert typeof(kwargs) == "dict object", typeof(kwargs)
670
def args_tuple_keywords_reassign_pyobjects(*args, **kwargs):
672
>>> args_tuple_keywords_reassign_pyobjects(1,2,3, a=1, b=2)
674
assert typeof(args) == "Python object", typeof(args)
675
assert typeof(kwargs) == "Python object", typeof(kwargs)
685
cdef class Base0: pass
686
cdef class Base(Base0): pass
687
cdef class A(Base): pass
688
cdef class AA(A): pass
689
cdef class AAA(AA): pass
690
cdef class B(Base): pass
691
cdef class BB(B): pass
693
cdef class CC(C): pass
696
def common_extension_type_base():
698
>>> common_extension_type_base()
702
assert typeof(x) == "A", typeof(x)
705
assert typeof(y) == "Base", typeof(y)
708
assert typeof(z) == "Base", typeof(z)
711
assert typeof(w) == "Python object", typeof(w)
713
cdef class AcceptsKeywords:
714
def __init__(self, *args, **kwds):
718
def constructor_call():
720
>>> constructor_call()
722
x = AcceptsKeywords(a=1, b=2)
723
assert typeof(x) == "AcceptsKeywords", typeof(x)
731
# It's only safe to infer small integer literals.
733
b = 100000000000000000000000000000000
734
assert typeof(a) == "long", typeof(a)
735
assert typeof(b) == "Python object", typeof(b)
736
c, d = 10, 100000000000000000000000000000000
737
assert typeof(c) == "long", typeof(c)
738
assert typeof(d) == "Python object", typeof(d)
741
class EmptyContextManager(object):
744
def __exit__(self, *args):
754
with EmptyContextManager() as x:
760
cdef class TypedContextManager(object):
761
cpdef double __enter__(self):
763
def __exit__(self, *args):
766
def with_statement_typed():
768
>>> with_statement_typed()
774
with TypedContextManager() as x:
779
def with_statement_untyped():
781
>>> with_statement_untyped()
787
cdef object t = TypedContextManager()
795
b = b.foo(keyword=None)
798
# Regression test for trac #638.
810
def test_int_typedef_inference():
812
>>> test_int_typedef_inference()
817
assert typeof(x + y) == typeof(y + x) == 'my_long', typeof(x + y)
818
assert typeof(y + z) == typeof(z + y) == 'long long', typeof(y + z)
820
from libc.stdint cimport int32_t, int64_t
825
cdef unsigned long ux = 4
826
assert typeof(x + x32) == typeof(x32 + x) == 'long', typeof(x + x32)
827
assert typeof(x + x64) == typeof(x64 + x) == 'int64_t', typeof(x + x64)
828
# The correct answer here is either unsigned long or int64_t, depending on
829
# whether sizeof(long) == 64 or not. Incorrect signedness is probably
830
# preferable to incorrect width.
831
assert typeof(ux + x64) == typeof(x64 + ux) == 'int64_t', typeof(ux + x64)
833
cdef class InferInProperties:
835
>>> InferInProperties().x
836
('double', 'str object', 'MyEnum', 'MyEnum')
849
return typeof(a), typeof(b), typeof(c), typeof(d)
851
cdef class WithMethods:
853
def __init__(self, offset):
855
cpdef int one_arg(self, int x):
856
return x + self.offset
857
cpdef int default_arg(self, int x, int y=0):
858
return x + y + self.offset
860
def test_bound_methods():
862
>>> test_bound_methods()
865
assert typeof(o) == 'WithMethods', typeof(o)
868
assert one_arg(2) == 12, one_arg(2)
870
default_arg = o.default_arg
871
assert default_arg(2) == 12, default_arg(2)
872
assert default_arg(2, 3) == 15, default_arg(2, 2)
874
def test_builtin_max():
876
# builtin max is slightly complicated because it gets transformed to EvalWithTempExprNode
877
# See https://github.com/cython/cython/issues/4155
878
>>> test_builtin_max()
883
a = max(self.a, self.a)
884
assert typeof(a) == "Python object", typeof(a)