Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Lib/test/libregrtest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down
30 changes: 24 additions & 6 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Loading