set.pyx 9.28 KB
Newer Older
Stefan Behnel's avatar
Stefan Behnel committed
1

2 3
cimport cython

4

5 6
def cython_set():
    """
Stefan Behnel's avatar
Stefan Behnel committed
7
    >>> cython_set() is set
8 9 10 11 12
    True
    """
    assert set is cython.set
    return cython.set

13 14 15

def cython_frozenset():
    """
Stefan Behnel's avatar
Stefan Behnel committed
16
    >>> cython_frozenset() is frozenset
17 18 19 20 21 22
    True
    """
    assert frozenset is cython.frozenset
    return cython.frozenset


23 24
def cython_set_override():
    """
Stefan Behnel's avatar
Stefan Behnel committed
25
    >>> cython_set_override() is set
26 27 28 29 30
    True
    """
    set = 1
    return cython.set

31 32 33

def cython_frozenset_override():
    """
Stefan Behnel's avatar
Stefan Behnel committed
34
    >>> cython_frozenset_override() is frozenset
35 36 37 38 39 40
    True
    """
    frozenset = 1
    return cython.frozenset


41
def test_set_literal():
42
    """
Stefan Behnel's avatar
Stefan Behnel committed
43
    >>> type(test_set_literal()) is set
44 45 46 47 48
    True
    >>> sorted(test_set_literal())
    ['a', 'b', 1]
    """
    cdef set s1 = {1,'a',1,'b','a'}
49 50
    return s1

51

52
def test_set_add():
53
    """
Stefan Behnel's avatar
Stefan Behnel committed
54
    >>> type(test_set_add()) is set
55 56
    True
    >>> 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 66
    return s1

67

68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
def test_set_contains(v):
    """
    >>> test_set_contains(1)
    True
    >>> test_set_contains(2)
    False
    >>> test_set_contains(frozenset([1, 2, 3]))
    True
    >>> test_set_contains(frozenset([1, 2]))
    False
    >>> test_set_contains(set([1, 2, 3]))
    True
    >>> test_set_contains(set([1, 2]))
    False
    >>> try: test_set_contains([1, 2])
    ... except TypeError: pass
    ... else: print("NOT RAISED!")
    """
    cdef set s1
    s1 = set()
    s1.add(1)
    s1.add('a')
    s1.add(frozenset([1, 2, 3]))
    return v in s1


Stefan Behnel's avatar
Stefan Behnel committed
94 95
def test_set_update(v=None):
    """
Stefan Behnel's avatar
Stefan Behnel committed
96
    >>> type(test_set_update()) is set
Stefan Behnel's avatar
Stefan Behnel committed
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    True
    >>> sorted(test_set_update())
    ['a', 'b', 'c', 1, 2, (1, 2)]
    >>> sorted(test_set_update([]))
    ['a', 'b', 'c', 1, 2, (1, 2)]
    >>> try: test_set_update(object())
    ... except TypeError: pass
    ... else: print("NOT RAISED!")
    """
    cdef set s1
    s1 = set([1, (1, 2)])
    s1.update((1,))
    s1.update('abc')
    s1.update(set([1]))
    s1.update(frozenset((1,2)))
    if v is not None:
        s1.update(v)
    return s1


Robert Bradshaw's avatar
Robert Bradshaw committed
117
def test_set_multi_update():
118 119 120 121
    """
    >>> type(test_set_multi_update()) is set
    True
    >>> sorted(test_set_multi_update())
Robert Bradshaw's avatar
Robert Bradshaw committed
122
    ['a', 'b', 'c', 1, 2, 3]
123 124
    """
    cdef set s1 = set()
Robert Bradshaw's avatar
Robert Bradshaw committed
125
    s1.update('abc', set([1, 3]), frozenset([1, 2]))
126 127 128
    return s1


Stefan Behnel's avatar
Stefan Behnel committed
129 130
def test_object_update(v=None):
    """
Stefan Behnel's avatar
Stefan Behnel committed
131
    >>> type(test_object_update()) is set
Stefan Behnel's avatar
Stefan Behnel committed
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
    True
    >>> sorted(test_object_update())
    ['a', 'b', 'c', 1, 2, (1, 2)]
    >>> sorted(test_object_update([]))
    ['a', 'b', 'c', 1, 2, (1, 2)]
    >>> try: test_object_update(object())
    ... except TypeError: pass
    ... else: print("NOT RAISED!")
    """
    cdef object s1
    s1 = set([1, (1, 2)])
    s1.update((1,))
    s1.update('abc')
    s1.update(set([1]))
    s1.update(frozenset((1,2)))
    if v is not None:
        s1.update(v)
    return s1


152
def test_set_clear():
153
    """
