Skip to content

bug(python): pylock.toml dependencies without a version are dropped from the dependency graph #11411

Open
vincntlaw/trivy
#1

Description

@DmitriyLewen

Description

When a dependency in [[packages.dependencies]] of pylock.toml (PEP 751) is specified by name only, e.g. { name = "beta" }, Trivy silently drops it from the dependency graph.
As a result, the SBOM (CycloneDX dependsOn, SPDX relationships) is incomplete, and the package shows up directly under pylock.toml instead of under its parent.
Vulnerability detection is not affected.

Reproduced on v0.75.0 and main:

mkdir pylock-name-only && cd pylock-name-only
cat > pylock.toml <<'EOF'
lock-version = "1.0"
created-by = "minimal-reproducer"

[[packages]]
name = "alpha"
version = "1.0.0"
dependencies = [{ name = "beta" }]

[[packages]]
name = "beta"
version = "2.0.0"
EOF
trivy fs --format cyclonedx --output bom.json .
jq -c '.dependencies[]' bom.json

alpha@1.0.0 is expected to depend on beta@2.0.0, but its dependsOn is empty.
If the selector is changed to { name = "beta", version = "2.0.0" }, the relationship appears.

Such lock files are produced by real tools, e.g. Pex (see test_issue_2877.py).

Discussed in #11402

Root cause

PEP 751 allows [[packages.dependencies]] to contain only the minimum set of keys that identifies the [[packages]] entry unambiguously (packages.dependencies).
If there is only one package with that name in the lock file, version can be omitted.

Parse() in pkg/dependency/parser/python/pylock/parse.go builds the dependency ID from name and version.
For { name = "beta" } the ID is beta, while the package is stored under beta@2.0.0.
The dependency is then discarded by the "Filter out dependencies that are not in the package list" filter, without any log message.

Implementation challenges

1. Ambiguous selectors

A single pylock.toml can contain several entries with the same name, e.g. different versions for different environments (marker).
In that case a name-only selector is ambiguous, and picking one of the entries arbitrarily is not an option.
PEP 751 also allows an entry to be narrowed down by other keys (e.g. vcs), which Trivy doesn't read at the moment.

2. Cache

Analyzer results are cached.
Without bumping version in pkg/fanal/analyzer/language/python/pylock/pylock.go, users keep cached results without these dependencies, and the fix will look like it doesn't work.

3. Tests

All dependencies in pkg/dependency/parser/python/pylock/testdata/pylock.toml currently have a version, so this case isn't covered by tests.
It should be checked whether the golden file of the integration test integration/testdata/pylock.json.golden changes.

Before implementation

Before implementing, the approach should be discussed and agreed on in this issue, and only then should the implementation start.

Activity

  1. added
    kind/bugCategorizes issue or PR as related to a bug.
    help wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.
    good first issueDenotes an issue ready for a new contributor, according to the "help wanted" guidelines.
    scan/vulnerabilityIssues relating to vulnerability scanning
    on Oct 14, 2026
  2. ozenyunus35 commented on Oct 14, 2026

    @ozenyunus35

    Hi @DmitriyLewen, I'd like to pick this up. Here's the approach I have in mind:

    • In Parse(), first collect the package IDs for each normalized name. For a dependency with a version, nothing changes.
    • For a dependency without a version: if exactly one package has that name, use its ID. If there are several (e.g. different versions per marker) or none, skip it and log at debug level why, instead of dropping it silently. Since Trivy doesn't read marker/vcs, it won't try to pick one of several entries.
    • Bump version in pkg/fanal/analyzer/language/python/pylock/pylock.go to 2, so cached results are refreshed.
    • Tests: a new testdata/name-only.toml with a name-only dependency (resolved), an ambiguous one with two versions (skipped) and an unknown one (skipped). The integration fixture's dependencies all have a version, so pylock.json.golden doesn't change.

    Does that sound good? I have it ready and can open a PR once you're OK with it.

  3. DmitriyLewen commented on Oct 15, 2026

    @DmitriyLewen
    ContributorAuthor

    Hello @ozenyunus35.
    Thanks for your interest in working on this issue.

    The plan looks good.
    I'm assigning the issue to you.

    We are currently busy with higher-priority tasks, so the review may take some time.
    Thanks for your understanding and patience.

    Regards, Dmitriy

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

Metadata

Metadata

Assignees

Labels

good first issueDenotes an issue ready for a new contributor, according to the "help wanted" guidelines.help wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.kind/bugCategorizes issue or PR as related to a bug.scan/vulnerabilityIssues relating to vulnerability scanning

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions