Skip to content

PEP 621 Project metadata#

PDM reads the project's metadata following the standardized format of PEP 621. View the PEP for the detailed specification. These metadata are stored in [project] table of pyproject.toml.

In the following part of this document, metadata should be written under [project] table if not given explicitly.

Multiline description#

You can split a long description onto multiple lines, thanks to TOML support for multiline strings. Just remember to escape new lines, so the final description appears on one line only in your package metadata. Indentation will be removed as well when escaping new lines:

1
2
3
4
5
6
description = """\
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
    Ut enim ad minim veniam, quis nostrud exercitation ullamco \
    laboris nisi ut aliquip ex ea commodo consequat.\
"""

See TOML's specification on strings.

Determine the package version dynamically#

The package version can be retrieved from the __version__ variable of a given file. To do this, put the following under the [tool.pdm] table:

1
2
[tool.pdm]
version = {from = "mypackage/__init__.py"}

Remember set dynamic = ["version"] in [project] metadata.

PDM can also read version from SCM tags. If you are using git or hg as the version control system, define the version as follows:

1
2
[tool.pdm]
version = {use_scm = true}

In either case, you MUST delete the version field from the [project] table, and include version in the dynamic field, or the backend will raise an error:

1
dynamic = ["version"]

Dependency specification#

The project.dependencies is an array of dependency specification strings following the PEP 440 and PEP 508.

Examples:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
dependencies = [
    # Named requirement
    "requests",
    # Named requirement with version specifier
    "flask >= 1.1.0",
    # Requirement with environment marker
    "pywin32; sys_platform == 'win32'",
    # URL requirement
    "pip @ https://github.com/pypa/pip.git@20.3.1"
]

Editable requirement#

Beside of the normal dependency specifications, one can also have some packages installed in editable mode. The editable specification string format is the same as Pip's editable install mode.

Examples:

1
2
3
4
5
dependencies = [
    ...,
    "-e path/to/SomeProject",
    "-e git+http://repo/my_project.git#egg=SomeProject"
]

About editable installation

One can have editable installation and normal installation for the same package. The one that comes at last wins. However, editable dependencies WON'T be included in the metadata of the built artifacts since they are not valid PEP 508 strings. They only exist for development purpose.

Optional dependencies#

You can have some requirements optional, which is similar to setuptools' extras_require parameter.

1
2
3
4
5
6
7
[project.optional-dependencies]
socks = [ 'PySocks >= 1.5.6, != 1.5.7, < 2' ]
tests = [
  'ddt >= 1.2.2, < 2',
  'pytest < 6',
  'mock >= 1.0.1, < 4; python_version < "3.4"',
]

To install a group of optional dependencies:

1
pdm install -G socks

-G option can be given multiple times to include more than one group.

Console scripts#

The following content:

1
2
[project.scripts]
mycli = "mycli.__main__:main"

will be translated to setuptools style:

1
2
3
4
5
entry_points = {
    'console_scripts': [
        'mycli=mycli.__main__:main'
    ]
}

Also, [project.gui-scripts] will be translated to gui_scripts entry points group in setuptools style.

Entry points#

Other types of entry points are given by [project.entry-points.<type>] section, with the same format of [project.scripts]:

1
2
[project.entry-points.pytest11]
myplugin = "mypackage.plugin:pytest_plugin"