Skip to content

Commit c9583d9

Browse files
authored
Add durations to unittest in 3.12 (#10636)
1 parent 8888ac0 commit c9583d9

File tree

4 files changed

+94
-37
lines changed

4 files changed

+94
-37
lines changed

stdlib/unittest/main.pyi

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import sys
12
import unittest.case
23
import unittest.loader
34
import unittest.result
@@ -23,22 +24,43 @@ class TestProgram:
2324
progName: str | None
2425
warnings: str | None
2526
testNamePatterns: list[str] | None
26-
def __init__(
27-
self,
28-
module: None | str | ModuleType = "__main__",
29-
defaultTest: str | Iterable[str] | None = None,
30-
argv: list[str] | None = None,
31-
testRunner: type[_TestRunner] | _TestRunner | None = None,
32-
testLoader: unittest.loader.TestLoader = ...,
33-
exit: bool = True,
34-
verbosity: int = 1,
35-
failfast: bool | None = None,
36-
catchbreak: bool | None = None,
37-
buffer: bool | None = None,
38-
warnings: str | None = None,
39-
*,
40-
tb_locals: bool = False,
41-
) -> None: ...
27+
if sys.version_info >= (3, 12):
28+
durations: unittest.result._DurationsType | None
29+
def __init__(
30+
self,
31+
module: None | str | ModuleType = "__main__",
32+
defaultTest: str | Iterable[str] | None = None,
33+
argv: list[str] | None = None,
34+
testRunner: type[_TestRunner] | _TestRunner | None = None,
35+
testLoader: unittest.loader.TestLoader = ...,
36+
exit: bool = True,
37+
verbosity: int = 1,
38+
failfast: bool | None = None,
39+
catchbreak: bool | None = None,
40+
buffer: bool | None = None,
41+
warnings: str | None = None,
42+
*,
43+
tb_locals: bool = False,
44+
durations: unittest.result._DurationsType | None = None,
45+
) -> None: ...
46+
else:
47+
def __init__(
48+
self,
49+
module: None | str | ModuleType = "__main__",
50+
defaultTest: str | Iterable[str] | None = None,
51+
argv: list[str] | None = None,
52+
testRunner: type[_TestRunner] | _TestRunner | None = None,
53+
testLoader: unittest.loader.TestLoader = ...,
54+
exit: bool = True,
55+
verbosity: int = 1,
56+
failfast: bool | None = None,
57+
catchbreak: bool | None = None,
58+
buffer: bool | None = None,
59+
warnings: str | None = None,
60+
*,
61+
tb_locals: bool = False,
62+
) -> None: ...
63+
4264
def usageExit(self, msg: Any = None) -> None: ...
4365
def parseArgs(self, argv: list[str]) -> None: ...
4466
def createTests(self, from_discovery: bool = False, Loader: unittest.loader.TestLoader | None = None) -> None: ...

stdlib/unittest/result.pyi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import sys
12
import unittest.case
23
from _typeshed import OptExcInfo
34
from collections.abc import Callable
45
from typing import Any, TextIO, TypeVar
6+
from typing_extensions import TypeAlias
57

68
_F = TypeVar("_F", bound=Callable[..., Any])
9+
_DurationsType: TypeAlias = list[tuple[str, float]]
710

811
STDOUT_LINE: str
912
STDERR_LINE: str
@@ -22,6 +25,8 @@ class TestResult:
2225
buffer: bool
2326
failfast: bool
2427
tb_locals: bool
28+
if sys.version_info >= (3, 12):
29+
collectedDurations: _DurationsType
2530
def __init__(self, stream: TextIO | None = None, descriptions: bool | None = None, verbosity: int | None = None) -> None: ...
2631
def printErrors(self) -> None: ...
2732
def wasSuccessful(self) -> bool: ...
@@ -37,3 +42,5 @@ class TestResult:
3742
def addExpectedFailure(self, test: unittest.case.TestCase, err: OptExcInfo) -> None: ...
3843
def addUnexpectedSuccess(self, test: unittest.case.TestCase) -> None: ...
3944
def addSubTest(self, test: unittest.case.TestCase, subtest: unittest.case.TestCase, err: OptExcInfo | None) -> None: ...
45+
if sys.version_info >= (3, 12):
46+
def addDuration(self, test: unittest.case.TestCase, elapsed: float) -> None: ...

stdlib/unittest/runner.pyi

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import sys
12
import unittest.case
23
import unittest.result
34
import unittest.suite
5+
from _typeshed import Incomplete
46
from collections.abc import Callable, Iterable
57
from typing import TextIO
68
from typing_extensions import TypeAlias
@@ -14,23 +16,57 @@ class TextTestResult(unittest.result.TestResult):
1416
separator2: str
1517
showAll: bool # undocumented
1618
stream: TextIO # undocumented
17-
def __init__(self, stream: TextIO, descriptions: bool, verbosity: int) -> None: ...
19+
if sys.version_info >= (3, 12):
20+
durations: unittest.result._DurationsType | None
21+
def __init__(
22+
self, stream: TextIO, descriptions: bool, verbosity: int, *, durations: unittest.result._DurationsType | None = None
23+
) -> None: ...
24+
else:
25+
def __init__(self, stream: TextIO, descriptions: bool, verbosity: int) -> None: ...
26+
1827
def getDescription(self, test: unittest.case.TestCase) -> str: ...
1928
def printErrorList(self, flavour: str, errors: Iterable[tuple[unittest.case.TestCase, str]]) -> None: ...
2029

2130
class TextTestRunner:
2231
resultclass: _ResultClassType
23-
def __init__(
24-
self,
25-
stream: TextIO | None = None,
26-
descriptions: bool = True,
27-
verbosity: int = 1,
28-
failfast: bool = False,
29-
buffer: bool = False,
30-
resultclass: _ResultClassType | None = None,
31-
warnings: type[Warning] | None = None,
32-
*,
33-
tb_locals: bool = False,
34-
) -> None: ...
32+
# TODO: add `_WritelnDecorator` type
33+
# stream: _WritelnDecorator
34+
stream: Incomplete
35+
descriptions: bool
36+
verbosity: int
37+
failfast: bool
38+
buffer: bool
39+
warnings: str | None
40+
tb_locals: bool
41+
42+
if sys.version_info >= (3, 12):
43+
durations: unittest.result._DurationsType | None
44+
def __init__(
45+
self,
46+
stream: TextIO | None = None,
47+
descriptions: bool = True,
48+
verbosity: int = 1,
49+
failfast: bool = False,
50+
buffer: bool = False,
51+
resultclass: _ResultClassType | None = None,
52+
warnings: str | None = None,
53+
*,
54+
tb_locals: bool = False,
55+
durations: unittest.result._DurationsType | None = None,
56+
) -> None: ...
57+
else:
58+
def __init__(
59+
self,
60+
stream: TextIO | None = None,
61+
descriptions: bool = True,
62+
verbosity: int = 1,
63+
failfast: bool = False,
64+
buffer: bool = False,
65+
resultclass: _ResultClassType | None = None,
66+
warnings: str | None = None,
67+
*,
68+
tb_locals: bool = False,
69+
) -> None: ...
70+
3571
def _makeResult(self) -> unittest.result.TestResult: ...
3672
def run(self, test: unittest.suite.TestSuite | unittest.case.TestCase) -> unittest.result.TestResult: ...

tests/stubtest_allowlists/py312.txt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,9 @@ typing_extensions.Protocol
6464
typing_extensions.SupportsAbs.__type_params__
6565
typing_extensions.SupportsRound.__type_params__
6666
unittest.TestLoader.loadTestsFromModule
67-
unittest.TestProgram.__init__
68-
unittest.TestResult.addDuration
69-
unittest.TextTestResult.__init__
70-
unittest.TextTestRunner.__init__
7167
unittest.load_tests
7268
unittest.loader.TestLoader.loadTestsFromModule
73-
unittest.main.TestProgram.__init__
7469
unittest.mock.NonCallableMock.__new__
75-
unittest.result.TestResult.addDuration
76-
unittest.runner.TextTestResult.__init__
77-
unittest.runner.TextTestRunner.__init__
7870
urllib.request.AbstractHTTPHandler.__init__
7971
urllib.request.HTTPSHandler.__init__
8072
zipfile.Path.glob

0 commit comments

Comments
 (0)