pypa/pip · error · InstallationError
Packages installed from PyPI cannot depend on packages…
Error message
Packages installed from PyPI cannot depend on packages which are not also hosted on PyPI.
{comes_from.name} depends on {req} What it means
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.
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)
Defensive patterns
Strategy: try-catch
Validate before calling
# This is a policy enforcement; pre-validation means checking if the dependency has a URL
from pip._vendor.packaging.requirements import Requirement
def has_external_url_dep(req: Requirement) -> bool:
"""Check if a requirement references a direct (non-PyPI) URL."""
return bool(req.url) Type guard
from pip._vendor.packaging.requirements import Requirement
def is_pypi_safe_requirement(req: Requirement) -> bool:
"""Returns True if the requirement has no direct URL (safe for PyPI deps)."""
return not req.url Try / catch
from pip._internal.exceptions import InstallationError
try:
ireq = install_req_from_req_string(req_string, comes_from=parent_ireq)
except InstallationError as e:
if "cannot depend on packages which are not also hosted on PyPI" in str(e):
logger.warning("Security policy blocked external URL dep from %s", parent_ireq.name)
# install the dependency separately from a trusted source
else:
raise Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Can't verify hashes for these file:// requirements because…
- Can't verify hashes for these requirements because we don't…
- In --require-hashes mode, all requirements must have their…
- The editable requirement
- XMLRPC request failed
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/a31ca388c82dec5c.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/req/constructors.py:470
user_supplied: bool = False,
) -> InstallRequirement:
try:
req = get_requirement(req_string)
except InvalidRequirement as exc:
raise InstallationError(f"Invalid requirement: {req_string!r}: {exc}")
domains_not_allowed = [
PyPI.file_storage_domain,
TestPyPI.file_storage_domain,
]
if (
req.url
and comes_from
and comes_from.link
and comes_from.link.netloc in domains_not_allowed
):
# Explicitly disallow pypi packages that depend on external urls
raise InstallationError(
"Packages installed from PyPI cannot depend on packages "
"which are not also hosted on PyPI.\n"
f"{comes_from.name} depends on {req} "
)
return InstallRequirement(
req,
comes_from,
isolated=isolated,
user_supplied=user_supplied,
)
def install_req_from_parsed_requirement(
parsed_req: ParsedRequirement,
isolated: bool = False,
user_supplied: bool = False,
config_settings: dict[str, str | list[str]] | None = None,View on GitHub (pinned to f399c37189)