{"id":"98f444cb7538884c","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/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/req/constructors.py#L452-L488","documentation":"Raised by install_req_from_req_string() when a requirement resolved from a package hosted on PyPI (or TestPyPI) itself depends on a package whose URL is NOT hosted on PyPI's file storage domain. This is a safety guard (constructors.py:470): pip forbids PyPI packages from transparently pulling arbitrary external code, which could be a supply-chain exfiltration or trojan vector.","triggerScenarios":"A package on PyPI declares a dependency like `evil @ https://evil.example.com/code` or `git+https://...`. When pip resolves that dependency, comes_from.link.netloc is files.pythonhosted.org (PyPI) but req.url points elsewhere, tripping the check at constructors.py:463-468.","commonSituations":"A legitimate package mistakenly externalizing a dependency. A typosquatted or compromised package trying to pull external payloads. Using --index-url pointing at a mirror while a dep hardcodes a non-PyPI URL. Test packages on TestPyPI referencing external repos.","solutions":["Do not use the offending package; report it to PyPI's security team if it appears malicious.","If you control the package, publish the dependency to PyPI instead of referencing an external URL.","If this is your own private/index setup, ensure dependencies also resolve through your index rather than hardcoded external URLs.","As a last resort for trusted internal use, vendor the dependency or host it on your own index."],"exampleFix":"# before (in a package's dependencies on PyPI)\n# install_requires=[\"helper @ https://my.server/helper.tar.gz\"]\n# after\n# Publish 'helper' to PyPI, then:\n# install_requires=[\"helper>=1.0\"]","handlingStrategy":"validation","validationCode":"from pip._internal.models.index import PyPI, TestPyPI\n\ndef assert_no_external_dep_from_pypi(req_url: str, comes_from_netloc: str) -> None:\n    forbidden = {PyPI.file_storage_domain, TestPyPI.file_storage_domain}\n    if req_url and comes_from_netloc in forbidden:\n        # req_url starting with http(s):// that is NOT on files.pythonhosted.org\n        from urllib.parse import urlparse\n        netloc = urlparse(req_url).netloc\n        if netloc and netloc not in forbidden:\n            raise ValueError(f\"PyPI package cannot depend on external URL {req_url}\")","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Never publish a package whose dependencies reference external URLs; keep all deps on PyPI.","Audit install_requires/dependencies for any `name @ url` entries before release.","Treat this error as a possible supply-chain incident and investigate upstream packages."],"tags":["security","supply-chain","pypi","requirements"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}