mirror of https://github.com/pypa/pip
Merge pull request #10082 from uranusjr/setup-py-freeze
Unify Python project root detection logic
This commit is contained in:
commit
4704da4dad
|
@ -0,0 +1 @@
|
|||
Correctly allow PEP 517 projects to be detected without warnings in ``pip freeze``.
|
|
@ -39,7 +39,7 @@ from pip._internal.utils.deprecation import deprecated
|
|||
from pip._internal.utils.filesystem import copy2_fixed
|
||||
from pip._internal.utils.hashes import Hashes, MissingHashes
|
||||
from pip._internal.utils.logging import indent_log
|
||||
from pip._internal.utils.misc import display_path, hide_url, rmtree
|
||||
from pip._internal.utils.misc import display_path, hide_url, is_installable_dir, rmtree
|
||||
from pip._internal.utils.temp_dir import TempDirectory
|
||||
from pip._internal.utils.unpacking import unpack_file
|
||||
from pip._internal.vcs import vcs
|
||||
|
@ -376,7 +376,7 @@ class RequirementPreparer:
|
|||
# installation.
|
||||
# FIXME: this won't upgrade when there's an existing
|
||||
# package unpacked in `req.source_dir`
|
||||
if os.path.exists(os.path.join(req.source_dir, 'setup.py')):
|
||||
if is_installable_dir(req.source_dir):
|
||||
raise PreviousBuildDirError(
|
||||
"pip can't proceed with requirements '{}' due to a"
|
||||
"pre-existing build directory ({}). This is likely "
|
||||
|
|
|
@ -248,8 +248,8 @@ def _looks_like_path(name):
|
|||
def _get_url_from_path(path, name):
|
||||
# type: (str, str) -> Optional[str]
|
||||
"""
|
||||
First, it checks whether a provided path is an installable directory
|
||||
(e.g. it has a setup.py). If it is, returns the path.
|
||||
First, it checks whether a provided path is an installable directory. If it
|
||||
is, returns the path.
|
||||
|
||||
If false, check if the path is an archive file (such as a .whl).
|
||||
The function checks if the path is a file. If false, if the path has
|
||||
|
|
|
@ -270,13 +270,20 @@ def tabulate(rows):
|
|||
|
||||
|
||||
def is_installable_dir(path: str) -> bool:
|
||||
"""Is path is a directory containing pyproject.toml, setup.cfg or setup.py?"""
|
||||
"""Is path is a directory containing pyproject.toml or setup.py?
|
||||
|
||||
If pyproject.toml exists, this is a PEP 517 project. Otherwise we look for
|
||||
a legacy setuptools layout by identifying setup.py. We don't check for the
|
||||
setup.cfg because using it without setup.py is only available for PEP 517
|
||||
projects, which are already covered by the pyproject.toml check.
|
||||
"""
|
||||
if not os.path.isdir(path):
|
||||
return False
|
||||
return any(
|
||||
os.path.isfile(os.path.join(path, signifier))
|
||||
for signifier in ("pyproject.toml", "setup.cfg", "setup.py")
|
||||
)
|
||||
if os.path.isfile(os.path.join(path, "pyproject.toml")):
|
||||
return True
|
||||
if os.path.isfile(os.path.join(path, "setup.py")):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE):
|
||||
|
|
|
@ -18,7 +18,7 @@ from pip._internal.vcs.versioncontrol import (
|
|||
RemoteNotValidError,
|
||||
RevOptions,
|
||||
VersionControl,
|
||||
find_path_to_setup_from_repo_root,
|
||||
find_path_to_project_root_from_repo_root,
|
||||
vcs,
|
||||
)
|
||||
|
||||
|
@ -410,8 +410,8 @@ class Git(VersionControl):
|
|||
def get_subdirectory(cls, location):
|
||||
# type: (str) -> Optional[str]
|
||||
"""
|
||||
Return the path to setup.py, relative to the repo root.
|
||||
Return None if setup.py is in the repo root.
|
||||
Return the path to Python project root, relative to the repo root.
|
||||
Return None if the project root is in the repo root.
|
||||
"""
|
||||
# find the repo root
|
||||
git_dir = cls.run_command(
|
||||
|
@ -423,7 +423,7 @@ class Git(VersionControl):
|
|||
if not os.path.isabs(git_dir):
|
||||
git_dir = os.path.join(location, git_dir)
|
||||
repo_root = os.path.abspath(os.path.join(git_dir, '..'))
|
||||
return find_path_to_setup_from_repo_root(location, repo_root)
|
||||
return find_path_to_project_root_from_repo_root(location, repo_root)
|
||||
|
||||
@classmethod
|
||||
def get_url_rev_and_auth(cls, url):
|
||||
|
|
|
@ -10,7 +10,7 @@ from pip._internal.utils.urls import path_to_url
|
|||
from pip._internal.vcs.versioncontrol import (
|
||||
RevOptions,
|
||||
VersionControl,
|
||||
find_path_to_setup_from_repo_root,
|
||||
find_path_to_project_root_from_repo_root,
|
||||
vcs,
|
||||
)
|
||||
|
||||
|
@ -120,8 +120,8 @@ class Mercurial(VersionControl):
|
|||
def get_subdirectory(cls, location):
|
||||
# type: (str) -> Optional[str]
|
||||
"""
|
||||
Return the path to setup.py, relative to the repo root.
|
||||
Return None if setup.py is in the repo root.
|
||||
Return the path to Python project root, relative to the repo root.
|
||||
Return None if the project root is in the repo root.
|
||||
"""
|
||||
# find the repo root
|
||||
repo_root = cls.run_command(
|
||||
|
@ -129,7 +129,7 @@ class Mercurial(VersionControl):
|
|||
).strip()
|
||||
if not os.path.isabs(repo_root):
|
||||
repo_root = os.path.abspath(os.path.join(location, repo_root))
|
||||
return find_path_to_setup_from_repo_root(location, repo_root)
|
||||
return find_path_to_project_root_from_repo_root(location, repo_root)
|
||||
|
||||
@classmethod
|
||||
def get_repository_root(cls, location):
|
||||
|
|
|
@ -7,6 +7,7 @@ from pip._internal.utils.misc import (
|
|||
HiddenText,
|
||||
display_path,
|
||||
is_console_interactive,
|
||||
is_installable_dir,
|
||||
split_auth_from_netloc,
|
||||
)
|
||||
from pip._internal.utils.subprocess import CommandArgs, make_command
|
||||
|
@ -111,18 +112,17 @@ class Subversion(VersionControl):
|
|||
@classmethod
|
||||
def get_remote_url(cls, location):
|
||||
# type: (str) -> str
|
||||
# In cases where the source is in a subdirectory, not alongside
|
||||
# setup.py we have to look up in the location until we find a real
|
||||
# setup.py
|
||||
# In cases where the source is in a subdirectory, we have to look up in
|
||||
# the location until we find a valid project root.
|
||||
orig_location = location
|
||||
while not os.path.exists(os.path.join(location, 'setup.py')):
|
||||
while not is_installable_dir(location):
|
||||
last_location = location
|
||||
location = os.path.dirname(location)
|
||||
if location == last_location:
|
||||
# We've traversed up to the root of the filesystem without
|
||||
# finding setup.py
|
||||
# finding a Python project.
|
||||
logger.warning(
|
||||
"Could not find setup.py for directory %s (tried all "
|
||||
"Could not find Python project for directory %s (tried all "
|
||||
"parent directories)",
|
||||
orig_location,
|
||||
)
|
||||
|
|
|
@ -27,6 +27,7 @@ from pip._internal.utils.misc import (
|
|||
display_path,
|
||||
hide_url,
|
||||
hide_value,
|
||||
is_installable_dir,
|
||||
rmtree,
|
||||
)
|
||||
from pip._internal.utils.subprocess import CommandArgs, call_subprocess, make_command
|
||||
|
@ -68,23 +69,23 @@ def make_vcs_requirement_url(repo_url, rev, project_name, subdir=None):
|
|||
return req
|
||||
|
||||
|
||||
def find_path_to_setup_from_repo_root(location, repo_root):
|
||||
def find_path_to_project_root_from_repo_root(location, repo_root):
|
||||
# type: (str, str) -> Optional[str]
|
||||
"""
|
||||
Find the path to `setup.py` by searching up the filesystem from `location`.
|
||||
Return the path to `setup.py` relative to `repo_root`.
|
||||
Return None if `setup.py` is in `repo_root` or cannot be found.
|
||||
Find the the Python project's root by searching up the filesystem from
|
||||
`location`. Return the path to project root relative to `repo_root`.
|
||||
Return None if the project root is `repo_root`, or cannot be found.
|
||||
"""
|
||||
# find setup.py
|
||||
# find project root.
|
||||
orig_location = location
|
||||
while not os.path.exists(os.path.join(location, 'setup.py')):
|
||||
while not is_installable_dir(location):
|
||||
last_location = location
|
||||
location = os.path.dirname(location)
|
||||
if location == last_location:
|
||||
# We've traversed up to the root of the filesystem without
|
||||
# finding setup.py
|
||||
# finding a Python project.
|
||||
logger.warning(
|
||||
"Could not find setup.py for directory %s (tried all "
|
||||
"Could not find a Python project for directory %s (tried all "
|
||||
"parent directories)",
|
||||
orig_location,
|
||||
)
|
||||
|
@ -296,8 +297,8 @@ class VersionControl:
|
|||
def get_subdirectory(cls, location):
|
||||
# type: (str) -> Optional[str]
|
||||
"""
|
||||
Return the path to setup.py, relative to the repo root.
|
||||
Return None if setup.py is in the repo root.
|
||||
Return the path to Python project root, relative to the repo root.
|
||||
Return None if the project root is in the repo root.
|
||||
"""
|
||||
return None
|
||||
|
||||
|
|
Loading…
Reference in New Issue