fix: skip marker-constrained uninstalled packages in Python requirements#459
fix: skip marker-constrained uninstalled packages in Python requirements#459ruromero wants to merge 1 commit intoguacsec:mainfrom
Conversation
When a requirements.txt contains packages with PEP 508 environment markers (e.g., `pywin32==306 ; platform_system == "Windows"`), pip only installs packages whose markers match the current platform. Previously, the JavaScript client scanned ALL packages from the manifest regardless of markers, throwing an error when a marker- constrained package was not installed. This fix uses tree-sitter to detect `marker_spec` nodes on each requirement and skips packages that have a marker but are absent from the installed packages cache (`pip freeze`). Packages with markers that ARE installed are still included in the SBOM. Implements TC-4043 Assisted-by: Claude Code Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Review Summary by QodoSkip marker-constrained uninstalled packages in Python requirements
WalkthroughsDescription• Skip PEP 508 marker-constrained uninstalled packages in Python requirements • Detect environment markers using tree-sitter marker_spec nodes • Check installed packages cache before processing requirements • Add comprehensive test suite for marker handling with mocked pip output Diagramflowchart LR
A["requirements.txt with markers"] -->|tree-sitter parse| B["Detect marker_spec nodes"]
B -->|hasMarker flag| C["Check pip freeze cache"]
C -->|marker + not installed| D["Skip package"]
C -->|marker + installed| E["Include in SBOM"]
C -->|no marker| E
File Changes1. src/providers/python_controller.js
|
Code Review by Qodo
|
| if(hasMarker && CachedEnvironmentDeps[depName.toLowerCase()] === undefined) { | ||
| return | ||
| } |
There was a problem hiding this comment.
1. Skips required marker deps 🐞 Bug ≡ Correctness
In Python_controller#getDependenciesImpl, any requirement with a marker is silently skipped when not found in the installed-packages cache, without evaluating whether the marker expression is false for the current environment. This can drop required dependencies (marker evaluates true but package is missing) and produce an incomplete SBOM instead of failing fast.
Agent Prompt
### Issue description
Marker-constrained requirements are skipped solely based on absence from the installed package cache (`pip show`/`pipdeptree`), but the code never checks whether the marker actually evaluates to `false` for the current environment. This can silently omit dependencies that should apply (marker evaluates `true`) but are missing due to an incomplete/broken environment.
### Issue Context
- `#parseRequirements()` currently returns `{ name, version, hasMarker }`, but not the marker expression.
- `#getDependenciesImpl()` uses `hasMarker && notInstalled => return`.
### Fix Focus Areas
- src/providers/python_controller.js[98-114]
- src/providers/python_controller.js[228-246]
### Suggested fix
1. Extend `#parseRequirements()` to also return the marker text (e.g., locate the `marker_spec` child node and capture its `.text`).
2. When `hasMarker && notInstalled`, evaluate the marker against the current environment and:
- If marker evaluates **false**: skip (current intended behavior).
- If marker evaluates **true**: keep current behavior for missing deps (error out via existing flow), so SBOM isn’t silently incomplete.
3. If marker evaluation cannot be performed (e.g., missing evaluator), fail closed (do not skip) or gate skipping behind an explicit option.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Summary
pywin32==306 ; platform_system == "Windows") that are not installed because the marker didn't match are now silently skipped instead of throwing an errorDetails
Uses tree-sitter
marker_specnode detection in#parseRequirements()and checks against the installed packages cache (pip freeze) before processing each requirement. The fix follows the same decision logic as pip itself: if a package has a marker and pip didn't install it, skip it.Implements TC-4043
Test plan
pip freeze/pip showoutput🤖 Generated with Claude Code