From 800597a48bf1be21addec9cd0d323295265926e0 Mon Sep 17 00:00:00 2001 From: Sumit Date: Wed, 11 Nov 2026 20:08:55 +0530 Subject: [PATCH] [aiofiles] Narrow NamedTemporaryFile.name to str or bytes --- stubs/aiofiles/aiofiles/tempfile/__init__.pyi | 264 ++++++++++++++++-- stubs/aiofiles/aiofiles/threadpool/binary.pyi | 21 +- stubs/aiofiles/aiofiles/threadpool/text.pyi | 13 +- 3 files changed, 260 insertions(+), 38 deletions(-) diff --git a/stubs/aiofiles/aiofiles/tempfile/__init__.pyi b/stubs/aiofiles/aiofiles/tempfile/__init__.pyi index b9806ecd636e..131104560eeb 100644 --- a/stubs/aiofiles/aiofiles/tempfile/__init__.pyi +++ b/stubs/aiofiles/aiofiles/tempfile/__init__.pyi @@ -82,14 +82,42 @@ if sys.version_info >= (3, 12): buffering: int = -1, encoding: str | None = None, newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: StrPath | None = None, + delete: bool = True, + delete_on_close: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncTextIOWrapper[str]]: ... + @overload + def NamedTemporaryFile( + mode: OpenTextMode, + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: bytes | None = None, + prefix: bytes | None = None, + dir: BytesPath | None = None, + delete: bool = True, + delete_on_close: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncTextIOWrapper[bytes]]: ... + @overload + def NamedTemporaryFile( + mode: OpenTextMode, + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: str | bytes | None = None, + prefix: str | bytes | None = None, dir: StrOrBytesPath | None = None, delete: bool = True, delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncTextIOWrapper]: ... + ) -> AiofilesContextManager[AsyncTextIOWrapper[str | bytes]]: ... # Unbuffered binary: returns a FileIO @overload @@ -98,14 +126,42 @@ if sys.version_info >= (3, 12): buffering: Literal[0], encoding: None = None, newline: None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: StrPath | None = None, + delete: bool = True, + delete_on_close: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncFileIO[str]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryMode, + buffering: Literal[0], + encoding: None = None, + newline: None = None, + suffix: bytes | None = None, + prefix: bytes | None = None, + dir: BytesPath | None = None, + delete: bool = True, + delete_on_close: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncFileIO[bytes]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryMode, + buffering: Literal[0], + encoding: None = None, + newline: None = None, + suffix: str | bytes | None = None, + prefix: str | bytes | None = None, dir: StrOrBytesPath | None = None, delete: bool = True, delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncFileIO]: ... + ) -> AiofilesContextManager[AsyncFileIO[str | bytes]]: ... # Buffered binary reading/updating: AsyncBufferedReader @overload @@ -114,14 +170,42 @@ if sys.version_info >= (3, 12): buffering: Literal[-1, 1] = -1, encoding: None = None, newline: None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: StrPath | None = None, + delete: bool = True, + delete_on_close: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncBufferedReader[str]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryModeReading | OpenBinaryModeUpdating = "w+b", + buffering: Literal[-1, 1] = -1, + encoding: None = None, + newline: None = None, + suffix: bytes | None = None, + prefix: bytes | None = None, + dir: BytesPath | None = None, + delete: bool = True, + delete_on_close: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncBufferedReader[bytes]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryModeReading | OpenBinaryModeUpdating = "w+b", + buffering: Literal[-1, 1] = -1, + encoding: None = None, + newline: None = None, + suffix: str | bytes | None = None, + prefix: str | bytes | None = None, dir: StrOrBytesPath | None = None, delete: bool = True, delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncBufferedReader]: ... + ) -> AiofilesContextManager[AsyncBufferedReader[str | bytes]]: ... # Buffered binary writing: AsyncBufferedIOBase @overload @@ -130,14 +214,42 @@ if sys.version_info >= (3, 12): buffering: Literal[-1, 1] = -1, encoding: None = None, newline: None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: StrPath | None = None, + delete: bool = True, + delete_on_close: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncBufferedIOBase[str]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = -1, + encoding: None = None, + newline: None = None, + suffix: bytes | None = None, + prefix: bytes | None = None, + dir: BytesPath | None = None, + delete: bool = True, + delete_on_close: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncBufferedIOBase[bytes]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = -1, + encoding: None = None, + newline: None = None, + suffix: str | bytes | None = None, + prefix: str | bytes | None = None, dir: StrOrBytesPath | None = None, delete: bool = True, delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncBufferedIOBase]: ... + ) -> AiofilesContextManager[AsyncBufferedIOBase[str | bytes]]: ... else: # Text mode: always returns AsyncTextIOWrapper @overload @@ -146,13 +258,39 @@ else: buffering: int = -1, encoding: str | None = None, newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: StrPath | None = None, + delete: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncTextIOWrapper[str]]: ... + @overload + def NamedTemporaryFile( + mode: OpenTextMode, + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: bytes | None = None, + prefix: bytes | None = None, + dir: BytesPath | None = None, + delete: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncTextIOWrapper[bytes]]: ... + @overload + def NamedTemporaryFile( + mode: OpenTextMode, + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: str | bytes | None = None, + prefix: str | bytes | None = None, dir: StrOrBytesPath | None = None, delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncTextIOWrapper]: ... + ) -> AiofilesContextManager[AsyncTextIOWrapper[str | bytes]]: ... # Unbuffered binary: returns a FileIO @overload @@ -161,13 +299,39 @@ else: buffering: Literal[0], encoding: None = None, newline: None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: StrPath | None = None, + delete: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncFileIO[str]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryMode, + buffering: Literal[0], + encoding: None = None, + newline: None = None, + suffix: bytes | None = None, + prefix: bytes | None = None, + dir: BytesPath | None = None, + delete: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncFileIO[bytes]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryMode, + buffering: Literal[0], + encoding: None = None, + newline: None = None, + suffix: str | bytes | None = None, + prefix: str | bytes | None = None, dir: StrOrBytesPath | None = None, delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncFileIO]: ... + ) -> AiofilesContextManager[AsyncFileIO[str | bytes]]: ... # Buffered binary reading/updating: AsyncBufferedReader @overload @@ -176,13 +340,39 @@ else: buffering: Literal[-1, 1] = -1, encoding: None = None, newline: None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: StrPath | None = None, + delete: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncBufferedReader[str]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryModeReading | OpenBinaryModeUpdating = "w+b", + buffering: Literal[-1, 1] = -1, + encoding: None = None, + newline: None = None, + suffix: bytes | None = None, + prefix: bytes | None = None, + dir: BytesPath | None = None, + delete: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncBufferedReader[bytes]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryModeReading | OpenBinaryModeUpdating = "w+b", + buffering: Literal[-1, 1] = -1, + encoding: None = None, + newline: None = None, + suffix: str | bytes | None = None, + prefix: str | bytes | None = None, dir: StrOrBytesPath | None = None, delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncBufferedReader]: ... + ) -> AiofilesContextManager[AsyncBufferedReader[str | bytes]]: ... # Buffered binary writing: AsyncBufferedIOBase @overload @@ -191,13 +381,39 @@ else: buffering: Literal[-1, 1] = -1, encoding: None = None, newline: None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: StrPath | None = None, + delete: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncBufferedIOBase[str]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = -1, + encoding: None = None, + newline: None = None, + suffix: bytes | None = None, + prefix: bytes | None = None, + dir: BytesPath | None = None, + delete: bool = True, + loop: AbstractEventLoop | None = None, + executor: Executor | None = None, + ) -> AiofilesContextManager[AsyncBufferedIOBase[bytes]]: ... + @overload + def NamedTemporaryFile( + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = -1, + encoding: None = None, + newline: None = None, + suffix: str | bytes | None = None, + prefix: str | bytes | None = None, dir: StrOrBytesPath | None = None, delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncBufferedIOBase]: ... + ) -> AiofilesContextManager[AsyncBufferedIOBase[str | bytes]]: ... # Text mode: always returns AsyncTextIOWrapper @overload diff --git a/stubs/aiofiles/aiofiles/threadpool/binary.pyi b/stubs/aiofiles/aiofiles/threadpool/binary.pyi index 2a02d55752ec..8b7a7ec61d39 100644 --- a/stubs/aiofiles/aiofiles/threadpool/binary.pyi +++ b/stubs/aiofiles/aiofiles/threadpool/binary.pyi @@ -1,14 +1,17 @@ from _typeshed import FileDescriptorOrPath, ReadableBuffer, WriteableBuffer from collections.abc import Iterable from io import FileIO -from typing import type_check_only +from typing import Generic, type_check_only +from typing_extensions import TypeVar from ..base import AsyncBase, AsyncIndirectBase +_NameT_co = TypeVar("_NameT_co", bound=FileDescriptorOrPath, default=FileDescriptorOrPath, covariant=True) + # This class does not exist at runtime and instead these methods are # all dynamically patched in. @type_check_only -class _UnknownAsyncBinaryIO(AsyncBase[bytes]): +class _UnknownAsyncBinaryIO(AsyncBase[bytes], Generic[_NameT_co]): async def close(self) -> None: ... async def flush(self) -> None: ... async def isatty(self) -> bool: ... @@ -30,28 +33,28 @@ class _UnknownAsyncBinaryIO(AsyncBase[bytes]): @property def mode(self) -> str: ... @property - def name(self) -> FileDescriptorOrPath: ... + def name(self) -> _NameT_co: ... -class AsyncBufferedIOBase(_UnknownAsyncBinaryIO): +class AsyncBufferedIOBase(_UnknownAsyncBinaryIO[_NameT_co]): async def read1(self, size: int = ..., /) -> bytes: ... def detach(self) -> FileIO: ... @property def raw(self) -> FileIO: ... -class AsyncIndirectBufferedIOBase(AsyncIndirectBase[bytes], _UnknownAsyncBinaryIO): +class AsyncIndirectBufferedIOBase(AsyncIndirectBase[bytes], _UnknownAsyncBinaryIO[_NameT_co]): async def read1(self, size: int = ..., /) -> bytes: ... def detach(self) -> FileIO: ... @property def raw(self) -> FileIO: ... -class AsyncBufferedReader(AsyncBufferedIOBase): +class AsyncBufferedReader(AsyncBufferedIOBase[_NameT_co]): async def peek(self, size: int = ..., /) -> bytes: ... -class AsyncIndirectBufferedReader(AsyncIndirectBufferedIOBase): +class AsyncIndirectBufferedReader(AsyncIndirectBufferedIOBase[_NameT_co]): async def peek(self, size: int = ..., /) -> bytes: ... -class AsyncFileIO(_UnknownAsyncBinaryIO): +class AsyncFileIO(_UnknownAsyncBinaryIO[_NameT_co]): async def readall(self) -> bytes: ... -class AsyncIndirectFileIO(AsyncIndirectBase[bytes], _UnknownAsyncBinaryIO): +class AsyncIndirectFileIO(AsyncIndirectBase[bytes], _UnknownAsyncBinaryIO[_NameT_co]): async def readall(self) -> bytes: ... diff --git a/stubs/aiofiles/aiofiles/threadpool/text.pyi b/stubs/aiofiles/aiofiles/threadpool/text.pyi index 6c6bf20a408c..196828065156 100644 --- a/stubs/aiofiles/aiofiles/threadpool/text.pyi +++ b/stubs/aiofiles/aiofiles/threadpool/text.pyi @@ -1,11 +1,14 @@ from _typeshed import FileDescriptorOrPath from collections.abc import Iterable -from typing import BinaryIO, type_check_only +from typing import BinaryIO, Generic, type_check_only +from typing_extensions import TypeVar from ..base import AsyncBase, AsyncIndirectBase +_NameT_co = TypeVar("_NameT_co", bound=FileDescriptorOrPath, default=FileDescriptorOrPath, covariant=True) + @type_check_only -class _UnknownAsyncTextIO(AsyncBase[str]): +class _UnknownAsyncTextIO(AsyncBase[str], Generic[_NameT_co]): async def close(self) -> None: ... async def flush(self) -> None: ... async def isatty(self) -> bool: ... @@ -35,9 +38,9 @@ class _UnknownAsyncTextIO(AsyncBase[str]): @property def newlines(self) -> str | tuple[str, ...] | None: ... @property - def name(self) -> FileDescriptorOrPath: ... + def name(self) -> _NameT_co: ... @property def mode(self) -> str: ... -class AsyncTextIOWrapper(_UnknownAsyncTextIO): ... -class AsyncTextIndirectIOWrapper(AsyncIndirectBase[str], _UnknownAsyncTextIO): ... +class AsyncTextIOWrapper(_UnknownAsyncTextIO[_NameT_co]): ... +class AsyncTextIndirectIOWrapper(AsyncIndirectBase[str], _UnknownAsyncTextIO[_NameT_co]): ...