Lock file#
PDM installs packages exclusively from the existing lock file named pdm.lock
. This file serves as the sole source of truth for installing dependencies. The lock file contains essential information such as:
- All packages and their versions
- The file names and hashes of the packages
- Optionally, the origin URLs to download the packages (See also: Static URLs)
- The dependencies and markers of each package (See also: Inherit the metadata from parents)
To create or overwrite the lock file, run pdm lock
, and it supports the same update strategies as pdm add
. In addition, the pdm install
and pdm add
commands will also automatically create the pdm.lock
file.
Should I add pdm.lock
to version control?
It depends. If your goal is to make CI use the same dependency versions as local development and avoid unexpected failures, you should add the pdm.lock
file to version control. Otherwise, if your project is a library and you want CI to mimic the installation on user site to ensure that the current version on PyPI doesn't break anything, then do not submit the pdm.lock
file.
Install the packages pinned in lock file#
There are a few similar commands to do this job with slight differences:
pdm sync
installs packages from the lock file.pdm update
will update the lock file, thenpdm sync
.pdm install
will check the project file for changes, update the lock file if needed, thenpdm sync
.
pdm sync
also has a few options to manage installed packages:
--clean
: will remove packages no longer in the lockfile--clean-unselected
(or--only-keep
): more thorough version of--clean
that will also remove packages not in the groups specified by the-G
,-d
, and--prod
options. Note: by default,pdm sync
selects all groups from the lockfile, so--clean-unselected
is identical to--clean
unless-G
,-d
, and--prod
are used.
Hashes in the lock file#
By default, pdm install
will check if the lock file matches the content of pyproject.toml
, this is done by storing a content hash of pyproject.toml
in the lock file.
To check if the hash in the lock file is up-to-date:
1 |
|
If you want to refresh the lock file without changing the dependencies, you can use the --refresh
option:
1 |
|
This command also refreshes all file hashes recorded in the lock file.
Specify another lock file to use#
By default, PDM uses pdm.lock
in the current directory. You can specify another lock file with the -L/--lockfile
option or the PDM_LOCKFILE
environment variable:
1 |
|
This command installs packages from my-lockfile.lock
instead of pdm.lock
.
Alternate lock files are helpful when there exist conflicting dependencies for different environments. In this case, if you lock them as a whole, PDM will raise an error. So you have to select a subset of dependency groups and lock them separately.
For a realistic example, your project depends on a release version of werkzeug
and you may want to work with a local in-development copy of it when developing. You can add the following to your pyproject.toml
:
1 2 3 4 5 6 |
|
Then, run pdm lock
with different options to generate lockfiles for different purposes:
1 2 3 4 5 6 |
|
Check the metadata.groups
field in the lockfile to see which groups are included.
Option to not write lock file#
Sometimes you want to add or update dependencies without updating the lock file, or you don't want to generate pdm.lock
, you can use the --frozen-lockfile
option:
1 |
|
In this case, the lock file, if existing, will become read-only, no write operation will be performed on it. However, dependency resolution step will still be performed if needed.
Lock strategies#
Currently, we support three flags to control the locking behavior: cross_platform
, static_urls
and direct_minimal_versions
, with the meanings as follows.
You can pass one or more flags to pdm lock
by --strategy/-S
option, either by giving a comma-separated list or by passing the option multiple times.
Both of these commands function in the same way:
1 2 |
|
The flags will be encoded in the lockfile and get read when you run pdm lock
next time. But you can disable flags by prefixing the flag name with no_
:
1 |
|
This command makes the lockfile not cross-platform.
Cross platform#
Added in version 2.6.0
Deprecated in 2.17.0
See Lock for specific platforms or Python versions for the new behavior.
By default, the generated lockfile is cross-platform, which means the current platform isn't taken into account when resolving the dependencies. The result lockfile will contain wheels and dependencies for all possible platforms and Python versions.
However, sometimes this will result in a wrong lockfile when a release doesn't contain all wheels.
To avoid this, you can tell PDM to create a lockfile that works for this platform only, trimming the wheels not relevant to the current platform.
This can be done by passing the --strategy no_cross_platform
option to pdm lock
:
1 |
|
Static URLs#
Added in version 2.8.0
By default, PDM only stores the filenames of the packages in the lockfile, which benefits the reusability across different package indexes.
However, if you want to store the static URLs of the packages in the lockfile, you can pass the --strategy static_urls
option to pdm lock
:
1 |
|
The settings will be saved and remembered for the same lockfile. You can also pass --strategy no_static_urls
to disable it.
Direct minimal versions#
Added in version 2.10.0
When it is enabled by passing --strategy direct_minimal_versions
, dependencies specified in the pyproject.toml
will be resolved to the minimal versions available, rather than the latest versions. This is useful when you want to test the compatibility of your project within a range of dependency versions.
For example, if you specified flask>=2.0
in the pyproject.toml
, flask
will be resolved to version 2.0.0
if there is no other compatibility issue.
Note
Version constraints in package dependencies are not future-proof. If you resolve the dependencies to the minimal versions, there will likely be backwards-compatibility issues.
For example, flask==2.0.0
requires werkzeug>=2.0
, but in fact, it can not work with Werkzeug 3.0.0
, which is released 2 years after it.
Inherit the metadata from parents#
Added in version 2.11.0
Previously, the pdm lock
command would record package metadata as it is. When installing, PDM would start from the top requirements and traverse down to the leaf node of the dependency tree. It would then evaluate any marker it encounters against the current environment. If a marker is not satisfied, the package would be discarded. In other words, we need an additional "resolution" step in installation.
When the inherit_metadata
strategy is enabled, PDM will inherit and merge environment markers from a package's ancestors. These markers are then encoded in the lockfile during locking, resulting in faster installations. This has been enabled by default from version 2.11.0
, to disable this strategy in the config, use pdm config strategy.inherit_metadata false
.
Exclude packages newer than specific date#
Added in version 2.13.0
You can exclude packages that are newer than a specified date by passing the --exclude-newer
option to pdm lock
. This is useful when you want to lock the dependencies to a specific date, for example, to ensure reproducibility of the build.
The date may be specified as a RFC 3339 timestamp (e.g., 2006-12-02T02:07:43Z
) or UTC date in the same format (e.g., 2006-12-02
).
1 |
|
Note
The package index must support the upload-time
field as specified in PEP 700. If the field is not present for a given distribution, the distribution will be treated as unavailable.
Set acceptable format for locking or installing#
If you want to control the format(binary/sdist) of the packages, you can set the env vars PDM_NO_BINARY
, PDM_ONLY_BINARY
and PDM_PREFER_BINARY
.
Each env var is a comma-separated list of package name. You can set it to :all:
to apply to all packages. For example:
1 2 3 4 5 6 7 8 |
|
You can also defined those values in your project pyproject.toml
with the no-binary
, only-binary
and prefer-binary
keys of the tool.pdm.resolution
section.
They accept the same format as the environment variables and also support lists.
1 2 3 4 5 6 7 8 9 |
|
Note
Each environment variable takes precedence over its pyproject.toml
alternative.
Allow prerelease versions to be installed#
Include the following setting in pyproject.toml
to enable:
1 2 |
|
Solve the locking failure#
If PDM is not able to find a resolution to satisfy the requirements, it will raise an error. For example,
1 2 3 4 5 6 7 |
|
You can either change to a lower version of django
or remove the upper bound of asgiref
. But if it is not eligible for your project, you can try overriding the resolved package versions or even don't lock that specific package in pyproject.toml
.
Export locked packages to alternative formats#
You can export the pdm.lock
file to other formats, which will simplify the CI flow or image building process. At present, only the requirements.txt
format is supported.
1 |
|
Tip
You can also run pdm export
with a .pre-commit
hook.