]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-109413: Run mypy on `libregrtest` in CI (#112558)
authorAlex Waygood <Alex.Waygood@Gmail.com>
Thu, 30 Nov 2023 23:00:14 +0000 (23:00 +0000)
committerGitHub <noreply@github.com>
Thu, 30 Nov 2023 23:00:14 +0000 (23:00 +0000)
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
.github/workflows/mypy.yml
Lib/test/libregrtest/cmdline.py
Lib/test/libregrtest/main.py
Lib/test/libregrtest/mypy.ini
Lib/test/libregrtest/refleak.py
Lib/test/libregrtest/results.py
Lib/test/libregrtest/run_workers.py
Lib/test/libregrtest/runtests.py
Lib/test/libregrtest/setup.py
Lib/test/libregrtest/utils.py

index 405511ca6820b30d7269dc0338f419f4098b7542..72ae67aa02aa9685b87fe9682112080380fb24ac 100644 (file)
@@ -8,6 +8,7 @@ on:
   pull_request:
     paths:
       - ".github/workflows/mypy.yml"
+      - "Lib/test/libregrtest/**"
       - "Tools/cases_generator/**"
       - "Tools/clinic/**"
       - "Tools/peg_generator/**"
@@ -32,6 +33,7 @@ jobs:
     strategy:
       matrix:
         target: [
+          "Lib/test/libregrtest",
           "Tools/cases_generator",
           "Tools/clinic",
           "Tools/peg_generator",
index a5f02d6335f58f155aa4cc9b30146758c7fa5af5..0053bce4292f64f1a642685a3ad7774dceda0c4a 100644 (file)
@@ -3,7 +3,7 @@ import os.path
 import shlex
 import sys
 from test.support import os_helper, Py_DEBUG
-from .utils import ALL_RESOURCES, RESOURCE_NAMES
+from .utils import ALL_RESOURCES, RESOURCE_NAMES, TestFilter
 
 
 USAGE = """\
@@ -161,7 +161,7 @@ class Namespace(argparse.Namespace):
         self.forever = False
         self.header = False
         self.failfast = False
-        self.match_tests = []
+        self.match_tests: TestFilter = []
         self.pgo = False
         self.pgo_extended = False
         self.worker_json = None
index 86428945a6def2bda8c72246a7172c40f648a9c7..55fc3a820d345121f16b4b172bbf4c3e5c2d72e7 100644 (file)
@@ -295,7 +295,9 @@ class Regrtest:
             namespace = dict(locals())
             tracer.runctx(cmd, globals=globals(), locals=namespace)
             result = namespace['result']
-            result.covered_lines = list(tracer.counts)
+            # Mypy doesn't know about this attribute yet,
+            # but it will do soon: https://github.com/python/typeshed/pull/11091
+            result.covered_lines = list(tracer.counts)  # type: ignore[attr-defined]
         else:
             result = run_single_test(test_name, runtests)
 
@@ -371,7 +373,8 @@ class Regrtest:
                 os.unlink(self.next_single_filename)
 
         if coverage is not None:
-            coverage.write_results(show_missing=True, summary=True,
+            # 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]
                                    coverdir=self.coverage_dir,
                                    ignore_missing_files=True)
 
@@ -432,7 +435,10 @@ class Regrtest:
         if self.num_workers < 0:
             # Use all CPUs + 2 extra worker processes for tests
             # that like to sleep
-            self.num_workers = (os.process_cpu_count() or 1) + 2
+            #
+            # 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]
 
         # For a partial run, we do not need to clutter the output.
         if (self.want_header
index fefc347728a701832e41cc490055c7d2efeba46e..331fe681b9f56b5f0e5ea82a10778bc471287bb4 100644 (file)
@@ -5,7 +5,7 @@
 [mypy]
 files = Lib/test/libregrtest
 explicit_package_bases = True
-python_version = 3.11
+python_version = 3.12
 platform = linux
 pretty = True
 
index ada1a65b867ee65d9b8fb7d62fd9be9040a3bcc7..5836a8421cb42d51f5e7077f706afddb8cb31440 100644 (file)
@@ -52,7 +52,8 @@ def runtest_refleak(test_name, test_func,
     except ImportError:
         zdc = None # Run unmodified on platforms without zipimport support
     else:
-        zdc = zipimport._zip_directory_cache.copy()
+        # private attribute that mypy doesn't know about:
+        zdc = zipimport._zip_directory_cache.copy()  # type: ignore[attr-defined]
     abcs = {}
     for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]:
         if not isabstract(abc):
index 71aaef3ae9ae616d93f0a57064acc623dfc2ec24..59a566c032847e4e0ed585c9b59db54d2db911b7 100644 (file)
@@ -34,7 +34,7 @@ class TestResults:
         self.test_times: list[tuple[float, TestName]] = []
         self.stats = TestStats()
         # used by --junit-xml
-        self.testsuite_xml: list[str] = []
+        self.testsuite_xml: list = []
         # used by -T with -j
         self.covered_lines: set[Location] = set()
 
index 99c2cf34d206d0236d5bdb554424bb99830c3152..35aaf90ffc42992d4575a1ac001ef135ca80e4e9 100644 (file)
@@ -10,7 +10,7 @@ import tempfile
 import threading
 import time
 import traceback
-from typing import Literal, TextIO
+from typing import Any, Literal, TextIO
 
 from test import support
 from test.support import os_helper, MS_WINDOWS
@@ -243,7 +243,9 @@ class WorkerThread(threading.Thread):
 
             json_fd = json_tmpfile.fileno()
             if MS_WINDOWS:
-                json_handle = msvcrt.get_osfhandle(json_fd)
+                # The msvcrt module is only available on Windows;
+                # we run mypy with `--platform=linux` in CI
+                json_handle: int = msvcrt.get_osfhandle(json_fd)  # type: ignore[attr-defined]
                 json_file = JsonFile(json_handle,
                                      JsonFileType.WINDOWS_HANDLE)
             else:
@@ -259,7 +261,7 @@ class WorkerThread(threading.Thread):
         else:
             match_tests = None
 
-        kwargs = {}
+        kwargs: dict[str, Any] = {}
         if match_tests:
             kwargs['match_tests'] = [(test, True) for test in match_tests]
         if self.runtests.output_on_failure:
@@ -345,6 +347,7 @@ class WorkerThread(threading.Thread):
             json_file, json_tmpfile = self.create_json_file(stack)
             worker_runtests = self.create_worker_runtests(test_name, json_file)
 
+            retcode: str | int | None
             retcode, tmp_files = self.run_tmp_files(worker_runtests,
                                                     stdout_file.fileno())
 
index ac47c07f8d434101dae5d6ba3fc0b2c77074d1a7..b765ba5b41d236d01a7128f958605b6711eb1c8c 100644 (file)
@@ -33,7 +33,8 @@ class JsonFile:
                 popen_kwargs['pass_fds'] = [self.file]
             case JsonFileType.WINDOWS_HANDLE:
                 # Windows handle
-                startupinfo = subprocess.STARTUPINFO()
+                # We run mypy with `--platform=linux` so it complains about this:
+                startupinfo = subprocess.STARTUPINFO()  # type: ignore[attr-defined]
                 startupinfo.lpAttributeList = {"handle_list": [self.file]}
                 popen_kwargs['startupinfo'] = startupinfo
 
index 97edba9f87d7f9307062657dd04918aa96b16ce5..9e9741493e9a5bc704ab79f4408e6d076a2f2da4 100644 (file)
@@ -124,7 +124,8 @@ def setup_tests(runtests: RunTests):
         support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, timeout)
 
     if runtests.hunt_refleak:
-        unittest.BaseTestSuite._cleanup = False
+        # private attribute that mypy doesn't know about:
+        unittest.BaseTestSuite._cleanup = False  # type: ignore[attr-defined]
 
     if runtests.gc_threshold is not None:
         gc.set_threshold(runtests.gc_threshold)
index e4a28af381ee2da1d8166bad3d0e1dda4e8db30f..d47e9388e62db2826690a6c49b4168ab59f43c3d 100644 (file)
@@ -12,7 +12,7 @@ import sys
 import sysconfig
 import tempfile
 import textwrap
-from collections.abc import Callable
+from collections.abc import Callable, Iterable
 
 from test import support
 from test.support import os_helper
@@ -547,7 +547,7 @@ def is_cross_compiled():
     return ('_PYTHON_HOST_PLATFORM' in os.environ)
 
 
-def format_resources(use_resources: tuple[str, ...]):
+def format_resources(use_resources: Iterable[str]):
     use_resources = set(use_resources)
     all_resources = set(ALL_RESOURCES)
 
@@ -580,9 +580,10 @@ def display_header(use_resources: tuple[str, ...],
     print("== Python build:", ' '.join(get_build_info()))
     print("== cwd:", os.getcwd())
 
-    cpu_count = os.cpu_count()
+    cpu_count: object = os.cpu_count()
     if cpu_count:
-        process_cpu_count = os.process_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]
         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)