Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
the package version; publishing uses PyPI trusted publishing.
- Made the safe runtime the default while retaining the legacy runtime only
behind an explicit migration flag.
- Changed the safe runtime's `Py7zip.get_binary_url()` to raise
`NotImplementedError` directing callers to the public `download_binary()`
entry point instead of returning a fabricated cache-relative path
(OVH-05).

## 0.7.3

Expand Down
24 changes: 20 additions & 4 deletions py7zip/py7zip.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import requests

from .platforms import ArtifactCatalog
from .safe import SafePy7zip


Expand Down Expand Up @@ -145,10 +144,27 @@ def download_binary(self):
os.chmod(self.binary_path, 0o755)

def get_binary_url(self):
"""Dynamically gets the URL of the required system binary."""
"""Return the source location for the platform's 7-Zip binary.

On the safe runtime (default), binary acquisition is explicit:
callers must invoke :meth:`download_binary` (or supply a
pre-verified ``binary_path``) before using the wrapper. This
method raises :class:`NotImplementedError` rather than returning
a fabricated cache-relative path, because the safe runtime does
not construct download URLs at construction time.

On the legacy runtime (``legacy=True``), returns the URL where
the historical in-package binary would have been served from,
or raises :class:`NotImplementedError` for unsupported host
platforms.
"""
if not self.legacy:
spec = ArtifactCatalog.resolve(self.platform_info)
return f"{self._safe.cache_dir}/{spec.relative_path}"
raise NotImplementedError(
"get_binary_url() is not supported on the safe runtime; "
"call download_binary() to acquire a verified binary into "
"the cache directory, or supply a pre-verified "
"binary_path=... to the constructor."
)
if self.platform not in self.supported:
raise NotImplementedError(f"Platform '{self.platform}' is not supported.")
return self.url
Expand Down
20 changes: 20 additions & 0 deletions tests/test_default_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@ def test_default_aliases_require_individual_option_arguments(tmp_path):
wrapper.compress("source", "destination", options="-y")


def test_get_binary_url_raises_on_safe_runtime(tmp_path):
"""The safe runtime exposes acquisition, not download URLs.

Per the F2 finding in the platform-architecture audit, the safe
runtime previously returned a fabricated cache-relative path that
did not correspond to any real download. Acquisition is now
explicit via the public ``download_binary()`` entry point; this
method raises a typed error pointing callers at that API rather
than the internal ``SafePy7zip.ensure_binary()``.
"""
wrapper = Py7zip(cache_dir=tmp_path)

with pytest.raises(NotImplementedError) as excinfo:
wrapper.get_binary_url()

message = str(excinfo.value)
assert "download_binary()" in message
assert "ensure_binary" not in message


def test_legacy_mode_is_explicit():
assert "legacy" in Py7zip.__init__.__code__.co_varnames
assert ArchiveRunner is not None
Loading