diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b81131a2..d0f8d0a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,32 @@ jobs: - name: Check rust formatting (rustfmt) run: nox -s fmt-rust + check-msrv: + needs: [fmt] + runs-on: ubuntu-latest + if: github.ref != 'refs/heads/main' + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.56.0 + targets: x86_64-unknown-linux-gnu + components: clippy,rust-src + - uses: actions/setup-python@v4 + with: + architecture: "x64" + - uses: Swatinem/rust-cache@v2 + with: + key: check-msrv-1.56.0 + continue-on-error: true + - run: python -m pip install --upgrade pip && pip install nox + - name: Prepare minimal package versions + run: nox -s set-minimal-package-versions + - run: nox -s check-all + + env: + CARGO_BUILD_TARGET: x86_64-unknown-linux-gnu + clippy: needs: [fmt] runs-on: ${{ matrix.platform.os }} @@ -80,16 +106,6 @@ jobs: rust-target: "i686-pc-windows-msvc", }, ] - include: - - rust: 1.56.0 - python-version: "3.11" - platform: - { - os: "ubuntu-latest", - python-architecture: "x64", - rust-target: "x86_64-unknown-linux-gnu", - } - msrv: "MSRV" name: clippy/${{ matrix.platform.rust-target }}/${{ matrix.rust }} steps: - uses: actions/checkout@v3 @@ -106,9 +122,6 @@ jobs: key: clippy-${{ matrix.platform.rust-target }}-${{ matrix.platform.os }}-${{ matrix.rust }} continue-on-error: true - run: python -m pip install --upgrade pip && pip install nox - - if: matrix.msrv == 'MSRV' - name: Prepare minimal package versions (MSRV only) - run: nox -s set-minimal-package-versions - run: nox -s clippy-all env: CARGO_BUILD_TARGET: ${{ matrix.platform.rust-target }} @@ -353,6 +366,7 @@ jobs: conclusion: needs: - fmt + - check-msrv - clippy - build-pr - build-full diff --git a/noxfile.py b/noxfile.py index d264cdc0..7b8246e1 100644 --- a/noxfile.py +++ b/noxfile.py @@ -8,7 +8,7 @@ import time from functools import lru_cache from glob import glob from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Callable, Dict, List, Optional, Tuple import nox @@ -96,25 +96,19 @@ def _clippy(session: nox.Session, *, env: Dict[str, str] = None) -> bool: success = True env = env or os.environ for feature_set in _get_feature_sets(): - command = "clippy" - extra = ("--", "--deny=warnings") - if _get_rust_version()[:2] == (1, 48): - # 1.48 crashes during clippy because of lints requested - # in .cargo/config - command = "check" - extra = () try: _run( session, "cargo", - command, + "clippy", *feature_set, "--all-targets", "--workspace", # linting pyo3-ffi-check requires docs to have been built or # the macros will error; doesn't seem worth it on CI "--exclude=pyo3-ffi-check", - *extra, + "--", + "--deny=warnings", external=True, env=env, ) @@ -126,31 +120,43 @@ def _clippy(session: nox.Session, *, env: Dict[str, str] = None) -> bool: @nox.session(name="clippy-all", venv_backend="none") def clippy_all(session: nox.Session) -> None: success = True - with tempfile.NamedTemporaryFile("r+") as config: - env = os.environ.copy() - env["PYO3_CONFIG_FILE"] = config.name - env["PYO3_CI"] = "1" - def _clippy_with_config(implementation, version) -> bool: - config.seek(0) - config.truncate(0) - config.write( - f"""\ -implementation={implementation} -version={version} -suppress_build_script_link_lines=true -""" - ) - config.flush() + def _clippy_with_config(env: Dict[str, str]) -> None: + nonlocal success + success &= _clippy(session, env=env) - session.log(f"{implementation} {version}") - return _clippy(session, env=env) + _for_all_version_configs(session, _clippy_with_config) - for version in PY_VERSIONS: - success &= _clippy_with_config("CPython", version) + if not success: + session.error("one or more jobs failed") - for version in PYPY_VERSIONS: - success &= _clippy_with_config("PyPy", version) + +@nox.session(name="check-all", venv_backend="none") +def check_all(session: nox.Session) -> None: + success = True + + def _check(env: Dict[str, str]) -> None: + nonlocal success + env = env or os.environ + for feature_set in _get_feature_sets(): + try: + _run( + session, + "cargo", + "check", + *feature_set, + "--all-targets", + "--workspace", + # linting pyo3-ffi-check requires docs to have been built or + # the macros will error; doesn't seem worth it on CI + "--exclude=pyo3-ffi-check", + external=True, + env=env, + ) + except Exception: + success = False + + _for_all_version_configs(session, _check) if not success: session.error("one or more jobs failed") @@ -422,42 +428,13 @@ def set_minimal_package_versions(session: nox.Session): "examples/word-count", ) min_pkg_versions = { - # newer versions of rust_decimal want newer arrayvec - "rust_decimal": "1.18.0", - # newer versions of arrayvec use const generics (Rust 1.51+) - "arrayvec": "0.5.2", + "rust_decimal": "1.26.1", "csv": "1.1.6", - # newer versions of chrono use i32::rem_euclid as a const fn - "chrono": "0.4.24", - "indexmap": "1.6.2", - "inventory": "0.3.4", - "hashbrown": "0.9.1", - "plotters": "0.3.1", - "plotters-svg": "0.3.1", - "plotters-backend": "0.3.2", - "bumpalo": "3.10.0", - "once_cell": "1.14.0", - "rayon": "1.5.3", - "rayon-core": "1.9.3", + "hashbrown": "0.12.3", + "once_cell": "1.17.2", + "rayon": "1.6.1", + "rayon-core": "1.10.2", "regex": "1.7.3", - # string_cache 0.8.4 depends on parking_lot 0.12 - "string_cache": "0.8.3", - # 1.15.0 depends on hermit-abi 0.2.6 which has edition 2021 and breaks 1.48.0 - "num_cpus": "1.14.0", - "parking_lot": "0.11.0", - # 1.0.77 needs basic-toml which has edition 2021 - "trybuild": "1.0.76", - # pins to avoid syn 2.0 (which requires Rust 1.56) - "ghost": "0.1.8", - "serde": "1.0.156", - "serde_derive": "1.0.156", - "cxx": "1.0.92", - "cxxbridge-macro": "1.0.92", - "cxx-build": "1.0.92", - "web-sys": "0.3.61", - "js-sys": "0.3.61", - "wasm-bindgen": "0.2.84", - "syn": "1.0.109", } # run cargo update first to ensure that everything is at highest @@ -634,7 +611,7 @@ def _run_cargo_set_package_version( *, project: Optional[str] = None, ) -> None: - command = ["cargo", "update", "-p", pkg_id, "--precise", version] + command = ["cargo", "update", "-p", pkg_id, "--precise", version, "--workspace"] if project: command.append(f"--manifest-path={project}/Cargo.toml") _run(session, *command, external=True) @@ -642,3 +619,33 @@ def _run_cargo_set_package_version( def _get_output(*args: str) -> str: return subprocess.run(args, capture_output=True, text=True, check=True).stdout + + +def _for_all_version_configs( + session: nox.Session, job: Callable[[Dict[str, str]], None] +) -> None: + with tempfile.NamedTemporaryFile("r+") as config: + env = os.environ.copy() + env["PYO3_CONFIG_FILE"] = config.name + env["PYO3_CI"] = "1" + + def _job_with_config(implementation, version) -> bool: + config.seek(0) + config.truncate(0) + config.write( + f"""\ +implementation={implementation} +version={version} +suppress_build_script_link_lines=true +""" + ) + config.flush() + + session.log(f"{implementation} {version}") + return job(env) + + for version in PY_VERSIONS: + _job_with_config("CPython", version) + + for version in PYPY_VERSIONS: + _job_with_config("PyPy", version) diff --git a/pyo3-build-config/src/lib.rs b/pyo3-build-config/src/lib.rs index f870daa7..07c5bcb6 100644 --- a/pyo3-build-config/src/lib.rs +++ b/pyo3-build-config/src/lib.rs @@ -161,6 +161,11 @@ pub fn print_feature_cfgs() { if rustc_minor_version >= 59 { println!("cargo:rustc-cfg=thread_local_const_init"); } + + // Enable use of `#[cfg(panic = "...")]` on Rust 1.60 and greater + if rustc_minor_version >= 60 { + println!("cargo:rustc-cfg=panic_unwind"); + } } /// Private exports used in PyO3's build.rs diff --git a/tests/test_class_attributes.rs b/tests/test_class_attributes.rs index 04397145..e07aa457 100644 --- a/tests/test_class_attributes.rs +++ b/tests/test_class_attributes.rs @@ -96,7 +96,7 @@ fn recursive_class_attributes() { } #[test] -#[cfg(panic = "unwind")] +#[cfg_attr(cfg_panic, cfg(panic = "unwind"))] fn test_fallible_class_attribute() { use pyo3::{exceptions::PyValueError, types::PyString};