Skip to content

Commit 0e240d7

Browse files
committed
Force the --python-tag when autobuilding wheels
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.
1 parent 4bc2480 commit 0e240d7

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

pip/pep425tags.py

+9
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ def get_impl_version_info():
5555
return sys.version_info[0], sys.version_info[1]
5656

5757

58+
def get_impl_tag():
59+
"""
60+
Returns the Tag for this specific implementation.
61+
"""
62+
return "{0}{1}".format(get_abbr_impl(), get_impl_ver())
63+
64+
5865
def get_flag(var, fallback, expected=True, warn=True):
5966
"""Use a fallback method for determining SOABI flags if the needed config
6067
var is unset or unavailable."""
@@ -198,3 +205,5 @@ def get_supported(versions=None, noarch=False):
198205

199206
supported_tags = get_supported()
200207
supported_tags_noarch = get_supported(noarch=True)
208+
209+
implementation_tag = get_impl_tag()

pip/wheel.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -662,14 +662,14 @@ def __init__(self, requirement_set, finder, build_options=None,
662662
self.build_options = build_options or []
663663
self.global_options = global_options or []
664664

665-
def _build_one(self, req, output_dir):
665+
def _build_one(self, req, output_dir, python_tag=None):
666666
"""Build one wheel.
667667
668668
:return: The filename of the built wheel, or None if the build failed.
669669
"""
670670
tempd = tempfile.mkdtemp('pip-wheel-')
671671
try:
672-
if self.__build_one(req, tempd):
672+
if self.__build_one(req, tempd, python_tag=python_tag):
673673
try:
674674
wheel_name = os.listdir(tempd)[0]
675675
wheel_path = os.path.join(output_dir, wheel_name)
@@ -692,13 +692,17 @@ def _base_setup_args(self, req):
692692
"__file__, 'exec'))" % req.setup_py
693693
] + list(self.global_options)
694694

695-
def __build_one(self, req, tempd):
695+
def __build_one(self, req, tempd, python_tag=None):
696696
base_args = self._base_setup_args(req)
697697

698698
logger.info('Running setup.py bdist_wheel for %s', req.name)
699699
logger.debug('Destination directory: %s', tempd)
700700
wheel_args = base_args + ['bdist_wheel', '-d', tempd] \
701701
+ self.build_options
702+
703+
if python_tag is not None:
704+
wheel_args += ["--python-tag", python_tag]
705+
702706
try:
703707
call_subprocess(wheel_args, cwd=req.source_dir, show_stdout=False)
704708
return True
@@ -776,7 +780,9 @@ def build(self, autobuilding=False):
776780
with indent_log():
777781
build_success, build_failure = [], []
778782
for req in buildset:
783+
python_tag = None
779784
if autobuilding:
785+
python_tag = pep425tags.implementation_tag
780786
output_dir = _cache_for_link(self._cache_root, req.link)
781787
try:
782788
ensure_dir(output_dir)
@@ -787,7 +793,10 @@ def build(self, autobuilding=False):
787793
continue
788794
else:
789795
output_dir = self._wheel_dir
790-
wheel_file = self._build_one(req, output_dir)
796+
wheel_file = self._build_one(
797+
req, output_dir,
798+
python_tag=python_tag,
799+
)
791800
if wheel_file:
792801
build_success.append(req)
793802
if autobuilding:

tests/functional/test_install.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import pytest
99

10+
from pip import pep425tags
1011
from pip.utils import appdirs, rmtree
1112
from tests.lib import (pyversion, pyversion_tuple,
1213
_create_test_package, _create_svn_repo, path_to_url)
@@ -737,7 +738,7 @@ def test_install_builds_wheels(script, data):
737738
assert expected in str(res), str(res)
738739
root = appdirs.user_cache_dir('pip')
739740
wheels = []
740-
for top, dirs, files in os.walk(root):
741+
for top, dirs, files in os.walk(os.path.join(root, "wheels")):
741742
wheels.extend(files)
742743
# and built wheels for upper and wheelbroken
743744
assert "Running setup.py bdist_wheel for upper" in str(res), str(res)
@@ -754,6 +755,10 @@ def test_install_builds_wheels(script, data):
754755
assert "Running setup.py install for requires-wheel" in str(res), str(res)
755756
# wheelbroken has to run install
756757
assert "Running setup.py install for wheelb" in str(res), str(res)
758+
# We want to make sure we used the correct implementation tag
759+
assert wheels == [
760+
"Upper-2.0-{0}-none-any.whl".format(pep425tags.implementation_tag),
761+
]
757762

758763

759764
def test_install_no_binary_disables_building_wheels(script, data):

0 commit comments

Comments
 (0)