Skip to content

feat(supply_chain): scan tool-specific pyproject.toml dependency tables (Poetry/PDM/Hatch/uv)#190

Open
Shrotriya-lalit wants to merge 1 commit into
NVIDIA:mainfrom
Shrotriya-lalit:fix/issue-171-pyproject-tool-table-deps
Open

feat(supply_chain): scan tool-specific pyproject.toml dependency tables (Poetry/PDM/Hatch/uv)#190
Shrotriya-lalit wants to merge 1 commit into
NVIDIA:mainfrom
Shrotriya-lalit:fix/issue-171-pyproject-tool-table-deps

Conversation

@Shrotriya-lalit

Copy link
Copy Markdown
Contributor

Problem

_extract_packages_from_pyproject only read the PEP 621 [project] tables and PEP 735 [dependency-groups]. Projects using Poetry, PDM, Hatch, or uv declare their dependencies in [tool.*] tables that were silently skipped, producing false negatives in the supply-chain analyzer.

Committed to in the PR #95 discussion: "I'll open a follow-up issue to track this... the tool-table coverage can land as an incremental improvement."

Closes #171

Changes

src/skillspector/nodes/analyzers/static_patterns_supply_chain.py

Extended _extract_packages_from_pyproject to also read:

Table Tool
[tool.poetry.dependencies] Poetry (runtime)
[tool.poetry.dev-dependencies] Poetry (dev, legacy)
[tool.poetry.group.<name>.dependencies] Poetry (new-style groups)
[tool.pdm.dev-dependencies] PDM
[tool.hatch.envs.<name>.dependencies] Hatch (per-environment)
[tool.uv.dev-dependencies] uv

Poetry's special python key (interpreter constraint, not a package) is excluded. All non-dependency tool config sections ([tool.black], [tool.mypy], etc.) are unaffected.

tests/unit/test_patterns_new.py

Six new tests:

  • test_pyproject_poetry_deps_extracted[tool.poetry.dependencies] + [tool.poetry.dev-dependencies], confirms python key excluded
  • test_pyproject_poetry_groups_extracted[tool.poetry.group.<name>.dependencies]
  • test_pyproject_pdm_dev_deps_extracted[tool.pdm.dev-dependencies] groups
  • test_pyproject_hatch_env_deps_extracted[tool.hatch.envs.<name>.dependencies] per-env lists
  • test_pyproject_uv_dev_deps_extracted[tool.uv] dev-dependencies list
  • test_pyproject_tool_tables_no_false_positives_on_config_keys — pure config sections produce no findings

Test results

191 tests in test_patterns_new.py pass. Full suite: 932 passed, 12 skipped, 6 xfailed.

Poetry, PDM, Hatch, and uv each declare dependencies in their own
[tool.*] tables. Before this change those tables were silently skipped,
producing false negatives for projects that use any of these build
tools — the most common case in modern Python projects.

Add parsing for:
- [tool.poetry.dependencies] / [tool.poetry.dev-dependencies]
- [tool.poetry.group.<name>.dependencies]  (new-style Poetry groups)
- [tool.pdm.dev-dependencies]
- [tool.hatch.envs.<name>.dependencies]
- [tool.uv.dev-dependencies]

Poetry's special "python" key is excluded (it constrains the
interpreter, not a package). All other tool config sections (e.g.
[tool.black], [tool.mypy]) are unaffected.

Closes NVIDIA#171

Signed-off-by: Lalit Shrotriya <shrotriya.lalit@outlook.com>
table = poetry.get(table_name)
if isinstance(table, dict):
specs.extend(
pkg for pkg in table if isinstance(pkg, str) and pkg != "python"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Automated SkillSpector Review]

Non-blocking: only the Poetry dependency name (the table key) is collected here; the version constraint (the value, e.g. "^2.28" or {version = "..."}) is dropped, so SC-rules that key off versions can't evaluate Poetry-declared deps. The PEP 508 paths (PDM/Hatch/uv) retain versions. Fine as a follow-up.

@rng1995 rng1995 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Automated SkillSpector Review]

Approved.

Closes a real supply-chain false-negative gap: dependencies declared in tool-specific tables (Poetry, PDM, Hatch, uv) were silently skipped and are now extracted. The parsing is defensive throughout (isinstance guards at every level), excludes Poetry's python interpreter key, and the 6 tests include a no-false-positive check for pure [tool.black]/[tool.mypy] config sections.

Non-blocking: for Poetry tables only the package name (dict key) is captured, so the version constraint (the value) is dropped and version-based vuln matching won't apply to Poetry-declared deps. PEP 508 strings (PDM/Hatch/uv) keep their versions. Worth a follow-up if version-aware checks matter for Poetry projects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants