Repository: pypa/pip

Issue:
Use plain "abi3" where supported in pep425tags.get_supported
**What's the problem this feature will solve?**

Currently we calculate stable ABI tags dynamically, when it could be static.

Recall that wheel filenames look like:

```
...-{python tag}-{abi tag}-{platform tag}.whl
```

The `{abi tag}` is defined in [PEP 425](https://www.python.org/dev/peps/pep-0425/#abi-tag). One specific ABI tag called out is "abi3", which is defined as "the CPython stable ABI".

Instead of just using "abi3", to get the list of stable ABIs in [`pep425tags.get_supported()`](https://github.com/pypa/pip/blob/d38cead0310978984b103e9fdd253fdb5fed167c/src/pip/_internal/pep425tags.py#L363-L365) we use this:

```
    for suffix in get_extension_suffixes():
        if suffix.startswith('.abi'):
            abi3s.add(suffix.split('.', 2)[1])
```

This seems like an attempt to apply [PEP 3149](https://www.python.org/dev/peps/pep-3149/) to wheel ABI tags, but seems like overkill given the only defined stable ABI is "abi3".

It would be simpler to integrate with the current `packaging.tags` if we just assume "abi3" is the only possible value and is available only on CPython 3.2+.

**Describe the solution you'd like**

```
if sys.implementation.name == "cpython" and sys.version_info >= (3, 2):
    abi3s.add("abi3")
```

or something simpler since this will only ever be the single value.

**Alternative Solutions**

* Keep the current behavior and make a change in `packaging.tags` to support multiple user-specified stable ABIs (or to divine them in the same way we do above), and
* Update the relevant PEPs to be more clear

**Additional context**

* pypa/packaging#187


Discussion:

Resolving patch:
diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py
--- a/src/pip/_internal/pep425tags.py
+++ b/src/pip/_internal/pep425tags.py
@@ -10,13 +10,14 @@
 import warnings
 from collections import OrderedDict
 
+from pip._vendor.six import PY2
+
 import pip._internal.utils.glibc
-from pip._internal.utils.compat import get_extension_suffixes
 from pip._internal.utils.typing import MYPY_CHECK_RUNNING
 
 if MYPY_CHECK_RUNNING:
     from typing import (
-        Tuple, Callable, List, Optional, Union, Dict, Set
+        Tuple, Callable, List, Optional, Union, Dict
     )
 
     Pep425Tag = Tuple[str, str, str]
@@ -361,12 +362,10 @@ def get_supported(
     if abi:
         abis[0:0] = [abi]
 
-    abi3s = set()  # type: Set[str]
-    for suffix in get_extension_suffixes():
-        if suffix.startswith('.abi'):
-            abi3s.add(suffix.split('.', 2)[1])
+    supports_abi3 = not PY2 and impl == "cp"
 
-    abis.extend(sorted(list(abi3s)))
+    if supports_abi3:
+        abis.append("abi3")
 
     abis.append('none')
 
@@ -419,13 +418,13 @@ def get_supported(
             supported.append(('%s%s' % (impl, versions[0]), abi, arch))
 
     # abi3 modules compatible with older version of Python
-    for version in versions[1:]:
-        # abi3 was introduced in Python 3.2
-        if version in {'31', '30'}:
-            break
-        for abi in abi3s:   # empty set if not Python 3
+    if supports_abi3:
+        for version in versions[1:]:
+            # abi3 was introduced in Python 3.2
+            if version in {'31', '30'}:
+                break
             for arch in arches:
-                supported.append(("%s%s" % (impl, version), abi, arch))
+                supported.append(("%s%s" % (impl, version), "abi3", arch))
 
     # Has binaries, does not use the Python API:
     for arch in arches:
diff --git a/src/pip/_internal/utils/compat.py b/src/pip/_internal/utils/compat.py
--- a/src/pip/_internal/utils/compat.py
+++ b/src/pip/_internal/utils/compat.py
@@ -43,7 +43,6 @@
 __all__ = [
     "ipaddress", "uses_pycache", "console_to_str",
     "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size",
-    "get_extension_suffixes",
 ]
 
 
@@ -189,19 +188,6 @@ def get_path_uid(path):
     return file_uid
 
 
-if PY2:
-    from imp import get_suffixes
-
-    def get_extension_suffixes():
-        return [suffix[0] for suffix in get_suffixes()]
-
-else:
-    from importlib.machinery import EXTENSION_SUFFIXES
-
-    def get_extension_suffixes():
-        return EXTENSION_SUFFIXES
-
-
 def expanduser(path):
     # type: (str) -> str
     """


Test patch: