python-poetry / python-poetry/poetry
Poetry can get locked into an unusable state with plugins: 'The command "..." already exists'
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 34.3k
- Forks
- 2.5k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 30
Description
- I am on the latest Poetry version.
- I have searched the issues of this repo and believe that this is not a duplicate.
- If an exception occurs when executing a command, I executed it again in debug mode (
-vvvoption).
- OS version and name: Windows 11
- Poetry version: 1.2.0
- Link of a Gist with the contents of your pyproject.toml file: N/A
Issue
If plugins with conflicting commands are installed, Poetry gets locked into an unusable state where even --help fails, and there's no way to recover unless you manually activate Poetry's internal venv and remove the plugins. Someone reported this to me because I had a plugin called poetry-dynamic-versioning-plugin that I've since deprecated and merged into poetry-dynamic-versioning[plugin]. If you still have the deprecated one installed and then install the newly updated one, it breaks Poetry.
$ poetry self add poetry-dynamic-versioning-plugin
Using version ^0.4.0 for poetry-dynamic-versioning-plugin
Updating dependencies
Resolving dependencies... (0.5s)
Writing lock file
Package operations: 4 installs, 0 updates, 0 removals
• Installing markupsafe (2.1.1)
• Installing dunamai (1.13.0)
• Installing jinja2 (3.1.2)
• Installing poetry-dynamic-versioning-plugin (0.4.0)
$ poetry self add poetry-dynamic-versioning[plugin]
Using version ^0.18.0 for poetry-dynamic-versioning
Updating dependencies
Resolving dependencies... (0.2s)
Writing lock file
Package operations: 1 install, 0 updates, 0 removals
• Installing poetry-dynamic-versioning (0.18.0)
$ poetry --help
The command "dynamic-versioning" already exists.
With debug mode:
$ poetry --help -vvv
Stack trace:
5 ~\.local\pipx\venvs\poetry\lib\site-packages\cleo\application.py:329 in run
327│
328│ try:
→ 329│ exit_code = self._run(io)
330│ except Exception as e:
331│ if not self._catch_exceptions:
4 ~\.local\pipx\venvs\poetry\lib\site-packages\poetry\console\application.py:183 in _run
181│ self._disable_cache = io.input.has_parameter_option("--no-cache")
182│
→ 183│ self._load_plugins(io)
184│
185│ exit_code: int = super()._run(io)
3 ~\.local\pipx\venvs\poetry\lib\site-packages\poetry\console\application.py:349 in _load_plugins
347│ manager = PluginManager(ApplicationPlugin.group)
348│ manager.load_plugins()
→ 349│ manager.activate(self)
350│
351│ self._plugins_loaded = True
2 ~\.local\pipx\venvs\poetry\lib\site-packages\poetry\plugins\plugin_manager.py:71 in activate
69│ def activate(self, *args: Any, **kwargs: Any) -> None:
70│ for plugin in self._plugins:
→ 71│ plugin.activate(*args, **kwargs)
72│
73│ def _load_plugin_entry_point(self, ep: metadata.EntryPoint) -> None:
1 ~\.local\pipx\venvs\poetry\lib\site-packages\poetry_dynamic_versioning\plugin.py:93 in activate
91│ self._application = application
92│
→ 93│ application.command_loader.register_factory(
94│ "dynamic-versioning", lambda: DynamicVersioningCommand(application)
95│ )
LogicException
The command "dynamic-versioning" already exists.
at ~\.local\pipx\venvs\poetry\lib\site-packages\poetry\console\command_loader.py:20 in register_factory
16│ def register_factory(
17│ self, command_name: str, factory: Callable[[], Command]
18│ ) -> None:
19│ if command_name in self._factories:
→ 20│ raise LogicException(f'The command "{command_name}" already exists.')
21│
22│ self._factories[command_name] = factory
23│
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the conflicting-plugin case with the two poetry self add commands, then read poetry/console/application.py, poetry/plugins/plugin_manager.py, and cleo's command_loader.py at the stack-trace entry points. Done means Poetry can recover from conflicting plugin commands instead of making even --help fail.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100