{"id":"4d9c74eb03576191","repo":"pypa/pip","slug":"editable-requirements-are-not-allowed-as-constrain-4d9c74","errorCode":null,"errorMessage":"Editable requirements are not allowed as constraints","messagePattern":"Editable requirements are not allowed as constraints","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/resolution/resolvelib/factory.py","lineNumber":553,"sourceCode":"            else:\n                # require the base from the link\n                yield self.make_requirement_from_candidate(cand)\n                if ireq.extras:\n                    # require the extras on top of the base candidate\n                    yield self.make_requirement_from_candidate(\n                        self._make_extras_candidate(cand, frozenset(ireq.extras))\n                    )\n\n    def collect_root_requirements(\n        self, root_ireqs: list[InstallRequirement]\n    ) -> CollectedRootRequirements:\n        collected = CollectedRootRequirements([], {}, {})\n        for i, ireq in enumerate(root_ireqs):\n            if ireq.constraint:\n                # Ensure we only accept valid constraints\n                problem = check_invalid_constraint_type(ireq)\n                if problem:\n                    raise InstallationError(problem)\n                if not ireq.match_markers():\n                    continue\n                assert ireq.name, \"Constraint must be named\"\n                name = canonicalize_name(ireq.name)\n                if name in collected.constraints:\n                    collected.constraints[name] &= ireq\n                else:\n                    collected.constraints[name] = Constraint.from_ireq(ireq)\n            else:\n                reqs = list(\n                    self._make_requirements_from_install_req(\n                        ireq,\n                        requested_extras=(),\n                    )\n                )\n                if not reqs:\n                    continue\n                template = reqs[0]","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/resolution/resolvelib/factory.py#L535-L571","documentation":"InstallationError from check_invalid_constraint_type when a constraint entry is editable ('-e ./pkg' or '-e git+...'). Editable installs cannot act as constraints because a constraint only narrows version selection for a named project; an editable is an install instruction. The resolver rejects it (with a preceding deprecation notice) rather than silently misinterpreting it.","triggerScenarios":"A file passed with '-c' contains a line like '-e ./local/pkg' or '-e git+https://.../pkg.git'. collect_root_requirements calls check_invalid_constraint_type, req.editable is True, and the problem string is raised.","commonSituations":"Reusing a monorepo dev-requirements file as both install and constraints; copy-pasting an editable line into a constraints file by mistake; teams merging a constraints file and a dev-install file.","solutions":["Remove '-e' from any line in the constraints file.","Move editable installs into the regular requirements file ('-r'), not the constraints file ('-c').","If you need to pin a local editable, pin the underlying project name+version in the constraint and keep '-e' on the install side.","Re-run pip after editing to confirm."],"exampleFix":"# before — constraints.txt\n-e ./local/mylib\n\n# after — move to requirements.txt\n-e ./local/mylib\n# and in constraints.txt keep only:\nmylib==1.0","handlingStrategy":"validation","validationCode":"def constraints_have_no_editable(path: str) -> bool:\n    bad = [l.strip() for l in open(path) if l.strip().startswith('-e ')]\n    if bad:\n        print(f'editable in constraints: {bad}'); return False\n    return True","typeGuard":"def is_non_editable_constraint(line: str) -> bool:\n    return not line.strip().startswith('-e ')","tryCatchPattern":"if not constraints_have_no_editable('constraints.txt'):\n    print('move -e lines out of constraints file')\nelse:\n    run_pip(['install', '-c', 'constraints.txt', 'pkg'])","preventionTips":["Never put '-e' lines in a constraints file.","Separate install requirements (-r) from constraints (-c) physically.","Lint for '-e' in constraints in CI."],"tags":["constraints","editable","resolver","config"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}