Installing Packages
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the Python Reference bibliography. |
pip install is pip’s central command: it turns requirements into installed distributions in one environment. This page goes
through its behaviour and options for pip 26.2.2. Every example ran on CPython 3.14.6 on 2026-10-22, in a fresh venv, against PyPI
on that day and the birdtally wheel built on the
packaging concepts page (passed with
--find-links dist). Requirement files, constraints, groups, indexes, VCS installs, builds and hashes have their own pages; see the
pip landing page.
What pip install does
pip install [options] <requirement specifier> [package-index-options] ...
pip install [options] -r <requirements file> [package-index-options] ...
pip install [options] [-e] <vcs project url> ...
pip install [options] [-e] <local project path> ...
pip install [options] <archive url/path> ...
-
Argument handling. Each argument is classified, in this order, as a project or archive URL, a local directory (which must contain
pyproject.tomlorsetup.py), a local sdist or wheel file, or a requirement specifier. -
Working out the name and version. For a wheel, from the file name. For local directories and explicitly given sdists, pip asks the project’s build backend for the metadata (a PEP 517 build, see Build System Interface). For sdists found on an index, from the file name.
-
Finding packages on the index (PyPI unless
--index-urlsays otherwise),--find-linkslocations and any--extra-index-url. All locations are equal: pip takes the best version from any of them. -
Satisfying requirements. The resolver picks, for every package, the latest version that satisfies all constraints, excluding pre-releases by default. See Dependency Resolution.
-
Installation order. Dependencies are installed before their dependents ("topological order", since pip 6.1), so the environment stays usable if the install fails half way. That is the only promise about order.
Requirement forms
python -m pip install birdtally # a name: the latest final release
python -m pip install "birdtally==0.1.0" # a specifier
python -m pip install "birdtally[pretty]>=0.1" # extras and a specifier
python -m pip install 'colorama; sys_platform == "win32"' # a marker
python -m pip install ./dist/birdtally-0.1.0-py3-none-any.whl # a local wheel or sdist
python -m pip install . # a local project directory
python -m pip install "birdtally @ https://example.org/birdtally-0.1.0-py3-none-any.whl" # a direct URL
python -m pip install -r requirements.txt # a requirements file
Quote anything with [, <, >, ; or spaces. > redirects output in every shell (pip install rich>=13 writes a file named
=13), and zsh treats [pretty] as a glob, failing with no matches found before pip even runs. The syntax itself is PEP 508; see
Versions & Dependency Specifiers.
Upgrades and reinstalls
Without --upgrade, an already installed version that satisfies the requirement is kept and the resolver does not even look at
newer ones. The options:
| Option | Effect |
|---|---|
|
Allow the named packages to move to the newest allowed version. |
|
Dependencies are upgraded only if the new version of a named package needs a newer one. |
|
Upgrade every dependency to the newest allowed version too. |
|
Reinstall all packages even if they are up to date. |
|
Ignore what is installed and overwrite it. Can break an environment whose packages came from another installer. |
|
Install only the named packages, none of their dependencies. |
|
Ignore |
With rich 13.9.4 already installed, installing birdtally with its pretty extra keeps it, because rich>=13 is satisfied:
python -m pip install "rich==13.9.4"
python -m pip install --find-links dist "birdtally[pretty]"
Looking in links: dist
Processing ./dist/birdtally-0.1.0-py3-none-any.whl
Requirement already satisfied: rich>=13 in ./.venv/lib/python3.14/site-packages (from birdtally[pretty]) (13.9.4)
Requirement already satisfied: markdown-it-py>=2.2.0 in ./.venv/lib/python3.14/site-packages (from rich>=13->birdtally[pretty]) (4.2.0)
Requirement already satisfied: pygments<3.0.0,>=2.13.0 in ./.venv/lib/python3.14/site-packages (from rich>=13->birdtally[pretty]) (2.21.0)
Requirement already satisfied: mdurl~=0.1 in ./.venv/lib/python3.14/site-packages (from markdown-it-py>=2.2.0->rich>=13->birdtally[pretty]) (0.1.2)
Installing collected packages: birdtally
Successfully installed birdtally-0.1.0
--upgrade alone still keeps rich 13.9.4 (only-if-needed); --upgrade-strategy eager replaces it:
python -m pip install --upgrade --upgrade-strategy eager --find-links dist "birdtally[pretty]"
…
Uninstalling rich-13.9.4:
Successfully uninstalled rich-13.9.4
Successfully installed rich-15.0.0
only-if-needed became the default in pip 10. The design notes describe a third, undocumented to-satisfy-only strategy that you
should not use.
--only-deps (pip 26.2)
--only-deps installs the dependencies of the given requirements without the requirements themselves: the common "prepare an
environment for this project, then mount the source" step. Extras work:
python -m pip install --only-deps "./birdtally[pretty]"
python -m pip list
Processing …/pip-flavour/birdtally
Collecting rich>=13 (from birdtally==0.1.0)
Using cached rich-15.0.0-py3-none-any.whl.metadata (18 kB)
…
Installing collected packages: pygments, mdurl, markdown-it-py, rich
Successfully installed markdown-it-py-4.2.0 mdurl-0.1.2 pygments-2.21.0 rich-15.0.0
birdtally itself is not in pip list afterwards. The option cannot be combined with --no-deps, -r, --group or
--requirements-from-script (or the legacy resolver): every package in a requirements file or group counts as user-supplied, so
pip could not tell whether you mean "these packages" or "their dependencies".
python -m pip install --only-deps --group test .
ERROR: Cannot use '--only-dependencies' in combination with '--group'. If this is unexpected, please refer to the user guide:
https://pip.pypa.io/en/stable/user_guide/#installing-only-dependencies
Poetry’s equivalent is poetry install --no-root.
Where packages go
| Option | Destination |
|---|---|
(none) |
The |
|
The user site ( |
|
A plain directory, for vendoring or bundling. Existing files are not replaced unless |
|
An installation prefix with its own |
|
Install everything relative to an alternate root, for building distribution packages. |
Inside a venv the user site is invisible, and --user fails:
ERROR: Can not perform a '--user' install. User site-packages are not visible in this virtualenv.
--target ./target and --prefix ./prefix with tomli-w produce:
target/tomli_w
target/tomli_w-1.2.0.dist-info
prefix/lib/python3.14/site-packages/tomli_w
prefix/lib/python3.14/site-packages/tomli_w-1.2.0.dist-info
Neither is checked by the PEP 668 marker, because neither installs into the interpreter’s own environment.
Pre-releases
By default pip ignores pre-releases unless nothing else satisfies a requirement. On 2026-10-22 the newest Celery was 5.7.0rc1
while the newest final release was 5.6.3:
| Command | celery | kombu (a dependency) |
|---|---|---|
|
5.6.3 |
5.6.2 |
|
5.7.0rc1 |
5.7.0rc1 |
|
5.7.0rc1 |
5.7.0rc1 |
|
5.6.3 |
5.6.2 |
(Each row was produced with --dry-run --quiet --report - and the versions read from the report.)
-
--pre(PIP_PRE) allows pre-releases of every package. -
--all-releases <names>(26.0) allows them for the named packages only,:all:for all,:none:to reset. -
--only-final <names>(26.0) forbids them for the named packages, which wins over--all-releases :all:. -
--precannot be combined with the other two:ERROR: --pre cannot be used with --all-releases or --only-final.
Allowing pre-releases of celery alone also pulled in kombu 5.7.0rc1, because celery 5.7.0rc1 requires a kombu pre-release
explicitly, and a specifier that names a pre-release allows it. In the last row, forbidding kombu pre-releases forced pip back to
the final Celery. A pre-release that is already installed is always acceptable.
Wheels or sources
| Option | Effect |
|---|---|
|
Never use sdists for these packages ( |
|
Never use wheels from the index for these packages; build from source. Cached wheels may still be used. |
|
Prefer an older wheel over a newer sdist. |
docopt has only ever published an sdist, so binary-only mode cannot install it:
python -m pip install --dry-run --only-binary :all: docopt
ERROR: Could not find a version that satisfies the requirement docopt (from versions: none)
ERROR: No matching distribution found for docopt
(from versions: none) here does not mean the project is missing: every file was filtered out. Without the option pip downloads
docopt-0.6.2.tar.gz and builds it. --no-binary tomli-w does the reverse and builds tomli_w-1.2.0.tar.gz although a wheel
exists. Wheels are preferred because installing one runs no project code; see
Packaging Concepts & Standards.
Selecting for another platform
--platform, --python-version, --implementation and --abi make pip pick wheels for a different interpreter or operating
system, which is mainly useful with pip download and --target to prepare a bundle. Because pip cannot build or inspect sdists for
a platform it is not running on, these options require --no-deps or --only-binary=:all::
python -m pip download --platform win_amd64 -d w2 tomli
ERROR: When restricting platform and interpreter constraints using --python-version, --platform, --abi, or --implementation, either --no-deps must be set, or --only-binary=:all: must be set and --no-binary must not be set (or must be set to :none:).
python -m pip download --no-deps --only-binary :all: --platform win_amd64 --python-version 3.13 --implementation cp -d winwheels "tomli==2.5.0"
ls winwheels
Saved ./winwheels/tomli-2.5.0-cp313-cp313-win_amd64.whl
Successfully downloaded tomli
tomli-2.5.0-cp313-cp313-win_amd64.whl
Time and freshness: --uploaded-prior-to and --refresh-package
--uploaded-prior-to (26.0, durations such as P3D since 26.1) hides files uploaded after a date or more recently than a number of
days, as a cooldown against compromised releases or to reproduce an old resolution. --refresh-package <names> (26.2) bypasses the
cached index page for those packages; it is needed since 26.2 because pip now honours the index’s Cache-Control headers, so a
release published a minute ago may not be visible yet. Both are demonstrated on
Supply-Chain Security.
--dry-run and the installation report
--dry-run (22.2) resolves and prints Would install … without changing anything. --report <file> (22.2, format version 1
stable since 23.0) writes a JSON description of what pip installed or would install; - writes it to standard output, in which
case add --quiet so that log lines do not mix with the JSON. With --ignore-installed the report describes a full resolution
regardless of what is installed:
python -m pip install --dry-run --ignore-installed --quiet --report - --find-links dist "birdtally[pretty]" > report.json
The top level holds version, pip_version, the marker environment and the install array. The first two items, with the
metadata trimmed and the hashes shortened:
{
"download_info": {
"url": "file://…/dist/birdtally-0.1.0-py3-none-any.whl",
"archive_info": {
"hashes": {
"sha256": "35a50693…9984a56b5a"
},
"hash": "sha256=35a5069350968616bed7f40135c5594911438241543d3b4a03fa389984a56b5a"
}
},
"is_direct": false,
"is_yanked": false,
"requested": true,
"requested_extras": [
"pretty"
],
"metadata": {
"metadata_version": "2.5",
"name": "birdtally",
"version": "0.1.0",
"requires_dist": [
"rich>=13; extra == 'pretty'"
],
"provides_extra": [
"pretty"
]
}
}
{
"download_info": {
"url": "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl",
"archive_info": {
"hashes": {
"sha256": "33bd4ef7…e27de0bb"
},
"hash": "sha256=33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb"
}
},
"is_direct": false,
"is_yanked": false,
"requested": false
}
-
requestedis true for what you asked for (on the command line or in a requirements file), false for dependencies, andrequested_extrasappears only on requested items. -
is_directis true for direct URL requirements;download_infothen equals the futuredirect_url.json. -
is_yanked(23.3) flags a yanked file that pip still selected because it was pinned exactly. -
metadatais the full core metadata as JSON, including the PEP 639 licence fields since pip 25.0.
The documentation is explicit that the report is "not meant to be a lock file format": it describes one resolution on one platform.
Use pip lock or poetry.lock for that.
Bytecode and root
--compile (the default) byte-compiles the installed .py files; --no-compile skips it, which saves time and space in images
where the files are compiled on first import anyway. --no-warn-script-location silences the warning that a console script went
into a directory that is not on PATH, and --no-warn-conflicts the conflict warning described next. --root-user-action ignore
silences the warning about running as root.
Source: pip install: --root-user-action.
The consistency pitfall: pip install x, then pip install y
Each pip install resolves only the requirements it is given, together with what they need. It does not re-check every package
already installed. A second command can therefore break the first:
python -m pip install "rich==15.0.0"
python -m pip install "markdown-it-py<2"
python -m pip check; echo "exit=$?"
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
rich 15.0.0 requires markdown-it-py>=2.2.0, but you have markdown-it-py 1.1.0 which is incompatible.
Successfully installed attrs-21.4.0 markdown-it-py-1.1.0
rich 15.0.0 has requirement markdown-it-py>=2.2.0, but you have markdown-it-py 1.1.0.
exit=1
The install succeeds with a warning; only pip check (exit code 1) turns it into a failure. Worse, extras are invisible to the
check: after pip install "birdtally[pretty]", pip install "rich<13" installed rich 12.6.0 and pip check printed
No broken requirements found., because pip does not record which extras were requested. The cure is to install everything an
environment needs in one command (a requirements file, a lock file or a group) and to run pip check in CI. Poetry avoids the
problem by resolving the whole project every time; see
Poetry: Lock File, install, update & sync.
Source: pip user guide: Installing packages, pip check.
pip and Poetry
| pip | Poetry |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|