alexmojaki / executing

Get information about what a Python frame is currently doing, particularly the AST node being executed
MIT License
330 stars 32 forks source link

3.11 decorator detection bug #49

Closed alexmojaki closed 2 years ago

alexmojaki commented 2 years ago
import inspect

import executing

frame = inspect.currentframe()

class Tester:
    def __call__(self, f):
        deco(f)

tester = Tester()

def deco(f):
    assert f.__name__ == 'foo'
    ex = executing.Source.executing(frame)
    print(f"{ex.node = }\n{ex.decorator = }\n")

for d in [deco, tester]:
    @d
    def foo():
        pass

3.10 output:

ex.node = <ast.FunctionDef object at 0x7f9c7e65b1c0>
ex.decorator = <ast.Name object at 0x7f9c7e65a2f0>

ex.node = <ast.FunctionDef object at 0x7f9c7e65b1c0>
ex.decorator = <ast.Name object at 0x7f9c7e65a2f0>

3.11 output:

ex.node = <ast.Name object at 0x7fd9fe5a96f0>
ex.decorator = None

ex.node = <ast.FunctionDef object at 0x7fd9fe5a9780>
ex.decorator = <ast.Name object at 0x7fd9fe5a96f0>

Somehow, the decorator is only detected when it's an object with __call__. When it's just a function, executing sets decorator to None and node to the decorator instead of the function definition. This is REALLY weird.