pypa/pip · error · InstallationError

Constraints cannot have extras

Error message

Constraints cannot have extras

What it means

InstallationError from check_invalid_constraint_type when a constraint entry has extras, e.g. 'package[extra]'. Constraints narrow the version of a single project; extras are an install-time selection and cannot be expressed as a constraint, so the resolver rejects the entry (after a deprecation warning).

Source

Thrown at src/pip/_internal/resolution/resolvelib/factory.py:553

            else:
                # require the base from the link
                yield self.make_requirement_from_candidate(cand)
                if ireq.extras:
                    # require the extras on top of the base candidate
                    yield self.make_requirement_from_candidate(
                        self._make_extras_candidate(cand, frozenset(ireq.extras))
                    )

    def collect_root_requirements(
        self, root_ireqs: list[InstallRequirement]
    ) -> CollectedRootRequirements:
        collected = CollectedRootRequirements([], {}, {})
        for i, ireq in enumerate(root_ireqs):
            if ireq.constraint:
                # Ensure we only accept valid constraints
                problem = check_invalid_constraint_type(ireq)
                if problem:
                    raise InstallationError(problem)
                if not ireq.match_markers():
                    continue
                assert ireq.name, "Constraint must be named"
                name = canonicalize_name(ireq.name)
                if name in collected.constraints:
                    collected.constraints[name] &= ireq
                else:
                    collected.constraints[name] = Constraint.from_ireq(ireq)
            else:
                reqs = list(
                    self._make_requirements_from_install_req(
                        ireq,
                        requested_extras=(),
                    )
                )
                if not reqs:
                    continue
                template = reqs[0]

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Strip the '[...]' extras from every line in the constraints file, leaving just 'package<specifier>'.
  2. Put extras on the install side: in requirements.txt use 'package[test]', in constraints.txt use 'package'.
  3. Re-generate constraints from your lockfile with extras excluded.
  4. Re-run pip to confirm no constraint carries extras.

Example fix

# before — constraints.txt
requests[socks]==2.31.0

# after
requests==2.31.0   # extras belong in requirements.txt, not constraints.txt
Defensive patterns

Strategy: validation

Validate before calling

def constraints_have_no_extras(path: str) -> bool:
    import re
    bad = [l.strip() for l in open(path) if re.search(r'\[[^\]]+\]', l)]
    if bad:
        print(f'extras in constraints: {bad}'); return False
    return True

Type guard

def is_constraint_without_extras(line: str) -> bool:
    import re
    return not re.search(r'^[^\s#-]\S*\[[^\]]+\]', line.strip())

Try / catch

if not constraints_have_no_extras('constraints.txt'):
    print('strip extras from constraints lines')
else:
    run_pip(['install', '-c', 'constraints.txt', 'pkg'])

Prevention

When it happens

Trigger: A constraints file ('-c') contains 'package[test]' or 'package[extra1,extra2]'. req.extras is non-empty in check_invalid_constraint_type, the problem string is set, and collect_root_requirements raises.

Common situations: Lockfile tool emitting extras into a constraints file; reusing a dev-requirements file as constraints; combining extras with version pins in the same file.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/a7009b949f806d6c.json. Report an issue: GitHub.