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:

dependencies = [
  "click>=7, <9, != 8.0.0",

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 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
  • posix
  • java
sys_platform import sys
  • linux
  • win32
  • darwin
platform_machine import platform
  • x86_64
platform_python_implementation import platform
  • CPython
  • Jython
platform_release import platform
  • 1.8.0_51
  • 3.14.1-x86_64-linode39
platform_system import platform
  • Linux
  • Windows
  • Darwin
platform_version import platform
  • 10.0.19041
  • #1 SMP Fri Apr 2 22:23:49 UTC 2021
python_version import platform
  • 2.7
  • 3.10
python_full_version import platform
  • 2.7.18
  • 3.11.0b1
implementation_name import sys
  • cpython
implementation_version See here
  • 2.7.18
  • 3.11.0b1


You can select groups of optional dependencies to install using the extras syntax. For example, if a dependency named foo defined the following:

crypto = [
fastjson = [
cli = [
  "colorama; platform_system == 'Windows'",

You can select the cli and crypto features like so:


Note that the features come immediately after the package name, before any version specifiers.


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:

name = "awesome-project"

crypto = [
dev = [

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:


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:


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


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


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


You can install source archives and wheels by simply referring to a URL:

black @
pytorch @

An expected hash value may be specified by appending a #<HASH_ALGORITHM>=<EXPECTED_HASH> component:

requests @

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.