Skip to content

Add python 3.15 to tests - #2069

Draft
Finn Womack (finnagin) wants to merge 9 commits into
microsoft:mainfrom
finnagin:py315
Draft

Add python 3.15 to tests#2069
Finn Womack (finnagin) wants to merge 9 commits into
microsoft:mainfrom
finnagin:py315

Conversation

@finnagin

Copy link
Copy Markdown

No description provided.

Verify that an exception already reported as unhandled remains
recognized after a nested exception replaces the transient exception
state. This prevents the original exception from being reported twice.
Track the identity of an exception once it has been reported as
unhandled so that nested exceptions cannot cause it to be reported
again. Clear the transient exception state before stopping while
retaining the reported exception tag for the remainder of its unwind.

This fixes duplicate SystemExit stops exposed by Python 3.15, where
traceback formatting can trigger a nested monitored exception while
resolving its lazy _colorize import.
Regenerate the .pyx and .c files from the modified
_pydevd_sys_monitoring.py implementation.
Python 3.15 propagates the multithreaded os.fork() DeprecationWarning
as an exception when warnings are configured as errors. Debuggee test
sessions set PYTHONWARNINGS=error, and debugpy's worker threads cause
CPython to emit this warning during the multiprocessing fork tests.

The child process has already been created when the warning is raised
in the parent. This terminates the parent while the child is attaching,
resulting in premature terminated events or test timeouts.

Ignore only this specific warning when the test intentionally uses the
fork start method. Other warnings remain errors, and spawn-based tests
are unaffected.
@finnagin

Copy link
Copy Markdown
Author

The tests are all passing now. There were 2 issues uncovered by updating to 3.15.

The smaller issue was that there was a deprecation warning for calling os.fork from a process with multiple threads. That warning was added in 3.12 but was not originally raised to be an error by cpython when PYTHONWARNINGS=error was set. This was a bug and was fixed in 3.15 (python/cpython#135427) and now, because it's raising an error, caused a few multiprocessing tests to fail.

This was fixed by adding a step in those tests to ignore that specific deprecation warning since those tests were specifically testing os.fork.

The larger issue involved duplicate exception stops when using the sys.monitoring backend in the vendored pydevd code. Pydevd keeps a temporary thread-local state identifying the exception currently being tracked as unhandled. That state was used both to locate the exception’s unhandled boundary and to determine whether the exception had already caused a debugger stop.

While pydevd was processing the first unhandled SystemExit stop, it formatted the exception’s traceback. Python 3.15 traceback code now has a lazy import for _colorize. This lazy import triggers during the handling of the SystemExit stop. During that import, the import machinery probes collections.abc.__path__, which raises a benign, caught AttributeError. Pydevd’s monitoring callbacks observed that nested exception and replaced the temporary state that had identified the original SystemExit with a new temporary state for the AttributeError.

When execution continued, the original SystemExit resumed unwinding. Because its identifying state had been replaced by the nested AttributeError, pydevd no longer recognized it as already reported and stopped on the same SystemExit a second time. Since the import in 3.14 was eager, the caught AttributeError happened earlier in the code, so the bug wasn't triggered.

This second issue was fixed by tracking an already-reported exception separately from the temporary state used to find its unhandled boundary. Nested exceptions then can replace the temporary state, but won't erase the record that the original exception has already caused a debugger stop. Also, a test was added to check this specific bug instead of relying on it incidentally getting triggered by an unrelated change in the timing of when a module gets imported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants