pypa/pip · error · CommandError

When restricting platform and interpreter constraints using…

Error message

When restricting platform and interpreter constraints using --python-version, --platform, --abi, or --implementation, either --no-deps must be set, or --only-binary=:all: must be set and --no-binary must not be set (or must be set to :none:).

What it means

Raised as CommandError by check_dist_restriction (cmdoptions.py:123) when platform/interpreter constraint options (--python-version, --platform, --abi, --implementation) are set together with source-distribution dependencies allowed. The guard at lines 114-122 computes sdist_dependencies_allowed as format_control != only-binary:all: OR not --no-deps; combining cross-platform targeting with sdists is unsafe because source builds run against the host interpreter, not the constrained target, so the resulting artifacts are not guaranteed to be compatible.

Solutions

  1. Add `--only-binary=:all:` (and ensure --no-binary is unset or `:none:`) so only prebuilt wheels for the target are selected.
  2. Alternatively add `--no-deps` to skip dependency resolution entirely (you then handle deps separately).
  3. Verify the package actually publishes wheels for your target platform/abi; if only sdists exist, cross-targeting is unsupported for that package.

Example fix

# before
pip download --platform manylinux2014_x86_64 --python-version 39 --abi cp39 numpy
# after
pip download --platform manylinux2014_x86_64 --python-version 39 --abi cp39 --only-binary=:all: numpy
Defensive patterns

Strategy: validation

Validate before calling

# Enforce the cross-target rule before invoking pip.
def validate_cross_target(opts):
    restricted = any(opts.get(k) for k in ("python_version", "platforms", "abis", "implementation"))
    binary_all = opts.get("only_binary") == ":all:" and not opts.get("no_binary")
    if restricted and not (opts.get("no_deps") or binary_all):
        raise ValueError("Add --only-binary=:all: or --no-deps when using platform/abi constraints")
    return True

Prevention

When it happens

Trigger: `pip download --platform manylinux2014_x86_64 --python-version 39 --abi cp39 <pkg>` without --only-binary=:all: or --no-deps; mixing --implementation with any package whose deps might need building.

Common situations: Building a wheel cache for a different platform (common in lock-file generation and air-gapped environments) and forgetting to force binary-only resolution; upgrading a resolver workflow that previously used --no-deps but dropped it.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/bcc58b12d6333bf4. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_internal/cli/cmdoptions.py:123

    dist_restriction_set = any(
        [
            options.python_version,
            options.platforms,
            options.abis,
            options.implementation,
        ]
    )

    binary_only = FormatControl(set(), {":all:"})
    sdist_dependencies_allowed = (
        options.format_control != binary_only and not options.ignore_dependencies
    )

    # Installations or downloads using dist restrictions must not combine
    # source distributions and dist-specific wheels, as they are not
    # guaranteed to be locally compatible.
    if dist_restriction_set and sdist_dependencies_allowed:
        raise CommandError(
            "When restricting platform and interpreter constraints using "
            "--python-version, --platform, --abi, or --implementation, "
            "either --no-deps must be set, or --only-binary=:all: must be "
            "set and --no-binary must not be set (or must be set to "
            ":none:)."
        )

    if check_target:
        if not options.dry_run and dist_restriction_set and not options.target_dir:
            raise CommandError(
                "Can not use any platform or abi specific options unless "
                "installing via '--target' or using '--dry-run'"
            )

    if dist_restriction_set:
        # Lazy import to keep CLI startup fast
        from pip._internal.utils import pylock as pylock_utils

View on GitHub (pinned to f399c37189)