Skip to content

Commit

Permalink
Force the --python-tag when autobuilding wheels
Browse files Browse the repository at this point in the history
A lot of existing tarballs will successfully build a wheel, but the
wheel will be implicitly broken because they will have dynamically
adjusted the install_requires inside of their setup.py. Typically
this is done for things like Python version, implementation, or what
OS this is being installed on. We don't consider cache directories
to be OS agnostic but we do consider them to be Python version and
implementation agnostic. To solve this, we'll force the cached
wheel to use a more specific Python tag that includes the major
version and the implementation.
  • Loading branch information
dstufft committed Nov 4, 2015
1 parent 4bc2480 commit 0e240d7
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
9 changes: 9 additions & 0 deletions pip/pep425tags.py
Expand Up @@ -55,6 +55,13 @@ def get_impl_version_info():
return sys.version_info[0], sys.version_info[1]


def get_impl_tag():
"""
Returns the Tag for this specific implementation.
"""
return "{0}{1}".format(get_abbr_impl(), get_impl_ver())


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."""
Expand Down Expand Up @@ -198,3 +205,5 @@ def get_supported(versions=None, noarch=False):

supported_tags = get_supported()
supported_tags_noarch = get_supported(noarch=True)

implementation_tag = get_impl_tag()
17 changes: 13 additions & 4 deletions pip/wheel.py
Expand Up @@ -662,14 +662,14 @@ def __init__(self, requirement_set, finder, build_options=None,
self.build_options = build_options or []
self.global_options = global_options or []

def _build_one(self, req, output_dir):
def _build_one(self, req, output_dir, python_tag=None):
"""Build one wheel.
:return: The filename of the built wheel, or None if the build failed.
"""
tempd = tempfile.mkdtemp('pip-wheel-')
try:
if self.__build_one(req, tempd):
if self.__build_one(req, tempd, python_tag=python_tag):
try:
wheel_name = os.listdir(tempd)[0]
wheel_path = os.path.join(output_dir, wheel_name)
Expand All @@ -692,13 +692,17 @@ def _base_setup_args(self, req):
"__file__, 'exec'))" % req.setup_py
] + list(self.global_options)

def __build_one(self, req, tempd):
def __build_one(self, req, tempd, python_tag=None):
base_args = self._base_setup_args(req)

logger.info('Running setup.py bdist_wheel for %s', req.name)
logger.debug('Destination directory: %s', tempd)
wheel_args = base_args + ['bdist_wheel', '-d', tempd] \
+ self.build_options

if python_tag is not None:
wheel_args += ["--python-tag", python_tag]

try:
call_subprocess(wheel_args, cwd=req.source_dir, show_stdout=False)
return True
Expand Down Expand Up @@ -776,7 +780,9 @@ def build(self, autobuilding=False):
with indent_log():
build_success, build_failure = [], []
for req in buildset:
python_tag = None
if autobuilding:
python_tag = pep425tags.implementation_tag
output_dir = _cache_for_link(self._cache_root, req.link)
try:
ensure_dir(output_dir)
Expand All @@ -787,7 +793,10 @@ def build(self, autobuilding=False):
continue
else:
output_dir = self._wheel_dir
wheel_file = self._build_one(req, output_dir)
wheel_file = self._build_one(
req, output_dir,
python_tag=python_tag,
)
if wheel_file:
build_success.append(req)
if autobuilding:
Expand Down
7 changes: 6 additions & 1 deletion tests/functional/test_install.py
Expand Up @@ -7,6 +7,7 @@

import pytest

from pip import pep425tags
from pip.utils import appdirs, rmtree
from tests.lib import (pyversion, pyversion_tuple,
_create_test_package, _create_svn_repo, path_to_url)
Expand Down Expand Up @@ -737,7 +738,7 @@ def test_install_builds_wheels(script, data):
assert expected in str(res), str(res)
root = appdirs.user_cache_dir('pip')
wheels = []
for top, dirs, files in os.walk(root):
for top, dirs, files in os.walk(os.path.join(root, "wheels")):
wheels.extend(files)
# and built wheels for upper and wheelbroken
assert "Running setup.py bdist_wheel for upper" in str(res), str(res)
Expand All @@ -754,6 +755,10 @@ def test_install_builds_wheels(script, data):
assert "Running setup.py install for requires-wheel" in str(res), str(res)
# wheelbroken has to run install
assert "Running setup.py install for wheelb" in str(res), str(res)
# We want to make sure we used the correct implementation tag
assert wheels == [
"Upper-2.0-{0}-none-any.whl".format(pep425tags.implementation_tag),
]


def test_install_no_binary_disables_building_wheels(script, data):
Expand Down

0 comments on commit 0e240d7

Please sign in to comment.