From a73656a93a2c58464a48a5be6947d33fe25d0d0b Mon Sep 17 00:00:00 2001 From: Shamil Abdulaev Date: Wed, 26 Aug 2026 10:17:07 +0300 Subject: [PATCH 1/3] Modernize annotation usage in libregrtest --- Lib/test/libregrtest/main.py | 8 ++------ Lib/test/libregrtest/mypy.ini | 2 +- Lib/test/libregrtest/refleak.py | 9 +++------ Lib/test/libregrtest/results.py | 6 ++---- Lib/test/libregrtest/utils.py | 3 +-- .../2026-08-26-10-06-54.gh-issue-156402.ouqfgaOZ.rst | 2 ++ 6 files changed, 11 insertions(+), 19 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2026-08-26-10-06-54.gh-issue-156402.ouqfgaOZ.rst diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index db2e9acb850f107..2e8397a8a91d324 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -470,8 +470,7 @@ def finalize_tests(self, coverage: trace.CoverageResults | None) -> None: os.unlink(self.next_single_filename) if coverage is not None: - # uses a new-in-Python 3.13 keyword argument that mypy doesn't know about yet: - coverage.write_results(show_missing=True, summary=True, # type: ignore[call-arg] + coverage.write_results(show_missing=True, summary=True, coverdir=self.coverage_dir, ignore_missing_files=True) @@ -539,10 +538,7 @@ def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int: if self.num_workers < 0: # Use all CPUs + 2 extra worker processes for tests # that like to sleep - # - # os.process.cpu_count() is new in Python 3.13; - # mypy doesn't know about it yet - self.num_workers = (os.process_cpu_count() or 1) + 2 # type: ignore[attr-defined] + self.num_workers = (os.process_cpu_count() or 1) + 2 # For a partial run, we do not need to clutter the output. if (self.want_header diff --git a/Lib/test/libregrtest/mypy.ini b/Lib/test/libregrtest/mypy.ini index 3fa9afcb7a4a8c3..2830647635278cc 100644 --- a/Lib/test/libregrtest/mypy.ini +++ b/Lib/test/libregrtest/mypy.ini @@ -5,7 +5,7 @@ [mypy] files = Lib/test/libregrtest explicit_package_bases = True -python_version = 3.12 +python_version = 3.15 platform = linux pretty = True diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index e7da17e500ead96..1535924f49e0df2 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -95,9 +95,8 @@ def runtest_refleak(test_name, test_func, # `ByteString` is not included in `collections.abc.__all__` with warnings.catch_warnings(action='ignore', category=DeprecationWarning): - ByteString = collections.abc.ByteString - # Mypy doesn't even think `ByteString` is a class, hence the `type: ignore` - for obj in ByteString.__subclasses__() + [ByteString]: # type: ignore[attr-defined] + ByteString = collections.abc.ByteString # type: ignore[attr-defined] + for obj in ByteString.__subclasses__() + [ByteString]: abcs[obj] = _get_dump(obj)[0] # bpo-31217: Integer pool to get a single integer object for the same @@ -154,9 +153,7 @@ def get_pooled_int(value): # Also, readjust the reference counts and alloc blocks by ignoring # any strings that might have been interned during test_func. These # strings will be deallocated at runtime shutdown - interned_immortal_after = getunicodeinternedsize( - # Use an internal-only keyword argument that mypy doesn't know yet - _only_immortal=True) # type: ignore[call-arg] + interned_immortal_after = getunicodeinternedsize(_only_immortal=True) alloc_after = getallocatedblocks() - interned_immortal_after rc_after = gettotalrefcount() fd_after = fd_count() diff --git a/Lib/test/libregrtest/results.py b/Lib/test/libregrtest/results.py index ea5fee334215417..e2d5af50be849a1 100644 --- a/Lib/test/libregrtest/results.py +++ b/Lib/test/libregrtest/results.py @@ -1,7 +1,6 @@ import sys import trace from _colorize import get_colors # type: ignore[import-not-found] -from typing import TYPE_CHECKING from .runtests import RunTests from .result import State, TestResult, TestStats, Location @@ -9,8 +8,7 @@ StrPath, TestName, TestTuple, TestList, FilterDict, printlist, count, format_duration) -if TYPE_CHECKING: - from xml.etree.ElementTree import Element +lazy from xml.etree.ElementTree import Element # Python uses exit code 1 when an exception is not caught @@ -41,7 +39,7 @@ def __init__(self) -> None: self.test_times: list[tuple[float, TestName]] = [] self.stats = TestStats() # used by --junit-xml - self.testsuite_xml: list['Element'] = [] + self.testsuite_xml: list[Element] = [] # used by -T with -j self.covered_lines: set[Location] = set() diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index dfec7a59b02583b..24d4c37624bedaf 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -657,8 +657,7 @@ def display_header(use_resources: dict[str, str | None], cpu_count: object = os.cpu_count() if cpu_count: - # The function is new in Python 3.13; mypy doesn't know about it yet: - process_cpu_count = os.process_cpu_count() # type: ignore[attr-defined] + process_cpu_count = os.process_cpu_count() if process_cpu_count and process_cpu_count != cpu_count: cpu_count = f"{process_cpu_count} (process) / {cpu_count} (system)" print("== CPU count:", cpu_count) diff --git a/Misc/NEWS.d/next/Tests/2026-08-26-10-06-54.gh-issue-156402.ouqfgaOZ.rst b/Misc/NEWS.d/next/Tests/2026-08-26-10-06-54.gh-issue-156402.ouqfgaOZ.rst new file mode 100644 index 000000000000000..066b1829ebc1d6b --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2026-08-26-10-06-54.gh-issue-156402.ouqfgaOZ.rst @@ -0,0 +1,2 @@ +Modernize annotation usage in :mod:`!test.libregrtest` by replacing a +type-checking-only import with a lazy import. Patched by Shamil Abdulaev. From 70ce71df7d90118f373bd67bc68662513fafe115 Mon Sep 17 00:00:00 2001 From: Shamil Abdulaev Date: Wed, 26 Aug 2026 12:52:12 +0300 Subject: [PATCH 2/3] Remove unnecessary libregrtest NEWS entry --- .../next/Tests/2026-08-26-10-06-54.gh-issue-156402.ouqfgaOZ.rst | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 Misc/NEWS.d/next/Tests/2026-08-26-10-06-54.gh-issue-156402.ouqfgaOZ.rst diff --git a/Misc/NEWS.d/next/Tests/2026-08-26-10-06-54.gh-issue-156402.ouqfgaOZ.rst b/Misc/NEWS.d/next/Tests/2026-08-26-10-06-54.gh-issue-156402.ouqfgaOZ.rst deleted file mode 100644 index 066b1829ebc1d6b..000000000000000 --- a/Misc/NEWS.d/next/Tests/2026-08-26-10-06-54.gh-issue-156402.ouqfgaOZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Modernize annotation usage in :mod:`!test.libregrtest` by replacing a -type-checking-only import with a lazy import. Patched by Shamil Abdulaev. From 661fd50c0ea4676454cebfff9c3bb31d1850a431 Mon Sep 17 00:00:00 2001 From: Shamil Abdulaev Date: Wed, 26 Aug 2026 12:52:16 +0300 Subject: [PATCH 3/3] Move Element lazy import to stdlib import group --- Lib/test/libregrtest/results.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/test/libregrtest/results.py b/Lib/test/libregrtest/results.py index e2d5af50be849a1..3475f645729182c 100644 --- a/Lib/test/libregrtest/results.py +++ b/Lib/test/libregrtest/results.py @@ -1,6 +1,7 @@ import sys import trace from _colorize import get_colors # type: ignore[import-not-found] +lazy from xml.etree.ElementTree import Element from .runtests import RunTests from .result import State, TestResult, TestStats, Location @@ -8,8 +9,6 @@ StrPath, TestName, TestTuple, TestList, FilterDict, printlist, count, format_duration) -lazy from xml.etree.ElementTree import Element - # Python uses exit code 1 when an exception is not caught # argparse.ArgumentParser.error() uses exit code 2