1
2cimport cython
3
4def coerce_char_default(char c):
5    """
6    Default char -> int coercion
7
8    >>> coerce_char_default(ord('A')) == ord('A')
9    True
10    """
11    return c
12
13
14def coerce_uchar_default(unsigned char c):
15    """
16    Default char -> int coercion
17
18    >>> coerce_uchar_default(ord('A')) == ord('A')
19    True
20    """
21    return c
22
23
24@cython.test_assert_path_exists("//CoerceIntToBytesNode")
25@cython.test_fail_if_path_exists("//CoerceToPyTypeNode")
26def coerce_char_bytes_cast(char c):
27    """
28    Explicit char -> bytes coercion
29
30    >>> coerce_char_bytes_cast(ord('A')) == 'A'.encode('ASCII')
31    True
32    """
33    return <bytes>c
34
35
36@cython.test_assert_path_exists("//CoerceIntToBytesNode")
37@cython.test_fail_if_path_exists("//CoerceToPyTypeNode")
38def coerce_uchar_bytes_cast(unsigned char c):
39    """
40    Explicit uchar -> bytes coercion
41
42    >>> coerce_uchar_bytes_cast(ord('A')) == 'A'.encode('ASCII')
43    True
44    >>> b = coerce_uchar_bytes_cast(ord('\\xff'))
45    >>> b == '\\xff' or b == '\\xff'.encode('ISO-8859-1') # Py2 or Py3
46    True
47    """
48    return <bytes>c
49
50
51@cython.test_assert_path_exists("//CoerceIntToBytesNode")
52@cython.test_fail_if_path_exists("//CoerceToPyTypeNode")
53def coerce_int_bytes_cast(int c):
54    """
55    Explicit int -> bytes coercion
56
57    >>> coerce_int_bytes_cast(ord('A')) == 'A'.encode('ASCII')
58    True
59    >>> coerce_int_bytes_cast(ord('A') + 0x100)
60    Traceback (most recent call last):
61    OverflowError: value too large to pack into a byte
62    >>> coerce_int_bytes_cast(ord('A') - 0x100)
63    Traceback (most recent call last):
64    OverflowError: value too large to pack into a byte
65    """
66    return <bytes>c
67
68
69@cython.test_assert_path_exists("//CoerceIntToBytesNode")
70@cython.test_fail_if_path_exists("//CoerceToPyTypeNode")
71def coerce_uint_bytes_cast(unsigned int c):
72    """
73    Explicit uint -> bytes coercion
74
75    >>> coerce_uint_bytes_cast(ord('A')) == 'A'.encode('ASCII')
76    True
77    >>> b = coerce_uint_bytes_cast(ord('\\xff'))
78    >>> b == '\\xff' or b == '\\xff'.encode('ISO-8859-1') # Py2 or Py3
79    True
80
81    >>> coerce_uint_bytes_cast(ord('A') + 0x100)
82    Traceback (most recent call last):
83    OverflowError: value too large to pack into a byte
84    """
85    return <bytes>c
86
87
88@cython.test_assert_path_exists("//CoerceIntToBytesNode")
89@cython.test_fail_if_path_exists("//CoerceToPyTypeNode")
90def coerce_char_bytes_assign(char c):
91    """
92    Implicit char -> bytes coercion in assignments
93
94    >>> coerce_char_bytes_assign(ord('A')) == 'A'.encode('ASCII')
95    True
96    """
97    cdef bytes s = c
98    return s
99
100
101@cython.test_assert_path_exists("//CoerceIntToBytesNode")
102@cython.test_fail_if_path_exists("//CoerceToPyTypeNode")
103def coerce_uchar_bytes_assign(unsigned char c):
104    """
105    Implicit uchar -> bytes coercion in assignments
106
107    >>> coerce_uchar_bytes_assign(ord('A')) == 'A'.encode('ASCII')
108    True
109    >>> b = coerce_uchar_bytes_assign(ord('\\xff'))
110    >>> b == '\\xff' or b == '\\xff'.encode('ISO-8859-1') # Py2 or Py3
111    True
112    """
113    cdef bytes s = c
114    return s
115
116
117@cython.test_assert_path_exists("//CoerceIntToBytesNode")
118@cython.test_fail_if_path_exists("//CoerceToPyTypeNode")
119def coerce_int_bytes_assign(int c):
120    """
121    Implicit int -> bytes coercion in assignments
122
123    >>> coerce_int_bytes_assign(ord('A')) == 'A'.encode('ASCII')
124    True
125
126    >>> coerce_int_bytes_assign(ord('A') + 0x100)
127    Traceback (most recent call last):
128    OverflowError: value too large to pack into a byte
129    >>> coerce_int_bytes_assign(ord('A') - 0x100)
130    Traceback (most recent call last):
131    OverflowError: value too large to pack into a byte
132    """
133    cdef bytes s = c
134    return s
135
136
137@cython.test_assert_path_exists("//CoerceIntToBytesNode")
138@cython.test_fail_if_path_exists("//CoerceToPyTypeNode")
139def coerce_uint_bytes_assign(unsigned int c):
140    """
141    Implicit uint -> bytes coercion in assignments
142
143    >>> coerce_uint_bytes_assign(ord('A')) == 'A'.encode('ASCII')
144    True
145    >>> b = coerce_uint_bytes_assign(ord('\\xff'))
146    >>> b == '\\xff' or b == '\\xff'.encode('ISO-8859-1') # Py2 or Py3
147    True
148
149    >>> coerce_uint_bytes_assign(ord('A') + 0x100)
150    Traceback (most recent call last):
151    OverflowError: value too large to pack into a byte
152    """
153    cdef bytes s = c
154    return s
155
156
157def inplace_ops_use_arithmetic():
158    """
159    >>> print(inplace_ops_use_arithmetic().decode('ascii'))
160    bc
161    """
162    cdef char* s = 'abc'
163    cdef object x = 1
164    s += 1
165    s += 2*x
166    s -= 1
167    s -= x
168    return s
169
170
171@cython.test_fail_if_path_exists('//CoerceFromPyTypeNode')
172def indexing_to_char(bytes s):
173    """
174    >>> ord('b')
175    98
176    >>> indexing_to_char('abc'.encode('ascii'))
177    98
178    """
179    cdef unsigned char c = s[1]
180    return c
181