Stefan Behnel's avatar
Stefan Behnel committed
154
    >>> type(test_set_clear()) is set
155 156 157 158
    True
    >>> list(test_set_clear())
    []
    """
159 160 161 162 163
    cdef set s1
    s1 = set([1])
    s1.clear()
    return s1

164

165 166 167
def test_set_clear_None():
    """
    >>> test_set_clear_None()
Stefan Behnel's avatar
Stefan Behnel committed
168
    Traceback (most recent call last):
169
    AttributeError: 'NoneType' object has no attribute 'clear'
170 171 172 173
    """
    cdef set s1 = None
    s1.clear()

174

175
def test_set_list_comp():
176
    """
Stefan Behnel's avatar
Stefan Behnel committed
177
    >>> type(test_set_list_comp()) is set
178 179 180 181
    True
    >>> sorted(test_set_list_comp())
    [0, 1, 2]
    """
182 183 184 185
    cdef set s1
    s1 = set([i%3 for i in range(5)])
    return s1

186 187 188

def test_frozenset_list_comp():
    """
Stefan Behnel's avatar
Stefan Behnel committed
189
    >>> type(test_frozenset_list_comp()) is frozenset
190 191 192 193 194 195 196 197 198
    True
    >>> sorted(test_frozenset_list_comp())
    [0, 1, 2]
    """
    cdef frozenset s1
    s1 = frozenset([i%3 for i in range(5)])
    return s1


199
def test_set_pop():
200
    """
Stefan Behnel's avatar
Stefan Behnel committed
201
    >>> type(test_set_pop()) is set
202 203 204 205
    True
    >>> list(test_set_pop())
    []
    """
206 207
    cdef set s1
    s1 = set()
208
    s1.add('2')
209 210 211
    two = s1.pop()
    return s1

212

213 214 215
@cython.test_fail_if_path_exists("//SimpleCallNode//NameNode")
def test_object_pop(s):
    """
Stefan Behnel's avatar
Stefan Behnel committed
216
    >>> s = set([2])
217 218 219 220 221 222 223
    >>> test_object_pop(s)
    2
    >>> list(s)
    []
    """
    return s.pop()

224

225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
def test_noop_pop():
    """
    >>> test_noop_pop()
    """
    set([0]).pop()


def test_noop_pop_exception():
    """
    >>> try: test_noop_pop_exception()
    ... except KeyError: pass
    ... else: print("KeyError expected but not raised!")
    """
    set([]).pop()


241
def test_set_discard():
242
    """
Stefan Behnel's avatar
Stefan Behnel committed
243
    >>> type(test_set_discard()) is set
244 245 246 247
    True
    >>> sorted(test_set_discard())
    ['12', 233]
    """
248 249
    cdef set s1
    s1 = set()
250
    s1.add('12')
251 252
    s1.add(3)
    s1.add(233)
253
    s1.discard('3')
254 255
    s1.discard(3)
    return s1
256

257

Stefan Behnel's avatar
Stefan Behnel committed
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
def test_set_sideeffect_unhashable_failure():
    """
    >>> test_set_sideeffect_unhashable_failure()
    [2, 4, 5]
    """
    L = []
    def sideeffect(x):
        L.append(x)
        return x
    def unhashable_value(x):
        L.append(x)
        return set()
    try:
        s = set([1,sideeffect(2),3,unhashable_value(4),sideeffect(5)])
    except TypeError: pass
    else: assert False, "expected exception not raised"
    return L

276

277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
def test_set_sideeffect_unhashable_failure_literal():
    """
    >>> test_set_sideeffect_unhashable_failure_literal()
    [2, 4, 5]
    """
    L = []
    def sideeffect(x):
        L.append(x)
        return x
    def unhashable_value(x):
        L.append(x)
        return set()
    try:
        s = {1,sideeffect(2),3,unhashable_value(4),sideeffect(5)}
    except TypeError: pass
    else: assert False, "expected exception not raised"
    return L


296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
def test_frozenset_sideeffect_unhashable_failure():
    """
    >>> test_frozenset_sideeffect_unhashable_failure()
    [2, 4, 5]
    """
    L = []
    def sideeffect(x):
        L.append(x)
        return x
    def unhashable_value(x):
        L.append(x)
        return set()
    try:
        s = frozenset([1,sideeffect(2),3,unhashable_value(4),sideeffect(5)])
    except TypeError: pass
    else: assert False, "expected exception not raised"
    return L


315
@cython.test_assert_path_exists("//SetNode")
316 317 318 319
@cython.test_fail_if_path_exists(
    "//SimpleCallNode",
    "//PythonCapiCallNode"
)
320 321 322
def test_set_of_list():
    """
    >>> s = test_set_of_list()
