Skip to content

Comments

feat(python): add pylock.toml support#10137

Open
DmitriyLewen wants to merge 11 commits intoaquasecurity:mainfrom
DmitriyLewen:feat/pylock-analyzer
Open

feat(python): add pylock.toml support#10137
DmitriyLewen wants to merge 11 commits intoaquasecurity:mainfrom
DmitriyLewen:feat/pylock-analyzer

Conversation

@DmitriyLewen
Copy link
Contributor

@DmitriyLewen DmitriyLewen commented Feb 4, 2026

Description

Add support for pylock.toml (PEP 751) lock file format.
This PR implements:

  • New pylock analyzer that works in fs and repo modes
  • PyLock LangType and TypePyLock analyzer type constants
  • PURL mapping for pylock packages (mapped to PyPi)
  • detector mapping for pylock type
  • Integration test with vulnerability detection
  • Documentation update for Python page

Changes

  • pkg/fanal/types/const.go: Add PyLock LangType and rename filename constant to PyLockFile
  • pkg/fanal/analyzer/const.go: Add TypePyLock analyzer type and update slices
  • pkg/fanal/analyzer/language/python/pylock/: New pylock analyzer package
  • pkg/dependency/parser/python/pylock/parse.go: Update parser to accept context parameter
  • pkg/purl/purl.go: Add PyLock to PyPi type mapping
  • integration/: Add integration test for pylock
  • docs/guide/coverage/language/python.md: Add pylock documentation

Example

➜ ./trivy -q fs pylock.toml  --table-mode summary

Report Summary

┌─────────────┬────────┬─────────────────┬─────────┐
│   Target    │  Type  │ Vulnerabilities │ Secrets │
├─────────────┼────────┼─────────────────┼─────────┤
│ pylock.toml │ pylock │       12        │    -    │
└─────────────┴────────┴─────────────────┴─────────┘

Related issues

Related PRs

Checklist

  • I've read the guidelines for contributing to this repository.
  • I've followed the conventions in the PR title.
  • I've added tests that prove my fix is effective or that my feature works.
  • I've updated the documentation with the relevant information (if needed).
  • I've added usage information (if the PR introduces new options)
  • I've included a "before" and "after" example to the description (if the PR is a user interface change).

Add support for pylock.toml (PEP 751) lock file format.

- Add PyLock LangType and TypePyLock analyzer type
- Add pylock analyzer for fs and repo modes
- Update parser to accept context parameter
- Update purl package to map PyLock to PyPi
- Add integration test and documentation
@github-actions github-actions bot added the apidiff Indicates Go API changes relevant to library consumers (CLI compatibility may be unaffected) label Feb 4, 2026
@aqua-bot aqua-bot requested a review from a team February 4, 2026 11:09
@DmitriyLewen DmitriyLewen self-assigned this Feb 4, 2026
@aquasecurity aquasecurity deleted a comment from github-actions bot Feb 4, 2026
@DmitriyLewen DmitriyLewen removed the request for review from a team February 4, 2026 11:36
@DmitriyLewen DmitriyLewen added autoready Automatically mark PR as ready for review when all checks pass and removed apidiff Indicates Go API changes relevant to library consumers (CLI compatibility may be unaffected) labels Feb 4, 2026
@github-actions github-actions bot added the apidiff Indicates Go API changes relevant to library consumers (CLI compatibility may be unaffected) label Feb 4, 2026
@aqua-bot aqua-bot requested a review from a team February 4, 2026 12:07
@github-actions github-actions bot marked this pull request as ready for review February 4, 2026 12:26
@github-actions github-actions bot requested a review from knqyf263 as a code owner February 4, 2026 12:26
@github-actions github-actions bot removed the autoready Automatically mark PR as ready for review when all checks pass label Feb 4, 2026
@aquasecurity aquasecurity deleted a comment from github-actions bot Feb 5, 2026
@DmitriyLewen DmitriyLewen removed the request for review from a team February 5, 2026 05:47

type pylockAnalyzer struct{}

func (a pylockAnalyzer) Analyze(ctx context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

PEP 751 states that pylock.toml should be placed alongside pyproject.toml:

The lock file(s) SHOULD be located in the directory as appropriate for the scope of the lock file. Locking against a single pyproject.toml, for instance, would place the pylock.toml in the same directory.

Don't we need to parse pyproject.toml (e.g., [project.dependencies]) to determine direct vs indirect dependencies, similar to how the poetry analyzer does it? If so, this would need to be a PostAnalyzer instead of a simple Analyzer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I initially added the analyzer only for pylock.toml, but it makes sense to support pyproject.toml as well.
Added in 2ad6402

}

