1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00

Merge pull request #7494 from chrahunt/refactor/wheel-metadata-retrieval

Only allow one top-level .dist-info directory in wheels
This commit is contained in:
Christopher Hunt 2019-12-23 05:41:30 +08:00 committed by GitHub
commit 92da786643
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 6 deletions

2
news/7487.removal Normal file
View file

@ -0,0 +1,2 @@
Wheel processing no longer permits wheels containing more than one top-level
.dist-info directory.

View file

@ -315,8 +315,10 @@ def install_unpacked_wheel(
:param pycompile: Whether to byte-compile installed Python files
:param warn_script_location: Whether to check that scripts are installed
into a directory on PATH
:raises UnsupportedWheel: when the directory holds an unpacked wheel with
incompatible Wheel-Version
:raises UnsupportedWheel:
* when the directory holds an unpacked wheel with incompatible
Wheel-Version
* when the .dist-info dir does not match the wheel
"""
# TODO: Investigate and break this up.
# TODO: Look into moving this into a dedicated class for representing an
@ -381,8 +383,7 @@ def install_unpacked_wheel(
continue
elif (
is_base and
s.endswith('.dist-info') and
canonicalize_name(s).startswith(canonicalize_name(name))
s.endswith('.dist-info')
):
assert not info_dir, (
'Multiple .dist-info directories: {}, '.format(
@ -445,6 +446,15 @@ def install_unpacked_wheel(
req_description
)
info_dir_name = canonicalize_name(os.path.basename(info_dir[0]))
canonical_name = canonicalize_name(name)
if not info_dir_name.startswith(canonical_name):
raise UnsupportedWheel(
"{} .dist-info directory {!r} does not start with {!r}".format(
req_description, os.path.basename(info_dir[0]), canonical_name
)
)
# Get the defined entry points
ep_file = os.path.join(info_dir[0], 'entry_points.txt')
console, gui = get_entrypoints(ep_file)

View file

@ -1,9 +1,11 @@
import distutils
import glob
import os
import shutil
import pytest
from tests.lib import create_basic_wheel_for_package
from tests.lib.path import Path
@ -432,3 +434,41 @@ def test_wheel_install_with_no_cache_dir(script, tmpdir, data):
package = data.packages.joinpath("simple.dist-0.1-py2.py3-none-any.whl")
result = script.pip('install', '--no-cache-dir', '--no-index', package)
result.assert_installed('simpledist', editable=False)
def test_wheel_install_fails_with_extra_dist_info(script):
package = create_basic_wheel_for_package(
script,
"simple",
"0.1.0",
extra_files={
"unrelated-2.0.0.dist-info/WHEEL": "Wheel-Version: 1.0",
"unrelated-2.0.0.dist-info/METADATA": (
"Name: unrelated\nVersion: 2.0.0\n"
),
},
)
result = script.pip(
"install", "--no-cache-dir", "--no-index", package, expect_error=True
)
assert "Multiple .dist-info directories" in result.stderr
def test_wheel_install_fails_with_unrelated_dist_info(script):
package = create_basic_wheel_for_package(script, "simple", "0.1.0")
new_name = "unrelated-2.0.0-py2.py3-none-any.whl"
new_package = os.path.join(os.path.dirname(package), new_name)
shutil.move(package, new_package)
result = script.pip(
"install",
"--no-cache-dir",
"--no-index",
new_package,
expect_error=True,
)
assert (
"'simple-0.1.0.dist-info' does not start with 'unrelated'"
in result.stderr
)

View file

@ -921,8 +921,9 @@ def create_test_package_with_setup(script, **setup_kwargs):
return pkg_path
def create_basic_wheel_for_package(script, name, version,
depends=None, extras=None):
def create_basic_wheel_for_package(
script, name, version, depends=None, extras=None, extra_files=None
):
if depends is None:
depends = []
if extras is None:
@ -966,6 +967,9 @@ def create_basic_wheel_for_package(script, name, version,
"{dist_info}/RECORD": ""
}
if extra_files:
files.update(extra_files)
# Some useful shorthands
archive_name = "{name}-{version}-py2.py3-none-any.whl".format(
name=name, version=version