diff --git a/src/poetry/console/commands/add.py b/src/poetry/console/commands/add.py index 6a0c38f9f23..549c895ca98 100644 --- a/src/poetry/console/commands/add.py +++ b/src/poetry/console/commands/add.py @@ -215,7 +215,15 @@ def handle(self) -> int: constraint_name = _constraint["name"] assert isinstance(constraint_name, str) - section[constraint_name] = constraint + + canonical_constraint_name = canonicalize_name(constraint_name) + + for key in section: + if canonicalize_name(key) == canonical_constraint_name: + section[key] = constraint + break + else: + section[constraint_name] = constraint with contextlib.suppress(ValueError): self.poetry.package.dependency_group(group).remove_dependency( diff --git a/tests/console/commands/test_add.py b/tests/console/commands/test_add.py index ff34c4f8b20..9bc238aeb7a 100644 --- a/tests/console/commands/test_add.py +++ b/tests/console/commands/test_add.py @@ -1055,6 +1055,44 @@ def test_add_should_skip_when_adding_canonicalized_existing_package_with_no_cons assert expected in tester.io.fetch_output() +def test_add_latest_should_not_create_duplicate_keys( + 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.md" + + [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 content["tool"]["poetry"]["dependencies"]["Foo"] == "^0.6" + 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" in updated_content["tool"]["poetry"]["dependencies"] + assert updated_content["tool"]["poetry"]["dependencies"]["Foo"] == "^1.1.2" + assert "foo" not in updated_content["tool"]["poetry"]["dependencies"] + + def test_add_should_work_when_adding_existing_package_with_latest_constraint( app: PoetryTestApplication, repo: TestRepository, tester: CommandTester ):