From 5b14f05d120bc33a17783c43fc5b28d2d06342fd Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Tue, 4 May 2021 16:50:52 +0800 Subject: [PATCH] Better diagnose when setup.py/cfg cannot be found This adds a check beforer invoking 'setup.py egg_info' to make sure the file (or setup.cfg) actually exists, and emit a clearer error message when neither can be found and the egg_info command can never succeed. --- news/9944.bugfix.rst | 2 ++ src/pip/_internal/req/req_install.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 news/9944.bugfix.rst diff --git a/news/9944.bugfix.rst b/news/9944.bugfix.rst new file mode 100644 index 00000000000..58bb70b78f3 --- /dev/null +++ b/news/9944.bugfix.rst @@ -0,0 +1,2 @@ +Emit clearer error message when a project root does not contain either +``pyproject.toml``, ``setup.py`` or ``setup.cfg``. diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py index 55c17ac8b45..c2eea37123e 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py @@ -509,6 +509,19 @@ def load_pyproject_toml(self): self.unpacked_source_directory, backend, backend_path=backend_path, ) + def _check_setup_py_or_cfg_exists(self) -> bool: + """Check if the requirement actually has a setuptools build file. + + If setup.py does not exist, we also check setup.cfg in the same + directory and allow the directory if that exists. + """ + if os.path.exists(self.setup_py_path): + return True + stem, ext = os.path.splitext(self.setup_py_path) + if ext == ".py" and os.path.exists(f"{stem}.cfg"): + return True + return False + def _generate_metadata(self): # type: () -> str """Invokes metadata generator functions, with the required arguments. @@ -516,6 +529,12 @@ def _generate_metadata(self): if not self.use_pep517: assert self.unpacked_source_directory + if not self._check_setup_py_or_cfg_exists(): + raise InstallationError( + f'File "setup.py" or "setup.cfg" not found for legacy ' + f'project {self}.' + ) + return generate_metadata_legacy( build_env=self.build_env, setup_py_path=self.setup_py_path,