1
2cimport cython
3
4
5def cython_set():
6    """
7    >>> cython_set() is set
8    True
9    """
10    assert set is cython.set
11    return cython.set
12
13
14def cython_frozenset():
15    """
16    >>> cython_frozenset() is frozenset
17    True
18    """
19    assert frozenset is cython.frozenset
20    return cython.frozenset
21
22
23def cython_set_override():
24    """
25    >>> cython_set_override() is set
26    True
27    """
28    set = 1
29    return cython.set
30
31
32def cython_frozenset_override():
33    """
34    >>> cython_frozenset_override() is frozenset
35    True
36    """
37    frozenset = 1
38    return cython.frozenset
39
40
41def test_set_literal():
42    """
43    >>> type(test_set_literal()) is set
44    True
45    >>> sorted(test_set_literal())
46    ['a', 'b', 1]
47    """
48    cdef set s1 = {1,'a',1,'b','a'}
49    return s1
50
51
52def test_set_add():
53    """
54    >>> type(test_set_add()) is set
55    True
56    >>> sorted(test_set_add())
57    ['a', 1, (1, 2)]
58    """
59    cdef set s1
60    s1 = set([1, (1, 2)])
61    s1.add(1)
62    s1.add('a')
63    s1.add(1)
64    s1.add((1,2))
65    return s1
66
67
68def test_set_contains(v):
69    """
70    >>> test_set_contains(1)
71    True
72    >>> test_set_contains(2)
73    False
74    >>> test_set_contains(frozenset([1, 2, 3]))
75    True
76    >>> test_set_contains(frozenset([1, 2]))
77    False
78    >>> test_set_contains(set([1, 2, 3]))
79    True
80    >>> test_set_contains(set([1, 2]))
81    False
82    >>> try: test_set_contains([1, 2])
83    ... except TypeError: pass
84    ... else: print("NOT RAISED!")
85    """
86    cdef set s1
87    s1 = set()
88    s1.add(1)
89    s1.add('a')
90    s1.add(frozenset([1, 2, 3]))
91    return v in s1
92
93
94def test_set_update(v=None):
95    """
96    >>> type(test_set_update()) is set
97    True
98    >>> sorted(test_set_update())
99    ['a', 'b', 'c', 1, 2, (1, 2)]
100    >>> sorted(test_set_update([]))
101    ['a', 'b', 'c', 1, 2, (1, 2)]
102    >>> try: test_set_update(object())
103    ... except TypeError: pass
104    ... else: print("NOT RAISED!")
105    """
106    cdef set s1
107    s1 = set([1, (1, 2)])
108    s1.update((1,))
109    s1.update('abc')
110    s1.update(set([1]))
111    s1.update(frozenset((1,2)))
112    if v is not None:
113        s1.update(v)
114    return s1
115
116
117def test_set_multi_update():
118    """
119    >>> type(test_set_multi_update()) is set
120    True
121    >>> sorted(test_set_multi_update())
122    ['a', 'b', 'c', 1, 2, 3]
123    """
124    cdef set s1 = set()
125    s1.update('abc', set([1, 3]), frozenset([1, 2]))
126    return s1
127
128
129def test_object_update(v=None):
130    """
131    >>> type(test_object_update()) is set
132    True
133    >>> sorted(test_object_update())
134    ['a', 'b', 'c', 1, 2, (1, 2)]
135    >>> sorted(test_object_update([]))
136    ['a', 'b', 'c', 1, 2, (1, 2)]
137    >>> try: test_object_update(object())
138    ... except TypeError: pass
139    ... else: print("NOT RAISED!")
140    """
141    cdef object s1
142    s1 = set([1, (1, 2)])
143    s1.update((1,))
144    s1.update('abc')
145    s1.update(set([1]))
146    s1.update(frozenset((1,2)))
147    if v is not None:
148        s1.update(v)
149    return s1
150
151
152def test_set_clear():
153    """
154    >>> type(test_set_clear()) is set
155    True
156    >>> list(test_set_clear())
157    []
158    """
159    cdef set s1
160    s1 = set([1])
161    s1.clear()
162    return s1
163
164
165def test_set_clear_None():
166    """
167    >>> test_set_clear_None()
168    Traceback (most recent call last):
169    AttributeError: 'NoneType' object has no attribute 'clear'
170    """
171    cdef set s1 = None
172    s1.clear()
173
174
175def test_set_list_comp():
176    """
177    >>> type(test_set_list_comp()) is set
178    True
179    >>> sorted(test_set_list_comp())
180    [0, 1, 2]
181    """
182    cdef set s1
183    s1 = set([i%3 for i in range(5)])
184    return s1
185
186
187def test_frozenset_list_comp():
188    """
189    >>> type(test_frozenset_list_comp()) is frozenset
190    True
191    >>> sorted(test_frozenset_list_comp())
192    [0, 1, 2]
193    """
194    cdef frozenset s1
195    s1 = frozenset([i%3 for i in range(5)])
196    return s1
197
198
199def test_set_pop():
200    """
201    >>> type(test_set_pop()) is set
202    True
203    >>> list(test_set_pop())
204    []
205    """
206    cdef set s1
207    s1 = set()
208    s1.add('2')
209    two = s1.pop()
210    return s1
211
212
213@cython.test_fail_if_path_exists("//SimpleCallNode//NameNode")
214def test_object_pop(s):
215    """
216    >>> s = set([2])
217    >>> test_object_pop(s)
218    2
219    >>> list(s)
220    []
221    """
222    return s.pop()
223
224
225def test_noop_pop():
226    """
227    >>> test_noop_pop()
228    """
229    set([0]).pop()
230
231
232def test_noop_pop_exception():
233    """
234    >>> try: test_noop_pop_exception()
235    ... except KeyError: pass
236    ... else: print("KeyError expected but not raised!")
237    """
238    set([]).pop()
239
240
241def test_set_discard():
242    """
243    >>> type(test_set_discard()) is set
244    True
245    >>> sorted(test_set_discard())
246    ['12', 233]
247    """
248    cdef set s1
249    s1 = set()
250    s1.add('12')
251    s1.add(3)
252    s1.add(233)
253    s1.discard('3')
254    s1.discard(3)
255    return s1
256
257
258def test_set_sideeffect_unhashable_failure():
259    """
260    >>> test_set_sideeffect_unhashable_failure()
261    [2, 4, 5]
262    """
263    L = []
264    def sideeffect(x):
265        L.append(x)
266        return x
267    def unhashable_value(x):
268        L.append(x)
269        return set()
270    try:
271        s = set([1,sideeffect(2),3,unhashable_value(4),sideeffect(5)])
272    except TypeError: pass
273    else: assert False, "expected exception not raised"
274    return L
275
276
277def test_set_sideeffect_unhashable_failure_literal():
278    """
279    >>> test_set_sideeffect_unhashable_failure_literal()
280    [2, 4, 5]
281    """
282    L = []
283    def sideeffect(x):
284        L.append(x)
285        return x
286    def unhashable_value(x):
287        L.append(x)
288        return set()
289    try:
290        s = {1,sideeffect(2),3,unhashable_value(4),sideeffect(5)}
291    except TypeError: pass
292    else: assert False, "expected exception not raised"
293    return L
294
295
296def test_frozenset_sideeffect_unhashable_failure():
297    """
298    >>> test_frozenset_sideeffect_unhashable_failure()
299    [2, 4, 5]
300    """
301    L = []
302    def sideeffect(x):
303        L.append(x)
304        return x
305    def unhashable_value(x):
306        L.append(x)
307        return set()
308    try:
309        s = frozenset([1,sideeffect(2),3,unhashable_value(4),sideeffect(5)])
310    except TypeError: pass
311    else: assert False, "expected exception not raised"
312    return L
313
314
315@cython.test_assert_path_exists("//SetNode")
316@cython.test_fail_if_path_exists(
317    "//SimpleCallNode",
318    "//PythonCapiCallNode"
319)
320def test_set_of_list():
321    """
322    >>> s = test_set_of_list()
323    >>> isinstance(s, set)
324    True
325    >>> sorted(s)
326    [1, 2, 3]
327    """
328    return set([1, 2, 3])
329
330
331@cython.test_assert_path_exists("//PythonCapiCallNode")
332@cython.test_fail_if_path_exists("//SetNode")
333def test_frozenset_of_list():
334    """
335    >>> s = test_frozenset_of_list()
336    >>> isinstance(s, frozenset)
337    True
338    >>> sorted(s)
339    [1, 2, 3]
340    """
341    return frozenset([1, 2, 3])
342
343
344@cython.test_assert_path_exists("//SetNode")
345@cython.test_fail_if_path_exists("//SimpleCallNode")
346def test_set_of_tuple():
347    """
348    >>> s = test_set_of_tuple()
349    >>> isinstance(s, set)
350    True
351    >>> sorted(s)
352    [1, 2, 3]
353    """
354    return set((1, 2, 3))
355
356
357@cython.test_assert_path_exists("//PythonCapiCallNode")
358@cython.test_fail_if_path_exists("//SetNode")
359def test_frozenset_of_tuple():
360    """
361    >>> s = test_frozenset_of_tuple()
362    >>> isinstance(s, frozenset)
363    True
364    >>> sorted(s)
365    [1, 2, 3]
366    """
367    return frozenset((1, 2, 3))
368
369
370@cython.test_assert_path_exists("//PythonCapiCallNode")
371@cython.test_fail_if_path_exists(
372    "//SimpleCallNode",
373    "//SetNode"
374)
375def test_set_of_iterable(x):
376    """
377    >>> s = test_set_of_iterable([1, 2, 3])
378    >>> isinstance(s, set)
379    True
380    >>> sorted(s)
381    [1, 2, 3]
382    """
383    return set(x)
384
385
386@cython.test_assert_path_exists("//PythonCapiCallNode")
387@cython.test_fail_if_path_exists(
388    "//SimpleCallNode",
389    "//SetNode"
390)
391def test_frozenset_of_iterable(x):
392    """
393    >>> s = test_frozenset_of_iterable([1, 2, 3])
394    >>> isinstance(s, frozenset)
395    True
396    >>> sorted(s)
397    [1, 2, 3]
398
399    >>> s = test_frozenset_of_iterable(frozenset([1, 2, 3]))
400    >>> isinstance(s, frozenset)
401    True
402    >>> sorted(s)
403    [1, 2, 3]
404    """
405    return frozenset(x)
406
407
408@cython.test_assert_path_exists("//PythonCapiCallNode")
409@cython.test_fail_if_path_exists(
410    "//SimpleCallNode",
411    "//SetNode"
412)
413def test_empty_frozenset():
414    """
415    >>> s = test_empty_frozenset()
416    >>> isinstance(s, frozenset)
417    True
418    >>> len(s)
419    0
420    >>> import sys
421    >>> sys.version_info >= (3, 10) or s is frozenset()   # singleton (in Python < 3.10)!
422    True
423    """
424    return frozenset()
425
426
427@cython.test_fail_if_path_exists(
428    '//ListNode//ListNode',
429    '//ListNode//PythonCapiCallNode//PythonCapiCallNode',
430    '//ListNode//SimpleCallNode//SimpleCallNode',
431)
432def test_singleton_empty_frozenset():
433    """
434    >>> import sys
435    >>> test_singleton_empty_frozenset() if sys.version_info < (3, 10) else 1  # from CPython's test_set.py
436    1
437    """
438    f = frozenset()
439    efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
440           frozenset(), frozenset([]), frozenset(()), frozenset(''),
441           frozenset(range(0)), frozenset(frozenset()),
442           frozenset(f), f]
443    return len(set(map(id, efs)))  # note, only a singleton in Python <3.10
444
445
446def sorted(it):
447    # Py3 can't compare different types
448    chars = []
449    nums = []
450    tuples = []
451    for item in it:
452        if type(item) is int:
453            nums.append(item)
454        elif type(item) is tuple:
455            tuples.append(item)
456        else:
457            chars.append(item)
458    nums.sort()
459    chars.sort()
460    tuples.sort()
461    return chars+nums+tuples
462