poetry-plugin-export icon indicating copy to clipboard operation
poetry-plugin-export copied to clipboard

`poetry export --format requirements.txt …` export a commit hash of an installed repository instead of the initial used tag reference.

Open guillaumededrie opened this issue 1 year ago • 13 comments
trafficstars

Poetry is used to build a package that will be installed in a Docker image:

# Build
$ poetry build --format wheel
$ poetry export --format requirements.txt --output constraints.txt --without-hashes

# Export the .whl and constraints.txt file (multi-stage build)

# Install
$ pip install --no-cache-dir ./$APP_NAME*.whl --constraint constraints.txt

As of today, it was working well. But we've added a new package using this (as an example) poetry add git+https://github.com/me/new-package#1.6.0 (new-package = {git = "https://github.com/me/new-package", rev = "1.6.0"} is present in the [tool.poetry.dependencies] of the pyproject.toml) and when we tried to install the generated wheel by Poetry using an exported requirements.txt, we ended up with this error:

The conflict is caused by:
    my-app 1.0.0 depends on new-package 1.6.0 (from git+https://github.com/me/[email protected])
    The user requested (constraint) new-package
To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict
ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts

If we take a look at the constraints.txt file, we can see that line: new-package @ git+https://github.com/me/new-package@c3e22d63f50256f588bd1438eedcd761a1507a43 ; python_version >= "3.11" and python_version < "4.0", which doesn't match the initial git+https://github.com/me/[email protected].

Workarounds

If we replace this line by new-package @ git+https://github.com/me/[email protected] the problem disappear.

guillaumededrie avatar Apr 03 '24 15:04 guillaumededrie

you have exported requirements.txt and are trying to use that as constraints. if you wanted constraints you should have exported with the constraints.txt format

(though I don't know whether that will make a difference here)

but probably you can just treat it as requirements.txt all along pip install --no-deps -r requirements.txt

dimbleby avatar Apr 03 '24 15:04 dimbleby

@dimbleby thanks for the --format constraints.txt tip, didn't see the option. Unfortunently, the results is the same (== the commit hash is used instead of the tag version).

What you are suggesting is installing first the dependencies and not combining it with the package installation?

guillaumededrie avatar Apr 04 '24 08:04 guillaumededrie

if everything is working then requirements.txt contains all dependencies, there is no need to ask pip to rediscover them (and risk that it disagrees)

fwiw I find it hard to call the exported requirements.txt wrong. Locking to an exact sha is the most reliable way of, well, locking.

I doubt that you will get much traction but imo it would be logical to call this a pip bug for failing to recognise that the tag and the sha represent the same thing.

dimbleby avatar Apr 04 '24 09:04 dimbleby

This is also a problem for me. My requirements.txt does not contain all dependencies, I cannot use the --no-deps option. I agree that locking the exact hashes of packages is the most reliable way to pin versions, however, it does break pip installation. Is it possible to add some simple flag to the export requirements without hashes?

rusmux avatar Apr 17 '24 04:04 rusmux

My requirements.txt does not contain all dependencies, I cannot use the --no-deps option

Yes it does - that's what poetry export does - and yes you can.

dimbleby avatar Apr 17 '24 07:04 dimbleby

I am having the same issue where poetry export uses the commit sha instead of the pinned version from the pyproject.toml.

When I try to install using the requirements.txt it finds conflicts:

The user requested package1 1.0.0 (from git+https://****@github.com/org/package1@9827ewfeef2734hf4ufh44fdfdf) package2 1.0.0 depends on package1 1.0.0 (from git+https://github.com/org/[email protected])

This commit and this version are identical. I understand this is probably a pip issue - but is there any way to enforce the poetry export to use the pinned version instead of the commit hash?

resthomas avatar Jul 08 '24 12:07 resthomas

the answer is still --no-deps

dimbleby avatar Jul 08 '24 12:07 dimbleby

the answer is still --no-deps

This works locally - however I am deploying python applications to Azure app services and functions which run pip install as part of their deployment pipeline. Ideally if my requirements.txt contained the pinned versions from the pyproject.toml it would resolve this

resthomas avatar Jul 08 '24 13:07 resthomas

add --no-deps to the top of the exported file?

if that works out for you maybe submit a pull request here to do that always

dimbleby avatar Jul 08 '24 13:07 dimbleby

add --no-deps to the top of the exported file?

if that works out for you maybe submit a pull request here to do that always

Good suggestion, but it seems like this is currently impossible using pip: https://github.com/pypa/pip/pull/10837

There is ongoing discussion on whether --no-deps will be added as a supported command to requirements.txt files

resthomas avatar Jul 08 '24 15:07 resthomas