Skip to content

Bump importlib to 3.14 #14138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
May 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions stdlib/@tests/stubtest_allowlists/py314.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@ fractions.Fraction.__rpow__
gzip.GzipFile.readinto
gzip.GzipFile.readinto1
gzip.compress
importlib.abc.ResourceReader
importlib.abc.Traversable
importlib.abc.TraversableResources
importlib.machinery.__all__
importlib.machinery.AppleFrameworkLoader
importlib.util.__all__
importlib.util.Loader
multiprocessing.forkserver.main
multiprocessing.managers.BaseListProxy.clear
multiprocessing.managers.BaseListProxy.copy
Expand Down Expand Up @@ -93,6 +86,7 @@ typing.NewType.__mro_entries__

builtins.ellipsis # type is not exposed anywhere
importlib._abc.Loader.exec_module # See Lib/importlib/_abc.py. Might be defined for backwards compatibility
importlib.util.Loader.exec_module

# positional-only complaints caused by differences between typing aliases and the "real" classes in the stdlib
_collections_abc.Coroutine.send
Expand Down
8 changes: 6 additions & 2 deletions stdlib/@tests/test_cases/check_importlib.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import importlib.abc
import importlib.util
import pathlib
import sys
Expand All @@ -10,9 +9,14 @@
from types import ModuleType
from typing_extensions import Self

if sys.version_info >= (3, 11):
from importlib.resources.abc import Traversable
else:
from importlib.abc import Traversable


# Assert that some Path classes are Traversable.
def traverse(t: importlib.abc.Traversable) -> None:
def traverse(t: Traversable) -> None:
pass