Stefan Behnel's avatar
Stefan Behnel committed
323
    >>> isinstance(s, set)
324 325 326 327 328 329
    True
    >>> sorted(s)
    [1, 2, 3]
    """
    return set([1, 2, 3])

330 331 332 333 334 335

@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//SetNode")
def test_frozenset_of_list():
    """
    >>> s = test_frozenset_of_list()
Stefan Behnel's avatar
Stefan Behnel committed
336
    >>> isinstance(s, frozenset)
337 338 339 340 341 342 343
    True
    >>> sorted(s)
    [1, 2, 3]
    """
    return frozenset([1, 2, 3])


344 345 346 347 348
@cython.test_assert_path_exists("//SetNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def test_set_of_tuple():
    """
    >>> s = test_set_of_tuple()
Stefan Behnel's avatar
Stefan Behnel committed
349
    >>> isinstance(s, set)
350 351 352 353
    True
    >>> sorted(s)
    [1, 2, 3]
    """
354
    return set((1, 2, 3))
355

356 357 358 359 360 361

@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//SetNode")
def test_frozenset_of_tuple():
    """
    >>> s = test_frozenset_of_tuple()
Stefan Behnel's avatar
Stefan Behnel committed
362
    >>> isinstance(s, frozenset)
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
    True
    >>> sorted(s)
    [1, 2, 3]
    """
    return frozenset((1, 2, 3))


@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists(
    "//SimpleCallNode",
    "//SetNode"
)
def test_set_of_iterable(x):
    """
    >>> s = test_set_of_iterable([1, 2, 3])
Stefan Behnel's avatar
Stefan Behnel committed
378
    >>> isinstance(s, set)
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
    True
    >>> sorted(s)
    [1, 2, 3]
    """
    return set(x)


@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists(
    "//SimpleCallNode",
    "//SetNode"
)
def test_frozenset_of_iterable(x):
    """
    >>> s = test_frozenset_of_iterable([1, 2, 3])
Stefan Behnel's avatar
Stefan Behnel committed
394
    >>> isinstance(s, frozenset)
395 396 397
    True
    >>> sorted(s)
    [1, 2, 3]
398

Stefan Behnel's avatar
Stefan Behnel committed
399 400
    >>> s = test_frozenset_of_iterable(frozenset([1, 2, 3]))
    >>> isinstance(s, frozenset)
401 402 403
    True
    >>> sorted(s)
    [1, 2, 3]
404 405 406 407
    """
    return frozenset(x)


408 409 410 411 412 413 414 415
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists(
    "//SimpleCallNode",
    "//SetNode"
)
def test_empty_frozenset():
    """
    >>> s = test_empty_frozenset()
Stefan Behnel's avatar
Stefan Behnel committed
416
    >>> isinstance(s, frozenset)
417 418 419
    True
    >>> len(s)
    0
420 421
    >>> import sys
    >>> sys.version_info >= (3, 10) or s is frozenset()   # singleton (in Python < 3.10)!
422 423 424 425 426
    True
    """
    return frozenset()


Stefan Behnel's avatar
Stefan Behnel committed
427 428 429 430 431
@cython.test_fail_if_path_exists(
    '//ListNode//ListNode',
    '//ListNode//PythonCapiCallNode//PythonCapiCallNode',
    '//ListNode//SimpleCallNode//SimpleCallNode',
)
432 433
def test_singleton_empty_frozenset():
    """
434 435
    >>> import sys
    >>> test_singleton_empty_frozenset() if sys.version_info < (3, 10) else 1  # from CPython's test_set.py
436 437 438 439 440 441 442
    1
    """
    f = frozenset()
    efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
           frozenset(), frozenset([]), frozenset(()), frozenset(''),
           frozenset(range(0)), frozenset(frozenset()),
           frozenset(f), f]
443
    return len(set(map(id, efs)))  # note, only a singleton in Python <3.10
444 445


446
def sorted(it):
447
    # Py3 can't compare different types
448 449
    chars = []
    nums = []
450
    tuples = []
451 452 453
    for item in it:
        if type(item) is int:
            nums.append(item)
454 455
        elif type(item) is tuple:
            tuples.append(item)
456 457 458 459
        else:
            chars.append(item)
    nums.sort()
    chars.sort()
460 461
    tuples.sort()
    return chars+nums+tuples