diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4489e609..1d22dc89a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -276,10 +276,15 @@ jobs: python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python), matrix.python))[startsWith(matrix.python, 'pypy')] }} cache: pip cache-dependency-path: test-requirements.txt + - name: Check Formatting + if: matrix.check_formatting == '1' + run: + python -m pip install tox + tox -m check - name: Run tests + if: matrix.check_formatting == '0' run: ./ci.sh env: - CHECK_FORMATTING: '${{ matrix.check_formatting }}' NO_TEST_REQUIREMENTS: '${{ matrix.no_test_requirements }}' - if: >- always() diff --git a/check.sh b/check.sh deleted file mode 100755 index 701db8ce6..000000000 --- a/check.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash - -set -ex - -ON_GITHUB_CI=true -EXIT_STATUS=0 - -# If not running on Github's CI, discard the summaries -if [ -z "${GITHUB_STEP_SUMMARY+x}" ]; then - GITHUB_STEP_SUMMARY=/dev/null - ON_GITHUB_CI=false -fi - -# Test if the generated code is still up to date -echo "::group::Generate Exports" -python ./src/trio/_tools/gen_exports.py --test \ - || EXIT_STATUS=$? -echo "::endgroup::" - -# Run mypy on all supported platforms -# MYPY is set if any of them fail. -MYPY=0 -echo "::group::Mypy" -# Cleanup previous runs. -rm -f mypy_annotate.dat -# Pipefail makes these pipelines fail if mypy does, even if mypy_annotate.py succeeds. -set -o pipefail -mypy --show-error-end --platform linux | python ./src/trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Linux \ - || { echo "* Mypy (Linux) found type errors." >> "$GITHUB_STEP_SUMMARY"; MYPY=1; } -# Darwin tests FreeBSD too -mypy --show-error-end --platform darwin | python ./src/trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Mac \ - || { echo "* Mypy (Mac) found type errors." >> "$GITHUB_STEP_SUMMARY"; MYPY=1; } -mypy --show-error-end --platform win32 | python ./src/trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Windows \ - || { echo "* Mypy (Windows) found type errors." >> "$GITHUB_STEP_SUMMARY"; MYPY=1; } -set +o pipefail -# Re-display errors using Github's syntax, read out of mypy_annotate.dat -python ./src/trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat -# Then discard. -rm -f mypy_annotate.dat -echo "::endgroup::" -# Display a big error if we failed, outside the group so it can't be collapsed. -if [ $MYPY -ne 0 ]; then - echo "::error:: Mypy found type errors." - EXIT_STATUS=1 -fi - -# Check pip compile is consistent -echo "::group::Pip Compile - Tests & Docs" -pre-commit run pip-compile --all-files \ - || EXIT_STATUS=$? -echo "::endgroup::" - -echo "::group::Pyright interface tests" -python src/trio/_tests/check_type_completeness.py || EXIT_STATUS=$? - -pyright src/trio/_tests/type_tests || EXIT_STATUS=$? -pyright src/trio/_core/_tests/type_tests || EXIT_STATUS=$? -echo "::endgroup::" - -# Finally, leave a really clear warning of any issues and exit -if [ $EXIT_STATUS -ne 0 ]; then - cat <> "$GITHUB_STEP_SUMMARY" -exit 0 diff --git a/ci.sh b/ci.sh index 83ec65748..f414d94a2 100755 --- a/ci.sh +++ b/ci.sh @@ -47,115 +47,109 @@ python -m build wheel_package=$(ls dist/*.whl) python -m uv pip install "trio @ $wheel_package" -c test-requirements.txt -if [ "$CHECK_FORMATTING" = "1" ]; then - python -m uv pip install -r test-requirements.txt exceptiongroup - echo "::endgroup::" - source check.sh +# Actual tests +# expands to 0 != 1 if NO_TEST_REQUIREMENTS is not set, if set the `-0` has no effect +# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02 +if [ "${NO_TEST_REQUIREMENTS-0}" == 1 ]; then + python -m uv pip install pytest coverage -c test-requirements.txt + flags="--skip-optional-imports" else - # Actual tests - # expands to 0 != 1 if NO_TEST_REQUIREMENTS is not set, if set the `-0` has no effect - # https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02 - if [ "${NO_TEST_REQUIREMENTS-0}" == 1 ]; then - python -m uv pip install pytest coverage -c test-requirements.txt - flags="--skip-optional-imports" - else - python -m uv pip install -r test-requirements.txt - flags="" - fi + python -m uv pip install -r test-requirements.txt + flags="" +fi - # So we can run the test for our apport/excepthook interaction working - if [ -e /etc/lsb-release ] && grep -q Ubuntu /etc/lsb-release; then - sudo apt install -q python3-apport - fi +# So we can run the test for our apport/excepthook interaction working +if [ -e /etc/lsb-release ] && grep -q Ubuntu /etc/lsb-release; then + sudo apt install -q python3-apport +fi - # If we're testing with a LSP installed, then it might break network - # stuff, so wait until after we've finished setting everything else - # up. - if [ "$LSP" != "" ]; then - echo "Installing LSP from ${LSP}" - # We use --insecure because one of the LSP's has been observed to give - # cert verification errors: - # - # https://github.com/python-trio/trio/issues/1478 - # - # *Normally*, you should never ever use --insecure, especially when - # fetching an executable! But *in this case*, we're intentionally - # installing some untrustworthy quasi-malware onto into a sandboxed - # machine for testing. So MITM attacks are really the least of our - # worries. - if [ "$LSP_EXTRACT_FILE" != "" ]; then - # We host the Astrill VPN installer ourselves, and encrypt it - # so as to decrease the chances of becoming an inadvertent - # public redistributor. - curl-harder -o lsp-installer.zip "$LSP" - unzip -P "not very secret trio ci key" lsp-installer.zip "$LSP_EXTRACT_FILE" - mv "$LSP_EXTRACT_FILE" lsp-installer.exe - else - curl-harder --insecure -o lsp-installer.exe "$LSP" - fi - # This is only needed for the Astrill LSP, but there's no harm in - # doing it all the time. The cert was manually extracted by installing - # the package in a VM, clicking "Always trust from this publisher" - # when installing, and then running 'certmgr.msc' and exporting the - # certificate. See: - # http://www.migee.com/2010/09/24/solution-for-unattendedsilent-installs-and-would-you-like-to-install-this-device-software/ - certutil -addstore "TrustedPublisher" src/trio/_tests/astrill-codesigning-cert.cer - # Double-slashes are how you tell windows-bash that you want a single - # slash, and don't treat this as a unix-style filename that needs to - # be replaced by a windows-style filename. - # http://www.mingw.org/wiki/Posix_path_conversion - ./lsp-installer.exe //silent //norestart - echo "Waiting for LSP to appear in Winsock catalog" - while ! netsh winsock show catalog | grep "Layered Chain Entry"; do - sleep 1 - done - netsh winsock show catalog +# If we're testing with a LSP installed, then it might break network +# stuff, so wait until after we've finished setting everything else +# up. +if [ "$LSP" != "" ]; then + echo "Installing LSP from ${LSP}" + # We use --insecure because one of the LSP's has been observed to give + # cert verification errors: + # + # https://github.com/python-trio/trio/issues/1478 + # + # *Normally*, you should never ever use --insecure, especially when + # fetching an executable! But *in this case*, we're intentionally + # installing some untrustworthy quasi-malware onto into a sandboxed + # machine for testing. So MITM attacks are really the least of our + # worries. + if [ "$LSP_EXTRACT_FILE" != "" ]; then + # We host the Astrill VPN installer ourselves, and encrypt it + # so as to decrease the chances of becoming an inadvertent + # public redistributor. + curl-harder -o lsp-installer.zip "$LSP" + unzip -P "not very secret trio ci key" lsp-installer.zip "$LSP_EXTRACT_FILE" + mv "$LSP_EXTRACT_FILE" lsp-installer.exe + else + curl-harder --insecure -o lsp-installer.exe "$LSP" fi - echo "::endgroup::" - - echo "::group::Setup for tests" + # This is only needed for the Astrill LSP, but there's no harm in + # doing it all the time. The cert was manually extracted by installing + # the package in a VM, clicking "Always trust from this publisher" + # when installing, and then running 'certmgr.msc' and exporting the + # certificate. See: + # http://www.migee.com/2010/09/24/solution-for-unattendedsilent-installs-and-would-you-like-to-install-this-device-software/ + certutil -addstore "TrustedPublisher" src/trio/_tests/astrill-codesigning-cert.cer + # Double-slashes are how you tell windows-bash that you want a single + # slash, and don't treat this as a unix-style filename that needs to + # be replaced by a windows-style filename. + # http://www.mingw.org/wiki/Posix_path_conversion + ./lsp-installer.exe //silent //norestart + echo "Waiting for LSP to appear in Winsock catalog" + while ! netsh winsock show catalog | grep "Layered Chain Entry"; do + sleep 1 + done + netsh winsock show catalog +fi +echo "::endgroup::" - # We run the tests from inside an empty directory, to make sure Python - # doesn't pick up any .py files from our working dir. Might have already - # been created by a previous run. - mkdir empty || true - cd empty +echo "::group::Setup for tests" - INSTALLDIR=$(python -c "import os, trio; print(os.path.dirname(trio.__file__))") - cp ../pyproject.toml "$INSTALLDIR" # TODO: remove this +# We run the tests from inside an empty directory, to make sure Python +# doesn't pick up any .py files from our working dir. Might have already +# been created by a previous run. +mkdir empty || true +cd empty - # get mypy tests a nice cache - MYPYPATH=".." mypy --config-file= --cache-dir=./.mypy_cache -c "import trio" >/dev/null 2>/dev/null || true +INSTALLDIR=$(python -c "import os, trio; print(os.path.dirname(trio.__file__))") +cp ../pyproject.toml "$INSTALLDIR" # TODO: remove this - # support subprocess spawning with coverage.py - echo "import coverage; coverage.process_startup()" | tee -a "$INSTALLDIR/../sitecustomize.py" +# get mypy tests a nice cache +MYPYPATH=".." mypy --config-file= --cache-dir=./.mypy_cache -c "import trio" >/dev/null 2>/dev/null || true - perl -i -pe 's/-p trio\._tests\.pytest_plugin//' "$INSTALLDIR/pyproject.toml" +# support subprocess spawning with coverage.py +echo "import coverage; coverage.process_startup()" | tee -a "$INSTALLDIR/../sitecustomize.py" - echo "::endgroup::" - echo "::group:: Run Tests" - if PYTHONPATH=../tests COVERAGE_PROCESS_START=$(pwd)/../pyproject.toml \ - coverage run --rcfile=../pyproject.toml -m \ - pytest -ra --junitxml=../test-results.xml \ - -p _trio_check_attrs_aliases --verbose --durations=10 \ - -p trio._tests.pytest_plugin --run-slow $flags "${INSTALLDIR}"; then - PASSED=true - else - PASSED=false - fi - echo "::endgroup::" - echo "::group::Coverage" +perl -i -pe 's/-p trio\._tests\.pytest_plugin//' "$INSTALLDIR/pyproject.toml" - coverage combine --rcfile ../pyproject.toml - coverage report -m --rcfile ../pyproject.toml - coverage xml --rcfile ../pyproject.toml +echo "::endgroup::" +echo "::group:: Run Tests" +if PYTHONPATH=../tests COVERAGE_PROCESS_START=$(pwd)/../pyproject.toml \ + coverage run --rcfile=../pyproject.toml -m \ + pytest -ra --junitxml=../test-results.xml \ + -p _trio_check_attrs_aliases --verbose --durations=10 \ + -p trio._tests.pytest_plugin --run-slow $flags "${INSTALLDIR}"; then + PASSED=true +else + PASSED=false +fi +echo "::endgroup::" +echo "::group::Coverage" - # Remove the LSP again; again we want to do this ASAP to avoid - # accidentally breaking other stuff. - if [ "$LSP" != "" ]; then - netsh winsock reset - fi +coverage combine --rcfile ../pyproject.toml +coverage report -m --rcfile ../pyproject.toml +coverage xml --rcfile ../pyproject.toml - echo "::endgroup::" - $PASSED +# Remove the LSP again; again we want to do this ASAP to avoid +# accidentally breaking other stuff. +if [ "$LSP" != "" ]; then + netsh winsock reset fi + +echo "::endgroup::" +$PASSED diff --git a/tox.ini b/tox.ini index 0a06b3c0e..24c5ea99b 100644 --- a/tox.ini +++ b/tox.ini @@ -5,15 +5,17 @@ labels = cython = py39-cython2,py39-cython,py311-cython2,py313-cython # TODO: -# coverage -# ci.sh uses --verbose --durations=10 -# -p _trio_check_attrs_aliases -# mypy cache -# LSP -# apport -# use tox in CI -# switch to nox? -# move to pyproject.toml +# * environment to check coverage +# * replace ci.sh +# * --verbose --durations=10 +# * -p _trio_check_attrs_aliases +# * mypy cache +# * LSP +# * apport +# * use tox in CI +# * switch to nox? +# * move to pyproject.toml? +# * this means conditional deps need to be replaced # protip: install uv-tox for faster venv generation @@ -52,18 +54,6 @@ commands = cython --version python -m tests.cython.run_test_cython -# tox -m check should be equivalent to this -[testenv:checksh] -deps = - -r test-requirements.txt - exceptiongroup -base_python = 3.13 -allowlist_externals = ./check.sh -set_env = - PYRIGHT_PYTHON_IGNORE_WARNINGS=1 -commands = - ./check.sh - [testenv:gen_exports] deps = -r test-requirements.txt