diff --git a/pyarn/lockfile.py b/pyarn/lockfile.py index b936d78..64ba261 100644 --- a/pyarn/lockfile.py +++ b/pyarn/lockfile.py @@ -19,7 +19,7 @@ import logging import re from pathlib import Path -from typing import Optional, Pattern +from typing import Any, Dict, Optional, Pattern from ply import lex, yacc @@ -36,15 +36,15 @@ class Package: def __init__( self, - name, - version, - url=None, - checksum=None, - path=None, - relpath=None, - dependencies=None, - alias=None, - ): + name: str, + version: str, + url: Optional[str] = None, + checksum: Optional[str] = None, + path: Optional[str] = None, + relpath: Optional[str] = None, + dependencies: Optional[Dict[str, str]] = None, + alias: Optional[str] = None, + ) -> None: if not name: raise ValueError("Package name was not provided") @@ -68,7 +68,7 @@ def relpath(self, path: Optional[str]) -> None: self.path = path @classmethod - def from_dict(cls, raw_name, data): + def from_dict(cls, raw_name: str, data: Dict[str, Any]) -> "Package": name_at_version = re.compile(r"(?P@?[^@]+)(?:@(?P[^,]*))?") # _version is the version as declared in package.json, not the resolved version @@ -83,9 +83,14 @@ def from_dict(cls, raw_name, data): if _version: path = cls.get_path_from_version_specifier(_version) + # Ensure the resolved version key exists to appease mypy + version = data.get("version") + if not version: + raise ValueError("Package version was not provided") + return cls( name=name, - version=data.get("version"), + version=version, url=data.get("resolved"), checksum=data.get("integrity"), path=path, diff --git a/tests/test_lockfile.py b/tests/test_lockfile.py index 9efc9f5..6393f75 100644 --- a/tests/test_lockfile.py +++ b/tests/test_lockfile.py @@ -123,16 +123,21 @@ def test_packages(): assert packages[0].path is None -def test_packages_no_version(): +def test_lock_packages_no_version(): data = "breakfast@^1.1.1:\n eggs bacon" lock = lockfile.Lockfile.from_str(data) with pytest.raises(ValueError, match="Package version was not provided"): lock.packages() +def test_package_no_version(): + with pytest.raises(ValueError, match="Package version was not provided"): + lockfile.Package("breakfast", None) # type: ignore[arg-type] + + def test_packages_no_name(): with pytest.raises(ValueError, match="Package name was not provided"): - lockfile.Package(None, "1.0.0") + lockfile.Package(None, "1.0.0") # type: ignore[arg-type] def test_packages_url():