You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Regression in python3.10 with traceback frame having lineno of -1 #88099
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee='https://github.com/markshannon'closed_at=<Date2021-04-30.13:34:44.252>created_at=<Date2021-04-24.19:56:33.908>labels= ['release-blocker', '3.10', '3.11']
title='Regression in python3.10 with traceback frame having lineno of -1'updated_at=<Date2021-06-07.20:58:11.753>user='https://github.com/asottile'
Traceback (most recent call last):
File "/home/asottile/workspace/cpython/t.py", line 10, in main
raise AssertionError('hi')
AssertionError: hi
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/asottile/workspace/cpython/t.py", line 14, in <module>
exit(main())
File "/home/asottile/workspace/cpython/t.py", line 10, in main
raise AssertionError('hi')
File "/home/asottile/workspace/cpython/t.py", line 5, in __exit__
raise AssertionError('boom!')
AssertionError: boom!
output in python3.10:
Traceback (most recent call last):
File "/home/asottile/workspace/cpython/t.py", line 10, in main
raise AssertionError('hi')
AssertionError: hi
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/asottile/workspace/cpython/t.py", line 14, in <module>
exit(main())
File "/home/asottile/workspace/cpython/t.py", line -1, in main
File "/home/asottile/workspace/cpython/t.py", line 5, in __exit__
raise AssertionError('boom!')
AssertionError: boom!
Notice the second to last frame is now missing and invalid (line -1)
3bd6035b6baf1a7d51b7cc2c6bb2c81886236b67 is the first bad commit
commit 3bd6035b6baf1a7d51b7cc2c6bb2c81886236b67
Author: Mark Shannon <mark@hotpy.org>
Date: Wed Jan 13 12:05:43 2021 +0000
bpo-42908: Mark cleanup code at end of try-except and with artificial (#24202)
* Mark bytecodes at end of try-except as artificial.
* Make sure that the CFG is consistent throughout optimiization.
* Extend line-number propagation logic so that implicit returns after 'try-except' or 'with' have the correct line numbers.
* Update importlib
Lib/test/test_dis.py | 2 +-
Lib/test/test_sys_settrace.py | 40 +
Python/compile.c | 135 +-
Python/importlib.h | 3153 ++++++++++++++---------------
Python/importlib_external.h | 4489 ++++++++++++++++++++---------------------
Python/importlib_zipimport.h | 1013 +++++-----
6 files changed, 4473 insertions(+), 4359 deletions(-)
bisect run success
What exactly is the issue here?
That the line number is -1, or that is different from 3.9?
The -1 should be None. I can fix that, but there is the issue of whether the cleanup code in a with statement should have a line number or not.
The traceback for 3.9 is incorrect, the program is not on line 10 when __exit__ is called.
Currently we mark the cleanup code for the with statement as artificial meaning that it has no line number.
We could give it the line number of the with keyword, but that might break coverage and profiling tools.
PEP-626 says that the "with" keyword is executable, and should be traced, but nothing about whether that includes the cleanup call to __exit__.
The traceback for 3.9 is incorrect, the program is not on line 10 when __exit__ is called.
It's kind of not on any line in main(), but line 10 is the most useful line to indicate. It's the last bit of the user's code that was running, and it is the reason for leaving the with statement.
In this case, if happens that line 10 was the last line of code executing in the body of the with statement.
But the reason it was listed, was that it was statically the last line of code in the body.
If the body is something like:
if TRUE:
...
else:
...
Then the reported last line will be 4, even though it is never executed.
We can fix this, at the cost of extra compiler complexity and increased bytecode size for the non-exceptional case, but it is very difficult for the exceptional case, because we don't know statically where the exception has come from.
I'm trying to see if these changes affect coverage.py, but pytest 6.2.3 fails with:
=== CPython 3.10.0a7+ (rev 558df90) with Python tracer (.tox/anypy/bin/python) ===
ImportError while loading conftest '/Users/nedbatchelder/coverage/trunk/tests/conftest.py'.
TypeError: required field "lineno" missing from alias
Is this something I am doing wrong?
asottile commented on May 1, 2021
asottilemannequin
MannequinAuthor
More actions
ah yeah that's the asname ast change -- if you use the unreleased main branch it has a fix for that
The pytest failure still happens with 3.10.0b1 and pytest 6.2.3.
What I am missing? 3.10.0b1 includes the fixes for this issue, no? Is it because the fixes still require some changes in the source? If that's the case, we should mention it in the What's New
I'm asking if pytest can make a release to update.
In any case, shouldn't that be requested in the pytest issue tracker?
asottile commented on May 4, 2021
asottilemannequin
MannequinAuthor
More actions
I've released pytest 6.2.4 for the other breakage (which is unrelated to this bpo -- it was the asname source position issue)
BTW, I created a separate issue about this: https://bugs.python.org/issue44088 because I wasn't sure if I should continue on this one, sorry. Feel free to close either one.
Activity
asottile commentedon Apr 24, 2021
This is breaking pytest for failed assertions: pytest-dev/pytest#8227
It also breaks the traceback in the output below
Here's a minimal example:
On python3.9 you get this:
output in python3.10:
Notice the second to last frame is now missing and invalid (line -1)
I bisected this and found this is the culprit:
3bd6035
#24202
which appears to be due to bpo-42908
pablogsal commentedon Apr 24, 2021
Marking as release blocker since is breaking pytest
pablogsal commentedon Apr 24, 2021
Thanks for the bisection, Anthony
markshannon commentedon Apr 26, 2021
What exactly is the issue here?
That the line number is -1, or that is different from 3.9?
The
-1should beNone. I can fix that, but there is the issue of whether the cleanup code in a with statement should have a line number or not.The traceback for 3.9 is incorrect, the program is not on line 10 when __exit__ is called.
Currently we mark the cleanup code for the with statement as artificial meaning that it has no line number.
We could give it the line number of the
withkeyword, but that might break coverage and profiling tools.PEP-626 says that the "with" keyword is executable, and should be traced, but nothing about whether that includes the cleanup call to __exit__.
nedbat commentedon Apr 26, 2021
Mark, you say:
It's kind of not on any line in main(), but line 10 is the most useful line to indicate. It's the last bit of the user's code that was running, and it is the reason for leaving the with statement.
markshannon commentedon Apr 26, 2021
In this case, if happens that line 10 was the last line of code executing in the body of the with statement.
But the reason it was listed, was that it was statically the last line of code in the body.
If the body is something like:
Then the reported last line will be 4, even though it is never executed.
We can fix this, at the cost of extra compiler complexity and increased bytecode size for the non-exceptional case, but it is very difficult for the exceptional case, because we don't know statically where the exception has come from.
markshannon commentedon Apr 26, 2021
This test case was added for 3.10.
In 3.9 it reports that the pass statement executes, even though it is unreachable.
https://github.com/python/cpython/blob/master/Lib/test/test_sys_settrace.py#L919
8 remaining items
asottile commentedon Apr 30, 2021
can confirm that pytest no longer crashes
nedbat commentedon May 1, 2021
I'm trying to see if these changes affect coverage.py, but pytest 6.2.3 fails with:
=== CPython 3.10.0a7+ (rev 558df90) with Python tracer (.tox/anypy/bin/python) ===
ImportError while loading conftest '/Users/nedbatchelder/coverage/trunk/tests/conftest.py'.
TypeError: required field "lineno" missing from alias
Is this something I am doing wrong?
asottile commentedon May 1, 2021
ah yeah that's the
asnameast change -- if you use the unreleased main branch it has a fix for thatnedbat commentedon May 4, 2021
Thanks, tip of pytest works for me. Is this error going to happen for everyone testing with 3.10b1? If so, can we get a release of pytest?
pablogsal commentedon May 4, 2021
3.10.0b1 includes both of these PRs so people testing the beta should not get affected. That's why I marked this as release blocker.
nedbat commentedon May 4, 2021
The pytest failure still happens with 3.10.0b1 and pytest 6.2.3. I'm asking if pytest can make a release to update.
pablogsal commentedon May 4, 2021
What I am missing? 3.10.0b1 includes the fixes for this issue, no? Is it because the fixes still require some changes in the source? If that's the case, we should mention it in the What's New
In any case, shouldn't that be requested in the pytest issue tracker?
asottile commentedon May 4, 2021
I've released pytest 6.2.4 for the other breakage (which is unrelated to this bpo -- it was the asname source position issue)
nedbat commentedon May 5, 2021
Mark, I'm not clear if the line number can still be None in some circumstances.
With this code (from site.py in the stdlib):
545: def execsitecustomize():
546: """Run custom site specific code, if available."""
547: try:
548: try:
549: import sitecustomize
550: except ImportError as exc:
551: if exc.name == 'sitecustomize':
552: pass
553: else:
554: raise
555: except Exception as err:
556: if sys.flags.verbose:
557: sys.excepthook(*sys.exc_info())
558: else:
559: sys.stderr.write(
560: "Error in sitecustomize; set PYTHONVERBOSE for traceback:\n"
561: "%s: %s\n" %
562: (err.__class__.__name__, err))
I get traces with these events and line numbers:
exception 549 (ModuleNotFoundError("No module named 'sitecustomize'"))
line 550
line 551
line 552
return None
Is this what you expected?
markshannon commentedon May 10, 2021
Ned, no line numbers should never be None.
(Except under very unusual circumstances, like the trace function raising an error)
Taking a look at the disassembly of execsitecustomize, there is a return with no line number, which shouldn't happen.
nedbat commentedon May 12, 2021
BTW, I created a separate issue about this: https://bugs.python.org/issue44088 because I wasn't sure if I should continue on this one, sorry. Feel free to close either one.
markshannon commentedon May 13, 2021
New changeset 0acdf25 by Mark Shannon in branch '3.10':
[3.10] bpo-43933: Force RETURN_VALUE bytecodes to have line numbers (GH-26061)
0acdf25
nedbat commentedon May 13, 2021
Thanks, this fixes my issue.
vstinner commentedon Jun 7, 2021
See also bpo-44297.