Decoratored functions parsed differently by ast stdlib between 3.7 and 3.8

Mike Lee Williams mjwilliams at gmail.com
Fri Apr 30 22:54:53 EDT 2021


This trivial bit of code is parsed differently by the ast module between python
3.7 and python 3.8. I'm trying to figure out what changed and why, and once I
know that, if it's possible and desirable to retain the 3.7 behavior for my use
case (which needs to give the same result for this input on 3.7 and 3.8).

Here's the bit of python code:

    @hello
    def f(): pass

And here's a script to parse it with ast from the standard library

    import ast

    code = "@hello\ndef f(): pass"

    p = ast.parse(code)

    for t in p.body:
        print(t.lineno)

And here's the problem

    $ python3.8 parse.py
    2

    $ python3.7 parse.py
    1

I don't understand why this output differs between 3.7 and 3.8. It seems 3.8 is
ignoring the decorator somehow? The node has hello in decorator_list, so it's
there in the ast. But it's counting lines differently.

Passing the new passing feature_version=(3, 7) keyword argument introduced to
3.7 to ast.parse does not restore the 3.7 behavior in 3.8 so I'm assuming this
is not a python language grammar change but rather an ast API change (or a
bug?!)

The release notes for 3.8 mention AST, but none of the changes look relevant
as they all refer to typing https://docs.python.org/3/whatsnew/3.8.html#ast

So: what changed? Why? Can I and should I try to get the old behavior back?

Thanks!
Mike Lee Williams


More information about the Python-list mailing list