Skip to content

Allow specifying lockfile targets within pyproject.toml #3188

@sneakers-the-rat

Description

@sneakers-the-rat

Is your feature/enhancement proposal related to a problem? Please describe.

I am starting to work on a project that will need some reasonably different deps across platforms (OS as well as CPU architecture) and python versions, and I would like to be able to offer a lockfile for each of them.

Separately, the current default behavior for a package without need for multiple architectures, but support for a range of python versions, (edit:) will pin a version compatible with the full range of python versions specified (if i'm reading the docs right, the cli output seems to suggest for python>=3.9,<4.0 it's targeting ~=3.9), which is a good default, but it would be nice to use the most recent package version for each python version.

I love the support for specifying lock targets (super refreshing after dealing with poetry): https://pdm-project.org/en/latest/usage/lock-targets/
as well as the ability to generate separate lockfiles as well as combine them into a single lockfile.

I could make a pre-commit/CI action to regenerate the lockfile that iterates through the intended lockfile targets, but it would be nice to be able to configure that declaratively in the pyproject.toml, both for ease of use and documentation, but also because i figure it is probably possible to make combined, multi-target locking more efficient than doing each separately.

Describe the solution you'd like

I think some syntax like this would be nice (that is basically just a config file version of the CLI args

[tool.pdm.lock]
## --------------
## `python` - Specify python versions to lock for

# the minimum python version specified in `requires-python`
python = 'minimum'

# the maximum ''
python = 'maximum'

# each minor version (3.8.*, 3.9.*) in `requires-python`
python = 'minor'

# specific python versions
python = [
  '3.9', # ~=3.9 
  '3.10.8', # ==3.10.8
  '>=3.8,<3.10' # not sure when this would be good, but...
  # ...
]

## --------------
## `platform` - Specify platforms to lock for
platform = [
  'linux',
  'manylinux_2_17_x86_64',
  # ...
]

## --------------
## `implementation` - Specify implementations to lock for
implementation = [
  'cpython', 
  'pypy',
  'pyston'
]


## --------------
## `implementation` - Specify implementations to lock for
# default, use single lockfile for all configured targets
lockfile = 'pdm.lock'

# use a pattern to generate multiple lockfiles
# e.g. unique for each target
lockfile = 'pdm-{python}-{platform}-{implementation}.lock'
# e.g. combine platforms and implementations by omitting it and causing a collision
lockfile = 'pdm-{python}.lock'

## --------------
## `target` - OR set explicit combinations (mutually exclusive with above options)
target = [
  {python="3.8", platform="linux", lockfile="pdm-38-linux.lock"},
  {python="3.9", platform="windows", lockfile="pdm-39-windows.lock"},
  # ...
]

Where if the top config variables (non-target) are used, then the values for target are calculated as product(python, platform, implementation), or the target can be set explicitly if greater control over the combination is needed.


I'd be happy to draft this PR if the maintainers are interested in this, but wanted to check first. No problem is not. obvi flexible on the syntax :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    ⭐ enhancementImprovements for existing features💨 sprintSpecial label for PyCon sprint

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions