[3.13] gh-135734: correctly handle --enable-optimizations --disable-test-modules combination (#137998)

This commit is contained in:
Bénédikt Tran 2025-08-21 20:28:03 +02:00 committed by GitHub
parent 6587786270
commit 41c2c8f01c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 38 additions and 7 deletions

View file

@ -9,6 +9,7 @@
from typing import NoReturn
from test.support import (os_helper, MS_WINDOWS, flush_std_streams,
can_use_suppress_immortalization,
suppress_immortalization)
from .cmdline import _parse_args, Namespace
@ -536,8 +537,16 @@ def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
if self.num_workers:
self._run_tests_mp(runtests, self.num_workers)
else:
# gh-135734: suppress_immortalization() raises SkipTest
# if _testinternalcapi is missing and the -R option is set.
if not can_use_suppress_immortalization(runtests.hunt_refleak):
print("Module '_testinternalcapi' is missing. "
"Did you disable it with --disable-test-modules?",
file=sys.stderr)
raise SystemExit(1)
# gh-117783: don't immortalize deferred objects when tracking
# refleaks. Only releveant for the free-threaded build.
# refleaks. Only relevant for the free-threaded build.
with suppress_immortalization(runtests.hunt_refleak):
self.run_tests_sequentially(runtests)

View file

@ -519,25 +519,43 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'):
reason = e.args[0] if e.args else reason
return unittest.skipIf(skip, reason)
@contextlib.contextmanager
def suppress_immortalization(suppress=True):
"""Suppress immortalization of deferred objects."""
def can_use_suppress_immortalization(suppress=True):
"""Check if suppress_immortalization(suppress) can be used.
Use this helper in code where SkipTest must be eagerly handled.
"""
if not suppress:
return True
try:
import _testinternalcapi
except ImportError:
yield
return
return False
return True
@contextlib.contextmanager
def suppress_immortalization(suppress=True):
"""Suppress immortalization of deferred objects.
If _testinternalcapi is not available, the decorated test or class
is skipped. Use can_use_suppress_immortalization() outside test cases
to check if this decorator can be used.
"""
if not suppress:
yield
yield # no-op
return
from .import_helper import import_module
_testinternalcapi = import_module("_testinternalcapi")
_testinternalcapi.suppress_immortalization(True)
try:
yield
finally:
_testinternalcapi.suppress_immortalization(False)
def skip_if_suppress_immortalization():
try:
import _testinternalcapi

View file

@ -0,0 +1,4 @@
Python can correctly be configured and built with
``./configure --enable-optimizations --disable-test-modules``.
Previously, the profile data generation step failed due to PGO tests where
immortalization couldn't be properly suppressed. Patch by Bénédikt Tran.