Skip to content

fix: forward py7zip options with safe argv semantics - #26

Draft
aliasfoxkde wants to merge 5 commits into
mainfrom
codex/py7zip-option-argv-20261011
Draft

aliasfoxkde wants to merge 5 commits into
mainfrom
codex/py7zip-option-argv-20261011

Conversation

@aliasfoxkde

@aliasfoxkde aliasfoxkde commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Preserve default-safe TypeError behavior for non-empty string options.
  • Forward sequences as one argv element each with shell disabled; preserve legacy string compatibility.
  • Add targeted tests and document the contract/compatibility migration.

Validation

  • Full pytest suite: 135 passed (NVMe checkout; TMPDIR=/nas/Temp).
  • Independent GLM-5-Turbo diff review: no code blockers; required documentation correction completed.
  • git diff --check: clean.

Merge gate

Draft intentionally. Open PR #8 also changes py7zip/py7zip.py and uses options.split(). Reconcile that overlapping change and re-evaluate the combined source before marking ready; do not merge either branch based on this PR alone.

Michael Kinney and others added 2 commits October 11, 2026 16:16
Add a strict mypy gate (strict = true, python_version 3.9) over the
py7zip runtime package via [tool.mypy] in pyproject.toml, with a CI
typecheck lane running mypy 1.x (mypy 2.x dropped the 3.9 target this
project still supports). Annotate every public method of the legacy
Py7zip wrapper and the dev scratch script under py7zip/tests/ so the
whole distributed tree checks clean with no type: ignore, no stub
overrides, and no excludes.

Runtime behavior is preserved: annotations only, plus an explicit
return None where functions previously fell off the end, a local
result->completed rename to disambiguate the legacy subprocess result
from the safe ArchiveResult, and assert binary_path is not None
narrowing at the two legacy-only sites that read the str the legacy
__init__ always assigns (unreachable via the public constructor).
py7zip/tests/debugging.py ships in the wheel, so it is typed rather
than excluded; its fix is an unreachable __file__ fallback.

Validation: mypy 1.20.2 --strict (6 files, no issues); focused tests
for touched paths (59 passed); full offline suite under unshare -rn
(129 passed); isolated wheel build + twine check PASSED; git diff
--check clean.

Co-Authored-By: Claude <noreply@anthropic.com>
@bolt-new-by-stackblitz

Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@coderabbitai

coderabbitai Bot commented Oct 11, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Michael Kinney and others added 3 commits October 12, 2026 03:50
Review of PR #26 found the options-contract landing (3e070ba, audit
decision D5 / OVH-16) missing from the Unreleased section of
.github/CHANGELOG.md, the release-note location designated by
AGENTS.md; the sibling mypy commit in this PR carries its own bullet.

Validation: git diff --check clean; python -m pytest tests
-p no:cacheprovider -> 135 passed.

Co-Authored-By: Claude <noreply@anthropic.com>
The safe branch of Py7zip.wrapper() dispatched every operation to
SafePy7zip.run(), bypassing the archive-member traversal guard that
lives only in SafePy7zip.decompress(); the public safe decompress(),
extract(), and wrapper() entry points could therefore extract a member
outside the destination root.

Route the safe branch through SafePy7zip.compress()/decompress() so
decompression lists the archive and validates every member path before
extraction, raising ArchiveTraversalError first.  Option validation is
extracted into safe.validate_options() and called before acquisition
and listing, so the pinned contract holds: a non-empty options string
raises TypeError before any 7-Zip process starts, "" forwards no
arguments, and a sequence is forwarded element by element.  Compression
remains the plain "a" invocation with no listing.

Legacy runtime behavior is unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant