Skip to content

Commit d31dc66

Browse files
MAINT Inject compat layer to Transaction (#213)
* Inject compat layer to transaction * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent eefb57a commit d31dc66

6 files changed

Lines changed: 54 additions & 21 deletions

File tree

micropip/package_index.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from typing import Any
1010
from urllib.parse import urljoin, urlparse, urlunparse
1111

12-
from ._compat import fetch_string_and_headers
12+
from ._compat import CompatibilityLayer
1313
from ._utils import is_package_compatible, parse_version
1414
from ._vendored.mousebender.simple import from_project_details_html
1515
from ._vendored.packaging.src.packaging.utils import InvalidWheelFilename
@@ -271,6 +271,9 @@ def _select_parser(
271271
async def query_package(
272272
name: str,
273273
index_urls: list[str] | str,
274+
*,
275+
# TODO: instead of passing this as a parameter, it should be a class attribute
276+
compat_layer: type[CompatibilityLayer],
274277
fetch_kwargs: dict[str, Any] | None = None,
275278
) -> ProjectInfo:
276279
"""
@@ -312,7 +315,9 @@ async def query_package(
312315
url = f"{url}/{name}/"
313316
logger.debug("Url has no placeholder, appending package name : %r", url)
314317
try:
315-
metadata, headers = await fetch_string_and_headers(url, _fetch_kwargs)
318+
metadata, headers = await compat_layer.fetch_string_and_headers(
319+
url, _fetch_kwargs
320+
)
316321
except Exception as e:
317322
logger.debug(
318323
"Error fetching metadata for the package %r from (%r): %r, trying next index.",

micropip/package_manager.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ async def install(
170170
wheel_base = Path(getsitepackages()[0])
171171

172172
transaction = Transaction(
173+
_compat_layer=self.compat_layer,
173174
ctx=ctx, # type: ignore[arg-type]
174175
ctx_extras=[],
175176
keep_going=keep_going,

micropip/transaction.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from urllib.parse import urlparse
99

1010
from . import package_index
11-
from ._compat import LOCKFILE_PACKAGES
11+
from ._compat import CompatibilityLayer
1212
from ._utils import (
1313
best_compatible_tag_index,
1414
check_compatible,
@@ -30,6 +30,8 @@
3030

3131
@dataclass
3232
class Transaction:
33+
_compat_layer: type[CompatibilityLayer]
34+
3335
ctx: dict[str, str]
3436
ctx_extras: list[dict[str, str]]
3537
keep_going: bool
@@ -208,9 +210,9 @@ async def _add_requirement_from_pyodide_lock(self, req: Requirement) -> bool:
208210
Find requirement from pyodide-lock.json. If the requirement is found,
209211
add it to the package list and return True. Otherwise, return False.
210212
"""
211-
locked_package = LOCKFILE_PACKAGES.get(req.name)
213+
locked_package = self._compat_layer.lockfile_packages.get(req.name)
212214
if locked_package and req.specifier.contains(
213-
LOCKFILE_PACKAGES[req.name]["version"], prereleases=True
215+
self._compat_layer.lockfile_packages[req.name]["version"], prereleases=True
214216
):
215217
version = locked_package["version"]
216218
self.pyodide_packages.append(
@@ -230,7 +232,8 @@ async def _add_requirement_from_package_index(self, req: Requirement):
230232
metadata = await package_index.query_package(
231233
req.name,
232234
self.index_urls,
233-
self.fetch_kwargs,
235+
compat_layer=self._compat_layer,
236+
fetch_kwargs=self.fetch_kwargs,
234237
)
235238

236239
logger.debug("Transaction: got metadata %r for requirement %r", metadata, req)

tests/conftest.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ def add_pkg_version(
304304
self.metadata_map[filename] = metadata
305305
self.top_level_map[filename] = top_level
306306

307-
async def query_package(self, pkgname, index_urls, kwargs):
307+
async def query_package(self, pkgname, index_urls, *, compat_layer, fetch_kwargs):
308308
from micropip.package_index import ProjectInfo
309309

310310
try:
@@ -453,3 +453,13 @@ def _run(*lines, error_match=None):
453453
selenium_standalone_micropip.run_js(js)
454454

455455
return _run
456+
457+
458+
@pytest.fixture
459+
def host_compat_layer():
460+
"""
461+
Fixture to provide the compatibility layer for the host environment.
462+
"""
463+
from micropip._compat._compat_not_in_pyodide import CompatibilityNotInPyodide
464+
465+
yield CompatibilityNotInPyodide

tests/test_package_index.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def test_contain_placeholder():
133133
("numpy", "black"),
134134
],
135135
)
136-
async def test_query_package(mock_fixture, pkg1, pkg2, request):
136+
async def test_query_package(mock_fixture, pkg1, pkg2, request, host_compat_layer):
137137
gen_mock_server = request.getfixturevalue(mock_fixture)
138138
pkg1_index_url = gen_mock_server(pkgs=[pkg1], pkgs_not_found=[pkg2])
139139
pkg2_index_url = gen_mock_server(pkgs=[pkg2], pkgs_not_found=[pkg1])
@@ -143,10 +143,14 @@ async def test_query_package(mock_fixture, pkg1, pkg2, request):
143143
[pkg1_index_url],
144144
[pkg2_index_url, pkg1_index_url],
145145
):
146-
project_info = await package_index.query_package(pkg1, index_urls=_index_urls)
146+
project_info = await package_index.query_package(
147+
pkg1, index_urls=_index_urls, compat_layer=host_compat_layer
148+
)
147149

148150
assert project_info.name == pkg1
149151
assert project_info.releases
150152

151153
with pytest.raises(ValueError, match="Can't fetch metadata"):
152-
await package_index.query_package(pkg1, index_urls=[pkg2_index_url])
154+
await package_index.query_package(
155+
pkg1, index_urls=[pkg2_index_url], compat_layer=host_compat_layer
156+
)

tests/test_transaction.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,11 @@ def test_parse_wheel_url3():
5252
assert wheel.tags == frozenset({Tag("cp35", "cp35m", "macosx_10_9_intel")})
5353

5454

55-
def create_transaction(Transaction):
55+
def create_transaction(Transaction, compat_layer):
5656
from micropip.package_index import DEFAULT_INDEX_URLS
5757

5858
return Transaction(
59+
_compat_layer=compat_layer,
5960
wheels=[],
6061
locked={},
6162
keep_going=True,
@@ -71,12 +72,12 @@ def create_transaction(Transaction):
7172

7273

7374
@pytest.mark.asyncio
74-
async def test_add_requirement(wheel_catalog):
75+
async def test_add_requirement(wheel_catalog, host_compat_layer):
7576
from micropip.transaction import Transaction
7677

7778
snowballstemmer_wheel = wheel_catalog.get("snowballstemmer")
7879

79-
transaction = create_transaction(Transaction)
80+
transaction = create_transaction(Transaction, host_compat_layer)
8081
await transaction.add_requirement(snowballstemmer_wheel.url)
8182

8283
wheel = transaction.wheels[0]
@@ -90,10 +91,10 @@ async def test_add_requirement(wheel_catalog):
9091

9192

9293
@pytest.mark.asyncio
93-
async def test_add_requirement_marker(mock_importlib, wheel_base):
94+
async def test_add_requirement_marker(mock_importlib, wheel_base, host_compat_layer):
9495
from micropip.transaction import Transaction
9596

96-
transaction = create_transaction(Transaction)
97+
transaction = create_transaction(Transaction, host_compat_layer)
9798

9899
await transaction.gather_requirements(
99100
[
@@ -125,29 +126,31 @@ async def test_add_requirement_marker(mock_importlib, wheel_base):
125126

126127

127128
@pytest.mark.asyncio
128-
async def test_add_requirement_query_url(mock_importlib, wheel_base, monkeypatch):
129+
async def test_add_requirement_query_url(
130+
mock_importlib, wheel_base, monkeypatch, host_compat_layer
131+
):
129132
from micropip.transaction import Transaction
130133

131134
async def mock_add_wheel(self, wheel, extras, *, specifier=""):
132135
self.mock_wheel = wheel
133136

134137
monkeypatch.setattr(Transaction, "add_wheel", mock_add_wheel)
135138

136-
transaction = create_transaction(Transaction)
139+
transaction = create_transaction(Transaction, host_compat_layer)
137140
await transaction.add_requirement(f"{SNOWBALL_WHEEL}?b=1")
138141
wheel = transaction.mock_wheel
139142
assert wheel.name == "snowballstemmer"
140143
assert wheel.filename == SNOWBALL_WHEEL # without the query params
141144

142145

143146
@pytest.mark.asyncio
144-
async def test_install_non_pure_python_wheel():
147+
async def test_install_non_pure_python_wheel(host_compat_layer):
145148
from micropip.transaction import Transaction
146149

147150
msg = "Wheel platform 'macosx_10_9_intel' is not compatible with Pyodide's platform"
148151
with pytest.raises(ValueError, match=msg):
149152
url = "http://a/scikit_learn-0.22.2.post1-cp35-cp35m-macosx_10_9_intel.whl"
150-
transaction = create_transaction(Transaction)
153+
transaction = create_transaction(Transaction, host_compat_layer)
151154
await transaction.add_requirement(url)
152155

153156

@@ -324,11 +327,12 @@ def test_last_version_and_best_tag_from_pypi(
324327
assert str(wheel.version) == new_version
325328

326329

327-
def test_search_pyodide_lock_first():
330+
def test_search_pyodide_lock_first(host_compat_layer):
328331
from micropip import package_index
329332
from micropip.transaction import Transaction
330333

331334
t = Transaction(
335+
_compat_layer=host_compat_layer,
332336
ctx={},
333337
ctx_extras=[],
334338
keep_going=True,
@@ -341,6 +345,7 @@ def test_search_pyodide_lock_first():
341345
assert t.search_pyodide_lock_first is True
342346

343347
t = Transaction(
348+
_compat_layer=host_compat_layer,
344349
ctx={},
345350
ctx_extras=[],
346351
keep_going=True,
@@ -355,7 +360,11 @@ def test_search_pyodide_lock_first():
355360

356361
@pytest.mark.asyncio
357362
async def test_index_url_priority(
358-
mock_importlib, wheel_base, monkeypatch, mock_package_index_simple_json_api
363+
mock_importlib,
364+
wheel_base,
365+
monkeypatch,
366+
mock_package_index_simple_json_api,
367+
host_compat_layer,
359368
):
360369
# Test that if the index_urls are provided, package should be searched in
361370
# the index_urls first before searching in Pyodide lock file.
@@ -373,6 +382,7 @@ async def mock_add_wheel(self, wheel, extras, *, specifier=""):
373382
mock_index_url = mock_package_index_simple_json_api(pkgs=["black"])
374383

375384
t = Transaction(
385+
_compat_layer=host_compat_layer,
376386
keep_going=True,
377387
deps=False,
378388
pre=False,

0 commit comments

Comments
 (0)