1
2cimport cython
3
4
5### extension types
6
7cdef class MyExtType:
8    cdef object attr
9    def __cinit__(self):
10        self.attr = 123
11
12cdef attr(MyExtType x):
13    return x is None and 321 or x.attr
14
15
16# defaults, without 'not/or None'
17
18def ext_default(MyExtType x): # currently behaves like 'or None'
19    """
20    >>> ext_default(MyExtType())
21    123
22    >>> ext_default(None)
23    321
24    """
25    return attr(x)
26
27@cython.allow_none_for_extension_args(False)
28def ext_default_none(MyExtType x=None): # special cased default arg
29    """
30    >>> ext_default_none(MyExtType())
31    123
32    >>> ext_default_none(None)
33    321
34    >>> ext_default_none()
35    321
36    """
37    return attr(x)
38
39@cython.allow_none_for_extension_args(True)
40def ext_default_check_off(MyExtType x):
41    """
42    >>> ext_default_check_off(MyExtType())
43    123
44    >>> ext_default_check_off(None)
45    321
46    """
47    return attr(x)
48
49@cython.allow_none_for_extension_args(False)
50def ext_default_check_on(MyExtType x):
51    """
52    >>> ext_default_check_on(MyExtType())
53    123
54    >>> ext_default_check_on(None)
55    Traceback (most recent call last):
56    TypeError: Argument 'x' has incorrect type (expected ext_type_none_arg.MyExtType, got NoneType)
57    """
58    return attr(x)
59
60
61# with 'or/not None'
62
63def ext_or_none(MyExtType x or None):
64    """
65    >>> ext_or_none(MyExtType())
66    123
67    >>> ext_or_none(None)
68    321
69    """
70    return attr(x)
71
72def ext_not_none(MyExtType x not None):
73    """
74    >>> ext_not_none(MyExtType())
75    123
76    >>> ext_not_none(None)
77    Traceback (most recent call last):
78    TypeError: Argument 'x' has incorrect type (expected ext_type_none_arg.MyExtType, got NoneType)
79    """
80    return attr(x)
81
82
83### builtin types (using list)
84
85cdef litem(list L, int item):
86    return L is None and 321 or L[item]
87
88
89# defaults, without 'not/or None'
90
91def builtin_default(list L): # currently behaves like 'or None'
92    """
93    >>> builtin_default([123])
94    123
95    >>> builtin_default(None)
96    321
97    """
98    return litem(L, 0)
99
100@cython.allow_none_for_extension_args(False)
101def builtin_default_none(list L=None): # special cased default arg
102    """
103    >>> builtin_default_none([123])
104    123
105    >>> builtin_default_none(None)
106    321
107    >>> builtin_default_none()
108    321
109    """
110    return litem(L, 0)
111
112@cython.allow_none_for_extension_args(True)
113def builtin_default_check_off(list L):
114    """
115    >>> builtin_default_check_off([123])
116    123
117    >>> builtin_default_check_off(None)
118    321
119    """
120    return litem(L, 0)
121
122@cython.allow_none_for_extension_args(False)
123def builtin_default_check_on(list L):
124    """
125    >>> builtin_default_check_on([123])
126    123
127    >>> builtin_default_check_on(None)
128    Traceback (most recent call last):
129    TypeError: Argument 'L' has incorrect type (expected list, got NoneType)
130    """
131    return litem(L, 0)
132
133
134# with 'or/not None'
135
136def builtin_or_none(list L or None):
137    """
138    >>> builtin_or_none([123])
139    123
140    >>> builtin_or_none(None)
141    321
142    """
143    return litem(L, 0)
144
145def builtin_not_none(list L not None):
146    """
147    >>> builtin_not_none([123])
148    123
149    >>> builtin_not_none(None)
150    Traceback (most recent call last):
151    TypeError: Argument 'L' has incorrect type (expected list, got NoneType)
152    """
153    return litem(L, 0)
154
155
156## builtin type 'object' - isinstance(None, object) is True!
157
158@cython.allow_none_for_extension_args(False)
159def object_default(object o): # always behaves like 'or None'
160    """
161    >>> object_default(object())
162    'object'
163    >>> object_default([])
164    'list'
165    >>> object_default(None)
166    'NoneType'
167    """
168    return type(o).__name__
169
170@cython.allow_none_for_extension_args(False)
171def object_default_none(object o=None): # behaves like 'or None'
172    """
173    >>> object_default_none(object())
174    'object'
175    >>> object_default_none([])
176    'list'
177    >>> object_default_none(None)
178    'NoneType'
179    >>> object_default_none()
180    'NoneType'
181    """
182    return type(o).__name__
183
184@cython.allow_none_for_extension_args(False)
185def object_or_none(object o or None):
186    """
187    >>> object_or_none(object())
188    'object'
189    >>> object_or_none([])
190    'list'
191    >>> object_or_none(None)
192    'NoneType'
193    """
194    return type(o).__name__
195
196@cython.allow_none_for_extension_args(False)
197def object_not_none(object o not None):
198    """
199    >>> object_not_none(object())
200    'object'
201    >>> object_not_none([])
202    'list'
203    >>> object_not_none(None)
204    Traceback (most recent call last):
205    TypeError: Argument 'o' must not be None
206    """
207    return type(o).__name__
208
209
210## untyped 'object' - isinstance(None, object) is True!
211
212@cython.allow_none_for_extension_args(False)
213def notype_default(o): # behaves like 'or None'
214    """
215    >>> notype_default(object())
216    'object'
217    >>> notype_default([])
218    'list'
219    >>> notype_default(None)
220    'NoneType'
221    """
222    return type(o).__name__
223
224@cython.allow_none_for_extension_args(False)
225def notype_default_none(o=None): # behaves like 'or None'
226    """
227    >>> notype_default_none(object())
228    'object'
229    >>> notype_default_none([])
230    'list'
231    >>> notype_default_none(None)
232    'NoneType'
233    >>> notype_default_none()
234    'NoneType'
235    """
236    return type(o).__name__
237
238@cython.allow_none_for_extension_args(False)
239def notype_or_none(o or None):
240    """
241    >>> notype_or_none(object())
242    'object'
243    >>> notype_or_none([])
244    'list'
245    >>> notype_or_none(None)
246    'NoneType'
247    """
248    return type(o).__name__
249
250@cython.allow_none_for_extension_args(False)
251def notype_not_none(o not None):
252    """
253    >>> notype_not_none(object())
254    'object'
255    >>> notype_not_none([])
256    'list'
257    >>> notype_not_none(None)
258    Traceback (most recent call last):
259    TypeError: Argument 'o' must not be None
260    """
261    return type(o).__name__
262