File: cell_free_vars_cases.py

package info (click to toggle)
python-bytecode 0.16.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 780 kB
  • sloc: python: 8,300; makefile: 169; sh: 40
file content (106 lines) | stat: -rw-r--r-- 2,091 bytes parent folder | download | duplicates (2)
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
# Function making heavy use of cell and free vars to test bytecode round tripping
# capabilities.


def simple_cellvar():  # a cellvar in f
    a = 1

    def g():  # a freevar in g
        return a

    return g


def cellvar_share_name(a=1):  # a cellvar in f, but stored as varname
    def g():  # a freevar in g
        return a

    return g


def cellvar_shared_and_unshared(a=1):  # a, b cellvar in f, but a stored as varname
    b = 1

    def g():  # a, b freevar in g
        return a + b

    return g


class A:
    a = 1

    def f(self):
        return 1


def class_loadderef():
    a = 1

    class B(A):
        b = a

    return B.b


# NOTE aliasing super such that there is no LOAD_GLOBAL super cause the omission of
# the required implicit __class__ cell which breaks the subsequent call
# Under Python 3.11 the creation of cellvars is made explicit by MAKE_CELL


def class_super():
    class B(A):
        def f(self):
            super().f()

    return B().f


def test_freevar():
    class Foo:
        r = 0

        @classmethod
        def bar(cls, k):
            class Snafu(k):
                def do_debug(self, arg):
                    cls.r += 1
                    return super().d(arg)

            return Snafu


# NOTE this is not really a cell var case but it ensures proper
# placements of CACHE vs labels
_localedirs: dict = {}
_default_localedir = ""


def bindtextdomain(domain="", localedir=None):
    global _localedirs
    if localedir is not None:
        _localedirs[domain] = localedir
    return _localedirs.get(domain, _default_localedir)


TEST_CASES = [
    simple_cellvar,
    cellvar_share_name,
    cellvar_shared_and_unshared,
    class_super,
    class_loadderef,
    bindtextdomain,
    test_freevar,
]

if __name__ == "__main__":
    import dis
    import inspect

    for f in TEST_CASES:
        print("--------------------------------------------------------------")
        for line in inspect.getsourcelines(f)[0]:  # type: ignore
            print(line.rstrip())
        print()
        dis.dis(f.__code__)
        print()