On Wed, May 19, 2021 at 7:28 PM Pablo Galindo Salgado
Excellent point! Do you know how reliable this is in practice, i.e. what proportion of bytecode source spans are something you can successfully pass to ast.parse? If it works it's obviously nicer, but I can't tell how often it works. E.g. anything including return/break/continue/yield/await will fail, since those require an enclosing context to be legal. I doubt return/break/continue will raise exceptions often, but yield/await do all the time.
All those limitations are compiler-time limitations because they imply scoping. A valid AST is any piece of a converted parse tree, or a piece of the PEG sub grammar:
ast.dump(ast.parse("yield")) 'Module(body=[Expr(value=Yield())], type_ignores=[])' ast.dump(ast.parse("return")) 'Module(body=[Return()], type_ignores=[])' ast.dump(ast.parse("continue")) 'Module(body=[Continue()], type_ignores=[])' ast.dump(ast.parse("await x")) "Module(body=[Expr(value=Await(value=Name(id='x', ctx=Load())))], type_ignores=[])"
Ah, nice! I guess I was confused by memories of the behavior in 3.6 and earlier, where 'await' was a pseudokeyword: ❯ docker run -it --rm python:3.6-alpine
import ast ast.parse("await f()") SyntaxError: invalid syntax
Hopefully if we add more pseudokeywords in the future it won't break the ability to parse traceback spans. -n -- Nathaniel J. Smith -- https://vorpus.org