Skip to content

poetry remove crashes when removing a package from a legacy dependency group (PEP 735) containing include-group #10586

@Wellshh

Description

@Wellshh

Description

When attempting to remove a package from a dependency group that is defined using the PEP 735 format, the poetry remove command crashes and throws AttributeError: 'InlineTable' object has no attribute 'split' if nested group is used (the groups's dependency list contains { include-group = "..."} ), which is supported for Poetry 2.2.1: Including dependencies from other groups.

Analysis

The root cause appears to be in the implementation of the remove command. When processing a dependency group defined under the legacy [dependency-groups] key, the code iterates through a list that can contain mixed types (package strings and include-group tables). The command's logic does not filter out the non-string table objects before passing them to Dependency.create_from_pep_508, which expects a string.

Workarounds

May use the poetry style of nested poetry group:

[tool.poetry.group.test.dependencies]
pytest = "^8.0.0"

[tool.poetry.group.lint.dependencies]
ruff = "^0.11"

[tool.poetry.group.dev]
include-groups = [
    "test",
    "lint",
]

Poetry Installation Method

pipx

Operating System

MacOS Tahoe 26.0.1

Poetry Version

Poetry (version 2.2.1)

Poetry Configuration

cache-dir = "/Users/wells/Library/Caches/pypoetry"
data-dir = "/Users/wells/Library/Application Support/pypoetry"
installer.max-workers = null
installer.no-binary = null
installer.only-binary = null
installer.parallel = true
installer.re-resolve = true
keyring.enabled = true
python.installation-dir = "{data-dir}/python"  # /Users/wells/Library/Application Support/pypoetry/python
requests.max-retries = 0
solver.lazy-wheel = true
system-git-client = false
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}/virtualenvs"  # /Users/wells/Library/Caches/pypoetry/virtualenvs
virtualenvs.prompt = "{project_name}-py{python_version}"
virtualenvs.use-poetry-python = false

Python Sysconfig

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

Example pyproject.toml

[project]
name = "xx"
version = "0.1.1"
description = "This is the recommendation engine."
requires-python = ">=3.12"
dynamic = [ "readme" ]
dependencies = [
    "redis (>=6.4.0,<7.0.0)",
    "fastapi (>=0.119.0,<0.120.0)"
]

[dependency-groups]
lint = [
    "mypy",
]
test = [
    "pytest",
]
dev = [
    { include-group = "lint" }, 
    { include-group = "test" },
    "requests"
]

[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.mypy]
ignore_missing_imports = true
disallow_untyped_defs = true
check_untyped_defs = true
strict_equality = true
enable_error_code='explicit-override'

[tool.poetry]
package-mode = false
readme = ["docs/README.rst"]

Poetry Runtime Logs

poetry-runtime.log
Stack trace:

10  ~/.local/pipx/venvs/poetry/lib/python3.14/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

 9  ~/.local/pipx/venvs/poetry/lib/python3.14/site-packages/poetry/console/application.py:260 in _run
     258│ 
     259│             try:
   → 260│                 exit_code = super()._run(io)
     261│             except PoetryRuntimeError as e:
     262│                 io.write_error_line("")

 8  ~/.local/pipx/venvs/poetry/lib/python3.14/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│ 

 7  ~/.local/pipx/venvs/poetry/lib/python3.14/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

 6  ~/.local/pipx/venvs/poetry/lib/python3.14/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

 5  ~/.local/pipx/venvs/poetry/lib/python3.14/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:

 4  ~/.local/pipx/venvs/poetry/lib/python3.14/site-packages/poetry/console/commands/installer_command.py:39 in execute
      37│     def execute(self, io: IO) -> int:
      38│         PoetryKeyring.preflight_check(io, self.poetry.config)
   →  39│         return super().execute(io)
      40│ 

 3  ~/.local/pipx/venvs/poetry/lib/python3.14/site-packages/cleo/commands/command.py:61 in execute
      59│ 
      60│         try:
   →  61│             return self.handle()
      62│         except KeyboardInterrupt:
      63│             return 1

 2  ~/.local/pipx/venvs/poetry/lib/python3.14/site-packages/poetry/console/commands/remove.py:96 in handle
      94│ 
      95│             for group_name, standard_section, poetry_section in group_sections:
   →  96│                 removed |= self._remove_packages(
      97│                     packages=packages,
      98│                     standard_section=standard_section,

 1  ~/.local/pipx/venvs/poetry/lib/python3.14/site-packages/poetry/console/commands/remove.py:187 in _remove_packages
     185│             normalized_name = canonicalize_name(package)
     186│             for requirement in standard_section.copy():
   → 187│                 if Dependency.create_from_pep_508(requirement).name == normalized_name:
     188│                     standard_section.remove(requirement)
     189│                     removed.add(package)

AttributeError

'InlineTable' object has no attribute 'split'

at ~/.local/pipx/venvs/poetry/lib/python3.14/site-packages/poetry/core/packages/dependency.py:363 in create_from_pep_508
    359│         from poetry.core.vcs.git import ParsedUrl
    360│         from poetry.core.version.requirements import parse_requirement
    361│ 
    362│         # Removing comments
  → 363│         parts = name.split(" #", 1)
    364│         name = parts[0].strip()
    365│         if len(parts) > 1:
    366│             rest = parts[1]
    367│             if " ;" in rest:

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/cliRelated to the command linekind/bugSomething isn't working as expected

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions