Skip to content

Commit

Permalink
Add implied assertion in WheelInfo
Browse files Browse the repository at this point in the history
Some simple indexes (anaconda), only list the full-pathname of download
URL (assuming same domain, which make sens).

WheelInfo.download does not work on this case at it tries to make the
requests on the current page domain.

Thus we implicitely assume that URL start with http (well https:// would
be better, but when you prototype local index could be http.)

The error can be weird if we let it propagate (bad ziplife as you try to
decode often a 404 html page as ZIP).

This thus just add an assert at construction time to catch the error
early and that we start with actual protocol.

It should in the end be pushed earler in the code (likely at parsing
time), where we are likely to know the index URL and be able to resolve
URLs at that time.

I think there was also a missing comma in test parametrisations, and I
added a !r in a few places as I had some error with empty filenames,
without quotes, so hard to see.

The conftest was also update to explicitely pass a fake URL instead of
just a filename.

I'm not entirely sure we should allow constructing URLs with things that
don't have a protocol though, as this can be confusing.
  • Loading branch information
Carreau committed Oct 22, 2024
1 parent 4044983 commit e3c5a3f
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 7 deletions.
4 changes: 2 additions & 2 deletions micropip/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,9 @@ def check_compatible(filename: str) -> None:
try:
tags = parse_tags(filename)
except InvalidWheelFilename:
raise ValueError(f"Wheel filename is invalid: {filename}") from None
raise ValueError(f"Wheel filename is invalid: {filename!r}") from None
except InvalidVersion:
raise ValueError(f"Wheel version is invalid: {filename}") from None
raise ValueError(f"Wheel version is invalid: {filename!r}") from None

tag: Tag = next(iter(tags))
if "emscripten" not in tag.platform:
Expand Down
5 changes: 5 additions & 0 deletions micropip/wheelinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ class WheelInfo:
_dist_info: Path | None = None

def __post_init__(self):
assert (
self.url.startwith(p) for p in ("http:", "https:", "emfs:", "file:")
), self.url
self._project_name = safe_name(self.name)

@classmethod
Expand All @@ -63,6 +66,8 @@ def from_url(cls, url: str) -> "WheelInfo":
See https://www.python.org/dev/peps/pep-0427/#file-name-convention
"""
parsed_url = urlparse(url)
if parsed_url.scheme == "":
url = "file:///" + url
file_name = Path(parsed_url.path).name
name, version, build, tags = parse_wheel_filename(file_name)
return WheelInfo(
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ def add_pkg_version(
releases[version] = [
{
"filename": filename,
"url": filename,
"url": f"http://fake.domain/f/{filename}",
"digests": {
"sha256": Wildcard(),
},
Expand Down
2 changes: 1 addition & 1 deletion tests/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def _mock_fetch_bytes(arg, *args, **kwargs):

msg = "Access-Control-Allow-Origin"
with pytest.raises(ValueError, match=msg):
await micropip.install("htps://x.com/xxx-1.0.0-py3-none-any.whl")
await micropip.install("https://x.com/xxx-1.0.0-py3-none-any.whl")


@pytest.mark.skip_refcount_check
Expand Down
12 changes: 9 additions & 3 deletions tests/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,29 @@
"path",
[
SNOWBALL_WHEEL,
f"/{SNOWBALL_WHEEL}" f"a/{SNOWBALL_WHEEL}",
f"/{SNOWBALL_WHEEL}",
f"a/{SNOWBALL_WHEEL}",
f"/a/{SNOWBALL_WHEEL}",
f"//a/{SNOWBALL_WHEEL}",
],
)
@pytest.mark.parametrize("protocol", ["https:", "file:", "emfs:", ""])
@pytest.mark.parametrize(
"protocol",
["http:", "https:", "file:", "emfs:", ""],
)
def test_parse_wheel_url1(protocol, path):
pytest.importorskip("packaging")
from micropip.transaction import WheelInfo

url = protocol + path
wheel = WheelInfo.from_url(url)

check_url = url if protocol else "file:///" + path
assert wheel.name == "snowballstemmer"
assert str(wheel.version) == "2.0.0"
assert wheel.sha256 is None
assert wheel.filename == SNOWBALL_WHEEL
assert wheel.url == url
assert wheel.url == check_url
assert wheel.tags == frozenset(
{Tag("py2", "none", "any"), Tag("py3", "none", "any")}
)
Expand Down

0 comments on commit e3c5a3f

Please sign in to comment.