feat(install): add --exclude-paths install option#152
Merged
Conversation
Opt-in `install --exclude-paths PATTERN [PATTERN ...]` that drops wheel members matching one or more fnmatch globs before extraction. Intended for RPM packaging to strip test files (pkg/tests/, test_*.py, *_test.py) and similar artifacts shipped inside wheels but unwanted in installed form. Default empty -- byte-identical when the flag isn't set. nargs="+", matching the existing `deps eval --exclude` convention. See for details: docs/designs/exclude_paths_option.md Fixes: #151 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Stanislav Levin <slev@altlinux.org>
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In
install_wheel, the local variable namechainfor the iterator returned byfilter_dist_info/filter_exclude_pathscan be confusing given the common use ofitertools.chain; consider renaming it to something more domain-specific (e.g.member_iter) to improve readability. - The new
--exclude-pathsflag usesnargs='+', which is inherently greedy and can consume the wheel path if it appears after the option; if this proves surprising in practice, you might consider adding an argparse-level constraint or helper (e.g. a custom action or clearer usage error) to defensively guide users toward the intended argument ordering.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `install_wheel`, the local variable name `chain` for the iterator returned by `filter_dist_info`/`filter_exclude_paths` can be confusing given the common use of `itertools.chain`; consider renaming it to something more domain-specific (e.g. `member_iter`) to improve readability.
- The new `--exclude-paths` flag uses `nargs='+'`, which is inherently greedy and can consume the wheel path if it appears after the option; if this proves surprising in practice, you might consider adding an argparse-level constraint or helper (e.g. a custom action or clearer usage error) to defensively guide users toward the intended argument ordering.
## Individual Comments
### Comment 1
<location path="tests/unit/test_main.py" line_range="616-627" />
<code_context>
+ mock_install_wheel.assert_called_once_with(*i_args, **i_kwargs)
+
+
+@pytest.mark.usefixtures("mock_read_tracker")
+def test_install_cli_exclude_paths_requires_value(mock_install_wheel):
+ """
+ --exclude-paths requires at least one value (nargs='+').
+ """
+ install_args = ["install", "--exclude-paths"]
+
+ with pytest.raises(SystemExit):
+ project_main.main(install_args)
+ # actual error message is controlled by cpython,
+ # so it's unreliable to check stderr
+ mock_install_wheel.assert_not_called()
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Strengthen the CLI error test by asserting the SystemExit code
In `test_install_cli_exclude_paths_requires_value`, you can make the test more robust by capturing the exception (`with pytest.raises(SystemExit) as excinfo:`) and asserting `excinfo.value.code == 2`. This keeps the test independent of the error message while still verifying the CLI is treated as an argument error by argparse.
```suggestion
@pytest.mark.usefixtures("mock_read_tracker")
def test_install_cli_exclude_paths_requires_value(mock_install_wheel):
"""
--exclude-paths requires at least one value (nargs='+').
"""
install_args = ["install", "--exclude-paths"]
with pytest.raises(SystemExit) as excinfo:
project_main.main(install_args)
# argparse uses exit code 2 for CLI argument errors
assert excinfo.value.code == 2
# actual error message is controlled by cpython,
# so it's unreliable to check stderr
mock_install_wheel.assert_not_called()
```
</issue_to_address>
### Comment 2
<location path="docs/designs/exclude_paths_option.md" line_range="10-12" />
<code_context>
+but that aren't useful in installed form.
+
+## Motivation
+Some Python projects ship test files (e.g. `pkg/tests/`,
+`test_*.py`, `*_test.py`) inside their wheel. For RPM packaging
+those files:
+
</code_context>
<issue_to_address>
**issue (typo):** Add a comma after "For RPM packaging" for grammatical correctness.
This will read more naturally as: "For RPM packaging, those files:".
```suggestion
Some Python projects ship test files (e.g. `pkg/tests/`,
`test_*.py`, `*_test.py`) inside their wheel. For RPM packaging,
those files:
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Opt-in
install --exclude-paths PATTERN [PATTERN ...]that drops wheel members matching one or more fnmatch globs before extraction. Intended for RPM packaging to strip test files (pkg/tests/, test_*.py, *_test.py) and similar artifacts shipped inside wheels but unwanted in installed form. Default empty -- byte-identical when the flag isn't set. nargs="+", matching the existingdeps eval --excludeconvention.See for details:
docs/designs/exclude_paths_option.md
Fixes: #151
Summary by Sourcery
Add an opt-in install-time path exclusion mechanism to filter wheel contents based on glob patterns before extraction and document its behavior.
New Features:
Enhancements:
Tests: