1
2cimport cython
3
4def f(a,b):
5    """
6    >>> f(1,[1,2,3])
7    True
8    >>> f(5,[1,2,3])
9    False
10    >>> f(2,(1,2,3))
11    True
12    """
13    cdef object result = a in b
14    return result
15
16def g(a,b):
17    """
18    >>> g(1,[1,2,3])
19    1
20    >>> g(5,[1,2,3])
21    0
22    >>> g(2,(1,2,3))
23    1
24    """
25    cdef int result = a in b
26    return result
27
28def h(b):
29    """
30    >>> h([1,2,3,4])
31    True
32    >>> h([1,3,4])
33    False
34    """
35    cdef object result = 2 in b
36    return result
37
38def j(b):
39    """
40    >>> j([1,2,3,4])
41    1
42    >>> j([1,3,4])
43    0
44    """
45    cdef int result = 2 in b
46    return result
47
48@cython.test_fail_if_path_exists("//SwitchStatNode")
49def k(a):
50    """
51    >>> k(1)
52    1
53    >>> k(5)
54    0
55    """
56    cdef int result = a in [1,2,3,4]
57    return result
58
59@cython.test_assert_path_exists("//SwitchStatNode")
60@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
61def m_list(int a):
62    """
63    >>> m_list(2)
64    1
65    >>> m_list(5)
66    0
67    """
68    cdef int result = a in [1,2,3,4]
69    return result
70
71@cython.test_assert_path_exists("//SwitchStatNode")
72@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
73def m_tuple(int a):
74    """
75    >>> m_tuple(2)
76    1
77    >>> m_tuple(5)
78    0
79    """
80    cdef int result = a in (1,2,3,4)
81    return result
82
83@cython.test_assert_path_exists("//SwitchStatNode")
84@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
85def m_set(int a):
86    """
87    >>> m_set(2)
88    1
89    >>> m_set(5)
90    0
91    """
92    cdef int result = a in {1,2,3,4}
93    return result
94
95cdef bytes bytes_string = b'ab\0cde\0f\0g'
96py_bytes_string = bytes_string
97
98@cython.test_assert_path_exists("//PrimaryCmpNode")
99@cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode")
100def m_bytes(char a, bytes bytes_string):
101    """
102    >>> m_bytes(ord('f'), py_bytes_string)
103    1
104    >>> m_bytes(ord('X'), py_bytes_string)
105    0
106    >>> 'f'.encode('ASCII') in None    # doctest: +ELLIPSIS
107    Traceback (most recent call last):
108    TypeError: ...iterable...
109    >>> m_bytes(ord('f'), None)
110    Traceback (most recent call last):
111    TypeError: argument of type 'NoneType' is not iterable
112    """
113    cdef int result = a in bytes_string
114    return result
115
116@cython.test_assert_path_exists("//PrimaryCmpNode")
117@cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode")
118def m_bytes_unsigned(unsigned char a, bytes bytes_string):
119    """
120    >>> m_bytes(ord('f'), py_bytes_string)
121    1
122    >>> m_bytes(ord('X'), py_bytes_string)
123    0
124    >>> 'f'.encode('ASCII') in None    # doctest: +ELLIPSIS
125    Traceback (most recent call last):
126    TypeError: ...iterable...
127    >>> m_bytes(ord('f'), None)
128    Traceback (most recent call last):
129    TypeError: argument of type 'NoneType' is not iterable
130    """
131    cdef int result = a in bytes_string
132    return result
133
134@cython.test_assert_path_exists("//SwitchStatNode")
135@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
136def m_bytes_literal(char a):
137    """
138    >>> m_bytes_literal(ord('f'))
139    1
140    >>> m_bytes_literal(ord('X'))
141    0
142    """
143    cdef int result = a in b'ab\0cde\0f\0g'
144    return result
145
146@cython.test_assert_path_exists("//SwitchStatNode")
147@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
148def m_bytes_literal_unsigned(unsigned char a):
149    """
150    >>> m_bytes_literal(ord('f'))
151    1
152    >>> m_bytes_literal(ord('X'))
153    0
154    """
155    cdef int result = a in b'ab\0cde\0f\0g'
156    return result
157
158cdef unicode unicode_string = u'abc\0defg\u1234\uF8D2'
159py_unicode_string = unicode_string
160
161@cython.test_assert_path_exists("//PrimaryCmpNode")
162@cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode")
163def m_unicode(Py_UNICODE a, unicode unicode_string):
164    """
165    >>> m_unicode(ord('f'), py_unicode_string)
166    1
167    >>> m_unicode(ord('X'), py_unicode_string)
168    0
169    >>> m_unicode(ord(py_klingon_character), py_unicode_string)
170    1
171
172    >>> 'f' in None   # doctest: +ELLIPSIS
173    Traceback (most recent call last):
174    TypeError: ...iterable...
175    >>> m_unicode(ord('f'), None)
176    Traceback (most recent call last):
177    TypeError: argument of type 'NoneType' is not iterable
178    """
179    cdef int result = a in unicode_string
180    return result
181
182cdef unicode klingon_character = u'\uF8D2'
183py_klingon_character = klingon_character
184
185@cython.test_assert_path_exists("//SwitchStatNode")
186@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
187def m_unicode_literal(Py_UNICODE a):
188    """
189    >>> m_unicode_literal(ord('f'))
190    1
191    >>> m_unicode_literal(ord('X'))
192    0
193    >>> m_unicode_literal(ord(py_klingon_character))
194    1
195    """
196    cdef int result = a in u'abc\0defg\u1234\uF8D2'
197    return result
198
199cdef unicode wide_unicode_character = u'\U0010FEDC'
200py_wide_unicode_character = wide_unicode_character
201wide_unicode_character_surrogate1 = 0xDBFF
202wide_unicode_character_surrogate2 = 0xDEDC
203
204@cython.test_fail_if_path_exists("//SwitchStatNode")
205@cython.test_assert_path_exists("//PrimaryCmpNode")
206def m_wide_unicode_literal(Py_UCS4 a):
207    """
208    >>> m_unicode_literal(ord('f'))
209    1
210    >>> m_unicode_literal(ord('X'))
211    0
212    >>> import sys
213    >>> if sys.maxunicode == 65535:
214    ...     m_wide_unicode_literal(wide_unicode_character_surrogate1)
215    ...     m_wide_unicode_literal(wide_unicode_character_surrogate2)
216    ... else:
217    ...     m_wide_unicode_literal(ord(py_wide_unicode_character))
218    ...     1
219    1
220    1
221    """
222    cdef int result = a in u'abc\0defg\u1234\uF8D2\U0010FEDC'
223    return result
224
225@cython.test_assert_path_exists("//SwitchStatNode")
226@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
227def conditional_int(int a):
228    """
229    >>> conditional_int(1)
230    1
231    >>> conditional_int(0)
232    2
233    >>> conditional_int(5)
234    2
235    """
236    return 1 if a in (1,2,3,4) else 2
237
238@cython.test_assert_path_exists("//SwitchStatNode")
239@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
240def conditional_object(int a):
241    """
242    >>> conditional_object(1)
243    1
244    >>> conditional_object(0)
245    '2'
246    >>> conditional_object(5)
247    '2'
248    """
249    return 1 if a in (1,2,3,4) else '2'
250
251@cython.test_assert_path_exists("//SwitchStatNode")
252@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
253def conditional_bytes(char a):
254    """
255    >>> conditional_bytes(ord('a'))
256    1
257    >>> conditional_bytes(ord('X'))
258    '2'
259    >>> conditional_bytes(0)
260    '2'
261    """
262    return 1 if a in b'abc' else '2'
263
264@cython.test_assert_path_exists("//SwitchStatNode")
265@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
266def conditional_unicode(Py_UNICODE a):
267    """
268    >>> conditional_unicode(ord('a'))
269    1
270    >>> conditional_unicode(ord('X'))
271    '2'
272    >>> conditional_unicode(0)
273    '2'
274    """
275    return 1 if a in u'abc' else '2'
276
277@cython.test_assert_path_exists("//SwitchStatNode")
278@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
279def conditional_none(int a):
280    """
281    >>> conditional_none(1)
282    >>> conditional_none(0)
283    1
284    >>> conditional_none(5)
285    1
286    """
287    return None if a in {1,2,3,4} else 1
288
289@cython.test_assert_path_exists(
290    "//BoolBinopNode",
291    "//BoolBinopNode//PrimaryCmpNode"
292)
293@cython.test_fail_if_path_exists("//ListNode")
294def n(a):
295    """
296    >>> n('d *')
297    1
298    >>> n('xxx')
299    0
300    """
301    cdef int result = a.lower() in [u'a *',u'b *',u'c *',u'd *']
302    return result
303
304def p(a):
305    """
306    >>> p(1)
307    0
308    >>> p('a')
309    1
310    """
311    cdef dict d = {u'a': 1, u'b': 2}
312    cdef int result = a in d
313    return result
314
315def q(a):
316    """
317    >>> q(1)
318    Traceback (most recent call last):
319    TypeError: 'NoneType' object is not iterable
320        >>> l = [1,2,3,4]
321    >>> l2 = [l[1:],l[:-1],l]
322    >>> 2 in l in l2
323    True
324    """
325    cdef dict d = None
326    cdef int result = a in d # should fail with a TypeError
327    return result
328
329def r(a):
330    """
331    >>> r(2)
332    1
333    """
334    cdef object l = [1,2,3,4]
335    cdef object l2 = [l[1:],l[:-1],l]
336    cdef int result = a in l in l2
337    return result
338
339def s(a):
340    """
341    >>> s(2)
342    1
343    """
344    cdef int result = a in [1,2,3,4] in [[1,2,3],[2,3,4],[1,2,3,4]]
345    return result
346
347#@cython.test_assert_path_exists("//ReturnStatNode//BoolNode")
348#@cython.test_fail_if_path_exists("//SwitchStatNode")
349def constant_empty_sequence(a):
350    """
351    >>> constant_empty_sequence(1)
352    False
353    >>> constant_empty_sequence(5)
354    False
355    """
356    return a in ()
357
358@cython.test_fail_if_path_exists("//ReturnStatNode//BoolNode")
359@cython.test_assert_path_exists("//PrimaryCmpNode")
360def constant_empty_sequence_side_effect(a):
361    """
362    >>> l =[]
363    >>> def a():
364    ...     l.append(1)
365    ...     return 1
366
367    >>> constant_empty_sequence_side_effect(a)
368    False
369    >>> l
370    [1]
371    """
372    return a() in ()
373
374def test_error_non_iterable(x):
375    """
376    >>> test_error_non_iterable(1)   # doctest: +ELLIPSIS
377    Traceback (most recent call last):
378    TypeError: ...iterable...
379    """
380    return x in 42
381
382def test_error_non_iterable_cascaded(x):
383    """
384    >>> test_error_non_iterable_cascaded(1)   # doctest: +ELLIPSIS
385    Traceback (most recent call last):
386    TypeError: ...iterable...
387    """
388    return 1 == x in 42
389
390def test_inop_cascaded(x):
391    """
392    >>> test_inop_cascaded(1)
393    False
394    >>> test_inop_cascaded(2)
395    True
396    >>> test_inop_cascaded(3)
397    False
398    """
399    return 1 != x in [2]
400
401### The following tests are copied from CPython's test_grammar.py.
402### They look stupid, but the nice thing about them is that Cython
403### treats '1' as a C integer constant that triggers Python object
404### coercion for the 'in' operator here, whereas the left side of
405### the cascade can be evaluated entirely in C space.
406
407def test_inop_cascaded_one():
408    """
409    >>> test_inop_cascaded_one()
410    False
411    """
412    return 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1
413
414def test_inop_cascaded_int_orig(int x):
415    """
416    >>> test_inop_cascaded_int_orig(1)
417    False
418    """
419    return 1 < 1 > 1 == 1 >= 1 <= 1 != x in 1 not in 1 is 1 is not 1
420
421def test_inop_cascaded_one_err():
422    """
423    >>> test_inop_cascaded_one_err()   # doctest: +ELLIPSIS
424    Traceback (most recent call last):
425    TypeError:... itera...
426    """
427    return 1 == 1 >= 1 <= 1 in 1 not in 1 is 1 is not 1
428
429def test_inop_cascaded_int_orig_err(int x):
430    """
431    >>> test_inop_cascaded_int_orig_err(1)   # doctest: +ELLIPSIS
432    Traceback (most recent call last):
433    TypeError:... itera...
434    """
435    return 1 == 1 >= 1 <= 1 == x in 1 not in 1 is 1 is not 1
436
437###
438
439def test_inop_cascaded_int(int x):
440    """
441    >>> test_inop_cascaded_int(1)
442    False
443    >>> test_inop_cascaded_int(2)
444    True
445    >>> test_inop_cascaded_int(3)
446    False
447    """
448    return 1 != x in [1,2]
449