From 96982debdc5eca137c2f3ed6a8ebe52c3f471cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Sat, 26 Aug 2023 13:47:34 +0200 Subject: [PATCH 1/3] builder: make poetry forward-compatible to poetry-core#629, which postpones validating the package so that packages created by build scripts are supported --- src/poetry/console/commands/install.py | 13 ++++++++++++- tests/console/commands/test_install.py | 1 - 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/poetry/console/commands/install.py b/src/poetry/console/commands/install.py index cc6e22eb624..d946ea529d2 100644 --- a/src/poetry/console/commands/install.py +++ b/src/poetry/console/commands/install.py @@ -155,6 +155,11 @@ def handle(self) -> int: if self.option("no-root"): return 0 + # Prior to https://github.com/python-poetry/poetry-core/pull/629 + # the existence of a module/package was checked when creating the + # EditableBuilder. Afterwards, the existence is checked after + # executing the build script (if there is one), + # i.e. during EditableBuilder.build(). try: builder = EditableBuilder(self.poetry, self.env, self.io) except ModuleOrPackageNotFound: @@ -178,7 +183,13 @@ def handle(self) -> int: self.line("") return 0 - builder.build() + try: + builder.build() + except ModuleOrPackageNotFound: + # This is likely due to the fact that the project is an application + # not following the structure expected by Poetry. + # No need for an editable install in this case. + return 0 if overwrite: self.overwrite(log_install.format(tag="success")) diff --git a/tests/console/commands/test_install.py b/tests/console/commands/test_install.py index bf3c819552a..cf3f287a147 100644 --- a/tests/console/commands/test_install.py +++ b/tests/console/commands/test_install.py @@ -33,7 +33,6 @@ "Python Poetry " ] license = "MIT" -readme = "README.rst" [tool.poetry.dependencies] python = "~2.7 || ^3.4" From 239ec4a73564a8faa2abdc27e53db574cc8e9e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Sat, 2 Sep 2023 11:52:29 +0200 Subject: [PATCH 2/3] install: do not fail silently if current project cannot be installed --- src/poetry/console/commands/install.py | 17 ++++++++++-- tests/console/commands/test_install.py | 36 ++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/poetry/console/commands/install.py b/src/poetry/console/commands/install.py index d946ea529d2..9c928ae2df4 100644 --- a/src/poetry/console/commands/install.py +++ b/src/poetry/console/commands/install.py @@ -162,10 +162,16 @@ def handle(self) -> int: # i.e. during EditableBuilder.build(). try: builder = EditableBuilder(self.poetry, self.env, self.io) - except ModuleOrPackageNotFound: + except (ModuleOrPackageNotFound, FileNotFoundError) as e: # This is likely due to the fact that the project is an application # not following the structure expected by Poetry # If this is a true error it will be picked up later by build anyway. + self.line_error( + f"The current project could not be installed: {e}\n" + "If you do not want to install the current project" + " use --no-root", + style="warning", + ) return 0 log_install = ( @@ -185,10 +191,17 @@ def handle(self) -> int: try: builder.build() - except ModuleOrPackageNotFound: + except (ModuleOrPackageNotFound, FileNotFoundError) as e: # This is likely due to the fact that the project is an application # not following the structure expected by Poetry. # No need for an editable install in this case. + self.line("") + self.line_error( + f"The current project could not be installed: {e}\n" + "If you do not want to install the current project" + " use --no-root", + style="warning", + ) return 0 if overwrite: diff --git a/tests/console/commands/test_install.py b/tests/console/commands/test_install.py index cf3f287a147..bf0789c8616 100644 --- a/tests/console/commands/test_install.py +++ b/tests/console/commands/test_install.py @@ -347,9 +347,9 @@ def test_remove_untracked_outputs_deprecation_warning( assert tester.status_code == 0 assert ( - tester.io.fetch_error() - == "The `--remove-untracked` option is deprecated, use the `--sync` option" + "The `--remove-untracked` option is deprecated, use the `--sync` option" " instead.\n" + in tester.io.fetch_error() ) @@ -416,6 +416,38 @@ def test_install_logs_output_decorated( assert tester.io.fetch_output() == expected +@pytest.mark.parametrize("with_root", [True]) +@pytest.mark.parametrize("error", ["module", "readme", ""]) +def test_install_warning_corrupt_root( + command_tester_factory: CommandTesterFactory, + project_factory: ProjectFactory, + with_root: bool, + error: str, +) -> None: + name = "corrupt" + content = f"""\ +[tool.poetry] +name = "{name}" +version = "1.2.3" +description = "" +authors = [] +""" + if error == "readme": + content += 'readme = "missing_readme.md"\n' + poetry = project_factory(name=name, pyproject_content=content) + if error != "module": + (poetry.pyproject_path.parent / f"{name}.py").touch() + + tester = command_tester_factory("install", poetry=poetry) + tester.execute("" if with_root else "--no-root") + + assert tester.status_code == 0 + if with_root and error: + assert "The current project could not be installed: " in tester.io.fetch_error() + else: + assert tester.io.fetch_error() == "" + + @pytest.mark.parametrize("options", ["", "--without dev"]) @pytest.mark.parametrize( "project", ["missing_directory_dependency", "missing_file_dependency"] From 087dc3c2757f0e2c5d057f80f60e5a642f1f88d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Sat, 2 Sep 2023 12:36:19 +0200 Subject: [PATCH 3/3] simplify code --- src/poetry/console/commands/install.py | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/poetry/console/commands/install.py b/src/poetry/console/commands/install.py index 9c928ae2df4..8e716caa2b0 100644 --- a/src/poetry/console/commands/install.py +++ b/src/poetry/console/commands/install.py @@ -155,25 +155,6 @@ def handle(self) -> int: if self.option("no-root"): return 0 - # Prior to https://github.com/python-poetry/poetry-core/pull/629 - # the existence of a module/package was checked when creating the - # EditableBuilder. Afterwards, the existence is checked after - # executing the build script (if there is one), - # i.e. during EditableBuilder.build(). - try: - builder = EditableBuilder(self.poetry, self.env, self.io) - except (ModuleOrPackageNotFound, FileNotFoundError) as e: - # This is likely due to the fact that the project is an application - # not following the structure expected by Poetry - # If this is a true error it will be picked up later by build anyway. - self.line_error( - f"The current project could not be installed: {e}\n" - "If you do not want to install the current project" - " use --no-root", - style="warning", - ) - return 0 - log_install = ( "Installing the current project:" f" {self.poetry.package.pretty_name}" @@ -189,7 +170,13 @@ def handle(self) -> int: self.line("") return 0 + # Prior to https://github.com/python-poetry/poetry-core/pull/629 + # the existence of a module/package was checked when creating the + # EditableBuilder. Afterwards, the existence is checked after + # executing the build script (if there is one), + # i.e. during EditableBuilder.build(). try: + builder = EditableBuilder(self.poetry, self.env, self.io) builder.build() except (ModuleOrPackageNotFound, FileNotFoundError) as e: # This is likely due to the fact that the project is an application