Skip to content

Commit

Permalink
Port list and mock_package into PackageManager (#118)
Browse files Browse the repository at this point in the history
* feat: port list()

* feat: add mock_package to package manager

* fix: import
  • Loading branch information
RulerOfCakes authored Jul 4, 2024
1 parent 8b39458 commit f9ec77e
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 62 deletions.
59 changes: 4 additions & 55 deletions micropip/_commands/list.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,7 @@
import importlib.metadata

from .._compat import REPODATA_PACKAGES, loadedPackages
from ..package import PackageDict, PackageMetadata
from .._compat import REPODATA_PACKAGES
from ..list import list_installed_packages
from ..package import PackageDict


def _list() -> PackageDict:
"""Get the dictionary of installed packages.
Returns
-------
``PackageDict``
A dictionary of installed packages.
>>> import micropip
>>> await micropip.install('regex') # doctest: +SKIP
>>> package_list = micropip.list()
>>> print(package_list) # doctest: +SKIP
Name | Version | Source
----------------- | -------- | -------
regex | 2021.7.6 | pyodide
>>> "regex" in package_list # doctest: +SKIP
True
"""

# Add packages that are loaded through pyodide.loadPackage
packages = PackageDict()
for dist in importlib.metadata.distributions():
name = dist.name
version = dist.version
source = dist.read_text("PYODIDE_SOURCE")
if source is None:
# source is None if PYODIDE_SOURCE does not exist. In this case the
# wheel was installed manually, not via `pyodide.loadPackage` or
# `micropip`.
continue
packages[name] = PackageMetadata(
name=name,
version=version,
source=source,
)

for name, pkg_source in loadedPackages.to_py().items():
if name in packages:
continue

if name in REPODATA_PACKAGES:
version = REPODATA_PACKAGES[name]["version"]
source_ = "pyodide"
if pkg_source != "default channel":
# Pyodide package loaded from a custom URL
source_ = pkg_source
else:
# TODO: calculate version from wheel metadata
version = "unknown"
source_ = pkg_source
packages[name] = PackageMetadata(name=name, version=version, source=source_)
return packages
return list_installed_packages(REPODATA_PACKAGES)
61 changes: 61 additions & 0 deletions micropip/list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import importlib.metadata
from typing import Any

from ._compat import loadedPackages
from .package import PackageDict, PackageMetadata


def list_installed_packages(
lockfile_packages: dict[str, dict[str, Any]]
) -> PackageDict:
"""Get the dictionary of installed packages.
Returns
-------
``PackageDict``
A dictionary of installed packages.
>>> import micropip
>>> await micropip.install('regex') # doctest: +SKIP
>>> package_list = micropip.list()
>>> print(package_list) # doctest: +SKIP
Name | Version | Source
----------------- | -------- | -------
regex | 2021.7.6 | pyodide
>>> "regex" in package_list # doctest: +SKIP
True
"""

# Add packages that are loaded through pyodide.loadPackage
packages = PackageDict()
for dist in importlib.metadata.distributions():
name = dist.name
version = dist.version
source = dist.read_text("PYODIDE_SOURCE")
if source is None:
# source is None if PYODIDE_SOURCE does not exist. In this case the
# wheel was installed manually, not via `pyodide.loadPackage` or
# `micropip`.
continue
packages[name] = PackageMetadata(
name=name,
version=version,
source=source,
)

for name, pkg_source in loadedPackages.to_py().items():
if name in packages:
continue

if name in lockfile_packages:
version = lockfile_packages[name]["version"]
source_ = "pyodide"
if pkg_source != "default channel":
# Pyodide package loaded from a custom URL
source_ = pkg_source
else:
# TODO: calculate version from wheel metadata
version = "unknown"
source_ = pkg_source
packages[name] = PackageMetadata(name=name, version=version, source=source_)
return packages
26 changes: 19 additions & 7 deletions micropip/package_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
)

from micropip import package_index
from micropip._commands import mock_package
from micropip.freeze import freeze_lockfile
from micropip.list import list_installed_packages
from micropip.package import PackageDict


class PackageManager:
Expand All @@ -29,20 +32,29 @@ def __init__(self) -> None:
def install(self):
raise NotImplementedError()

def list(self):
raise NotImplementedError()
def list(self) -> PackageDict:
return list_installed_packages(self.repodata_packages)

def freeze(self) -> str:
return freeze_lockfile(self.repodata_packages, self.repodata_info)

def add_mock_package(self):
raise NotImplementedError()
def add_mock_package(
self,
name: str,
version: str,
*,
modules: dict[str, str | None] | None = None,
persistent: bool = False,
):
return mock_package.add_mock_package(
name, version, modules=modules, persistent=persistent
)

def list_mock_packages(self):
raise NotImplementedError()
return mock_package.list_mock_packages()

def remove_mock_package(self):
raise NotImplementedError()
def remove_mock_package(self, name: str):
return mock_package.remove_mock_package(name)

def uninstall(self):
raise NotImplementedError()
Expand Down
11 changes: 11 additions & 0 deletions tests/test_package_manager.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import json

import pytest

import micropip.package_index as package_index
from micropip.package_manager import PackageManager

Expand Down Expand Up @@ -57,3 +59,12 @@ def test_freeze():
"info": test_repodata_info,
"packages": test_repodata_packages,
}


@pytest.mark.skip(reason="Not implemented")
def test_list():
manager = get_test_package_manager()

_package_dict = manager.list()

# TODO: implement test after implementing manager.install()

0 comments on commit f9ec77e

Please sign in to comment.