summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Coraor <nate@bx.psu.edu>2016-02-01 14:29:22 -0500
committerNate Coraor <nate@bx.psu.edu>2016-02-01 14:29:22 -0500
commit044cedcce403c36ddc7644a32151f38252918dff (patch)
tree1af991a4a3ce93bdc45df621e7f6e1cc9775f37c
parente43da9a3d182fd834e147a680683e5138d17b070 (diff)
parent2c52729ccaf837c8c41696b38e7bf2fc9fd3267c (diff)
downloadwheel-044cedcce403c36ddc7644a32151f38252918dff.tar.gz
Merged in natefoo/wheel-pr (pull request #55)
SOABI support for Python 2.X and PyPy
-rw-r--r--wheel/bdist_wheel.py12
-rw-r--r--wheel/pep425tags.py87
2 files changed, 79 insertions, 20 deletions
diff --git a/wheel/bdist_wheel.py b/wheel/bdist_wheel.py
index aa7c0c7..b8abaa0 100644
--- a/wheel/bdist_wheel.py
+++ b/wheel/bdist_wheel.py
@@ -33,7 +33,7 @@ from distutils.sysconfig import get_python_version
from distutils import log as logger
-from .pep425tags import get_abbr_impl, get_impl_ver
+from .pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag
from .util import native, open_for_csv
from .archive import archive_wheelfile
from .pkginfo import read_pkg_info, write_pkg_info
@@ -143,14 +143,8 @@ class bdist_wheel(Command):
plat_name = plat_name.replace('-', '_').replace('.', '_')
impl_name = get_abbr_impl()
impl_ver = get_impl_ver()
- # PEP 3149 -- no SOABI in Py 2
- # For PyPy?
- # "pp%s%s" % (sys.pypy_version_info.major,
- # sys.pypy_version_info.minor)
- abi_tag = sysconfig.get_config_vars().get('SOABI', 'none')
- if abi_tag.startswith('cpython-'):
- abi_tag = 'cp' + abi_tag.split('-')[1]
-
+ # PEP 3149
+ abi_tag = str(get_abi_tag()).lower()
tag = (impl_name + impl_ver, abi_tag, plat_name)
# XXX switch to this alternate implementation for non-pure:
assert tag == supported_tags[0]
diff --git a/wheel/pep425tags.py b/wheel/pep425tags.py
index 2cf2230..2fe8510 100644
--- a/wheel/pep425tags.py
+++ b/wheel/pep425tags.py
@@ -1,6 +1,7 @@
"""Generate and work with PEP 425 Compatibility Tags."""
import sys
+import warnings
try:
import sysconfig
@@ -10,6 +11,14 @@ except ImportError: # pragma nocover
import distutils.util
+def get_config_var(var):
+ try:
+ return sysconfig.get_config_var(var)
+ except IOError as e: # pip Issue #1074
+ warnings.warn("{0}".format(e), RuntimeWarning)
+ return None
+
+
def get_abbr_impl():
"""Return abbreviated implementation name."""
if hasattr(sys, 'pypy_version_info'):
@@ -25,12 +34,69 @@ def get_abbr_impl():
def get_impl_ver():
"""Return implementation version."""
- impl_ver = sysconfig.get_config_var("py_version_nodot")
- if not impl_ver:
- impl_ver = ''.join(map(str, sys.version_info[:2]))
+ impl_ver = get_config_var("py_version_nodot")
+ if not impl_ver or get_abbr_impl() == 'pp':
+ impl_ver = ''.join(map(str, get_impl_version_info()))
return impl_ver
+def get_impl_version_info():
+ """Return sys.version_info-like tuple for use in decrementing the minor
+ version."""
+ if get_abbr_impl() == 'pp':
+ # as per https://github.com/pypa/pip/issues/2882
+ return (sys.version_info[0], sys.pypy_version_info.major,
+ sys.pypy_version_info.minor)
+ else:
+ return sys.version_info[0], sys.version_info[1]
+
+
+def get_flag(var, fallback, expected=True, warn=True):
+ """Use a fallback method for determining SOABI flags if the needed config
+ var is unset or unavailable."""
+ val = get_config_var(var)
+ if val is None:
+ if warn:
+ warnings.warn("Config variable '{0}' is unset, Python ABI tag may "
+ "be incorrect".format(var), RuntimeWarning, 2)
+ return fallback()
+ return val == expected
+
+
+def get_abi_tag():
+ """Return the ABI tag based on SOABI (if available) or emulate SOABI
+ (CPython 2, PyPy)."""
+ soabi = get_config_var('SOABI')
+ impl = get_abbr_impl()
+ if not soabi and impl in ('cp', 'pp') and hasattr(sys, 'maxunicode'):
+ d = ''
+ m = ''
+ u = ''
+ if get_flag('Py_DEBUG',
+ lambda: hasattr(sys, 'gettotalrefcount'),
+ warn=(impl == 'cp')):
+ d = 'd'
+ if get_flag('WITH_PYMALLOC',
+ lambda: impl == 'cp',
+ warn=(impl == 'cp')):
+ m = 'm'
+ if get_flag('Py_UNICODE_SIZE',
+ lambda: sys.maxunicode == 0x10ffff,
+ expected=4,
+ warn=(impl == 'cp' and
+ sys.version_info < (3, 3))) \
+ and sys.version_info < (3, 3):
+ u = 'u'
+ abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u)
+ elif soabi and soabi.startswith('cpython-'):
+ abi = 'cp' + soabi.split('-')[1]
+ elif soabi:
+ abi = soabi.replace('.', '_').replace('-', '_')
+ else:
+ abi = None
+ return abi
+
+
def get_platform():
"""Return our platform name 'win32', 'linux_x86_64'"""
# XXX remove distutils dependency
@@ -49,18 +115,19 @@ def get_supported(versions=None):
# Versions must be given with respect to the preference
if versions is None:
versions = []
- major = sys.version_info[0]
+ version_info = get_impl_version_info()
+ major = version_info[:-1]
# Support all previous minor Python versions.
- for minor in range(sys.version_info[1], -1, -1):
- versions.append(''.join(map(str, (major, minor))))
+ for minor in range(version_info[-1], -1, -1):
+ versions.append(''.join(map(str, major + (minor,))))
impl = get_abbr_impl()
abis = []
- soabi = sysconfig.get_config_var('SOABI')
- if soabi and soabi.startswith('cpython-'):
- abis[0:0] = ['cp' + soabi.split('-')[1]]
+ abi = get_abi_tag()
+ if abi:
+ abis[0:0] = [abi]
abi3s = set()
import imp
@@ -96,5 +163,3 @@ def get_supported(versions=None):
supported.append(('py%s' % (version[0]), 'none', 'any'))
return supported
-
-