diff --git a/micropip/_utils.py b/micropip/_utils.py index 9d6bc35..1167a01 100644 --- a/micropip/_utils.py +++ b/micropip/_utils.py @@ -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: diff --git a/micropip/wheelinfo.py b/micropip/wheelinfo.py index c6d255f..d9c5a89 100644 --- a/micropip/wheelinfo.py +++ b/micropip/wheelinfo.py @@ -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 @@ -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( diff --git a/tests/conftest.py b/tests/conftest.py index af55b88..c704a57 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -270,7 +270,7 @@ def add_pkg_version( releases[version] = [ { "filename": filename, - "url": filename, + "url": f"http://fake.domain/f/{filename}", "digests": { "sha256": Wildcard(), }, diff --git a/tests/test_install.py b/tests/test_install.py index 111926a..aa89b0e 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -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 diff --git a/tests/test_transaction.py b/tests/test_transaction.py index 326490d..d7b9ceb 100644 --- a/tests/test_transaction.py +++ b/tests/test_transaction.py @@ -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")} )