File: pypy-738-decorated-functions.txt

package info (click to toggle)
python-coverage 7.8.2%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 4,188 kB
  • sloc: python: 31,123; ansic: 1,184; javascript: 773; makefile: 304; sh: 107; xml: 48
file content (97 lines) | stat: -rw-r--r-- 3,398 bytes parent folder | download | duplicates (3)
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
Comparing versions:

export PY38=/usr/local/pyenv/pyenv/versions/3.8.12/bin/python3.8
export PY39=/usr/local/pyenv/pyenv/versions/3.9.10/bin/python3.9
export PP38old=/usr/local/pypy/pypy3.8-v7.3.7-osx64/bin/pypy3
export PP38=/usr/local/pypy/pypy3.8-v7.3.8rc1-osx64/bin/pypy3
export PP39=/usr/local/pypy/pypy3.9-v7.3.8rc1-osx64/bin/pypy3

$ for py in $PY38 $PY39 $PP38old $PP38 $PP39; do $py -m coverage run --debug=pybehave igor.py; done 2>&1 | grep trace
            trace_decorated_def: True
     trace_decorator_line_again: False
            trace_decorated_def: True
     trace_decorator_line_again: False
            trace_decorated_def: False
     trace_decorator_line_again: False
            trace_decorated_def: False
     trace_decorator_line_again: False
            trace_decorated_def: False
     trace_decorator_line_again: False

# t466a_ast.py:
    import ast
    import sys

    def find_function(node, name):
        if node.__class__.__name__ == "FunctionDef" and node.name == name:
            return node
        for node in getattr(node, "body", ()):
            fnode = find_function(node, name)
            if fnode is not None:
                return fnode

    root_node = ast.parse(open(__file__).read())
    func_node = find_function(root_node, "parse")

    print(func_node.name, func_node.lineno, func_node.end_lineno, tuple(sys.version_info), tuple(getattr(sys, "pypy_version_info", ())))

    class Parser(object):

        @classmethod
        def parse(cls):
            formats = [ 5 ]


            return None

    Parser.parse()


$ for py in $PY38 $PY39 $PP38old $PP38 $PP39; do $py t466a_ast.py; done
parse 20 24 (3, 8, 12, 'final', 0) ()
parse 20 24 (3, 9, 10, 'final', 0) ()
parse 19 -1 (3, 8, 12, 'final', 0) (7, 3, 7, 'final', 0)
parse 19 -1 (3, 8, 12, 'final', 0) (7, 3, 8, 'final', 0)
parse 20 24 (3, 9, 10, 'final', 0) (7, 3, 8, 'final', 0)


PyPy <=3.8 includes the decorator line in the FunctionDef node
PyPy >=3.9 does not include the decorator line in the node

PyPy traces the decorator line, but not the def:

$ $PP38 -m trace --trace t466a_plain.py
 --- modulename: t466a_plain, funcname: <module>
t466a_plain.py(1): class Parser(object):
 --- modulename: t466a_plain, funcname: Parser
t466a_plain.py(1): class Parser(object):
t466a_plain.py(3):     @classmethod
t466a_plain.py(10): Parser.parse()
 --- modulename: t466a_plain, funcname: parse
t466a_plain.py(5):         formats = [ 5 ]
t466a_plain.py(8):         return None

$ $PP39 -m trace --trace t466a_plain.py
 --- modulename: t466a_plain, funcname: <module>
t466a_plain.py(1): class Parser(object):
 --- modulename: t466a_plain, funcname: Parser
t466a_plain.py(1): class Parser(object):
t466a_plain.py(3):     @classmethod
t466a_plain.py(10): Parser.parse()
 --- modulename: t466a_plain, funcname: parse
t466a_plain.py(5):         formats = [ 5 ]
t466a_plain.py(8):         return None

CPython traces the decorator and the def:

$ $PY39 -m trace --trace t466a_plain.py
 --- modulename: t466a_plain, funcname: <module>
t466a_plain.py(1): class Parser(object):
 --- modulename: t466a_plain, funcname: Parser
t466a_plain.py(1): class Parser(object):
t466a_plain.py(3):     @classmethod
t466a_plain.py(4):     def parse(cls):
t466a_plain.py(10): Parser.parse()
 --- modulename: t466a_plain, funcname: parse
t466a_plain.py(5):         formats = [ 5 ]
t466a_plain.py(8):         return None