Skip to content

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
  • posix
  • java
sys_platform import sys
sys.platform
  • linux
  • win32
  • darwin
platform_machine import platform
platform.machine()
  • x86_64
platform_python_implementation import platform
platform.python_implementation()
  • CPython
  • Jython
platform_release import platform
platform.release()
  • 1.8.0_51
  • 3.14.1-x86_64-linode39
platform_system import platform
platform.system()
  • Linux
  • Windows
  • Darwin
platform_version import platform
platform.version()
  • 10.0.19041
  • #1 SMP Fri Apr 2 22:23:49 UTC 2021
python_version import platform
'.'.join(platform.python_version_tuple()[:2])
  • 2.7
  • 3.10
python_full_version import platform
platform.python_version()
  • 2.7.18
  • 3.11.0b1
implementation_name import sys
sys.implementation.name
  • cpython
implementation_version See here
  • 2.7.18
  • 3.11.0b1

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
  • git+file
  • git+https
  • git+ssh
  • git+http ⚠
  • git+git ⚠
  • git ⚠
  • Commit hash
  • Tag name
  • Branch name
proj @ git+https://github.com/org/proj.git@v1
Executable Schemes Revisions Example
hg
  • hg+file
  • hg+https
  • hg+ssh
  • hg+http ⚠
  • hg+static-http ⚠
  • Revision hash
  • Revision number
  • Tag name
  • Branch name
proj @ hg+file:///path/to/proj@v1
Executable Schemes Revisions Example
svn
  • svn+https
  • svn+ssh
  • svn+http ⚠
  • svn+svn ⚠
  • svn ⚠
  • Revision number
proj @ svn+file:///path/to/proj
Executable Schemes Revisions Example
bzr
  • bzr+https
  • bzr+ssh
  • bzr+sftp
  • bzr+lp
  • bzr+http ⚠
  • bzr+ftp ⚠
  • Revision number
  • Tag name
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: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.