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]