diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 833a3217..00000000 --- a/.coveragerc +++ /dev/null @@ -1,19 +0,0 @@ -[run] -omit = - # leading `*/` for pytest-dev/pytest-cov#456 - */.tox/* - */pep517-build-env-* - tests/* - prepare/* - */_itertools.py - exercises.py - */pip-run-* -disable_warnings = - couldnt-parse - -[report] -show_missing = True -exclude_also = - # jaraco/skeleton#97 - @overload - if TYPE_CHECKING: diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 304196f8..00000000 --- a/.editorconfig +++ /dev/null @@ -1,19 +0,0 @@ -root = true - -[*] -charset = utf-8 -indent_style = tab -indent_size = 4 -insert_final_newline = true -end_of_line = lf - -[*.py] -indent_style = space -max_line_length = 88 - -[*.{yml,yaml}] -indent_style = space -indent_size = 2 - -[*.rst] -indent_style = space diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 5cbfe040..00000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -tidelift: pypi/importlib-metadata diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 89ff3396..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,8 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "pip" - directory: "/" - schedule: - interval: "daily" - allow: - - dependency-type: "all" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index ac0ff69e..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,122 +0,0 @@ -name: tests - -on: - merge_group: - push: - branches-ignore: - # temporary GH branches relating to merge queues (jaraco/skeleton#93) - - gh-readonly-queue/** - tags: - # required if branches-ignore is supplied (jaraco/skeleton#103) - - '**' - pull_request: - -permissions: - contents: read - -env: - # Environment variable to support color support (jaraco/skeleton#66) - FORCE_COLOR: 1 - - # Suppress noisy pip warnings - PIP_DISABLE_PIP_VERSION_CHECK: 'true' - PIP_NO_PYTHON_VERSION_WARNING: 'true' - PIP_NO_WARN_SCRIPT_LOCATION: 'true' - - # Ensure tests can sense settings about the environment - TOX_OVERRIDE: >- - testenv.pass_env+=GITHUB_*,FORCE_COLOR - - -jobs: - test: - strategy: - # https://blog.jaraco.com/efficient-use-of-ci-resources/ - matrix: - python: - - "3.8" - - "3.12" - platform: - - ubuntu-latest - - macos-latest - - windows-latest - include: - - python: "3.9" - platform: ubuntu-latest - - python: "3.10" - platform: ubuntu-latest - - python: "3.11" - platform: ubuntu-latest - - python: pypy3.10 - platform: ubuntu-latest - runs-on: ${{ matrix.platform }} - continue-on-error: ${{ matrix.python == '3.13' }} - steps: - - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python }} - allow-prereleases: true - - name: Install tox - run: python -m pip install tox - - name: Run - run: tox - - collateral: - strategy: - fail-fast: false - matrix: - job: - - diffcov - - docs - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: 3.x - - name: Install tox - run: python -m pip install tox - - name: Eval ${{ matrix.job }} - run: tox -e ${{ matrix.job }} - - check: # This job does nothing and is only used for the branch protection - if: always() - - needs: - - test - - collateral - - runs-on: ubuntu-latest - - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} - - release: - permissions: - contents: write - needs: - - check - if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: 3.x - - name: Install tox - run: python -m pip install tox - - name: Run - run: tox -e release - env: - TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index ae864d61..00000000 --- a/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -build -/coverage.xml -/diffcov.html -htmlcov -importlib_metadata.egg-info -.mypy_cache -/.coverage -/.DS_Store -artifacts -.eggs -.doctrees -dist -pip-wheel-metadata diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 5a4a7e91..00000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -repos: -- repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.8 - hooks: - - id: ruff - - id: ruff-format diff --git a/.readthedocs.yaml b/.readthedocs.yaml deleted file mode 100644 index dc8516ac..00000000 --- a/.readthedocs.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: 2 -python: - install: - - path: . - extra_requirements: - - doc - -# required boilerplate readthedocs/readthedocs.org#10401 -build: - os: ubuntu-lts-latest - tools: - python: latest - # post-checkout job to ensure the clone isn't shallow jaraco/skeleton#114 - jobs: - post_checkout: - - git fetch --unshallow || true diff --git a/LICENSE b/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/importlib_metadata/__init__.py b/Lib/importlib/metadata/__init__.py similarity index 98% rename from importlib_metadata/__init__.py rename to Lib/importlib/metadata/__init__.py index 2c71d33c..b59587e8 100644 --- a/importlib_metadata/__init__.py +++ b/Lib/importlib/metadata/__init__.py @@ -5,11 +5,11 @@ import abc import sys import json -import zipp import email import types import inspect import pathlib +import zipfile import operator import textwrap import functools @@ -18,12 +18,7 @@ import collections from . import _meta -from .compat import py39, py311 from ._collections import FreezableDefaultDict, Pair -from ._compat import ( - NullFinder, - install, -) from ._functools import method_cache, pass_none from ._itertools import always_iterable, bucket, unique_everseen from ._meta import PackageMetadata, SimplePath @@ -280,7 +275,7 @@ def select(self, **params) -> EntryPoints: Select entry points from self that match the given parameters (typically group and/or name). """ - return EntryPoints(ep for ep in self if py39.ep_matches(ep, **params)) + return EntryPoints(ep for ep in self if ep.matches(**params)) @property def names(self) -> Set[str]: @@ -560,7 +555,8 @@ def _read_files_egginfo_installed(self): return paths = ( - py311.relative_fix((subdir / name).resolve()) + (subdir / name) + .resolve() .relative_to(self.locate_file('').resolve(), walk_up=True) .as_posix() for name in text.splitlines() @@ -741,7 +737,7 @@ def children(self): return [] def zip_children(self): - zip_path = zipp.Path(self.root) + zip_path = zipfile.Path(self.root) names = zip_path.root.namelist() self.joinpath = zip_path.joinpath @@ -861,14 +857,7 @@ def __bool__(self): return bool(self.name) -@install -class MetadataPathFinder(NullFinder, DistributionFinder): - """A degenerate finder for distribution packages on the file system. - - This finder supplies only a find_distributions() method for versions - of Python that do not have a PathFinder find_distributions(). - """ - +class MetadataPathFinder(DistributionFinder): @classmethod def find_distributions( cls, context=DistributionFinder.Context() @@ -990,7 +979,7 @@ def version(distribution_name: str) -> str: _unique = functools.partial( unique_everseen, - key=py39.normalized_name, + key=operator.attrgetter('_normalized_name'), ) """ Wrapper for ``distributions`` to return unique distributions by name. diff --git a/importlib_metadata/_adapters.py b/Lib/importlib/metadata/_adapters.py similarity index 100% rename from importlib_metadata/_adapters.py rename to Lib/importlib/metadata/_adapters.py diff --git a/importlib_metadata/_collections.py b/Lib/importlib/metadata/_collections.py similarity index 100% rename from importlib_metadata/_collections.py rename to Lib/importlib/metadata/_collections.py diff --git a/importlib_metadata/_functools.py b/Lib/importlib/metadata/_functools.py similarity index 100% rename from importlib_metadata/_functools.py rename to Lib/importlib/metadata/_functools.py diff --git a/importlib_metadata/_itertools.py b/Lib/importlib/metadata/_itertools.py similarity index 100% rename from importlib_metadata/_itertools.py rename to Lib/importlib/metadata/_itertools.py diff --git a/importlib_metadata/_meta.py b/Lib/importlib/metadata/_meta.py similarity index 100% rename from importlib_metadata/_meta.py rename to Lib/importlib/metadata/_meta.py diff --git a/importlib_metadata/_text.py b/Lib/importlib/metadata/_text.py similarity index 100% rename from importlib_metadata/_text.py rename to Lib/importlib/metadata/_text.py diff --git a/importlib_metadata/diagnose.py b/Lib/importlib/metadata/diagnose.py similarity index 100% rename from importlib_metadata/diagnose.py rename to Lib/importlib/metadata/diagnose.py diff --git a/tests/_context.py b/Lib/test/test_importlib/metadata/_context.py similarity index 100% rename from tests/_context.py rename to Lib/test/test_importlib/metadata/_context.py diff --git a/tests/_path.py b/Lib/test/test_importlib/metadata/_path.py similarity index 100% rename from tests/_path.py rename to Lib/test/test_importlib/metadata/_path.py diff --git a/docs/__init__.py b/Lib/test/test_importlib/metadata/data/__init__.py similarity index 100% rename from docs/__init__.py rename to Lib/test/test_importlib/metadata/data/__init__.py diff --git a/tests/data/example-21.12-py3-none-any.whl b/Lib/test/test_importlib/metadata/data/example-21.12-py3-none-any.whl similarity index 100% rename from tests/data/example-21.12-py3-none-any.whl rename to Lib/test/test_importlib/metadata/data/example-21.12-py3-none-any.whl diff --git a/tests/data/example-21.12-py3.6.egg b/Lib/test/test_importlib/metadata/data/example-21.12-py3.6.egg similarity index 100% rename from tests/data/example-21.12-py3.6.egg rename to Lib/test/test_importlib/metadata/data/example-21.12-py3.6.egg diff --git a/tests/data/example2-1.0.0-py3-none-any.whl b/Lib/test/test_importlib/metadata/data/example2-1.0.0-py3-none-any.whl similarity index 100% rename from tests/data/example2-1.0.0-py3-none-any.whl rename to Lib/test/test_importlib/metadata/data/example2-1.0.0-py3-none-any.whl diff --git a/tests/data/sources/example/example/__init__.py b/Lib/test/test_importlib/metadata/data/sources/example/example/__init__.py similarity index 100% rename from tests/data/sources/example/example/__init__.py rename to Lib/test/test_importlib/metadata/data/sources/example/example/__init__.py diff --git a/tests/data/sources/example/setup.py b/Lib/test/test_importlib/metadata/data/sources/example/setup.py similarity index 100% rename from tests/data/sources/example/setup.py rename to Lib/test/test_importlib/metadata/data/sources/example/setup.py diff --git a/tests/data/sources/example2/example2/__init__.py b/Lib/test/test_importlib/metadata/data/sources/example2/example2/__init__.py similarity index 100% rename from tests/data/sources/example2/example2/__init__.py rename to Lib/test/test_importlib/metadata/data/sources/example2/example2/__init__.py diff --git a/tests/data/sources/example2/pyproject.toml b/Lib/test/test_importlib/metadata/data/sources/example2/pyproject.toml similarity index 100% rename from tests/data/sources/example2/pyproject.toml rename to Lib/test/test_importlib/metadata/data/sources/example2/pyproject.toml diff --git a/tests/fixtures.py b/Lib/test/test_importlib/metadata/fixtures.py similarity index 98% rename from tests/fixtures.py rename to Lib/test/test_importlib/metadata/fixtures.py index 187f1705..826b1b32 100644 --- a/tests/fixtures.py +++ b/Lib/test/test_importlib/metadata/fixtures.py @@ -7,8 +7,9 @@ import functools import contextlib -from .compat.py312 import import_helper -from .compat.py39 import os_helper +from test.support import import_helper +from test.support import os_helper +from test.support import requires_zlib from . import _path from ._path import FilesSpec @@ -362,8 +363,9 @@ def DALS(str): return textwrap.dedent(str).lstrip() +@requires_zlib() class ZipFixtures: - root = 'tests.data' + root = 'test.test_importlib.metadata.data' def _fixture_on_path(self, filename): pkg_file = resources.files(self.root).joinpath(filename) diff --git a/Lib/test/test_importlib/metadata/stubs.py b/Lib/test/test_importlib/metadata/stubs.py new file mode 100644 index 00000000..e5b011c3 --- /dev/null +++ b/Lib/test/test_importlib/metadata/stubs.py @@ -0,0 +1,10 @@ +import unittest + + +class fake_filesystem_unittest: + """ + Stubbed version of the pyfakefs module + """ + class TestCase(unittest.TestCase): + def setUpPyfakefs(self): + self.skipTest("pyfakefs not available") diff --git a/tests/test_api.py b/Lib/test/test_importlib/metadata/test_api.py similarity index 98% rename from tests/test_api.py rename to Lib/test/test_importlib/metadata/test_api.py index 7ce0cd64..813febf2 100644 --- a/tests/test_api.py +++ b/Lib/test/test_importlib/metadata/test_api.py @@ -4,7 +4,7 @@ import importlib from . import fixtures -from importlib_metadata import ( +from importlib.metadata import ( Distribution, PackageNotFoundError, distribution, @@ -144,10 +144,6 @@ def test_metadata_for_this_package(self): classifiers = md.get_all('Classifier') assert 'Topic :: Software Development :: Libraries' in classifiers - def test_importlib_metadata_version(self): - resolved = version('importlib-metadata') - assert re.match(self.version_pattern, resolved) - def test_missing_key(self): """ Requesting a missing key raises KeyError. diff --git a/tests/test_main.py b/Lib/test/test_importlib/metadata/test_main.py similarity index 97% rename from tests/test_main.py rename to Lib/test/test_importlib/metadata/test_main.py index dc248492..a0bc8222 100644 --- a/tests/test_main.py +++ b/Lib/test/test_importlib/metadata/test_main.py @@ -2,14 +2,17 @@ import pickle import unittest import importlib -import importlib_metadata -from .compat.py39 import os_helper +import importlib.metadata +from test.support import os_helper -import pyfakefs.fake_filesystem_unittest as ffs +try: + import pyfakefs.fake_filesystem_unittest as ffs +except ImportError: + from .stubs import fake_filesystem_unittest as ffs from . import fixtures from ._path import Symlink -from importlib_metadata import ( +from importlib.metadata import ( Distribution, EntryPoint, PackageNotFoundError, @@ -77,10 +80,10 @@ def test_entrypoint_with_colon_in_name(self): def test_resolve_without_attr(self): ep = EntryPoint( name='ep', - value='importlib_metadata', + value='importlib.metadata', group='grp', ) - assert ep.load() is importlib_metadata + assert ep.load() is importlib.metadata class NameNormalizationTests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): @@ -258,7 +261,7 @@ def test_discovery(self): Discovering distributions should succeed even if there is an invalid path on sys.path. """ - importlib_metadata.distributions() + importlib.metadata.distributions() class InaccessibleSysPath(fixtures.OnSysPath, ffs.TestCase): @@ -274,13 +277,13 @@ def test_discovery(self): Discovering distributions should succeed even if there is an invalid path on sys.path. """ - list(importlib_metadata.distributions()) + list(importlib.metadata.distributions()) class TestEntryPoints(unittest.TestCase): def __init__(self, *args): super().__init__(*args) - self.ep = importlib_metadata.EntryPoint( + self.ep = importlib.metadata.EntryPoint( name='name', value='value', group='group' ) diff --git a/tests/test_zip.py b/Lib/test/test_importlib/metadata/test_zip.py similarity index 98% rename from tests/test_zip.py rename to Lib/test/test_importlib/metadata/test_zip.py index 01aba6df..276f6288 100644 --- a/tests/test_zip.py +++ b/Lib/test/test_importlib/metadata/test_zip.py @@ -2,7 +2,7 @@ import unittest from . import fixtures -from importlib_metadata import ( +from importlib.metadata import ( PackageNotFoundError, distribution, distributions, diff --git a/NEWS.rst b/NEWS.rst deleted file mode 100644 index 2e22a335..00000000 --- a/NEWS.rst +++ /dev/null @@ -1,971 +0,0 @@ -v8.2.0 -====== - -Features --------- - -- Add SimplePath to importlib_metadata.__all__. (#494) - - -v8.1.0 -====== - -Features --------- - -- Prioritize valid dists to invalid dists when retrieving by name. (#489) - - -v8.0.0 -====== - -Deprecations and Removals -------------------------- - -- Message.__getitem__ now raises a KeyError on missing keys. (#371) -- Removed deprecated support for Distribution subclasses not implementing abstract methods. - - -v7.2.1 -====== - -Bugfixes --------- - -- When reading installed files from an egg, use ``relative_to(walk_up=True)`` to honor files installed outside of the installation root. (#455) - - -v7.2.0 -====== - -Features --------- - -- Deferred select imports in for speedup (python/cpython#109829). -- Updated fixtures for python/cpython#120801. - - -v7.1.0 -====== - -Features --------- - -- Improve import time (python/cpython#114664). - - -Bugfixes --------- - -- Make MetadataPathFinder.find_distributions a classmethod for consistency with CPython. Closes #484. (#484) -- Allow ``MetadataPathFinder.invalidate_caches`` to be called as a classmethod. - - -v7.0.2 -====== - -No significant changes. - - -v7.0.1 -====== - -Bugfixes --------- - -- Corrected the interface for SimplePath to encompass the expectations of locate_file and PackagePath. -- Fixed type annotations to allow strings. - - -v7.0.0 -====== - -Deprecations and Removals -------------------------- - -- Removed EntryPoint access by numeric index (tuple behavior). - - -v6.11.0 -======= - -Features --------- - -- Added ``Distribution.origin`` supplying the ``direct_url.json`` in a ``SimpleNamespace``. (#404) - - -v6.10.0 -======= - -Features --------- - -- Added diagnose script. (#461) - - -v6.9.0 -====== - -Features --------- - -- Added EntryPoints.__repr__ (#473) - - -v6.8.0 -====== - -Features --------- - -- Require Python 3.8 or later. - - -v6.7.0 -====== - -* #453: When inferring top-level names that are importable for - distributions in ``package_distributions``, now symlinks to - other directories are honored. - -v6.6.0 -====== - -* #449: Expanded type annotations. - -v6.5.1 -====== - -* python/cpython#103661: Removed excess error suppression in - ``_read_files_egginfo_installed`` and fixed path handling - on Windows. - -v6.5.0 -====== - -* #422: Removed ABC metaclass from ``Distribution`` and instead - deprecated construction of ``Distribution`` objects without - concrete methods. - -v6.4.1 -====== - -* Updated docs with tweaks from upstream CPython. - -v6.4.0 -====== - -* Consolidated some behaviors in tests around ``_path``. -* Added type annotation for ``Distribution.read_text``. - -v6.3.0 -====== - -* #115: Support ``installed-files.txt`` for ``Distribution.files`` - when present. - -v6.2.1 -====== - -* #442: Fixed issue introduced in v6.1.0 where non-importable - names (metadata dirs) began appearing in - ``packages_distributions``. - -v6.2.0 -====== - -* #384: ``PackageMetadata`` now stipulates an additional ``get`` - method allowing for easy querying of metadata keys that may not - be present. - -v6.1.0 -====== - -* #428: ``packages_distributions`` now honors packages and modules - with Python modules that not ``.py`` sources (e.g. ``.pyc``, - ``.so``). - -v6.0.1 -====== - -* #434: Expand protocol for ``PackageMetadata.get_all`` to match - the upstream implementation of ``email.message.Message.get_all`` - in python/typeshed#9620. - -v6.0.0 -====== - -* #419: Declared ``Distribution`` as an abstract class, enforcing - definition of abstract methods in instantiated subclasses. It's no - longer possible to instantiate a ``Distribution`` or any subclasses - unless they define the abstract methods. - - Please comment in the issue if this change breaks any projects. - This change will likely be rolled back if it causes significant - disruption. - -v5.2.0 -====== - -* #371: Deprecated expectation that ``PackageMetadata.__getitem__`` - will return ``None`` for missing keys. In the future, it will raise a - ``KeyError``. - -v5.1.0 -====== - -* #415: Instrument ``SimplePath`` with generic support. - -v5.0.0 -====== - -* #97, #284, #300: Removed compatibility shims for deprecated entry - point interfaces. - -v4.13.0 -======= - -* #396: Added compatibility for ``PathDistributions`` originating - from Python 3.8 and 3.9. - -v4.12.0 -======= - -* py-93259: Now raise ``ValueError`` when ``None`` or an empty - string are passed to ``Distribution.from_name`` (and other - callers). - -v4.11.4 -======= - -* #379: In ``PathDistribution._name_from_stem``, avoid including - parts of the extension in the result. -* #381: In ``PathDistribution._normalized_name``, ensure names - loaded from the stem of the filename are also normalized, ensuring - duplicate entry points by packages varying only by non-normalized - name are hidden. - -Note (#459): This change had a backward-incompatible effect for -any installers that created metadata in the filesystem with dashes -in the package names (not replaced by underscores). - -v4.11.3 -======= - -* #372: Removed cast of path items in FastPath, not needed. - -v4.11.2 -======= - -* #369: Fixed bug where ``EntryPoint.extras`` was returning - match objects and not the extras strings. - -v4.11.1 -======= - -* #367: In ``Distribution.requires`` for egg-info, if ``requires.txt`` - is empty, return an empty list. - -v4.11.0 -======= - -* bpo-46246: Added ``__slots__`` to ``EntryPoints``. - -v4.10.2 -======= - -* #365 and bpo-46546: Avoid leaking ``method_name`` in - ``DeprecatedList``. - -v4.10.1 -======= - -v2.1.3 -======= - -* #361: Avoid potential REDoS in ``EntryPoint.pattern``. - -v4.10.0 -======= - -* #354: Removed ``Distribution._local`` factory. This - functionality was created as a demonstration of the - possible implementation. Now, the - `pep517 `_ package - provides this functionality directly through - `pep517.meta.load `_. - -v4.9.0 -====== - -* Require Python 3.7 or later. - -v4.8.3 -====== - -* #357: Fixed requirement generation from egg-info when a - URL requirement is given. - -v4.8.2 -====== - -v2.1.2 -====== - -* #353: Fixed discovery of distributions when path is empty. - -v4.8.1 -====== - -* #348: Restored support for ``EntryPoint`` access by item, - deprecating support in the process. Users are advised - to use direct member access instead of item-based access:: - - - ep[0] -> ep.name - - ep[1] -> ep.value - - ep[2] -> ep.group - - ep[:] -> ep.name, ep.value, ep.group - -v4.8.0 -====== - -* #337: Rewrote ``EntryPoint`` as a simple class, still - immutable and still with the attributes, but without any - expectation for ``namedtuple`` functionality such as - ``_asdict``. - -v4.7.1 -====== - -* #344: Fixed regression in ``packages_distributions`` when - neither top-level.txt nor a files manifest is present. - -v4.7.0 -====== - -* #330: In ``packages_distributions``, now infer top-level - names from ``.files()`` when a ``top-level.txt`` - (Setuptools-specific metadata) is not present. - -v4.6.4 -====== - -* #334: Correct ``SimplePath`` protocol to match ``pathlib`` - protocol for ``__truediv__``. - -v4.6.3 -====== - -* Moved workaround for #327 to ``_compat`` module. - -v4.6.2 -====== - -* bpo-44784: Avoid errors in test suite when - DeprecationWarnings are treated as errors. - -v4.6.1 -====== - -* #327: Deprecation warnings now honor call stack variance - on PyPy. - -v4.6.0 -====== - -* #326: Performance tests now rely on - `pytest-perf `_. - To disable these tests, which require network access - and a git checkout, pass ``-p no:perf`` to pytest. - -v4.5.0 -====== - -* #319: Remove ``SelectableGroups`` deprecation exception - for flake8. - -v4.4.0 -====== - -* #300: Restore compatibility in the result from - ``Distribution.entry_points`` (``EntryPoints``) to honor - expectations in older implementations and issuing - deprecation warnings for these cases: - - - ``EntryPoints`` objects are once again mutable, allowing - for ``sort()`` and other list-based mutation operations. - Avoid deprecation warnings by casting to a - mutable sequence (e.g. - ``list(dist.entry_points).sort()``). - - - ``EntryPoints`` results once again allow - for access by index. To avoid deprecation warnings, - cast the result to a Sequence first - (e.g. ``tuple(dist.entry_points)[0]``). - -v4.3.1 -====== - -* #320: Fix issue where normalized name for eggs was - incorrectly solicited, leading to metadata being - unavailable for eggs. - -v4.3.0 -====== - -* #317: De-duplication of distributions no longer requires - loading the full metadata for ``PathDistribution`` objects, - entry point loading performance by ~10x. - -v4.2.0 -====== - -* Prefer f-strings to ``.format`` calls. - -v4.1.0 -====== - -* #312: Add support for metadata 2.2 (``Dynamic`` field). - -* #315: Add ``SimplePath`` protocol for interface clarity - in ``PathDistribution``. - -v4.0.1 -====== - -* #306: Clearer guidance about compatibility in readme. - -v4.0.0 -====== - -* #304: ``PackageMetadata`` as returned by ``metadata()`` - and ``Distribution.metadata()`` now provides normalized - metadata honoring PEP 566: - - - If a long description is provided in the payload of the - RFC 822 value, it can be retrieved as the ``Description`` - field. - - Any multi-line values in the metadata will be returned as - such. - - For any multi-line values, line continuation characters - are removed. This backward-incompatible change means - that any projects relying on the RFC 822 line continuation - characters being present must be tolerant to them having - been removed. - - Add a ``json`` property that provides the metadata - converted to a JSON-compatible form per PEP 566. - - -v3.10.1 -======= - -* Minor tweaks from CPython. - -v3.10.0 -======= - -* #295: Internal refactoring to unify section parsing logic. - -v3.9.1 -====== - -* #296: Exclude 'prepare' package. -* #297: Fix ValueError when entry points contains comments. - -v3.9.0 -====== - -* Use of Mapping (dict) interfaces on ``SelectableGroups`` - is now flagged as deprecated. Instead, users are advised - to use the select interface for future compatibility. - - Suppress the warning with this filter: - ``ignore:SelectableGroups dict interface``. - - Or with this invocation in the Python environment: - ``warnings.filterwarnings('ignore', 'SelectableGroups dict interface')``. - - Preferably, switch to the ``select`` interface introduced - in 3.7.0. See the - `entry points documentation `_ and changelog for the 3.6 - release below for more detail. - - For some use-cases, especially those that rely on - ``importlib.metadata`` in Python 3.8 and 3.9 or - those relying on older ``importlib_metadata`` (especially - on Python 3.5 and earlier), - `backports.entry_points_selectable `_ - was created to ease the transition. Please have a look - at that project if simply relying on importlib_metadata 3.6+ - is not straightforward. Background in #298. - -* #283: Entry point parsing no longer relies on ConfigParser - and instead uses a custom, one-pass parser to load the - config, resulting in a ~20% performance improvement when - loading entry points. - -v3.8.2 -====== - -* #293: Re-enabled lazy evaluation of path lookup through - a FreezableDefaultDict. - -v3.8.1 -====== - -* #293: Workaround for error in distribution search. - -v3.8.0 -====== - -* #290: Add mtime-based caching for ``FastPath`` and its - lookups, dramatically increasing performance for repeated - distribution lookups. - -v3.7.3 -====== - -* Docs enhancements and cleanup following review in - `GH-24782 `_. - -v3.7.2 -====== - -* Cleaned up cruft in entry_points docstring. - -v3.7.1 -====== - -* Internal refactoring to facilitate ``entry_points() -> dict`` - deprecation. - -v3.7.0 -====== - -* #131: Added ``packages_distributions`` to conveniently - resolve a top-level package or module to its distribution(s). - -v3.6.0 -====== - -* #284: Introduces new ``EntryPoints`` object, a tuple of - ``EntryPoint`` objects but with convenience properties for - selecting and inspecting the results: - - - ``.select()`` accepts ``group`` or ``name`` keyword - parameters and returns a new ``EntryPoints`` tuple - with only those that match the selection. - - ``.groups`` property presents all of the group names. - - ``.names`` property presents the names of the entry points. - - Item access (e.g. ``eps[name]``) retrieves a single - entry point by name. - - ``entry_points`` now accepts "selection parameters", - same as ``EntryPoint.select()``. - - ``entry_points()`` now provides a future-compatible - ``SelectableGroups`` object that supplies the above interface - (except item access) but remains a dict for compatibility. - - In the future, ``entry_points()`` will return an - ``EntryPoints`` object for all entry points. - - If passing selection parameters to ``entry_points``, the - future behavior is invoked and an ``EntryPoints`` is the - result. - -* #284: Construction of entry points using - ``dict([EntryPoint, ...])`` is now deprecated and raises - an appropriate DeprecationWarning and will be removed in - a future version. - -* #300: ``Distribution.entry_points`` now presents as an - ``EntryPoints`` object and access by index is no longer - allowed. If access by index is required, cast to a sequence - first. - -v3.5.0 -====== - -* #280: ``entry_points`` now only returns entry points for - unique distributions (by name). - -v3.4.0 -====== - -* #10: Project now declares itself as being typed. -* #272: Additional performance enhancements to distribution - discovery. -* #111: For PyPA projects, add test ensuring that - ``MetadataPathFinder._search_paths`` honors the needed - interface. Method is still private. - -v3.3.0 -====== - -* #265: ``EntryPoint`` objects now expose a ``.dist`` object - referencing the ``Distribution`` when constructed from a - Distribution. - -v3.2.0 -====== - -* The object returned by ``metadata()`` now has a - formally-defined protocol called ``PackageMetadata`` - with declared support for the ``.get_all()`` method. - Fixes #126. - -v3.1.1 -====== - -v2.1.1 -====== - -* #261: Restored compatibility for package discovery for - metadata without version in the name and for legacy - eggs. - -v3.1.0 -====== - -* Merge with 2.1.0. - -v2.1.0 -====== - -* #253: When querying for package metadata, the lookup - now honors - `package normalization rules `_. - -v3.0.0 -====== - -* Require Python 3.6 or later. - -v2.0.0 -====== - -* ``importlib_metadata`` no longer presents a - ``__version__`` attribute. Consumers wishing to - resolve the version of the package should query it - directly with - ``importlib_metadata.version('importlib-metadata')``. - Closes #71. - -v1.7.0 -====== - -* ``PathNotFoundError`` now has a custom ``__str__`` - mentioning "package metadata" being missing to help - guide users to the cause when the package is installed - but no metadata is present. Closes #124. - -v1.6.1 -====== - -* Added ``Distribution._local()`` as a provisional - demonstration of how to load metadata for a local - package. Implicitly requires that - `pep517 `_ is - installed. Ref #42. -* Ensure inputs to FastPath are Unicode. Closes #121. -* Tests now rely on ``importlib.resources.files`` (and - backport) instead of the older ``path`` function. -* Support any iterable from ``find_distributions``. - Closes #122. - -v1.6.0 -====== - -* Added ``module`` and ``attr`` attributes to ``EntryPoint`` - -v1.5.2 -====== - -* Fix redundant entries from ``FastPath.zip_children``. - Closes #117. - -v1.5.1 -====== - -* Improve reliability and consistency of compatibility - imports for contextlib and pathlib when running tests. - Closes #116. - -v1.5.0 -====== - -* Additional performance optimizations in FastPath now - saves an additional 20% on a typical call. -* Correct for issue where PyOxidizer finder has no - ``__module__`` attribute. Closes #110. - -v1.4.0 -====== - -* Through careful optimization, ``distribution()`` is - 3-4x faster. Thanks to Antony Lee for the - contribution. Closes #95. - -* When searching through ``sys.path``, if any error - occurs attempting to list a path entry, that entry - is skipped, making the system much more lenient - to errors. Closes #94. - -v1.3.0 -====== - -* Improve custom finders documentation. Closes #105. - -v1.2.0 -====== - -* Once again, drop support for Python 3.4. Ref #104. - -v1.1.3 -====== - -* Restored support for Python 3.4 due to improper version - compatibility declarations in the v1.1.0 and v1.1.1 - releases. Closes #104. - -v1.1.2 -====== - -* Repaired project metadata to correctly declare the - ``python_requires`` directive. Closes #103. - -v1.1.1 -====== - -* Fixed ``repr(EntryPoint)`` on PyPy 3 also. Closes #102. - -v1.1.0 -====== - -* Dropped support for Python 3.4. -* EntryPoints are now pickleable. Closes #96. -* Fixed ``repr(EntryPoint)`` on PyPy 2. Closes #97. - -v1.0.0 -====== - -* Project adopts semver for versioning. - -* Removed compatibility shim introduced in 0.23. - -* For better compatibility with the stdlib implementation and to - avoid the same distributions being discovered by the stdlib and - backport implementations, the backport now disables the - stdlib DistributionFinder during initialization (import time). - Closes #91 and closes #100. - -0.23 -==== - -* Added a compatibility shim to prevent failures on beta releases - of Python before the signature changed to accept the - "context" parameter on find_distributions. This workaround - will have a limited lifespan, not to extend beyond release of - Python 3.8 final. - -0.22 -==== - -* Renamed ``package`` parameter to ``distribution_name`` - as `recommended `_ - in the following functions: ``distribution``, ``metadata``, - ``version``, ``files``, and ``requires``. This - backward-incompatible change is expected to have little impact - as these functions are assumed to be primarily used with - positional parameters. - -0.21 -==== - -* ``importlib.metadata`` now exposes the ``DistributionFinder`` - metaclass and references it in the docs for extending the - search algorithm. -* Add ``Distribution.at`` for constructing a Distribution object - from a known metadata directory on the file system. Closes #80. -* Distribution finders now receive a context object that - supplies ``.path`` and ``.name`` properties. This change - introduces a fundamental backward incompatibility for - any projects implementing a ``find_distributions`` method - on a ``MetaPathFinder``. This new layer of abstraction - allows this context to be supplied directly or constructed - on demand and opens the opportunity for a - ``find_distributions`` method to solicit additional - context from the caller. Closes #85. - -0.20 -==== - -* Clarify in the docs that calls to ``.files`` could return - ``None`` when the metadata is not present. Closes #69. -* Return all requirements and not just the first for dist-info - packages. Closes #67. - -0.19 -==== - -* Restrain over-eager egg metadata resolution. -* Add support for entry points with colons in the name. Closes #75. - -0.18 -==== - -* Parse entry points case sensitively. Closes #68 -* Add a version constraint on the backport configparser package. Closes #66 - -0.17 -==== - -* Fix a permission problem in the tests on Windows. - -0.16 -==== - -* Don't crash if there exists an EGG-INFO directory on sys.path. - -0.15 -==== - -* Fix documentation. - -0.14 -==== - -* Removed ``local_distribution`` function from the API. - **This backward-incompatible change removes this - behavior summarily**. Projects should remove their - reliance on this behavior. A replacement behavior is - under review in the `pep517 project - `_. Closes #42. - -0.13 -==== - -* Update docstrings to match PEP 8. Closes #63. -* Merged modules into one module. Closes #62. - -0.12 -==== - -* Add support for eggs. !65; Closes #19. - -0.11 -==== - -* Support generic zip files (not just wheels). Closes #59 -* Support zip files with multiple distributions in them. Closes #60 -* Fully expose the public API in ``importlib_metadata.__all__``. - -0.10 -==== - -* The ``Distribution`` ABC is now officially part of the public API. - Closes #37. -* Fixed support for older single file egg-info formats. Closes #43. -* Fixed a testing bug when ``$CWD`` has spaces in the path. Closes #50. -* Add Python 3.8 to the ``tox`` testing matrix. - -0.9 -=== - -* Fixed issue where entry points without an attribute would raise an - Exception. Closes #40. -* Removed unused ``name`` parameter from ``entry_points()``. Closes #44. -* ``DistributionFinder`` classes must now be instantiated before - being placed on ``sys.meta_path``. - -0.8 -=== - -* This library can now discover/enumerate all installed packages. **This - backward-incompatible change alters the protocol finders must - implement to support distribution package discovery.** Closes #24. -* The signature of ``find_distributions()`` on custom installer finders - should now accept two parameters, ``name`` and ``path`` and - these parameters must supply defaults. -* The ``entry_points()`` method no longer accepts a package name - but instead returns all entry points in a dictionary keyed by the - ``EntryPoint.group``. The ``resolve`` method has been removed. Instead, - call ``EntryPoint.load()``, which has the same semantics as - ``pkg_resources`` and ``entrypoints``. **This is a backward incompatible - change.** -* Metadata is now always returned as Unicode text regardless of - Python version. Closes #29. -* This library can now discover metadata for a 'local' package (found - in the current-working directory). Closes #27. -* Added ``files()`` function for resolving files from a distribution. -* Added a new ``requires()`` function, which returns the requirements - for a package suitable for parsing by - ``packaging.requirements.Requirement``. Closes #18. -* The top-level ``read_text()`` function has been removed. Use - ``PackagePath.read_text()`` on instances returned by the ``files()`` - function. **This is a backward incompatible change.** -* Release dates are now automatically injected into the changelog - based on SCM tags. - -0.7 -=== - -* Fixed issue where packages with dashes in their names would - not be discovered. Closes #21. -* Distribution lookup is now case-insensitive. Closes #20. -* Wheel distributions can no longer be discovered by their module - name. Like Path distributions, they must be indicated by their - distribution package name. - -0.6 -=== - -* Removed ``importlib_metadata.distribution`` function. Now - the public interface is primarily the utility functions exposed - in ``importlib_metadata.__all__``. Closes #14. -* Added two new utility functions ``read_text`` and - ``metadata``. - -0.5 -=== - -* Updated README and removed details about Distribution - class, now considered private. Closes #15. -* Added test suite support for Python 3.4+. -* Fixed SyntaxErrors on Python 3.4 and 3.5. !12 -* Fixed errors on Windows joining Path elements. !15 - -0.4 -=== - -* Housekeeping. - -0.3 -=== - -* Added usage documentation. Closes #8 -* Add support for getting metadata from wheels on ``sys.path``. Closes #9 - -0.2 -=== - -* Added ``importlib_metadata.entry_points()``. Closes #1 -* Added ``importlib_metadata.resolve()``. Closes #12 -* Add support for Python 2.7. Closes #4 - -0.1 -=== - -* Initial release. - - -.. - Local Variables: - mode: change-log-mode - indent-tabs-mode: nil - sentence-end-double-space: t - fill-column: 78 - coding: utf-8 - End: diff --git a/README.rst b/README.rst deleted file mode 100644 index ffb63387..00000000 --- a/README.rst +++ /dev/null @@ -1,90 +0,0 @@ -.. image:: https://img.shields.io/pypi/v/importlib_metadata.svg - :target: https://pypi.org/project/importlib_metadata - -.. image:: https://img.shields.io/pypi/pyversions/importlib_metadata.svg - -.. image:: https://github.com/python/importlib_metadata/actions/workflows/main.yml/badge.svg - :target: https://github.com/python/importlib_metadata/actions?query=workflow%3A%22tests%22 - :alt: tests - -.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json - :target: https://github.com/astral-sh/ruff - :alt: Ruff - -.. image:: https://readthedocs.org/projects/importlib-metadata/badge/?version=latest - :target: https://importlib-metadata.readthedocs.io/en/latest/?badge=latest - -.. image:: https://img.shields.io/badge/skeleton-2024-informational - :target: https://blog.jaraco.com/skeleton - -.. image:: https://tidelift.com/badges/package/pypi/importlib-metadata - :target: https://tidelift.com/subscription/pkg/pypi-importlib-metadata?utm_source=pypi-importlib-metadata&utm_medium=readme - -Library to access the metadata for a Python package. - -This package supplies third-party access to the functionality of -`importlib.metadata `_ -including improvements added to subsequent Python versions. - - -Compatibility -============= - -New features are introduced in this third-party library and later merged -into CPython. The following table indicates which versions of this library -were contributed to different versions in the standard library: - -.. list-table:: - :header-rows: 1 - - * - importlib_metadata - - stdlib - * - 7.0 - - 3.13 - * - 6.5 - - 3.12 - * - 4.13 - - 3.11 - * - 4.6 - - 3.10 - * - 1.4 - - 3.8 - - -Usage -===== - -See the `online documentation `_ -for usage details. - -`Finder authors -`_ can -also add support for custom package installers. See the above documentation -for details. - - -Caveats -======= - -This project primarily supports third-party packages installed by PyPA -tools (or other conforming packages). It does not support: - -- Packages in the stdlib. -- Packages installed without metadata. - -Project details -=============== - - * Project home: https://github.com/python/importlib_metadata - * Report bugs at: https://github.com/python/importlib_metadata/issues - * Code hosting: https://github.com/python/importlib_metadata - * Documentation: https://importlib-metadata.readthedocs.io/ - -For Enterprise -============== - -Available as part of the Tidelift Subscription. - -This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use. - -`Learn more `_. diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 54f99acb..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,3 +0,0 @@ -# Security Contact - -To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. diff --git a/conftest.py b/conftest.py deleted file mode 100644 index 779ac24b..00000000 --- a/conftest.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys - - -collect_ignore = [ - # this module fails mypy tests because 'setup.py' matches './setup.py' - 'tests/data/sources/example/setup.py', -] - - -def pytest_configure(): - remove_importlib_metadata() - - -def remove_importlib_metadata(): - """ - Because pytest imports importlib_metadata, the coverage - reports are broken (#322). So work around the issue by - undoing the changes made by pytest's import of - importlib_metadata (if any). - """ - if sys.meta_path[-1].__class__.__name__ == 'MetadataPathFinder': - del sys.meta_path[-1] - for mod in list(sys.modules): - if mod.startswith('importlib_metadata'): - del sys.modules[mod] diff --git a/docs/api.rst b/docs/api.rst deleted file mode 100644 index d22eecd5..00000000 --- a/docs/api.rst +++ /dev/null @@ -1,16 +0,0 @@ -============= -API Reference -============= - -``importlib_metadata`` module ------------------------------ - -.. automodule:: importlib_metadata - :members: - :undoc-members: - :show-inheritance: - -.. automodule:: importlib_metadata._meta - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index 2cd8fb0c..00000000 --- a/docs/conf.py +++ /dev/null @@ -1,72 +0,0 @@ -extensions = [ - 'sphinx.ext.autodoc', - 'jaraco.packaging.sphinx', -] - -master_doc = "index" -html_theme = "furo" - -# Link dates and other references in the changelog -extensions += ['rst.linker'] -link_files = { - '../NEWS.rst': dict( - using=dict(GH='https://github.com'), - replace=[ - dict( - pattern=r'(Issue #|\B#)(?P\d+)', - url='{package_url}/issues/{issue}', - ), - dict( - pattern=r'(?m:^((?Pv?\d+(\.\d+){1,2}))\n[-=]+\n)', - with_scm='{text}\n{rev[timestamp]:%d %b %Y}\n', - ), - dict( - pattern=r'PEP[- ](?P\d+)', - url='https://peps.python.org/pep-{pep_number:0>4}/', - ), - dict( - pattern=r'(python/cpython#|Python #|py-)(?P\d+)', - url='https://github.com/python/cpython/issues/{python}', - ), - ], - ) -} - -# Be strict about any broken references -nitpicky = True - -# Include Python intersphinx mapping to prevent failures -# jaraco/skeleton#51 -extensions += ['sphinx.ext.intersphinx'] -intersphinx_mapping = { - 'python': ('https://docs.python.org/3', None), -} - -# Preserve authored syntax for defaults -autodoc_preserve_defaults = True - -extensions += ['jaraco.tidelift'] - -intersphinx_mapping.update( - importlib_resources=( - 'https://importlib-resources.readthedocs.io/en/latest/', - None, - ), -) - -intersphinx_mapping.update( - packaging=( - 'https://packaging.python.org/en/latest/', - None, - ), -) - -nitpick_ignore = [ - # Workaround for #316 - ('py:class', 'importlib_metadata.EntryPoints'), - ('py:class', 'importlib_metadata.PackagePath'), - ('py:class', 'importlib_metadata.SelectableGroups'), - ('py:class', 'importlib_metadata._meta._T'), - # Workaround for #435 - ('py:class', '_T'), -] diff --git a/docs/history.rst b/docs/history.rst deleted file mode 100644 index 5bdc2320..00000000 --- a/docs/history.rst +++ /dev/null @@ -1,8 +0,0 @@ -:tocdepth: 2 - -.. _changes: - -History -******* - -.. include:: ../NEWS (links).rst diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 66755216..00000000 --- a/docs/index.rst +++ /dev/null @@ -1,41 +0,0 @@ -Welcome to |project| documentation! -=================================== - -.. sidebar-links:: - :home: - :pypi: - -``importlib_metadata`` supplies a backport of :mod:`importlib.metadata`, -enabling early access to features of future Python versions and making -functionality available for older Python versions. Users are encouraged to -use the Python standard library where suitable and fall back to -this library for future compatibility. For general usage guidance, start -with :mod:`importlib.metadata` but substitute ``importlib_metadata`` -for ``importlib.metadata``. - - -.. toctree:: - :maxdepth: 1 - - api - migration - history - -.. tidelift-referral-banner:: - - -Project details -=============== - - * Project home: https://github.com/python/importlib_metadata - * Report bugs at: https://github.com/python/importlib_metadata/issues - * Code hosting: https://github.com/python/importlib_metadata - * Documentation: https://importlib-metadata.readthedocs.io/ - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/migration.rst b/docs/migration.rst deleted file mode 100644 index 3c700778..00000000 --- a/docs/migration.rst +++ /dev/null @@ -1,84 +0,0 @@ -.. _migration: - -================= - Migration guide -================= - -The following guide will help you migrate common ``pkg_resources`` -APIs to ``importlib_metadata``. ``importlib_metadata`` aims to -replace the following ``pkg_resources`` APIs: - -* ``pkg_resources.iter_entry_points()`` -* ``pkg_resources.require()`` -* convenience functions -* ``pkg_resources.find_distributions()`` -* ``pkg_resources.get_distribution()`` - -Other functionality from ``pkg_resources`` is replaced by other -packages such as -`importlib_resources `_ -and `packaging `_. - - -pkg_resources.iter_entry_points() -================================= - -``importlib_metadata`` provides :ref:`entry-points`. - -Compatibility note: entry points provided by importlib_metadata -do not have the following implicit behaviors found in those -from ``pkg_resources``: - -- Each EntryPoint is not automatically validated to match. To - ensure each one is validated, invoke any property on the - object (e.g. ``ep.name``). - -- When invoking ``EntryPoint.load()``, no checks are performed - to ensure the declared extras are installed. If this behavior - is desired/required, it is left to the user to perform the - check and install any dependencies. See - `importlib_metadata#368 `_ - for more details. - -pkg_resources.require() -======================= - -``importlib_metadata`` does not provide support for dynamically -discovering or requiring distributions nor does it provide any -support for managing the "working set". Furthermore, -``importlib_metadata`` assumes that only one version of a given -distribution is discoverable at any time (no support for multi-version -installs). Any projects that require the above behavior needs to -provide that behavior independently. - -``importlib_metadata`` does aim to resolve metadata concerns late -such that any dynamic changes to package availability should be -reflected immediately. - -Convenience functions -===================== - -In addition to the support for direct access to ``Distribution`` -objects (below), ``importlib_metadata`` presents some top-level -functions for easy access to the most common metadata: - -- :ref:`metadata` queries the metadata fields from the distribution. -- :ref:`version` provides quick access to the distribution version. -- :ref:`requirements` presents the requirements of the distribution. -- :ref:`files` provides file-like access to the data blobs backing - the metadata. - -pkg_resources.find_distributions() -================================== - -``importlib_metadata`` provides functionality -similar to ``find_distributions()``. Both ``distributions(...)`` and -``Distribution.discover(...)`` return an iterable of :ref:`distributions` -matching the indicated parameters. - -pkg_resources.get_distribution() -================================= - -Similar to ``distributions``, the ``distribution()`` function provides -access to a single distribution by name. - diff --git a/exercises.py b/exercises.py deleted file mode 100644 index c88fa983..00000000 --- a/exercises.py +++ /dev/null @@ -1,45 +0,0 @@ -from pytest_perf.deco import extras - - -@extras('perf') -def discovery_perf(): - "discovery" - import importlib_metadata # end warmup - - importlib_metadata.distribution('ipython') - - -def entry_points_perf(): - "entry_points()" - import importlib_metadata # end warmup - - importlib_metadata.entry_points() - - -@extras('perf') -def cached_distribution_perf(): - "cached distribution" - import importlib_metadata - - importlib_metadata.distribution('ipython') # end warmup - importlib_metadata.distribution('ipython') - - -@extras('perf') -def uncached_distribution_perf(): - "uncached distribution" - import importlib - import importlib_metadata - - # end warmup - importlib.invalidate_caches() - importlib_metadata.distribution('ipython') - - -def entrypoint_regexp_perf(): - import importlib_metadata - import re - - input = '0' + ' ' * 2**10 + '0' # end warmup - - re.match(importlib_metadata.EntryPoint.pattern, input) diff --git a/importlib_metadata/_compat.py b/importlib_metadata/_compat.py deleted file mode 100644 index df312b1c..00000000 --- a/importlib_metadata/_compat.py +++ /dev/null @@ -1,57 +0,0 @@ -import sys -import platform - - -__all__ = ['install', 'NullFinder'] - - -def install(cls): - """ - Class decorator for installation on sys.meta_path. - - Adds the backport DistributionFinder to sys.meta_path and - attempts to disable the finder functionality of the stdlib - DistributionFinder. - """ - sys.meta_path.append(cls()) - disable_stdlib_finder() - return cls - - -def disable_stdlib_finder(): - """ - Give the backport primacy for discovering path-based distributions - by monkey-patching the stdlib O_O. - - See #91 for more background for rationale on this sketchy - behavior. - """ - - def matches(finder): - return getattr( - finder, '__module__', None - ) == '_frozen_importlib_external' and hasattr(finder, 'find_distributions') - - for finder in filter(matches, sys.meta_path): # pragma: nocover - del finder.find_distributions - - -class NullFinder: - """ - A "Finder" (aka "MetaPathFinder") that never finds any modules, - but may find distributions. - """ - - @staticmethod - def find_spec(*args, **kwargs): - return None - - -def pypy_partial(val): - """ - Adjust for variable stacklevel on partial under PyPy. - - Workaround for #327. - """ - is_pypy = platform.python_implementation() == 'PyPy' - return val + is_pypy diff --git a/importlib_metadata/compat/__init__.py b/importlib_metadata/compat/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/importlib_metadata/compat/py311.py b/importlib_metadata/compat/py311.py deleted file mode 100644 index 3a532743..00000000 --- a/importlib_metadata/compat/py311.py +++ /dev/null @@ -1,22 +0,0 @@ -import os -import pathlib -import sys -import types - - -def wrap(path): # pragma: no cover - """ - Workaround for https://github.com/python/cpython/issues/84538 - to add backward compatibility for walk_up=True. - An example affected package is dask-labextension, which uses - jupyter-packaging to install JupyterLab javascript files outside - of site-packages. - """ - - def relative_to(root, *, walk_up=False): - return pathlib.Path(os.path.relpath(path, root)) - - return types.SimpleNamespace(relative_to=relative_to) - - -relative_fix = wrap if sys.version_info < (3, 12) else lambda x: x diff --git a/importlib_metadata/compat/py39.py b/importlib_metadata/compat/py39.py deleted file mode 100644 index 1f15bd97..00000000 --- a/importlib_metadata/compat/py39.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -Compatibility layer with Python 3.8/3.9 -""" - -from typing import TYPE_CHECKING, Any, Optional - -if TYPE_CHECKING: # pragma: no cover - # Prevent circular imports on runtime. - from .. import Distribution, EntryPoint -else: - Distribution = EntryPoint = Any - - -def normalized_name(dist: Distribution) -> Optional[str]: - """ - Honor name normalization for distributions that don't provide ``_normalized_name``. - """ - try: - return dist._normalized_name - except AttributeError: - from .. import Prepared # -> delay to prevent circular imports. - - return Prepared.normalize(getattr(dist, "name", None) or dist.metadata['Name']) - - -def ep_matches(ep: EntryPoint, **params) -> bool: - """ - Workaround for ``EntryPoint`` objects without the ``matches`` method. - """ - try: - return ep.matches(**params) - except AttributeError: - from .. import EntryPoint # -> delay to prevent circular imports. - - # Reconstruct the EntryPoint object to make sure it is compatible. - return EntryPoint(ep.name, ep.value, ep.group).matches(**params) diff --git a/importlib_metadata/py.typed b/importlib_metadata/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/mypy.ini b/mypy.ini deleted file mode 100644 index b6f97276..00000000 --- a/mypy.ini +++ /dev/null @@ -1,5 +0,0 @@ -[mypy] -ignore_missing_imports = True -# required to support namespace packages -# https://github.com/python/mypy/issues/14057 -explicit_package_bases = True diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 24ce25e3..00000000 --- a/pyproject.toml +++ /dev/null @@ -1,62 +0,0 @@ -[build-system] -requires = ["setuptools>=61.2", "setuptools_scm[toml]>=3.4.1"] -build-backend = "setuptools.build_meta" - -[project] -name = "importlib_metadata" -authors = [ - { name = "Jason R. Coombs", email = "jaraco@jaraco.com" }, -] -description = "Read metadata from Python packages" -readme = "README.rst" -classifiers = [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", -] -requires-python = ">=3.8" -dependencies = [ - "zipp>=0.5", - 'typing-extensions>=3.6.4; python_version < "3.8"', -] -dynamic = ["version"] - -[project.urls] -Source = "https://github.com/python/importlib_metadata" - -[project.optional-dependencies] -test = [ - # upstream - "pytest >= 6, != 8.1.*", - "pytest-checkdocs >= 2.4", - "pytest-cov", - "pytest-mypy", - "pytest-enabler >= 2.2", - "pytest-ruff >= 0.2.1; sys_platform != 'cygwin'", - - # local - 'importlib_resources>=1.3; python_version < "3.9"', - "packaging", - "pyfakefs", - "flufl.flake8", - "pytest-perf >= 0.9.2", - "jaraco.test >= 5.4", -] -doc = [ - # upstream - "sphinx >= 3.5", - "jaraco.packaging >= 9.3", - "rst.linker >= 1.9", - "furo", - "sphinx-lint", - - # tidelift - "jaraco.tidelift >= 1.4", - - # local -] -perf = ["ipython"] - -[tool.setuptools_scm] diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 9a0f3bce..00000000 --- a/pytest.ini +++ /dev/null @@ -1,25 +0,0 @@ -[pytest] -norecursedirs=dist build .tox .eggs -addopts= - --doctest-modules - --import-mode importlib -consider_namespace_packages=true -filterwarnings= - ## upstream - - # Ensure ResourceWarnings are emitted - default::ResourceWarning - - # realpython/pytest-mypy#152 - ignore:'encoding' argument not specified::pytest_mypy - - # python/cpython#100750 - ignore:'encoding' argument not specified::platform - - # pypa/build#615 - ignore:'encoding' argument not specified::build.env - - # dateutil/dateutil#1284 - ignore:datetime.datetime.utcfromtimestamp:DeprecationWarning:dateutil.tz.tz - - ## end upstream diff --git a/ruff.toml b/ruff.toml deleted file mode 100644 index 922aa1f1..00000000 --- a/ruff.toml +++ /dev/null @@ -1,30 +0,0 @@ -[lint] -extend-select = [ - "C901", - "PERF401", - "W", -] -ignore = [ - # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules - "W191", - "E111", - "E114", - "E117", - "D206", - "D300", - "Q000", - "Q001", - "Q002", - "Q003", - "COM812", - "COM819", - "ISC001", - "ISC002", -] - -[format] -# Enable preview to get hugged parenthesis unwrapping and other nice surprises -# See https://github.com/jaraco/skeleton/pull/133#issuecomment-2239538373 -preview = true -# https://docs.astral.sh/ruff/settings/#format_quote-style -quote-style = "preserve" diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/compat/__init__.py b/tests/compat/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/compat/py312.py b/tests/compat/py312.py deleted file mode 100644 index ea9a58ba..00000000 --- a/tests/compat/py312.py +++ /dev/null @@ -1,18 +0,0 @@ -import contextlib - -from .py39 import import_helper - - -@contextlib.contextmanager -def isolated_modules(): - """ - Save modules on entry and cleanup on exit. - """ - (saved,) = import_helper.modules_setup() - try: - yield - finally: - import_helper.modules_cleanup(saved) - - -vars(import_helper).setdefault('isolated_modules', isolated_modules) diff --git a/tests/compat/py39.py b/tests/compat/py39.py deleted file mode 100644 index 9476eb35..00000000 --- a/tests/compat/py39.py +++ /dev/null @@ -1,9 +0,0 @@ -from jaraco.test.cpython import from_test_support, try_import - - -os_helper = try_import('os_helper') or from_test_support( - 'FS_NONASCII', 'skip_unless_symlink', 'temp_dir' -) -import_helper = try_import('import_helper') or from_test_support( - 'modules_setup', 'modules_cleanup' -) diff --git a/tests/compat/test_py39_compat.py b/tests/compat/test_py39_compat.py deleted file mode 100644 index 549e518a..00000000 --- a/tests/compat/test_py39_compat.py +++ /dev/null @@ -1,73 +0,0 @@ -import sys -import pathlib -import unittest - -from .. import fixtures -from importlib_metadata import ( - distribution, - distributions, - entry_points, - metadata, - version, -) - - -class OldStdlibFinderTests(fixtures.DistInfoPkgOffPath, unittest.TestCase): - def setUp(self): - if sys.version_info >= (3, 10): - self.skipTest("Tests specific for Python 3.8/3.9") - super().setUp() - - def _meta_path_finder(self): - from importlib.metadata import ( - Distribution, - DistributionFinder, - PathDistribution, - ) - from importlib.util import spec_from_file_location - - path = pathlib.Path(self.site_dir) - - class CustomDistribution(Distribution): - def __init__(self, name, path): - self.name = name - self._path_distribution = PathDistribution(path) - - def read_text(self, filename): - return self._path_distribution.read_text(filename) - - def locate_file(self, path): - return self._path_distribution.locate_file(path) - - class CustomFinder: - @classmethod - def find_spec(cls, fullname, _path=None, _target=None): - candidate = pathlib.Path(path, *fullname.split(".")).with_suffix(".py") - if candidate.exists(): - return spec_from_file_location(fullname, candidate) - - @classmethod - def find_distributions(self, context=DistributionFinder.Context()): - for dist_info in path.glob("*.dist-info"): - yield PathDistribution(dist_info) - name, _, _ = str(dist_info).partition("-") - yield CustomDistribution(name + "_custom", dist_info) - - return CustomFinder - - def test_compatibility_with_old_stdlib_path_distribution(self): - """ - Given a custom finder that uses Python 3.8/3.9 importlib.metadata is installed, - when importlib_metadata functions are called, there should be no exceptions. - Ref python/importlib_metadata#396. - """ - self.fixtures.enter_context(fixtures.install_finder(self._meta_path_finder())) - - assert list(distributions()) - assert distribution("distinfo_pkg") - assert distribution("distinfo_pkg_custom") - assert version("distinfo_pkg") > "0" - assert version("distinfo_pkg_custom") > "0" - assert list(metadata("distinfo_pkg")) - assert list(metadata("distinfo_pkg_custom")) - assert list(entry_points(group="entries")) diff --git a/tests/data/__init__.py b/tests/data/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/test_integration.py b/tests/test_integration.py deleted file mode 100644 index f7af67f3..00000000 --- a/tests/test_integration.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -Test behaviors specific to importlib_metadata. - -These tests are excluded downstream in CPython as they -test functionality only in importlib_metadata or require -behaviors ('packaging') that aren't available in the -stdlib. -""" - -import unittest -import packaging.requirements -import packaging.version - -from . import fixtures -from importlib_metadata import ( - _compat, - version, -) - - -class IntegrationTests(fixtures.DistInfoPkg, unittest.TestCase): - def test_package_spec_installed(self): - """ - Illustrate the recommended procedure to determine if - a specified version of a package is installed. - """ - - def is_installed(package_spec): - req = packaging.requirements.Requirement(package_spec) - return version(req.name) in req.specifier - - assert is_installed('distinfo-pkg==1.0') - assert is_installed('distinfo-pkg>=1.0,<2.0') - assert not is_installed('distinfo-pkg<1.0') - - -class FinderTests(fixtures.Fixtures, unittest.TestCase): - def test_finder_without_module(self): - class ModuleFreeFinder: - """ - A finder without an __module__ attribute - """ - - def find_module(self, name): - pass - - def __getattribute__(self, name): - if name == '__module__': - raise AttributeError(name) - return super().__getattribute__(name) - - self.fixtures.enter_context(fixtures.install_finder(ModuleFreeFinder())) - _compat.disable_stdlib_finder() diff --git a/towncrier.toml b/towncrier.toml deleted file mode 100644 index 6fa480e4..00000000 --- a/towncrier.toml +++ /dev/null @@ -1,2 +0,0 @@ -[tool.towncrier] -title_format = "{version}" diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 71fd05f6..00000000 --- a/tox.ini +++ /dev/null @@ -1,63 +0,0 @@ -[testenv] -description = perform primary checks (tests, style, types, coverage) -deps = -setenv = - PYTHONWARNDEFAULTENCODING = 1 -commands = - pytest {posargs} -passenv = - HOME -usedevelop = True -extras = - test - -[testenv:diffcov] -description = run tests and check that diff from main is covered -deps = - {[testenv]deps} - diff-cover -commands = - pytest {posargs} --cov-report xml - diff-cover coverage.xml --compare-branch=origin/main --html-report diffcov.html - diff-cover coverage.xml --compare-branch=origin/main --fail-under=100 - -[testenv:docs] -description = build the documentation -extras = - doc - test -changedir = docs -commands = - python -m sphinx -W --keep-going . {toxinidir}/build/html - python -m sphinxlint \ - # workaround for sphinx-contrib/sphinx-lint#83 - --jobs 1 - -[testenv:finalize] -description = assemble changelog and tag a release -skip_install = True -deps = - towncrier - jaraco.develop >= 7.23 -pass_env = * -commands = - python -m jaraco.develop.finalize - - -[testenv:release] -description = publish the package to PyPI and GitHub -skip_install = True -deps = - build - twine>=3 - jaraco.develop>=7.1 -pass_env = - TWINE_PASSWORD - GITHUB_TOKEN -setenv = - TWINE_USERNAME = {env:TWINE_USERNAME:__token__} -commands = - python -c "import shutil; shutil.rmtree('dist', ignore_errors=True)" - python -m build - python -m twine upload dist/* - python -m jaraco.develop.create-github-release