From bc4f3fb075e0aa1982b4691b6032ba0f84f119af Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 17:52:52 +0530 Subject: [PATCH 01/15] Add `pypa/packaging` as a submodule --- .gitmodules | 3 +++ micropip/_vendored/packaging | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 micropip/_vendored/packaging diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e76562c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "micropip/_vendored/packaging"] + path = micropip/_vendored/packaging + url = https://github.com/pypa/packaging/ diff --git a/micropip/_vendored/packaging b/micropip/_vendored/packaging new file mode 160000 index 0000000..d8e3b31 --- /dev/null +++ b/micropip/_vendored/packaging @@ -0,0 +1 @@ +Subproject commit d8e3b31b734926ebbcaff654279f6855a73e052f From e2df367a47f7b4dc99fa44920c8f25dd517f3158 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 17:54:28 +0530 Subject: [PATCH 02/15] Add commit hash and tag in a comment --- .gitmodules | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitmodules b/.gitmodules index e76562c..8a4e61d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,5 @@ +# d8e3b31b734926ebbcaff654279f6855a73e052f, for 24.2 release +# https://github.com/pypa/packaging/releases/tag/24.2 [submodule "micropip/_vendored/packaging"] path = micropip/_vendored/packaging url = https://github.com/pypa/packaging/ From 6a056386eb1af32351ea8ec3fb0b260347b5d0ca Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 18:48:22 +0530 Subject: [PATCH 03/15] Import `packaging` from vendored source --- micropip/_utils.py | 13 ++++++------- micropip/externals/mousebender/simple.py | 9 ++++----- micropip/freeze.py | 3 +-- micropip/install.py | 3 +-- micropip/metadata.py | 4 ++-- micropip/package.py | 2 +- micropip/package_index.py | 5 ++--- micropip/transaction.py | 5 ++--- micropip/wheelinfo.py | 7 +++---- tests/conftest.py | 3 ++- tests/test_install.py | 2 +- tests/test_transaction.py | 15 ++++++--------- tests/test_uninstall.py | 2 +- 13 files changed, 32 insertions(+), 41 deletions(-) diff --git a/micropip/_utils.py b/micropip/_utils.py index 70d4724..10ed88c 100644 --- a/micropip/_utils.py +++ b/micropip/_utils.py @@ -4,14 +4,13 @@ from pathlib import Path from sysconfig import get_config_var, get_platform -from packaging.requirements import Requirement -from packaging.tags import Tag -from packaging.tags import sys_tags as sys_tags_orig -from packaging.utils import BuildTag, InvalidWheelFilename, canonicalize_name -from packaging.utils import parse_wheel_filename as parse_wheel_filename_orig -from packaging.version import InvalidVersion, Version - from ._compat import REPODATA_PACKAGES +from ._vendored.packaging.requirements import Requirement +from ._vendored.packaging.tags import Tag +from ._vendored.packaging.tags import sys_tags as sys_tags_orig +from ._vendored.packaging.utils import BuildTag, InvalidWheelFilename, canonicalize_name +from ._vendored.packaging.utils import parse_wheel_filename as parse_wheel_filename_orig +from ._vendored.packaging.version import InvalidVersion, Version def get_dist_info(dist: Distribution) -> Path: diff --git a/micropip/externals/mousebender/simple.py b/micropip/externals/mousebender/simple.py index 134bf05..dbbf022 100644 --- a/micropip/externals/mousebender/simple.py +++ b/micropip/externals/mousebender/simple.py @@ -7,13 +7,12 @@ import warnings from typing import Any, Dict, List, Optional, Union, Literal, TypeAlias, TypedDict -import packaging.utils +import micropip._vendored.packaging.utils as packaging_utils ACCEPT_JSON_V1 = "application/vnd.pypi.simple.v1+json" - class UnsupportedAPIVersion(Exception): """The major version of an API response is not supported.""" @@ -92,7 +91,7 @@ class ProjectDetails_1_0(TypedDict): """A :class:`~typing.TypedDict` for a project details response (:pep:`691`).""" meta: _Meta_1_0 - name: packaging.utils.NormalizedName + name: packaging_utils.NormalizedName files: list[ProjectFileDetails_1_0] @@ -100,7 +99,7 @@ class ProjectDetails_1_1(TypedDict): """A :class:`~typing.TypedDict` for a project details response (:pep:`700`).""" meta: _Meta_1_1 - name: packaging.utils.NormalizedName + name: packaging_utils.NormalizedName files: list[ProjectFileDetails_1_1] # PEP 700 versions: List[str] @@ -235,6 +234,6 @@ def from_project_details_html(html: str, name: str) -> ProjectDetails_1_0: files.append(details) return { "meta": {"api-version": "1.0"}, - "name": packaging.utils.canonicalize_name(name), + "name": packaging_utils.canonicalize_name(name), "files": files, } \ No newline at end of file diff --git a/micropip/freeze.py b/micropip/freeze.py index b4fa9a3..b968bba 100644 --- a/micropip/freeze.py +++ b/micropip/freeze.py @@ -4,9 +4,8 @@ from copy import deepcopy from typing import Any -from packaging.utils import canonicalize_name - from ._utils import fix_package_dependencies +from ._vendored.packaging.utils import canonicalize_name def freeze_lockfile( diff --git a/micropip/install.py b/micropip/install.py index 5e32b50..2e340a4 100644 --- a/micropip/install.py +++ b/micropip/install.py @@ -4,9 +4,8 @@ from pathlib import Path from typing import Any -from packaging.markers import default_environment - from ._compat import loadPackage, to_js +from ._vendored.packaging.markers import default_environment from .constants import FAQ_URLS from .logging import setup_logging from .transaction import Transaction diff --git a/micropip/metadata.py b/micropip/metadata.py index 6809e50..b920cac 100644 --- a/micropip/metadata.py +++ b/micropip/metadata.py @@ -7,8 +7,8 @@ from collections.abc import Iterable from pathlib import Path -from packaging.requirements import Requirement -from packaging.utils import canonicalize_name +from ._vendored.packaging.requirements import Requirement +from ._vendored.packaging.utils import canonicalize_name def safe_name(name): diff --git a/micropip/package.py b/micropip/package.py index d39afa8..85f8388 100644 --- a/micropip/package.py +++ b/micropip/package.py @@ -3,7 +3,7 @@ from dataclasses import astuple, dataclass from typing import Any -from packaging.utils import canonicalize_name +from ._vendored.packaging.utils import canonicalize_name __all__ = ["PackageDict"] diff --git a/micropip/package_index.py b/micropip/package_index.py index 562a252..d0de389 100644 --- a/micropip/package_index.py +++ b/micropip/package_index.py @@ -9,11 +9,10 @@ from typing import Any from urllib.parse import urljoin, urlparse, urlunparse -from packaging.utils import InvalidWheelFilename -from packaging.version import InvalidVersion, Version - from ._compat import HttpStatusError, fetch_string_and_headers from ._utils import is_package_compatible, parse_version +from ._vendored.packaging.utils import InvalidWheelFilename +from ._vendored.packaging.version import InvalidVersion, Version from .externals.mousebender.simple import from_project_details_html from .types import DistributionMetadata from .wheelinfo import WheelInfo diff --git a/micropip/transaction.py b/micropip/transaction.py index f29c48a..60a85f5 100644 --- a/micropip/transaction.py +++ b/micropip/transaction.py @@ -6,12 +6,11 @@ from importlib.metadata import PackageNotFoundError from urllib.parse import urlparse -from packaging.requirements import Requirement -from packaging.utils import canonicalize_name - from . import package_index from ._compat import REPODATA_PACKAGES from ._utils import best_compatible_tag_index, check_compatible +from ._vendored.packaging.requirements import Requirement +from ._vendored.packaging.utils import canonicalize_name from .constants import FAQ_URLS from .package import PackageMetadata from .package_index import ProjectInfo diff --git a/micropip/wheelinfo.py b/micropip/wheelinfo.py index 8e35f69..ba5cb11 100644 --- a/micropip/wheelinfo.py +++ b/micropip/wheelinfo.py @@ -7,10 +7,6 @@ from typing import Any, Literal from urllib.parse import ParseResult, urlparse -from packaging.requirements import Requirement -from packaging.tags import Tag -from packaging.version import Version - from ._compat import ( fetch_bytes, get_dynlibs, @@ -18,6 +14,9 @@ loadedPackages, ) from ._utils import parse_wheel_filename +from ._vendored.packaging.requirements import Requirement +from ._vendored.packaging.tags import Tag +from ._vendored.packaging.version import Version from .metadata import Metadata, safe_name, wheel_dist_info_dir from .types import DistributionMetadata diff --git a/tests/conftest.py b/tests/conftest.py index a1a3a51..fef79f3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,10 +10,11 @@ from typing import Any import pytest -from packaging.utils import parse_wheel_filename from pytest_httpserver import HTTPServer from pytest_pyodide import spawn_web_server +from micropip._vendored.packaging.utils import parse_wheel_filename + def pytest_addoption(parser): parser.addoption( diff --git a/tests/test_install.py b/tests/test_install.py index 9b7f7bc..e6af931 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -1,9 +1,9 @@ import pytest from conftest import mock_fetch_cls -from packaging.utils import parse_wheel_filename from pytest_pyodide import run_in_pyodide import micropip +from micropip._vendored.packaging.utils import parse_wheel_filename def test_install_custom_url(selenium_standalone_micropip, wheel_catalog): diff --git a/tests/test_transaction.py b/tests/test_transaction.py index 714ac46..02a959a 100644 --- a/tests/test_transaction.py +++ b/tests/test_transaction.py @@ -1,6 +1,7 @@ import pytest from conftest import SNOWBALL_WHEEL -from packaging.tags import Tag + +from micropip._vendored.packaging.tags import Tag @pytest.mark.parametrize( @@ -188,8 +189,7 @@ def _pypi_metadata(package, versions_to_tags): def test_last_version_from_pypi(): pytest.importorskip("packaging") - from packaging.requirements import Requirement - + from micropip._vendored.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement("dummy_module") @@ -209,8 +209,7 @@ def test_find_wheel_invalid_version(): it should be skipped instead of producing an error """ pytest.importorskip("packaging") - from packaging.requirements import Requirement - + from micropip._vendored.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement("dummy_module") @@ -245,8 +244,7 @@ def test_find_wheel_invalid_version(): @pytest.mark.parametrize(*_best_tag_test_cases) def test_best_tag_from_pypi(package, version, incompatible_tags, compatible_tags): pytest.importorskip("packaging") - from packaging.requirements import Requirement - + from micropip._vendored.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement(package) @@ -280,8 +278,7 @@ def test_last_version_and_best_tag_from_pypi( package, old_version, new_version, old_tags, new_tags ): pytest.importorskip("packaging") - from packaging.requirements import Requirement - + from micropip._vendored.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement(package) diff --git a/tests/test_uninstall.py b/tests/test_uninstall.py index f862345..a7133f0 100644 --- a/tests/test_uninstall.py +++ b/tests/test_uninstall.py @@ -1,7 +1,7 @@ # isort: skip_file from pytest_pyodide import run_in_pyodide -from packaging.utils import parse_wheel_filename +from micropip._vendored.packaging.utils import parse_wheel_filename TEST_PACKAGE_NAME = "test-wheel-uninstall" From 340ffdb4156d80aabdb9598ec34429dbdfc61eb0 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 18:48:33 +0530 Subject: [PATCH 04/15] Mark TODO item --- micropip/_compat/_compat_not_in_pyodide.py | 1 + 1 file changed, 1 insertion(+) diff --git a/micropip/_compat/_compat_not_in_pyodide.py b/micropip/_compat/_compat_not_in_pyodide.py index 96cc53b..d2dca77 100644 --- a/micropip/_compat/_compat_not_in_pyodide.py +++ b/micropip/_compat/_compat_not_in_pyodide.py @@ -14,6 +14,7 @@ class CompatibilityNotInPyodide(CompatibilityLayer): # Vendored from packaging + # TODO: use packaging APIs here instead? _canonicalize_regex = re.compile(r"[-_.]+") class HttpStatusError(Exception): From cfc48ad743cd58b0be11aa24d15a225b407693fe Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 18:48:49 +0530 Subject: [PATCH 05/15] Drop dependency on `packaging` --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d761a26..01b94cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ classifiers = [ "Operating System :: OS Independent", ] dynamic = ["version"] -dependencies = ["packaging>=23.0"] + [project.optional-dependencies] test = [ "pytest-httpserver", From f2842e54416af4ef6821694d87c36b30cf24d0a0 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 18:49:03 +0530 Subject: [PATCH 06/15] Checkout submodules recursively --- .github/workflows/main.yml | 5 +++++ .github/workflows/remote_package_index_test.yml | 2 ++ 2 files changed, 7 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2a474e0..cbd2519 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,6 +28,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: recursive - uses: actions/setup-python@v5 with: @@ -88,6 +90,7 @@ jobs: - uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb # v4.2.2 with: ref: ${{ github.event.pull_request.head.sha }} + submodules: recursive - id: check-integration-test-trigger name: Check integration test trigger @@ -110,6 +113,8 @@ jobs: environment: PyPi-deploy steps: - uses: actions/checkout@v4 + with: + submodules: recursive - uses: actions/setup-python@v5 with: diff --git a/.github/workflows/remote_package_index_test.yml b/.github/workflows/remote_package_index_test.yml index fb8739f..b341345 100644 --- a/.github/workflows/remote_package_index_test.yml +++ b/.github/workflows/remote_package_index_test.yml @@ -23,6 +23,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: recursive - uses: actions/setup-python@v5 with: From fa8c092fbdb9ac1125566ad528fb8435a9a5ee6a Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 18:49:16 +0530 Subject: [PATCH 07/15] Add a CHANGELOG entry for #178 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8140467..13d710c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 (the ones that starts with `../` or `./`) [#174](https://github.com/pyodide/micropip/pull/174) +### Added + +- `micropip` now vendors `pypa/packaging` for better reliability. + [#178](https://github.com/pyodide/micropip/pull/178) + ## [0.8.0] - 2024/12/15 ### Added From 38c0888434e99fd7197319113e5c9297dc658b4b Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 19:28:17 +0530 Subject: [PATCH 08/15] Adhere to import order and location --- micropip/_utils.py | 18 ++++++++++++------ micropip/externals/mousebender/simple.py | 2 +- micropip/freeze.py | 2 +- micropip/install.py | 2 +- micropip/metadata.py | 4 ++-- micropip/package.py | 2 +- micropip/package_index.py | 4 ++-- micropip/transaction.py | 4 ++-- micropip/wheelinfo.py | 6 +++--- pyproject.toml | 5 +++++ tests/conftest.py | 2 +- tests/test_install.py | 2 +- tests/test_transaction.py | 10 +++++----- tests/test_uninstall.py | 2 +- 14 files changed, 38 insertions(+), 27 deletions(-) diff --git a/micropip/_utils.py b/micropip/_utils.py index 10ed88c..e9bd886 100644 --- a/micropip/_utils.py +++ b/micropip/_utils.py @@ -5,12 +5,18 @@ from sysconfig import get_config_var, get_platform from ._compat import REPODATA_PACKAGES -from ._vendored.packaging.requirements import Requirement -from ._vendored.packaging.tags import Tag -from ._vendored.packaging.tags import sys_tags as sys_tags_orig -from ._vendored.packaging.utils import BuildTag, InvalidWheelFilename, canonicalize_name -from ._vendored.packaging.utils import parse_wheel_filename as parse_wheel_filename_orig -from ._vendored.packaging.version import InvalidVersion, Version +from ._vendored.packaging.src.packaging.requirements import Requirement +from ._vendored.packaging.src.packaging.tags import Tag +from ._vendored.packaging.src.packaging.tags import sys_tags as sys_tags_orig +from ._vendored.packaging.src.packaging.utils import ( + BuildTag, + InvalidWheelFilename, + canonicalize_name, +) +from ._vendored.packaging.src.packaging.utils import ( + parse_wheel_filename as parse_wheel_filename_orig, +) +from ._vendored.packaging.src.packaging.version import InvalidVersion, Version def get_dist_info(dist: Distribution) -> Path: diff --git a/micropip/externals/mousebender/simple.py b/micropip/externals/mousebender/simple.py index dbbf022..3c46068 100644 --- a/micropip/externals/mousebender/simple.py +++ b/micropip/externals/mousebender/simple.py @@ -7,7 +7,7 @@ import warnings from typing import Any, Dict, List, Optional, Union, Literal, TypeAlias, TypedDict -import micropip._vendored.packaging.utils as packaging_utils +import micropip._vendored.packaging.src.packaging.utils as packaging_utils ACCEPT_JSON_V1 = "application/vnd.pypi.simple.v1+json" diff --git a/micropip/freeze.py b/micropip/freeze.py index b968bba..caa8dfb 100644 --- a/micropip/freeze.py +++ b/micropip/freeze.py @@ -5,7 +5,7 @@ from typing import Any from ._utils import fix_package_dependencies -from ._vendored.packaging.utils import canonicalize_name +from ._vendored.packaging.src.packaging.utils import canonicalize_name def freeze_lockfile( diff --git a/micropip/install.py b/micropip/install.py index 2e340a4..ac4a0d8 100644 --- a/micropip/install.py +++ b/micropip/install.py @@ -5,7 +5,7 @@ from typing import Any from ._compat import loadPackage, to_js -from ._vendored.packaging.markers import default_environment +from ._vendored.packaging.src.packaging.markers import default_environment from .constants import FAQ_URLS from .logging import setup_logging from .transaction import Transaction diff --git a/micropip/metadata.py b/micropip/metadata.py index b920cac..0809fc1 100644 --- a/micropip/metadata.py +++ b/micropip/metadata.py @@ -7,8 +7,8 @@ from collections.abc import Iterable from pathlib import Path -from ._vendored.packaging.requirements import Requirement -from ._vendored.packaging.utils import canonicalize_name +from ._vendored.packaging.src.packaging.requirements import Requirement +from ._vendored.packaging.src.packaging.utils import canonicalize_name def safe_name(name): diff --git a/micropip/package.py b/micropip/package.py index 85f8388..c00476e 100644 --- a/micropip/package.py +++ b/micropip/package.py @@ -3,7 +3,7 @@ from dataclasses import astuple, dataclass from typing import Any -from ._vendored.packaging.utils import canonicalize_name +from ._vendored.packaging.src.packaging.utils import canonicalize_name __all__ = ["PackageDict"] diff --git a/micropip/package_index.py b/micropip/package_index.py index d0de389..187e777 100644 --- a/micropip/package_index.py +++ b/micropip/package_index.py @@ -11,8 +11,8 @@ from ._compat import HttpStatusError, fetch_string_and_headers from ._utils import is_package_compatible, parse_version -from ._vendored.packaging.utils import InvalidWheelFilename -from ._vendored.packaging.version import InvalidVersion, Version +from ._vendored.packaging.src.packaging.utils import InvalidWheelFilename +from ._vendored.packaging.src.packaging.version import InvalidVersion, Version from .externals.mousebender.simple import from_project_details_html from .types import DistributionMetadata from .wheelinfo import WheelInfo diff --git a/micropip/transaction.py b/micropip/transaction.py index 60a85f5..f830f05 100644 --- a/micropip/transaction.py +++ b/micropip/transaction.py @@ -9,8 +9,8 @@ from . import package_index from ._compat import REPODATA_PACKAGES from ._utils import best_compatible_tag_index, check_compatible -from ._vendored.packaging.requirements import Requirement -from ._vendored.packaging.utils import canonicalize_name +from ._vendored.packaging.src.packaging.requirements import Requirement +from ._vendored.packaging.src.packaging.utils import canonicalize_name from .constants import FAQ_URLS from .package import PackageMetadata from .package_index import ProjectInfo diff --git a/micropip/wheelinfo.py b/micropip/wheelinfo.py index ba5cb11..3483bef 100644 --- a/micropip/wheelinfo.py +++ b/micropip/wheelinfo.py @@ -14,9 +14,9 @@ loadedPackages, ) from ._utils import parse_wheel_filename -from ._vendored.packaging.requirements import Requirement -from ._vendored.packaging.tags import Tag -from ._vendored.packaging.version import Version +from ._vendored.packaging.src.packaging.requirements import Requirement +from ._vendored.packaging.src.packaging.tags import Tag +from ._vendored.packaging.src.packaging.version import Version from .metadata import Metadata, safe_name, wheel_dist_info_dir from .types import DistributionMetadata diff --git a/pyproject.toml b/pyproject.toml index 01b94cb..4b72842 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,12 @@ known-first-party = [ ] [tool.mypy] +exclude = ["micropip/_vendored/"] python_version = "3.12" show_error_codes = true warn_unreachable = true ignore_missing_imports = true + +[[tool.mypy.overrides]] +module = "micropip._vendored.*" +warn_unreachable = false diff --git a/tests/conftest.py b/tests/conftest.py index fef79f3..ff24ab9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,7 +13,7 @@ from pytest_httpserver import HTTPServer from pytest_pyodide import spawn_web_server -from micropip._vendored.packaging.utils import parse_wheel_filename +from micropip._vendored.packaging.src.packaging.utils import parse_wheel_filename def pytest_addoption(parser): diff --git a/tests/test_install.py b/tests/test_install.py index e6af931..ca5d224 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -3,7 +3,7 @@ from pytest_pyodide import run_in_pyodide import micropip -from micropip._vendored.packaging.utils import parse_wheel_filename +from micropip._vendored.packaging.src.packaging.utils import parse_wheel_filename def test_install_custom_url(selenium_standalone_micropip, wheel_catalog): diff --git a/tests/test_transaction.py b/tests/test_transaction.py index 02a959a..ce199e9 100644 --- a/tests/test_transaction.py +++ b/tests/test_transaction.py @@ -1,7 +1,7 @@ import pytest from conftest import SNOWBALL_WHEEL -from micropip._vendored.packaging.tags import Tag +from micropip._vendored.packaging.src.packaging.tags import Tag @pytest.mark.parametrize( @@ -189,7 +189,7 @@ def _pypi_metadata(package, versions_to_tags): def test_last_version_from_pypi(): pytest.importorskip("packaging") - from micropip._vendored.packaging.requirements import Requirement + from micropip._vendored.packaging.src.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement("dummy_module") @@ -209,7 +209,7 @@ def test_find_wheel_invalid_version(): it should be skipped instead of producing an error """ pytest.importorskip("packaging") - from micropip._vendored.packaging.requirements import Requirement + from micropip._vendored.packaging.src.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement("dummy_module") @@ -244,7 +244,7 @@ def test_find_wheel_invalid_version(): @pytest.mark.parametrize(*_best_tag_test_cases) def test_best_tag_from_pypi(package, version, incompatible_tags, compatible_tags): pytest.importorskip("packaging") - from micropip._vendored.packaging.requirements import Requirement + from micropip._vendored.packaging.src.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement(package) @@ -278,7 +278,7 @@ def test_last_version_and_best_tag_from_pypi( package, old_version, new_version, old_tags, new_tags ): pytest.importorskip("packaging") - from micropip._vendored.packaging.requirements import Requirement + from micropip._vendored.packaging.src.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement(package) diff --git a/tests/test_uninstall.py b/tests/test_uninstall.py index a7133f0..fc3d7a5 100644 --- a/tests/test_uninstall.py +++ b/tests/test_uninstall.py @@ -1,7 +1,7 @@ # isort: skip_file from pytest_pyodide import run_in_pyodide -from micropip._vendored.packaging.utils import parse_wheel_filename +from micropip._vendored.packaging.src.packaging.utils import parse_wheel_filename TEST_PACKAGE_NAME = "test-wheel-uninstall" From e5d9f7da24cdd28e01a3ea07c28d9f8c35f5a25f Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 19:28:31 +0530 Subject: [PATCH 09/15] Keep dependencies list but keep it empty --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 4b72842..936b698 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ classifiers = [ "Operating System :: OS Independent", ] dynamic = ["version"] +dependencies = [] [project.optional-dependencies] test = [ From 1f59b0182471d9ae7675670b602f2ee3c3fa9dc1 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 22:23:17 +0530 Subject: [PATCH 10/15] Redirect imports from `src/packaging/` --- micropip/_utils.py | 12 +-- micropip/_vendored/__init__.py | 97 ++++++++++++++++++++++++ micropip/externals/mousebender/simple.py | 2 +- micropip/freeze.py | 2 +- micropip/install.py | 2 +- micropip/metadata.py | 4 +- micropip/package.py | 2 +- micropip/package_index.py | 4 +- micropip/transaction.py | 4 +- micropip/wheelinfo.py | 6 +- tests/conftest.py | 2 +- tests/test_install.py | 2 +- tests/test_transaction.py | 10 +-- tests/test_uninstall.py | 2 +- 14 files changed, 124 insertions(+), 27 deletions(-) create mode 100644 micropip/_vendored/__init__.py diff --git a/micropip/_utils.py b/micropip/_utils.py index e9bd886..2524f08 100644 --- a/micropip/_utils.py +++ b/micropip/_utils.py @@ -5,18 +5,18 @@ from sysconfig import get_config_var, get_platform from ._compat import REPODATA_PACKAGES -from ._vendored.packaging.src.packaging.requirements import Requirement -from ._vendored.packaging.src.packaging.tags import Tag -from ._vendored.packaging.src.packaging.tags import sys_tags as sys_tags_orig -from ._vendored.packaging.src.packaging.utils import ( +from ._vendored.packaging.requirements import Requirement +from ._vendored.packaging.tags import Tag +from ._vendored.packaging.tags import sys_tags as sys_tags_orig +from ._vendored.packaging.utils import ( BuildTag, InvalidWheelFilename, canonicalize_name, ) -from ._vendored.packaging.src.packaging.utils import ( +from ._vendored.packaging.utils import ( parse_wheel_filename as parse_wheel_filename_orig, ) -from ._vendored.packaging.src.packaging.version import InvalidVersion, Version +from ._vendored.packaging.version import InvalidVersion, Version def get_dist_info(dist: Distribution) -> Path: diff --git a/micropip/_vendored/__init__.py b/micropip/_vendored/__init__.py new file mode 100644 index 0000000..55e8914 --- /dev/null +++ b/micropip/_vendored/__init__.py @@ -0,0 +1,97 @@ +# micropip/_vendored/__init__.py + +# This is a proxy file that redirects imports from micropip._vendored.packaging +# to the actual packaging API present in the packaging/src/packaging directory +# next to this file. + +import importlib.util +import sys +import types +from pathlib import Path + +PACKAGING_PATH = Path(__file__).parent / "packaging" / "src" / "packaging" + + +def _create_module(name, package_path=None): + """ + Creates a module object for the given name and makes it available both under + micropip._vendored.packaging and packaging namespaces. + + Args: + name: The name of the module (without the full package path) + package_path: Optional path to the module file, if different from default location + """ + vendored_name = f"micropip._vendored.packaging.{name}" + direct_name = f"packaging.{name}" + + # If the module is already in sys.modules, return it, and we + # add it to sys.modules under both names before executing it. + if vendored_name in sys.modules: + return sys.modules[vendored_name] + + module = types.ModuleType(vendored_name) + module.__package__ = "micropip._vendored.packaging" + + sys.modules[vendored_name] = module + sys.modules[direct_name] = module + + if package_path is None: + module_path = PACKAGING_PATH / f"{name}.py" + else: + module_path = package_path + + if module_path.exists(): + spec = importlib.util.spec_from_file_location( + vendored_name, module_path, submodule_search_locations=[str(PACKAGING_PATH)] + ) + module.__spec__ = spec + module.__file__ = str(module_path) + loader = spec.loader + loader.exec_module(module) + + return module + + +#################################################### + +packaging_vendored = types.ModuleType("micropip._vendored.packaging") +packaging_direct = types.ModuleType( + "packaging" +) # this is where we redirect the imports. + +packaging_vendored.__path__ = [str(PACKAGING_PATH)] +packaging_vendored.__package__ = "micropip._vendored" +packaging_direct.__path__ = [str(PACKAGING_PATH)] +packaging_direct.__package__ = "" + +sys.modules["micropip._vendored.packaging"] = packaging_vendored +sys.modules["packaging"] = packaging_direct + +#################################################### + +# 1. First, handle any packages: these are directories with __init__.py. +for path in PACKAGING_PATH.glob("*/__init__.py"): + package_name = path.parent.name + module = _create_module(f"{package_name}/__init__", path) + setattr(packaging_vendored, package_name, module) + setattr(packaging_direct, package_name, module) + +# 2. Then, we load all the internal modules +internal_modules = [path.stem for path in PACKAGING_PATH.glob("_*.py")] +for name in internal_modules: + module = _create_module(name) + setattr(packaging_vendored, name, module) + setattr(packaging_direct, name, module) + +# 3. Finally, we'll load all the regular modules (whatever is in the +# public API) +for path in PACKAGING_PATH.glob("*.py"): + if path.stem == "__init__" or path.stem.startswith("_"): + continue + + module = _create_module(path.stem) + setattr(packaging_vendored, path.stem, module) + setattr(packaging_direct, path.stem, module) + + +globals()["packaging"] = packaging_vendored diff --git a/micropip/externals/mousebender/simple.py b/micropip/externals/mousebender/simple.py index 3c46068..dbbf022 100644 --- a/micropip/externals/mousebender/simple.py +++ b/micropip/externals/mousebender/simple.py @@ -7,7 +7,7 @@ import warnings from typing import Any, Dict, List, Optional, Union, Literal, TypeAlias, TypedDict -import micropip._vendored.packaging.src.packaging.utils as packaging_utils +import micropip._vendored.packaging.utils as packaging_utils ACCEPT_JSON_V1 = "application/vnd.pypi.simple.v1+json" diff --git a/micropip/freeze.py b/micropip/freeze.py index caa8dfb..b968bba 100644 --- a/micropip/freeze.py +++ b/micropip/freeze.py @@ -5,7 +5,7 @@ from typing import Any from ._utils import fix_package_dependencies -from ._vendored.packaging.src.packaging.utils import canonicalize_name +from ._vendored.packaging.utils import canonicalize_name def freeze_lockfile( diff --git a/micropip/install.py b/micropip/install.py index ac4a0d8..2e340a4 100644 --- a/micropip/install.py +++ b/micropip/install.py @@ -5,7 +5,7 @@ from typing import Any from ._compat import loadPackage, to_js -from ._vendored.packaging.src.packaging.markers import default_environment +from ._vendored.packaging.markers import default_environment from .constants import FAQ_URLS from .logging import setup_logging from .transaction import Transaction diff --git a/micropip/metadata.py b/micropip/metadata.py index 0809fc1..b920cac 100644 --- a/micropip/metadata.py +++ b/micropip/metadata.py @@ -7,8 +7,8 @@ from collections.abc import Iterable from pathlib import Path -from ._vendored.packaging.src.packaging.requirements import Requirement -from ._vendored.packaging.src.packaging.utils import canonicalize_name +from ._vendored.packaging.requirements import Requirement +from ._vendored.packaging.utils import canonicalize_name def safe_name(name): diff --git a/micropip/package.py b/micropip/package.py index c00476e..85f8388 100644 --- a/micropip/package.py +++ b/micropip/package.py @@ -3,7 +3,7 @@ from dataclasses import astuple, dataclass from typing import Any -from ._vendored.packaging.src.packaging.utils import canonicalize_name +from ._vendored.packaging.utils import canonicalize_name __all__ = ["PackageDict"] diff --git a/micropip/package_index.py b/micropip/package_index.py index 187e777..d0de389 100644 --- a/micropip/package_index.py +++ b/micropip/package_index.py @@ -11,8 +11,8 @@ from ._compat import HttpStatusError, fetch_string_and_headers from ._utils import is_package_compatible, parse_version -from ._vendored.packaging.src.packaging.utils import InvalidWheelFilename -from ._vendored.packaging.src.packaging.version import InvalidVersion, Version +from ._vendored.packaging.utils import InvalidWheelFilename +from ._vendored.packaging.version import InvalidVersion, Version from .externals.mousebender.simple import from_project_details_html from .types import DistributionMetadata from .wheelinfo import WheelInfo diff --git a/micropip/transaction.py b/micropip/transaction.py index f830f05..60a85f5 100644 --- a/micropip/transaction.py +++ b/micropip/transaction.py @@ -9,8 +9,8 @@ from . import package_index from ._compat import REPODATA_PACKAGES from ._utils import best_compatible_tag_index, check_compatible -from ._vendored.packaging.src.packaging.requirements import Requirement -from ._vendored.packaging.src.packaging.utils import canonicalize_name +from ._vendored.packaging.requirements import Requirement +from ._vendored.packaging.utils import canonicalize_name from .constants import FAQ_URLS from .package import PackageMetadata from .package_index import ProjectInfo diff --git a/micropip/wheelinfo.py b/micropip/wheelinfo.py index 3483bef..ba5cb11 100644 --- a/micropip/wheelinfo.py +++ b/micropip/wheelinfo.py @@ -14,9 +14,9 @@ loadedPackages, ) from ._utils import parse_wheel_filename -from ._vendored.packaging.src.packaging.requirements import Requirement -from ._vendored.packaging.src.packaging.tags import Tag -from ._vendored.packaging.src.packaging.version import Version +from ._vendored.packaging.requirements import Requirement +from ._vendored.packaging.tags import Tag +from ._vendored.packaging.version import Version from .metadata import Metadata, safe_name, wheel_dist_info_dir from .types import DistributionMetadata diff --git a/tests/conftest.py b/tests/conftest.py index ff24ab9..fef79f3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,7 +13,7 @@ from pytest_httpserver import HTTPServer from pytest_pyodide import spawn_web_server -from micropip._vendored.packaging.src.packaging.utils import parse_wheel_filename +from micropip._vendored.packaging.utils import parse_wheel_filename def pytest_addoption(parser): diff --git a/tests/test_install.py b/tests/test_install.py index ca5d224..e6af931 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -3,7 +3,7 @@ from pytest_pyodide import run_in_pyodide import micropip -from micropip._vendored.packaging.src.packaging.utils import parse_wheel_filename +from micropip._vendored.packaging.utils import parse_wheel_filename def test_install_custom_url(selenium_standalone_micropip, wheel_catalog): diff --git a/tests/test_transaction.py b/tests/test_transaction.py index ce199e9..02a959a 100644 --- a/tests/test_transaction.py +++ b/tests/test_transaction.py @@ -1,7 +1,7 @@ import pytest from conftest import SNOWBALL_WHEEL -from micropip._vendored.packaging.src.packaging.tags import Tag +from micropip._vendored.packaging.tags import Tag @pytest.mark.parametrize( @@ -189,7 +189,7 @@ def _pypi_metadata(package, versions_to_tags): def test_last_version_from_pypi(): pytest.importorskip("packaging") - from micropip._vendored.packaging.src.packaging.requirements import Requirement + from micropip._vendored.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement("dummy_module") @@ -209,7 +209,7 @@ def test_find_wheel_invalid_version(): it should be skipped instead of producing an error """ pytest.importorskip("packaging") - from micropip._vendored.packaging.src.packaging.requirements import Requirement + from micropip._vendored.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement("dummy_module") @@ -244,7 +244,7 @@ def test_find_wheel_invalid_version(): @pytest.mark.parametrize(*_best_tag_test_cases) def test_best_tag_from_pypi(package, version, incompatible_tags, compatible_tags): pytest.importorskip("packaging") - from micropip._vendored.packaging.src.packaging.requirements import Requirement + from micropip._vendored.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement(package) @@ -278,7 +278,7 @@ def test_last_version_and_best_tag_from_pypi( package, old_version, new_version, old_tags, new_tags ): pytest.importorskip("packaging") - from micropip._vendored.packaging.src.packaging.requirements import Requirement + from micropip._vendored.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement(package) diff --git a/tests/test_uninstall.py b/tests/test_uninstall.py index fc3d7a5..a7133f0 100644 --- a/tests/test_uninstall.py +++ b/tests/test_uninstall.py @@ -1,7 +1,7 @@ # isort: skip_file from pytest_pyodide import run_in_pyodide -from micropip._vendored.packaging.src.packaging.utils import parse_wheel_filename +from micropip._vendored.packaging.utils import parse_wheel_filename TEST_PACKAGE_NAME = "test-wheel-uninstall" From 8a4dfe29c6be6e8e5532d3a72ab281634ab79e7e Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sat, 25 Jan 2025 22:27:41 +0530 Subject: [PATCH 11/15] Add better explanation --- micropip/_vendored/__init__.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/micropip/_vendored/__init__.py b/micropip/_vendored/__init__.py index 55e8914..715c9f0 100644 --- a/micropip/_vendored/__init__.py +++ b/micropip/_vendored/__init__.py @@ -70,21 +70,32 @@ def _create_module(name, package_path=None): #################################################### # 1. First, handle any packages: these are directories with __init__.py. +# 2. Then, we load all the internal modules +# 3. Finally, we'll load all the regular modules (whatever is in the +# public API) +# +# While rudimentary, this order is important because the internal modules +# may depend on subpackages, and regular modules may depend on internal ones. +# +# For example, the metadata.py module imports from licenses, requirements, +# specifiers, and utils. +# +# Similarly, tags.py needs _manylinux and _musllinux to be available. + + for path in PACKAGING_PATH.glob("*/__init__.py"): package_name = path.parent.name module = _create_module(f"{package_name}/__init__", path) setattr(packaging_vendored, package_name, module) setattr(packaging_direct, package_name, module) -# 2. Then, we load all the internal modules internal_modules = [path.stem for path in PACKAGING_PATH.glob("_*.py")] for name in internal_modules: module = _create_module(name) setattr(packaging_vendored, name, module) setattr(packaging_direct, name, module) -# 3. Finally, we'll load all the regular modules (whatever is in the -# public API) + for path in PACKAGING_PATH.glob("*.py"): if path.stem == "__init__" or path.stem.startswith("_"): continue From b30ba384e0737046a17e52e5342812e14338b014 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Mon, 27 Jan 2025 18:13:14 +0530 Subject: [PATCH 12/15] Revert "Add better explanation" This reverts commit 8a4dfe29c6be6e8e5532d3a72ab281634ab79e7e. --- micropip/_vendored/__init__.py | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/micropip/_vendored/__init__.py b/micropip/_vendored/__init__.py index 715c9f0..55e8914 100644 --- a/micropip/_vendored/__init__.py +++ b/micropip/_vendored/__init__.py @@ -70,32 +70,21 @@ def _create_module(name, package_path=None): #################################################### # 1. First, handle any packages: these are directories with __init__.py. -# 2. Then, we load all the internal modules -# 3. Finally, we'll load all the regular modules (whatever is in the -# public API) -# -# While rudimentary, this order is important because the internal modules -# may depend on subpackages, and regular modules may depend on internal ones. -# -# For example, the metadata.py module imports from licenses, requirements, -# specifiers, and utils. -# -# Similarly, tags.py needs _manylinux and _musllinux to be available. - - for path in PACKAGING_PATH.glob("*/__init__.py"): package_name = path.parent.name module = _create_module(f"{package_name}/__init__", path) setattr(packaging_vendored, package_name, module) setattr(packaging_direct, package_name, module) +# 2. Then, we load all the internal modules internal_modules = [path.stem for path in PACKAGING_PATH.glob("_*.py")] for name in internal_modules: module = _create_module(name) setattr(packaging_vendored, name, module) setattr(packaging_direct, name, module) - +# 3. Finally, we'll load all the regular modules (whatever is in the +# public API) for path in PACKAGING_PATH.glob("*.py"): if path.stem == "__init__" or path.stem.startswith("_"): continue From 8c8f0f806d4b141cf79b3b6f4c08330d89543275 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Mon, 27 Jan 2025 18:13:17 +0530 Subject: [PATCH 13/15] Revert "Redirect imports from `src/packaging/`" This reverts commit 1f59b0182471d9ae7675670b602f2ee3c3fa9dc1. --- micropip/_utils.py | 12 +-- micropip/_vendored/__init__.py | 97 ------------------------ micropip/externals/mousebender/simple.py | 2 +- micropip/freeze.py | 2 +- micropip/install.py | 2 +- micropip/metadata.py | 4 +- micropip/package.py | 2 +- micropip/package_index.py | 4 +- micropip/transaction.py | 4 +- micropip/wheelinfo.py | 6 +- tests/conftest.py | 2 +- tests/test_install.py | 2 +- tests/test_transaction.py | 10 +-- tests/test_uninstall.py | 2 +- 14 files changed, 27 insertions(+), 124 deletions(-) delete mode 100644 micropip/_vendored/__init__.py diff --git a/micropip/_utils.py b/micropip/_utils.py index 2524f08..e9bd886 100644 --- a/micropip/_utils.py +++ b/micropip/_utils.py @@ -5,18 +5,18 @@ from sysconfig import get_config_var, get_platform from ._compat import REPODATA_PACKAGES -from ._vendored.packaging.requirements import Requirement -from ._vendored.packaging.tags import Tag -from ._vendored.packaging.tags import sys_tags as sys_tags_orig -from ._vendored.packaging.utils import ( +from ._vendored.packaging.src.packaging.requirements import Requirement +from ._vendored.packaging.src.packaging.tags import Tag +from ._vendored.packaging.src.packaging.tags import sys_tags as sys_tags_orig +from ._vendored.packaging.src.packaging.utils import ( BuildTag, InvalidWheelFilename, canonicalize_name, ) -from ._vendored.packaging.utils import ( +from ._vendored.packaging.src.packaging.utils import ( parse_wheel_filename as parse_wheel_filename_orig, ) -from ._vendored.packaging.version import InvalidVersion, Version +from ._vendored.packaging.src.packaging.version import InvalidVersion, Version def get_dist_info(dist: Distribution) -> Path: diff --git a/micropip/_vendored/__init__.py b/micropip/_vendored/__init__.py deleted file mode 100644 index 55e8914..0000000 --- a/micropip/_vendored/__init__.py +++ /dev/null @@ -1,97 +0,0 @@ -# micropip/_vendored/__init__.py - -# This is a proxy file that redirects imports from micropip._vendored.packaging -# to the actual packaging API present in the packaging/src/packaging directory -# next to this file. - -import importlib.util -import sys -import types -from pathlib import Path - -PACKAGING_PATH = Path(__file__).parent / "packaging" / "src" / "packaging" - - -def _create_module(name, package_path=None): - """ - Creates a module object for the given name and makes it available both under - micropip._vendored.packaging and packaging namespaces. - - Args: - name: The name of the module (without the full package path) - package_path: Optional path to the module file, if different from default location - """ - vendored_name = f"micropip._vendored.packaging.{name}" - direct_name = f"packaging.{name}" - - # If the module is already in sys.modules, return it, and we - # add it to sys.modules under both names before executing it. - if vendored_name in sys.modules: - return sys.modules[vendored_name] - - module = types.ModuleType(vendored_name) - module.__package__ = "micropip._vendored.packaging" - - sys.modules[vendored_name] = module - sys.modules[direct_name] = module - - if package_path is None: - module_path = PACKAGING_PATH / f"{name}.py" - else: - module_path = package_path - - if module_path.exists(): - spec = importlib.util.spec_from_file_location( - vendored_name, module_path, submodule_search_locations=[str(PACKAGING_PATH)] - ) - module.__spec__ = spec - module.__file__ = str(module_path) - loader = spec.loader - loader.exec_module(module) - - return module - - -#################################################### - -packaging_vendored = types.ModuleType("micropip._vendored.packaging") -packaging_direct = types.ModuleType( - "packaging" -) # this is where we redirect the imports. - -packaging_vendored.__path__ = [str(PACKAGING_PATH)] -packaging_vendored.__package__ = "micropip._vendored" -packaging_direct.__path__ = [str(PACKAGING_PATH)] -packaging_direct.__package__ = "" - -sys.modules["micropip._vendored.packaging"] = packaging_vendored -sys.modules["packaging"] = packaging_direct - -#################################################### - -# 1. First, handle any packages: these are directories with __init__.py. -for path in PACKAGING_PATH.glob("*/__init__.py"): - package_name = path.parent.name - module = _create_module(f"{package_name}/__init__", path) - setattr(packaging_vendored, package_name, module) - setattr(packaging_direct, package_name, module) - -# 2. Then, we load all the internal modules -internal_modules = [path.stem for path in PACKAGING_PATH.glob("_*.py")] -for name in internal_modules: - module = _create_module(name) - setattr(packaging_vendored, name, module) - setattr(packaging_direct, name, module) - -# 3. Finally, we'll load all the regular modules (whatever is in the -# public API) -for path in PACKAGING_PATH.glob("*.py"): - if path.stem == "__init__" or path.stem.startswith("_"): - continue - - module = _create_module(path.stem) - setattr(packaging_vendored, path.stem, module) - setattr(packaging_direct, path.stem, module) - - -globals()["packaging"] = packaging_vendored diff --git a/micropip/externals/mousebender/simple.py b/micropip/externals/mousebender/simple.py index dbbf022..3c46068 100644 --- a/micropip/externals/mousebender/simple.py +++ b/micropip/externals/mousebender/simple.py @@ -7,7 +7,7 @@ import warnings from typing import Any, Dict, List, Optional, Union, Literal, TypeAlias, TypedDict -import micropip._vendored.packaging.utils as packaging_utils +import micropip._vendored.packaging.src.packaging.utils as packaging_utils ACCEPT_JSON_V1 = "application/vnd.pypi.simple.v1+json" diff --git a/micropip/freeze.py b/micropip/freeze.py index b968bba..caa8dfb 100644 --- a/micropip/freeze.py +++ b/micropip/freeze.py @@ -5,7 +5,7 @@ from typing import Any from ._utils import fix_package_dependencies -from ._vendored.packaging.utils import canonicalize_name +from ._vendored.packaging.src.packaging.utils import canonicalize_name def freeze_lockfile( diff --git a/micropip/install.py b/micropip/install.py index 2e340a4..ac4a0d8 100644 --- a/micropip/install.py +++ b/micropip/install.py @@ -5,7 +5,7 @@ from typing import Any from ._compat import loadPackage, to_js -from ._vendored.packaging.markers import default_environment +from ._vendored.packaging.src.packaging.markers import default_environment from .constants import FAQ_URLS from .logging import setup_logging from .transaction import Transaction diff --git a/micropip/metadata.py b/micropip/metadata.py index b920cac..0809fc1 100644 --- a/micropip/metadata.py +++ b/micropip/metadata.py @@ -7,8 +7,8 @@ from collections.abc import Iterable from pathlib import Path -from ._vendored.packaging.requirements import Requirement -from ._vendored.packaging.utils import canonicalize_name +from ._vendored.packaging.src.packaging.requirements import Requirement +from ._vendored.packaging.src.packaging.utils import canonicalize_name def safe_name(name): diff --git a/micropip/package.py b/micropip/package.py index 85f8388..c00476e 100644 --- a/micropip/package.py +++ b/micropip/package.py @@ -3,7 +3,7 @@ from dataclasses import astuple, dataclass from typing import Any -from ._vendored.packaging.utils import canonicalize_name +from ._vendored.packaging.src.packaging.utils import canonicalize_name __all__ = ["PackageDict"] diff --git a/micropip/package_index.py b/micropip/package_index.py index d0de389..187e777 100644 --- a/micropip/package_index.py +++ b/micropip/package_index.py @@ -11,8 +11,8 @@ from ._compat import HttpStatusError, fetch_string_and_headers from ._utils import is_package_compatible, parse_version -from ._vendored.packaging.utils import InvalidWheelFilename -from ._vendored.packaging.version import InvalidVersion, Version +from ._vendored.packaging.src.packaging.utils import InvalidWheelFilename +from ._vendored.packaging.src.packaging.version import InvalidVersion, Version from .externals.mousebender.simple import from_project_details_html from .types import DistributionMetadata from .wheelinfo import WheelInfo diff --git a/micropip/transaction.py b/micropip/transaction.py index 60a85f5..f830f05 100644 --- a/micropip/transaction.py +++ b/micropip/transaction.py @@ -9,8 +9,8 @@ from . import package_index from ._compat import REPODATA_PACKAGES from ._utils import best_compatible_tag_index, check_compatible -from ._vendored.packaging.requirements import Requirement -from ._vendored.packaging.utils import canonicalize_name +from ._vendored.packaging.src.packaging.requirements import Requirement +from ._vendored.packaging.src.packaging.utils import canonicalize_name from .constants import FAQ_URLS from .package import PackageMetadata from .package_index import ProjectInfo diff --git a/micropip/wheelinfo.py b/micropip/wheelinfo.py index ba5cb11..3483bef 100644 --- a/micropip/wheelinfo.py +++ b/micropip/wheelinfo.py @@ -14,9 +14,9 @@ loadedPackages, ) from ._utils import parse_wheel_filename -from ._vendored.packaging.requirements import Requirement -from ._vendored.packaging.tags import Tag -from ._vendored.packaging.version import Version +from ._vendored.packaging.src.packaging.requirements import Requirement +from ._vendored.packaging.src.packaging.tags import Tag +from ._vendored.packaging.src.packaging.version import Version from .metadata import Metadata, safe_name, wheel_dist_info_dir from .types import DistributionMetadata diff --git a/tests/conftest.py b/tests/conftest.py index fef79f3..ff24ab9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,7 +13,7 @@ from pytest_httpserver import HTTPServer from pytest_pyodide import spawn_web_server -from micropip._vendored.packaging.utils import parse_wheel_filename +from micropip._vendored.packaging.src.packaging.utils import parse_wheel_filename def pytest_addoption(parser): diff --git a/tests/test_install.py b/tests/test_install.py index e6af931..ca5d224 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -3,7 +3,7 @@ from pytest_pyodide import run_in_pyodide import micropip -from micropip._vendored.packaging.utils import parse_wheel_filename +from micropip._vendored.packaging.src.packaging.utils import parse_wheel_filename def test_install_custom_url(selenium_standalone_micropip, wheel_catalog): diff --git a/tests/test_transaction.py b/tests/test_transaction.py index 02a959a..ce199e9 100644 --- a/tests/test_transaction.py +++ b/tests/test_transaction.py @@ -1,7 +1,7 @@ import pytest from conftest import SNOWBALL_WHEEL -from micropip._vendored.packaging.tags import Tag +from micropip._vendored.packaging.src.packaging.tags import Tag @pytest.mark.parametrize( @@ -189,7 +189,7 @@ def _pypi_metadata(package, versions_to_tags): def test_last_version_from_pypi(): pytest.importorskip("packaging") - from micropip._vendored.packaging.requirements import Requirement + from micropip._vendored.packaging.src.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement("dummy_module") @@ -209,7 +209,7 @@ def test_find_wheel_invalid_version(): it should be skipped instead of producing an error """ pytest.importorskip("packaging") - from micropip._vendored.packaging.requirements import Requirement + from micropip._vendored.packaging.src.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement("dummy_module") @@ -244,7 +244,7 @@ def test_find_wheel_invalid_version(): @pytest.mark.parametrize(*_best_tag_test_cases) def test_best_tag_from_pypi(package, version, incompatible_tags, compatible_tags): pytest.importorskip("packaging") - from micropip._vendored.packaging.requirements import Requirement + from micropip._vendored.packaging.src.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement(package) @@ -278,7 +278,7 @@ def test_last_version_and_best_tag_from_pypi( package, old_version, new_version, old_tags, new_tags ): pytest.importorskip("packaging") - from micropip._vendored.packaging.requirements import Requirement + from micropip._vendored.packaging.src.packaging.requirements import Requirement from micropip.transaction import find_wheel requirement = Requirement(package) diff --git a/tests/test_uninstall.py b/tests/test_uninstall.py index a7133f0..fc3d7a5 100644 --- a/tests/test_uninstall.py +++ b/tests/test_uninstall.py @@ -1,7 +1,7 @@ # isort: skip_file from pytest_pyodide import run_in_pyodide -from micropip._vendored.packaging.utils import parse_wheel_filename +from micropip._vendored.packaging.src.packaging.utils import parse_wheel_filename TEST_PACKAGE_NAME = "test-wheel-uninstall" From e6932b21263f0a128d26556a7325b449a9b008c9 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Mon, 27 Jan 2025 18:28:35 +0530 Subject: [PATCH 14/15] Exclude unncessary files from vendored `packaging` --- .github/workflows/main.yml | 4 ++++ MANIFEST.in | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 MANIFEST.in diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cbd2519..787d505 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -119,11 +119,15 @@ jobs: - uses: actions/setup-python@v5 with: python-version: 3.12 + + # IMPORTANT: always build sdist, and then the wheel from + # the sdist (like it is currently done here). - name: Install requirements and build wheel shell: bash -l {0} run: | python -m pip install build twine python -m build . + - name: Publish package uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..93030c1 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,16 @@ +exclude micropip/_vendored/packaging/.github/* +exclude micropip/_vendored/packaging/docs/* +exclude micropip/_vendored/packaging/tasks/* +exclude micropip/_vendored/packaging/tests/* +exclude micropip/_vendored/packaging/.pre-commit-config.yaml +exclude micropip/_vendored/packaging/.readthedocs.yml +exclude micropip/_vendored/packaging/CHANGELOG.rst +exclude micropip/_vendored/packaging/CONTRIBUTING.rst +exclude micropip/_vendored/packaging/noxfile.py +exclude micropip/_vendored/packaging/pyproject.toml + +include micropip/_vendored/packaging/LICENSE +include micropip/_vendored/packaging/LICENSE.APACHE +include micropip/_vendored/packaging/LICENSE.BSD + +include micropip/_vendored/packaging/README.rst From f9b51725c0bda81a1b79668371e83c5adf89fe76 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Wed, 29 Jan 2025 05:45:38 +0530 Subject: [PATCH 15/15] Add reason about building from sdist --- .github/workflows/main.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 787d505..cdc899a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,7 +19,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - pyodide-version: ['0.27.0a2'] + pyodide-version: ["0.27.0a2"] test-config: [ # FIXME: recent version of chrome gets timeout {runner: selenium, runtime: chrome, runtime-version: "125" }, @@ -121,7 +121,11 @@ jobs: python-version: 3.12 # IMPORTANT: always build sdist, and then the wheel from - # the sdist (like it is currently done here). + # the sdist (like it is currently done here). This is + # because we want to ensure that no extra files get + # copied, which can be the case with building in-tree. + # The MANIFEST.in file ensures that the sdist doesn't + # contain any unnecessary files. - name: Install requirements and build wheel shell: bash -l {0} run: |