Manage project#
PDM can act as a PEP 517 build backend, to enable that, write the following lines in your
pyproject.toml
. If you used pdm init
to create it for you, it should be done already.
1 2 3 |
|
pip
will read the backend settings to install or build a package.
Choose a Python interpreter#
If you have used pdm init
, you must have already seen how PDM detects and selects the Python
interpreter. After initialized, you can also change the settings by pdm use <python_version_or_path>
.
The argument can be either a version specifier of any length, or a relative or absolute path to the
python interpreter, but remember the Python interpreter must conform with the python_requires
constraint in the project file.
How requires-python
controls the project#
PDM respects the value of requires-python
in the way that it tries to pick package candidates that can work
on all python versions that requires-python
contains. For example, if requires-python
is >=2.7
, PDM will try
to find the latest version of foo
, whose requires-python
version range is a superset of >=2.7
.
So, make sure you write requires-python
properly if you don't want any outdated packages to be locked.
Build distribution artifacts#
1 2 3 4 5 |
|
The artifacts can then be uploaded to PyPI by twine or using the
pdm-publish plugin. Available options can be found by
typing pdm build --help
.
Show the current Python environment#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Configure the project#
PDM's config
command works just like git config
, except that --list
isn't needed to
show configurations.
Show the current configurations:
1 |
|
Get one single configuration:
1 |
|
Change a configuration value and store in home configuration:
1 |
|
By default, the configuration are changed globally, if you want to make the config seen by this project only, add a --local
flag:
1 |
|
Any local configurations will be stored in .pdm.toml
under the project root directory.
The configuration files are searched in the following order:
<PROJECT_ROOT>/.pdm.toml
- The project configuration~/.pdm/config.toml
- The home configuration
If -g/--global
option is used, the first item will be replaced by ~/.pdm/global-project/.pdm.toml
.
You can find all available configuration items in Configuration Page.
Cache the installation of wheels#
If a package is required by many projects on the system, each project has to keep its own copy. This may become a waste of disk space especially for data science and machine learning libraries.
PDM supports caching the installations of the same wheel by installing it into a centralized package repository and linking to that installation in different projects. To enabled it, run:
1 |
|
It can be enabled on a project basis, by adding --local
option to the command.
The caches are located under $(pdm config cache_dir)/packages
. One can view the cache usage by pdm cache info
. But be noted the cached installations are managed automatically -- They get deleted when not linked from any projects. Manually deleting the caches from the disk may break some projects on the system.
Note
Only the installation of named requirements resolved from PyPI can be cached.
Manage global project#
Sometimes users may want to keep track of the dependencies of global Python interpreter as well.
It is easy to do so with PDM, via -g/--global
option which is supported by most subcommands.
If the option is passed, ~/.pdm/global-project
will be used as the project directory, which is
almost the same as normal project except that pyproject.toml
will be created automatically for you
and it doesn't support build features. The idea is taken from Haskell's stack.
However, unlike stack
, by default, PDM won't use global project automatically if a local project is not found.
Users should pass -g/--global
explicitly to activate it, since it is not very pleasing if packages go to a wrong place.
But PDM also leave the decision to users, just set the config auto_global
to true
.
If you want global project to track another project file other than ~/.pdm/global-project
, you can provide the
project path via -p/--project <path>
option.
CAUTION
Be careful with remove
and sync --clean
commands when global project is used, because it may remove packages installed in your system Python.
Working with a virtualenv#
Although PDM enforces PEP 582 by default, it also allows users to install packages into the virtualenv. It is controlled
by the configuration item use_venv
. When it is set to True
, PDM will use the virtualenv if:
- a virtualenv is already activated.
- any of
venv
,.venv
,env
is a valid virtualenv folder.
Besides, when use-venv
is on and the interpreter path given is a venv-like path, PDM will reuse that venv directory as well.
For enhanced virtualenv support such as virtualenv management and auto-creation, please go for pdm-venv, which can be installed as a plugin.
Import project metadata from existing project files#
If you are already other package manager tools like Pipenv or Poetry, it is easy to migrate to PDM.
PDM provides import
command so that you don't have to initialize the project manually, it now supports:
- Pipenv's
Pipfile
- Poetry's section in
pyproject.toml
- Flit's section in
pyproject.toml
requirements.txt
format used by Pip
Also, when you are executing pdm init
or pdm install
, PDM can auto-detect possible files to import
if your PDM project has not been initialized yet.
Export locked packages to alternative formats#
You can also export pdm.lock
to other formats, to ease the CI flow or image building process. Currently,
only requirements.txt
and setup.py
format is supported:
1 2 |
|
Hide the credentials from pyproject.toml#
There are many times when we need to use sensitive information, such as login credentials for the PyPI server
and username passwords for VCS repositories. We do not want to expose this information in pyproject.toml
and upload it to git.
PDM provides several methods to achieve this:
- User can give the auth information with environment variables which are encoded in the URL directly:
1 2 3 4 5 6 7 8 9 |
|
Environment variables must be encoded in the form ${ENV_NAME}
, other forms are not supported. Besides, only auth part will be expanded.
-
If the credentials are not provided in the URL and a 401 response is received from the server, PDM will prompt for username and password when
-v/--verbose
is passed as command line argument, otherwise PDM will fail with an error telling users what happens. Users can then choose to store the credentials in the keyring after a confirmation question. -
A VCS repository applies the first method only, and an index server applies both methods.
Run Scripts in Isolated Environment#
With PDM, you can run arbitrary scripts or commands with local packages loaded:
1 |
|
PDM also supports custom script shortcuts in the optional [tool.pdm.scripts]
section of pyproject.toml
.
You can then run pdm run <shortcut_name>
to invoke the script in the context of your PDM project. For example:
1 2 |
|
And then in your terminal:
1 2 |
|
Any extra arguments will be appended to the command:
1 2 |
|
PDM supports 3 types of scripts:
Normal command#
Plain text scripts are regarded as normal command, or you can explicitly specify it:
1 2 |
|
In some cases, such as when wanting to add comments between parameters, it might be more convenient to specify the command as an array instead of a string:
1 2 3 4 5 6 7 |
|
Shell script#
Shell scripts can be used to run more shell-specific tasks, such as pipeline and output redirecting.
This is basically run via subprocess.Popen()
with shell=True
:
1 2 |
|
Call a Python function#
The script can be also defined as calling a python function in the form <module_name>:<func_name>
:
1 2 |
|
The function can be supplied with literal arguments:
1 2 |
|
Environment variables support#
All environment variables set in the current shell can be seen by pdm run
and will be expanded when executed.
Besides, you can also define some fixed environment variables in your pyproject.toml
:
1 2 3 |
|
Note how we use TOML's syntax to define a compound dictionary.
A dotenv file is also supported via env_file = "<file_path>"
setting.
For environment variables and/or dotenv file shared by all scripts, you can define env
and env_file
settings under a special key named _
of tool.pdm.scripts
table:
1 2 3 4 |
|
Besides, PDM also injects the root path of the project via PDM_PROJECT_ROOT
environment variable.
Load site-packages in the running environment#
To make sure the running environment is properly isolated from the outer Python interpreter,
site-packages from the selected interpreter WON'T be loaded into sys.path
, unless any of the following conditions holds:
- The executable is from
PATH
but not inside the__pypackages__
folder. -s/--site-packages
flag is followingpdm run
.site_packages = true
is in either the script table or the global setting key_
.
Note that site-packages will always be loaded if running with PEP 582 enabled(without the pdm run
prefix).
Show the list of scripts shortcuts#
Use pdm run --list/-l
to show the list of available script shortcuts:
1 2 3 4 5 6 |
|
You can add an help
option with the description of the script, and it will be displayed in the Description
column in the above output.
Manage caches#
PDM provides a convenient command group to manage the cache, there are four kinds of caches:
wheels/
stores the built results of non-wheel distributions and files.http/
stores the HTTP response content.metadata/
stores package metadata retrieved by the resolver.hashes/
stores the file hashes fetched from the package index or calculated locally.packages/
The centrialized repository for installed wheels.
See the current cache usage by typing pdm cache info
. Besides, you can use add
, remove
and list
subcommands to manage the cache content.
Find the usage by the --help
option of each command.
How we make PEP 582 packages available to the Python interpreter#
Thanks to the site packages loading on Python startup. It is possible to patch the sys.path
by executing the sitecustomize.py
shipped with PDM. The interpreter can search the directories
for the nearest __pypackage__
folder and append it to the sys.path
variable.