1import cython
2
3def simple_convert(*o):
4    """
5    >>> simple_convert(1, 2)
6    (1, 2.0)
7
8    >>> simple_convert(1)
9    Traceback (most recent call last):
10    ...
11    TypeError: Expected a tuple of size 2, got tuple
12    >>> simple_convert(1, 2, 3)
13    Traceback (most recent call last):
14    ...
15    TypeError: Expected a tuple of size 2, got tuple
16    """
17    cdef (int, double) xy = o
18    return xy
19
20def indexing((int, double) xy):
21    """
22    >>> indexing((1, 2))
23    (2, 3.0)
24    """
25    x = xy[0]
26    y = xy[1]
27    xy[0] = x + 1
28    xy[1] = y + 1
29    return xy
30
31def unpacking((int, double) xy):
32    """
33    >>> unpacking((1, 2))
34    (1, 2.0)
35    """
36    x, y = xy
37    return x, y
38
39cdef (int, double) side_effect((int, double) xy):
40    print "called with", xy
41    return xy
42
43def unpacking_with_side_effect((int, double) xy):
44    """
45    >>> unpacking_with_side_effect((1, 2))
46    called with (1, 2.0)
47    (1, 2.0)
48    """
49    x, y = side_effect(xy)
50    return x, y
51
52def packing_tuple(int x, double y):
53    """
54    >>> packing_tuple(1, 2)
55    (1, 2.0)
56    """
57    cdef (int, double) xy = (x, y)
58    assert xy == (x, y), xy
59    xy = (x, y) * 1
60    assert xy == (x, y), xy
61    xy = 1 * (x, y)
62    return xy
63
64def packing_list(int x, double y):
65    """
66    >>> packing_list(1, 2)
67    (1, 2.0)
68    """
69    cdef (int, double) xy = [x, y]
70    assert xy == (x, y), xy
71    xy = [x, y] * 1
72    assert xy == (x, y), xy
73    xy = 1 * [x, y]
74    return xy
75
76def coerce_packing_tuple(int x, int y):
77    cdef (int, double) xy = (x, y)
78    """
79    >>> coerce_packing_tuple(1, 2)
80    (1, 2.0)
81    """
82    return xy
83
84def c_types(int a, double b):
85    """
86    >>> c_types(1, 2)
87    (1, 2.0)
88    """
89    cdef int* a_ptr
90    cdef double* b_ptr
91    cdef (int*, double*) ab = (&a, &b)
92    a_ptr, b_ptr = ab
93    return a_ptr[0], b_ptr[0]
94
95
96cdef union Union:
97    int x
98    double y
99
100
101def union_in_ctuple_literal():
102    """
103    >>> union_in_ctuple_literal()
104    (1, 2.0)
105    """
106    cdef (Union,) a = ({"x": 1},)
107    cdef (Union,) b = ({"y": 2},)
108    return a[0].x, b[0].y
109
110
111def union_in_ctuple_dynamic(*values):
112    """
113    >>> union_in_ctuple_dynamic(1, {'x': 1})
114    1
115    >>> union_in_ctuple_dynamic(2, {'y': 2})
116    2.0
117    >>> union_in_ctuple_dynamic(1, {'x': 1, 'y': 2})
118    Traceback (most recent call last):
119    ValueError: More than one union attribute passed: 'x' and 'y'
120    """
121    cdef (int, Union) a = values
122    return a[1].x if a[0] == 1 else a[1].y
123
124
125cdef (int, int*) cdef_ctuple_return_type(int x, int* x_ptr):
126    return x, x_ptr
127
128def call_cdef_ctuple_return_type(int x):
129    """
130    >>> call_cdef_ctuple_return_type(2)
131    (2, 2)
132    """
133    cdef (int, int*) res = cdef_ctuple_return_type(x, &x)
134    return res[0], res[1][0]
135
136
137cpdef (int, double) cpdef_ctuple_return_type(int x, double y):
138    """
139    >>> cpdef_ctuple_return_type(1, 2)
140    (1, 2.0)
141    """
142    return x, y
143
144
145def cast_to_ctuple(*o):
146    """
147    >>> cast_to_ctuple(1, 2.)
148    (1, 2.0)
149    """
150    cdef int x
151    cdef double y
152    x, y = <(int, double)>o
153    return x, y
154
155
156@cython.infer_types(True)
157def test_type_inference():
158    """
159    >>> test_type_inference()
160    """
161    cdef int x = 1
162    cdef double y = 2
163    cdef object o = 3
164    xy = (x, y)
165    assert cython.typeof(xy) == "(int, double)", cython.typeof(xy)
166    xo = (x, o)
167    assert cython.typeof(xo) == "tuple object", cython.typeof(xo)
168
169
170@cython.locals(a=(int,int), b=(cython.long,cython.float))
171def test_pure_python_declaration(x, y):
172    """
173    >>> test_pure_python_declaration(1, 2)
174    (int, int)
175    (long, float)
176    ((1, 2), (1, 2.0))
177    >>> test_pure_python_declaration(1.0, 2.0)
178    (int, int)
179    (long, float)
180    ((1, 2), (1, 2.0))
181    >>> test_pure_python_declaration('x', 'y')
182    Traceback (most recent call last):
183    TypeError: an integer is required
184    """
185    a = (x, y)
186    b = (x, y)
187    print(cython.typeof(a))
188    print(cython.typeof(b))
189    return (a, b)
190
191
192def test_equality((int, int) ab, (int, int) cd, (int, int) ef):
193    """
194    >>> test_equality((1, 2), (3, 4), (5, 6))
195    True
196    >>> test_equality((1, 2), (3, 4), (3, 4))
197    True
198    >>> test_equality((3, 4), (3, 4), (3, 4))
199    False
200    """
201    return ab < cd <= ef
202
203def test_equality_different_types((double, int) ab, (int, int) cd, (long, int) ef):
204    """
205    >>> test_equality((1, 2), (3, 4), (5, 6))
206    True
207    >>> test_equality((1, 2), (3, 4), (3, 4))
208    True
209    >>> test_equality((3, 4), (3, 4), (3, 4))
210    False
211    """
212    return ab < cd <= ef
213
214def test_binop((int, int) ab, (double, double) cd):
215    """
216    >>> test_binop((1, 2), (3, 4))
217    (1, 2, 3.0, 4.0)
218    """
219    return ab + cd
220
221def test_mul((int, int) ab, int c):
222    """
223    >>> test_mul((1, 2), 3)
224    (1, 2, 1, 2, 1, 2)
225    """
226    return ab * c
227
228def test_unop((int, int) ab):
229    """
230    >>> test_unop((1, 2))
231    True
232    """
233    return not ab
234