-
-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Poetry deps w/ python version and platform, and multiple constraints dependencies #592
Poetry deps w/ python version and platform, and multiple constraints dependencies #592
Conversation
|
||
# handle exact version specifiers correctly | ||
>>> encode_poetry_python_version_to_selector_item("3.8") | ||
"py==38" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pytest is running your doctests here as well, that is why it is failing on ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is interesting, I've fixed the examples output format. Thanks for having a look at it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you currently have or
where there should be and
, e.g. >=3.10.0,<3.11.0
--> py>=310 and py<311
.
# handle caret operator correctly | ||
>>> encode_poetry_python_version_to_selector_item("^3.10") | ||
# renders '>=3.10.0,<4.0.0' | ||
"py>=310 or py<4" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"py>=310 or py<4" | |
"py>=310 and py<4" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
# handle tilde operator correctly | ||
>>> encode_poetry_python_version_to_selector_item("~3.10") | ||
# renders '>=3.10.0,<3.11.0' | ||
"py>=310 or py<311" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"py>=310 or py<311" | |
"py>=310 and py<311" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
operator, version = parse_python_version(conda_clause) | ||
version_selector = version.replace(".", "") | ||
conda_selectors.append(f"py{operator}{version_selector}") | ||
selectors = " or ".join(conda_selectors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
selectors = " or ".join(conda_selectors) | |
selectors = " and ".join(conda_selectors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
I think it may eventually be important to support |
# Split into major, minor, and discard the rest (patch or additional parts) | ||
major, minor, *_ = version.split(".") | ||
|
||
# Return only major if minor is "0", otherwise return major.minor | ||
return operator, major if minor == "0" else f"{major}.{minor}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we probably need this to also support:
parse_python_version('>=3')
When I tried that, I see (as I expected I might):
File "/home/xylar/code/grayskull/poetry-deps-w-python-ver-platform-and-multiple-deps/./test.py", line 6, in <module>
print(parse_python_version('>=3'))
~~~~~~~~~~~~~~~~~~~~^^^^^^^
File "/home/xylar/code/grayskull/poetry-deps-w-python-ver-platform-and-multiple-deps/grayskull/strategy/parse_poetry_version.py", line 324, in parse_python_version
major, minor, *_ = version.split(".")
^^^^^^^^^^^^^^^^
ValueError: not enough values to unpack (expected at least 2, got 1)
Could you add a test for this situation and make the necessary changes to support a single digit as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added support for 1 digit and three dots case (e.g. 3.8.0.1
, never seen for Python version specifier but valid syntax). Thanks for checking that out!
@lorepirri, I should have said before diving into the details. I really appreciate this work a ton! The lack for support for these python selectors has been bothering me a lot for a long time, but I've felt a little overwhelmed when I looked into trying to fix them. This is some great work! Not surprisingly, there are still a few wrinkles to iron out. |
@xylar |
oh yeah... sorry about that! Nice catch. The I'm left wondering how Poetry will interpret |
Thank you for the nice words and the review for this PR @xylar . |
I don't believe that's valid. That would be |
I'm not either. Hopefully @marcelotrevisani can provide that expertise. |
Indeed, If one would want to express |
Added support for Multiple version specifiers are at the moment always rendered in If one would want to express
|
When there are any extras in a dependency requirement for I did not explore the reason yet. Shall it be the same for Poetry? Maybe this is another question @marcelotrevisani can help with. |
that is set to And thanks a lot for your contribution! I really appreciate it, I believe @xylar have done a good review and I am also happy with the current state of the PR, unless you want to improve a few bits more, but that can also be done in a second PR if you wish :) |
I imagine there could be some growing pains with this update. There are a lot of cases to consider and @lorepirri, you've done quite a good job of that. Even so, if there are some bugs that come up after we send this into the wild, I'm more than happy to help with them in the future. |
@lorepirri, it sounded like you wanted to tackle |
@xylar I've added "~=" and ".*" support it was a bit more effort than I thought mostly because ".*" expands to two selectors in "or". The PR starts to be a bit crowded, I would not add anything else here. There are a few changes to review, unfortunately.
Thanks for your support! I made the parser a little bit more robust and now it accepts a PEP440 version in the Python version even though I would not expect to ever receive
Thanks for having created As for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lorepirri, I'm very happy with the work you have done on the ~=
and .*
support. It's clear that some choices need to be made about how these get supported in a way that makes sense for python and I think the choices you've documented make a lot of sense. Hopefully, no one will be silly enough to use some of the weirder cases you added support for but it's nice to have some sensible fallback even if they do rather than just having grayskull crash.
PR description updated (removed the TODOs and
|
Thank you @xylar for having had a look at it once again! I'm glad that I could add some value to the project. I decided to simplify the cases for the In case there will be the need to fully expand
|
and expand only for: | ||
"~=3.8" -> ">=3.8, ==3.*" -> ">=3.8, <4.0a" -> "py>=38 and py<4" | ||
"~=3.0" -> ">=3.0, ==3.*" -> ">=3.0, <4.0a" -> "py>=3 and py<4" | ||
in the rest of the cases it's a simple conversion to ">=" operator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the rest of the cases it's a simple conversion to ">=" operator. | |
in the rest of the cases it's a simple conversion to ">="/"==" operator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks for your contribution!
Thank you for merging @marcelotrevisani . We could close #463 #535 and the PR #523 (it seems stale). |
Description
When reading Poetry dependencies from a
pyproject.toml
, Grayskull does not read the requirements ofpython
version andplatform
.Also, it does not support multiple constraints dependencies and it crashes (see #463 #535 and an open PR #523 by @xhochy ).
This PR aims to add some support for these two missing features.
As mentioned in the two issues, one could see
grayskull
crashing on:grayskull pypi databricks-sql-connector
grayskull pypi xypattern
grayskull pypi ersilia
grayskull pypi nannyml
(this one is still failing for a dependency that uses caret^
and nonsemver
standard version^0.8.post1
andgrayskull
crashes when trying to coerce it tosemver
for thefloor
. See [BUG] Crash for a Poetry dependency w/^
and a nonsemver
standard version #593 )Tests are added, including some basic regression tests for
databricks-sql-connector
,xypattern
,ersilia
, andnannyml
.Tagging also for visibility people active in the issues: @xylar @darynwhite @kcpevey @DhanshreeA @thewchan
Known limits
Platform
From Poetry dependencies documentation, the requirement
platform
seems to have only two valueslinux
anddarwin
, probablywindows
but not sure (respectively rendered aslinux
,osx
, andwin
selectors).It is unclear if one could use
platform = "!=darwin"
to express# [not osx]
.Python version
python
version is rendered naively and differently than forpypi.py
andpy_base.py
(I did not get the functiongeneric_py_ver_to
withpy2k
andpy3k
, because a lot going on in that function and I am not familiar with those selectors). If the version is>=3.10
this will simply result in a selectorpy>=310
.If this is not wanted or bloating the code, I am willing to re-use functions from
py_base.py
orpypi.py
with the right guidance (thanks).It does expand caret and tilde (e.g.
^3.10
->py>=310 and py<4
), and always removespatch
, and alsominor
if0
(e.g.3.11.1
->py==311
,3.12.0
->py==312
, and4.0.0
->py==4
).Multiple version specifiers are at the moment always rendered in
and
. For example>=3.10.0,<3.11.0
with renderpy>=310 and py<311
. Same asconda-build
is doing. Ref: https://docs.conda.io/projects/conda-build/en/latest/resources/package-spec.html#package-match-specificationsIf one would want to express
<3.7
or>=3.10
should use the pipe operator<3.7|>=3.10
. In fact,<3.7|>=3.10
renderspy<37 or py>=310
and<3.8|>=3.10,!=3.11
renderspy<38 or py>=310 and py!=311
(,
andand
take precedence over|
andor
).It does handle compatible release operator
~=
correctly and the wildcard.*
suffix in the version as well (not very common though as the resulting selectors are not interesting).Others
👉 Fixes a minor bug: the compatible release operator
~=
in the dependency version could not be used because the parser was jumping to expanding the tilde~
and crashing on=
(or returning the wrong version containing=
). Therefore I suspect that the~=
operator was never handled (maybe never used, or nobody reported this bug).What does not add:
markers
,extras
, and others, are not supported (ignored). Nevertheless, the ground is set, and it is easier now to add support for this.grayskull
is able to handle it.xref #463 #535 / PR #523