Search code examples
python-packagingpython-poetry

Poetry: How to publish project packages targeting multiple Python versions?


I have one project I'd like to publish as packages targeting two Python versions (3.6 and 3.8).

What I understand:

  • How to install and activate different python versions using pyenv.
  • How to get poetry to create virtual environments that correspond to the chosen Python version.
  • How to setup pyproject.toml to specify the python version, manage dependencies, and publish a package using this configuration.

What I do not understand: how can I publish the same package for more than one Python version? I can't be the only one with this use-case right?

  • Does need two pyproject.toml files? (one for each python version and set of corresponding dependencies...)
  • Are there established ways of doing this with Poetry, or are other tools/workflows necessary?

Edit

Doing a bit more digging, I found this https://python-poetry.org/docs/dependency-specification/#multiple-constraints-dependencies which looks like it might be relevant.

Here's the example at the link above.

[tool.poetry.dependencies]
foo = [
    {version = "<=1.9", python = "^2.7"},
    {version = "^2.0", python = "^3.4"}
]

I've also found you can specify the Python version using poetry add like this...

poetry add cleo --python 3.6.10

Which adds dependencies in pyproject.toml like this...

cleo = {version = "^0.8.1", python = "3.6.10"}

Going to experiment and see if this works.


Solution

  • No. You don't need to create multiple pyproject.toml files or otherwise create separate workflows for each Python version you're targeting (for this specific situation targeting similar versions at least).

    You can simply use dependency syntax to say you want to target >=3.6<4.0 like this...

    [tool.poetry.dependencies]
    python = '^3.6'
    

    And then add dependencies similarly...

    poetry add <dependency> python ^3.6
    

    Which results in something like this...

    [tool.poetry.dependencies]
    python = '^3.6'
    cleo = {version = "^0.8.1", python = "^3.6"}
    pyyaml = {version = "^5.4.1", python = "^3.6"}
    ...
    

    This worked, though I further went and made some of dependencies less specific to avoid incompatibilities on certain hosts.

    pyyaml = {version = "^5.0", python = "^3.6"}
    ...