Skip to content

Commit 85121de

Browse files
authored
Update importlib resources for 3.13 (#12298)
1 parent 9488989 commit 85121de

File tree

8 files changed

+153
-27
lines changed

8 files changed

+153
-27
lines changed

stdlib/@tests/stubtest_allowlists/py312.txt

+3
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ platform.uname_result.processor
164164
unittest.TestCase.__init_subclass__
165165
unittest.case.TestCase.__init_subclass__
166166

167+
# Deprecated argument is supported at runtime by renaming it through a decorator.
168+
importlib.resources._common.files
169+
importlib.resources.files
167170
# Problematic protocol signature at runtime, see source code comments.
168171
importlib.abc.Traversable.open
169172
importlib.resources.abc.Traversable.open

stdlib/@tests/stubtest_allowlists/py313.txt

+3-10
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@
44

55
# TODO: triage these new errors
66
_tkinter.create
7-
importlib.resources.Anchor
8-
importlib.resources.Resource
9-
importlib.resources.__all__
10-
importlib.resources.contents
11-
importlib.resources.is_resource
12-
importlib.resources.open_binary
13-
importlib.resources.open_text
14-
importlib.resources.path
15-
importlib.resources.read_binary
16-
importlib.resources.read_text
177
os.path.splitroot
188
tkinter.Misc.after_info
199
tkinter.Misc.busy
@@ -151,6 +141,9 @@ platform.uname_result.processor
151141
unittest.TestCase.__init_subclass__
152142
unittest.case.TestCase.__init_subclass__
153143

144+
# Deprecated argument is supported at runtime by renaming it through a decorator.
145+
importlib.resources._common.files
146+
importlib.resources.files
154147
# Problematic protocol signature at runtime, see source code comments.
155148
importlib.abc.Traversable.open
156149
importlib.resources.abc.Traversable.open
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from __future__ import annotations
2+
3+
import importlib.resources
4+
import pathlib
5+
import sys
6+
7+
8+
class _CustomPathLike:
9+
def __fspath__(self) -> str:
10+
return ""
11+
12+
13+
if sys.version_info >= (3, 13):
14+
15+
def f(pth: pathlib.Path | str | _CustomPathLike) -> None:
16+
importlib.resources.open_binary("pkg", pth)
17+
# Encoding defaults to "utf-8" for one arg.
18+
importlib.resources.open_text("pkg", pth)
19+
# Otherwise, it must be specified.
20+
importlib.resources.open_text("pkg", pth, pth) # type: ignore
21+
importlib.resources.open_text("pkg", pth, pth, encoding="utf-8")
22+
23+
# Encoding defaults to "utf-8" for one arg.
24+
importlib.resources.read_text("pkg", pth)
25+
# Otherwise, it must be specified.
26+
importlib.resources.read_text("pkg", pth, pth) # type: ignore
27+
importlib.resources.read_text("pkg", pth, pth, encoding="utf-8")
28+
29+
importlib.resources.read_binary("pkg", pth)
30+
importlib.resources.path("pkg", pth)
31+
importlib.resources.is_resource("pkg", pth)
32+
importlib.resources.contents("pkg", pth)

stdlib/VERSIONS

+2
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ importlib.metadata._meta: 3.10-
161161
importlib.metadata.diagnose: 3.13-
162162
importlib.readers: 3.10-
163163
importlib.resources: 3.7-
164+
importlib.resources._common: 3.11-
165+
importlib.resources._functional: 3.13-
164166
importlib.resources.abc: 3.11-
165167
importlib.resources.readers: 3.11-
166168
importlib.resources.simple: 3.11-

stdlib/importlib/abc.pyi

+2-2
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,10 @@ if sys.version_info >= (3, 9):
145145
# which is not the case.
146146
@overload
147147
@abstractmethod
148-
def open(self, mode: Literal["r"] = "r", /, *, encoding: str | None = None, errors: str | None = None) -> IO[str]: ...
148+
def open(self, mode: Literal["r"] = "r", *, encoding: str | None = None, errors: str | None = None) -> IO[str]: ...
149149
@overload
150150
@abstractmethod
151-
def open(self, mode: Literal["rb"], /) -> IO[bytes]: ...
151+
def open(self, mode: Literal["rb"]) -> IO[bytes]: ...
152152
@property
153153
@abstractmethod
154154
def name(self) -> str: ...

stdlib/importlib/resources/__init__.pyi

+39-15
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,61 @@ from types import ModuleType
77
from typing import Any, BinaryIO, TextIO
88
from typing_extensions import TypeAlias
99

10+
if sys.version_info >= (3, 11):
11+
from importlib.resources._common import Package as Package
12+
else:
13+
Package: TypeAlias = str | ModuleType
14+
1015
if sys.version_info >= (3, 9):
1116
from importlib.abc import Traversable
1217

13-
__all__ = ["Package", "Resource", "contents", "is_resource", "open_binary", "open_text", "path", "read_binary", "read_text"]
18+
__all__ = ["Package", "contents", "is_resource", "open_binary", "open_text", "path", "read_binary", "read_text"]
1419

1520
if sys.version_info >= (3, 9):
1621
__all__ += ["as_file", "files"]
1722

1823
if sys.version_info >= (3, 10):
1924
__all__ += ["ResourceReader"]
2025

21-
Package: TypeAlias = str | ModuleType
26+
if sys.version_info < (3, 13):
27+
__all__ += ["Resource"]
2228

23-
if sys.version_info >= (3, 11):
24-
Resource: TypeAlias = str
25-
else:
29+
if sys.version_info < (3, 11):
2630
Resource: TypeAlias = str | os.PathLike[Any]
31+
elif sys.version_info < (3, 13):
32+
Resource: TypeAlias = str
2733

28-
def open_binary(package: Package, resource: Resource) -> BinaryIO: ...
29-
def open_text(package: Package, resource: Resource, encoding: str = "utf-8", errors: str = "strict") -> TextIO: ...
30-
def read_binary(package: Package, resource: Resource) -> bytes: ...
31-
def read_text(package: Package, resource: Resource, encoding: str = "utf-8", errors: str = "strict") -> str: ...
32-
def path(package: Package, resource: Resource) -> AbstractContextManager[Path]: ...
33-
def is_resource(package: Package, name: str) -> bool: ...
34-
def contents(package: Package) -> Iterator[str]: ...
34+
if sys.version_info >= (3, 13):
35+
from importlib.resources._common import Anchor as Anchor
3536

36-
if sys.version_info >= (3, 9):
37+
__all__ += ["Anchor"]
38+
39+
from importlib.resources._functional import (
40+
contents as contents,
41+
is_resource as is_resource,
42+
open_binary as open_binary,
43+
open_text as open_text,
44+
path as path,
45+
read_binary as read_binary,
46+
read_text as read_text,
47+
)
48+
49+
else:
50+
def open_binary(package: Package, resource: Resource) -> BinaryIO: ...
51+
def open_text(package: Package, resource: Resource, encoding: str = "utf-8", errors: str = "strict") -> TextIO: ...
52+
def read_binary(package: Package, resource: Resource) -> bytes: ...
53+
def read_text(package: Package, resource: Resource, encoding: str = "utf-8", errors: str = "strict") -> str: ...
54+
def path(package: Package, resource: Resource) -> AbstractContextManager[Path]: ...
55+
def is_resource(package: Package, name: str) -> bool: ...
56+
def contents(package: Package) -> Iterator[str]: ...
57+
58+
if sys.version_info >= (3, 11):
59+
from importlib.resources._common import as_file as as_file
60+
elif sys.version_info >= (3, 9):
3761
def as_file(path: Traversable) -> AbstractContextManager[Path]: ...
3862

39-
if sys.version_info >= (3, 12):
40-
def files(anchor: Package | None = ...) -> Traversable: ...
63+
if sys.version_info >= (3, 11):
64+
from importlib.resources._common import files as files
4165

4266
elif sys.version_info >= (3, 9):
4367
def files(package: Package) -> Traversable: ...
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import sys
2+
3+
# Even though this file is 3.11+ only, Pyright will complain in stubtest for older versions.
4+
if sys.version_info >= (3, 11):
5+
import types
6+
from collections.abc import Callable
7+
from contextlib import AbstractContextManager
8+
from importlib.abc import ResourceReader, Traversable
9+
from pathlib import Path
10+
from typing import overload
11+
from typing_extensions import TypeAlias, deprecated
12+
13+
Package: TypeAlias = str | types.ModuleType
14+
15+
if sys.version_info >= (3, 12):
16+
Anchor: TypeAlias = Package
17+
18+
def package_to_anchor(
19+
func: Callable[[Anchor | None], Traversable]
20+
) -> Callable[[Anchor | None, Anchor | None], Traversable]: ...
21+
@overload
22+
def files(anchor: Anchor | None = None) -> Traversable: ...
23+
@overload
24+
@deprecated("First parameter to files is renamed to 'anchor'")
25+
def files(package: Anchor | None = None) -> Traversable: ...
26+
27+
else:
28+
def files(package: Package) -> Traversable: ...
29+
30+
def get_resource_reader(package: types.ModuleType) -> ResourceReader | None: ...
31+
32+
if sys.version_info >= (3, 12):
33+
def resolve(cand: Anchor | None) -> types.ModuleType: ...
34+
35+
else:
36+
def resolve(cand: Package) -> types.ModuleType: ...
37+
38+
if sys.version_info < (3, 12):
39+
def get_package(package: Package) -> types.ModuleType: ...
40+
41+
def from_package(package: types.ModuleType) -> Traversable: ...
42+
def as_file(path: Traversable) -> AbstractContextManager[Path]: ...
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import sys
2+
3+
# Even though this file is 3.13+ only, Pyright will complain in stubtest for older versions.
4+
if sys.version_info >= (3, 13):
5+
from _typeshed import StrPath
6+
from collections.abc import Iterator
7+
from contextlib import AbstractContextManager
8+
from importlib.resources._common import Anchor
9+
from io import TextIOWrapper
10+
from pathlib import Path
11+
from typing import BinaryIO, overload
12+
from typing_extensions import Unpack
13+
14+
def open_binary(anchor: Anchor, *path_names: StrPath) -> BinaryIO: ...
15+
@overload
16+
def open_text(
17+
anchor: Anchor, *path_names: Unpack[tuple[StrPath]], encoding: str | None = "utf-8", errors: str | None = "strict"
18+
) -> TextIOWrapper: ...
19+
@overload
20+
def open_text(anchor: Anchor, *path_names: StrPath, encoding: str | None, errors: str | None = "strict") -> TextIOWrapper: ...
21+
def read_binary(anchor: Anchor, *path_names: StrPath) -> bytes: ...
22+
@overload
23+
def read_text(
24+
anchor: Anchor, *path_names: Unpack[tuple[StrPath]], encoding: str | None = "utf-8", errors: str | None = "strict"
25+
) -> str: ...
26+
@overload
27+
def read_text(anchor: Anchor, *path_names: StrPath, encoding: str | None, errors: str | None = "strict") -> str: ...
28+
def path(anchor: Anchor, *path_names: StrPath) -> AbstractContextManager[Path]: ...
29+
def is_resource(anchor: Anchor, *path_names: StrPath) -> bool: ...
30+
def contents(anchor: Anchor, *path_names: StrPath) -> Iterator[str]: ...

0 commit comments

Comments
 (0)