diff --git a/CHANGELOG.md b/CHANGELOG.md index 49c8902..8a7067a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Adds `PackageSpec.from_wheel` for generating a package spec from a `.whl` file +- Pinned to `pydantic >=1.10.2,<2` + [#23](https://github.com/pyodide/pyodide-lock/pull/23) + +- Added `PackageSpec.from_wheel` for generating a package spec from a `.whl` file [#18](https://github.com/pyodide/pyodide-lock/pull/18) -- Adds `parse_top_level_import_name` for finding importable names in `.whl` files + +- Added `parse_top_level_import_name` for finding importable names in `.whl` files [#17](https://github.com/pyodide/pyodide-lock/pull/17) ## [0.1.0a3] - 2023-09-15 @@ -26,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.1.0a2] - 2023-07-21 ### Added + - Add `check_wheel_filenames` method to `PyodideLockSpec` that checks that the package name in version are consistent between the wheel filename and the corresponding pyodide-lock.json fields diff --git a/pyodide_lock/spec.py b/pyodide_lock/spec.py index ac860b2..c2f0c58 100644 --- a/pyodide_lock/spec.py +++ b/pyodide_lock/spec.py @@ -2,7 +2,7 @@ from pathlib import Path from typing import Literal -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, Extra from .utils import ( _generate_package_hash, @@ -12,17 +12,16 @@ class InfoSpec(BaseModel): - model_config = ConfigDict(extra="forbid") - arch: Literal["wasm32", "wasm64"] = "wasm32" platform: str version: str python: str + class Config: + extra = Extra.forbid -class PackageSpec(BaseModel): - model_config = ConfigDict(extra="forbid") +class PackageSpec(BaseModel): name: str version: str file_name: str @@ -37,6 +36,9 @@ class PackageSpec(BaseModel): # This field is deprecated shared_library: bool = False + class Config: + extra = Extra.forbid + @classmethod def from_wheel( cls, @@ -76,22 +78,23 @@ def update_sha256(self, path: Path) -> "PackageSpec": class PyodideLockSpec(BaseModel): """A specification for the pyodide-lock.json file.""" - model_config = ConfigDict(extra="forbid") - info: InfoSpec packages: dict[str, PackageSpec] + class Config: + extra = Extra.forbid + @classmethod def from_json(cls, path: Path) -> "PyodideLockSpec": """Read the lock spec from a json file.""" - with path.open("r") as fh: + with path.open("r", encoding="utf-8") as fh: data = json.load(fh) return cls(**data) def to_json(self, path: Path, indent: int | None = None) -> None: """Write the lock spec to a json file.""" - with path.open("w") as fh: - json.dump(self.model_dump(), fh, indent=indent) + with path.open("w", encoding="utf-8") as fh: + fh.write(self.json(indent=indent, sort_keys=True)) def check_wheel_filenames(self) -> None: """Check that the package name and version are consistent in wheel filenames""" diff --git a/pyproject.toml b/pyproject.toml index ebd6d0c..a9c5f26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,8 @@ description = "Tooling to manage the `pyodide-lock.json` file" readme = "README.md" requires-python = ">=3.10" dependencies = [ - "pydantic" + # compatible with pyodide-build and the as-shipped wheel in the pyodide distribution + "pydantic >=1.10.2,<2", ] classifiers = [ "Programming Language :: Python :: 3", diff --git a/tests/test_spec.py b/tests/test_spec.py index beb4478..7d29ae2 100644 --- a/tests/test_spec.py +++ b/tests/test_spec.py @@ -119,11 +119,11 @@ def test_extra_config_forbidden(): info_data["extra"] = "extra" # type: ignore[index] package_data["extra"] = "extra" - with pytest.raises(ValidationError, match="Extra inputs are not permitted"): + with pytest.raises(ValidationError, match="extra fields not permitted"): PyodideLockSpec(**lock_data) - with pytest.raises(ValidationError, match="Extra inputs are not permitted"): + with pytest.raises(ValidationError, match="extra fields not permitted"): InfoSpec(**info_data) # type: ignore[arg-type] - with pytest.raises(ValidationError, match="Extra inputs are not permitted"): + with pytest.raises(ValidationError, match="extra fields not permitted"): PackageSpec(**package_data) diff --git a/tests/test_wheel.py b/tests/test_wheel.py index a008bb8..8dfd8ec 100644 --- a/tests/test_wheel.py +++ b/tests/test_wheel.py @@ -46,7 +46,7 @@ def test_self_wheel(): assert WHEEL is not None - spec = PackageSpec.from_wheel(WHEEL).model_dump_json(indent=2) + spec = PackageSpec.from_wheel(WHEEL).json(indent=2, sort_keys=True) expected = PackageSpec( name="pyodide-lock", @@ -59,7 +59,7 @@ def test_self_wheel(): depends=["pydantic"], unvendored_tests=False, shared_library=False, - ).model_dump_json(indent=2) + ).json(indent=2, sort_keys=True) assert spec == expected