poetry
Last updated October 25, 2026View source (v0.30.0)
This page explains how Bomly builds a dependency graph for poetry projects: the detector chain it runs, what that chain needs, and what it can report.
| Property | Value |
|---|---|
| Package manager | poetry |
| Ecosystem | python |
| Detector chain | poetry-detector, syft-detector |
| Evidence patterns | poetry.lock, pyproject.toml |
| Ignored directories | __pycache__ |
| Ignored directory markers | pyvenv.cfg |
| Multi-module resolution | No |
| Install-first support | Yes |
| Remediation hints | direct-bump1, transitive-override2 |
| Commands the chain may run | poetry. The Syft fallback is built in; the lite build runs an external syft from PATH instead. |
How poetry resolves
poetry-detector is lockfile-first. A readable poetry.lock is the preferred source because it is deterministic and carries transitive dependency data. Bomly falls back to inspecting a Poetry environment only when a lockfile exists but cannot be parsed.
| Path | Strategy | Command |
|---|---|---|
poetry.lock present | Lockfile parser | None |
| Lockfile unreadable | Locked install and inspect | poetry install --no-root --sync, then poetry run python -m pip inspect --local |
| Lockfile missing | Fail | None |
The inspected graph comes from Poetry's project environment after a locked install. Bomly never inspects an arbitrary ambient Python environment.
The lockfile parser runs nothing and never uses the network. The locked install fallback may download packages from PyPI or configured Poetry sources. It uses the existing lockfile and does not change project manifests. See Network and privacy for the shared rule.
Prerequisites
- A committed
poetry.lock. - A
pyproject.toml, which is the evidence that triggers the detector. - For
--install-first:poetryonPATH.
Examples
Fix a direct vulnerability
Raise the range in pyproject.toml:
[tool.poetry.dependencies]
requests = "^2.32.0"
Re-lock with poetry lock --no-update --regenerate and re-scan.
Pin a transitive vulnerability
Add the transitive package at the top level so the resolver respects your version:
[tool.poetry.dependencies]
urllib3 = ">=2.2.2"
Re-lock and re-scan.
--install-first
With --install-first, Bomly runs poetry install --no-root --sync before resolving the graph. That can download packages from PyPI and writes to the Poetry-managed environment without changing the lockfile.
bomly scan --install-first
To append flags to that command, repeat --install-arg. This requires --detectors poetry-detector. Bomly records the command, with secrets removed, in the scan JSON under the manifest's resolution metadata.
# Production-only graph: skip the dev and docs groups
bomly scan --install-first --detectors poetry-detector \
--install-arg --without --install-arg dev \
--install-arg --without --install-arg docs
Source details
Bomly reads registry, Git, URL, and local-directory sources from each package's source table in poetry.lock. An unrecognized source type stays unknown.
Reachability (experimental)
With --analyze, the pyreach analyzer reports a package as reachable when app source imports it. Unreachable is a triage signal, not proof of safety; see Reachability.
Limitations
- Poetry 1.x and 2.x lockfiles are both supported.
- Optional extras (
requests[socks]) are recorded as one distribution. The extra's own dependencies appear in the lockfile and the graph as usual. - Private indexes (Poetry
sourceconfiguration) need~/.config/pypoetry/auth.tomlset up locally. - No lockfile, no graph. Bomly refuses to inspect an unprepared Poetry environment when
poetry.lockis missing, because that can produce stale or unrelated dependencies.