Procedural macro in Python

Similar to this stuff in Rust.

The way to invoke procedural macro in Python (the wish of this proposal) should be like function call or decorator. with $ (the only available punctuation in Python language definition ). like hello_macro$(...) or @hello_macro2$.

Due to the dynamic feature of Python, procedural macro is simply a ordinary function with a string typed positional argument and return a string.

When invoke procedural, the Python interpreter feed the code snippet between the bracket of macro invocation, to the function of macro, then replace with the return string value of macro function.

And the macro can even defined after the invocation part of macro. like

m_usage = hello_macro$(1, 2, 3)

def hello_macro(s: str)->str:
    return f'["{s}"]'

The value of m_usage equals to "1, 2, 3".

When Python interpreter meet macro invocation, it will seeking for the definition of macro, if the definition found, it make substitution. Otherwise, it keep going. until the definition occurs.

If eventually, there is no definition of a certain macro, error raised.

It will keep replacing until all macro invocation is replaced to normal code.

Of course, for the ease, it can only allow the case where procedural macro define before the invocation.

See PEP 638 for a more complete version of this.