-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Restore legacy PyPy wheel interpreter tags #7655
Restore legacy PyPy wheel interpreter tags #7655
Conversation
pip used to calculate the interpreter tag for PyPy (and other non-CPython implementations) incorrectly. This was fixed as part of the migration to using packaging.tags to generate the list of potentially compatible wheel tags for a target platform. However, there are published PyPy wheels that use the old tag format, so this adds in a compatibility pass that accepts additional wheel tags in cases where pip versions prior to 20.0 previously did so.
@pradyunsg I've added low level unit tests that rely on knowing how the backwards compatibility aliases are generated. These are nice and fast, and can be run on CPython, not just on alternate implementations. However, I'm wondering if it might be worth also adding an explicit higher level integration test that only runs on PyPy, to prove that I've actually solved the reported bug (the unit test would then be demonstrating that the fix isn't PyPy specific). |
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. A few minor non-blocking comments.
It would be worthwhile and we should add one. I was gonna politely ask in a follow up comment, if you'd be willing to do so in this PR, and it looks like you're already thinking about it. :) |
I'm happy to add the high level test, but I'm not familiar enough with the layout of pip's test suite to have a good idea on where to add it (by contrast, adding the unit tests was easy, as I just searched for references to "pep425"). The |
Ah, looking further, I think I found the right place: test/functional/test_download.py. That already has several tests related to checking that platform-specific wheels are found and downloaded as expected, so we just need to add some extra cases there for non-CPython interpreters. |
Alas, looking at the way That means this new patch should also be PyPy-specific, specifically looking for |
Marked as WIP, as I need to significantly rework this based on the extra details I found in the commit that removed the old PyPy-specific code. I should be able to wrap that up tomorrow my time (it's currently 10 pm in UTC+10). |
Also noting another potential location for the higher level test: However, I'd like to do a true end to end test, as one of the things we're checking here is what gets passed to |
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 should guard this behavior behind a flag that, if used, should cause a deprecation warning to be traced. The reason for this approach is:
- to prevent undue burden on other implementations, who would otherwise be forced to copy/paste pep425tags again
- tracing a warning if a wheel is merely present in the available packages would be annoying during the whole transition period, where we would expect indexes to have wheels with both forms
- doing anything smarter, like tracing a deprecation warning only if a wheel is "considered" or "used", would get much harder when implementing the new resolver
@chrahunt I've described a new implementation strategy in #7629 (comment), as I no longer think my original idea is viable. That approach should naturally contain the problem, as the wheels built for currently available versions of PyPy using versions of the wheel prior to 0.34.0 will be grandfathered in, but anything built for PyPy3 8.0.0 or later will need to use the standard tags, or it won't work. |
I believe the rework is completed now, so I've removed the WIP marker and asked @pradyunsg to take another look. |
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'll take a closer look in the morning. :)
Noting that CI isn't happy with these changes -- looks like |
The new code was relying on the PyPy tag threshold dict being insertion ordered, but wasn't ensuring that was actually true on Python 2.7 and 3.5. I updated it to use |
The Windows errors look completely unrelated (something about an EnvironmentError attempt to install files): https://dev.azure.com/pypa/pip/_build/results?buildId=18040&view=logs&j=404e6841-f5ba-57d9-f2c8-8c5322057572&t=0219f6bf-240d-5b08-c877-377b12af5079&l=309 |
I filed #7667 for the PAX sdist installation issue (I believe the format change in the wheel tarball revealed a latent defect in pip) |
…ypy-wheel-compatibility
There have been significant changes since this review.
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 approach does sound reasonable to me -- but I really feel like I should defer to @chrahunt here. :P
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.
Overall this approach seems fine to me. I think any other installer that would
want to emulate this behavior (which they shouldn't feel obliged to) could do so
pretty easily.
The current method of generating the legacy PyPy tags looks OK and aligns with
the discussion in #7269.
I have a few comments on the deprecation warning. Given this implementation,
from my perspective, the desired behavior is:
- Only trace this deprecation notice when the package is actually used - currently
it would be traced when any wheel with a legacy tag in the repository is considered - Trace this deprecation notice for each such package (or all at once) - currently
it would be traced only once for the first package we consider (sincewarnings.warn
with "default" config will only trace the first instance for a given module + line number)
In a more ideal world we would only trace the deprecation notice when the result from the
legacy PyPy tag contributes to the resolution process, but I don't think it will be common
for these wheels to have more than one Python tag so I don't have a problem ignoring that
consideration.
One way to adapt the current implementation could be:
- Add a member to
Wheel
likeis_using_pypy_legacy_tags
to capture whether
_infer_missing_pypy_version_tags
returned anything before adding the result topyversions
. - Make a helper function that takes in a list of
Wheel
and traces a deprecation warning
for the ones usingis_using_pypy_legacy_tags
. - Call the helper function after resolving in
commands/download.py
,commands/install.py
,
andcommands/wheel.py
. We can create the list of wheel files by using thelocal_path
member ofInstallRequirement
s for whichis_wheel
is true.
This won't have the best error message, notably it won't say where the wheel files came
from, but it should satisfy the desired behavior mentioned above and not require a lot
of additional work to preserve the behavior with the upcoming resolver changes.
Gentle nudge on this @ncoghlan. Would it be possible for you to update this PR, or would you prefer/be OK with someone else taking this forward? |
I'd definitely be fine with someone else moving it forward (I confess I forgot there were review comments still to be addressed - I'm a few weeks behind on open source email notifications at the moment) |
Closing since no one has stepped up to take this forward, and if someone does, it'll be a new PR anyway. |
pip used to calculate the interpreter tag for PyPy (and other
non-CPython implementations) incorrectly. This was fixed as part
of the migration to using packaging.tags to generate the list of
potentially compatible wheel tags for a target platform.
However, there are published PyPy wheels that use the old tag
format, so this adds in a compatibility pass that accepts
additional wheel tags in cases where pip versions prior to 20.0
previously did so.
Fixes #7629