|
13 | 13 | import nox
|
14 | 14 | import nox.command
|
15 | 15 |
|
| 16 | +try: |
| 17 | + import tomllib as toml |
| 18 | +except ImportError: |
| 19 | + try: |
| 20 | + import toml |
| 21 | + except ImportError: |
| 22 | + toml = None |
| 23 | + |
16 | 24 | nox.options.sessions = ["test", "clippy", "rustfmt", "ruff", "docs"]
|
17 | 25 |
|
18 | 26 |
|
@@ -479,10 +487,7 @@ def check_changelog(session: nox.Session):
|
479 | 487 | def set_minimal_package_versions(session: nox.Session):
|
480 | 488 | from collections import defaultdict
|
481 | 489 |
|
482 |
| - try: |
483 |
| - import tomllib as toml |
484 |
| - except ImportError: |
485 |
| - import toml |
| 490 | + assert toml is not None, "requires Python 3.11 or toml package" |
486 | 491 |
|
487 | 492 | projects = (
|
488 | 493 | None,
|
@@ -593,6 +598,77 @@ def test_version_limits(session: nox.Session):
|
593 | 598 | _run_cargo(session, "check", env=env, expect_error=True)
|
594 | 599 |
|
595 | 600 |
|
| 601 | +@nox.session(name="test-feature-powerset", venv_backend="none") |
| 602 | +def test_feature_powerset(session: nox.Session): |
| 603 | + assert toml is not None, "requires Python 3.11 or toml package" |
| 604 | + |
| 605 | + with (PYO3_DIR / "Cargo.toml").open("rb") as cargo_toml_file: |
| 606 | + cargo_toml = toml.load(cargo_toml_file) |
| 607 | + |
| 608 | + EXCLUDED_FROM_FULL = { |
| 609 | + "nightly", |
| 610 | + "extension-module", |
| 611 | + "full", |
| 612 | + "default", |
| 613 | + "auto-initialize", |
| 614 | + "generate-import-lib", |
| 615 | + "multiple-pymethods", # TODO add this after MSRV 1.62 |
| 616 | + } |
| 617 | + |
| 618 | + features = cargo_toml["features"] |
| 619 | + |
| 620 | + full_feature = set(features["full"]) |
| 621 | + expected_full_feature = { |
| 622 | + feature |
| 623 | + for feature in features |
| 624 | + if not feature.startswith("abi3") and feature not in EXCLUDED_FROM_FULL |
| 625 | + } |
| 626 | + |
| 627 | + uncovered_features = expected_full_feature - full_feature |
| 628 | + |
| 629 | + assert not uncovered_features, uncovered_features |
| 630 | + |
| 631 | + experimental_features = { |
| 632 | + feature for feature in full_feature if feature.startswith("experimental-") |
| 633 | + } |
| 634 | + full_without_experimental = full_feature - experimental_features |
| 635 | + |
| 636 | + abi3_version_features = { |
| 637 | + feature for feature in features if feature.startswith("abi3-") |
| 638 | + } |
| 639 | + |
| 640 | + # justification: we always assume that feature within these groups are |
| 641 | + # mutually exclusive to simplify CI |
| 642 | + features_to_group = [ |
| 643 | + full_without_experimental, |
| 644 | + experimental_features, |
| 645 | + ] |
| 646 | + |
| 647 | + features_to_skip = [ |
| 648 | + *EXCLUDED_FROM_FULL, |
| 649 | + *abi3_version_features, |
| 650 | + ] |
| 651 | + |
| 652 | + comma_join = ",".join |
| 653 | + _run_cargo( |
| 654 | + session, |
| 655 | + "hack", |
| 656 | + "--feature-powerset", |
| 657 | + '--optional-deps=""', |
| 658 | + f'--skip="{comma_join(features_to_skip)}"', |
| 659 | + *( |
| 660 | + f"--group-features={comma_join(group)}" |
| 661 | + for group in features_to_group |
| 662 | + if len(group) > 1 |
| 663 | + ), |
| 664 | + "test", |
| 665 | + "--lib", |
| 666 | + "--tests", |
| 667 | + # don't run doctests here as it's unlikely they work with |
| 668 | + # literally every combination, and the link times will cripple CI |
| 669 | + ) |
| 670 | + |
| 671 | + |
596 | 672 | def _build_docs_for_ffi_check(session: nox.Session) -> None:
|
597 | 673 | # pyo3-ffi-check needs to scrape docs of pyo3-ffi
|
598 | 674 | _run_cargo(session, "doc", _FFI_CHECK, "-p", "pyo3-ffi", "--no-deps")
|
|
0 commit comments