summaryrefslogtreecommitdiff
path: root/tests/run/extra_patma_py.py
blob: a5046b997eaeea745e3392ae9acf92f2f32ebab3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# mode: run
# tag: pure3.10

from __future__ import print_function

import array
import sys

__doc__ = ""

def test_type_inference(x):
    """
    The type should not be infered to be anything specific
    >>> test_type_inference(1)
    one 1
    >>> test_type_inference([])
    any object []
    """
    match x:
        case 1 as a:
            print("one", a)
        case a:
            print("any object", a)


def test_assignment_and_guards(x):
    """
    Tests that the flow control is right. The second case can be
    reached either by failing the pattern or by failing the guard,
    and this affects whether variables are assigned
    >>> test_assignment_and_guards([1])
    ('first', 1)
    >>> test_assignment_and_guards([1, 2])
    ('second', 1)
    >>> test_assignment_and_guards([-1, 2])
    ('second', -1)
    """
    match x:
        case [a] if a>0:
            return "first", a
        case [a, *_]:
            return "second", a


def test_array_is_sequence(x):
    """
    Because this has to be specifically special-cased on early Python versions
    >>> test_array_is_sequence(array.array('i', [0, 1, 2]))
    1
    >>> test_array_is_sequence(array.array('i', [0, 1, 2, 3, 4]))
    [0, 1, 2, 3, 4]
    """
    match x:
        case [0, y, 2]:
            return y
        case [*z]:
            return z
        case _:
            return "Not a sequence"


def test_duplicate_keys(key1, key2):
    """
    Extra to TestValueErrors in test_patma
    Cython sorts keys into literal and runtime. This tests when two runtime keys clash

    >>> test_duplicate_keys("a", "b")
    True

    Slightly awkward doctest to work around Py2 incompatibility
    >>> try:
    ...    test_duplicate_keys("a", "a")
    ... except ValueError as e:
    ...    if sys.version_info[0] > 2:
    ...        assert e.args[0] == "mapping pattern checks duplicate key ('a')", e.args[0]
    ...    else:
    ...        assert e.args[0] == "mapping pattern checks duplicate key"
    """
    class Keys:
        KEY_1 = key1
        KEY_2 = key2

    match {"a": 1, "b": 2}:
        case {Keys.KEY_1: _, Keys.KEY_2: _}:
            return True
        case _:
            return False


class PyClass(object):
    pass


class PrivateAttrLookupOuter:
    """
    CPython doesn't mangle private names in class patterns
    (so Cython should do the same)

    >>> py_class_inst = PyClass()
    >>> py_class_inst._PyClass__something = 1
    >>> py_class_inst._PrivateAttrLookupOuter__something = 2
    >>> py_class_inst.__something = 3
    >>> PrivateAttrLookupOuter().f(py_class_inst)
    3
    """
    def f(self, x):
        match x:
            case PyClass(__something=y):
                return y


if sys.version_info[0] < 3:
    class OldStyleClass:
        pass

    def test_oldstyle_class_failure(x):
        match x:
            case OldStyleClass():
                return True

    __doc__ += """
    >>> test_oldstyle_class_failure(1)
    Traceback (most recent call last):
    ...
    TypeError: called match pattern must be a new-style class.
    """