Skip to content
Open
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
7 changes: 7 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,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 }}
Expand Down Expand Up @@ -669,6 +675,7 @@ jobs:
- build-emscripten
- build-wasi
- test-hypothesis
- test-lazy-imports-all
- build-asan
- build-san
- cross-build-linux
Expand Down
80 changes: 80 additions & 0 deletions .github/workflows/reusable-test-lazy-imports-all.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
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:
Comment thread
brittanyrey marked this conversation as resolved.
test-lazy-imports-all:
name: 'Run Tests with lazy_imports=all'
runs-on: ubuntu-24.04
timeout-minutes: 60
env:
EXCLUDE_FILE: Lib/test/lazy_imports_all_exclude.txt
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can simplify this with there being four entries.

# exact test names (whole-line, fixed-string match) from the run list.
grep -vE '^\s*(#.*)?$' "$EXCLUDE_FILE" > exclude_tests.txt
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 ./python -X lazy_imports=all -m test --fast-ci --timeout=900 < run_tests.txt
- name: Verify excluded tests still need exclusion
if: success()
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
50 changes: 50 additions & 0 deletions Lib/test/lazy_imports_all_exclude.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# 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.test_pydoc.test_pydoc

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are four entries, I'm not sure we need this file, we can just list them in an envvar in the workflow IMO.

test___all__
test__interpreters
test_builtin
test_clinic
test_compileall
test_crossinterp
test_datetime
test_external_inspection
test_generated_cases
test_heapq
test_idle
test_import
test_importlib
test_interpreters
test_json
test_lazy_import
test_pkg
test_profile
test_profiling
test_pyrepl
test_subprocess
test_symtable
test_tools
test_trace
test_type_annotations
test_typing
test_unittest
test_xmlrpc
test_zipfile
test_zoneinfo
Loading