poetry: Cannot install Apache Airflow due to ambiguous constraint
- Poetry version: Poetry (version 1.2.2)
- Python version: Python: 3.10.8
- OS version and name: MacOS 13.0.1
- pyproject.toml:
[tool.poetry.dependencies]
python = "^3.10"
apache-airflow-providers-google = { version = "==8.5.0rc1", allow-prereleases = true }
- I am on the latest stable Poetry version, installed using a recommended method.
- I have searched the issues of this repo and believe that this is not a duplicate.
- https://github.com/python-poetry/poetry/issues/6774 looks related but is a different error as that is installing incorrect packages
- I have consulted the FAQ and blog for any relevant entries or release notes.
- If an exception occurs when executing a command, I executed it again in debug mode (
-vvv
option) and have included the output below.
Issue
I am unable to run poetry lock
with the above dependency.
Expected
Poetry locks correctly using apache-airflow-providers-common-sql==1.3.0rc1
Actual
Poetry returns the following error
poetry lock
Updating dependencies
Resolving dependencies... (1.5s)
Because apache-airflow-providers-google (8.5.0rc1) depends on apache-airflow-providers-common-sql (>=1.3.0) which doesn't match any versions, apache-airflow-providers-google is forbidden.
So, because poetry depends on apache-airflow-providers-google (==8.5.0rc1), version solving failed.
It looks like poetry has the following bug
Poetry is not supported to install airflow, and it has apparently a bug that it cannot properly handle the vaild >= .* requirement.
Note: the reproducibility of this example will stop once airflow publishes the final release of apache-airflow-providers-common-sql==1.3.0
Verifying that pypi has the expected requirement
API response
import json
import requests
package_name = 'apache-airflow-providers-google/8.5.0rc1'
url = 'https://pypi.python.org/pypi/' + str(package_name) + '/json'
data = requests.get(url).json()
print(data['info']['requires_dist'])
for apache-airflow-provider-common-sql returns the following
apache-airflow-providers-common-sql (>=1.3.0.*)
Further Notes
pipenv & pip run without issue
Pipenv
Pipfile
[packages]
apache-airflow-providers-google = { version = "==8.5.0rc1", pre="true" }
CLI
mkdir test-pipenv && cd test-pipenv
pip install pipenv
pipenv lock
nano pipfile
pipenv lock
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Locking [dev-packages] dependencies...
Updated Pipfile.lock (43302be42e771518e472473549c7ab11902fd6f2e7eed04c64ffcd2d5f9be4e8)!
Locked Packages
...
"apache-airflow-providers-common-sql": {
"hashes": [
"sha256:9308d3ac4d1f888f1a1f91c18cfa493291e333635cf0a0f93565581a83b1f097",
"sha256:f5eb101f15a3535f879509873992d7194ef3e2a48316c984a0fc2a3a3af9001e"
],
"markers": "python_version ~= '3.7'",
"version": "==1.3.0rc1"
},
"apache-airflow-providers-google": {
"hashes": [
"sha256:a6d94a647c4dca9b2b75b4bf98c20c3809eb4ff8ccf4e7219f19df8fec3ea0de",
"sha256:db9105714472b9cf344b55a72172dd87d85b7de5c8c5755bd86007c23d3ec3cf"
],
"index": "pypi",
"version": "==8.5.0rc1"
},
...
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 38 (13 by maintainers)
Commits related to this issue
- Fix suffix for pre-release cross-dependent packages We used .* as suffix for dependent pre-release packages but it turned out to be misunderstanding of the dependencies and PEP440. According to PEP4... — committed to potiuk/airflow by potiuk 2 years ago
- Fix suffix for pre-release cross-dependent packages (#27727) We used .* as suffix for dependent pre-release packages but it turned out to be misunderstanding of the dependencies and PEP440. Accor... — committed to apache/airflow by potiuk 2 years ago
- apache 2.5.1 -> affirm 2.5.1 (#29) * Handle transient state errors in `RedshiftResumeClusterOperator` and `RedshiftPauseClusterOperator` (#27276) * Modify RedshiftPauseClusterOperator and Redshift... — committed to Affirm/airflow by deleted user a year ago
- Fix suffix for pre-release cross-dependent packages (#27727) We used .* as suffix for dependent pre-release packages but it turned out to be misunderstanding of the dependencies and PEP440. Accordin... — committed to GoogleCloudPlatform/composer-airflow by potiuk 2 years ago
- Fix suffix for pre-release cross-dependent packages (#27727) We used .* as suffix for dependent pre-release packages but it turned out to be misunderstanding of the dependencies and PEP440. Accordin... — committed to GoogleCloudPlatform/composer-airflow by potiuk 2 years ago
When you talk about poetry “supporting constraints” - I think you mean: things that are like requirements eg “foo>=1.2”, but which don’t actually require the named package to be installed?
presumably the use case for such things would be for transitive dependencies where you don’t want to specify an explicit dependency, but if the solver does encounter that package then you want to guide it towards (or away from) some particular version?
I’ve seen requests for similar, but don’t recall anything spelling out this particular approach.
Feel free to raise a feature request where folk can figure out whether this is a good idea, or a duplicate, or neither, or both.
Fix for airflow provider packages in https://github.com/apache/airflow/pull/27727
Just noting that indeed poetry does make a mess of prefix matching on
==
constraints: this codesays
allowed=False
which certainly disagrees with one of the examples in PEP440.So while - at least according to my reading - the problem in this particular issue is the airflow constraint rather than the poetry handling of it, we’re certainly very adjacent to a poetry bug
A new one would be lovely, thanks
Yep. That’s what I have in my PR.
https://peps.python.org/pep-0440/#summary-of-permitted-suffixes-and-relative-ordering
this is not true. Their order is well defined by PEP440 and a regular
>=
starting at the earliest should meet your need.I think
==1.3.0.*
achieves what you want per PEP 440 (though I suspect that poetry will make a mess of that). Also>=1.3.0rc1
should work (and I think poetry will get that right).So far as I can tell PEP 440 simply doesn’t allow
>=1.3.0.*
and so it’s presumably more or less arbitrary whether pip or poetry happens to do what you want@potiuk I don’t see any justification for
>=1.3.0.*
in https://peps.python.org/pep-0440/#inclusive-ordered-comparison.==1.3.0.*
would be allowed per the previous section (and quite possibly mis-handled by poetry) but the>=
operator requires an actual version identifier - which1.3.0.*
is not.@r-richmond that still requires that “the available version satisfies the version specifier”. poetry has done its best with the malformed version specifier, interpreting it as
>=1.3.0
, but no available version does satisfy that.I’m at risk of being out of my depth here but the following statement
Appears to be at odds with the spec defined in pep 440 Specifically the last portion of this sentence
Further Details
From the following section (Bullet 2)
By default, dependency resolution tools SHOULD:
From the spec on Request Options
Dependency resolution tools SHOULD also allow users to request the following alternative behaviours:
I believe this is what the intent of poetry’s allow-prereleases is as well. so even if poetry wanted to break the implied behavior above shouldn’t my usage of that flag in pyproject.toml have allowed the pre-release.
not a bug, because the requirement is
>=1.3.0
and the highest available version is1.3.0rc1
- which is strictly less than1.3.0
(possibly also duplicate #4405, though I’ve not read the whole of that issue)