Skip to content

Render @decorator syntax for function and class defs#612

Open
mariopenterman wants to merge 1 commit into
zrax:masterfrom
mariopenterman:pr/decorator-syntax
Open

Render @decorator syntax for function and class defs#612
mariopenterman wants to merge 1 commit into
zrax:masterfrom
mariopenterman:pr/decorator-syntax

Conversation

@mariopenterman

@mariopenterman mariopenterman commented Jun 22, 2026

Copy link
Copy Markdown

Decorated function/class defs are currently mis-rendered as an IIFE, silently dropping the decorator and producing invalid Python.

Before (current master)

@staticmethod
def f(): pass

decompiles to:

f = (lambda : pass)()        # not valid Python

After this PR

@staticmethod
def f():
    pass

What it does

On 3.11 a decorated def compiles to LOAD <deco>; MAKE_FUNCTION; PRECALL 0; CALL 0, leaving the function in the CALL "self" slot with argc 0. This recognizes that no-arg-CALL-of-a-freshly-built-def pattern as decorator application, attaches the call chain to the def, and emits real @deco lines. Single, stacked, and dotted decorators are handled.

A self-contained test (tests/input/decorators.py + compiled .pyc + expected tokenized output) is included; the full suite stays green.

Reconstruct decorator application (PEP 318) for Python 3.11. A decorated def
compiles to `LOAD <deco>; MAKE_FUNCTION; PRECALL 0; CALL 0`, leaving the
function in the CALL "self" slot with argc 0; previously this was mis-rendered
as an IIFE `name = (lambda ...)()`, silently dropping the decorator.

- ASTFunction / ASTClass carry an ordered decorator list.
- A no-arg CALL whose callable is a freshly built function/class is recognized
  as decorator application: the def is bound to its name and the decorator
  wraps that name.
- When a store re-binds a def's name to `deco(name)`, the call chain is peeled
  and attached to the def so the printer emits real `@deco` lines.

Function and method decorators (single, stacked, and dotted) now render as
proper decorator syntax.

Signed-off-by: Mario Penterman <mariopenterman@gmail.com>
@mariopenterman mariopenterman marked this pull request as ready for review June 22, 2026 22:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant