https://github.com/python/cpython/commit/b62e0286858fcd9345b8ec40f490754a306a2186
commit: b62e0286858fcd9345b8ec40f490754a306a2186
branch: main
author: Brittany Reynoso <[email protected]>
committer: pablogsal <[email protected]>
date: 2026-09-18T12:06:44-04:00
summary:

gh-149640: Add new GitHub action to test lazy_imports=all against test suite 
(#151105)

* Add new github action to test lazy imports all against stdlib.

* Adjust GH Action naming to better match existing checks

* Address comments for reusability

* Fix double typo + add flaky module

* Update test name

* Remove concurrency configeration for reusable-test-lazy-imports-all.yml

* bikeshed renames

* Take a swing at adding exclusion checks

* remove allegedly passing modules?

* clean up

* Fix bug with env var not flowing through and bring back exclusions

* Accidentally added random files

* Add more modules

* Address incorrect exclusions

* Address feedback: update ubuntu version and CODEOWNERS file

* Prune test_idle and test_zoneinfo from the exclusion list

* Address comments. Variety of small nits and cleanups.

* Remove accidental file and remove myself from codeowners :(

* Deleting other random empty files

* Minor change to trigger tests again

* Minor change to trigger tests again 2

files:
A .github/workflows/reusable-test-lazy-imports-all.yml
A Lib/test/lazy_imports_all_exclude.txt
M .github/CODEOWNERS
M .github/workflows/build.yml

diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index d12eaee2adb3963..0a0100fcb2ebb50 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -290,9 +290,10 @@ Tools/jit/                    @brandtbucher 
@savannahostrowski @diegorusso
 InternalDocs/jit.md           @brandtbucher @savannahostrowski @diegorusso 
@AA-Turner
 
 # Lazy imports (PEP 810)
-Objects/lazyimportobject.c                  @yhg1s @DinoV @pablogsal
-Include/internal/pycore_lazyimportobject.h  @yhg1s @DinoV @pablogsal
-Lib/test/test_lazy_import                   @yhg1s @DinoV @pablogsal
+.github/workflows/reusable-test-lazy-imports-all.yml    @yhg1s @DinoV 
@pablogsal
+Objects/lazyimportobject.c                              @yhg1s @DinoV 
@pablogsal
+Include/internal/pycore_lazyimportobject.h              @yhg1s @DinoV 
@pablogsal
+Lib/test/test_lazy_import                               @yhg1s @DinoV 
@pablogsal
 
 # Micro-op / μop / Tier 2 Optimiser
 Python/optimizer.c            @markshannon @Fidget-Spinner
@@ -655,5 +656,8 @@ Objects/**/clinic/
 PC/**/clinic/
 Python/**/clinic/
 
+# Exclude Lazy Imports=all CI carve out file
+Lib/test/lazy_imports_all_exclude.txt
+
 # Exclude HTML IDs list
 Doc/tools/removed-ids.txt
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 7fdc81ae0ade1d2..e11e6aa6b6d3dc1 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -476,6 +476,12 @@ jobs:
         name: hypothesis-example-db
         path: ${{ env.CPYTHON_BUILDDIR }}/.hypothesis/examples/
 
+  test-lazy-imports-all:
+    name: 'Lazy imports enabled'
+    needs: build-context
+    if: fromJSON(needs.build-context.outputs.run-tests)
+    uses: ./.github/workflows/reusable-test-lazy-imports-all.yml
+
   build-asan:
     name: 'Address sanitizer'
     runs-on: ${{ matrix.os }}
@@ -648,6 +654,7 @@ jobs:
     - build-emscripten
     - build-wasi
     - test-hypothesis
+    - test-lazy-imports-all
     - build-asan
     - build-san
     - cross-build-linux
@@ -705,4 +712,5 @@ jobs:
           ${{ !fromJSON(needs.build-context.outputs.run-ios) && 'build-ios,' 
|| '' }}
           ${{ !fromJSON(needs.build-context.outputs.run-emscripten) && 
'build-emscripten,' || '' }}
           ${{ !fromJSON(needs.build-context.outputs.run-wasi) && 'build-wasi,' 
|| '' }}
+          ${{ !fromJSON(needs.build-context.outputs.run-tests) && 
'test-lazy-imports-all,' || '' }}
         jobs: ${{ toJSON(needs) }}
diff --git a/.github/workflows/reusable-test-lazy-imports-all.yml 
b/.github/workflows/reusable-test-lazy-imports-all.yml
new file mode 100644
index 000000000000000..3754308e89cad4b
--- /dev/null
+++ b/.github/workflows/reusable-test-lazy-imports-all.yml
@@ -0,0 +1,79 @@
+name: Reusable Lazy Imports Tests
+
+# Run the CPython test suite with global lazy imports forced on
+# (``-X lazy_imports=all``).
+#
+# Modules that are known to fail under lazy imports are listed in
+# Lib/test/lazy_imports_all_exclude.txt and skipped here. Remove entries from
+# that file as the modules are fixed so this workflow starts guarding them
+# against regressions. Excluded modules are also checked separately so the
+# workflow fails when one starts passing and its exclusion should be removed.
+
+on:
+  workflow_call:
+
+permissions:
+  contents: read
+
+env:
+  FORCE_COLOR: 1
+
+jobs:
+  test-lazy-imports-all:
+    name: 'Run Tests with lazy_imports=all'
+    runs-on: ubuntu-26.04
+    timeout-minutes: 60
+    env:
+      EXCLUDE_FILE: Lib/test/lazy_imports_all_exclude.txt
+    steps:
+    - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+      with:
+        persist-credentials: false
+    - name: Register gcc problem matcher
+      run: echo "::add-matcher::.github/problem-matchers/gcc.json"
+    - name: Install dependencies
+      run: sudo ./.github/workflows/posix-deps-apt.sh
+    - name: Configure CPython
+      run: ./configure --config-cache --with-pydebug
+    - name: Build CPython
+      run: make -j4
+    - name: Display build info
+      run: make pythoninfo
+    - name: Verify lazy imports are fully enabled
+      run: ./python -X lazy_imports=all -c "import sys; assert 
sys.flags.lazy_imports == 1, sys.flags.lazy_imports; print('lazy imports all 
enabled')"
+    - name: Build test list (all tests minus the known-failing exclusions)
+      run: |
+        set -euo pipefail
+        ./python -m test --list-tests > all_tests.txt
+        # Strip comments/blank lines from the exclusion file, then drop those
+        # exact test names (whole-line, fixed-string match) from the run list.
+        grep -vE '^\s*(#.*)?$' "$EXCLUDE_FILE" > exclude_tests.txt || true
+        grep -vxF -f exclude_tests.txt all_tests.txt > run_tests.txt
+        # Fail loudly if any exclusion entry matched nothing: a stale or
+        # mistyped name (or a change in `--list-tests` output) would otherwise
+        # silently stop excluding a module and let it fail the run.
+        stale=$(comm -23 <(sort -u exclude_tests.txt) <(sort -u all_tests.txt))
+        if [ -n "$stale" ]; then
+          echo "::error::Stale entries in $EXCLUDE_FILE (no longer match 
'python -m test --list-tests'); remove or fix them:"
+          echo "$stale"
+          exit 1
+        fi
+        echo "Excluding $(wc -l < exclude_tests.txt) module(s); running $(wc 
-l < run_tests.txt) of $(wc -l < all_tests.txt)."
+    - name: Run tests with lazy imports
+      run: xvfb-run xargs -a run_tests.txt ./python -X lazy_imports=all -m 
test --fast-ci --timeout=900 < /dev/null
+    - name: Verify excluded tests still need exclusion
+      run: |
+        set -euo pipefail
+        unexpected_passes=()
+        while IFS= read -r test_name; do
+          [ -n "$test_name" ] || continue
+          echo "Checking excluded test: $test_name"
+          if xvfb-run ./python -X lazy_imports=all -m test --fast-ci 
--timeout=900 "$test_name"; then
+            unexpected_passes+=("$test_name")
+          fi
+        done < exclude_tests.txt
+        if [ "${#unexpected_passes[@]}" -ne 0 ]; then
+          echo "::error::These tests still appear in $EXCLUDE_FILE but now 
pass with -X lazy_imports=all. Remove them from the exclude file:"
+          printf '%s\n' "${unexpected_passes[@]}"
+          exit 1
+        fi
diff --git a/Lib/test/lazy_imports_all_exclude.txt 
b/Lib/test/lazy_imports_all_exclude.txt
new file mode 100644
index 000000000000000..2680d3b1e4357b7
--- /dev/null
+++ b/Lib/test/lazy_imports_all_exclude.txt
@@ -0,0 +1,40 @@
+# Test modules that currently FAIL under global lazy imports
+# (``-X lazy_imports=all`` / ``PYTHON_LAZY_IMPORTS=all``).
+#
+# The "Lazy Imports All" CI workflow
+# (.github/workflows/reusable-test-lazy-imports-all.yml) runs the whole test
+# suite with lazy_imports=all, skipping every module listed here. Exclusion is
+# whole-module: a listed module is skipped entirely, so any passing tests it
+# contains are not covered until its line is removed. As each module is fixed,
+# delete its line so the workflow starts guarding it against regressions. The
+# workflow also checks listed modules separately and fails if one now passes,
+# so accidental fixes prompt cleanup of this file.
+#
+# Format: one test name per line, exactly as printed by
+# ``python -m test --list-tests``. Lines starting with ``#`` and blank lines
+# are ignored. Note that split test packages use a dotted path
+# (e.g. test.test_future_stmt.test_future) while ordinary modules use the bare
+# name (e.g. test_builtin).
+
+test.test_inspect.test_inspect
+test___all__
+test__interpreters
+test_builtin
+test_clinic
+test_crossinterp
+test_datetime
+test_generated_cases
+test_heapq
+test_import
+test_importlib
+test_json
+test_pkg
+test_profile
+test_profiling
+test_pyrepl
+test_subprocess
+test_symtable
+test_tools
+test_trace
+test_type_annotations
+test_unittest

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to