From 1a5c2bebfdf4e51c7801a9ab7d2f2f153bbe80bc Mon Sep 17 00:00:00 2001 From: finswimmer Date: Tue, 18 Oct 2022 18:05:43 +0200 Subject: [PATCH] fix: ensure no duplicate package names are stored in pyproject.toml --- src/poetry/console/commands/add.py | 5 ++++ tests/console/commands/test_add.py | 48 ++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/poetry/console/commands/add.py b/src/poetry/console/commands/add.py index 6a0c38f9f23..08e9e5613bf 100644 --- a/src/poetry/console/commands/add.py +++ b/src/poetry/console/commands/add.py @@ -215,6 +215,11 @@ def handle(self) -> int: constraint_name = _constraint["name"] assert isinstance(constraint_name, str) + + for key in list(section.keys()): + if canonicalize_name(key) == canonicalize_name(constraint_name): + del section[key] + section[constraint_name] = constraint with contextlib.suppress(ValueError): diff --git a/tests/console/commands/test_add.py b/tests/console/commands/test_add.py index ff34c4f8b20..a2f41ec2966 100644 --- a/tests/console/commands/test_add.py +++ b/tests/console/commands/test_add.py @@ -43,6 +43,18 @@ def poetry_with_up_to_date_lockfile( ) +@pytest.fixture +def poetry_sample_project( + project_factory: ProjectFactory, fixture_dir: FixtureDirGetter +) -> Poetry: + source = fixture_dir("sample_project") + + return project_factory( + name="my-package", + pyproject_content=(source / "pyproject.toml").read_text(encoding="utf-8"), + ) + + @pytest.fixture() def tester(command_tester_factory: CommandTesterFactory) -> CommandTester: return command_tester_factory("add") @@ -1055,6 +1067,42 @@ def test_add_should_skip_when_adding_canonicalized_existing_package_with_no_cons assert expected in tester.io.fetch_output() +def test_add_should_replace_non_canonicalized_package( + project_factory: ProjectFactory, + repo: TestRepository, + command_tester_factory: CommandTesterFactory, +): + pyproject_content = """\ + [tool.poetry] + name = "simple-project" + version = "1.2.3" + description = "Some description." + authors = [ + "Python Poetry " + ] + license = "MIT" + readme = "README.rst" + + [tool.poetry.dependencies] + python = "^3.6" + Foo = "^0.6" + """ + + poetry = project_factory(name="simple-project", pyproject_content=pyproject_content) + content = poetry.file.read() + + assert "Foo" in content["tool"]["poetry"]["dependencies"] + assert "foo" not in content["tool"]["poetry"]["dependencies"] + + tester = command_tester_factory("add", poetry=poetry) + repo.add_package(get_package("foo", "1.1.2")) + tester.execute("foo@latest") + + updated_content = poetry.file.read() + assert "Foo" not in updated_content["tool"]["poetry"]["dependencies"] + assert "foo" in updated_content["tool"]["poetry"]["dependencies"] + + def test_add_should_work_when_adding_existing_package_with_latest_constraint( app: PoetryTestApplication, repo: TestRepository, tester: CommandTester ):