Dependency configuration¶
Project dependencies are defined with PEP 508 strings using optional PEP 440 version specifiers.
Version specifiers¶
A version specifier consists of a series of version clauses, separated by commas. For example:
[project]
...
dependencies = [
"cryptography",
"click>=7, <9, != 8.0.0",
"python-dateutil==2.8.*",
"numpy~=1.21.4",
]
The comma is equivalent to a logical AND
operator: a candidate version must match all given version clauses in order to match the specifier as a whole.
Operators¶
Operators | Function |
---|---|
~= | Compatible release |
== | Version matching |
!= | Version exclusion |
<= , >= | Inclusive ordered comparison |
< , > | Exclusive ordered comparison |
=== | Arbitrary equality |
Version matching¶
A version matching clause includes the version matching operator ==
and a version identifier.
By default, the version matching operator is based on a strict equality comparison: the specified version must be exactly the same as the requested version.
Clause | Allowed versions |
---|---|
==1 | 1.0.0 |
==1.2 | 1.2.0 |
Prefix matching may be requested instead of strict comparison, by appending a trailing .*
to the version identifier in the version matching clause. This means that additional trailing segments will be ignored when determining whether or not a version identifier matches the clause.
Clause | Allowed versions |
---|---|
==1.* | >=1.0.0, <2.0.0 |
==1.2.* | >=1.2.0, <1.3.0 |
Compatible release¶
A compatible release clause consists of the compatible release operator ~=
and a version identifier. It matches any candidate version that is expected to be compatible with the specified version.
For a given release identifier V.N
, the compatible release clause is approximately equivalent to the following pair of comparison clauses:
>= V.N, == V.*
This operator cannot be used with a single segment version number such as ~=1
.
Clause | Allowed versions |
---|---|
~=1.2 | >=1.2.0, <2.0.0 |
~=1.2.3 | >=1.2.3, <1.3.0 |
Version exclusion¶
A version exclusion clause includes the version exclusion operator !=
and a version identifier.
The allowed version identifiers and comparison semantics are the same as those of the Version matching operator, except that the sense of any match is inverted.
Ordered comparison¶
Inclusive comparisons allow for the version identifier part of clauses whereas exclusive comparisons do not. For example, >=1.2
allows for version 1.2.0
while >1.2
does not.
Unlike the inclusive ordered comparisons <=
and >=
, the exclusive ordered comparisons <
and >
specifically exclude pre-releases, post-releases, and local versions of the specified version.
Arbitrary equality¶
Though heavily discouraged, arbitrary equality comparisons allow for simple string matching without any version semantics, for example ===foobar
.
Environment markers¶
Environment markers allow for dependencies to only be installed when certain conditions are met.
For example, if you need to install the latest version of cryptography
that is available for a given Python major version you could define the following:
cryptography==3.3.2; python_version < "3"
cryptography>=35.0; python_version > "3"
Alternatively, if you only need it on Python 3 when running on Windows you could do:
cryptography; python_version ~= "3.0" and platform_system == "Windows"
The available environment markers are as follows.
Marker | Python equivalent | Examples |
---|---|---|
os_name | import os os.name |
|
sys_platform | import sys sys.platform |
|
platform_machine | import platform platform.machine() |
|
platform_python_implementation | import platform platform.python_implementation() |
|
platform_release | import platform platform.release() |
|
platform_system | import platform platform.system() |
|
platform_version | import platform platform.version() |
|
python_version | import platform '.'.join(platform.python_version_tuple()[:2]) |
|
python_full_version | import platform platform.python_version() |
|
implementation_name | import sys sys.implementation.name |
|
implementation_version | See here |
|
Features¶
You can select groups of optional dependencies to install using the extras syntax. For example, if a dependency named foo
defined the following:
[project.optional-dependencies]
crypto = [
"PyJWT",
"cryptography",
]
fastjson = [
"orjson",
]
cli = [
"prompt-toolkit",
"colorama; platform_system == 'Windows'",
]
You can select the cli
and crypto
features like so:
foo[cli,crypto]==1.*
Note that the features come immediately after the package name, before any version specifiers.
Self-referential¶
Feature groups can self-referentially extend others. For example, for a project called awesome-project
, the dev
feature group in the following pyproject.toml
file would select everything in the crypto
feature group, plus black
:
[project]
name = "awesome-project"
[project.optional-dependencies]
crypto = [
"PyJWT",
"cryptography",
]
dev = [
"awesome-project[crypto]",
"black",
]
Direct references¶
Instead of using normal version specifiers and fetching packages from an index like PyPI, you can define exact sources using direct references with an explicit URI.
Direct references are usually not meant to be used for dependencies of a published project but rather are used for defining dependencies for an environment.
All direct reference types are prefixed by the package name like:
<NAME> @ <REFERENCE>
Version control systems¶
Various version control systems (VCS) are supported as long as the associated executable is available along your PATH
.
VCS direct references are defined using one of the following formats:
<NAME> @ <SCHEME>://<PATH>
<NAME> @ <SCHEME>://<PATH>@<REVISION>
You may also append a #subdirectory=<PATH>
component for specifying the relative path to the Python package when it is not located at the root e.g. #subdirectory=lib/foo
.
For more information, refer to this.
Supported VCS¶
Executable | Schemes | Revisions | Example |
---|---|---|---|
git |
|
| proj @ git+https://github.com/org/proj.git@v1 |
Executable | Schemes | Revisions | Example |
---|---|---|---|
hg |
|
| proj @ hg+file:///path/to/proj@v1 |
Executable | Schemes | Revisions | Example |
---|---|---|---|
svn |
|
| proj @ svn+file:///path/to/proj |
Executable | Schemes | Revisions | Example |
---|---|---|---|
bzr |
|
| proj @ bzr+lp:proj@v1 |
Local¶
You can install local packages with the file
scheme in the following format:
<NAME> @ file://<HOST>/<PATH>
The <HOST>
is only used on Windows systems, where it can refer to a network share. If omitted it is assumed to be localhost
and the third slash must still be present.
The <PATH>
can refer to a source archive, a wheel, or a directory containing a Python package.
Type | Unix | Windows |
---|---|---|
Source archive | proj @ file:///path/to/pkg.tar.gz | proj @ file:///c:/path/to/pkg.tar.gz |
Wheel | proj @ file:///path/to/pkg.whl | proj @ file:///c:/path/to/pkg.whl |
Directory | proj @ file:///path/to/pkg | proj @ file:///c:/path/to/pkg |
Tip
You may also specify paths relative to your project's root directory on all platforms by using context formatting:
<NAME> @ {root:uri}/pkg_inside_project
<NAME> @ {root:parent:uri}/pkg_alongside_project
Remote¶
You can install source archives and wheels by simply referring to a URL:
black @ https://github.com/psf/black/archive/refs/tags/21.10b0.zip
pytorch @ https://download.pytorch.org/whl/cu102/torch-1.10.0%2Bcu102-cp39-cp39-linux_x86_64.whl
An expected hash value may be specified by appending a #<HASH_ALGORITHM>=<EXPECTED_HASH>
component:
requests @ https://github.com/psf/requests/archive/refs/tags/v2.26.0.zip#sha256=eb729a757f01c10546ebd179ae2aec852dd0d7f8ada2328ccf4558909d859985
If the hash differs from the expected hash, the installation will fail.
It is recommended that only hashes which are unconditionally provided by the latest version of the standard library's hashlib module be used for hashes. As of Python 3.10, that list consists of:
md5
sha1
sha224
sha256
sha384
sha512
blake2b
blake2s
Complex syntax¶
The following is an example that uses features and environment markers:
pkg[feature1,feature2] @ <REFERENCE> ; python_version < "3.7"
Note that the space before the semicolon is required.