Open matt-carr opened 1 year ago
sounds reasonable. @frenzymadness wdyt? please re-label if needed
/kind bug
I have an implementation that should fix this but it causes another 14 tests to fail which might be okay but I'd like to verify my understanding of the problem first.
Let's use httpcore as an example. httpcore requires h2 for extras named http2.
If I have something like this in my pyproject.toml:
[tool.poetry.dependencies]
python = "^3.10"
httpcore = "^0.17.3"
[tool.poetry.group.dev.dependencies]
httpcore = {extras = ["http2"], version = "^0.17.3"}
The expected result of micropipenv requirements --method poetry --no-dev
is:
#
# Default dependencies
#
httpcore==0.17.3 \
--hash=sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87 \
--hash=sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888
because I want only dependencies from the main category and h2 is not there, there is no reason to add [http2].
But when I manually add h2 into the main dependencies so then I have:
[tool.poetry.dependencies]
python = "^3.10"
httpcore = "^0.17.3"
h2 = "*"
[tool.poetry.group.dev.dependencies]
httpcore = {extras = ["http2"], version = "^0.17.3"}
then the result of the same command is:
#
# Default dependencies
#
h2==4.1.0 \
--hash=sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d \
--hash=sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb
httpcore[http2]==0.17.3 \
--hash=sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87 \
--hash=sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888
The reason for this is that h2 and httpcore are now in the same category so the detection of extras thinks that h2 is there because httpcore has been requested with [http2] - this is not true in this case but causes no harm because httpcore
and httpcore[http2]
represent the same set of packages to be installed.
But there is another problem with this implementation - recursion. Let's say I have this part in poetry.lock:
[[package]]
name = "boto3"
version = "1.26.42"
description = "The AWS SDK for Python"
category = "main"
optional = false
python-versions = ">= 3.7"
files = [
{file = "boto3-1.26.42-py3-none-any.whl", hash = "sha256:75c995a04723f23e35e16ea491ed91a1345e2fa6492678a216488512308dada1"},
{file = "boto3-1.26.42.tar.gz", hash = "sha256:4cfd7e05e4033dbca2cc59bcfdafbdaef9d83dc3c0448917569b301d85766d9d"},
]
[package.dependencies]
botocore = ">=1.29.42,<1.30.0"
jmespath = ">=0.7.1,<2.0.0"
s3transfer = ">=0.6.0,<0.7.0"
[package.extras]
crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
[[package]]
name = "botocore"
version = "1.29.42"
description = "Low-level, data-driven core of boto 3."
category = "main"
optional = false
python-versions = ">= 3.7"
files = [
{file = "botocore-1.29.42-py3-none-any.whl", hash = "sha256:f52f9dbd7ad42b3528c1052086c1a7b6122a018f919afdb604f2889caefe8092"},
{file = "botocore-1.29.42.tar.gz", hash = "sha256:d05c62f64e76194c40f598f5f7c804ec50d9820e9f03f6e0198558e4ace167c4"},
]
[package.dependencies]
jmespath = ">=0.7.1,<2.0.0"
python-dateutil = ">=2.1,<3.0.0"
urllib3 = ">=1.25.4,<1.27"
[package.extras]
crt = ["awscrt (==0.15.3)"]
The question to answer is: Should we install boto3
or boto3[crt]
? To answer this, we have to check whether all the dependencies of boto3[crt] are present but that means checking presence of botocore[crt]
and that's another level. botocore is there but awscrt (dependency of crt extra of botocore) is not. What should happen in those cases?
Also, thanks to this reproducer, I've realized that we have another problem: dependency can only belong to one category and the main/default one has a higher priority for us which means that when we use this example and run micropipenv with --no-default
there is no fastapi in devel dependencies :disappointed:
Describe the bug When specifying
package
as a core dependency andpackage[extras]
as a dev dependency in pyproject.toml,micropipenv requirements --no-dev
renderspackage[extras]
.To Reproduce
poetry lock
micropipenv requirements --no-dev
Expected behavior The package, without extras, should be output
Additional context Related to assumptions around the extras resolver
https://github.com/thoth-station/micropipenv/blob/master/micropipenv.py#L838-L849
Because all the extras are present and the root dependency is flagged as a main dependency, the resolver adds the extras.
Especially with 1.5 and on I'm not sure how you'd solve this issue besides checking the pyproject.toml file. Pre-1.5 you could theoretically check to see if all the extra dependencies had a different category than the parent but that might be a little heavy and especially considering https://github.com/thoth-station/micropipenv/issues/249 this whole discussion could be moot anyways