From 1a6e38c0bfccd18a01deaca1491bcde3e778404c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 31 Aug 2024 05:50:38 -0400 Subject: [PATCH 01/22] Remove workaround for sphinx-contrib/sphinx-lint#83 --- tox.ini | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index 01f0975..1424305 100644 --- a/tox.ini +++ b/tox.ini @@ -31,9 +31,7 @@ extras = changedir = docs commands = python -m sphinx -W --keep-going . {toxinidir}/build/html - python -m sphinxlint \ - # workaround for sphinx-contrib/sphinx-lint#83 - --jobs 1 + python -m sphinxlint [testenv:finalize] description = assemble changelog and tag a release From a675458e1a7d6ae81d0d441338a74dc98ffc5a61 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 7 Sep 2024 10:16:01 -0400 Subject: [PATCH 02/22] Allow the workflow to be triggered manually. --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ac0ff69..441b93e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,6 +10,7 @@ on: # required if branches-ignore is supplied (jaraco/skeleton#103) - '**' pull_request: + workflow_dispatch: permissions: contents: read From 81b766c06cc83679c4a04c2bfa6d2c8cc559bf33 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 11 Sep 2024 18:14:38 -0400 Subject: [PATCH 03/22] Fix an incompatibility (and source of merge conflicts) with projects using Ruff/isort. Remove extra line after imports in conf.py (jaraco/skeleton#147) --- docs/conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index d5745d6..240329c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,5 @@ from __future__ import annotations - extensions = [ 'sphinx.ext.autodoc', 'jaraco.packaging.sphinx', From 3fe8c5ba792fd58a5a24eef4e8a845f3b5dd6c2c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 11 Sep 2024 18:14:58 -0400 Subject: [PATCH 04/22] Add Python 3.13 and 3.14 into the matrix. (jaraco/skeleton#146) --- .github/workflows/main.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 441b93e..251b9c1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,7 +36,7 @@ jobs: matrix: python: - "3.8" - - "3.12" + - "3.13" platform: - ubuntu-latest - macos-latest @@ -48,10 +48,14 @@ jobs: platform: ubuntu-latest - python: "3.11" platform: ubuntu-latest + - python: "3.12" + platform: ubuntu-latest + - python: "3.14" + platform: ubuntu-latest - python: pypy3.10 platform: ubuntu-latest runs-on: ${{ matrix.platform }} - continue-on-error: ${{ matrix.python == '3.13' }} + continue-on-error: ${{ matrix.python == '3.14' }} steps: - uses: actions/checkout@v4 - name: Setup Python From 8684c7a028b65381ec6c6724e2f9c9bea7df0aee Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 11 Sep 2024 22:27:33 -0400 Subject: [PATCH 05/22] Add workaround for broken importlib.resources when an editable sentinel is present. Closes #318 --- importlib_resources/future/adapters.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/importlib_resources/future/adapters.py b/importlib_resources/future/adapters.py index 0e9764b..5cf1755 100644 --- a/importlib_resources/future/adapters.py +++ b/importlib_resources/future/adapters.py @@ -23,6 +23,13 @@ def wrapper(*args, **kwargs): except NotADirectoryError: # MultiplexedPath may fail on zip subdirectory return + except ValueError as exc: + # NamespaceReader in stdlib may fail for editable installs + # (python/importlib_resources#311, python/importlib_resources#318) + # Remove after bugfix applied to Python 3.13. + if "not enough values to unpack" not in str(exc): + raise + return # Python 3.10+ mod_name = reader.__class__.__module__ if mod_name.startswith('importlib.') and mod_name.endswith('readers'): From c00a2b75d0604db2e159838761a79d93b658f1e2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 12 Sep 2024 05:00:20 -0400 Subject: [PATCH 06/22] Separate bpo from Python issue numbers. --- docs/conf.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index a8abd1d..570346b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -27,8 +27,12 @@ url='https://peps.python.org/pep-{pep_number:0>4}/', ), dict( - pattern=r'(python/cpython#|Python #|bpo-)(?P\d+)', - url='http://bugs.python.org/issue{python}', + pattern=r'(python/cpython#|Python #)(?P\d+)', + url='https://github.com/python/cpython/issues/{python}', + ), + dict( + pattern=r'bpo-(?P\d+)', + url='http://bugs.python.org/issue{bpo}', ), ], ), From 313bed20576c7ba6097ea00aa1c488602ee7e29d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 12 Sep 2024 10:14:46 -0400 Subject: [PATCH 07/22] gh-123994: Generate utf-16 file using little endian and BOM. (#123995) --- importlib_resources/tests/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/importlib_resources/tests/util.py b/importlib_resources/tests/util.py index a4eafac..5f75517 100644 --- a/importlib_resources/tests/util.py +++ b/importlib_resources/tests/util.py @@ -145,7 +145,7 @@ def test_useless_loader(self): data01={ '__init__.py': '', 'binary.file': bytes(range(4)), - 'utf-16.file': 'Hello, UTF-16 world!\n'.encode('utf-16'), + 'utf-16.file': '\ufeffHello, UTF-16 world!\n'.encode('utf-16-le'), 'utf-8.file': 'Hello, UTF-8 world!\n'.encode('utf-8'), 'subdirectory': { '__init__.py': '', @@ -160,7 +160,7 @@ def test_useless_loader(self): }, namespacedata01={ 'binary.file': bytes(range(4)), - 'utf-16.file': 'Hello, UTF-16 world!\n'.encode('utf-16'), + 'utf-16.file': '\ufeffHello, UTF-16 world!\n'.encode('utf-16-le'), 'utf-8.file': 'Hello, UTF-8 world!\n'.encode('utf-8'), 'subdirectory': { 'binary.file': bytes(range(12, 16)), From cc5d9cbb6e76cee1dc1c75401a1fa605de333016 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 18 Sep 2024 14:14:34 +0200 Subject: [PATCH 08/22] gh-123085: _compile_importlib: Avoid copying sources before compilation (GH-124131) Co-authored-by: Jason R. Coombs --- importlib_resources/tests/test_files.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/importlib_resources/tests/test_files.py b/importlib_resources/tests/test_files.py index f1fe233..bca626c 100644 --- a/importlib_resources/tests/test_files.py +++ b/importlib_resources/tests/test_files.py @@ -154,18 +154,17 @@ def test_implicit_files_submodule(self): def _compile_importlib(self): """ Make a compiled-only copy of the importlib resources package. + + Currently only code is copied, as importlib resources doesn't itself + have any resources. """ bin_site = self.fixtures.enter_context(os_helper.temp_dir()) c_resources = pathlib.Path(bin_site, 'c_resources') sources = pathlib.Path(resources.__file__).parent - shutil.copytree(sources, c_resources, ignore=lambda *_: ['__pycache__']) - - for dirpath, _, filenames in os.walk(c_resources): - for filename in filenames: - source_path = pathlib.Path(dirpath) / filename - cfile = source_path.with_suffix('.pyc') - py_compile.compile(source_path, cfile) - pathlib.Path.unlink(source_path) + + for source_path in sources.glob('**/*.py'): + c_path = c_resources.joinpath(source_path.relative_to(sources)).with_suffix('.pyc') + py_compile.compile(source_path, c_path) self.fixtures.enter_context(import_helper.DirsOnSysPath(bin_site)) def test_implicit_files_with_compiled_importlib(self): From 9d4af05bac271932e3d6ab9307383da34b575e07 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 18 Sep 2024 21:40:41 -0400 Subject: [PATCH 09/22] =?UTF-8?q?=F0=9F=91=B9=20Feed=20the=20hobgoblins=20?= =?UTF-8?q?(delint).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- importlib_resources/tests/test_files.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/importlib_resources/tests/test_files.py b/importlib_resources/tests/test_files.py index bca626c..f45a229 100644 --- a/importlib_resources/tests/test_files.py +++ b/importlib_resources/tests/test_files.py @@ -163,7 +163,9 @@ def _compile_importlib(self): sources = pathlib.Path(resources.__file__).parent for source_path in sources.glob('**/*.py'): - c_path = c_resources.joinpath(source_path.relative_to(sources)).with_suffix('.pyc') + c_path = c_resources.joinpath(source_path.relative_to(sources)).with_suffix( + '.pyc' + ) py_compile.compile(source_path, c_path) self.fixtures.enter_context(import_helper.DirsOnSysPath(bin_site)) From 62b6678a32087ed3bfc8ff19761764340295834e Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Sat, 26 Oct 2024 00:12:59 +0100 Subject: [PATCH 10/22] Bump pre-commit hook for ruff to avoid clashes with pytest-ruff (jaraco/skeleton#150) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8ec58e2..04870d1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.6 + rev: v0.7.1 hooks: - id: ruff args: [--fix, --unsafe-fixes] From db4dfc495552aca8d6f05ed58441fa65fdc2ed9c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 28 Oct 2024 09:11:52 -0700 Subject: [PATCH 11/22] Add Python 3.13 and 3.14 into the matrix. (jaraco/skeleton#151) From e61a9df7cdc9c8d1b56c30b7b3f94a7cdac14414 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 28 Oct 2024 12:19:31 -0400 Subject: [PATCH 12/22] Include pyproject.toml in ruff.toml. Closes jaraco/skeleton#119. Workaround for astral-sh/ruff#10299. --- ruff.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ruff.toml b/ruff.toml index 922aa1f..8b22940 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,3 +1,6 @@ +# include pyproject.toml for requires-python (workaround astral-sh/ruff#10299) +include = "pyproject.toml" + [lint] extend-select = [ "C901", From 750a1891ec4a1c0602050e3463e9593a8c13aa14 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 28 Oct 2024 12:22:50 -0400 Subject: [PATCH 13/22] Require Python 3.9 or later now that Python 3.8 is EOL. --- .github/workflows/main.yml | 4 +--- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 251b9c1..9c01fc4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,15 +35,13 @@ jobs: # https://blog.jaraco.com/efficient-use-of-ci-resources/ matrix: python: - - "3.8" + - "3.9" - "3.13" platform: - ubuntu-latest - macos-latest - windows-latest include: - - python: "3.9" - platform: ubuntu-latest - python: "3.10" platform: ubuntu-latest - python: "3.11" diff --git a/pyproject.toml b/pyproject.toml index 1d81b1c..328b98c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", ] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = [ ] dynamic = ["version"] From 5c34e69568f23a524af4fa9dad3f5e80f22ec3e6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 1 Nov 2024 22:35:31 -0400 Subject: [PATCH 14/22] Use extend for proper workaround. Closes jaraco/skeleton#152 Workaround for astral-sh/ruff#10299 --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index 8b22940..9379d6e 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,5 +1,5 @@ -# include pyproject.toml for requires-python (workaround astral-sh/ruff#10299) -include = "pyproject.toml" +# extend pyproject.toml for requires-python (workaround astral-sh/ruff#10299) +extend = "pyproject.toml" [lint] extend-select = [ From 4ed8bffcbc354ccfc67031b86d0848cb61712c11 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 23 Dec 2024 16:19:37 -0500 Subject: [PATCH 15/22] =?UTF-8?q?=F0=9F=91=B9=20Feed=20the=20hobgoblins=20?= =?UTF-8?q?(delint).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- importlib_resources/tests/test_functional.py | 22 +++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/importlib_resources/tests/test_functional.py b/importlib_resources/tests/test_functional.py index 1851edf..ffe12db 100644 --- a/importlib_resources/tests/test_functional.py +++ b/importlib_resources/tests/test_functional.py @@ -182,17 +182,23 @@ def test_contents(self): set(c), {'utf-8.file', 'utf-16.file', 'binary.file', 'subdirectory'}, ) - with self.assertRaises(OSError), warnings_helper.check_warnings(( - ".*contents.*", - DeprecationWarning, - )): + with ( + self.assertRaises(OSError), + warnings_helper.check_warnings(( + ".*contents.*", + DeprecationWarning, + )), + ): list(resources.contents(self.anchor01, 'utf-8.file')) for path_parts in self._gen_resourcetxt_path_parts(): - with self.assertRaises(OSError), warnings_helper.check_warnings(( - ".*contents.*", - DeprecationWarning, - )): + with ( + self.assertRaises(OSError), + warnings_helper.check_warnings(( + ".*contents.*", + DeprecationWarning, + )), + ): list(resources.contents(self.anchor01, *path_parts)) with warnings_helper.check_warnings((".*contents.*", DeprecationWarning)): c = resources.contents(self.anchor01, 'subdirectory') From ef8977791bf94b18aa71922d1d58f3ffc8acd161 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 3 Jan 2025 09:53:54 -0500 Subject: [PATCH 16/22] Remove unused imports. --- importlib_resources/tests/test_files.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/importlib_resources/tests/test_files.py b/importlib_resources/tests/test_files.py index f45a229..b762d4d 100644 --- a/importlib_resources/tests/test_files.py +++ b/importlib_resources/tests/test_files.py @@ -1,7 +1,5 @@ -import os import pathlib import py_compile -import shutil import textwrap import unittest import warnings From 39a607d25def76ef760334a494554847da8c8f0f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 3 Jan 2025 10:23:13 -0500 Subject: [PATCH 17/22] Bump badge for 2025. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index efabeee..4d3cabe 100644 --- a/README.rst +++ b/README.rst @@ -14,5 +14,5 @@ .. .. image:: https://readthedocs.org/projects/PROJECT_RTD/badge/?version=latest .. :target: https://PROJECT_RTD.readthedocs.io/en/latest/?badge=latest -.. image:: https://img.shields.io/badge/skeleton-2024-informational +.. image:: https://img.shields.io/badge/skeleton-2025-informational :target: https://blog.jaraco.com/skeleton From 2a95f57deb157f48d81e3e6b38345e5615e744ee Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 3 Jan 2025 10:23:36 -0500 Subject: [PATCH 18/22] Re-enable type checks. --- importlib_resources/tests/test_files.py | 2 +- pyproject.toml | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/importlib_resources/tests/test_files.py b/importlib_resources/tests/test_files.py index b762d4d..8d87a01 100644 --- a/importlib_resources/tests/test_files.py +++ b/importlib_resources/tests/test_files.py @@ -70,7 +70,7 @@ def test_non_paths_in_dunder_path(self): to cause the ``PathEntryFinder`` to be called when searching for packages. In that case, resources should still be loadable. """ - import namespacedata01 + import namespacedata01 # type: ignore[import-not-found] namespacedata01.__path__.append( '__editable__.sample_namespace-1.0.finder.__path_hook__' diff --git a/pyproject.toml b/pyproject.toml index d08547f..608e751 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,3 @@ type = [ [tool.setuptools_scm] - - -[tool.pytest-enabler.mypy] -# Disabled due to jaraco/skeleton#143 From 2917dc4a76219e3d0b13a9e5f85fd7079062c824 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 3 Jan 2025 10:32:51 -0500 Subject: [PATCH 19/22] Apply import sort fixers from ruff. --- importlib_resources/__init__.py | 7 ++----- importlib_resources/_common.py | 12 ++++++------ importlib_resources/_functional.py | 3 +-- importlib_resources/abc.py | 14 +++++++++++--- importlib_resources/compat/py38.py | 2 -- importlib_resources/compat/py39.py | 1 - importlib_resources/future/adapters.py | 2 +- importlib_resources/readers.py | 3 +-- importlib_resources/tests/_path.py | 8 ++------ .../tests/test_compatibilty_files.py | 1 - importlib_resources/tests/test_contents.py | 1 + importlib_resources/tests/test_custom.py | 5 +++-- importlib_resources/tests/test_files.py | 7 ++++--- importlib_resources/tests/test_functional.py | 7 +++---- importlib_resources/tests/test_open.py | 1 + importlib_resources/tests/test_path.py | 1 + importlib_resources/tests/test_read.py | 3 ++- importlib_resources/tests/test_reader.py | 2 +- importlib_resources/tests/test_resource.py | 3 ++- importlib_resources/tests/util.py | 12 +++++------- 20 files changed, 47 insertions(+), 48 deletions(-) diff --git a/importlib_resources/__init__.py b/importlib_resources/__init__.py index 723c9f9..27d6c7f 100644 --- a/importlib_resources/__init__.py +++ b/importlib_resources/__init__.py @@ -8,12 +8,11 @@ """ from ._common import ( + Anchor, + Package, as_file, files, - Package, - Anchor, ) - from ._functional import ( contents, is_resource, @@ -23,10 +22,8 @@ read_binary, read_text, ) - from .abc import ResourceReader - __all__ = [ 'Package', 'Anchor', diff --git a/importlib_resources/_common.py b/importlib_resources/_common.py index f065d49..5f41c26 100644 --- a/importlib_resources/_common.py +++ b/importlib_resources/_common.py @@ -1,15 +1,15 @@ +import contextlib +import functools +import importlib +import inspect +import itertools import os import pathlib import tempfile -import functools -import contextlib import types -import importlib -import inspect import warnings -import itertools +from typing import Optional, Union, cast -from typing import Union, Optional, cast from .abc import ResourceReader, Traversable Package = Union[types.ModuleType, str] diff --git a/importlib_resources/_functional.py b/importlib_resources/_functional.py index f59416f..5a3ca0a 100644 --- a/importlib_resources/_functional.py +++ b/importlib_resources/_functional.py @@ -2,8 +2,7 @@ import warnings -from ._common import files, as_file - +from ._common import as_file, files _MISSING = object() diff --git a/importlib_resources/abc.py b/importlib_resources/abc.py index 7a58dd2..c0a4cb9 100644 --- a/importlib_resources/abc.py +++ b/importlib_resources/abc.py @@ -2,12 +2,20 @@ import io import itertools import pathlib -from typing import Any, BinaryIO, Iterable, Iterator, NoReturn, Text, Optional -from typing import runtime_checkable, Protocol +from typing import ( + Any, + BinaryIO, + Iterable, + Iterator, + NoReturn, + Optional, + Protocol, + Text, + runtime_checkable, +) from .compat.py38 import StrPath - __all__ = ["ResourceReader", "Traversable", "TraversableResources"] diff --git a/importlib_resources/compat/py38.py b/importlib_resources/compat/py38.py index 4d54825..80940e9 100644 --- a/importlib_resources/compat/py38.py +++ b/importlib_resources/compat/py38.py @@ -1,9 +1,7 @@ import os import sys - from typing import Union - if sys.version_info >= (3, 9): StrPath = Union[str, os.PathLike[str]] else: diff --git a/importlib_resources/compat/py39.py b/importlib_resources/compat/py39.py index ed5abd5..684d3c6 100644 --- a/importlib_resources/compat/py39.py +++ b/importlib_resources/compat/py39.py @@ -1,6 +1,5 @@ import sys - __all__ = ['ZipPath'] diff --git a/importlib_resources/future/adapters.py b/importlib_resources/future/adapters.py index 5cf1755..239e52b 100644 --- a/importlib_resources/future/adapters.py +++ b/importlib_resources/future/adapters.py @@ -3,7 +3,7 @@ from contextlib import suppress from types import SimpleNamespace -from .. import readers, _adapters +from .. import _adapters, readers def _block_standard(reader_getter): diff --git a/importlib_resources/readers.py b/importlib_resources/readers.py index 4f761c6..99884b6 100644 --- a/importlib_resources/readers.py +++ b/importlib_resources/readers.py @@ -3,14 +3,13 @@ import collections import contextlib import itertools -import pathlib import operator +import pathlib import re import warnings from collections.abc import Iterator from . import abc - from ._itertools import only from .compat.py39 import ZipPath diff --git a/importlib_resources/tests/_path.py b/importlib_resources/tests/_path.py index b144628..0033983 100644 --- a/importlib_resources/tests/_path.py +++ b/importlib_resources/tests/_path.py @@ -1,10 +1,6 @@ -import pathlib import functools - -from typing import Dict, Union -from typing import runtime_checkable -from typing import Protocol - +import pathlib +from typing import Dict, Protocol, Union, runtime_checkable #### # from jaraco.path 3.7.1 diff --git a/importlib_resources/tests/test_compatibilty_files.py b/importlib_resources/tests/test_compatibilty_files.py index 13ad0df..e8aac28 100644 --- a/importlib_resources/tests/test_compatibilty_files.py +++ b/importlib_resources/tests/test_compatibilty_files.py @@ -2,7 +2,6 @@ import unittest import importlib_resources as resources - from importlib_resources._adapters import ( CompatibilityFiles, wrap_spec, diff --git a/importlib_resources/tests/test_contents.py b/importlib_resources/tests/test_contents.py index 741a740..dcb872e 100644 --- a/importlib_resources/tests/test_contents.py +++ b/importlib_resources/tests/test_contents.py @@ -1,4 +1,5 @@ import unittest + import importlib_resources as resources from . import util diff --git a/importlib_resources/tests/test_custom.py b/importlib_resources/tests/test_custom.py index 86c6567..25ae0e7 100644 --- a/importlib_resources/tests/test_custom.py +++ b/importlib_resources/tests/test_custom.py @@ -1,10 +1,11 @@ -import unittest import contextlib import pathlib +import unittest import importlib_resources as resources + from .. import abc -from ..abc import TraversableResources, ResourceReader +from ..abc import ResourceReader, TraversableResources from . import util from .compat.py39 import os_helper diff --git a/importlib_resources/tests/test_files.py b/importlib_resources/tests/test_files.py index 8d87a01..be20660 100644 --- a/importlib_resources/tests/test_files.py +++ b/importlib_resources/tests/test_files.py @@ -1,15 +1,16 @@ +import contextlib +import importlib import pathlib import py_compile import textwrap import unittest import warnings -import importlib -import contextlib import importlib_resources as resources + from ..abc import Traversable from . import util -from .compat.py39 import os_helper, import_helper +from .compat.py39 import import_helper, os_helper @contextlib.contextmanager diff --git a/importlib_resources/tests/test_functional.py b/importlib_resources/tests/test_functional.py index ffe12db..2285389 100644 --- a/importlib_resources/tests/test_functional.py +++ b/importlib_resources/tests/test_functional.py @@ -1,12 +1,11 @@ -import unittest -import os import importlib - -from .compat.py39 import warnings_helper +import os +import unittest import importlib_resources as resources from . import util +from .compat.py39 import warnings_helper # Since the functional API forwards to Traversable, we only test # filesystem resources here -- not zip files, namespace packages etc. diff --git a/importlib_resources/tests/test_open.py b/importlib_resources/tests/test_open.py index c40bb8c..8a4b68e 100644 --- a/importlib_resources/tests/test_open.py +++ b/importlib_resources/tests/test_open.py @@ -1,6 +1,7 @@ import unittest import importlib_resources as resources + from . import util diff --git a/importlib_resources/tests/test_path.py b/importlib_resources/tests/test_path.py index 1e30f2b..0be673d 100644 --- a/importlib_resources/tests/test_path.py +++ b/importlib_resources/tests/test_path.py @@ -3,6 +3,7 @@ import unittest import importlib_resources as resources + from . import util diff --git a/importlib_resources/tests/test_read.py b/importlib_resources/tests/test_read.py index 6780a2d..216c8fe 100644 --- a/importlib_resources/tests/test_read.py +++ b/importlib_resources/tests/test_read.py @@ -1,8 +1,9 @@ import unittest +from importlib import import_module + import importlib_resources as resources from . import util -from importlib import import_module class CommonBinaryTests(util.CommonTests, unittest.TestCase): diff --git a/importlib_resources/tests/test_reader.py b/importlib_resources/tests/test_reader.py index 0a77eb4..f8cfd8d 100644 --- a/importlib_resources/tests/test_reader.py +++ b/importlib_resources/tests/test_reader.py @@ -1,8 +1,8 @@ import os.path import pathlib import unittest - from importlib import import_module + from importlib_resources.readers import MultiplexedPath, NamespaceReader from . import util diff --git a/importlib_resources/tests/test_resource.py b/importlib_resources/tests/test_resource.py index a0da6a3..c80afdc 100644 --- a/importlib_resources/tests/test_resource.py +++ b/importlib_resources/tests/test_resource.py @@ -1,8 +1,9 @@ import unittest +from importlib import import_module + import importlib_resources as resources from . import util -from importlib import import_module class ResourceTests: diff --git a/importlib_resources/tests/util.py b/importlib_resources/tests/util.py index 5f75517..07d1529 100644 --- a/importlib_resources/tests/util.py +++ b/importlib_resources/tests/util.py @@ -1,18 +1,16 @@ import abc +import contextlib import importlib import io +import pathlib import sys import types -import pathlib -import contextlib +from importlib.machinery import ModuleSpec from ..abc import ResourceReader -from .compat.py39 import import_helper, os_helper -from . import zip as zip_ from . import _path - - -from importlib.machinery import ModuleSpec +from . import zip as zip_ +from .compat.py39 import import_helper, os_helper class Reader(ResourceReader): From 8e9503d90943335369219ba3bc088d2bcd4bca7f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 3 Jan 2025 09:54:39 -0500 Subject: [PATCH 20/22] Add type annotations for Traversable.open. Closes #317. --- importlib_resources/abc.py | 18 +++++++++++++++--- newsfragments/317.feature.rst | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 newsfragments/317.feature.rst diff --git a/importlib_resources/abc.py b/importlib_resources/abc.py index c0a4cb9..39b0d37 100644 --- a/importlib_resources/abc.py +++ b/importlib_resources/abc.py @@ -1,5 +1,4 @@ import abc -import io import itertools import pathlib from typing import ( @@ -11,9 +10,14 @@ Optional, Protocol, Text, + TextIO, + Union, + overload, runtime_checkable, ) +from typing_extensions import Literal + from .compat.py38 import StrPath __all__ = ["ResourceReader", "Traversable", "TraversableResources"] @@ -138,8 +142,16 @@ def __truediv__(self, child: StrPath) -> "Traversable": """ return self.joinpath(child) + @overload + def open(self, mode: Literal['r'] = 'r', *args: Any, **kwargs: Any) -> TextIO: ... + + @overload + def open(self, mode: Literal['rb'], *args: Any, **kwargs: Any) -> BinaryIO: ... + @abc.abstractmethod - def open(self, mode='r', *args, **kwargs): + def open( + self, mode: str = 'r', *args: Any, **kwargs: Any + ) -> Union[TextIO, BinaryIO]: """ mode may be 'r' or 'rb' to open as text or binary. Return a handle suitable for reading (same as pathlib.Path.open). @@ -166,7 +178,7 @@ class TraversableResources(ResourceReader): def files(self) -> "Traversable": """Return a Traversable object for the loaded package.""" - def open_resource(self, resource: StrPath) -> io.BufferedReader: + def open_resource(self, resource: StrPath) -> BinaryIO: return self.files().joinpath(resource).open('rb') def resource_path(self, resource: Any) -> NoReturn: diff --git a/newsfragments/317.feature.rst b/newsfragments/317.feature.rst new file mode 100644 index 0000000..25b1a97 --- /dev/null +++ b/newsfragments/317.feature.rst @@ -0,0 +1 @@ +Add type annotations for Traversable.open. From 355a10db1644edcd92f876bd9aec4dd3839f7e75 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 3 Jan 2025 10:37:31 -0500 Subject: [PATCH 21/22] Remove Python 3.8 compatibility code. --- importlib_resources/abc.py | 3 ++- importlib_resources/compat/py38.py | 9 --------- newsfragments/+3f742cf7.feature.rst | 1 + 3 files changed, 3 insertions(+), 10 deletions(-) delete mode 100644 importlib_resources/compat/py38.py create mode 100644 newsfragments/+3f742cf7.feature.rst diff --git a/importlib_resources/abc.py b/importlib_resources/abc.py index 39b0d37..84631c7 100644 --- a/importlib_resources/abc.py +++ b/importlib_resources/abc.py @@ -1,5 +1,6 @@ import abc import itertools +import os import pathlib from typing import ( Any, @@ -18,7 +19,7 @@ from typing_extensions import Literal -from .compat.py38 import StrPath +StrPath = Union[str, os.PathLike[str]] __all__ = ["ResourceReader", "Traversable", "TraversableResources"] diff --git a/importlib_resources/compat/py38.py b/importlib_resources/compat/py38.py deleted file mode 100644 index 80940e9..0000000 --- a/importlib_resources/compat/py38.py +++ /dev/null @@ -1,9 +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/newsfragments/+3f742cf7.feature.rst b/newsfragments/+3f742cf7.feature.rst new file mode 100644 index 0000000..f171cdd --- /dev/null +++ b/newsfragments/+3f742cf7.feature.rst @@ -0,0 +1 @@ +Require Python 3.9 or later. From fa27acb836d98ffa87794de37d33b7188aad082f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 3 Jan 2025 10:38:40 -0500 Subject: [PATCH 22/22] Finalize --- NEWS.rst | 10 ++++++++++ newsfragments/+3f742cf7.feature.rst | 1 - newsfragments/317.feature.rst | 1 - 3 files changed, 10 insertions(+), 2 deletions(-) delete mode 100644 newsfragments/+3f742cf7.feature.rst delete mode 100644 newsfragments/317.feature.rst diff --git a/NEWS.rst b/NEWS.rst index 36aac37..c3612c1 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -1,3 +1,13 @@ +v6.5.0 +====== + +Features +-------- + +- Add type annotations for Traversable.open. (#317) +- Require Python 3.9 or later. + + v6.4.5 ====== diff --git a/newsfragments/+3f742cf7.feature.rst b/newsfragments/+3f742cf7.feature.rst deleted file mode 100644 index f171cdd..0000000 --- a/newsfragments/+3f742cf7.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Require Python 3.9 or later. diff --git a/newsfragments/317.feature.rst b/newsfragments/317.feature.rst deleted file mode 100644 index 25b1a97..0000000 --- a/newsfragments/317.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Add type annotations for Traversable.open.