Skip to content

Commit

Permalink
Merge pull request #7115 from pradyunsg/refactor/move-find_egg_info
Browse files Browse the repository at this point in the history
Move find_egg_info to operations.generate_metadata
  • Loading branch information
pradyunsg authored Oct 4, 2019
2 parents e6f69fa + b21f4c9 commit 1bdb702
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 54 deletions.
68 changes: 66 additions & 2 deletions src/pip/_internal/operations/generate_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import logging
import os

from pip._internal.exceptions import InstallationError
from pip._internal.utils.misc import ensure_dir
from pip._internal.utils.setuptools_build import make_setuptools_shim_args
from pip._internal.utils.subprocess import call_subprocess
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
from pip._internal.vcs import vcs

if MYPY_CHECK_RUNNING:
from typing import Callable, List
Expand All @@ -30,6 +32,65 @@ def get_metadata_generator(install_req):
return _generate_metadata


def _find_egg_info(source_directory, is_editable):
# type: (str, bool) -> str
"""Find an .egg-info in `source_directory`, based on `is_editable`.
"""

def looks_like_virtual_env(path):
# type: (str) -> bool
return (
os.path.lexists(os.path.join(path, 'bin', 'python')) or
os.path.exists(os.path.join(path, 'Scripts', 'Python.exe'))
)

def locate_editable_egg_info(base):
# type: (str) -> List[str]
candidates = [] # type: List[str]
for root, dirs, files in os.walk(base):
for dir_ in vcs.dirnames:
if dir_ in dirs:
dirs.remove(dir_)
# Iterate over a copy of ``dirs``, since mutating
# a list while iterating over it can cause trouble.
# (See https://github.com/pypa/pip/pull/462.)
for dir_ in list(dirs):
if looks_like_virtual_env(os.path.join(root, dir_)):
dirs.remove(dir_)
# Also don't search through tests
elif dir_ == 'test' or dir_ == 'tests':
dirs.remove(dir_)
candidates.extend(os.path.join(root, dir_) for dir_ in dirs)
return [f for f in candidates if f.endswith('.egg-info')]

def depth_of_directory(dir_):
# type: (str) -> int
return (
dir_.count(os.path.sep) +
(os.path.altsep and dir_.count(os.path.altsep) or 0)
)

base = source_directory
if is_editable:
filenames = locate_editable_egg_info(base)
else:
base = os.path.join(base, 'pip-egg-info')
filenames = os.listdir(base)

if not filenames:
raise InstallationError(
"Files/directories not found in %s" % base
)

# If we have more than one match, we pick the toplevel one. This
# can easily be the case if there is a dist folder which contains
# an extracted tarball for testing purposes.
if len(filenames) > 1:
filenames.sort(key=depth_of_directory)

return os.path.join(base, filenames[0])


def _generate_metadata_legacy(install_req):
# type: (InstallRequirement) -> str
req_details_str = install_req.name or "from {}".format(install_req.link)
Expand Down Expand Up @@ -63,8 +124,11 @@ def _generate_metadata_legacy(install_req):
command_desc='python setup.py egg_info',
)

# Return the metadata directory.
return install_req.find_egg_info()
# Return the .egg-info directory.
return _find_egg_info(
install_req.unpacked_source_directory,
install_req.editable,
)


def _generate_metadata(install_req):
Expand Down
52 changes: 0 additions & 52 deletions src/pip/_internal/req/req_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -613,58 +613,6 @@ def prepare_pep517_metadata(self):

return os.path.join(metadata_dir, distinfo_dir)

def find_egg_info(self):
# type: () -> str
def looks_like_virtual_env(path):
return (
os.path.lexists(os.path.join(path, 'bin', 'python')) or
os.path.exists(os.path.join(path, 'Scripts', 'Python.exe'))
)

def locate_editable_egg_info(base):
candidates = []
for root, dirs, files in os.walk(base):
for dir_ in vcs.dirnames:
if dir_ in dirs:
dirs.remove(dir_)
# Iterate over a copy of ``dirs``, since mutating
# a list while iterating over it can cause trouble.
# (See https://github.com/pypa/pip/pull/462.)
for dir_ in list(dirs):
if looks_like_virtual_env(os.path.join(root, dir_)):
dirs.remove(dir_)
# Also don't search through tests
elif dir_ == 'test' or dir_ == 'tests':
dirs.remove(dir_)
candidates.extend(os.path.join(root, dir_) for dir_ in dirs)
return [f for f in candidates if f.endswith('.egg-info')]

def depth_of_directory(dir_):
return (
dir_.count(os.path.sep) +
(os.path.altsep and dir_.count(os.path.altsep) or 0)
)

if self.editable:
base = self.source_dir
filenames = locate_editable_egg_info(base)
else:
base = os.path.join(self.unpacked_source_directory, 'pip-egg-info')
filenames = os.listdir(base)

if not filenames:
raise InstallationError(
"Files/directories not found in %s" % base
)

# If we have more than one match, we pick the toplevel one. This
# can easily be the case if there is a dist folder which contains
# an extracted tarball for testing purposes.
if len(filenames) > 1:
filenames.sort(key=depth_of_directory)

return os.path.join(base, filenames[0])

@property
def metadata(self):
# type: () -> Any
Expand Down

0 comments on commit 1bdb702

Please sign in to comment.