> > 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=[])" On Thu, 20 May 2021 at 03:22, Nathaniel Smith <n...@pobox.com> wrote: > On Tue, May 18, 2021 at 2:49 PM Pablo Galindo Salgado > <pablog...@gmail.com> wrote: > > * It actually doesn't have more advantages. The current solution in the > PEP can do exactly the same as this solution if you allow reparsing when > > displaying tracebacks. This is because with the start line, end line, > start offset and end offset and the original file, you can extract the > source that > > is associated with the instruction, parse it (and this > > is much faster because you just need to parse the tiny fragment) and > then you get an AST node that you can use for whatever you want. > > 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. > > You could kluge it by wrapping the source span in a dummy 'async def' > before parsing, since that makes yield/await legal, but OTOH it makes > 'yield from' and 'from X import *' illegal. > > I guess you could have a helper that attempts passing the string to > ast.parse, and if that fails tries wrapping it in a loop/sync > def/async def/etc. until one of them succeeds. Maybe that would be a > useful utility to add to the traceback module? > > Or add a PyCF_YOLO flag that tries to make sense of an arbitrary > out-of-context string. > > (Are there any other bits of syntax that require specific contexts > that I'm not thinking of? If __enter__/__exit__ raise an exception, > then what's the corresponding span? The entire 'with' block, or just > the 'with' line itself?) > > -n > > PS: this is completely orthogonal to PEP 657, but if you're excited > about making tracebacks more readable, another piece of low-hanging > fruit would be to print method __qualname__s instead of __name__s in > the traceback output. The reason we don't do that now is that > __qualname__ lives on the function object, but in a traceback, we > can't get the function object. The traceback only has access to the > code object, and the code object doesn't have __qualname__, just > __name__. Probably the cleanest way to do this would be to make the > traceback or code object have a pointer back to the function object. > See also https://bugs.python.org/issue12857. > > -- > Nathaniel J. Smith -- https://vorpus.org >
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/VLTCIVKY3PBZC6LAMQ7EFZBO53KSGWYD/ Code of Conduct: http://python.org/psf/codeofconduct/