setuptools icon indicating copy to clipboard operation
setuptools copied to clipboard

wheel install preference order is arbitrary

Open tdsmith opened this issue 7 years ago • 5 comments

The crash that this bug discusses was fixed upstream by removing the errant wheel, but the motivating observation for this report was that easy_install cffi downloaded a wheel that caused a crash on Python 3.7 on OS X at import _cffi_backend.

The crash was not observed with Python 3.6, because it downloaded a different wheel.

On 3.7, the downloaded wheel was https://files.pythonhosted.org/packages/15/5b/fe99b63da21831415c9b60467704cd0f96180e9d4c2d96eba424d63bebcb/cffi-1.11.5-cp34-abi3-macosx_10_6_intel.whl.

I was surprised that setuptools decided that this wheel was compatible with 3.7 but I think that's expected because it declares abi3, which turns out to have been an incorrect promise by cffi.

This file was selected on 3.7 but not 3.6 because of the ordering behavior of setuptools.package_index.PackageIndex, which determines which distribution easy_install will attempt to use, and which you can see here:

import setuptools.package_index
from pkg_resources import Requirement

pi = setuptools.package_index.PackageIndex()
pi.find_packages(Requirement.parse("cffi"))
pi["cffi"][:2]

On 3.6, this yielded (good):

[cffi 1.11.5 (https://files.pythonhosted.org/packages/8e/be/40b1bc2c3221acdefeb9dab6773d43cda7543ed0d8c8df8768f05af2d01e/cffi-1.11.5-cp36-cp36m-macosx_10_6_intel.whl#sha256=3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257),
 cffi 1.11.5 (https://files.pythonhosted.org/packages/15/5b/fe99b63da21831415c9b60467704cd0f96180e9d4c2d96eba424d63bebcb/cffi-1.11.5-cp34-abi3-macosx_10_6_intel.whl#sha256=facc52ea162864a51556925bfa09d8c8c131349aeabfce2da4a43198e36fba5c)]

On 3.7, this yielded (bad):

[cffi 1.11.5 (https://files.pythonhosted.org/packages/15/5b/fe99b63da21831415c9b60467704cd0f96180e9d4c2d96eba424d63bebcb/cffi-1.11.5-cp34-abi3-macosx_10_6_intel.whl#sha256=facc52ea162864a51556925bfa09d8c8c131349aeabfce2da4a43198e36fba5c),
 cffi 1.11.5 (https://files.pythonhosted.org/packages/0b/ba/32835c9965d8a0090723e1d0b47373365525c4bd08c807b5efdc9fecbc99/cffi-1.11.5-cp37-cp37m-macosx_10_9_x86_64.whl#sha256=ca1bd81f40adc59011f58159e4aa6445fc585a32bb8ac9badf7a2c1aa23822f2)]

Environment.add sorts the distributions in descending order by this key:

self.parsed_version,    # 1.11.5
self.precedence,        # binary or source
self.key,               # "cffi"
_remove_md5_fragment(self.location), # the url
self.py_version or '',  # not set by PackageIndex for wheels
self.platform or '',    # not set by PackageIndex for wheels

These keys are identical for the good and bad distributions up until self.location. You will notice that the URLs for the wheels, which is held in Distribution.location, contains a hash value before the wheel filename -- so the sort order is meaningless. Indeed, the wheels are sorted in descending order by the hash in the URL. (_remove_md5_fragment incidentally does not remove any of the modern hash components.)

The bad wheel had a relatively low hash value, so the 3.6-specific wheel "beat" it. The Python 3.7-specific wheel was unlucky and had an even lower hash value.

Perhaps the value of the final path component should be the sort key (i.e. remove_md5_fragment could be rehabilitated to do something useful). The most important bug here was that the wheel was mispublished, but the confusing behavior across different Python versions was due to sorting on a meaningless key.

tdsmith avatar Jul 01 '18 07:07 tdsmith