From 1b7ac445b6d8af770f9634dd0a98ed7bf882047b Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Sun, 12 Jun 2022 22:18:57 +0100 Subject: [PATCH 01/10] `unittest`: Improve `self.assertAlmostEqual` --- stdlib/unittest/case.pyi | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/stdlib/unittest/case.pyi b/stdlib/unittest/case.pyi index 7f2928233c10..bf11d5885566 100644 --- a/stdlib/unittest/case.pyi +++ b/stdlib/unittest/case.pyi @@ -6,7 +6,7 @@ from _typeshed import Self from collections.abc import Callable, Container, Iterable, Mapping, Sequence, Set as AbstractSet from contextlib import AbstractContextManager from types import TracebackType -from typing import Any, AnyStr, ClassVar, Generic, NamedTuple, NoReturn, Pattern, TypeVar, overload +from typing import Any, AnyStr, ClassVar, Generic, NamedTuple, NoReturn, Pattern, Protocol, SupportsAbs, TypeVar, overload from typing_extensions import ParamSpec from warnings import WarningMessage @@ -14,6 +14,7 @@ if sys.version_info >= (3, 9): from types import GenericAlias _T = TypeVar("_T") +_T_contra = TypeVar("_T_contra", contravariant=True) _E = TypeVar("_E", bound=BaseException) _FT = TypeVar("_FT", bound=Callable[..., Any]) _P = ParamSpec("_P") @@ -62,6 +63,9 @@ def skipUnless(condition: object, reason: str) -> Callable[[_FT], _FT]: ... class SkipTest(Exception): def __init__(self, reason: str) -> None: ... +class _SupportsAlmostEqualAssertions(Protocol[_T_contra]): + def __sub__(self, __other: _T_contra) -> SupportsAbs: ... + class TestCase: failureException: type[BaseException] longMessage: bool @@ -167,31 +171,19 @@ class TestCase: @overload def assertAlmostEqual( - self, first: float, second: float, places: int | None = ..., msg: Any = ..., delta: float | None = ... + self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: None = ..., msg: Any = ..., delta: float | None = ... ) -> None: ... @overload def assertAlmostEqual( - self, - first: datetime.datetime, - second: datetime.datetime, - places: int | None = ..., - msg: Any = ..., - delta: datetime.timedelta | None = ..., + self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: int, msg: Any = ..., delta: None = ... ) -> None: ... @overload - def assertNotAlmostEqual(self, first: float, second: float, *, msg: Any = ...) -> None: ... - @overload - def assertNotAlmostEqual(self, first: float, second: float, places: int | None = ..., msg: Any = ...) -> None: ... - @overload - def assertNotAlmostEqual(self, first: float, second: float, *, msg: Any = ..., delta: float | None = ...) -> None: ... + def assertNotAlmostEqual( + self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: None = ..., msg: Any = ..., delta: float | None = ... + ) -> None: ... @overload def assertNotAlmostEqual( - self, - first: datetime.datetime, - second: datetime.datetime, - places: int | None = ..., - msg: Any = ..., - delta: datetime.timedelta | None = ..., + self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: int, msg: Any = ..., delta: None = ... ) -> None: ... def assertRegex(self, text: AnyStr, expected_regex: AnyStr | Pattern[AnyStr], msg: Any = ...) -> None: ... def assertNotRegex(self, text: AnyStr, unexpected_regex: AnyStr | Pattern[AnyStr], msg: Any = ...) -> None: ... From 615e997699ebc5d5d27f32014f90a7a1018437b4 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Sun, 12 Jun 2022 22:29:45 +0100 Subject: [PATCH 02/10] Fix pyright complaints --- stdlib/unittest/case.pyi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stdlib/unittest/case.pyi b/stdlib/unittest/case.pyi index bf11d5885566..d6b9c7b7df59 100644 --- a/stdlib/unittest/case.pyi +++ b/stdlib/unittest/case.pyi @@ -1,4 +1,3 @@ -import datetime import logging import sys import unittest.result @@ -63,8 +62,11 @@ def skipUnless(condition: object, reason: str) -> Callable[[_FT], _FT]: ... class SkipTest(Exception): def __init__(self, reason: str) -> None: ... +class _SupportsDunderLeWithFloat(Protocol): + def __le__(self, __other: float) -> object: ... + class _SupportsAlmostEqualAssertions(Protocol[_T_contra]): - def __sub__(self, __other: _T_contra) -> SupportsAbs: ... + def __sub__(self, __other: _T_contra) -> SupportsAbs[_SupportsDunderLeWithFloat]: ... class TestCase: failureException: type[BaseException] From 704eda1998e53c1fca136e6f6e5b9eb70a0c8144 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Sun, 12 Jun 2022 22:44:03 +0100 Subject: [PATCH 03/10] Avoid regression with `datetime`, add a test --- stdlib/unittest/case.pyi | 13 +++++++++++++ test_cases/stdlib/test_unittest.py | 10 ++++++++++ 2 files changed, 23 insertions(+) create mode 100644 test_cases/stdlib/test_unittest.py diff --git a/stdlib/unittest/case.pyi b/stdlib/unittest/case.pyi index d6b9c7b7df59..f97194d5e1eb 100644 --- a/stdlib/unittest/case.pyi +++ b/stdlib/unittest/case.pyi @@ -4,6 +4,7 @@ import unittest.result from _typeshed import Self from collections.abc import Callable, Container, Iterable, Mapping, Sequence, Set as AbstractSet from contextlib import AbstractContextManager +from datetime import datetime from types import TracebackType from typing import Any, AnyStr, ClassVar, Generic, NamedTuple, NoReturn, Pattern, Protocol, SupportsAbs, TypeVar, overload from typing_extensions import ParamSpec @@ -171,19 +172,31 @@ class TestCase: self, logger: str | logging.Logger | None = ..., level: int | str | None = ... ) -> _AssertLogsContext[None]: ... + @overload + def assertAlmostEqual( + self, first: datetime, second: datetime, places: None = ..., msg: Any = ..., delta: float | None = ... + ) -> None: ... @overload def assertAlmostEqual( self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: None = ..., msg: Any = ..., delta: float | None = ... ) -> None: ... @overload + def assertAlmostEqual(self, first: datetime, second: datetime, places: int, msg: Any = ..., delta: None = ...) -> None: ... + @overload def assertAlmostEqual( self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: int, msg: Any = ..., delta: None = ... ) -> None: ... @overload + def assertNotAlmostEqual( + self, first: datetime, second: datetime, places: None = ..., msg: Any = ..., delta: float | None = ... + ) -> None: ... + @overload def assertNotAlmostEqual( self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: None = ..., msg: Any = ..., delta: float | None = ... ) -> None: ... @overload + def assertNotAlmostEqual(self, first: datetime, second: datetime, places: int, msg: Any = ..., delta: None = ...) -> None: ... + @overload def assertNotAlmostEqual( self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: int, msg: Any = ..., delta: None = ... ) -> None: ... diff --git a/test_cases/stdlib/test_unittest.py b/test_cases/stdlib/test_unittest.py new file mode 100644 index 000000000000..f85de0c7f0a0 --- /dev/null +++ b/test_cases/stdlib/test_unittest.py @@ -0,0 +1,10 @@ +from unittest import TestCase +from datetime import datetime +from fractions import Fraction +from decimal import Decimal + +def test_assertAlmostEqual(case: TestCase) -> None: + case.assertAlmostEqual(2.4, 2.41) + case.assertAlmostEqual(Fraction(49, 50), Fraction(48, 50)) + case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1)) + case.assertAlmostEqual(Decimal("1.1"), Decimal("1.11")) From 33c02d27b938a4724fee0b15ef4b193f7b4eeb2f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 12 Jun 2022 21:45:21 +0000 Subject: [PATCH 04/10] [pre-commit.ci] auto fixes from pre-commit.com hooks --- test_cases/stdlib/test_unittest.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test_cases/stdlib/test_unittest.py b/test_cases/stdlib/test_unittest.py index f85de0c7f0a0..c3d64538bbd3 100644 --- a/test_cases/stdlib/test_unittest.py +++ b/test_cases/stdlib/test_unittest.py @@ -1,7 +1,8 @@ -from unittest import TestCase from datetime import datetime -from fractions import Fraction from decimal import Decimal +from fractions import Fraction +from unittest import TestCase + def test_assertAlmostEqual(case: TestCase) -> None: case.assertAlmostEqual(2.4, 2.41) From 70c2420c2c195cbd4af24a33e1377a1d38b47cd9 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Sun, 12 Jun 2022 22:52:05 +0100 Subject: [PATCH 05/10] Improve tests --- test_cases/stdlib/test_unittest.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test_cases/stdlib/test_unittest.py b/test_cases/stdlib/test_unittest.py index c3d64538bbd3..886ab71a2c3d 100644 --- a/test_cases/stdlib/test_unittest.py +++ b/test_cases/stdlib/test_unittest.py @@ -1,3 +1,5 @@ +# pyright: reportUnnecessaryTypeIgnoreComment=true + from datetime import datetime from decimal import Decimal from fractions import Fraction @@ -9,3 +11,6 @@ def test_assertAlmostEqual(case: TestCase) -> None: case.assertAlmostEqual(Fraction(49, 50), Fraction(48, 50)) case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1)) case.assertAlmostEqual(Decimal("1.1"), Decimal("1.11")) + case.assertAlmostEqual(2.4, 2.41, places=8) + case.assertAlmostEqual(2.4, 2.41, delta=0.02) + case.assertAlmostEqual(2.4, 2.41, places=9, delta=0.02) # type: ignore[call-overload] From 93df0e044b8475eb9c1d9e21dfc824e1ce50c7ea Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Sun, 12 Jun 2022 22:55:23 +0100 Subject: [PATCH 06/10] One more --- test_cases/stdlib/test_unittest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test_cases/stdlib/test_unittest.py b/test_cases/stdlib/test_unittest.py index 886ab71a2c3d..4731ecd935cf 100644 --- a/test_cases/stdlib/test_unittest.py +++ b/test_cases/stdlib/test_unittest.py @@ -14,3 +14,4 @@ def test_assertAlmostEqual(case: TestCase) -> None: case.assertAlmostEqual(2.4, 2.41, places=8) case.assertAlmostEqual(2.4, 2.41, delta=0.02) case.assertAlmostEqual(2.4, 2.41, places=9, delta=0.02) # type: ignore[call-overload] + case.assertAlmostEqual("foo", "bar") # type: ignore[call-overload] From 389f6861ad207fbf983e3a5c62bfd6c9e30a4bb6 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Sun, 12 Jun 2022 22:59:54 +0100 Subject: [PATCH 07/10] Take care of the deprecated aliases as well --- stdlib/unittest/case.pyi | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/stdlib/unittest/case.pyi b/stdlib/unittest/case.pyi index f97194d5e1eb..0cb7ca4f2c05 100644 --- a/stdlib/unittest/case.pyi +++ b/stdlib/unittest/case.pyi @@ -256,14 +256,10 @@ class TestCase: ) -> None: ... @overload def failUnlessRaises(self, exception: type[_E] | tuple[type[_E], ...], msg: Any = ...) -> _AssertRaisesContext[_E]: ... - def failUnlessAlmostEqual(self, first: float, second: float, places: int = ..., msg: Any = ...) -> None: ... - def assertAlmostEquals( - self, first: float, second: float, places: int = ..., msg: Any = ..., delta: float = ... - ) -> None: ... - def failIfAlmostEqual(self, first: float, second: float, places: int = ..., msg: Any = ...) -> None: ... - def assertNotAlmostEquals( - self, first: float, second: float, places: int = ..., msg: Any = ..., delta: float = ... - ) -> None: ... + failUnlessAlmostEqual = assertAlmostEqual + assertAlmostEquals = assertAlmostEqual + failIfAlmostEqual = assertNotAlmostEqual + assertNotAlmostEquals = assertNotAlmostEqual def assertRegexpMatches(self, text: AnyStr, regex: AnyStr | Pattern[AnyStr], msg: Any = ...) -> None: ... def assertNotRegexpMatches(self, text: AnyStr, regex: AnyStr | Pattern[AnyStr], msg: Any = ...) -> None: ... @overload From a227de63aa5d238d453ffaaaf2d0869e65e27569 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 13 Jun 2022 22:40:02 +0100 Subject: [PATCH 08/10] Get all tests to pass correctly --- stdlib/_typeshed/__init__.pyi | 25 ++++++++------ stdlib/unittest/case.pyi | 53 +++++++++++++++++++----------- test_cases/stdlib/test_unittest.py | 25 +++++++------- 3 files changed, 62 insertions(+), 41 deletions(-) diff --git a/stdlib/_typeshed/__init__.pyi b/stdlib/_typeshed/__init__.pyi index aef6b553ea92..bdaf88feb2db 100644 --- a/stdlib/_typeshed/__init__.pyi +++ b/stdlib/_typeshed/__init__.pyi @@ -50,21 +50,23 @@ class SupportsAnext(Protocol[_T_co]): # Comparison protocols -class SupportsDunderLT(Protocol): - def __lt__(self, __other: Any) -> bool: ... +class SupportsDunderLT(Protocol[_T_contra]): + def __lt__(self, __other: _T_contra) -> bool: ... -class SupportsDunderGT(Protocol): - def __gt__(self, __other: Any) -> bool: ... +class SupportsDunderGT(Protocol[_T_contra]): + def __gt__(self, __other: _T_contra) -> bool: ... -class SupportsDunderLE(Protocol): - def __le__(self, __other: Any) -> bool: ... +class SupportsDunderLE(Protocol[_T_contra]): + def __le__(self, __other: _T_contra) -> bool: ... -class SupportsDunderGE(Protocol): - def __ge__(self, __other: Any) -> bool: ... +class SupportsDunderGE(Protocol[_T_contra]): + def __ge__(self, __other: _T_contra) -> bool: ... -class SupportsAllComparisons(SupportsDunderLT, SupportsDunderGT, SupportsDunderLE, SupportsDunderGE, Protocol): ... +class SupportsAllComparisons( + SupportsDunderLT[Any], SupportsDunderGT[Any], SupportsDunderLE[Any], SupportsDunderGE[Any], Protocol +): ... -SupportsRichComparison: TypeAlias = SupportsDunderLT | SupportsDunderGT +SupportsRichComparison: TypeAlias = SupportsDunderLT[Any] | SupportsDunderGT[Any] SupportsRichComparisonT = TypeVar("SupportsRichComparisonT", bound=SupportsRichComparison) # noqa: Y001 # Dunder protocols @@ -75,6 +77,9 @@ class SupportsAdd(Protocol[_T_contra, _T_co]): class SupportsRAdd(Protocol[_T_contra, _T_co]): def __radd__(self, __x: _T_contra) -> _T_co: ... +class SupportsSub(Protocol[_T_contra, _T_co]): + def __sub__(self, __x: _T_contra) -> _T_co: ... + class SupportsDivMod(Protocol[_T_contra, _T_co]): def __divmod__(self, __other: _T_contra) -> _T_co: ... diff --git a/stdlib/unittest/case.pyi b/stdlib/unittest/case.pyi index 0cb7ca4f2c05..1737ab1ef3c3 100644 --- a/stdlib/unittest/case.pyi +++ b/stdlib/unittest/case.pyi @@ -1,12 +1,25 @@ import logging import sys import unittest.result -from _typeshed import Self +from _typeshed import Self, SupportsDunderGE, SupportsSub from collections.abc import Callable, Container, Iterable, Mapping, Sequence, Set as AbstractSet from contextlib import AbstractContextManager from datetime import datetime from types import TracebackType -from typing import Any, AnyStr, ClassVar, Generic, NamedTuple, NoReturn, Pattern, Protocol, SupportsAbs, TypeVar, overload +from typing import ( + Any, + AnyStr, + ClassVar, + Generic, + NamedTuple, + NoReturn, + Pattern, + Protocol, + SupportsAbs, + SupportsRound, + TypeVar, + overload, +) from typing_extensions import ParamSpec from warnings import WarningMessage @@ -63,11 +76,9 @@ def skipUnless(condition: object, reason: str) -> Callable[[_FT], _FT]: ... class SkipTest(Exception): def __init__(self, reason: str) -> None: ... -class _SupportsDunderLeWithFloat(Protocol): - def __le__(self, __other: float) -> object: ... +class _SupportsAbsAndDunderGE(SupportsDunderGE[Any], SupportsAbs[Any], Protocol): ... -class _SupportsAlmostEqualAssertions(Protocol[_T_contra]): - def __sub__(self, __other: _T_contra) -> SupportsAbs[_SupportsDunderLeWithFloat]: ... +_S = TypeVar("_S", bound=SupportsSub[Any, Any]) class TestCase: failureException: type[BaseException] @@ -173,32 +184,34 @@ class TestCase: ) -> _AssertLogsContext[None]: ... @overload - def assertAlmostEqual( - self, first: datetime, second: datetime, places: None = ..., msg: Any = ..., delta: float | None = ... - ) -> None: ... + def assertAlmostEqual(self, first: _S, second: _S, places: None, msg: Any, delta: _SupportsAbsAndDunderGE) -> None: ... @overload def assertAlmostEqual( - self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: None = ..., msg: Any = ..., delta: float | None = ... + self, first: _S, second: _S, places: None = ..., msg: Any = ..., *, delta: _SupportsAbsAndDunderGE ) -> None: ... @overload - def assertAlmostEqual(self, first: datetime, second: datetime, places: int, msg: Any = ..., delta: None = ...) -> None: ... - @overload def assertAlmostEqual( - self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: int, msg: Any = ..., delta: None = ... + self, + first: SupportsSub[_T, SupportsAbs[SupportsRound[object]]], + second: _T, + places: int | None = ..., + msg: Any = ..., + delta: None = ..., ) -> None: ... @overload - def assertNotAlmostEqual( - self, first: datetime, second: datetime, places: None = ..., msg: Any = ..., delta: float | None = ... - ) -> None: ... + def assertNotAlmostEqual(self, first: _S, second: _S, places: None, msg: Any, delta: _SupportsAbsAndDunderGE) -> None: ... @overload def assertNotAlmostEqual( - self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: None = ..., msg: Any = ..., delta: float | None = ... + self, first: _S, second: _S, places: None = ..., msg: Any = ..., *, delta: _SupportsAbsAndDunderGE ) -> None: ... @overload - def assertNotAlmostEqual(self, first: datetime, second: datetime, places: int, msg: Any = ..., delta: None = ...) -> None: ... - @overload def assertNotAlmostEqual( - self, first: _SupportsAlmostEqualAssertions[_T], second: _T, places: int, msg: Any = ..., delta: None = ... + self, + first: SupportsSub[_T, SupportsAbs[SupportsRound[object]]], + second: _T, + places: int | None = ..., + msg: Any = ..., + delta: None = ..., ) -> None: ... def assertRegex(self, text: AnyStr, expected_regex: AnyStr | Pattern[AnyStr], msg: Any = ...) -> None: ... def assertNotRegex(self, text: AnyStr, unexpected_regex: AnyStr | Pattern[AnyStr], msg: Any = ...) -> None: ... diff --git a/test_cases/stdlib/test_unittest.py b/test_cases/stdlib/test_unittest.py index 4731ecd935cf..2010c4103e06 100644 --- a/test_cases/stdlib/test_unittest.py +++ b/test_cases/stdlib/test_unittest.py @@ -1,17 +1,20 @@ # pyright: reportUnnecessaryTypeIgnoreComment=true -from datetime import datetime +import unittest +from datetime import datetime, timedelta from decimal import Decimal from fractions import Fraction -from unittest import TestCase -def test_assertAlmostEqual(case: TestCase) -> None: - case.assertAlmostEqual(2.4, 2.41) - case.assertAlmostEqual(Fraction(49, 50), Fraction(48, 50)) - case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1)) - case.assertAlmostEqual(Decimal("1.1"), Decimal("1.11")) - case.assertAlmostEqual(2.4, 2.41, places=8) - case.assertAlmostEqual(2.4, 2.41, delta=0.02) - case.assertAlmostEqual(2.4, 2.41, places=9, delta=0.02) # type: ignore[call-overload] - case.assertAlmostEqual("foo", "bar") # type: ignore[call-overload] +case = unittest.TestCase() + +case.assertAlmostEqual(2.4, 2.41) +case.assertAlmostEqual(Fraction(49, 50), Fraction(48, 50)) +case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), delta=timedelta(hours=1)) +case.assertAlmostEqual(Decimal("1.1"), Decimal("1.11")) +case.assertAlmostEqual(2.4, 2.41, places=8) +case.assertAlmostEqual(2.4, 2.41, delta=0.02) + +case.assertAlmostEqual(2.4, 2.41, places=9, delta=0.02) # type: ignore[call-overload] +case.assertAlmostEqual("foo", "bar") # type: ignore[call-overload] +case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1)) # type: ignore[arg-type] From 6ed6d96c5b5b3239efee2654b499bb6b04d38bef Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 13 Jun 2022 22:58:39 +0100 Subject: [PATCH 09/10] Fix --- stdlib/_typeshed/__init__.pyi | 22 ++++++++++------------ stdlib/unittest/case.pyi | 6 ++---- test_cases/stdlib/test_unittest.py | 11 ++++++++++- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/stdlib/_typeshed/__init__.pyi b/stdlib/_typeshed/__init__.pyi index bdaf88feb2db..162c40522224 100644 --- a/stdlib/_typeshed/__init__.pyi +++ b/stdlib/_typeshed/__init__.pyi @@ -50,23 +50,21 @@ class SupportsAnext(Protocol[_T_co]): # Comparison protocols -class SupportsDunderLT(Protocol[_T_contra]): - def __lt__(self, __other: _T_contra) -> bool: ... +class SupportsDunderLT(Protocol): + def __lt__(self, __other: Any) -> bool: ... -class SupportsDunderGT(Protocol[_T_contra]): - def __gt__(self, __other: _T_contra) -> bool: ... +class SupportsDunderGT(Protocol): + def __gt__(self, __other: Any) -> bool: ... -class SupportsDunderLE(Protocol[_T_contra]): - def __le__(self, __other: _T_contra) -> bool: ... +class SupportsDunderLE(Protocol): + def __le__(self, __other: Any) -> bool: ... -class SupportsDunderGE(Protocol[_T_contra]): - def __ge__(self, __other: _T_contra) -> bool: ... +class SupportsDunderGE(Protocol): + def __ge__(self, __other: Any) -> bool: ... -class SupportsAllComparisons( - SupportsDunderLT[Any], SupportsDunderGT[Any], SupportsDunderLE[Any], SupportsDunderGE[Any], Protocol -): ... +class SupportsAllComparisons(SupportsDunderLT, SupportsDunderGT, SupportsDunderLE, SupportsDunderGE, Protocol): ... -SupportsRichComparison: TypeAlias = SupportsDunderLT[Any] | SupportsDunderGT[Any] +SupportsRichComparison: TypeAlias = SupportsDunderLT | SupportsDunderGT SupportsRichComparisonT = TypeVar("SupportsRichComparisonT", bound=SupportsRichComparison) # noqa: Y001 # Dunder protocols diff --git a/stdlib/unittest/case.pyi b/stdlib/unittest/case.pyi index 1737ab1ef3c3..323da28f9052 100644 --- a/stdlib/unittest/case.pyi +++ b/stdlib/unittest/case.pyi @@ -27,7 +27,7 @@ if sys.version_info >= (3, 9): from types import GenericAlias _T = TypeVar("_T") -_T_contra = TypeVar("_T_contra", contravariant=True) +_S = TypeVar("_S", bound=SupportsSub[Any, Any]) _E = TypeVar("_E", bound=BaseException) _FT = TypeVar("_FT", bound=Callable[..., Any]) _P = ParamSpec("_P") @@ -76,9 +76,7 @@ def skipUnless(condition: object, reason: str) -> Callable[[_FT], _FT]: ... class SkipTest(Exception): def __init__(self, reason: str) -> None: ... -class _SupportsAbsAndDunderGE(SupportsDunderGE[Any], SupportsAbs[Any], Protocol): ... - -_S = TypeVar("_S", bound=SupportsSub[Any, Any]) +class _SupportsAbsAndDunderGE(SupportsDunderGE, SupportsAbs[Any], Protocol): ... class TestCase: failureException: type[BaseException] diff --git a/test_cases/stdlib/test_unittest.py b/test_cases/stdlib/test_unittest.py index 2010c4103e06..086a1aef6211 100644 --- a/test_cases/stdlib/test_unittest.py +++ b/test_cases/stdlib/test_unittest.py @@ -5,16 +5,25 @@ from decimal import Decimal from fractions import Fraction - case = unittest.TestCase() case.assertAlmostEqual(2.4, 2.41) case.assertAlmostEqual(Fraction(49, 50), Fraction(48, 50)) case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), delta=timedelta(hours=1)) +case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), None, "foo", timedelta(hours=1)) case.assertAlmostEqual(Decimal("1.1"), Decimal("1.11")) case.assertAlmostEqual(2.4, 2.41, places=8) case.assertAlmostEqual(2.4, 2.41, delta=0.02) +case.assertAlmostEqual(2.4, 2.41, None, "foo", 0.02) case.assertAlmostEqual(2.4, 2.41, places=9, delta=0.02) # type: ignore[call-overload] case.assertAlmostEqual("foo", "bar") # type: ignore[call-overload] case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1)) # type: ignore[arg-type] + +case.assertNotAlmostEqual(Fraction(49, 50), Fraction(48, 50)) +case.assertNotAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), delta=timedelta(hours=1)) +case.assertNotAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), None, "foo", timedelta(hours=1)) + +case.assertNotAlmostEqual(2.4, 2.41, places=9, delta=0.02) # type: ignore[call-overload] +case.assertNotAlmostEqual("foo", "bar") # type: ignore[call-overload] +case.assertNotAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1)) # type: ignore[arg-type] From 761a483707133a2fc6b0b848e811d0dab1376a19 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 13 Jun 2022 23:00:19 +0100 Subject: [PATCH 10/10] Unused import --- stdlib/unittest/case.pyi | 1 - 1 file changed, 1 deletion(-) diff --git a/stdlib/unittest/case.pyi b/stdlib/unittest/case.pyi index 323da28f9052..15b573edeebb 100644 --- a/stdlib/unittest/case.pyi +++ b/stdlib/unittest/case.pyi @@ -4,7 +4,6 @@ import unittest.result from _typeshed import Self, SupportsDunderGE, SupportsSub from collections.abc import Callable, Container, Iterable, Mapping, Sequence, Set as AbstractSet from contextlib import AbstractContextManager -from datetime import datetime from types import TracebackType from typing import ( Any,