func (a pylockAnalyzer) Required(filePath string, _ os.FileInfo) bool {
return filepath.Base(filePath) == types.PyLockFile
Copy link
Collaborator

Choose a reason for hiding this comment

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

PEP 751 defines that a lock file must be named pylock.toml or match the regex r"^pylock\.([^.]+)\.toml$" (e.g., pylock.linux.toml, pylock.prod.toml). Do we need to handle the pylock.<IDENTIFIER>.toml pattern as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch!
Added d6ce02c.

I don't think it makes sense to use the regex from PEP 751.
I only added a check for the prefix and suffix.
I believe this should be sufficient for our case.

PEP 751 allows lock files to be named pylock.toml or
pylock.<identifier>.toml (e.g., pylock.linux.toml, pylock.prod.toml).
Prepare for pyproject.toml integration to identify direct/indirect
dependencies, similar to how poetry analyzer works.
Parse pyproject.toml alongside pylock.toml to identify direct vs
indirect dependencies using [project.dependencies] (PEP 621).
@aqua-bot aqua-bot requested a review from a team February 18, 2026 09:41
@aquasecurity aquasecurity deleted a comment from github-actions bot Feb 18, 2026
@DmitriyLewen DmitriyLewen removed the request for review from a team February 18, 2026 09:47
@DmitriyLewen DmitriyLewen removed the apidiff Indicates Go API changes relevant to library consumers (CLI compatibility may be unaffected) label Feb 18, 2026
func (a pylockAnalyzer) matchLockFile(filePath string) bool {
// Match pylock.toml or pylock.<identifier>.toml (PEP 751)
base := filepath.Base(filePath)
return strings.HasPrefix(base, "pylock.") && strings.HasSuffix(base, ".toml")
Copy link
Collaborator

Choose a reason for hiding this comment

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

PEP 751 defines the regex r"^pylock\.([^.]+)\.toml$" for named lock files, where the identifier must NOT contain dots ([^.]+). The current HasPrefix/HasSuffix approach is more permissive and would also match files like pylock.linux.arm64.toml, which is technically not valid per the spec. Is this intentional, or should we use a stricter regex match?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is an intentional trade-off. I prefer to avoid regex unless absolutely necessary, especially in a hot path like this (checking every scanned file).

I think we can afford to be lenient here. The likelihood of encountering a file with a dot in the identifier (e.g., pylock.linux.arm64.toml) is extremely low. Even if we do find such a file:

  • We scan it successfully. The user likely ignored the PEP 751 naming convention, but I don't think it's Trivy's job to enforce that.
  • If the file is invalid for some reason, we will simply show a debug log.

Copy link
Collaborator

Choose a reason for hiding this comment

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

At the very least, we should state that detecting files that violate PEP 751 is the intended behavior. Otherwise, it just looks like a bug. Even looking at the tests, they simply expect true, which also makes it look like dots are allowed in PEP 751.

		{
			name:     "named lock file with dots in identifier",
			filePath: "pylock.linux.arm64.toml",
			want:     true,
		},

Copy link
Contributor Author

@DmitriyLewen DmitriyLewen Feb 19, 2026

Choose a reason for hiding this comment

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

I don't know what I was thinking yesterday 😄 .
I realized I can simply check that there is no dot in the identifier.

Updated the logic in 57006f5

return xerrors.Errorf("unable to parse %s: %w", path, err)
}

directDeps := p.MainDeps()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we also mark dev dependencies (i.e., set Dev: true) here? The poetry analyzer identifies production dependencies by traversing the dependency graph from MainDeps(), and marks packages not reachable from that graph as Dev: true. A similar approach could work here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

make sense. Thanks!

Added in 42a8506

Traverse the dependency graph from production dependencies defined in
pyproject.toml [project.dependencies] to identify dev packages.
Packages not reachable from production roots are marked with Dev: true.
@github-actions github-actions bot added the apidiff Indicates Go API changes relevant to library consumers (CLI compatibility may be unaffected) label Feb 19, 2026
@aqua-bot aqua-bot requested a review from a team February 19, 2026 06:08
@aquasecurity aquasecurity deleted a comment from github-actions bot Feb 19, 2026
@DmitriyLewen DmitriyLewen removed the request for review from a team February 19, 2026 06:18
Use strict regex matching per PEP 751 specification:
^pylock\.([^.]+)\.toml$ - identifier cannot contain dots.

Also update documentation with pylock features.
@aqua-bot aqua-bot requested a review from a team February 19, 2026 06:32
@DmitriyLewen DmitriyLewen removed the request for review from a team February 19, 2026 06:33
@DmitriyLewen DmitriyLewen removed the apidiff Indicates Go API changes relevant to library consumers (CLI compatibility may be unaffected) label Feb 19, 2026
@aquasecurity aquasecurity deleted a comment from github-actions bot Feb 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for pylock.toml (PEP 751)

2 participants