From 63d239ffacab1a5819dfdb1e53b0b9c2b1c62bb7 Mon Sep 17 00:00:00 2001 From: Nate Coraor Date: Tue, 13 Oct 2015 15:58:03 -0400 Subject: [PATCH] 1. Provide a fallback mechanism for determining ABI flags if config vars are unavailable, but issue a warning if this is used. 2. Explicitly handle the case where the unicode detection finds wide unicode but this is a 3.3+ build (necessary due to #1) 3. Fix tests broken due to #2. --- pip/pep425tags.py | 35 ++++++++++++++++++++++++++++---- tests/unit/test_wheel.py | 43 +++++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/pip/pep425tags.py b/pip/pep425tags.py index e5feda04fe5..d2436458c3d 100644 --- a/pip/pep425tags.py +++ b/pip/pep425tags.py @@ -55,15 +55,42 @@ def get_impl_version_info(): 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'): - d = 'd' if get_config_var('Py_DEBUG') else '' - m = 'm' if get_config_var('WITH_PYMALLOC') else '' - u = 'u' if get_config_var('Py_UNICODE_SIZE') == 4 else '' + 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] diff --git a/tests/unit/test_wheel.py b/tests/unit/test_wheel.py index 2a280fffd41..6339c47fbb9 100644 --- a/tests/unit/test_wheel.py +++ b/tests/unit/test_wheel.py @@ -1,5 +1,6 @@ """Tests for wheel binary packages and .dist-info.""" import os +import sys import pytest from mock import patch, Mock @@ -317,26 +318,28 @@ def abi_tag_unicode(self, flags, config_vars): config_vars.update({'SOABI': None}) base = pip.pep425tags.get_abbr_impl() + pip.pep425tags.get_impl_ver() - config_vars.update({'Py_UNICODE_SIZE': 2}) - mock_gcf = self.mock_get_config_var(**config_vars) - with patch('pip.pep425tags.sysconfig.get_config_var', mock_gcf): - abi_tag = pip.pep425tags.get_abi_tag() - assert abi_tag == base + flags - - config_vars.update({'Py_UNICODE_SIZE': 4}) - mock_gcf = self.mock_get_config_var(**config_vars) - with patch('pip.pep425tags.sysconfig.get_config_var', mock_gcf): - abi_tag = pip.pep425tags.get_abi_tag() - assert abi_tag == base + flags + 'u' - - # On Python >= 3.3, UCS-4 is essentially permanently enabled, and - # Py_UNICODE_SIZE is None. SOABI on these builds does not include the - # 'u' so manual SOABI detection should not do so either. - config_vars.update({'Py_UNICODE_SIZE': None}) - mock_gcf = self.mock_get_config_var(**config_vars) - with patch('pip.pep425tags.sysconfig.get_config_var', mock_gcf): - abi_tag = pip.pep425tags.get_abi_tag() - assert abi_tag == base + flags + if sys.version_info < (3, 3): + config_vars.update({'Py_UNICODE_SIZE': 2}) + mock_gcf = self.mock_get_config_var(**config_vars) + with patch('pip.pep425tags.sysconfig.get_config_var', mock_gcf): + abi_tag = pip.pep425tags.get_abi_tag() + assert abi_tag == base + flags + + config_vars.update({'Py_UNICODE_SIZE': 4}) + mock_gcf = self.mock_get_config_var(**config_vars) + with patch('pip.pep425tags.sysconfig.get_config_var', mock_gcf): + abi_tag = pip.pep425tags.get_abi_tag() + assert abi_tag == base + flags + 'u' + + else: + # On Python >= 3.3, UCS-4 is essentially permanently enabled, and + # Py_UNICODE_SIZE is None. SOABI on these builds does not include + # the 'u' so manual SOABI detection should not do so either. + config_vars.update({'Py_UNICODE_SIZE': None}) + mock_gcf = self.mock_get_config_var(**config_vars) + with patch('pip.pep425tags.sysconfig.get_config_var', mock_gcf): + abi_tag = pip.pep425tags.get_abi_tag() + assert abi_tag == base + flags def test_broken_sysconfig(self): """