Skip to content

poetry version throws error Key "source" already exists. when sources are not in order in toml-file #10144

@HenningDinero

Description

@HenningDinero

Description

With a standard .toml file

[tool.poetry]
name = "name"
version = "0"
description = ""
authors = ["Me"]
readme = "README.md"
packages = [{ include = "my_namespace" }]

[tool.poetry.dependencies]
python = "~3.12"
# Dinero

[[tool.poetry.source]]
name = "my_repo"
url = "<some_url>"
priority = "primary"

[[tool.poetry.source]]
name = "PyPI"
priority = "supplemental"

[[tool.poetry.source]]
name = "torch-gpu-linux"
url = "https://download.pytorch.org/whl/cu118/"
priority = "explicit"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

running poetry version "1" works fine.
Now, if you then switch a source to the buttom of the file i.e after [build-system] like

[tool.poetry]
name = "name"
version = "0"
description = ""
authors = ["Me"]
readme = "README.md"
packages = [{ include = "my_namespace" }]

[tool.poetry.dependencies]
python = "~3.12"
# Dinero

[[tool.poetry.source]]
name = "my_repo"
url = "<some_url>"
priority = "primary"

[[tool.poetry.source]]
name = "PyPI"
priority = "supplemental"

[build-system] #  <-- Switched place with `torch-gpu-linux` source
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[[tool.poetry.source]]
name = "torch-gpu-linux"
url = "https://download.pytorch.org/whl/cu118/"
priority = "explicit"

running the same command throws the error Key "source" already exists.

I doubt that is a feature, and if it is, is it possible to get a more correct error? It is extremely difficult to debug on that error, and I discovered it by an accident (copy/pasting gone wrong but turns out right).

Workarounds

Specify all source next to each-other

Poetry Installation Method

pip

Operating System

Darwin

Poetry Version

1.8.5

Poetry Configuration

cache-dir = "/Users/henning/Library/Caches/pypoetry"
experimental.system-git-client = false
installer.max-workers = null
installer.modern-installation = true
installer.no-binary = null
installer.parallel = true
keyring.enabled = true
repositories.my_repo.url = <masked_url>
repositories.torch-gpu-linux.url = "https://download.pytorch.org/whl/cu118/"
solver.lazy-wheel = true
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.no-setuptools = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}/virtualenvs"  # /Users/henning/Library/Caches/pypoetry/virtualenvs
virtualenvs.prefer-active-python = false
virtualenvs.prompt = "{project_name}-py{python_version}"
warnings.export = true

Python Sysconfig

sysconfig.log
Paste the output of 'python -m sysconfig', over this line.

Example pyproject.toml

Poetry Runtime Logs

poetry-runtime.log
poetry version "0" -vvv
Loading configuration file /Users/henning/Library/Application Support/pypoetry/config.toml
Adding repository my_repo (<masked_repo>) and setting it as primary
Adding repository PyPI (https://pypi.org/simple/) and setting it as supplemental
Adding repository torch-gpu-linux (https://download.pytorch.org/whl/cu118) and setting it as explicit
Bumping version from 0 to 0

Stack trace:

13  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/cleo/application.py:327 in run
     325│ 
     326│             try:
   → 327│                 exit_code = self._run(io)
     328│             except BrokenPipeError:
     329│                 # If we are piped to another process, it may close early and send a

12  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/poetry/console/application.py:190 in _run
     188│         self._load_plugins(io)
     189│ 
   → 190│         exit_code: int = super()._run(io)
     191│         return exit_code
     192│ 

11  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/cleo/application.py:431 in _run
     429│             io.input.interactive(interactive)
     430│ 
   → 431│         exit_code = self._run_command(command, io)
     432│         self._running_command = None
     433│ 

10  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/cleo/application.py:473 in _run_command
     471│ 
     472│         if error is not None:
   → 473│             raise error
     474│ 
     475│         return terminate_event.exit_code

 9  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/cleo/application.py:457 in _run_command
     455│ 
     456│             if command_event.command_should_run():
   → 457│                 exit_code = command.run(io)
     458│             else:
     459│                 exit_code = ConsoleCommandEvent.RETURN_CODE_DISABLED

 8  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/cleo/commands/base_command.py:117 in run
     115│         io.input.validate()
     116│ 
   → 117│         return self.execute(io) or 0
     118│ 
     119│     def merge_application_definition(self, merge_args: bool = True) -> None:

 7  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/cleo/commands/command.py:61 in execute
      59│ 
      60│         try:
   →  61│             return self.handle()
      62│         except KeyboardInterrupt:
      63│             return 1

 6  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/poetry/console/commands/version.py:79 in handle
      77│             if not self.option("dry-run"):
      78│                 content: dict[str, Any] = self.poetry.file.read()
   →  79│                 poetry_content = content["tool"]["poetry"]
      80│                 poetry_content["version"] = version.text
      81│ 

 5  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/tomlkit/container.py:831 in __getitem__
     829│ 
     830│     def __getitem__(self, key: Key | str) -> Any:
   → 831│         if key not in self._internal_container:
     832│             raise NonExistentKey(key)
     833│ 

 4  <frozen _collections_abc>:813 in __contains__

 3  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/tomlkit/container.py:622 in __getitem__
     620│     # Dictionary methods
     621│     def __getitem__(self, key: Key | str) -> Item | Container:
   → 622│         item = self.item(key)
     623│         if isinstance(item, Item) and item.is_boolean():
     624│             return item.value

 2  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/tomlkit/container.py:470 in item
     468│             # so we need a proxy to retrieve the proper objects
     469│             # from the parent container
   → 470│             return OutOfOrderTableProxy(self, idx)
     471│ 
     472│         return self._body[idx][1]

 1  ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/tomlkit/container.py:816 in __init__
     814│                 table_idx = len(self._tables) - 1
     815│                 for k, v in item.value.body:
   → 816│                     self._internal_container._raw_append(k, v)
     817│                     self._tables_map.setdefault(k, []).append(table_idx)
     818│                     if k is not None:

KeyAlreadyPresent

Key "source" already exists.

at ~/.pyenv/versions/3.12.2/lib/python3.12/site-packages/tomlkit/container.py:313 in _raw_append
    309│                 current_idx = (current_idx,)
    310│ 
    311│             current = self._body[current_idx[-1]][1]
    312│             if key is not None and not isinstance(current, Table):
  → 313│                 raise KeyAlreadyPresent(key)
    314│ 
    315│             self._map[key] = (*current_idx, len(self._body))
    316│         elif key is not None:
    317│             self._map[key] = len(self._body)

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugSomething isn't working as expectedstatus/triageThis issue needs to be triaged

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions