Skip to content
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

Use packaging.tags for doing compatible wheel tag calculation #7354

Merged
merged 34 commits into from
Jan 8, 2020

Conversation

chrahunt
Copy link
Member

@chrahunt chrahunt commented Nov 15, 2019

Introduction

packaging.tags provides a simple sys_tags function for getting applicable tags for the running interpreter, but it does not allow customization of arguments. Since pip allows users to provide explicit interpreter (e.g. "pp"), platform (e.g. "linux_x86_64"), abi (e.g. "abi3"), and version (e.g. "35"), we have to use a different interface.

packaging.tags provides three functions for users that need to customize tag generation:

  1. cpython_tags - for tags applicable to CPython only
  2. generic_tags - for tags applicable to any non-CPython Python implementation
  3. compatible_tags - for tags that are not specific to an interpreter
    implementation

cpython_tags and generic_tags are mutually exclusive, and return tags that are the highest priority. These tags are the most specific.

compatible_tags are always applicable, and a lower priority since they may just be compatible with e.g. the Python language version, but lack optimizations available in compiled code available for a specific interpreter/ABI/platform.

In this PR we remove most of our custom logic in pip._internal.pep425tags, instead relying on these three functions from packaging.tags.

Approach

It's a given that we want to switch to packaging.tags for calculating compatible wheel tags, but while doing that we have a few other goals:

  1. minimize bugs merged by making changes easy to review
  2. if possible, compare the implementation in packaging.tags with what is currently in pip so we can understand possible issues that may be raised later

To satisfy 1, the PR is broken into small commits that should each be easy to recognize the literal changes of and confirm as equivalent or understand the scope of change. Each commit should pass lint checks and tests, which should reduce the number of trivial things that need to be worried about and ensure that all changes are self-contained.

To satisfy 2, we take an approach that transforms pep425tags into something that looks closer to packaging.tags before actually using the functions.

For each of the 3 custom tags functions, we make a copy of get_supported, then:

  1. Refactor it locally, taking into account its new, more limited, responsibilities
  2. Introduce the packaging.tags function for the case where there are no custom arguments provided
  3. Customize arguments one-by-one and delegate to the packaging.tags function
  4. When there is no pip-specific logic left, remove the intermediate function and use the packaging.tags function directly in get_supported

Following that, we remove unused utility methods, then in the end we're left with an implementation that relies solely on the tag generation in packaging.tags.


Fixes #6908.

@chrahunt chrahunt added the type: maintenance Related to Development and Maintenance Processes label Nov 15, 2019
@chrahunt chrahunt changed the title WIP: Use packaging.tags WIP: Replace pep425tags with packaging.tags Nov 15, 2019
@pradyunsg
Copy link
Member

You can probably do the following, to make the vendoring work properly.

diff --git a/tools/automation/vendoring/__init__.py b/tools/automation/vendoring/__init__.py
index 1c2ae3a6..a77e9e58 100644
--- a/tools/automation/vendoring/__init__.py
+++ b/tools/automation/vendoring/__init__.py
@@ -128,6 +128,7 @@ def vendor(ctx, vendor_dir):
     )
     remove_all(vendor_dir.glob('*.dist-info'))
     remove_all(vendor_dir.glob('*.egg-info'))
+    remove_all(vendor_dir.glob('*/py.typed'))
 
     # Cleanup setuptools unneeded parts
     (vendor_dir / 'easy_install.py').unlink()

@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Nov 17, 2019
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Nov 19, 2019
@chrahunt chrahunt force-pushed the maint/use-packaging-tags branch 2 times, most recently from d57eb4a to 72432af Compare November 23, 2019 23:03
@chrahunt
Copy link
Member Author

Test failure would be fixed by #7395.

@chrahunt
Copy link
Member Author

Updated for latest commit, but had to update vendoring script locally to work around pypa/flit#298.

@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Nov 26, 2019
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Jan 5, 2020
@chrahunt
Copy link
Member Author

chrahunt commented Jan 5, 2020

Rebased on master and updated to use the latest commit on master for packaging.

When packaging is released, I can start breaking pieces of this off into separate PRs.

Since this function is only called for non-CPython interpreters, the
abi3-related branches are not relevant.
As with cpython_tags and compatible_tags, we assume this function covers
our use cases in the no-argument case and will customize our arguments
for it in a few steps.
Now that we're fully using packaging.tags, everything in the supported
list is already Tag.

Further, since each function is responsible for its own set of
non-overlapping tags, we can also remove the de-duplication.
Since we only call this function when platform is not None, we can drop
one of the branches. This is the only place using our manylinux
auto-deduction functions, so those can be removed next.
The remaining glibc-related functions are required to allow us to put
the libc version in the pip user agent (for stats).
Previously, these were used when the user did not provide an explicit
ABI. Now this is handled internally in `packaging.tags` (by
`_cpython_abi` and `_generic_abi`).
Now handled internally in `packaging.tags` (in `_platform_tags`).
# type: (str) -> Optional[str]
return sysconfig.get_config_var(var)


def version_info_to_nodot(version_info):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

follow up: I suggest moving the call to be changed -- changing get_supported to allow for version to be None (and use this value in that case).

Copy link
Member

@xavfernandez xavfernandez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job 👍

@xavfernandez xavfernandez merged commit fe3e892 into pypa:master Jan 8, 2020
@pradyunsg
Copy link
Member

Indeed. This was a decently large chunk of work which required a fair bit of figuring out the right way, and I know that you've spent time and effort to make the PRs easy to review!

Thanks @chrahunt for driving this and making it happen!

@chrahunt chrahunt deleted the maint/use-packaging-tags branch January 9, 2020 04:54
@lock lock bot added the auto-locked Outdated issues that have been locked by automation label Feb 8, 2020
@lock lock bot locked as resolved and limited conversation to collaborators Feb 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
auto-locked Outdated issues that have been locked by automation !release blocker Hold a release until this is resolved type: maintenance Related to Development and Maintenance Processes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace pep425tags w/ packaging.tags
5 participants