From a09ebcc2e402a7cce24d132b2c80e2d79d189df5 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 29 Apr 2026 15:43:21 +0200 Subject: [PATCH 1/3] Fix docs mentioning that index URLs must support JSON API (they do not) --- micropip/package_manager.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/micropip/package_manager.py b/micropip/package_manager.py index 602c7fe..849a166 100644 --- a/micropip/package_manager.py +++ b/micropip/package_manager.py @@ -120,18 +120,22 @@ async def install( index_urls: A list of URLs or a single URL to use as the package index when looking - up packages. If None, *https://pypi.org/pypi/{package_name}/json* is used. + up packages. If None, *https://pypi.org/simple* is used. - - The index URL should support the \ + - The index URL may support the \ `JSON API `__ . - - The index URL may contain the placeholder {package_name} which will be \ + - The index URL may contain the placeholder {package_name}, for example \ + *https://pypi.org/pypi/{package_name}/json*, this placeholder will be \ replaced with the package name when looking up a package. If it does not \ contain the placeholder, the package name will be appended to the URL. - If a list of URLs is provided, micropip will try each URL in order until \ it finds a package. If no package is found, an error will be raised. + - The index URL must support CORS when used in a web browser. Note that \ + *https://pypi.org/simple* has CORS enabled. + constraints: A list of requirements with versions/URLs which will be used only if From 6ed470c3bed89d2f6ec4872b692f5e16cb7b3d25 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 30 Apr 2026 17:17:00 +0200 Subject: [PATCH 2/3] Implement suggestions --- micropip/package_manager.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/micropip/package_manager.py b/micropip/package_manager.py index 849a166..cb29d03 100644 --- a/micropip/package_manager.py +++ b/micropip/package_manager.py @@ -122,19 +122,13 @@ async def install( A list of URLs or a single URL to use as the package index when looking up packages. If None, *https://pypi.org/simple* is used. - - The index URL may support the \ - `JSON API `__ . - - - The index URL may contain the placeholder {package_name}, for example \ - *https://pypi.org/pypi/{package_name}/json*, this placeholder will be \ - replaced with the package name when looking up a package. If it does not \ - contain the placeholder, the package name will be appended to the URL. + - The index URL should support the \ + `Simple repository API `__ . - If a list of URLs is provided, micropip will try each URL in order until \ it finds a package. If no package is found, an error will be raised. - - The index URL must support CORS when used in a web browser. Note that \ - *https://pypi.org/simple* has CORS enabled. + - The index URL must support CORS when used in a web browser. constraints: @@ -466,7 +460,7 @@ def set_index_urls(self, urls: List[str] | str): # noqa: UP006 Set the index URLs to use when looking up packages. - The index URL should support the - `JSON API `__ . + `Simple repository API `__ . - The index URL may contain the placeholder {package_name} which will be replaced with the package name when looking up a package. If it does not @@ -475,6 +469,8 @@ def set_index_urls(self, urls: List[str] | str): # noqa: UP006 - If a list of URLs is provided, micropip will try each URL in order until it finds a package. If no package is found, an error will be raised. + - The index URL must support CORS when used in a web browser. + Parameters ---------- urls From e34ffc5b0f2b424c1dd194b2db21f40bb6cdc99a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 15:20:43 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/conftest.py | 6 ++---- tests/test_freeze.py | 6 ++---- tests/test_install.py | 36 ++++++++++++------------------------ tests/test_list.py | 24 ++++++++---------------- 4 files changed, 24 insertions(+), 48 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index d09338a..d3d199b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -94,12 +94,10 @@ def selenium_standalone_micropip(selenium_standalone, wheel_path): with httpserver: url = httpserver.url_for(f"/{wheel_file.name}") - selenium_standalone.run_js( - f""" + selenium_standalone.run_js(f""" await pyodide.loadPackage("{url}"); pyodide.runPython("import micropip"); - """ - ) + """) yield selenium_standalone diff --git a/tests/test_freeze.py b/tests/test_freeze.py index 3a18655..3ff1176 100644 --- a/tests/test_freeze.py +++ b/tests/test_freeze.py @@ -83,12 +83,10 @@ def test_freeze_lockfile_compat( wheel = wheel_catalog.get(name) url = wheel.url - lockfile_content = selenium.run_async( - f""" + lockfile_content = selenium.run_async(f""" await micropip.install("{url}") micropip.freeze() - """ - ) + """) lockfile_path = tmp_path / "lockfile.json" with open(lockfile_path, "w") as f: diff --git a/tests/test_install.py b/tests/test_install.py index 0eb07e4..e174875 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -29,74 +29,62 @@ def test_install_file_protocol_node(selenium_standalone_micropip, request): DIST_PATH = request.config.option.dist_dir pyparsing_wheel_name = list(DIST_PATH.glob("pyparsing*.whl"))[0].name - selenium.run_js( - f""" + selenium.run_js(f""" await pyodide.runPythonAsync(` import micropip await micropip.install('file:{pyparsing_wheel_name}') import pyparsing `); - """ - ) + """) def test_install_different_version(selenium_standalone_micropip): selenium = selenium_standalone_micropip - selenium.run_js( - """ + selenium.run_js(""" await pyodide.runPythonAsync(` import micropip await micropip.install( "https://files.pythonhosted.org/packages/89/06/2c2d3034b4d6bf22f2a4ae546d16925898658a33b4400cfb7e2c1e2871a3/pytz-2020.5-py2.py3-none-any.whl" ); `); - """ - ) - selenium.run_js( - """ + """) + selenium.run_js(""" await pyodide.runPythonAsync(` import pytz assert pytz.__version__ == "2020.5" `); - """ - ) + """) def test_install_different_version2(selenium_standalone_micropip): selenium = selenium_standalone_micropip - selenium.run_js( - """ + selenium.run_js(""" await pyodide.runPythonAsync(` import micropip await micropip.install( "pytz == 2020.5" ); `); - """ - ) - selenium.run_js( - """ + """) + selenium.run_js(""" await pyodide.runPythonAsync(` import pytz assert pytz.__version__ == "2020.5" `); - """ - ) + """) @pytest.mark.parametrize("jinja2", ["jinja2", "Jinja2"]) def test_install_mixed_case2(selenium_standalone_micropip, jinja2): selenium = selenium_standalone_micropip - selenium.run_js( - f""" + selenium.run_js(f""" await pyodide.loadPackage("micropip"); await pyodide.runPythonAsync(` import micropip await micropip.install("{jinja2}") import jinja2 `); - """ - ) + """) @pytest.mark.parametrize("set_constraints", [False, True]) diff --git a/tests/test_list.py b/tests/test_list.py index d229b9f..3464cf6 100644 --- a/tests/test_list.py +++ b/tests/test_list.py @@ -46,45 +46,38 @@ def test_list_load_package_from_url(selenium_standalone_micropip, wheel_catalog) url = snowball_wheel.url selenium = selenium_standalone_micropip - selenium.run_js( - f""" + selenium.run_js(f""" await pyodide.loadPackage({url!r}); await pyodide.runPythonAsync(` import micropip assert "snowballstemmer" in micropip.list() `); - """ - ) + """) def test_list_pyodide_package(selenium_standalone_micropip): selenium = selenium_standalone_micropip - selenium.run_js( - """ + selenium.run_js(""" await pyodide.runPythonAsync(` import micropip await micropip.install( "regex" ); `); - """ - ) - selenium.run_js( - """ + """) + selenium.run_js(""" await pyodide.runPythonAsync(` import micropip pkgs = micropip.list() assert "regex" in pkgs assert pkgs["regex"].source.lower() == "pyodide" `); - """ - ) + """) def test_list_loaded_from_js(selenium_standalone_micropip): selenium = selenium_standalone_micropip - selenium.run_js( - """ + selenium.run_js(""" await pyodide.loadPackage("regex"); await pyodide.runPythonAsync(` import micropip @@ -92,5 +85,4 @@ def test_list_loaded_from_js(selenium_standalone_micropip): assert "regex" in pkgs assert pkgs["regex"].source.lower() == "pyodide" `); - """ - ) + """)