python-poetry / poetry

Python packaging and dependency management made easy
https://python-poetry.org
MIT License
31.13k stars 2.25k forks source link

Wildcard version constraint not functioning as expected #8418

Open ninjit opened 1 year ago

ninjit commented 1 year ago

Issue

I'm just getting started with poetry, but I think I'm misunderstanding how the wildcard version constraints are implemented.

I'm specifying a python version as python = "3.8.*" in the toml file, before I start using poetry to add packages such as poetry add psychopy, but get the following error

The current project's Python requirement (==3.8.*) is not compatible with some of the required packages Python requirement:
  - psychopy requires Python <3.11,>=3.8, so it will not be satisfied for Python >=3.8.dev0,<3.8

I was able to solve this by using python = "~3.8" or python = ">=3.8, <3.9" explicitly, but according to the wildcard documentation (linked above), 3.8.* and ~3.8 should have been equivalent

dimbleby commented 1 year ago

pep440 seems sadly self-contradictory about the meaning of wildcards, recommend just not using them

https://peps.python.org/pep-0440/#examples says

  • ~=3.1: version 3.1 or later, but not version 4.0 or later.
  • == 3.1.*: any version that starts with 3.1. Equivalent to the ~=3.1.0 compatible release clause.

but: 3.1.0.dev0 starts with 3.1 and is earlier than 3.1: so the things that pep440 says are equivalent are not equivalent

BeRT2me commented 11 months ago

There seems to be movement to clarify this in pep440 https://github.com/python/peps/commit/a703204b82a262985243dbe1994581860eb62f6f

the 1.1a1 in == 1.1.* is dependent on whether the user requested pre-releases or not

Although, I think it's clear that poetry is going against pep440 based on the Handling of pre-releases section:

Pre-releases of any kind, including developmental releases, are implicitly excluded from all version specifiers, unless they are already present on the system, explicitly requested by the user, or if the only available version that satisfies the version specifier is a pre-release.

By default, dependency resolution tools SHOULD:

  • accept already installed pre-releases for all version specifiers
  • accept remotely available pre-releases for version specifiers where there is no final or post release that satisfies the version specifier
  • exclude all other pre-releases from consideration

Dependency resolution tools MAY issue a warning if a pre-release is needed to satisfy a version specifier.

Dependency resolution tools SHOULD also allow users to request the following alternative behaviours:

  • accepting pre-releases for all version specifiers
  • excluding pre-releases for all version specifiers (reporting an error or warning if a pre-release is already installed locally, or if a pre-release is the only way to satisfy a particular specifier)

Dependency resolution tools MAY also allow the above behaviour to be controlled on a per-distribution basis.

~Emphasis added.

"3.8.*" should exclude pre-releases/development releases by default, unless the user specifies otherwise.

I believe this should be configurable like so: python = {version = "3.8.*", allow-prereleases = true} (false would be default), but Poetry has not implemented this.

shadycuz commented 9 months ago

I am also having some problems. I want my project to support Python from 3.9 to 3.12.x which has been very challenging to do with Poetry.

I first tried this: python = ">=3.9,<=3.12" which worked until Python 3.12.1. I then tried python = ">=3.9,<=3.12.*" but it does not work. I would rather not have to use 3.12.1 and then update it every time a new patch version is released.

dimbleby commented 9 months ago

">=3.9,<3.13" of course

shadycuz commented 9 months ago

">=3.9,<3.13" of course

I thought I was being clever and went with ">=3.9,<3.12.100" 🤣

kristang commented 15 hours ago

What is the actual, intended behavior from poetry?

Building the following specifications using Python 3.11.7 and poetry 1.7.1 works as expected.

[tool.poetry.dependencies]
python = ">=3.9, <3.13"

Will create a PKG-INFO with:

[...]
Requires-Python: >=3.9,<3.13
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
[...]
[tool.poetry.dependencies]
python = ">=3.9, <=3.12"

Will create a PKG-INFO with:

[...]
Requires-Python: >=3.9,<=3.12
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
[...]
[tool.poetry.dependencies]
python = ">=3.9, <=3.12.*"

Will create a PKG-INFO with:

[...]
Requires-Python: >=3.9,<=3.12
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
[...]

But if you build with Python 3.12.1 only ">=3.9, <3.13" can be built, while <=3.12 and <=3.12.* fails.

Is the answer to never use less-than-or-equal in upper bounded versions or awaiting the resolution of the PEP issues mentioned by @dimbleby and @BeRT2me?

dimbleby commented 15 hours ago

advice is unchanged, don't use wildcards

kristang commented 15 hours ago

and does that mean <=3.12 implies a wildcard patch-number i.e. 3.12.*, so the recommendation to specify 3.12 as allowed is to use <3.13?

dimbleby commented 15 hours ago

please read the thread, you are just reliving a conversation that has already happened