diff --git a/newsfragments/4718.feature.1.rst b/newsfragments/4718.feature.1.rst new file mode 100644 index 0000000000..f171cdde84 --- /dev/null +++ b/newsfragments/4718.feature.1.rst @@ -0,0 +1 @@ +Require Python 3.9 or later. diff --git a/newsfragments/4718.feature.2.rst b/newsfragments/4718.feature.2.rst new file mode 100644 index 0000000000..7c32c13b61 --- /dev/null +++ b/newsfragments/4718.feature.2.rst @@ -0,0 +1,4 @@ +Remove dependency on ``importlib_resources`` +and the vendored copy of the library. +Instead, ``setuptools`` consistently rely on stdlib's ``importlib.resources`` +(available on Python 3.9+). diff --git a/newsfragments/4718.feature.3.rst b/newsfragments/4718.feature.3.rst new file mode 100644 index 0000000000..9c80da9064 --- /dev/null +++ b/newsfragments/4718.feature.3.rst @@ -0,0 +1,3 @@ +Setuptools' ``bdist_wheel`` implementation no longer produces wheels with +the ``m`` SOABI flag (pymalloc-related). +This flag was removed on Python 3.8+ (see :obj:`sys.abiflags`). diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index aa5d9f3a93..6418eb2ab0 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -21,8 +21,8 @@ import sys -if sys.version_info < (3, 8): # noqa: UP036 # Check for unsupported versions - raise RuntimeError("Python 3.8 or later is required") +if sys.version_info < (3, 9): # noqa: UP036 # Check for unsupported versions + raise RuntimeError("Python 3.9 or later is required") import _imp import collections diff --git a/pyproject.toml b/pyproject.toml index c80bee509c..300438232a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,7 +93,6 @@ core = [ "packaging>=24", "more_itertools>=8.8", "jaraco.text>=3.7", - "importlib_resources>=5.10.2; python_version < '3.9'", "importlib_metadata>=6; python_version < '3.10'", "tomli>=2.0.1; python_version < '3.11'", "wheel>=0.43.0", diff --git a/setuptools/_importlib.py b/setuptools/_importlib.py index 5317be0fa0..ce0fd52653 100644 --- a/setuptools/_importlib.py +++ b/setuptools/_importlib.py @@ -6,7 +6,4 @@ import importlib.metadata as metadata # noqa: F401 -if sys.version_info < (3, 9): - import importlib_resources as resources # pragma: no cover -else: - import importlib.resources as resources # noqa: F401 +import importlib.resources as resources # noqa: F401 diff --git a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/INSTALLER b/setuptools/_vendor/importlib_resources-6.4.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e38a..0000000000 --- a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/LICENSE b/setuptools/_vendor/importlib_resources-6.4.0.dist-info/LICENSE deleted file mode 100644 index d645695673..0000000000 --- a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/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/setuptools/_vendor/importlib_resources-6.4.0.dist-info/METADATA b/setuptools/_vendor/importlib_resources-6.4.0.dist-info/METADATA deleted file mode 100644 index b088e721d2..0000000000 --- a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/METADATA +++ /dev/null @@ -1,100 +0,0 @@ -Metadata-Version: 2.1 -Name: importlib_resources -Version: 6.4.0 -Summary: Read resources from Python packages -Home-page: https://github.com/python/importlib_resources -Author: Barry Warsaw -Author-email: barry@python.org -Project-URL: Documentation, https://importlib-resources.readthedocs.io/ -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3 :: Only -Requires-Python: >=3.8 -License-File: LICENSE -Requires-Dist: zipp >=3.1.0 ; python_version < "3.10" -Provides-Extra: docs -Requires-Dist: sphinx >=3.5 ; extra == 'docs' -Requires-Dist: sphinx <7.2.5 ; extra == 'docs' -Requires-Dist: jaraco.packaging >=9.3 ; extra == 'docs' -Requires-Dist: rst.linker >=1.9 ; extra == 'docs' -Requires-Dist: furo ; extra == 'docs' -Requires-Dist: sphinx-lint ; extra == 'docs' -Requires-Dist: jaraco.tidelift >=1.4 ; extra == 'docs' -Provides-Extra: testing -Requires-Dist: pytest >=6 ; extra == 'testing' -Requires-Dist: pytest-checkdocs >=2.4 ; extra == 'testing' -Requires-Dist: pytest-cov ; extra == 'testing' -Requires-Dist: pytest-enabler >=2.2 ; extra == 'testing' -Requires-Dist: pytest-ruff >=0.2.1 ; extra == 'testing' -Requires-Dist: zipp >=3.17 ; extra == 'testing' -Requires-Dist: jaraco.test >=5.4 ; extra == 'testing' -Requires-Dist: pytest-mypy ; (platform_python_implementation != "PyPy") and extra == 'testing' - -.. image:: https://img.shields.io/pypi/v/importlib_resources.svg - :target: https://pypi.org/project/importlib_resources - -.. image:: https://img.shields.io/pypi/pyversions/importlib_resources.svg - -.. image:: https://github.com/python/importlib_resources/actions/workflows/main.yml/badge.svg - :target: https://github.com/python/importlib_resources/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-resources/badge/?version=latest - :target: https://importlib-resources.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-resources - :target: https://tidelift.com/subscription/pkg/pypi-importlib-resources?utm_source=pypi-importlib-resources&utm_medium=readme - -``importlib_resources`` is a backport of Python standard library -`importlib.resources -`_ -module for older Pythons. - -The key goal of this module is to replace parts of `pkg_resources -`_ with a -solution in Python's stdlib that relies on well-defined APIs. This makes -reading resources included in packages easier, with more stable and consistent -semantics. - -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_resources - - stdlib - * - 6.0 - - 3.13 - * - 5.12 - - 3.12 - * - 5.7 - - 3.11 - * - 5.0 - - 3.10 - * - 1.3 - - 3.9 - * - 0.5 (?) - - 3.7 - -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/setuptools/_vendor/importlib_resources-6.4.0.dist-info/RECORD b/setuptools/_vendor/importlib_resources-6.4.0.dist-info/RECORD deleted file mode 100644 index 18888dea71..0000000000 --- a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/RECORD +++ /dev/null @@ -1,89 +0,0 @@ -importlib_resources-6.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -importlib_resources-6.4.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358 -importlib_resources-6.4.0.dist-info/METADATA,sha256=g4eM2LuL0OiZcUVND0qwDJUpE29gOvtO3BSPXTbO9Fk,3944 -importlib_resources-6.4.0.dist-info/RECORD,, -importlib_resources-6.4.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources-6.4.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92 -importlib_resources-6.4.0.dist-info/top_level.txt,sha256=fHIjHU1GZwAjvcydpmUnUrTnbvdiWjG4OEVZK8by0TQ,20 -importlib_resources/__init__.py,sha256=uyp1kzYR6SawQBsqlyaXXfIxJx4Z2mM8MjmZn8qq2Gk,505 -importlib_resources/__pycache__/__init__.cpython-312.pyc,, -importlib_resources/__pycache__/_adapters.cpython-312.pyc,, -importlib_resources/__pycache__/_common.cpython-312.pyc,, -importlib_resources/__pycache__/_itertools.cpython-312.pyc,, -importlib_resources/__pycache__/abc.cpython-312.pyc,, -importlib_resources/__pycache__/functional.cpython-312.pyc,, -importlib_resources/__pycache__/readers.cpython-312.pyc,, -importlib_resources/__pycache__/simple.cpython-312.pyc,, -importlib_resources/_adapters.py,sha256=vprJGbUeHbajX6XCuMP6J3lMrqCi-P_MTlziJUR7jfk,4482 -importlib_resources/_common.py,sha256=blt4-ZtHnbUPzQQyPP7jLGgl_86btIW5ZhIsEhclhoA,5571 -importlib_resources/_itertools.py,sha256=eDisV6RqiNZOogLSXf6LOGHOYc79FGgPrKNLzFLmCrU,1277 -importlib_resources/abc.py,sha256=UKNU9ncEDkZRB3txcGb3WLxsL2iju9JbaLTI-dfLE_4,5162 -importlib_resources/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources/compat/__pycache__/__init__.cpython-312.pyc,, -importlib_resources/compat/__pycache__/py38.cpython-312.pyc,, -importlib_resources/compat/__pycache__/py39.cpython-312.pyc,, -importlib_resources/compat/py38.py,sha256=MWhut3XsAJwBYUaa5Qb2AoCrZNqcQjVThP-P1uBoE_4,230 -importlib_resources/compat/py39.py,sha256=Wfln4uQUShNz1XdCG-toG6_Y0WrlUmO9JzpvtcfQ-Cw,184 -importlib_resources/functional.py,sha256=mLU4DwSlh8_2IXWqwKOfPVxyRqAEpB3B4XTfRxr3X3M,2651 -importlib_resources/future/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources/future/__pycache__/__init__.cpython-312.pyc,, -importlib_resources/future/__pycache__/adapters.cpython-312.pyc,, -importlib_resources/future/adapters.py,sha256=1-MF2VRcCButhcC1OMfZILU9o3kwZ4nXB2lurXpaIAw,2940 -importlib_resources/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources/readers.py,sha256=WNKurBHHVu9EVtUhWkOj2fxH50HP7uanNFuupAqH2S8,5863 -importlib_resources/simple.py,sha256=CQ3TiIMFiJs_80o-7xJL1EpbUUVna4-NGDrSTQ3HW2Y,2584 -importlib_resources/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources/tests/__pycache__/__init__.cpython-312.pyc,, -importlib_resources/tests/__pycache__/_path.cpython-312.pyc,, -importlib_resources/tests/__pycache__/test_compatibilty_files.cpython-312.pyc,, -importlib_resources/tests/__pycache__/test_contents.cpython-312.pyc,, -importlib_resources/tests/__pycache__/test_custom.cpython-312.pyc,, -importlib_resources/tests/__pycache__/test_files.cpython-312.pyc,, -importlib_resources/tests/__pycache__/test_functional.cpython-312.pyc,, -importlib_resources/tests/__pycache__/test_open.cpython-312.pyc,, -importlib_resources/tests/__pycache__/test_path.cpython-312.pyc,, -importlib_resources/tests/__pycache__/test_read.cpython-312.pyc,, -importlib_resources/tests/__pycache__/test_reader.cpython-312.pyc,, -importlib_resources/tests/__pycache__/test_resource.cpython-312.pyc,, -importlib_resources/tests/__pycache__/util.cpython-312.pyc,, -importlib_resources/tests/__pycache__/zip.cpython-312.pyc,, -importlib_resources/tests/_path.py,sha256=nkv3ek7D1U898v921rYbldDCtKri2oyYOi3EJqGjEGU,1289 -importlib_resources/tests/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources/tests/compat/__pycache__/__init__.cpython-312.pyc,, -importlib_resources/tests/compat/__pycache__/py312.cpython-312.pyc,, -importlib_resources/tests/compat/__pycache__/py39.cpython-312.pyc,, -importlib_resources/tests/compat/py312.py,sha256=qcWjpZhQo2oEsdwIlRRQHrsMGDltkFTnETeG7fLdUS8,364 -importlib_resources/tests/compat/py39.py,sha256=lRTk0RWAOEb9RzAgvdRnqJUGCBLc3qoFQwzuJSa_zP4,329 -importlib_resources/tests/data01/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources/tests/data01/__pycache__/__init__.cpython-312.pyc,, -importlib_resources/tests/data01/binary.file,sha256=BU7ewdAhH2JP7Qy8qdT5QAsOSRxDdCryxbCr6_DJkNg,4 -importlib_resources/tests/data01/subdirectory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources/tests/data01/subdirectory/__pycache__/__init__.cpython-312.pyc,, -importlib_resources/tests/data01/subdirectory/binary.file,sha256=xtRM9Bj2EOP-nh2SlP9D3vgcbNytbLsYIM_0jTqkNV0,4 -importlib_resources/tests/data01/utf-16.file,sha256=t5q9qhxX0rYqItBOM8D3ylwG-RHrnOYteTLtQr6sF7g,44 -importlib_resources/tests/data01/utf-8.file,sha256=kwWgYG4yQ-ZF2X_WA66EjYPmxJRn-w8aSOiS9e8tKYY,20 -importlib_resources/tests/data02/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources/tests/data02/__pycache__/__init__.cpython-312.pyc,, -importlib_resources/tests/data02/one/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources/tests/data02/one/__pycache__/__init__.cpython-312.pyc,, -importlib_resources/tests/data02/one/resource1.txt,sha256=10flKac7c-XXFzJ3t-AB5MJjlBy__dSZvPE_dOm2q6U,13 -importlib_resources/tests/data02/subdirectory/subsubdir/resource.txt,sha256=jnrBBztxYrtQck7cmVnc4xQVO4-agzAZDGSFkAWtlFw,10 -importlib_resources/tests/data02/two/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -importlib_resources/tests/data02/two/__pycache__/__init__.cpython-312.pyc,, -importlib_resources/tests/data02/two/resource2.txt,sha256=lt2jbN3TMn9QiFKM832X39bU_62UptDdUkoYzkvEbl0,13 -importlib_resources/tests/namespacedata01/binary.file,sha256=BU7ewdAhH2JP7Qy8qdT5QAsOSRxDdCryxbCr6_DJkNg,4 -importlib_resources/tests/namespacedata01/subdirectory/binary.file,sha256=cbkhEL8TXIVYHIoSj2oZwPasp1KwxskeNXGJnPCbFF0,4 -importlib_resources/tests/namespacedata01/utf-16.file,sha256=t5q9qhxX0rYqItBOM8D3ylwG-RHrnOYteTLtQr6sF7g,44 -importlib_resources/tests/namespacedata01/utf-8.file,sha256=kwWgYG4yQ-ZF2X_WA66EjYPmxJRn-w8aSOiS9e8tKYY,20 -importlib_resources/tests/test_compatibilty_files.py,sha256=95N_R7aik8cvnE6sBJpsxmP0K5plOWRIJDgbalD-Hpw,3314 -importlib_resources/tests/test_contents.py,sha256=70HW3mL_hv05Emv-OgdmwoLhXxjtuVxiWVaUpgRaRWA,930 -importlib_resources/tests/test_custom.py,sha256=QrHZqIWl0e-fsQRfm0ych8stOlKJOsAIU3rK6QOcyN0,1221 -importlib_resources/tests/test_files.py,sha256=OcShYu33kCcyXlDyZSVPkJNE08h-N_4bQOLV2QaSqX0,3472 -importlib_resources/tests/test_functional.py,sha256=ByCVViAwb2PIlKvDNJEqTZ0aLZGpFl5qa7CMCX-7HKM,8591 -importlib_resources/tests/test_open.py,sha256=ccmzbOeEa6zTd4ymZZ8yISrecfuYV0jhon-Vddqysu4,2778 -importlib_resources/tests/test_path.py,sha256=x8r2gJxG3hFM9xCOFNkgmHYXxsMldMLTSW_AZYf1l-A,2009 -importlib_resources/tests/test_read.py,sha256=7tsILQ2NoqVGFQxhHqxBwc5hWcN8b_3idojCsszTNfQ,3112 -importlib_resources/tests/test_reader.py,sha256=IcIUXaiPAtuahGV4_ZT4YXFLMMsJmcM1iOxqdIH2Aa4,5001 -importlib_resources/tests/test_resource.py,sha256=fcF8WgZ6rDCTRFnxtAUbdiaNe4G23yGovT1nb2dc7ls,7823 -importlib_resources/tests/util.py,sha256=vjVzEyX0X2RkTN-wGiQiplayp9sZom4JDjJinTNewos,4745 -importlib_resources/tests/zip.py,sha256=2MKmF8-osXBJSnqcUTuAUek_-tSB3iKmIT9qPhcsOsM,783 diff --git a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/REQUESTED b/setuptools/_vendor/importlib_resources-6.4.0.dist-info/REQUESTED deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/WHEEL b/setuptools/_vendor/importlib_resources-6.4.0.dist-info/WHEEL deleted file mode 100644 index bab98d6758..0000000000 --- a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.43.0) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/top_level.txt b/setuptools/_vendor/importlib_resources-6.4.0.dist-info/top_level.txt deleted file mode 100644 index 58ad1bd333..0000000000 --- a/setuptools/_vendor/importlib_resources-6.4.0.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -importlib_resources diff --git a/setuptools/_vendor/importlib_resources/__init__.py b/setuptools/_vendor/importlib_resources/__init__.py deleted file mode 100644 index 0d029abd63..0000000000 --- a/setuptools/_vendor/importlib_resources/__init__.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Read resources contained within a package.""" - -from ._common import ( - as_file, - files, - Package, - Anchor, -) - -from .functional import ( - contents, - is_resource, - open_binary, - open_text, - path, - read_binary, - read_text, -) - -from .abc import ResourceReader - - -__all__ = [ - 'Package', - 'Anchor', - 'ResourceReader', - 'as_file', - 'files', - 'contents', - 'is_resource', - 'open_binary', - 'open_text', - 'path', - 'read_binary', - 'read_text', -] diff --git a/setuptools/_vendor/importlib_resources/_adapters.py b/setuptools/_vendor/importlib_resources/_adapters.py deleted file mode 100644 index 50688fbb66..0000000000 --- a/setuptools/_vendor/importlib_resources/_adapters.py +++ /dev/null @@ -1,168 +0,0 @@ -from contextlib import suppress -from io import TextIOWrapper - -from . import abc - - -class SpecLoaderAdapter: - """ - Adapt a package spec to adapt the underlying loader. - """ - - def __init__(self, spec, adapter=lambda spec: spec.loader): - self.spec = spec - self.loader = adapter(spec) - - def __getattr__(self, name): - return getattr(self.spec, name) - - -class TraversableResourcesLoader: - """ - Adapt a loader to provide TraversableResources. - """ - - def __init__(self, spec): - self.spec = spec - - def get_resource_reader(self, name): - return CompatibilityFiles(self.spec)._native() - - -def _io_wrapper(file, mode='r', *args, **kwargs): - if mode == 'r': - return TextIOWrapper(file, *args, **kwargs) - elif mode == 'rb': - return file - raise ValueError(f"Invalid mode value '{mode}', only 'r' and 'rb' are supported") - - -class CompatibilityFiles: - """ - Adapter for an existing or non-existent resource reader - to provide a compatibility .files(). - """ - - class SpecPath(abc.Traversable): - """ - Path tied to a module spec. - Can be read and exposes the resource reader children. - """ - - def __init__(self, spec, reader): - self._spec = spec - self._reader = reader - - def iterdir(self): - if not self._reader: - return iter(()) - return iter( - CompatibilityFiles.ChildPath(self._reader, path) - for path in self._reader.contents() - ) - - def is_file(self): - return False - - is_dir = is_file - - def joinpath(self, other): - if not self._reader: - return CompatibilityFiles.OrphanPath(other) - return CompatibilityFiles.ChildPath(self._reader, other) - - @property - def name(self): - return self._spec.name - - def open(self, mode='r', *args, **kwargs): - return _io_wrapper(self._reader.open_resource(None), mode, *args, **kwargs) - - class ChildPath(abc.Traversable): - """ - Path tied to a resource reader child. - Can be read but doesn't expose any meaningful children. - """ - - def __init__(self, reader, name): - self._reader = reader - self._name = name - - def iterdir(self): - return iter(()) - - def is_file(self): - return self._reader.is_resource(self.name) - - def is_dir(self): - return not self.is_file() - - def joinpath(self, other): - return CompatibilityFiles.OrphanPath(self.name, other) - - @property - def name(self): - return self._name - - def open(self, mode='r', *args, **kwargs): - return _io_wrapper( - self._reader.open_resource(self.name), mode, *args, **kwargs - ) - - class OrphanPath(abc.Traversable): - """ - Orphan path, not tied to a module spec or resource reader. - Can't be read and doesn't expose any meaningful children. - """ - - def __init__(self, *path_parts): - if len(path_parts) < 1: - raise ValueError('Need at least one path part to construct a path') - self._path = path_parts - - def iterdir(self): - return iter(()) - - def is_file(self): - return False - - is_dir = is_file - - def joinpath(self, other): - return CompatibilityFiles.OrphanPath(*self._path, other) - - @property - def name(self): - return self._path[-1] - - def open(self, mode='r', *args, **kwargs): - raise FileNotFoundError("Can't open orphan path") - - def __init__(self, spec): - self.spec = spec - - @property - def _reader(self): - with suppress(AttributeError): - return self.spec.loader.get_resource_reader(self.spec.name) - - def _native(self): - """ - Return the native reader if it supports files(). - """ - reader = self._reader - return reader if hasattr(reader, 'files') else self - - def __getattr__(self, attr): - return getattr(self._reader, attr) - - def files(self): - return CompatibilityFiles.SpecPath(self.spec, self._reader) - - -def wrap_spec(package): - """ - Construct a package spec with traversable compatibility - on the spec/loader/reader. - """ - return SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) diff --git a/setuptools/_vendor/importlib_resources/_common.py b/setuptools/_vendor/importlib_resources/_common.py deleted file mode 100644 index 8df6b39e41..0000000000 --- a/setuptools/_vendor/importlib_resources/_common.py +++ /dev/null @@ -1,210 +0,0 @@ -import os -import pathlib -import tempfile -import functools -import contextlib -import types -import importlib -import inspect -import warnings -import itertools - -from typing import Union, Optional, cast -from .abc import ResourceReader, Traversable - -Package = Union[types.ModuleType, str] -Anchor = Package - - -def package_to_anchor(func): - """ - Replace 'package' parameter as 'anchor' and warn about the change. - - Other errors should fall through. - - >>> files('a', 'b') - Traceback (most recent call last): - TypeError: files() takes from 0 to 1 positional arguments but 2 were given - - Remove this compatibility in Python 3.14. - """ - undefined = object() - - @functools.wraps(func) - def wrapper(anchor=undefined, package=undefined): - if package is not undefined: - if anchor is not undefined: - return func(anchor, package) - warnings.warn( - "First parameter to files is renamed to 'anchor'", - DeprecationWarning, - stacklevel=2, - ) - return func(package) - elif anchor is undefined: - return func() - return func(anchor) - - return wrapper - - -@package_to_anchor -def files(anchor: Optional[Anchor] = None) -> Traversable: - """ - Get a Traversable resource for an anchor. - """ - return from_package(resolve(anchor)) - - -def get_resource_reader(package: types.ModuleType) -> Optional[ResourceReader]: - """ - Return the package's loader if it's a ResourceReader. - """ - # We can't use - # a issubclass() check here because apparently abc.'s __subclasscheck__() - # hook wants to create a weak reference to the object, but - # zipimport.zipimporter does not support weak references, resulting in a - # TypeError. That seems terrible. - spec = package.__spec__ - reader = getattr(spec.loader, 'get_resource_reader', None) # type: ignore - if reader is None: - return None - return reader(spec.name) # type: ignore - - -@functools.singledispatch -def resolve(cand: Optional[Anchor]) -> types.ModuleType: - return cast(types.ModuleType, cand) - - -@resolve.register -def _(cand: str) -> types.ModuleType: - return importlib.import_module(cand) - - -@resolve.register -def _(cand: None) -> types.ModuleType: - return resolve(_infer_caller().f_globals['__name__']) - - -def _infer_caller(): - """ - Walk the stack and find the frame of the first caller not in this module. - """ - - def is_this_file(frame_info): - return frame_info.filename == __file__ - - def is_wrapper(frame_info): - return frame_info.function == 'wrapper' - - not_this_file = itertools.filterfalse(is_this_file, inspect.stack()) - # also exclude 'wrapper' due to singledispatch in the call stack - callers = itertools.filterfalse(is_wrapper, not_this_file) - return next(callers).frame - - -def from_package(package: types.ModuleType): - """ - Return a Traversable object for the given package. - - """ - # deferred for performance (python/cpython#109829) - from .future.adapters import wrap_spec - - spec = wrap_spec(package) - reader = spec.loader.get_resource_reader(spec.name) - return reader.files() - - -@contextlib.contextmanager -def _tempfile( - reader, - suffix='', - # gh-93353: Keep a reference to call os.remove() in late Python - # finalization. - *, - _os_remove=os.remove, -): - # Not using tempfile.NamedTemporaryFile as it leads to deeper 'try' - # blocks due to the need to close the temporary file to work on Windows - # properly. - fd, raw_path = tempfile.mkstemp(suffix=suffix) - try: - try: - os.write(fd, reader()) - finally: - os.close(fd) - del reader - yield pathlib.Path(raw_path) - finally: - try: - _os_remove(raw_path) - except FileNotFoundError: - pass - - -def _temp_file(path): - return _tempfile(path.read_bytes, suffix=path.name) - - -def _is_present_dir(path: Traversable) -> bool: - """ - Some Traversables implement ``is_dir()`` to raise an - exception (i.e. ``FileNotFoundError``) when the - directory doesn't exist. This function wraps that call - to always return a boolean and only return True - if there's a dir and it exists. - """ - with contextlib.suppress(FileNotFoundError): - return path.is_dir() - return False - - -@functools.singledispatch -def as_file(path): - """ - Given a Traversable object, return that object as a - path on the local file system in a context manager. - """ - return _temp_dir(path) if _is_present_dir(path) else _temp_file(path) - - -@as_file.register(pathlib.Path) -@contextlib.contextmanager -def _(path): - """ - Degenerate behavior for pathlib.Path objects. - """ - yield path - - -@contextlib.contextmanager -def _temp_path(dir: tempfile.TemporaryDirectory): - """ - Wrap tempfile.TemporyDirectory to return a pathlib object. - """ - with dir as result: - yield pathlib.Path(result) - - -@contextlib.contextmanager -def _temp_dir(path): - """ - Given a traversable dir, recursively replicate the whole tree - to the file system in a context manager. - """ - assert path.is_dir() - with _temp_path(tempfile.TemporaryDirectory()) as temp_dir: - yield _write_contents(temp_dir, path) - - -def _write_contents(target, source): - child = target.joinpath(source.name) - if source.is_dir(): - child.mkdir() - for item in source.iterdir(): - _write_contents(child, item) - else: - child.write_bytes(source.read_bytes()) - return child diff --git a/setuptools/_vendor/importlib_resources/_itertools.py b/setuptools/_vendor/importlib_resources/_itertools.py deleted file mode 100644 index 7b775ef5ae..0000000000 --- a/setuptools/_vendor/importlib_resources/_itertools.py +++ /dev/null @@ -1,38 +0,0 @@ -# from more_itertools 9.0 -def only(iterable, default=None, too_long=None): - """If *iterable* has only one item, return it. - If it has zero items, return *default*. - If it has more than one item, raise the exception given by *too_long*, - which is ``ValueError`` by default. - >>> only([], default='missing') - 'missing' - >>> only([1]) - 1 - >>> only([1, 2]) # doctest: +IGNORE_EXCEPTION_DETAIL - Traceback (most recent call last): - ... - ValueError: Expected exactly one item in iterable, but got 1, 2, - and perhaps more.' - >>> only([1, 2], too_long=TypeError) # doctest: +IGNORE_EXCEPTION_DETAIL - Traceback (most recent call last): - ... - TypeError - Note that :func:`only` attempts to advance *iterable* twice to ensure there - is only one item. See :func:`spy` or :func:`peekable` to check - iterable contents less destructively. - """ - it = iter(iterable) - first_value = next(it, default) - - try: - second_value = next(it) - except StopIteration: - pass - else: - msg = ( - 'Expected exactly one item in iterable, but got {!r}, {!r}, ' - 'and perhaps more.'.format(first_value, second_value) - ) - raise too_long or ValueError(msg) - - return first_value diff --git a/setuptools/_vendor/importlib_resources/abc.py b/setuptools/_vendor/importlib_resources/abc.py deleted file mode 100644 index 7a58dd2f96..0000000000 --- a/setuptools/_vendor/importlib_resources/abc.py +++ /dev/null @@ -1,171 +0,0 @@ -import abc -import io -import itertools -import pathlib -from typing import Any, BinaryIO, Iterable, Iterator, NoReturn, Text, Optional -from typing import runtime_checkable, Protocol - -from .compat.py38 import StrPath - - -__all__ = ["ResourceReader", "Traversable", "TraversableResources"] - - -class ResourceReader(metaclass=abc.ABCMeta): - """Abstract base class for loaders to provide resource reading support.""" - - @abc.abstractmethod - def open_resource(self, resource: Text) -> BinaryIO: - """Return an opened, file-like object for binary reading. - - The 'resource' argument is expected to represent only a file name. - If the resource cannot be found, FileNotFoundError is raised. - """ - # This deliberately raises FileNotFoundError instead of - # NotImplementedError so that if this method is accidentally called, - # it'll still do the right thing. - raise FileNotFoundError - - @abc.abstractmethod - def resource_path(self, resource: Text) -> Text: - """Return the file system path to the specified resource. - - The 'resource' argument is expected to represent only a file name. - If the resource does not exist on the file system, raise - FileNotFoundError. - """ - # This deliberately raises FileNotFoundError instead of - # NotImplementedError so that if this method is accidentally called, - # it'll still do the right thing. - raise FileNotFoundError - - @abc.abstractmethod - def is_resource(self, path: Text) -> bool: - """Return True if the named 'path' is a resource. - - Files are resources, directories are not. - """ - raise FileNotFoundError - - @abc.abstractmethod - def contents(self) -> Iterable[str]: - """Return an iterable of entries in `package`.""" - raise FileNotFoundError - - -class TraversalError(Exception): - pass - - -@runtime_checkable -class Traversable(Protocol): - """ - An object with a subset of pathlib.Path methods suitable for - traversing directories and opening files. - - Any exceptions that occur when accessing the backing resource - may propagate unaltered. - """ - - @abc.abstractmethod - def iterdir(self) -> Iterator["Traversable"]: - """ - Yield Traversable objects in self - """ - - def read_bytes(self) -> bytes: - """ - Read contents of self as bytes - """ - with self.open('rb') as strm: - return strm.read() - - def read_text(self, encoding: Optional[str] = None) -> str: - """ - Read contents of self as text - """ - with self.open(encoding=encoding) as strm: - return strm.read() - - @abc.abstractmethod - def is_dir(self) -> bool: - """ - Return True if self is a directory - """ - - @abc.abstractmethod - def is_file(self) -> bool: - """ - Return True if self is a file - """ - - def joinpath(self, *descendants: StrPath) -> "Traversable": - """ - Return Traversable resolved with any descendants applied. - - Each descendant should be a path segment relative to self - and each may contain multiple levels separated by - ``posixpath.sep`` (``/``). - """ - if not descendants: - return self - names = itertools.chain.from_iterable( - path.parts for path in map(pathlib.PurePosixPath, descendants) - ) - target = next(names) - matches = ( - traversable for traversable in self.iterdir() if traversable.name == target - ) - try: - match = next(matches) - except StopIteration: - raise TraversalError( - "Target not found during traversal.", target, list(names) - ) - return match.joinpath(*names) - - def __truediv__(self, child: StrPath) -> "Traversable": - """ - Return Traversable child in self - """ - return self.joinpath(child) - - @abc.abstractmethod - def open(self, mode='r', *args, **kwargs): - """ - mode may be 'r' or 'rb' to open as text or binary. Return a handle - suitable for reading (same as pathlib.Path.open). - - When opening as text, accepts encoding parameters such as those - accepted by io.TextIOWrapper. - """ - - @property - @abc.abstractmethod - def name(self) -> str: - """ - The base name of this object without any parent references. - """ - - -class TraversableResources(ResourceReader): - """ - The required interface for providing traversable - resources. - """ - - @abc.abstractmethod - def files(self) -> "Traversable": - """Return a Traversable object for the loaded package.""" - - def open_resource(self, resource: StrPath) -> io.BufferedReader: - return self.files().joinpath(resource).open('rb') - - def resource_path(self, resource: Any) -> NoReturn: - raise FileNotFoundError(resource) - - def is_resource(self, path: StrPath) -> bool: - return self.files().joinpath(path).is_file() - - def contents(self) -> Iterator[str]: - return (item.name for item in self.files().iterdir()) diff --git a/setuptools/_vendor/importlib_resources/compat/__init__.py b/setuptools/_vendor/importlib_resources/compat/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources/compat/py38.py b/setuptools/_vendor/importlib_resources/compat/py38.py deleted file mode 100644 index 4d548257f8..0000000000 --- a/setuptools/_vendor/importlib_resources/compat/py38.py +++ /dev/null @@ -1,11 +0,0 @@ -import os -import sys - -from typing import Union - - -if sys.version_info >= (3, 9): - StrPath = Union[str, os.PathLike[str]] -else: - # PathLike is only subscriptable at runtime in 3.9+ - StrPath = Union[str, "os.PathLike[str]"] diff --git a/setuptools/_vendor/importlib_resources/compat/py39.py b/setuptools/_vendor/importlib_resources/compat/py39.py deleted file mode 100644 index ab87b9dc14..0000000000 --- a/setuptools/_vendor/importlib_resources/compat/py39.py +++ /dev/null @@ -1,10 +0,0 @@ -import sys - - -__all__ = ['ZipPath'] - - -if sys.version_info >= (3, 10): - from zipfile import Path as ZipPath # type: ignore -else: - from zipp import Path as ZipPath # type: ignore diff --git a/setuptools/_vendor/importlib_resources/functional.py b/setuptools/_vendor/importlib_resources/functional.py deleted file mode 100644 index f59416f2dd..0000000000 --- a/setuptools/_vendor/importlib_resources/functional.py +++ /dev/null @@ -1,81 +0,0 @@ -"""Simplified function-based API for importlib.resources""" - -import warnings - -from ._common import files, as_file - - -_MISSING = object() - - -def open_binary(anchor, *path_names): - """Open for binary reading the *resource* within *package*.""" - return _get_resource(anchor, path_names).open('rb') - - -def open_text(anchor, *path_names, encoding=_MISSING, errors='strict'): - """Open for text reading the *resource* within *package*.""" - encoding = _get_encoding_arg(path_names, encoding) - resource = _get_resource(anchor, path_names) - return resource.open('r', encoding=encoding, errors=errors) - - -def read_binary(anchor, *path_names): - """Read and return contents of *resource* within *package* as bytes.""" - return _get_resource(anchor, path_names).read_bytes() - - -def read_text(anchor, *path_names, encoding=_MISSING, errors='strict'): - """Read and return contents of *resource* within *package* as str.""" - encoding = _get_encoding_arg(path_names, encoding) - resource = _get_resource(anchor, path_names) - return resource.read_text(encoding=encoding, errors=errors) - - -def path(anchor, *path_names): - """Return the path to the *resource* as an actual file system path.""" - return as_file(_get_resource(anchor, path_names)) - - -def is_resource(anchor, *path_names): - """Return ``True`` if there is a resource named *name* in the package, - - Otherwise returns ``False``. - """ - return _get_resource(anchor, path_names).is_file() - - -def contents(anchor, *path_names): - """Return an iterable over the named resources within the package. - - The iterable returns :class:`str` resources (e.g. files). - The iterable does not recurse into subdirectories. - """ - warnings.warn( - "importlib.resources.contents is deprecated. " - "Use files(anchor).iterdir() instead.", - DeprecationWarning, - stacklevel=1, - ) - return (resource.name for resource in _get_resource(anchor, path_names).iterdir()) - - -def _get_encoding_arg(path_names, encoding): - # For compatibility with versions where *encoding* was a positional - # argument, it needs to be given explicitly when there are multiple - # *path_names*. - # This limitation can be removed in Python 3.15. - if encoding is _MISSING: - if len(path_names) > 1: - raise TypeError( - "'encoding' argument required with multiple path names", - ) - else: - return 'utf-8' - return encoding - - -def _get_resource(anchor, path_names): - if anchor is None: - raise TypeError("anchor must be module or string, got None") - return files(anchor).joinpath(*path_names) diff --git a/setuptools/_vendor/importlib_resources/future/__init__.py b/setuptools/_vendor/importlib_resources/future/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources/future/adapters.py b/setuptools/_vendor/importlib_resources/future/adapters.py deleted file mode 100644 index 0e9764bae8..0000000000 --- a/setuptools/_vendor/importlib_resources/future/adapters.py +++ /dev/null @@ -1,95 +0,0 @@ -import functools -import pathlib -from contextlib import suppress -from types import SimpleNamespace - -from .. import readers, _adapters - - -def _block_standard(reader_getter): - """ - Wrap _adapters.TraversableResourcesLoader.get_resource_reader - and intercept any standard library readers. - """ - - @functools.wraps(reader_getter) - def wrapper(*args, **kwargs): - """ - If the reader is from the standard library, return None to allow - allow likely newer implementations in this library to take precedence. - """ - try: - reader = reader_getter(*args, **kwargs) - except NotADirectoryError: - # MultiplexedPath may fail on zip subdirectory - return - # Python 3.10+ - mod_name = reader.__class__.__module__ - if mod_name.startswith('importlib.') and mod_name.endswith('readers'): - return - # Python 3.8, 3.9 - if isinstance(reader, _adapters.CompatibilityFiles) and ( - reader.spec.loader.__class__.__module__.startswith('zipimport') - or reader.spec.loader.__class__.__module__.startswith( - '_frozen_importlib_external' - ) - ): - return - return reader - - return wrapper - - -def _skip_degenerate(reader): - """ - Mask any degenerate reader. Ref #298. - """ - is_degenerate = ( - isinstance(reader, _adapters.CompatibilityFiles) and not reader._reader - ) - return reader if not is_degenerate else None - - -class TraversableResourcesLoader(_adapters.TraversableResourcesLoader): - """ - Adapt loaders to provide TraversableResources and other - compatibility. - - Ensures the readers from importlib_resources are preferred - over stdlib readers. - """ - - def get_resource_reader(self, name): - return ( - _skip_degenerate(_block_standard(super().get_resource_reader)(name)) - or self._standard_reader() - or super().get_resource_reader(name) - ) - - def _standard_reader(self): - return self._zip_reader() or self._namespace_reader() or self._file_reader() - - def _zip_reader(self): - with suppress(AttributeError): - return readers.ZipReader(self.spec.loader, self.spec.name) - - def _namespace_reader(self): - with suppress(AttributeError, ValueError): - return readers.NamespaceReader(self.spec.submodule_search_locations) - - def _file_reader(self): - try: - path = pathlib.Path(self.spec.origin) - except TypeError: - return None - if path.exists(): - return readers.FileReader(SimpleNamespace(path=path)) - - -def wrap_spec(package): - """ - Override _adapters.wrap_spec to use TraversableResourcesLoader - from above. Ensures that future behavior is always available on older - Pythons. - """ - return _adapters.SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) diff --git a/setuptools/_vendor/importlib_resources/py.typed b/setuptools/_vendor/importlib_resources/py.typed deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources/readers.py b/setuptools/_vendor/importlib_resources/readers.py deleted file mode 100644 index 4a80a774aa..0000000000 --- a/setuptools/_vendor/importlib_resources/readers.py +++ /dev/null @@ -1,194 +0,0 @@ -import collections -import contextlib -import itertools -import pathlib -import operator -import re -import warnings - -from . import abc - -from ._itertools import only -from .compat.py39 import ZipPath - - -def remove_duplicates(items): - return iter(collections.OrderedDict.fromkeys(items)) - - -class FileReader(abc.TraversableResources): - def __init__(self, loader): - self.path = pathlib.Path(loader.path).parent - - def resource_path(self, resource): - """ - Return the file system path to prevent - `resources.path()` from creating a temporary - copy. - """ - return str(self.path.joinpath(resource)) - - def files(self): - return self.path - - -class ZipReader(abc.TraversableResources): - def __init__(self, loader, module): - _, _, name = module.rpartition('.') - self.prefix = loader.prefix.replace('\\', '/') + name + '/' - self.archive = loader.archive - - def open_resource(self, resource): - try: - return super().open_resource(resource) - except KeyError as exc: - raise FileNotFoundError(exc.args[0]) - - def is_resource(self, path): - """ - Workaround for `zipfile.Path.is_file` returning true - for non-existent paths. - """ - target = self.files().joinpath(path) - return target.is_file() and target.exists() - - def files(self): - return ZipPath(self.archive, self.prefix) - - -class MultiplexedPath(abc.Traversable): - """ - Given a series of Traversable objects, implement a merged - version of the interface across all objects. Useful for - namespace packages which may be multihomed at a single - name. - """ - - def __init__(self, *paths): - self._paths = list(map(_ensure_traversable, remove_duplicates(paths))) - if not self._paths: - message = 'MultiplexedPath must contain at least one path' - raise FileNotFoundError(message) - if not all(path.is_dir() for path in self._paths): - raise NotADirectoryError('MultiplexedPath only supports directories') - - def iterdir(self): - children = (child for path in self._paths for child in path.iterdir()) - by_name = operator.attrgetter('name') - groups = itertools.groupby(sorted(children, key=by_name), key=by_name) - return map(self._follow, (locs for name, locs in groups)) - - def read_bytes(self): - raise FileNotFoundError(f'{self} is not a file') - - def read_text(self, *args, **kwargs): - raise FileNotFoundError(f'{self} is not a file') - - def is_dir(self): - return True - - def is_file(self): - return False - - def joinpath(self, *descendants): - try: - return super().joinpath(*descendants) - except abc.TraversalError: - # One of the paths did not resolve (a directory does not exist). - # Just return something that will not exist. - return self._paths[0].joinpath(*descendants) - - @classmethod - def _follow(cls, children): - """ - Construct a MultiplexedPath if needed. - - If children contains a sole element, return it. - Otherwise, return a MultiplexedPath of the items. - Unless one of the items is not a Directory, then return the first. - """ - subdirs, one_dir, one_file = itertools.tee(children, 3) - - try: - return only(one_dir) - except ValueError: - try: - return cls(*subdirs) - except NotADirectoryError: - return next(one_file) - - def open(self, *args, **kwargs): - raise FileNotFoundError(f'{self} is not a file') - - @property - def name(self): - return self._paths[0].name - - def __repr__(self): - paths = ', '.join(f"'{path}'" for path in self._paths) - return f'MultiplexedPath({paths})' - - -class NamespaceReader(abc.TraversableResources): - def __init__(self, namespace_path): - if 'NamespacePath' not in str(namespace_path): - raise ValueError('Invalid path') - self.path = MultiplexedPath(*map(self._resolve, namespace_path)) - - @classmethod - def _resolve(cls, path_str) -> abc.Traversable: - r""" - Given an item from a namespace path, resolve it to a Traversable. - - path_str might be a directory on the filesystem or a path to a - zipfile plus the path within the zipfile, e.g. ``/foo/bar`` or - ``/foo/baz.zip/inner_dir`` or ``foo\baz.zip\inner_dir\sub``. - """ - (dir,) = (cand for cand in cls._candidate_paths(path_str) if cand.is_dir()) - return dir - - @classmethod - def _candidate_paths(cls, path_str): - yield pathlib.Path(path_str) - yield from cls._resolve_zip_path(path_str) - - @staticmethod - def _resolve_zip_path(path_str): - for match in reversed(list(re.finditer(r'[\\/]', path_str))): - with contextlib.suppress( - FileNotFoundError, - IsADirectoryError, - NotADirectoryError, - PermissionError, - ): - inner = path_str[match.end() :].replace('\\', '/') + '/' - yield ZipPath(path_str[: match.start()], inner.lstrip('/')) - - def resource_path(self, resource): - """ - Return the file system path to prevent - `resources.path()` from creating a temporary - copy. - """ - return str(self.path.joinpath(resource)) - - def files(self): - return self.path - - -def _ensure_traversable(path): - """ - Convert deprecated string arguments to traversables (pathlib.Path). - - Remove with Python 3.15. - """ - if not isinstance(path, str): - return path - - warnings.warn( - "String arguments are deprecated. Pass a Traversable instead.", - DeprecationWarning, - stacklevel=3, - ) - - return pathlib.Path(path) diff --git a/setuptools/_vendor/importlib_resources/simple.py b/setuptools/_vendor/importlib_resources/simple.py deleted file mode 100644 index 96f117fec6..0000000000 --- a/setuptools/_vendor/importlib_resources/simple.py +++ /dev/null @@ -1,106 +0,0 @@ -""" -Interface adapters for low-level readers. -""" - -import abc -import io -import itertools -from typing import BinaryIO, List - -from .abc import Traversable, TraversableResources - - -class SimpleReader(abc.ABC): - """ - The minimum, low-level interface required from a resource - provider. - """ - - @property - @abc.abstractmethod - def package(self) -> str: - """ - The name of the package for which this reader loads resources. - """ - - @abc.abstractmethod - def children(self) -> List['SimpleReader']: - """ - Obtain an iterable of SimpleReader for available - child containers (e.g. directories). - """ - - @abc.abstractmethod - def resources(self) -> List[str]: - """ - Obtain available named resources for this virtual package. - """ - - @abc.abstractmethod - def open_binary(self, resource: str) -> BinaryIO: - """ - Obtain a File-like for a named resource. - """ - - @property - def name(self): - return self.package.split('.')[-1] - - -class ResourceContainer(Traversable): - """ - Traversable container for a package's resources via its reader. - """ - - def __init__(self, reader: SimpleReader): - self.reader = reader - - def is_dir(self): - return True - - def is_file(self): - return False - - def iterdir(self): - files = (ResourceHandle(self, name) for name in self.reader.resources) - dirs = map(ResourceContainer, self.reader.children()) - return itertools.chain(files, dirs) - - def open(self, *args, **kwargs): - raise IsADirectoryError() - - -class ResourceHandle(Traversable): - """ - Handle to a named resource in a ResourceReader. - """ - - def __init__(self, parent: ResourceContainer, name: str): - self.parent = parent - self.name = name # type: ignore - - def is_file(self): - return True - - def is_dir(self): - return False - - def open(self, mode='r', *args, **kwargs): - stream = self.parent.reader.open_binary(self.name) - if 'b' not in mode: - stream = io.TextIOWrapper(stream, *args, **kwargs) - return stream - - def joinpath(self, name): - raise RuntimeError("Cannot traverse into a resource") - - -class TraversableReader(TraversableResources, SimpleReader): - """ - A TraversableResources based on SimpleReader. Resource providers - may derive from this class to provide the TraversableResources - interface by supplying the SimpleReader interface. - """ - - def files(self): - return ResourceContainer(self) diff --git a/setuptools/_vendor/importlib_resources/tests/__init__.py b/setuptools/_vendor/importlib_resources/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources/tests/_path.py b/setuptools/_vendor/importlib_resources/tests/_path.py deleted file mode 100644 index 1f97c96146..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/_path.py +++ /dev/null @@ -1,56 +0,0 @@ -import pathlib -import functools - -from typing import Dict, Union - - -#### -# from jaraco.path 3.4.1 - -FilesSpec = Dict[str, Union[str, bytes, 'FilesSpec']] # type: ignore - - -def build(spec: FilesSpec, prefix=pathlib.Path()): - """ - Build a set of files/directories, as described by the spec. - - Each key represents a pathname, and the value represents - the content. Content may be a nested directory. - - >>> spec = { - ... 'README.txt': "A README file", - ... "foo": { - ... "__init__.py": "", - ... "bar": { - ... "__init__.py": "", - ... }, - ... "baz.py": "# Some code", - ... } - ... } - >>> target = getfixture('tmp_path') - >>> build(spec, target) - >>> target.joinpath('foo/baz.py').read_text(encoding='utf-8') - '# Some code' - """ - for name, contents in spec.items(): - create(contents, pathlib.Path(prefix) / name) - - -@functools.singledispatch -def create(content: Union[str, bytes, FilesSpec], path): - path.mkdir(exist_ok=True) - build(content, prefix=path) # type: ignore - - -@create.register -def _(content: bytes, path): - path.write_bytes(content) - - -@create.register -def _(content: str, path): - path.write_text(content, encoding='utf-8') - - -# end from jaraco.path -#### diff --git a/setuptools/_vendor/importlib_resources/tests/compat/__init__.py b/setuptools/_vendor/importlib_resources/tests/compat/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources/tests/compat/py312.py b/setuptools/_vendor/importlib_resources/tests/compat/py312.py deleted file mode 100644 index ea9a58ba2e..0000000000 --- a/setuptools/_vendor/importlib_resources/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/setuptools/_vendor/importlib_resources/tests/compat/py39.py b/setuptools/_vendor/importlib_resources/tests/compat/py39.py deleted file mode 100644 index e158eb85d3..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/compat/py39.py +++ /dev/null @@ -1,10 +0,0 @@ -""" -Backward-compatability shims to support Python 3.9 and earlier. -""" - -from jaraco.test.cpython import from_test_support, try_import - -import_helper = try_import('import_helper') or from_test_support( - 'modules_setup', 'modules_cleanup', 'DirsOnSysPath' -) -os_helper = try_import('os_helper') or from_test_support('temp_dir') diff --git a/setuptools/_vendor/importlib_resources/tests/data01/__init__.py b/setuptools/_vendor/importlib_resources/tests/data01/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources/tests/data01/binary.file b/setuptools/_vendor/importlib_resources/tests/data01/binary.file deleted file mode 100644 index eaf36c1dac..0000000000 Binary files a/setuptools/_vendor/importlib_resources/tests/data01/binary.file and /dev/null differ diff --git a/setuptools/_vendor/importlib_resources/tests/data01/subdirectory/__init__.py b/setuptools/_vendor/importlib_resources/tests/data01/subdirectory/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources/tests/data01/subdirectory/binary.file b/setuptools/_vendor/importlib_resources/tests/data01/subdirectory/binary.file deleted file mode 100644 index 5bd8bb897b..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/data01/subdirectory/binary.file +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/setuptools/_vendor/importlib_resources/tests/data01/utf-16.file b/setuptools/_vendor/importlib_resources/tests/data01/utf-16.file deleted file mode 100644 index 2cb772295e..0000000000 Binary files a/setuptools/_vendor/importlib_resources/tests/data01/utf-16.file and /dev/null differ diff --git a/setuptools/_vendor/importlib_resources/tests/data01/utf-8.file b/setuptools/_vendor/importlib_resources/tests/data01/utf-8.file deleted file mode 100644 index 1c0132ad90..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/data01/utf-8.file +++ /dev/null @@ -1 +0,0 @@ -Hello, UTF-8 world! diff --git a/setuptools/_vendor/importlib_resources/tests/data02/__init__.py b/setuptools/_vendor/importlib_resources/tests/data02/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources/tests/data02/one/__init__.py b/setuptools/_vendor/importlib_resources/tests/data02/one/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources/tests/data02/one/resource1.txt b/setuptools/_vendor/importlib_resources/tests/data02/one/resource1.txt deleted file mode 100644 index 61a813e401..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/data02/one/resource1.txt +++ /dev/null @@ -1 +0,0 @@ -one resource diff --git a/setuptools/_vendor/importlib_resources/tests/data02/subdirectory/subsubdir/resource.txt b/setuptools/_vendor/importlib_resources/tests/data02/subdirectory/subsubdir/resource.txt deleted file mode 100644 index 48f587a2d0..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/data02/subdirectory/subsubdir/resource.txt +++ /dev/null @@ -1 +0,0 @@ -a resource \ No newline at end of file diff --git a/setuptools/_vendor/importlib_resources/tests/data02/two/__init__.py b/setuptools/_vendor/importlib_resources/tests/data02/two/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/setuptools/_vendor/importlib_resources/tests/data02/two/resource2.txt b/setuptools/_vendor/importlib_resources/tests/data02/two/resource2.txt deleted file mode 100644 index a80ce46ea3..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/data02/two/resource2.txt +++ /dev/null @@ -1 +0,0 @@ -two resource diff --git a/setuptools/_vendor/importlib_resources/tests/namespacedata01/binary.file b/setuptools/_vendor/importlib_resources/tests/namespacedata01/binary.file deleted file mode 100644 index eaf36c1dac..0000000000 Binary files a/setuptools/_vendor/importlib_resources/tests/namespacedata01/binary.file and /dev/null differ diff --git a/setuptools/_vendor/importlib_resources/tests/namespacedata01/subdirectory/binary.file b/setuptools/_vendor/importlib_resources/tests/namespacedata01/subdirectory/binary.file deleted file mode 100644 index 100f50643d..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/namespacedata01/subdirectory/binary.file +++ /dev/null @@ -1 +0,0 @@ -  \ No newline at end of file diff --git a/setuptools/_vendor/importlib_resources/tests/namespacedata01/utf-16.file b/setuptools/_vendor/importlib_resources/tests/namespacedata01/utf-16.file deleted file mode 100644 index 2cb772295e..0000000000 Binary files a/setuptools/_vendor/importlib_resources/tests/namespacedata01/utf-16.file and /dev/null differ diff --git a/setuptools/_vendor/importlib_resources/tests/namespacedata01/utf-8.file b/setuptools/_vendor/importlib_resources/tests/namespacedata01/utf-8.file deleted file mode 100644 index 1c0132ad90..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/namespacedata01/utf-8.file +++ /dev/null @@ -1 +0,0 @@ -Hello, UTF-8 world! diff --git a/setuptools/_vendor/importlib_resources/tests/test_compatibilty_files.py b/setuptools/_vendor/importlib_resources/tests/test_compatibilty_files.py deleted file mode 100644 index 13ad0dfb21..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/test_compatibilty_files.py +++ /dev/null @@ -1,104 +0,0 @@ -import io -import unittest - -import importlib_resources as resources - -from importlib_resources._adapters import ( - CompatibilityFiles, - wrap_spec, -) - -from . import util - - -class CompatibilityFilesTests(unittest.TestCase): - @property - def package(self): - bytes_data = io.BytesIO(b'Hello, world!') - return util.create_package( - file=bytes_data, - path='some_path', - contents=('a', 'b', 'c'), - ) - - @property - def files(self): - return resources.files(self.package) - - def test_spec_path_iter(self): - self.assertEqual( - sorted(path.name for path in self.files.iterdir()), - ['a', 'b', 'c'], - ) - - def test_child_path_iter(self): - self.assertEqual(list((self.files / 'a').iterdir()), []) - - def test_orphan_path_iter(self): - self.assertEqual(list((self.files / 'a' / 'a').iterdir()), []) - self.assertEqual(list((self.files / 'a' / 'a' / 'a').iterdir()), []) - - def test_spec_path_is(self): - self.assertFalse(self.files.is_file()) - self.assertFalse(self.files.is_dir()) - - def test_child_path_is(self): - self.assertTrue((self.files / 'a').is_file()) - self.assertFalse((self.files / 'a').is_dir()) - - def test_orphan_path_is(self): - self.assertFalse((self.files / 'a' / 'a').is_file()) - self.assertFalse((self.files / 'a' / 'a').is_dir()) - self.assertFalse((self.files / 'a' / 'a' / 'a').is_file()) - self.assertFalse((self.files / 'a' / 'a' / 'a').is_dir()) - - def test_spec_path_name(self): - self.assertEqual(self.files.name, 'testingpackage') - - def test_child_path_name(self): - self.assertEqual((self.files / 'a').name, 'a') - - def test_orphan_path_name(self): - self.assertEqual((self.files / 'a' / 'b').name, 'b') - self.assertEqual((self.files / 'a' / 'b' / 'c').name, 'c') - - def test_spec_path_open(self): - self.assertEqual(self.files.read_bytes(), b'Hello, world!') - self.assertEqual(self.files.read_text(encoding='utf-8'), 'Hello, world!') - - def test_child_path_open(self): - self.assertEqual((self.files / 'a').read_bytes(), b'Hello, world!') - self.assertEqual( - (self.files / 'a').read_text(encoding='utf-8'), 'Hello, world!' - ) - - def test_orphan_path_open(self): - with self.assertRaises(FileNotFoundError): - (self.files / 'a' / 'b').read_bytes() - with self.assertRaises(FileNotFoundError): - (self.files / 'a' / 'b' / 'c').read_bytes() - - def test_open_invalid_mode(self): - with self.assertRaises(ValueError): - self.files.open('0') - - def test_orphan_path_invalid(self): - with self.assertRaises(ValueError): - CompatibilityFiles.OrphanPath() - - def test_wrap_spec(self): - spec = wrap_spec(self.package) - self.assertIsInstance(spec.loader.get_resource_reader(None), CompatibilityFiles) - - -class CompatibilityFilesNoReaderTests(unittest.TestCase): - @property - def package(self): - return util.create_package_from_loader(None) - - @property - def files(self): - return resources.files(self.package) - - def test_spec_path_joinpath(self): - self.assertIsInstance(self.files / 'a', CompatibilityFiles.OrphanPath) diff --git a/setuptools/_vendor/importlib_resources/tests/test_contents.py b/setuptools/_vendor/importlib_resources/tests/test_contents.py deleted file mode 100644 index 7dc3b0a619..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/test_contents.py +++ /dev/null @@ -1,43 +0,0 @@ -import unittest -import importlib_resources as resources - -from . import data01 -from . import util - - -class ContentsTests: - expected = { - '__init__.py', - 'binary.file', - 'subdirectory', - 'utf-16.file', - 'utf-8.file', - } - - def test_contents(self): - contents = {path.name for path in resources.files(self.data).iterdir()} - assert self.expected <= contents - - -class ContentsDiskTests(ContentsTests, unittest.TestCase): - def setUp(self): - self.data = data01 - - -class ContentsZipTests(ContentsTests, util.ZipSetup, unittest.TestCase): - pass - - -class ContentsNamespaceTests(ContentsTests, unittest.TestCase): - expected = { - # no __init__ because of namespace design - 'binary.file', - 'subdirectory', - 'utf-16.file', - 'utf-8.file', - } - - def setUp(self): - from . import namespacedata01 - - self.data = namespacedata01 diff --git a/setuptools/_vendor/importlib_resources/tests/test_custom.py b/setuptools/_vendor/importlib_resources/tests/test_custom.py deleted file mode 100644 index 86c65676f1..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/test_custom.py +++ /dev/null @@ -1,47 +0,0 @@ -import unittest -import contextlib -import pathlib - -import importlib_resources as resources -from .. import abc -from ..abc import TraversableResources, ResourceReader -from . import util -from .compat.py39 import os_helper - - -class SimpleLoader: - """ - A simple loader that only implements a resource reader. - """ - - def __init__(self, reader: ResourceReader): - self.reader = reader - - def get_resource_reader(self, package): - return self.reader - - -class MagicResources(TraversableResources): - """ - Magically returns the resources at path. - """ - - def __init__(self, path: pathlib.Path): - self.path = path - - def files(self): - return self.path - - -class CustomTraversableResourcesTests(unittest.TestCase): - def setUp(self): - self.fixtures = contextlib.ExitStack() - self.addCleanup(self.fixtures.close) - - def test_custom_loader(self): - temp_dir = pathlib.Path(self.fixtures.enter_context(os_helper.temp_dir())) - loader = SimpleLoader(MagicResources(temp_dir)) - pkg = util.create_package_from_loader(loader) - files = resources.files(pkg) - assert isinstance(files, abc.Traversable) - assert list(files.iterdir()) == [] diff --git a/setuptools/_vendor/importlib_resources/tests/test_files.py b/setuptools/_vendor/importlib_resources/tests/test_files.py deleted file mode 100644 index 3e86ec64bc..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/test_files.py +++ /dev/null @@ -1,117 +0,0 @@ -import textwrap -import unittest -import warnings -import importlib -import contextlib - -import importlib_resources as resources -from ..abc import Traversable -from . import data01 -from . import util -from . import _path -from .compat.py39 import os_helper -from .compat.py312 import import_helper - - -@contextlib.contextmanager -def suppress_known_deprecation(): - with warnings.catch_warnings(record=True) as ctx: - warnings.simplefilter('default', category=DeprecationWarning) - yield ctx - - -class FilesTests: - def test_read_bytes(self): - files = resources.files(self.data) - actual = files.joinpath('utf-8.file').read_bytes() - assert actual == b'Hello, UTF-8 world!\n' - - def test_read_text(self): - files = resources.files(self.data) - actual = files.joinpath('utf-8.file').read_text(encoding='utf-8') - assert actual == 'Hello, UTF-8 world!\n' - - def test_traversable(self): - assert isinstance(resources.files(self.data), Traversable) - - def test_joinpath_with_multiple_args(self): - files = resources.files(self.data) - binfile = files.joinpath('subdirectory', 'binary.file') - self.assertTrue(binfile.is_file()) - - def test_old_parameter(self): - """ - Files used to take a 'package' parameter. Make sure anyone - passing by name is still supported. - """ - with suppress_known_deprecation(): - resources.files(package=self.data) - - -class OpenDiskTests(FilesTests, unittest.TestCase): - def setUp(self): - self.data = data01 - - -class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase): - pass - - -class OpenNamespaceTests(FilesTests, unittest.TestCase): - def setUp(self): - from . import namespacedata01 - - self.data = namespacedata01 - - -class OpenNamespaceZipTests(FilesTests, util.ZipSetup, unittest.TestCase): - ZIP_MODULE = 'namespacedata01' - - -class SiteDir: - def setUp(self): - self.fixtures = contextlib.ExitStack() - self.addCleanup(self.fixtures.close) - self.site_dir = self.fixtures.enter_context(os_helper.temp_dir()) - self.fixtures.enter_context(import_helper.DirsOnSysPath(self.site_dir)) - self.fixtures.enter_context(import_helper.isolated_modules()) - - -class ModulesFilesTests(SiteDir, unittest.TestCase): - def test_module_resources(self): - """ - A module can have resources found adjacent to the module. - """ - spec = { - 'mod.py': '', - 'res.txt': 'resources are the best', - } - _path.build(spec, self.site_dir) - import mod - - actual = resources.files(mod).joinpath('res.txt').read_text(encoding='utf-8') - assert actual == spec['res.txt'] - - -class ImplicitContextFilesTests(SiteDir, unittest.TestCase): - def test_implicit_files(self): - """ - Without any parameter, files() will infer the location as the caller. - """ - spec = { - 'somepkg': { - '__init__.py': textwrap.dedent( - """ - import importlib_resources as res - val = res.files().joinpath('res.txt').read_text(encoding='utf-8') - """ - ), - 'res.txt': 'resources are the best', - }, - } - _path.build(spec, self.site_dir) - assert importlib.import_module('somepkg').val == 'resources are the best' - - -if __name__ == '__main__': - unittest.main() diff --git a/setuptools/_vendor/importlib_resources/tests/test_functional.py b/setuptools/_vendor/importlib_resources/tests/test_functional.py deleted file mode 100644 index 69706cf7be..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/test_functional.py +++ /dev/null @@ -1,242 +0,0 @@ -import unittest -import os -import contextlib - -try: - from test.support.warnings_helper import ignore_warnings, check_warnings -except ImportError: - # older Python versions - from test.support import ignore_warnings, check_warnings - -import importlib_resources as resources - -# Since the functional API forwards to Traversable, we only test -# filesystem resources here -- not zip files, namespace packages etc. -# We do test for two kinds of Anchor, though. - - -class StringAnchorMixin: - anchor01 = 'importlib_resources.tests.data01' - anchor02 = 'importlib_resources.tests.data02' - - -class ModuleAnchorMixin: - from . import data01 as anchor01 - from . import data02 as anchor02 - - -class FunctionalAPIBase: - def _gen_resourcetxt_path_parts(self): - """Yield various names of a text file in anchor02, each in a subTest""" - for path_parts in ( - ('subdirectory', 'subsubdir', 'resource.txt'), - ('subdirectory/subsubdir/resource.txt',), - ('subdirectory/subsubdir', 'resource.txt'), - ): - with self.subTest(path_parts=path_parts): - yield path_parts - - def test_read_text(self): - self.assertEqual( - resources.read_text(self.anchor01, 'utf-8.file'), - 'Hello, UTF-8 world!\n', - ) - self.assertEqual( - resources.read_text( - self.anchor02, - 'subdirectory', - 'subsubdir', - 'resource.txt', - encoding='utf-8', - ), - 'a resource', - ) - for path_parts in self._gen_resourcetxt_path_parts(): - self.assertEqual( - resources.read_text( - self.anchor02, - *path_parts, - encoding='utf-8', - ), - 'a resource', - ) - # Use generic OSError, since e.g. attempting to read a directory can - # fail with PermissionError rather than IsADirectoryError - with self.assertRaises(OSError): - resources.read_text(self.anchor01) - with self.assertRaises(OSError): - resources.read_text(self.anchor01, 'no-such-file') - with self.assertRaises(UnicodeDecodeError): - resources.read_text(self.anchor01, 'utf-16.file') - self.assertEqual( - resources.read_text( - self.anchor01, - 'binary.file', - encoding='latin1', - ), - '\x00\x01\x02\x03', - ) - self.assertEqual( - resources.read_text( - self.anchor01, - 'utf-16.file', - errors='backslashreplace', - ), - 'Hello, UTF-16 world!\n'.encode('utf-16').decode( - errors='backslashreplace', - ), - ) - - def test_read_binary(self): - self.assertEqual( - resources.read_binary(self.anchor01, 'utf-8.file'), - b'Hello, UTF-8 world!\n', - ) - for path_parts in self._gen_resourcetxt_path_parts(): - self.assertEqual( - resources.read_binary(self.anchor02, *path_parts), - b'a resource', - ) - - def test_open_text(self): - with resources.open_text(self.anchor01, 'utf-8.file') as f: - self.assertEqual(f.read(), 'Hello, UTF-8 world!\n') - for path_parts in self._gen_resourcetxt_path_parts(): - with resources.open_text( - self.anchor02, - *path_parts, - encoding='utf-8', - ) as f: - self.assertEqual(f.read(), 'a resource') - # Use generic OSError, since e.g. attempting to read a directory can - # fail with PermissionError rather than IsADirectoryError - with self.assertRaises(OSError): - resources.open_text(self.anchor01) - with self.assertRaises(OSError): - resources.open_text(self.anchor01, 'no-such-file') - with resources.open_text(self.anchor01, 'utf-16.file') as f: - with self.assertRaises(UnicodeDecodeError): - f.read() - with resources.open_text( - self.anchor01, - 'binary.file', - encoding='latin1', - ) as f: - self.assertEqual(f.read(), '\x00\x01\x02\x03') - with resources.open_text( - self.anchor01, - 'utf-16.file', - errors='backslashreplace', - ) as f: - self.assertEqual( - f.read(), - 'Hello, UTF-16 world!\n'.encode('utf-16').decode( - errors='backslashreplace', - ), - ) - - def test_open_binary(self): - with resources.open_binary(self.anchor01, 'utf-8.file') as f: - self.assertEqual(f.read(), b'Hello, UTF-8 world!\n') - for path_parts in self._gen_resourcetxt_path_parts(): - with resources.open_binary( - self.anchor02, - *path_parts, - ) as f: - self.assertEqual(f.read(), b'a resource') - - def test_path(self): - with resources.path(self.anchor01, 'utf-8.file') as path: - with open(str(path), encoding='utf-8') as f: - self.assertEqual(f.read(), 'Hello, UTF-8 world!\n') - with resources.path(self.anchor01) as path: - with open(os.path.join(path, 'utf-8.file'), encoding='utf-8') as f: - self.assertEqual(f.read(), 'Hello, UTF-8 world!\n') - - def test_is_resource(self): - is_resource = resources.is_resource - self.assertTrue(is_resource(self.anchor01, 'utf-8.file')) - self.assertFalse(is_resource(self.anchor01, 'no_such_file')) - self.assertFalse(is_resource(self.anchor01)) - self.assertFalse(is_resource(self.anchor01, 'subdirectory')) - for path_parts in self._gen_resourcetxt_path_parts(): - self.assertTrue(is_resource(self.anchor02, *path_parts)) - - def test_contents(self): - with check_warnings((".*contents.*", DeprecationWarning)): - c = resources.contents(self.anchor01) - self.assertGreaterEqual( - set(c), - {'utf-8.file', 'utf-16.file', 'binary.file', 'subdirectory'}, - ) - with contextlib.ExitStack() as cm: - cm.enter_context(self.assertRaises(OSError)) - cm.enter_context(check_warnings((".*contents.*", DeprecationWarning))) - - list(resources.contents(self.anchor01, 'utf-8.file')) - - for path_parts in self._gen_resourcetxt_path_parts(): - with contextlib.ExitStack() as cm: - cm.enter_context(self.assertRaises(OSError)) - cm.enter_context(check_warnings((".*contents.*", DeprecationWarning))) - - list(resources.contents(self.anchor01, *path_parts)) - with check_warnings((".*contents.*", DeprecationWarning)): - c = resources.contents(self.anchor01, 'subdirectory') - self.assertGreaterEqual( - set(c), - {'binary.file'}, - ) - - @ignore_warnings(category=DeprecationWarning) - def test_common_errors(self): - for func in ( - resources.read_text, - resources.read_binary, - resources.open_text, - resources.open_binary, - resources.path, - resources.is_resource, - resources.contents, - ): - with self.subTest(func=func): - # Rejecting None anchor - with self.assertRaises(TypeError): - func(None) - # Rejecting invalid anchor type - with self.assertRaises((TypeError, AttributeError)): - func(1234) - # Unknown module - with self.assertRaises(ModuleNotFoundError): - func('$missing module$') - - def test_text_errors(self): - for func in ( - resources.read_text, - resources.open_text, - ): - with self.subTest(func=func): - # Multiple path arguments need explicit encoding argument. - with self.assertRaises(TypeError): - func( - self.anchor02, - 'subdirectory', - 'subsubdir', - 'resource.txt', - ) - - -class FunctionalAPITest_StringAnchor( - unittest.TestCase, - FunctionalAPIBase, - StringAnchorMixin, -): - pass - - -class FunctionalAPITest_ModuleAnchor( - unittest.TestCase, - FunctionalAPIBase, - ModuleAnchorMixin, -): - pass diff --git a/setuptools/_vendor/importlib_resources/tests/test_open.py b/setuptools/_vendor/importlib_resources/tests/test_open.py deleted file mode 100644 index 44f1018af3..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/test_open.py +++ /dev/null @@ -1,89 +0,0 @@ -import unittest - -import importlib_resources as resources -from . import data01 -from . import util - - -class CommonBinaryTests(util.CommonTests, unittest.TestCase): - def execute(self, package, path): - target = resources.files(package).joinpath(path) - with target.open('rb'): - pass - - -class CommonTextTests(util.CommonTests, unittest.TestCase): - def execute(self, package, path): - target = resources.files(package).joinpath(path) - with target.open(encoding='utf-8'): - pass - - -class OpenTests: - def test_open_binary(self): - target = resources.files(self.data) / 'binary.file' - with target.open('rb') as fp: - result = fp.read() - self.assertEqual(result, bytes(range(4))) - - def test_open_text_default_encoding(self): - target = resources.files(self.data) / 'utf-8.file' - with target.open(encoding='utf-8') as fp: - result = fp.read() - self.assertEqual(result, 'Hello, UTF-8 world!\n') - - def test_open_text_given_encoding(self): - target = resources.files(self.data) / 'utf-16.file' - with target.open(encoding='utf-16', errors='strict') as fp: - result = fp.read() - self.assertEqual(result, 'Hello, UTF-16 world!\n') - - def test_open_text_with_errors(self): - """ - Raises UnicodeError without the 'errors' argument. - """ - target = resources.files(self.data) / 'utf-16.file' - with target.open(encoding='utf-8', errors='strict') as fp: - self.assertRaises(UnicodeError, fp.read) - with target.open(encoding='utf-8', errors='ignore') as fp: - result = fp.read() - self.assertEqual( - result, - 'H\x00e\x00l\x00l\x00o\x00,\x00 ' - '\x00U\x00T\x00F\x00-\x001\x006\x00 ' - '\x00w\x00o\x00r\x00l\x00d\x00!\x00\n\x00', - ) - - def test_open_binary_FileNotFoundError(self): - target = resources.files(self.data) / 'does-not-exist' - with self.assertRaises(FileNotFoundError): - target.open('rb') - - def test_open_text_FileNotFoundError(self): - target = resources.files(self.data) / 'does-not-exist' - with self.assertRaises(FileNotFoundError): - target.open(encoding='utf-8') - - -class OpenDiskTests(OpenTests, unittest.TestCase): - def setUp(self): - self.data = data01 - - -class OpenDiskNamespaceTests(OpenTests, unittest.TestCase): - def setUp(self): - from . import namespacedata01 - - self.data = namespacedata01 - - -class OpenZipTests(OpenTests, util.ZipSetup, unittest.TestCase): - pass - - -class OpenNamespaceZipTests(OpenTests, util.ZipSetup, unittest.TestCase): - ZIP_MODULE = 'namespacedata01' - - -if __name__ == '__main__': - unittest.main() diff --git a/setuptools/_vendor/importlib_resources/tests/test_path.py b/setuptools/_vendor/importlib_resources/tests/test_path.py deleted file mode 100644 index c3e1cbb4ed..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/test_path.py +++ /dev/null @@ -1,65 +0,0 @@ -import io -import pathlib -import unittest - -import importlib_resources as resources -from . import data01 -from . import util - - -class CommonTests(util.CommonTests, unittest.TestCase): - def execute(self, package, path): - with resources.as_file(resources.files(package).joinpath(path)): - pass - - -class PathTests: - def test_reading(self): - """ - Path should be readable and a pathlib.Path instance. - """ - target = resources.files(self.data) / 'utf-8.file' - with resources.as_file(target) as path: - self.assertIsInstance(path, pathlib.Path) - self.assertTrue(path.name.endswith("utf-8.file"), repr(path)) - self.assertEqual('Hello, UTF-8 world!\n', path.read_text(encoding='utf-8')) - - -class PathDiskTests(PathTests, unittest.TestCase): - data = data01 - - def test_natural_path(self): - """ - Guarantee the internal implementation detail that - file-system-backed resources do not get the tempdir - treatment. - """ - target = resources.files(self.data) / 'utf-8.file' - with resources.as_file(target) as path: - assert 'data' in str(path) - - -class PathMemoryTests(PathTests, unittest.TestCase): - def setUp(self): - file = io.BytesIO(b'Hello, UTF-8 world!\n') - self.addCleanup(file.close) - self.data = util.create_package( - file=file, path=FileNotFoundError("package exists only in memory") - ) - self.data.__spec__.origin = None - self.data.__spec__.has_location = False - - -class PathZipTests(PathTests, util.ZipSetup, unittest.TestCase): - def test_remove_in_context_manager(self): - """ - It is not an error if the file that was temporarily stashed on the - file system is removed inside the `with` stanza. - """ - target = resources.files(self.data) / 'utf-8.file' - with resources.as_file(target) as path: - path.unlink() - - -if __name__ == '__main__': - unittest.main() diff --git a/setuptools/_vendor/importlib_resources/tests/test_read.py b/setuptools/_vendor/importlib_resources/tests/test_read.py deleted file mode 100644 index 97d90128cf..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/test_read.py +++ /dev/null @@ -1,97 +0,0 @@ -import unittest -import importlib_resources as resources - -from . import data01 -from . import util -from importlib import import_module - - -class CommonBinaryTests(util.CommonTests, unittest.TestCase): - def execute(self, package, path): - resources.files(package).joinpath(path).read_bytes() - - -class CommonTextTests(util.CommonTests, unittest.TestCase): - def execute(self, package, path): - resources.files(package).joinpath(path).read_text(encoding='utf-8') - - -class ReadTests: - def test_read_bytes(self): - result = resources.files(self.data).joinpath('binary.file').read_bytes() - self.assertEqual(result, bytes(range(4))) - - def test_read_text_default_encoding(self): - result = ( - resources.files(self.data) - .joinpath('utf-8.file') - .read_text(encoding='utf-8') - ) - self.assertEqual(result, 'Hello, UTF-8 world!\n') - - def test_read_text_given_encoding(self): - result = ( - resources.files(self.data) - .joinpath('utf-16.file') - .read_text(encoding='utf-16') - ) - self.assertEqual(result, 'Hello, UTF-16 world!\n') - - def test_read_text_with_errors(self): - """ - Raises UnicodeError without the 'errors' argument. - """ - target = resources.files(self.data) / 'utf-16.file' - self.assertRaises(UnicodeError, target.read_text, encoding='utf-8') - result = target.read_text(encoding='utf-8', errors='ignore') - self.assertEqual( - result, - 'H\x00e\x00l\x00l\x00o\x00,\x00 ' - '\x00U\x00T\x00F\x00-\x001\x006\x00 ' - '\x00w\x00o\x00r\x00l\x00d\x00!\x00\n\x00', - ) - - -class ReadDiskTests(ReadTests, unittest.TestCase): - data = data01 - - -class ReadZipTests(ReadTests, util.ZipSetup, unittest.TestCase): - def test_read_submodule_resource(self): - submodule = import_module('data01.subdirectory') - result = resources.files(submodule).joinpath('binary.file').read_bytes() - self.assertEqual(result, bytes(range(4, 8))) - - def test_read_submodule_resource_by_name(self): - result = ( - resources.files('data01.subdirectory').joinpath('binary.file').read_bytes() - ) - self.assertEqual(result, bytes(range(4, 8))) - - -class ReadNamespaceTests(ReadTests, unittest.TestCase): - def setUp(self): - from . import namespacedata01 - - self.data = namespacedata01 - - -class ReadNamespaceZipTests(ReadTests, util.ZipSetup, unittest.TestCase): - ZIP_MODULE = 'namespacedata01' - - def test_read_submodule_resource(self): - submodule = import_module('namespacedata01.subdirectory') - result = resources.files(submodule).joinpath('binary.file').read_bytes() - self.assertEqual(result, bytes(range(12, 16))) - - def test_read_submodule_resource_by_name(self): - result = ( - resources.files('namespacedata01.subdirectory') - .joinpath('binary.file') - .read_bytes() - ) - self.assertEqual(result, bytes(range(12, 16))) - - -if __name__ == '__main__': - unittest.main() diff --git a/setuptools/_vendor/importlib_resources/tests/test_reader.py b/setuptools/_vendor/importlib_resources/tests/test_reader.py deleted file mode 100644 index 95c2fc85a4..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/test_reader.py +++ /dev/null @@ -1,145 +0,0 @@ -import os.path -import sys -import pathlib -import unittest - -from importlib import import_module -from importlib_resources.readers import MultiplexedPath, NamespaceReader - - -class MultiplexedPathTest(unittest.TestCase): - @classmethod - def setUpClass(cls): - cls.folder = pathlib.Path(__file__).parent / 'namespacedata01' - - def test_init_no_paths(self): - with self.assertRaises(FileNotFoundError): - MultiplexedPath() - - def test_init_file(self): - with self.assertRaises(NotADirectoryError): - MultiplexedPath(self.folder / 'binary.file') - - def test_iterdir(self): - contents = {path.name for path in MultiplexedPath(self.folder).iterdir()} - try: - contents.remove('__pycache__') - except (KeyError, ValueError): - pass - self.assertEqual( - contents, {'subdirectory', 'binary.file', 'utf-16.file', 'utf-8.file'} - ) - - def test_iterdir_duplicate(self): - data01 = pathlib.Path(__file__).parent.joinpath('data01') - contents = { - path.name for path in MultiplexedPath(self.folder, data01).iterdir() - } - for remove in ('__pycache__', '__init__.pyc'): - try: - contents.remove(remove) - except (KeyError, ValueError): - pass - self.assertEqual( - contents, - {'__init__.py', 'binary.file', 'subdirectory', 'utf-16.file', 'utf-8.file'}, - ) - - def test_is_dir(self): - self.assertEqual(MultiplexedPath(self.folder).is_dir(), True) - - def test_is_file(self): - self.assertEqual(MultiplexedPath(self.folder).is_file(), False) - - def test_open_file(self): - path = MultiplexedPath(self.folder) - with self.assertRaises(FileNotFoundError): - path.read_bytes() - with self.assertRaises(FileNotFoundError): - path.read_text() - with self.assertRaises(FileNotFoundError): - path.open() - - def test_join_path(self): - data01 = pathlib.Path(__file__).parent.joinpath('data01') - prefix = str(data01.parent) - path = MultiplexedPath(self.folder, data01) - self.assertEqual( - str(path.joinpath('binary.file'))[len(prefix) + 1 :], - os.path.join('namespacedata01', 'binary.file'), - ) - sub = path.joinpath('subdirectory') - assert isinstance(sub, MultiplexedPath) - assert 'namespacedata01' in str(sub) - assert 'data01' in str(sub) - self.assertEqual( - str(path.joinpath('imaginary'))[len(prefix) + 1 :], - os.path.join('namespacedata01', 'imaginary'), - ) - self.assertEqual(path.joinpath(), path) - - def test_join_path_compound(self): - path = MultiplexedPath(self.folder) - assert not path.joinpath('imaginary/foo.py').exists() - - def test_join_path_common_subdir(self): - data01 = pathlib.Path(__file__).parent.joinpath('data01') - data02 = pathlib.Path(__file__).parent.joinpath('data02') - prefix = str(data01.parent) - path = MultiplexedPath(data01, data02) - self.assertIsInstance(path.joinpath('subdirectory'), MultiplexedPath) - self.assertEqual( - str(path.joinpath('subdirectory', 'subsubdir'))[len(prefix) + 1 :], - os.path.join('data02', 'subdirectory', 'subsubdir'), - ) - - def test_repr(self): - self.assertEqual( - repr(MultiplexedPath(self.folder)), - f"MultiplexedPath('{self.folder}')", - ) - - def test_name(self): - self.assertEqual( - MultiplexedPath(self.folder).name, - os.path.basename(self.folder), - ) - - -class NamespaceReaderTest(unittest.TestCase): - site_dir = str(pathlib.Path(__file__).parent) - - @classmethod - def setUpClass(cls): - sys.path.append(cls.site_dir) - - @classmethod - def tearDownClass(cls): - sys.path.remove(cls.site_dir) - - def test_init_error(self): - with self.assertRaises(ValueError): - NamespaceReader(['path1', 'path2']) - - def test_resource_path(self): - namespacedata01 = import_module('namespacedata01') - reader = NamespaceReader(namespacedata01.__spec__.submodule_search_locations) - - root = os.path.abspath(os.path.join(__file__, '..', 'namespacedata01')) - self.assertEqual( - reader.resource_path('binary.file'), os.path.join(root, 'binary.file') - ) - self.assertEqual( - reader.resource_path('imaginary'), os.path.join(root, 'imaginary') - ) - - def test_files(self): - namespacedata01 = import_module('namespacedata01') - reader = NamespaceReader(namespacedata01.__spec__.submodule_search_locations) - root = os.path.abspath(os.path.join(__file__, '..', 'namespacedata01')) - self.assertIsInstance(reader.files(), MultiplexedPath) - self.assertEqual(repr(reader.files()), f"MultiplexedPath('{root}')") - - -if __name__ == '__main__': - unittest.main() diff --git a/setuptools/_vendor/importlib_resources/tests/test_resource.py b/setuptools/_vendor/importlib_resources/tests/test_resource.py deleted file mode 100644 index dc2a108cde..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/test_resource.py +++ /dev/null @@ -1,241 +0,0 @@ -import sys -import unittest -import importlib_resources as resources -import pathlib - -from . import data01 -from . import util -from importlib import import_module - - -class ResourceTests: - # Subclasses are expected to set the `data` attribute. - - def test_is_file_exists(self): - target = resources.files(self.data) / 'binary.file' - self.assertTrue(target.is_file()) - - def test_is_file_missing(self): - target = resources.files(self.data) / 'not-a-file' - self.assertFalse(target.is_file()) - - def test_is_dir(self): - target = resources.files(self.data) / 'subdirectory' - self.assertFalse(target.is_file()) - self.assertTrue(target.is_dir()) - - -class ResourceDiskTests(ResourceTests, unittest.TestCase): - def setUp(self): - self.data = data01 - - -class ResourceZipTests(ResourceTests, util.ZipSetup, unittest.TestCase): - pass - - -def names(traversable): - return {item.name for item in traversable.iterdir()} - - -class ResourceLoaderTests(unittest.TestCase): - def test_resource_contents(self): - package = util.create_package( - file=data01, path=data01.__file__, contents=['A', 'B', 'C'] - ) - self.assertEqual(names(resources.files(package)), {'A', 'B', 'C'}) - - def test_is_file(self): - package = util.create_package( - file=data01, path=data01.__file__, contents=['A', 'B', 'C', 'D/E', 'D/F'] - ) - self.assertTrue(resources.files(package).joinpath('B').is_file()) - - def test_is_dir(self): - package = util.create_package( - file=data01, path=data01.__file__, contents=['A', 'B', 'C', 'D/E', 'D/F'] - ) - self.assertTrue(resources.files(package).joinpath('D').is_dir()) - - def test_resource_missing(self): - package = util.create_package( - file=data01, path=data01.__file__, contents=['A', 'B', 'C', 'D/E', 'D/F'] - ) - self.assertFalse(resources.files(package).joinpath('Z').is_file()) - - -class ResourceCornerCaseTests(unittest.TestCase): - def test_package_has_no_reader_fallback(self): - """ - Test odd ball packages which: - # 1. Do not have a ResourceReader as a loader - # 2. Are not on the file system - # 3. Are not in a zip file - """ - module = util.create_package( - file=data01, path=data01.__file__, contents=['A', 'B', 'C'] - ) - # Give the module a dummy loader. - module.__loader__ = object() - # Give the module a dummy origin. - module.__file__ = '/path/which/shall/not/be/named' - module.__spec__.loader = module.__loader__ - module.__spec__.origin = module.__file__ - self.assertFalse(resources.files(module).joinpath('A').is_file()) - - -class ResourceFromZipsTest01(util.ZipSetupBase, unittest.TestCase): - ZIP_MODULE = 'data01' - - def test_is_submodule_resource(self): - submodule = import_module('data01.subdirectory') - self.assertTrue(resources.files(submodule).joinpath('binary.file').is_file()) - - def test_read_submodule_resource_by_name(self): - self.assertTrue( - resources.files('data01.subdirectory').joinpath('binary.file').is_file() - ) - - def test_submodule_contents(self): - submodule = import_module('data01.subdirectory') - self.assertEqual( - names(resources.files(submodule)), {'__init__.py', 'binary.file'} - ) - - def test_submodule_contents_by_name(self): - self.assertEqual( - names(resources.files('data01.subdirectory')), - {'__init__.py', 'binary.file'}, - ) - - def test_as_file_directory(self): - with resources.as_file(resources.files('data01')) as data: - assert data.name == 'data01' - assert data.is_dir() - assert data.joinpath('subdirectory').is_dir() - assert len(list(data.iterdir())) - assert not data.parent.exists() - - -class ResourceFromZipsTest02(util.ZipSetupBase, unittest.TestCase): - ZIP_MODULE = 'data02' - - def test_unrelated_contents(self): - """ - Test thata zip with two unrelated subpackages return - distinct resources. Ref python/importlib_resources#44. - """ - self.assertEqual( - names(resources.files('data02.one')), - {'__init__.py', 'resource1.txt'}, - ) - self.assertEqual( - names(resources.files('data02.two')), - {'__init__.py', 'resource2.txt'}, - ) - - -class DeletingZipsTest(util.ZipSetupBase, unittest.TestCase): - """Having accessed resources in a zip file should not keep an open - reference to the zip. - """ - - def test_iterdir_does_not_keep_open(self): - [item.name for item in resources.files('data01').iterdir()] - - def test_is_file_does_not_keep_open(self): - resources.files('data01').joinpath('binary.file').is_file() - - def test_is_file_failure_does_not_keep_open(self): - resources.files('data01').joinpath('not-present').is_file() - - @unittest.skip("Desired but not supported.") - def test_as_file_does_not_keep_open(self): # pragma: no cover - resources.as_file(resources.files('data01') / 'binary.file') - - def test_entered_path_does_not_keep_open(self): - """ - Mimic what certifi does on import to make its bundle - available for the process duration. - """ - resources.as_file(resources.files('data01') / 'binary.file').__enter__() - - def test_read_binary_does_not_keep_open(self): - resources.files('data01').joinpath('binary.file').read_bytes() - - def test_read_text_does_not_keep_open(self): - resources.files('data01').joinpath('utf-8.file').read_text(encoding='utf-8') - - -class ResourceFromNamespaceTests: - def test_is_submodule_resource(self): - self.assertTrue( - resources.files(import_module('namespacedata01')) - .joinpath('binary.file') - .is_file() - ) - - def test_read_submodule_resource_by_name(self): - self.assertTrue( - resources.files('namespacedata01').joinpath('binary.file').is_file() - ) - - def test_submodule_contents(self): - contents = names(resources.files(import_module('namespacedata01'))) - try: - contents.remove('__pycache__') - except KeyError: - pass - self.assertEqual( - contents, {'subdirectory', 'binary.file', 'utf-8.file', 'utf-16.file'} - ) - - def test_submodule_contents_by_name(self): - contents = names(resources.files('namespacedata01')) - try: - contents.remove('__pycache__') - except KeyError: - pass - self.assertEqual( - contents, {'subdirectory', 'binary.file', 'utf-8.file', 'utf-16.file'} - ) - - def test_submodule_sub_contents(self): - contents = names(resources.files(import_module('namespacedata01.subdirectory'))) - try: - contents.remove('__pycache__') - except KeyError: - pass - self.assertEqual(contents, {'binary.file'}) - - def test_submodule_sub_contents_by_name(self): - contents = names(resources.files('namespacedata01.subdirectory')) - try: - contents.remove('__pycache__') - except KeyError: - pass - self.assertEqual(contents, {'binary.file'}) - - -class ResourceFromNamespaceDiskTests(ResourceFromNamespaceTests, unittest.TestCase): - site_dir = str(pathlib.Path(__file__).parent) - - @classmethod - def setUpClass(cls): - sys.path.append(cls.site_dir) - - @classmethod - def tearDownClass(cls): - sys.path.remove(cls.site_dir) - - -class ResourceFromNamespaceZipTests( - util.ZipSetupBase, - ResourceFromNamespaceTests, - unittest.TestCase, -): - ZIP_MODULE = 'namespacedata01' - - -if __name__ == '__main__': - unittest.main() diff --git a/setuptools/_vendor/importlib_resources/tests/util.py b/setuptools/_vendor/importlib_resources/tests/util.py deleted file mode 100644 index fb827d2fa0..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/util.py +++ /dev/null @@ -1,164 +0,0 @@ -import abc -import importlib -import io -import sys -import types -import pathlib -import contextlib - -from . import data01 -from ..abc import ResourceReader -from .compat.py39 import import_helper, os_helper -from . import zip as zip_ - - -from importlib.machinery import ModuleSpec - - -class Reader(ResourceReader): - def __init__(self, **kwargs): - vars(self).update(kwargs) - - def get_resource_reader(self, package): - return self - - def open_resource(self, path): - self._path = path - if isinstance(self.file, Exception): - raise self.file - return self.file - - def resource_path(self, path_): - self._path = path_ - if isinstance(self.path, Exception): - raise self.path - return self.path - - def is_resource(self, path_): - self._path = path_ - if isinstance(self.path, Exception): - raise self.path - - def part(entry): - return entry.split('/') - - return any( - len(parts) == 1 and parts[0] == path_ for parts in map(part, self._contents) - ) - - def contents(self): - if isinstance(self.path, Exception): - raise self.path - yield from self._contents - - -def create_package_from_loader(loader, is_package=True): - name = 'testingpackage' - module = types.ModuleType(name) - spec = ModuleSpec(name, loader, origin='does-not-exist', is_package=is_package) - module.__spec__ = spec - module.__loader__ = loader - return module - - -def create_package(file=None, path=None, is_package=True, contents=()): - return create_package_from_loader( - Reader(file=file, path=path, _contents=contents), - is_package, - ) - - -class CommonTests(metaclass=abc.ABCMeta): - """ - Tests shared by test_open, test_path, and test_read. - """ - - @abc.abstractmethod - def execute(self, package, path): - """ - Call the pertinent legacy API function (e.g. open_text, path) - on package and path. - """ - - def test_package_name(self): - """ - Passing in the package name should succeed. - """ - self.execute(data01.__name__, 'utf-8.file') - - def test_package_object(self): - """ - Passing in the package itself should succeed. - """ - self.execute(data01, 'utf-8.file') - - def test_string_path(self): - """ - Passing in a string for the path should succeed. - """ - path = 'utf-8.file' - self.execute(data01, path) - - def test_pathlib_path(self): - """ - Passing in a pathlib.PurePath object for the path should succeed. - """ - path = pathlib.PurePath('utf-8.file') - self.execute(data01, path) - - def test_importing_module_as_side_effect(self): - """ - The anchor package can already be imported. - """ - del sys.modules[data01.__name__] - self.execute(data01.__name__, 'utf-8.file') - - def test_missing_path(self): - """ - Attempting to open or read or request the path for a - non-existent path should succeed if open_resource - can return a viable data stream. - """ - bytes_data = io.BytesIO(b'Hello, world!') - package = create_package(file=bytes_data, path=FileNotFoundError()) - self.execute(package, 'utf-8.file') - self.assertEqual(package.__loader__._path, 'utf-8.file') - - def test_extant_path(self): - # Attempting to open or read or request the path when the - # path does exist should still succeed. Does not assert - # anything about the result. - bytes_data = io.BytesIO(b'Hello, world!') - # any path that exists - path = __file__ - package = create_package(file=bytes_data, path=path) - self.execute(package, 'utf-8.file') - self.assertEqual(package.__loader__._path, 'utf-8.file') - - def test_useless_loader(self): - package = create_package(file=FileNotFoundError(), path=FileNotFoundError()) - with self.assertRaises(FileNotFoundError): - self.execute(package, 'utf-8.file') - - -class ZipSetupBase: - ZIP_MODULE = 'data01' - - def setUp(self): - self.fixtures = contextlib.ExitStack() - self.addCleanup(self.fixtures.close) - - self.fixtures.enter_context(import_helper.isolated_modules()) - - temp_dir = self.fixtures.enter_context(os_helper.temp_dir()) - modules = pathlib.Path(temp_dir) / 'zipped modules.zip' - src_path = pathlib.Path(__file__).parent.joinpath(self.ZIP_MODULE) - self.fixtures.enter_context( - import_helper.DirsOnSysPath(str(zip_.make_zip_file(src_path, modules))) - ) - - self.data = importlib.import_module(self.ZIP_MODULE) - - -class ZipSetup(ZipSetupBase): - pass diff --git a/setuptools/_vendor/importlib_resources/tests/zip.py b/setuptools/_vendor/importlib_resources/tests/zip.py deleted file mode 100644 index 962195a901..0000000000 --- a/setuptools/_vendor/importlib_resources/tests/zip.py +++ /dev/null @@ -1,32 +0,0 @@ -""" -Generate zip test data files. -""" - -import contextlib -import os -import pathlib -import zipfile - -import zipp - - -def make_zip_file(src, dst): - """ - Zip the files in src into a new zipfile at dst. - """ - with zipfile.ZipFile(dst, 'w') as zf: - for src_path, rel in walk(src): - dst_name = src.name / pathlib.PurePosixPath(rel.as_posix()) - zf.write(src_path, dst_name) - zipp.CompleteDirs.inject(zf) - return dst - - -def walk(datapath): - for dirpath, dirnames, filenames in os.walk(datapath): - with contextlib.suppress(ValueError): - dirnames.remove('__pycache__') - for filename in filenames: - res = pathlib.Path(dirpath) / filename - rel = res.relative_to(datapath) - yield res, rel diff --git a/setuptools/command/bdist_wheel.py b/setuptools/command/bdist_wheel.py index 7e4e556cb0..8cf91538f9 100644 --- a/setuptools/command/bdist_wheel.py +++ b/setuptools/command/bdist_wheel.py @@ -111,19 +111,11 @@ def get_abi_tag() -> str | None: impl = tags.interpreter_name() if not soabi and impl in ("cp", "pp") and hasattr(sys, "maxunicode"): d = "" - m = "" u = "" if get_flag("Py_DEBUG", hasattr(sys, "gettotalrefcount"), warn=(impl == "cp")): d = "d" - if get_flag( - "WITH_PYMALLOC", - impl == "cp", - warn=(impl == "cp" and sys.version_info < (3, 8)), - ) and sys.version_info < (3, 8): - m = "m" - - abi = f"{impl}{tags.interpreter_version()}{d}{m}{u}" + abi = f"{impl}{tags.interpreter_version()}{d}{u}" elif soabi and impl == "cp" and soabi.startswith("cpython"): # non-Windows abi = "cp" + soabi.split("-")[1] diff --git a/tox.ini b/tox.ini index b767cd4fbc..12e156a3fa 100644 --- a/tox.ini +++ b/tox.ini @@ -54,8 +54,6 @@ extras = doc test changedir = docs -deps = - importlib_resources < 6 # twisted/towncrier#528 (waiting for release) commands = python -m sphinx -W --keep-going . {toxinidir}/build/html python -m sphinxlint @@ -67,7 +65,6 @@ deps = towncrier bump2version jaraco.develop >= 7.23 - importlib_resources < 6 # twisted/towncrier#528 (waiting for release) pass_env = * commands = python tools/finalize.py @@ -78,7 +75,7 @@ deps = path jaraco.packaging # workaround for pypa/pyproject-hooks#192 - pyproject-hooks<1.1 + pyproject-hooks!=1.1 uv commands = vendor: python -m tools.vendored