1cimport cython
2
3bytes_abc = b'abc'
4bytes_ABC = b'ABC'
5bytes_abc_null = b'a\0b\0c'
6bytes_ABC_null = b'A\0B\0C'
7
8unicode_abc = u'abc'
9unicode_ABC = u'ABC'
10unicode_abc_null = u'a\0b\0c'
11unicode_ABC_null = u'A\0B\0C'
12
13
14def for_in_bytes(bytes s):
15    """
16    >>> for_in_bytes(bytes_abc)
17    'X'
18    >>> for_in_bytes(bytes_ABC)
19    'C'
20    >>> for_in_bytes(bytes_abc_null)
21    'X'
22    >>> for_in_bytes(bytes_ABC_null)
23    'C'
24    """
25    for c in s:
26        # Py2/Py3
27        if c == b'C' or c == c'C':
28            return 'C'
29    else:
30        return 'X'
31
32@cython.test_assert_path_exists("//ForFromStatNode")
33@cython.test_fail_if_path_exists("//ForInStatNode")
34def for_char_in_bytes(bytes s):
35    """
36    >>> for_char_in_bytes(bytes_abc)
37    'X'
38    >>> for_char_in_bytes(bytes_ABC)
39    'C'
40    >>> for_char_in_bytes(bytes_abc_null)
41    'X'
42    >>> for_char_in_bytes(bytes_ABC_null)
43    'C'
44    """
45    cdef char c
46    for c in s:
47        if c == b'C':
48            return 'C'
49    else:
50        return 'X'
51
52#### Py2 and Py3 behave differently here: Py2->bytes, Py3->integer
53##
54## @cython.test_assert_path_exists("//ForFromStatNode")
55## @cython.test_fail_if_path_exists("//ForInStatNode")
56## def for_obj_in_bytes_slice(bytes s):
57##     """
58##     >>> for_obj_in_bytes_slice(bytes_abc)
59##     'X'
60##     >>> for_obj_in_bytes_slice(bytes_ABC)
61##     'B'
62##     >>> for_obj_in_bytes_slice(bytes_abc_null)
63##     'X'
64##     >>> for_obj_in_bytes_slice(bytes_ABC_null)
65##     'B'
66##     """
67##     for c in s[1:-1]:
68##         if c == b'B':
69##             return 'B'
70##     else:
71##         return 'X'
72
73@cython.test_assert_path_exists("//ForFromStatNode")
74@cython.test_fail_if_path_exists("//ForInStatNode")
75def for_char_in_bytes_slice(bytes s):
76    """
77    >>> for_char_in_bytes_slice(bytes_abc)
78    'X'
79    >>> for_char_in_bytes_slice(bytes_ABC)
80    'B'
81    >>> for_char_in_bytes_slice(bytes_abc_null)
82    'X'
83    >>> for_char_in_bytes_slice(bytes_ABC_null)
84    'B'
85    """
86    cdef char c
87    for c in s[1:-1]:
88        if c == c'B':
89            return 'B'
90    else:
91        return 'X'
92
93@cython.test_assert_path_exists("//ForFromStatNode")
94@cython.test_fail_if_path_exists("//ForInStatNode")
95def for_char_in_enumerate_bytes(bytes s):
96    """
97    >>> for_char_in_enumerate_bytes(bytes_abc)
98    'X'
99    >>> for_char_in_enumerate_bytes(bytes_ABC)
100    2
101    >>> for_char_in_enumerate_bytes(bytes_abc_null)
102    'X'
103    >>> for_char_in_enumerate_bytes(bytes_ABC_null)
104    4
105    """
106    cdef char c
107    cdef Py_ssize_t i
108    for i, c in enumerate(s):
109        if c == b'C':
110            return i
111    else:
112        return 'X'
113
114#### Py2 and Py3 behave differently here: Py2->bytes, Py3->integer
115##
116## @cython.test_assert_path_exists("//ForFromStatNode")
117## @cython.test_fail_if_path_exists("//ForInStatNode")
118## def for_pyvar_in_char_ptr(char* c_string):
119##     """
120##     >>> for_pyvar_in_char_ptr( (bytes_abc+bytes_ABC) * 2 )
121##     [True, True, True, False, False, False, True, True, True, False]
122##     >>> for_pyvar_in_char_ptr( bytes_abc_null * 2 )
123##     [True, False, True, False, True, True, False, True, False, True]
124##     """
125##     in_test = []
126##     cdef object c
127##     for c in c_string[:10]:
128##         in_test.append( c in b'abc' )
129##     return in_test
130
131@cython.test_assert_path_exists("//ForFromStatNode")
132@cython.test_fail_if_path_exists("//ForInStatNode")
133def for_char_in_char_ptr(char* c_string):
134    """
135    >>> for_char_in_char_ptr( (bytes_abc+bytes_ABC) * 2 )
136    [True, True, True, False, False, False, True, True, True, False]
137    >>> for_char_in_char_ptr( bytes_abc_null * 2 )
138    [True, False, True, False, True, True, False, True, False, True]
139    """
140    in_test = []
141    cdef char c
142    for c in c_string[:10]:
143        in_test.append( c in b'abc' )
144    return in_test
145
146@cython.test_assert_path_exists("//ForFromStatNode")
147@cython.test_fail_if_path_exists("//ForInStatNode")
148def for_pyunicode_in_unicode(unicode s):
149    """
150    >>> for_pyunicode_in_unicode(unicode_abc)
151    'X'
152    >>> for_pyunicode_in_unicode(unicode_ABC)
153    'C'
154    >>> for_pyunicode_in_unicode(unicode_abc_null)
155    'X'
156    >>> for_pyunicode_in_unicode(unicode_ABC_null)
157    'C'
158    """
159    cdef Py_UNICODE c
160    for c in s:
161        if c == u'C':
162            return 'C'
163    else:
164        return 'X'
165
166@cython.test_assert_path_exists("//ForFromStatNode")
167@cython.test_fail_if_path_exists("//ForInStatNode")
168def for_pyunicode_in_enumerate_unicode(unicode s):
169    """
170    >>> for_pyunicode_in_enumerate_unicode(unicode_abc)
171    'X'
172    >>> for_pyunicode_in_enumerate_unicode(unicode_ABC)
173    2
174    >>> for_pyunicode_in_enumerate_unicode(unicode_abc_null)
175    'X'
176    >>> for_pyunicode_in_enumerate_unicode(unicode_ABC_null)
177    4
178    """
179    cdef Py_UNICODE c
180    cdef Py_ssize_t i
181    for i, c in enumerate(s):
182        if c == u'C':
183            return i
184    else:
185        return 'X'
186
187@cython.test_assert_path_exists("//ForFromStatNode")
188@cython.test_fail_if_path_exists("//ForInStatNode")
189def for_pyucs4_in_unicode(unicode s):
190    """
191    >>> for_pyucs4_in_unicode(unicode_abc)
192    'X'
193    >>> for_pyucs4_in_unicode(unicode_ABC)
194    'C'
195    >>> for_pyucs4_in_unicode(unicode_abc_null)
196    'X'
197    >>> for_pyucs4_in_unicode(unicode_ABC_null)
198    'C'
199    """
200    cdef Py_UCS4 c
201    for c in s:
202        if c == u'C':
203            return 'C'
204    else:
205        return 'X'
206
207@cython.test_assert_path_exists("//ForFromStatNode")
208@cython.test_fail_if_path_exists("//ForInStatNode")
209def for_pyucs4_in_enumerate_unicode(unicode s):
210    """
211    >>> for_pyucs4_in_enumerate_unicode(unicode_abc)
212    'X'
213    >>> for_pyucs4_in_enumerate_unicode(unicode_ABC)
214    2
215    >>> for_pyucs4_in_enumerate_unicode(unicode_abc_null)
216    'X'
217    >>> for_pyucs4_in_enumerate_unicode(unicode_ABC_null)
218    4
219    """
220    cdef Py_UCS4 c
221    cdef Py_ssize_t i
222    for i, c in enumerate(s):
223        if c == u'C':
224            return i
225    else:
226        return 'X'
227