From f9e2085a54210222b9843b4ac9f87e9373932795 Mon Sep 17 00:00:00 2001 From: nightcityblade Date: Sat, 8 Aug 2026 23:13:19 +0800 Subject: [PATCH 1/2] [aiofiles] Fix NamedTemporaryFile name type --- .../@tests/test_cases/check_tempfile.py | 11 ++++++ stubs/aiofiles/aiofiles/tempfile/__init__.pyi | 38 ++++++++++++++----- 2 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 stubs/aiofiles/@tests/test_cases/check_tempfile.py diff --git a/stubs/aiofiles/@tests/test_cases/check_tempfile.py b/stubs/aiofiles/@tests/test_cases/check_tempfile.py new file mode 100644 index 000000000000..9803b162cabb --- /dev/null +++ b/stubs/aiofiles/@tests/test_cases/check_tempfile.py @@ -0,0 +1,11 @@ +from typing_extensions import assert_type + +from aiofiles.tempfile import NamedTemporaryFile + + +async def check_named_temporary_file() -> None: + async with NamedTemporaryFile() as file: + assert_type(file.name, str) + + async with NamedTemporaryFile(mode="w") as file: + assert_type(file.name, str) diff --git a/stubs/aiofiles/aiofiles/tempfile/__init__.pyi b/stubs/aiofiles/aiofiles/tempfile/__init__.pyi index b9806ecd636e..3bc5d3f0abe9 100644 --- a/stubs/aiofiles/aiofiles/tempfile/__init__.pyi +++ b/stubs/aiofiles/aiofiles/tempfile/__init__.pyi @@ -11,12 +11,32 @@ from _typeshed import ( ) from asyncio import AbstractEventLoop from concurrent.futures import Executor -from typing import AnyStr, Literal, overload +from typing import AnyStr, Literal, overload, type_check_only from ..base import AiofilesContextManager from ..threadpool.binary import AsyncBufferedIOBase, AsyncBufferedReader, AsyncFileIO from ..threadpool.text import AsyncTextIOWrapper +@type_check_only +class _NamedAsyncBufferedIOBase(AsyncBufferedIOBase): + @property + def name(self) -> str: ... + +@type_check_only +class _NamedAsyncBufferedReader(AsyncBufferedReader): + @property + def name(self) -> str: ... + +@type_check_only +class _NamedAsyncFileIO(AsyncFileIO): + @property + def name(self) -> str: ... + +@type_check_only +class _NamedAsyncTextIOWrapper(AsyncTextIOWrapper): + @property + def name(self) -> str: ... + # Text mode: always returns AsyncTextIOWrapper @overload def TemporaryFile( @@ -89,7 +109,7 @@ if sys.version_info >= (3, 12): delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncTextIOWrapper]: ... + ) -> AiofilesContextManager[_NamedAsyncTextIOWrapper]: ... # Unbuffered binary: returns a FileIO @overload @@ -105,7 +125,7 @@ if sys.version_info >= (3, 12): delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncFileIO]: ... + ) -> AiofilesContextManager[_NamedAsyncFileIO]: ... # Buffered binary reading/updating: AsyncBufferedReader @overload @@ -121,7 +141,7 @@ if sys.version_info >= (3, 12): delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncBufferedReader]: ... + ) -> AiofilesContextManager[_NamedAsyncBufferedReader]: ... # Buffered binary writing: AsyncBufferedIOBase @overload @@ -137,7 +157,7 @@ if sys.version_info >= (3, 12): delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncBufferedIOBase]: ... + ) -> AiofilesContextManager[_NamedAsyncBufferedIOBase]: ... else: # Text mode: always returns AsyncTextIOWrapper @overload @@ -152,7 +172,7 @@ else: delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncTextIOWrapper]: ... + ) -> AiofilesContextManager[_NamedAsyncTextIOWrapper]: ... # Unbuffered binary: returns a FileIO @overload @@ -167,7 +187,7 @@ else: delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncFileIO]: ... + ) -> AiofilesContextManager[_NamedAsyncFileIO]: ... # Buffered binary reading/updating: AsyncBufferedReader @overload @@ -182,7 +202,7 @@ else: delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncBufferedReader]: ... + ) -> AiofilesContextManager[_NamedAsyncBufferedReader]: ... # Buffered binary writing: AsyncBufferedIOBase @overload @@ -197,7 +217,7 @@ else: delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[AsyncBufferedIOBase]: ... + ) -> AiofilesContextManager[_NamedAsyncBufferedIOBase]: ... # Text mode: always returns AsyncTextIOWrapper @overload From a638ba671a551569f11387b22462d9799a5cc130 Mon Sep 17 00:00:00 2001 From: nightcityblade Date: Mon, 7 Sep 2026 11:05:17 +0800 Subject: [PATCH 2/2] [aiofiles] Preserve bytes NamedTemporaryFile names --- .../@tests/test_cases/check_tempfile.py | 11 ------ stubs/aiofiles/aiofiles/tempfile/__init__.pyi | 34 +++++++++---------- 2 files changed, 17 insertions(+), 28 deletions(-) delete mode 100644 stubs/aiofiles/@tests/test_cases/check_tempfile.py diff --git a/stubs/aiofiles/@tests/test_cases/check_tempfile.py b/stubs/aiofiles/@tests/test_cases/check_tempfile.py deleted file mode 100644 index 9803b162cabb..000000000000 --- a/stubs/aiofiles/@tests/test_cases/check_tempfile.py +++ /dev/null @@ -1,11 +0,0 @@ -from typing_extensions import assert_type - -from aiofiles.tempfile import NamedTemporaryFile - - -async def check_named_temporary_file() -> None: - async with NamedTemporaryFile() as file: - assert_type(file.name, str) - - async with NamedTemporaryFile(mode="w") as file: - assert_type(file.name, str) diff --git a/stubs/aiofiles/aiofiles/tempfile/__init__.pyi b/stubs/aiofiles/aiofiles/tempfile/__init__.pyi index 3bc5d3f0abe9..564af22a9655 100644 --- a/stubs/aiofiles/aiofiles/tempfile/__init__.pyi +++ b/stubs/aiofiles/aiofiles/tempfile/__init__.pyi @@ -11,31 +11,31 @@ from _typeshed import ( ) from asyncio import AbstractEventLoop from concurrent.futures import Executor -from typing import AnyStr, Literal, overload, type_check_only +from typing import AnyStr, Generic, Literal, overload, type_check_only from ..base import AiofilesContextManager from ..threadpool.binary import AsyncBufferedIOBase, AsyncBufferedReader, AsyncFileIO from ..threadpool.text import AsyncTextIOWrapper @type_check_only -class _NamedAsyncBufferedIOBase(AsyncBufferedIOBase): +class _NamedAsyncBufferedIOBase(AsyncBufferedIOBase, Generic[AnyStr]): @property - def name(self) -> str: ... + def name(self) -> AnyStr: ... @type_check_only -class _NamedAsyncBufferedReader(AsyncBufferedReader): +class _NamedAsyncBufferedReader(AsyncBufferedReader, Generic[AnyStr]): @property - def name(self) -> str: ... + def name(self) -> AnyStr: ... @type_check_only -class _NamedAsyncFileIO(AsyncFileIO): +class _NamedAsyncFileIO(AsyncFileIO, Generic[AnyStr]): @property - def name(self) -> str: ... + def name(self) -> AnyStr: ... @type_check_only -class _NamedAsyncTextIOWrapper(AsyncTextIOWrapper): +class _NamedAsyncTextIOWrapper(AsyncTextIOWrapper, Generic[AnyStr]): @property - def name(self) -> str: ... + def name(self) -> AnyStr: ... # Text mode: always returns AsyncTextIOWrapper @overload @@ -109,7 +109,7 @@ if sys.version_info >= (3, 12): delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[_NamedAsyncTextIOWrapper]: ... + ) -> AiofilesContextManager[_NamedAsyncTextIOWrapper[AnyStr]]: ... # Unbuffered binary: returns a FileIO @overload @@ -125,7 +125,7 @@ if sys.version_info >= (3, 12): delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[_NamedAsyncFileIO]: ... + ) -> AiofilesContextManager[_NamedAsyncFileIO[AnyStr]]: ... # Buffered binary reading/updating: AsyncBufferedReader @overload @@ -141,7 +141,7 @@ if sys.version_info >= (3, 12): delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[_NamedAsyncBufferedReader]: ... + ) -> AiofilesContextManager[_NamedAsyncBufferedReader[AnyStr]]: ... # Buffered binary writing: AsyncBufferedIOBase @overload @@ -157,7 +157,7 @@ if sys.version_info >= (3, 12): delete_on_close: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[_NamedAsyncBufferedIOBase]: ... + ) -> AiofilesContextManager[_NamedAsyncBufferedIOBase[AnyStr]]: ... else: # Text mode: always returns AsyncTextIOWrapper @overload @@ -172,7 +172,7 @@ else: delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[_NamedAsyncTextIOWrapper]: ... + ) -> AiofilesContextManager[_NamedAsyncTextIOWrapper[AnyStr]]: ... # Unbuffered binary: returns a FileIO @overload @@ -187,7 +187,7 @@ else: delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[_NamedAsyncFileIO]: ... + ) -> AiofilesContextManager[_NamedAsyncFileIO[AnyStr]]: ... # Buffered binary reading/updating: AsyncBufferedReader @overload @@ -202,7 +202,7 @@ else: delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[_NamedAsyncBufferedReader]: ... + ) -> AiofilesContextManager[_NamedAsyncBufferedReader[AnyStr]]: ... # Buffered binary writing: AsyncBufferedIOBase @overload @@ -217,7 +217,7 @@ else: delete: bool = True, loop: AbstractEventLoop | None = None, executor: Executor | None = None, - ) -> AiofilesContextManager[_NamedAsyncBufferedIOBase]: ... + ) -> AiofilesContextManager[_NamedAsyncBufferedIOBase[AnyStr]]: ... # Text mode: always returns AsyncTextIOWrapper @overload