Expand Down
110 changes: 59 additions & 51 deletions stdlib/importlib/abc.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -113,63 +113,71 @@ class FileLoader(_bootstrap_external.FileLoader, ResourceLoader, ExecutionLoader
def get_filename(self, name: str | None = None) -> str: ...
def load_module(self, name: str | None = None) -> types.ModuleType: ...

class ResourceReader(metaclass=ABCMeta):
@abstractmethod
def open_resource(self, resource: str) -> IO[bytes]: ...
@abstractmethod
def resource_path(self, resource: str) -> str: ...
if sys.version_info >= (3, 10):
if sys.version_info < (3, 11):
class ResourceReader(metaclass=ABCMeta):
@abstractmethod
def is_resource(self, path: str) -> bool: ...
else:
def open_resource(self, resource: str) -> IO[bytes]: ...
@abstractmethod
def is_resource(self, name: str) -> bool: ...
def resource_path(self, resource: str) -> str: ...
if sys.version_info >= (3, 10):
@abstractmethod
def is_resource(self, path: str) -> bool: ...
else:
@abstractmethod
def is_resource(self, name: str) -> bool: ...

@abstractmethod
def contents(self) -> Iterator[str]: ...
@abstractmethod
def contents(self) -> Iterator[str]: ...

@runtime_checkable
class Traversable(Protocol):
@abstractmethod
def is_dir(self) -> bool: ...
@abstractmethod
def is_file(self) -> bool: ...
@abstractmethod
def iterdir(self) -> Iterator[Traversable]: ...
if sys.version_info >= (3, 11):
@runtime_checkable
class Traversable(Protocol):
@abstractmethod
def joinpath(self, *descendants: str) -> Traversable: ...
else:
def is_dir(self) -> bool: ...
@abstractmethod
def joinpath(self, child: str, /) -> Traversable: ...

# The documentation and runtime protocol allows *args, **kwargs arguments,
# but this would mean that all implementers would have to support them,
# which is not the case.
@overload
@abstractmethod
def open(self, mode: Literal["r"] = "r", *, encoding: str | None = None, errors: str | None = None) -> IO[str]: ...
@overload
@abstractmethod
def open(self, mode: Literal["rb"]) -> IO[bytes]: ...
@property
@abstractmethod
def name(self) -> str: ...
if sys.version_info >= (3, 10):
def __truediv__(self, child: str, /) -> Traversable: ...
else:
def is_file(self) -> bool: ...
@abstractmethod
def iterdir(self) -> Iterator[Traversable]: ...
if sys.version_info >= (3, 11):
@abstractmethod
def joinpath(self, *descendants: str) -> Traversable: ...
else:
@abstractmethod
def joinpath(self, child: str, /) -> Traversable: ...

# The documentation and runtime protocol allows *args, **kwargs arguments,
# but this would mean that all implementers would have to support them,
# which is not the case.
@overload
@abstractmethod
def open(self, mode: Literal["r"] = "r", *, encoding: str | None = None, errors: str | None = None) -> IO[str]: ...
@overload
@abstractmethod
def __truediv__(self, child: str, /) -> Traversable: ...
def open(self, mode: Literal["rb"]) -> IO[bytes]: ...
@property
@abstractmethod
def name(self) -> str: ...
if sys.version_info >= (3, 10):
def __truediv__(self, child: str, /) -> Traversable: ...
else:
@abstractmethod
def __truediv__(self, child: str, /) -> Traversable: ...

@abstractmethod
def read_bytes(self) -> bytes: ...
@abstractmethod
def read_text(self, encoding: str | None = None) -> str: ...
@abstractmethod
def read_bytes(self) -> bytes: ...
@abstractmethod
def read_text(self, encoding: str | None = None) -> str: ...

class TraversableResources(ResourceReader):
@abstractmethod
def files(self) -> Traversable: ...
def open_resource(self, resource: str) -> BufferedReader: ...
def resource_path(self, resource: Any) -> str: ...
def is_resource(self, path: str) -> bool: ...
def contents(self) -> Iterator[str]: ...
class TraversableResources(ResourceReader):
@abstractmethod
def files(self) -> Traversable: ...
def open_resource(self, resource: str) -> BufferedReader: ...
def resource_path(self, resource: Any) -> str: ...
def is_resource(self, path: str) -> bool: ...
def contents(self) -> Iterator[str]: ...

elif sys.version_info < (3, 14):
from importlib.resources.abc import (
ResourceReader as ResourceReader,
Traversable as Traversable,
TraversableResources as TraversableResources,
)
23 changes: 23 additions & 0 deletions stdlib/importlib/machinery.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,28 @@ from importlib._bootstrap_external import (

if sys.version_info >= (3, 11):
from importlib._bootstrap_external import NamespaceLoader as NamespaceLoader
if sys.version_info >= (3, 14):
from importlib._bootstrap_external import AppleFrameworkLoader as AppleFrameworkLoader

def all_suffixes() -> list[str]: ...

if sys.version_info >= (3, 14):
__all__ = [
"AppleFrameworkLoader",
"BYTECODE_SUFFIXES",
"BuiltinImporter",
"DEBUG_BYTECODE_SUFFIXES",
"EXTENSION_SUFFIXES",
"ExtensionFileLoader",
"FileFinder",
"FrozenImporter",
"ModuleSpec",
"NamespaceLoader",
"OPTIMIZED_BYTECODE_SUFFIXES",
"PathFinder",
"SOURCE_SUFFIXES",
"SourceFileLoader",
"SourcelessFileLoader",
"WindowsRegistryFinder",
"all_suffixes",
]
10 changes: 8 additions & 2 deletions stdlib/importlib/resources/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import os
import sys
from collections.abc import Iterator
from contextlib import AbstractContextManager
from importlib.abc import Traversable
from pathlib import Path
from types import ModuleType
from typing import Any, BinaryIO, Literal, TextIO
from typing_extensions import TypeAlias

if sys.version_info >= (3, 11):
from importlib.resources.abc import Traversable
else:
from importlib.abc import Traversable

if sys.version_info >= (3, 11):
from importlib.resources._common import Package as Package
else:
Expand Down Expand Up @@ -72,5 +76,7 @@ if sys.version_info >= (3, 11):
else:
def files(package: Package) -> Traversable: ...

if sys.version_info >= (3, 10):
if sys.version_info >= (3, 11):
from importlib.resources.abc import ResourceReader as ResourceReader
elif sys.version_info >= (3, 10):
from importlib.abc import ResourceReader as ResourceReader
2 changes: 1 addition & 1 deletion stdlib/importlib/resources/_common.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if sys.version_info >= (3, 11):
import types
from collections.abc import Callable
from contextlib import AbstractContextManager
from importlib.abc import ResourceReader, Traversable
from importlib.resources.abc import ResourceReader, Traversable
from pathlib import Path
from typing import Literal, overload
from typing_extensions import TypeAlias, deprecated
Expand Down
73 changes: 64 additions & 9 deletions stdlib/importlib/resources/abc.pyi
Original file line number Diff line number Diff line change
@@ -1,14 +1,69 @@
import sys
from abc import ABCMeta, abstractmethod
from collections.abc import Iterator
from io import BufferedReader
from typing import IO, Any, Literal, Protocol, overload, runtime_checkable

if sys.version_info >= (3, 11):
# These are all actually defined in this file on 3.11+,
# and re-exported from importlib.abc,
# but it's much less code duplication for typeshed if we pretend that they're still defined
# in importlib.abc on 3.11+, and re-exported from this file
from importlib.abc import (
ResourceReader as ResourceReader,
Traversable as Traversable,
TraversableResources as TraversableResources,
)
class ResourceReader(metaclass=ABCMeta):
@abstractmethod
def open_resource(self, resource: str) -> IO[bytes]: ...
@abstractmethod
def resource_path(self, resource: str) -> str: ...
if sys.version_info >= (3, 10):
@abstractmethod
def is_resource(self, path: str) -> bool: ...
else:
@abstractmethod
def is_resource(self, name: str) -> bool: ...

@abstractmethod
def contents(self) -> Iterator[str]: ...

@runtime_checkable
class Traversable(Protocol):
@abstractmethod
def is_dir(self) -> bool: ...
@abstractmethod
def is_file(self) -> bool: ...
@abstractmethod
def iterdir(self) -> Iterator[Traversable]: ...
if sys.version_info >= (3, 11):
@abstractmethod
def joinpath(self, *descendants: str) -> Traversable: ...
else:
@abstractmethod
def joinpath(self, child: str, /) -> Traversable: ...

# The documentation and runtime protocol allows *args, **kwargs arguments,
# but this would mean that all implementers would have to support them,
# which is not the case.
@overload
@abstractmethod
def open(self, mode: Literal["r"] = "r", *, encoding: str | None = None, errors: str | None = None) -> IO[str]: ...
@overload
@abstractmethod
def open(self, mode: Literal["rb"]) -> IO[bytes]: ...
@property
@abstractmethod
def name(self) -> str: ...
if sys.version_info >= (3, 10):
def __truediv__(self, child: str, /) -> Traversable: ...
else:
@abstractmethod
def __truediv__(self, child: str, /) -> Traversable: ...

@abstractmethod
def read_bytes(self) -> bytes: ...
@abstractmethod
def read_text(self, encoding: str | None = None) -> str: ...

class TraversableResources(ResourceReader):
@abstractmethod
def files(self) -> Traversable: ...
def open_resource(self, resource: str) -> BufferedReader: ...
def resource_path(self, resource: Any) -> str: ...
def is_resource(self, path: str) -> bool: ...
def contents(self) -> Iterator[str]: ...

__all__ = ["ResourceReader", "Traversable", "TraversableResources"]
24 changes: 20 additions & 4 deletions stdlib/importlib/util.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import importlib.abc
import importlib.machinery
import sys
import types
Expand All @@ -12,6 +11,7 @@ from importlib._bootstrap_external import (
source_from_cache as source_from_cache,
spec_from_file_location as spec_from_file_location,
)
from importlib.abc import Loader
from typing_extensions import ParamSpec

_P = ParamSpec("_P")
Expand All @@ -24,10 +24,26 @@ if sys.version_info < (3, 12):
def resolve_name(name: str, package: str | None) -> str: ...
def find_spec(name: str, package: str | None = None) -> importlib.machinery.ModuleSpec | None: ...

class LazyLoader(importlib.abc.Loader):
def __init__(self, loader: importlib.abc.Loader) -> None: ...
class LazyLoader(Loader):
def __init__(self, loader: Loader) -> None: ...
@classmethod
def factory(cls, loader: importlib.abc.Loader) -> Callable[..., LazyLoader]: ...
def factory(cls, loader: Loader) -> Callable[..., LazyLoader]: ...
def exec_module(self, module: types.ModuleType) -> None: ...

def source_hash(source_bytes: ReadableBuffer) -> bytes: ...

if sys.version_info >= (3, 14):
__all__ = [
"LazyLoader",
"Loader",
"MAGIC_NUMBER",
"cache_from_source",
"decode_source",
"find_spec",
"module_from_spec",
"resolve_name",
"source_from_cache",
"source_hash",
"spec_from_file_location",
"spec_from_loader",
]
14 changes: 12 additions & 2 deletions stdlib/zipimport.pyi
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import sys
from _typeshed import StrOrBytesPath
from importlib.abc import ResourceReader
from importlib.machinery import ModuleSpec
from types import CodeType, ModuleType
from typing_extensions import deprecated

if sys.version_info >= (3, 10):
from importlib.readers import ZipReader
else:
from importlib.abc import ResourceReader

if sys.version_info >= (3, 10):
from _frozen_importlib_external import _LoaderBasics
else:
Expand All @@ -29,7 +33,13 @@ class zipimporter(_LoaderBasics):
def get_code(self, fullname: str) -> CodeType: ...
def get_data(self, pathname: str) -> bytes: ...
def get_filename(self, fullname: str) -> str: ...
def get_resource_reader(self, fullname: str) -> ResourceReader | None: ... # undocumented
if sys.version_info >= (3, 14):
def get_resource_reader(self, fullname: str) -> ZipReader: ... # undocumented
elif sys.version_info >= (3, 10):
def get_resource_reader(self, fullname: str) -> ZipReader | None: ... # undocumented
else:
def get_resource_reader(self, fullname: str) -> ResourceReader | None: ... # undocumented

def get_source(self, fullname: str) -> str | None: ...
def is_package(self, fullname: str) -> bool: ...
@deprecated("Deprecated since 3.10; use exec_module() instead")
Expand Down
Loading