Skip to content

Extend dependency specifier syntax to allow specifying multiple allowed version intervals for the same package #18079

@codethief

Description

@codethief

Summary

Some packages like protobuf maintain several major versions at the same time. So when my project uses protobuf and needs to constrain its version (e.g. because a certain bug fix is only available in the version intervals >=3.27,<4, >=4.30,<5, >=5.27,<6, >=6.30,<7), it would be great if this could be done for each major version separately, so that downstream projects can still choose the major version of protobuf somewhat freely. It should also be possible to combine this with the python_version constraint. In other words, I want to be able to specify something like:

If python_version >= 3.14, use protobuf version >=3.27,<4 OR >=4.30,<5 OR >=5.27,<6 OR >=6.30,<7.

Real-life inspiration: pulumi/pulumi#21828 (comment)

Example

I'm not entirely sure about the syntax yet and am likely not fully aware of all constraints (pun intended). What I'm suggesting basically amounts to introducing a logical OR operator to combine multiple version specifiers in a single dependency specifier. Here is one suggestion for the syntax, using or as logical delimiter:

[project]
dependencies = [
  'protobuf>=3.20.3,<7; python_version < "3.14"',
  'protobuf>=3.27,<4 or >=4.30,<5 or >=5.27,<6 or >=6.30,<7; python_version >= "3.14"',
]

(and similarly for other places where package versions are specified, e.g. project.optional-dependencies, development dependencies / dependency groups, tool.uv.constraint-dependencies, tool.uv.override-dependencies etc.)

Notes regarding the different delimiters:

  • According to the version specifier spec, the comma , in something like protobuf>=3.27,<4 should be interpreted as logical AND.
  • The semicolon ; in a dependency specifier like protobuf>=3.27,<4; python_version >= "3.14" might also seem to act as a logical AND. However, python_version is actually a special environment marker and probably closer in spirit to an if.
  • and and or can already be used to combine environment markers, so the above suggestion to use or would be consistent with that.

EDIT: Originally, I was mostly thinking about allowing logical ORs in tool.uv.constraint-dependencies and tool.uv.override-dependencies, the syntax of which uv could probably extend quite easily. For project.dependencies and project.optional-dependencies, however, I realize one would probably need to augment the pyproject.toml specification for compatibility across package managers. So maybe this is the wrong forum to discuss this. (OTOH given how popular uv is, the uv devs could probably steer such a discussion more easily than others.) Either way, I'm leaving the ticket open if only to document for others that specifying multiple version intervals is currently not supported – something which took me quite a bit of time to find out.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or improvement to existing functionality

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions