diff --git a/mypy/typeshed/stdlib/_ctypes.pyi b/mypy/typeshed/stdlib/_ctypes.pyi index 756ee86d3342..165bb5337784 100644 --- a/mypy/typeshed/stdlib/_ctypes.pyi +++ b/mypy/typeshed/stdlib/_ctypes.pyi @@ -69,7 +69,7 @@ class _CData(metaclass=_CDataMeta): def __buffer__(self, __flags: int) -> memoryview: ... def __release_buffer__(self, __buffer: memoryview) -> None: ... -class _SimpleCData(Generic[_T], _CData): +class _SimpleCData(_CData, Generic[_T]): value: _T # The TypeVar can be unsolved here, # but we can't use overloads without creating many, many mypy false-positive errors @@ -78,7 +78,7 @@ class _SimpleCData(Generic[_T], _CData): class _CanCastTo(_CData): ... class _PointerLike(_CanCastTo): ... -class _Pointer(Generic[_CT], _PointerLike, _CData): +class _Pointer(_PointerLike, _CData, Generic[_CT]): _type_: type[_CT] contents: _CT @overload @@ -140,7 +140,7 @@ class _StructUnionBase(_CData, metaclass=_StructUnionMeta): class Union(_StructUnionBase): ... class Structure(_StructUnionBase): ... -class Array(Generic[_CT], _CData): +class Array(_CData, Generic[_CT]): @property @abstractmethod def _length_(self) -> int: ... diff --git a/mypy/typeshed/stdlib/asyncio/taskgroups.pyi b/mypy/typeshed/stdlib/asyncio/taskgroups.pyi index 47d9bb2f699e..aec3f1127f15 100644 --- a/mypy/typeshed/stdlib/asyncio/taskgroups.pyi +++ b/mypy/typeshed/stdlib/asyncio/taskgroups.pyi @@ -1,10 +1,11 @@ import sys from contextvars import Context from types import TracebackType -from typing import TypeVar +from typing import Any, TypeVar from typing_extensions import Self from . import _CoroutineLike +from .events import AbstractEventLoop from .tasks import Task if sys.version_info >= (3, 12): @@ -15,6 +16,10 @@ else: _T = TypeVar("_T") class TaskGroup: + _loop: AbstractEventLoop | None + _tasks: set[Task[Any]] + async def __aenter__(self) -> Self: ... async def __aexit__(self, et: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None) -> None: ... def create_task(self, coro: _CoroutineLike[_T], *, name: str | None = None, context: Context | None = None) -> Task[_T]: ... + def _on_task_done(self, task: Task[object]) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/tasks.pyi b/mypy/typeshed/stdlib/asyncio/tasks.pyi index 5ea30d3791de..3bc65e3703c5 100644 --- a/mypy/typeshed/stdlib/asyncio/tasks.pyi +++ b/mypy/typeshed/stdlib/asyncio/tasks.pyi @@ -243,12 +243,6 @@ if sys.version_info >= (3, 10): async def sleep(delay: float) -> None: ... @overload async def sleep(delay: float, result: _T) -> _T: ... - @overload - async def wait(fs: Iterable[_FT], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED") -> tuple[set[_FT], set[_FT]]: ... # type: ignore[misc] - @overload - async def wait( - fs: Iterable[Awaitable[_T]], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED" - ) -> tuple[set[Task[_T]], set[Task[_T]]]: ... async def wait_for(fut: _FutureLike[_T], timeout: float | None) -> _T: ... else: @@ -257,6 +251,25 @@ else: async def sleep(delay: float, *, loop: AbstractEventLoop | None = None) -> None: ... @overload async def sleep(delay: float, result: _T, *, loop: AbstractEventLoop | None = None) -> _T: ... + async def wait_for(fut: _FutureLike[_T], timeout: float | None, *, loop: AbstractEventLoop | None = None) -> _T: ... + +if sys.version_info >= (3, 11): + @overload + async def wait(fs: Iterable[_FT], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED") -> tuple[set[_FT], set[_FT]]: ... # type: ignore[misc] + @overload + async def wait( + fs: Iterable[Task[_T]], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED" + ) -> tuple[set[Task[_T]], set[Task[_T]]]: ... + +elif sys.version_info >= (3, 10): + @overload + async def wait(fs: Iterable[_FT], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED") -> tuple[set[_FT], set[_FT]]: ... # type: ignore[misc] + @overload + async def wait( + fs: Iterable[Awaitable[_T]], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED" + ) -> tuple[set[Task[_T]], set[Task[_T]]]: ... + +else: @overload async def wait( # type: ignore[misc] fs: Iterable[_FT], @@ -273,7 +286,6 @@ else: timeout: float | None = None, return_when: str = "ALL_COMPLETED", ) -> tuple[set[Task[_T]], set[Task[_T]]]: ... - async def wait_for(fut: _FutureLike[_T], timeout: float | None, *, loop: AbstractEventLoop | None = None) -> _T: ... if sys.version_info >= (3, 12): _TaskCompatibleCoro: TypeAlias = Coroutine[Any, Any, _T_co] @@ -291,7 +303,7 @@ class Task(Future[_T_co], Generic[_T_co]): # type: ignore[type-var] # pyright: coro: _TaskCompatibleCoro[_T_co], *, loop: AbstractEventLoop = ..., - name: str | None, + name: str | None = ..., context: Context | None = None, eager_start: bool = False, ) -> None: ... @@ -301,7 +313,7 @@ class Task(Future[_T_co], Generic[_T_co]): # type: ignore[type-var] # pyright: coro: _TaskCompatibleCoro[_T_co], *, loop: AbstractEventLoop = ..., - name: str | None, + name: str | None = ..., context: Context | None = None, ) -> None: ... elif sys.version_info >= (3, 8): diff --git a/mypy/typeshed/stdlib/configparser.pyi b/mypy/typeshed/stdlib/configparser.pyi index 6f9f788310d1..e6fedb0328c2 100644 --- a/mypy/typeshed/stdlib/configparser.pyi +++ b/mypy/typeshed/stdlib/configparser.pyi @@ -5,31 +5,53 @@ from re import Pattern from typing import Any, ClassVar, TypeVar, overload from typing_extensions import Literal, TypeAlias -__all__ = [ - "NoSectionError", - "DuplicateOptionError", - "DuplicateSectionError", - "NoOptionError", - "InterpolationError", - "InterpolationDepthError", - "InterpolationMissingOptionError", - "InterpolationSyntaxError", - "ParsingError", - "MissingSectionHeaderError", - "ConfigParser", - "RawConfigParser", - "Interpolation", - "BasicInterpolation", - "ExtendedInterpolation", - "LegacyInterpolation", - "SectionProxy", - "ConverterMapping", - "DEFAULTSECT", - "MAX_INTERPOLATION_DEPTH", -] - -if sys.version_info < (3, 12): - __all__ += ["SafeConfigParser"] +if sys.version_info >= (3, 12): + __all__ = ( + "NoSectionError", + "DuplicateOptionError", + "DuplicateSectionError", + "NoOptionError", + "InterpolationError", + "InterpolationDepthError", + "InterpolationMissingOptionError", + "InterpolationSyntaxError", + "ParsingError", + "MissingSectionHeaderError", + "ConfigParser", + "RawConfigParser", + "Interpolation", + "BasicInterpolation", + "ExtendedInterpolation", + "LegacyInterpolation", + "SectionProxy", + "ConverterMapping", + "DEFAULTSECT", + "MAX_INTERPOLATION_DEPTH", + ) +else: + __all__ = [ + "NoSectionError", + "DuplicateOptionError", + "DuplicateSectionError", + "NoOptionError", + "InterpolationError", + "InterpolationDepthError", + "InterpolationMissingOptionError", + "InterpolationSyntaxError", + "ParsingError", + "MissingSectionHeaderError", + "ConfigParser", + "SafeConfigParser", + "RawConfigParser", + "Interpolation", + "BasicInterpolation", + "ExtendedInterpolation", + "LegacyInterpolation", + "SectionProxy", + "ConverterMapping", + "DEFAULTSECT", + "MAX_INTERPOLATION_DEPTH", + ] _Section: TypeAlias = Mapping[str, str] _Parser: TypeAlias = MutableMapping[str, _Section] @@ -128,7 +150,8 @@ class RawConfigParser(_Parser): def read_file(self, f: Iterable[str], source: str | None = None) -> None: ... def read_string(self, string: str, source: str = "") -> None: ... def read_dict(self, dictionary: Mapping[str, Mapping[str, Any]], source: str = "") -> None: ... - def readfp(self, fp: Iterable[str], filename: str | None = None) -> None: ... + if sys.version_info < (3, 12): + def readfp(self, fp: Iterable[str], filename: str | None = None) -> None: ... # These get* methods are partially applied (with the same names) in # SectionProxy; the stubs should be kept updated together @overload @@ -277,7 +300,11 @@ class InterpolationSyntaxError(InterpolationError): ... class ParsingError(Error): source: str errors: list[tuple[int, str]] - def __init__(self, source: str | None = None, filename: str | None = None) -> None: ... + if sys.version_info >= (3, 12): + def __init__(self, source: str) -> None: ... + else: + def __init__(self, source: str | None = None, filename: str | None = None) -> None: ... + def append(self, lineno: int, line: str) -> None: ... class MissingSectionHeaderError(ParsingError): diff --git a/mypy/typeshed/stdlib/csv.pyi b/mypy/typeshed/stdlib/csv.pyi index 139ba7af2208..a9c7fe0492c8 100644 --- a/mypy/typeshed/stdlib/csv.pyi +++ b/mypy/typeshed/stdlib/csv.pyi @@ -69,7 +69,7 @@ class excel(Dialect): ... class excel_tab(excel): ... class unix_dialect(Dialect): ... -class DictReader(Generic[_T], Iterator[_DictReadMapping[_T | Any, str | Any]]): +class DictReader(Iterator[_DictReadMapping[_T | Any, str | Any]], Generic[_T]): fieldnames: Sequence[_T] | None restkey: str | None restval: str | None diff --git a/mypy/typeshed/stdlib/enum.pyi b/mypy/typeshed/stdlib/enum.pyi index a8ba7bf157c2..e6eaf6c413dc 100644 --- a/mypy/typeshed/stdlib/enum.pyi +++ b/mypy/typeshed/stdlib/enum.pyi @@ -33,7 +33,7 @@ if sys.version_info >= (3, 11): "verify", ] -if sys.version_info >= (3, 12): +if sys.version_info >= (3, 11): __all__ += ["pickle_by_enum_name", "pickle_by_global_name"] _EnumMemberT = TypeVar("_EnumMemberT") @@ -188,7 +188,7 @@ class Enum(metaclass=EnumMeta): def __hash__(self) -> int: ... def __format__(self, format_spec: str) -> str: ... def __reduce_ex__(self, proto: Unused) -> tuple[Any, ...]: ... - if sys.version_info >= (3, 12): + if sys.version_info >= (3, 11): def __copy__(self) -> Self: ... def __deepcopy__(self, memo: Any) -> Self: ... @@ -294,6 +294,6 @@ class auto(IntFlag): def value(self) -> Any: ... def __new__(cls) -> Self: ... -if sys.version_info >= (3, 12): +if sys.version_info >= (3, 11): def pickle_by_global_name(self: Enum, proto: int) -> str: ... def pickle_by_enum_name(self: _EnumMemberT, proto: int) -> tuple[Callable[..., Any], tuple[type[_EnumMemberT], str]]: ... diff --git a/mypy/typeshed/stdlib/genericpath.pyi b/mypy/typeshed/stdlib/genericpath.pyi index 46426b63c852..be08f7a3cb79 100644 --- a/mypy/typeshed/stdlib/genericpath.pyi +++ b/mypy/typeshed/stdlib/genericpath.pyi @@ -1,5 +1,6 @@ import os -from _typeshed import BytesPath, FileDescriptorOrPath, StrPath, SupportsRichComparisonT +import sys +from _typeshed import BytesPath, FileDescriptorOrPath, StrOrBytesPath, StrPath, SupportsRichComparisonT from collections.abc import Sequence from typing import overload from typing_extensions import Literal, LiteralString @@ -17,6 +18,8 @@ __all__ = [ "sameopenfile", "samestat", ] +if sys.version_info >= (3, 12): + __all__ += ["islink"] # All overloads can return empty string. Ideally, Literal[""] would be a valid # Iterable[T], so that list[T] | Literal[""] could be used as a return @@ -36,6 +39,9 @@ def getsize(filename: FileDescriptorOrPath) -> int: ... def isfile(path: FileDescriptorOrPath) -> bool: ... def isdir(s: FileDescriptorOrPath) -> bool: ... +if sys.version_info >= (3, 12): + def islink(path: StrOrBytesPath) -> bool: ... + # These return float if os.stat_float_times() == True, # but int is a subclass of float. def getatime(filename: FileDescriptorOrPath) -> float: ... diff --git a/mypy/typeshed/stdlib/gzip.pyi b/mypy/typeshed/stdlib/gzip.pyi index 1ec8b4b8ca7c..d001849e609c 100644 --- a/mypy/typeshed/stdlib/gzip.pyi +++ b/mypy/typeshed/stdlib/gzip.pyi @@ -139,8 +139,10 @@ class GzipFile(_compression.BaseStream): fileobj: _ReadableFileobj | _WritableFileobj | None = None, mtime: float | None = None, ) -> None: ... - @property - def filename(self) -> str: ... + if sys.version_info < (3, 12): + @property + def filename(self) -> str: ... + @property def mtime(self) -> int | None: ... crc: int diff --git a/mypy/typeshed/stdlib/ntpath.pyi b/mypy/typeshed/stdlib/ntpath.pyi index f1fa137c6d88..1a58b52de050 100644 --- a/mypy/typeshed/stdlib/ntpath.pyi +++ b/mypy/typeshed/stdlib/ntpath.pyi @@ -42,6 +42,9 @@ from posixpath import ( splitext as splitext, supports_unicode_filenames as supports_unicode_filenames, ) + +if sys.version_info >= (3, 12): + from posixpath import isjunction as isjunction, splitroot as splitroot from typing import AnyStr, overload from typing_extensions import LiteralString @@ -85,6 +88,8 @@ __all__ = [ "samestat", "commonpath", ] +if sys.version_info >= (3, 12): + __all__ += ["isjunction", "splitroot"] altsep: LiteralString diff --git a/mypy/typeshed/stdlib/os/__init__.pyi b/mypy/typeshed/stdlib/os/__init__.pyi index 994595aae781..961858ce3c19 100644 --- a/mypy/typeshed/stdlib/os/__init__.pyi +++ b/mypy/typeshed/stdlib/os/__init__.pyi @@ -388,6 +388,8 @@ class DirEntry(Generic[AnyStr]): def __fspath__(self) -> AnyStr: ... if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... + if sys.version_info >= (3, 12): + def is_junction(self) -> bool: ... @final class statvfs_result(structseq[int], tuple[int, int, int, int, int, int, int, int, int, int, int]): @@ -602,7 +604,12 @@ def isatty(__fd: int) -> bool: ... if sys.platform != "win32" and sys.version_info >= (3, 11): def login_tty(__fd: int) -> None: ... -def lseek(__fd: int, __position: int, __how: int) -> int: ... +if sys.version_info >= (3, 11): + def lseek(__fd: int, __position: int, __whence: int) -> int: ... + +else: + def lseek(__fd: int, __position: int, __how: int) -> int: ... + def open(path: StrOrBytesPath, flags: int, mode: int = 0o777, *, dir_fd: int | None = None) -> int: ... def pipe() -> tuple[int, int]: ... def read(__fd: int, __length: int) -> bytes: ... diff --git a/mypy/typeshed/stdlib/posixpath.pyi b/mypy/typeshed/stdlib/posixpath.pyi index 1945190be5f8..45a8ad7ec6a4 100644 --- a/mypy/typeshed/stdlib/posixpath.pyi +++ b/mypy/typeshed/stdlib/posixpath.pyi @@ -58,6 +58,8 @@ __all__ = [ "relpath", "commonpath", ] +if sys.version_info >= (3, 12): + __all__ += ["isjunction", "splitroot"] supports_unicode_filenames: bool # aliases (also in os) @@ -150,3 +152,10 @@ def isabs(s: StrOrBytesPath) -> bool: ... def islink(path: FileDescriptorOrPath) -> bool: ... def ismount(path: FileDescriptorOrPath) -> bool: ... def lexists(path: FileDescriptorOrPath) -> bool: ... + +if sys.version_info >= (3, 12): + def isjunction(path: StrOrBytesPath) -> bool: ... + @overload + def splitroot(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr, AnyOrLiteralStr]: ... + @overload + def splitroot(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr, AnyStr]: ... diff --git a/mypy/typeshed/stdlib/pydoc.pyi b/mypy/typeshed/stdlib/pydoc.pyi index 7791c977aa8b..1b09bcb059e4 100644 --- a/mypy/typeshed/stdlib/pydoc.pyi +++ b/mypy/typeshed/stdlib/pydoc.pyi @@ -198,7 +198,7 @@ def render_doc( thing: str | object, title: str = "Python Library Documentation: %s", forceload: bool = ..., renderer: Doc | None = None ) -> str: ... -if sys.version_info >= (3, 12): +if sys.version_info >= (3, 11): def doc( thing: str | object, title: str = "Python Library Documentation: %s", @@ -230,7 +230,7 @@ class Helper: def __call__(self, request: str | Helper | object = ...) -> None: ... def interact(self) -> None: ... def getline(self, prompt: str) -> str: ... - if sys.version_info >= (3, 12): + if sys.version_info >= (3, 11): def help(self, request: Any, is_cli: bool = False) -> None: ... else: def help(self, request: Any) -> None: ... diff --git a/mypy/typeshed/stdlib/ssl.pyi b/mypy/typeshed/stdlib/ssl.pyi index 1c49b130e48f..73762cd75e79 100644 --- a/mypy/typeshed/stdlib/ssl.pyi +++ b/mypy/typeshed/stdlib/ssl.pyi @@ -201,12 +201,13 @@ class Options(enum.IntFlag): OP_NO_RENEGOTIATION: int if sys.version_info >= (3, 8): OP_ENABLE_MIDDLEBOX_COMPAT: int - if sys.platform == "linux": - OP_IGNORE_UNEXPECTED_EOF: int if sys.version_info >= (3, 12): OP_LEGACY_SERVER_CONNECT: int if sys.version_info >= (3, 12) and sys.platform != "linux": OP_ENABLE_KTLS: int + if sys.version_info >= (3, 11): + OP_IGNORE_UNEXPECTED_EOF: int + elif sys.version_info >= (3, 8) and sys.platform == "linux": OP_IGNORE_UNEXPECTED_EOF: int OP_ALL: Options @@ -224,12 +225,13 @@ OP_NO_TICKET: Options OP_NO_RENEGOTIATION: Options if sys.version_info >= (3, 8): OP_ENABLE_MIDDLEBOX_COMPAT: Options - if sys.platform == "linux": - OP_IGNORE_UNEXPECTED_EOF: Options if sys.version_info >= (3, 12): OP_LEGACY_SERVER_CONNECT: Options if sys.version_info >= (3, 12) and sys.platform != "linux": OP_ENABLE_KTLS: Options +if sys.version_info >= (3, 11): + OP_IGNORE_UNEXPECTED_EOF: Options +elif sys.version_info >= (3, 8) and sys.platform == "linux": OP_IGNORE_UNEXPECTED_EOF: Options HAS_NEVER_CHECK_COMMON_NAME: bool diff --git a/mypy/typeshed/stdlib/tempfile.pyi b/mypy/typeshed/stdlib/tempfile.pyi index ea04303683b5..61bcde24255b 100644 --- a/mypy/typeshed/stdlib/tempfile.pyi +++ b/mypy/typeshed/stdlib/tempfile.pyi @@ -321,7 +321,7 @@ else: dir: GenericPath[AnyStr] | None = None, ) -> IO[Any]: ... -class _TemporaryFileWrapper(Generic[AnyStr], IO[AnyStr]): +class _TemporaryFileWrapper(IO[AnyStr], Generic[AnyStr]): file: IO[AnyStr] # io.TextIOWrapper, io.BufferedReader or io.BufferedWriter name: str delete: bool diff --git a/mypy/typeshed/stdlib/unittest/__init__.pyi b/mypy/typeshed/stdlib/unittest/__init__.pyi index 33820c793fa5..f96d6fb185c5 100644 --- a/mypy/typeshed/stdlib/unittest/__init__.pyi +++ b/mypy/typeshed/stdlib/unittest/__init__.pyi @@ -65,5 +65,7 @@ if sys.version_info >= (3, 8): if sys.version_info >= (3, 11): __all__ += ["enterModuleContext", "doModuleCleanups"] -def load_tests(loader: TestLoader, tests: TestSuite, pattern: str | None) -> TestSuite: ... +if sys.version_info < (3, 12): + def load_tests(loader: TestLoader, tests: TestSuite, pattern: str | None) -> TestSuite: ... + def __dir__() -> set[str]: ... diff --git a/mypy/typeshed/stdlib/unittest/loader.pyi b/mypy/typeshed/stdlib/unittest/loader.pyi index f3850c939d07..202309ac1d93 100644 --- a/mypy/typeshed/stdlib/unittest/loader.pyi +++ b/mypy/typeshed/stdlib/unittest/loader.pyi @@ -1,3 +1,4 @@ +import sys import unittest.case import unittest.suite from collections.abc import Callable, Sequence @@ -18,7 +19,11 @@ class TestLoader: testNamePatterns: list[str] | None suiteClass: _SuiteClass def loadTestsFromTestCase(self, testCaseClass: type[unittest.case.TestCase]) -> unittest.suite.TestSuite: ... - def loadTestsFromModule(self, module: ModuleType, *args: Any, pattern: Any = None) -> unittest.suite.TestSuite: ... + if sys.version_info >= (3, 12): + def loadTestsFromModule(self, module: ModuleType, *, pattern: str | None = None) -> unittest.suite.TestSuite: ... + else: + def loadTestsFromModule(self, module: ModuleType, *args: Any, pattern: str | None = None) -> unittest.suite.TestSuite: ... + def loadTestsFromName(self, name: str, module: ModuleType | None = None) -> unittest.suite.TestSuite: ... def loadTestsFromNames(self, names: Sequence[str], module: ModuleType | None = None) -> unittest.suite.TestSuite: ... def getTestCaseNames(self, testCaseClass: type[unittest.case.TestCase]) -> Sequence[str]: ... diff --git a/mypy/typeshed/stdlib/unittest/main.pyi b/mypy/typeshed/stdlib/unittest/main.pyi index 6d970c920096..d29e9a2b8da8 100644 --- a/mypy/typeshed/stdlib/unittest/main.pyi +++ b/mypy/typeshed/stdlib/unittest/main.pyi @@ -1,3 +1,4 @@ +import sys import unittest.case import unittest.loader import unittest.result @@ -23,22 +24,43 @@ class TestProgram: progName: str | None warnings: str | None testNamePatterns: list[str] | None - def __init__( - self, - module: None | str | ModuleType = "__main__", - defaultTest: str | Iterable[str] | None = None, - argv: list[str] | None = None, - testRunner: type[_TestRunner] | _TestRunner | None = None, - testLoader: unittest.loader.TestLoader = ..., - exit: bool = True, - verbosity: int = 1, - failfast: bool | None = None, - catchbreak: bool | None = None, - buffer: bool | None = None, - warnings: str | None = None, - *, - tb_locals: bool = False, - ) -> None: ... + if sys.version_info >= (3, 12): + durations: unittest.result._DurationsType | None + def __init__( + self, + module: None | str | ModuleType = "__main__", + defaultTest: str | Iterable[str] | None = None, + argv: list[str] | None = None, + testRunner: type[_TestRunner] | _TestRunner | None = None, + testLoader: unittest.loader.TestLoader = ..., + exit: bool = True, + verbosity: int = 1, + failfast: bool | None = None, + catchbreak: bool | None = None, + buffer: bool | None = None, + warnings: str | None = None, + *, + tb_locals: bool = False, + durations: unittest.result._DurationsType | None = None, + ) -> None: ... + else: + def __init__( + self, + module: None | str | ModuleType = "__main__", + defaultTest: str | Iterable[str] | None = None, + argv: list[str] | None = None, + testRunner: type[_TestRunner] | _TestRunner | None = None, + testLoader: unittest.loader.TestLoader = ..., + exit: bool = True, + verbosity: int = 1, + failfast: bool | None = None, + catchbreak: bool | None = None, + buffer: bool | None = None, + warnings: str | None = None, + *, + tb_locals: bool = False, + ) -> None: ... + def usageExit(self, msg: Any = None) -> None: ... def parseArgs(self, argv: list[str]) -> None: ... def createTests(self, from_discovery: bool = False, Loader: unittest.loader.TestLoader | None = None) -> None: ... diff --git a/mypy/typeshed/stdlib/unittest/result.pyi b/mypy/typeshed/stdlib/unittest/result.pyi index 8d78bc0f7dcf..dfc505936f59 100644 --- a/mypy/typeshed/stdlib/unittest/result.pyi +++ b/mypy/typeshed/stdlib/unittest/result.pyi @@ -1,9 +1,12 @@ +import sys import unittest.case from _typeshed import OptExcInfo from collections.abc import Callable from typing import Any, TextIO, TypeVar +from typing_extensions import TypeAlias _F = TypeVar("_F", bound=Callable[..., Any]) +_DurationsType: TypeAlias = list[tuple[str, float]] STDOUT_LINE: str STDERR_LINE: str @@ -22,6 +25,8 @@ class TestResult: buffer: bool failfast: bool tb_locals: bool + if sys.version_info >= (3, 12): + collectedDurations: _DurationsType def __init__(self, stream: TextIO | None = None, descriptions: bool | None = None, verbosity: int | None = None) -> None: ... def printErrors(self) -> None: ... def wasSuccessful(self) -> bool: ... @@ -37,3 +42,5 @@ class TestResult: def addExpectedFailure(self, test: unittest.case.TestCase, err: OptExcInfo) -> None: ... def addUnexpectedSuccess(self, test: unittest.case.TestCase) -> None: ... def addSubTest(self, test: unittest.case.TestCase, subtest: unittest.case.TestCase, err: OptExcInfo | None) -> None: ... + if sys.version_info >= (3, 12): + def addDuration(self, test: unittest.case.TestCase, elapsed: float) -> None: ... diff --git a/mypy/typeshed/stdlib/unittest/runner.pyi b/mypy/typeshed/stdlib/unittest/runner.pyi index c0ddcdb49208..0033083ac406 100644 --- a/mypy/typeshed/stdlib/unittest/runner.pyi +++ b/mypy/typeshed/stdlib/unittest/runner.pyi @@ -1,6 +1,8 @@ +import sys import unittest.case import unittest.result import unittest.suite +from _typeshed import Incomplete from collections.abc import Callable, Iterable from typing import TextIO from typing_extensions import TypeAlias @@ -14,23 +16,57 @@ class TextTestResult(unittest.result.TestResult): separator2: str showAll: bool # undocumented stream: TextIO # undocumented - def __init__(self, stream: TextIO, descriptions: bool, verbosity: int) -> None: ... + if sys.version_info >= (3, 12): + durations: unittest.result._DurationsType | None + def __init__( + self, stream: TextIO, descriptions: bool, verbosity: int, *, durations: unittest.result._DurationsType | None = None + ) -> None: ... + else: + def __init__(self, stream: TextIO, descriptions: bool, verbosity: int) -> None: ... + def getDescription(self, test: unittest.case.TestCase) -> str: ... def printErrorList(self, flavour: str, errors: Iterable[tuple[unittest.case.TestCase, str]]) -> None: ... class TextTestRunner: resultclass: _ResultClassType - def __init__( - self, - stream: TextIO | None = None, - descriptions: bool = True, - verbosity: int = 1, - failfast: bool = False, - buffer: bool = False, - resultclass: _ResultClassType | None = None, - warnings: type[Warning] | None = None, - *, - tb_locals: bool = False, - ) -> None: ... + # TODO: add `_WritelnDecorator` type + # stream: _WritelnDecorator + stream: Incomplete + descriptions: bool + verbosity: int + failfast: bool + buffer: bool + warnings: str | None + tb_locals: bool + + if sys.version_info >= (3, 12): + durations: unittest.result._DurationsType | None + def __init__( + self, + stream: TextIO | None = None, + descriptions: bool = True, + verbosity: int = 1, + failfast: bool = False, + buffer: bool = False, + resultclass: _ResultClassType | None = None, + warnings: str | None = None, + *, + tb_locals: bool = False, + durations: unittest.result._DurationsType | None = None, + ) -> None: ... + else: + def __init__( + self, + stream: TextIO | None = None, + descriptions: bool = True, + verbosity: int = 1, + failfast: bool = False, + buffer: bool = False, + resultclass: _ResultClassType | None = None, + warnings: str | None = None, + *, + tb_locals: bool = False, + ) -> None: ... + def _makeResult(self) -> unittest.result.TestResult: ... def run(self, test: unittest.suite.TestSuite | unittest.case.TestCase) -> unittest.result.TestResult: ...