Skip to content

Commit

Permalink
1. Provide a fallback mechanism for determining ABI flags if config vars
Browse files Browse the repository at this point in the history
   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.
  • Loading branch information
natefoo committed Oct 13, 2015
1 parent 1b5b4ac commit 63d239f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 24 deletions.
35 changes: 31 additions & 4 deletions pip/pep425tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
43 changes: 23 additions & 20 deletions tests/unit/test_wheel.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Tests for wheel binary packages and .dist-info."""
import os
import sys

import pytest
from mock import patch, Mock
Expand Down Expand Up @@ -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):
"""
Expand Down

0 comments on commit 63d239f

Please sign in to comment.