Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add to AST location info for compound exception headers or keywords #129157

Open
iritkatriel opened this issue Jan 21, 2025 · 3 comments
Open

Add to AST location info for compound exception headers or keywords #129157

iritkatriel opened this issue Jan 21, 2025 · 3 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-parser type-feature A feature request or enhancement

Comments

@iritkatriel
Copy link
Member

iritkatriel commented Jan 21, 2025

The location information in the AST for a compound statement spans the whole body.

For example:

>>> src = """with A as cm:
...     1
...     2
...     3
...     """

Output:

"Module(body=[With(items=[withitem(context_expr=Name(id='A', ctx=Load(), lineno=1, col_offset=5, end_lineno=1, end_col_offset=6), optional_vars=Name(id='cm', ctx=Store(), lineno=1, col_offset=10, end_lineno=1, end_col_offset=12))], body=[Expr(value=Constant(value=1, lineno=2, col_offset=4, end_lineno=2, end_col_offset=5), lineno=2, col_offset=4, end_lineno=2, end_col_offset=5), Expr(value=Constant(value=2, lineno=3, col_offset=4, end_lineno=3, end_col_offset=5), lineno=3, col_offset=4, end_lineno=3, end_col_offset=5), Expr(value=Constant(value=3, lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, col_offset=4, end_lineno=4, end_col_offset=5)], lineno=1, col_offset=0, end_lineno=4, end_col_offset=5)])"

If __enter__ or __exit__ of the context manager raises an exception, we don't want the location of the exception to span the entire body. Ideally it would be the location of the with keyword (my view) or the entire with x as y statement (@ericsnowcurrently's view). However, we don't have those locations in the AST so currently we hilight the location of the expression that creates the context manager:

>>> class C:
...     def __enter__(self): 1/0
...     def __exit__(*args): pass
...     
>>> with C() as c: pass
... 
Traceback (most recent call last):
  File "<python-input-11>", line 1, in <module>
    with C() as c: pass
         ~^^
  File "<python-input-10>", line 2, in __enter__
    def __enter__(self): 1/0
                         ~^~
ZeroDivisionError: division by zero

We have similar issue with except blocks and class definitions.

Can we add location information of the keywords, or of the header of a compound expression, to the AST?

@pablogsal @lysnikolaou

Linked PRs

@iritkatriel iritkatriel changed the title Add to AST location info for compound exception headers Add to AST location info for compound exception headers or keywords Jan 21, 2025
@picnixz picnixz added type-feature A feature request or enhancement interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Jan 21, 2025
@pablogsal
Copy link
Member

On it

@pablogsal
Copy link
Member

Let's settle on this one first and I will take the other in other PRs

pablogsal added a commit to pablogsal/cpython that referenced this issue Jan 22, 2025
…pawn the first line

Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
pablogsal added a commit to pablogsal/cpython that referenced this issue Jan 22, 2025
…pawn the first line

Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
pablogsal added a commit to pablogsal/cpython that referenced this issue Jan 22, 2025
…pawn the first line

Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
pablogsal added a commit to pablogsal/cpython that referenced this issue Jan 22, 2025
@JelleZijlstra
Copy link
Member

There's an analogous issue with for loops:

>>> class X:
...     def __iter__(self): return self
...     def __next__(self): 1/0
...     
>>> for f in X():
...     pass
...     
Traceback (most recent call last):
  File "<python-input-9>", line 1, in <module>
    for f in X():
             ~^^
  File "<python-input-8>", line 3, in __next__
    def __next__(self): 1/0
                        ~^~
ZeroDivisionError: division by zero

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-parser type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

5 participants