From 665866067367fd98d1a65df8f2decc1a037c4c30 Mon Sep 17 00:00:00 2001 From: Irv Lustig Date: Wed, 2 Aug 2023 08:25:13 -0400 Subject: [PATCH 1/6] make sub of timedelta work --- pandas-stubs/core/series.pyi | 10 ++++++++++ tests/test_timefuncs.py | 9 ++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 9a40582b5..c05e74237 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -1533,6 +1533,16 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]): @overload def __rxor__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... # type: ignore[misc] @overload + def __sub__( + self: Series[Timestamp], + other: Timedelta | TimedeltaSeries | TimedeltaIndex | np.timedelta64, + ) -> TimestampSeries: ... + @overload + def __sub__( + self: Series[Timedelta], + other: Timedelta | TimedeltaSeries | TimedeltaIndex | np.timedelta64, + ) -> TimedeltaSeries: ... + @overload def __sub__( self, other: Timestamp | datetime | TimestampSeries ) -> TimedeltaSeries: ... diff --git a/tests/test_timefuncs.py b/tests/test_timefuncs.py index ed1a0eab8..6b045950c 100644 --- a/tests/test_timefuncs.py +++ b/tests/test_timefuncs.py @@ -1130,7 +1130,14 @@ def test_timedelta64_and_arithmatic_operator() -> None: s1 = pd.Series(data=pd.date_range("1/1/2020", "2/1/2020")) s2 = pd.Series(data=pd.date_range("1/1/2021", "2/1/2021")) s3 = s2 - s1 - # https://github.com/pandas-dev/pandas/issues/54059 needs to be fixed + check(assert_type(s3, "TimedeltaSeries"), pd.Series, pd.Timedelta) + td1 = pd.Timedelta(1, "D") + check(assert_type(s2 - td1, "TimestampSeries"), pd.Series, pd.Timestamp) + # GH 758 + s4 = s1.astype(object) + check(assert_type(s4 - td1, "TimestampSeries"), pd.Series, pd.Timestamp) + + # https://github.com/pandas-dev/pandas/issues/54059 says this is invalid if PD_LTE_20: td = np.timedelta64(1, "M") check(assert_type((s1 - td), "TimestampSeries"), pd.Series, pd.Timestamp) From 5a724bfe1f453e4b99e1293a1dd1ed0fc65bb0b9 Mon Sep 17 00:00:00 2001 From: Irv Lustig Date: Wed, 2 Aug 2023 09:31:27 -0400 Subject: [PATCH 2/6] fix issues due to pyright 1.1.320 --- pyproject.toml | 1 + tests/test_indexes.py | 11 ++++++++++- tests/test_pandas.py | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c4d577a94..717e9a13d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -197,6 +197,7 @@ reportPrivateUsage = false # enable optional checks reportMissingModuleSource = true useLibraryCodeForTypes = false +defineConstant = { MYPY_CHECKING = false } [tool.codespell] ignore-words-list = "indext, mose, sav, ser" diff --git a/tests/test_indexes.py b/tests/test_indexes.py index fa4557600..be6a7c4ce 100644 --- a/tests/test_indexes.py +++ b/tests/test_indexes.py @@ -24,6 +24,15 @@ ) if TYPE_CHECKING: + MYPY_CHECKING: bool = True + if MYPY_CHECKING: + from typing import Any + + from typing_extensions import TypeAlias + + SupportsRichComparison: TypeAlias = Any + else: + from _typeshed import SupportsRichComparison from pandas.core.indexes.base import ( _ComplexIndexType, _FloatIndexType, @@ -722,7 +731,7 @@ def test_sorted_and_list() -> None: check( assert_type( sorted(i1), - list, + list["SupportsRichComparison"], ), list, ) diff --git a/tests/test_pandas.py b/tests/test_pandas.py index 3d1426223..401fc1aa1 100644 --- a/tests/test_pandas.py +++ b/tests/test_pandas.py @@ -1272,7 +1272,7 @@ def test_merge_ordered() -> None: ) pd.merge_ordered( # type: ignore[call-overload] ls, - rf, # pyright: ignore[reportGeneralTypeIssues] + rf, left_on="left", right_on="b", left_by="left", # pyright: ignore[reportGeneralTypeIssues] From 375fe8260a7c20453f0fd82e996b2c82795175dd Mon Sep 17 00:00:00 2001 From: Irv Lustig Date: Wed, 2 Aug 2023 09:36:21 -0400 Subject: [PATCH 3/6] fix for older python with list subscript --- tests/test_indexes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_indexes.py b/tests/test_indexes.py index be6a7c4ce..972657a5c 100644 --- a/tests/test_indexes.py +++ b/tests/test_indexes.py @@ -32,7 +32,7 @@ SupportsRichComparison: TypeAlias = Any else: - from _typeshed import SupportsRichComparison + pass from pandas.core.indexes.base import ( _ComplexIndexType, _FloatIndexType, @@ -731,7 +731,7 @@ def test_sorted_and_list() -> None: check( assert_type( sorted(i1), - list["SupportsRichComparison"], + "list[SupportsRichComparison]", ), list, ) From 7595c3653116818978b6db650ea48fa64dde4f9b Mon Sep 17 00:00:00 2001 From: Irv Lustig Date: Wed, 2 Aug 2023 09:47:07 -0400 Subject: [PATCH 4/6] change order of test so ruff does not remove import from typeshed --- tests/test_indexes.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_indexes.py b/tests/test_indexes.py index 972657a5c..514bf6782 100644 --- a/tests/test_indexes.py +++ b/tests/test_indexes.py @@ -25,14 +25,15 @@ if TYPE_CHECKING: MYPY_CHECKING: bool = True - if MYPY_CHECKING: + if not MYPY_CHECKING: + from _typeshed import SupportsRichComparison + else: from typing import Any from typing_extensions import TypeAlias SupportsRichComparison: TypeAlias = Any - else: - pass + from pandas.core.indexes.base import ( _ComplexIndexType, _FloatIndexType, From 53e221362fcc8ed21d3fc149aa775f917e612f3e Mon Sep 17 00:00:00 2001 From: Irv Lustig Date: Wed, 2 Aug 2023 09:52:49 -0400 Subject: [PATCH 5/6] get ruff to ignore a line --- tests/test_indexes.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test_indexes.py b/tests/test_indexes.py index 514bf6782..82d0ab6a5 100644 --- a/tests/test_indexes.py +++ b/tests/test_indexes.py @@ -25,15 +25,14 @@ if TYPE_CHECKING: MYPY_CHECKING: bool = True - if not MYPY_CHECKING: - from _typeshed import SupportsRichComparison - else: + if MYPY_CHECKING: from typing import Any from typing_extensions import TypeAlias SupportsRichComparison: TypeAlias = Any - + else: + from _typeshed import SupportsRichComparison # noqa: F401 from pandas.core.indexes.base import ( _ComplexIndexType, _FloatIndexType, From 5310eb682334877ae00a06b80082fc80f7467aee Mon Sep 17 00:00:00 2001 From: Irv Lustig Date: Wed, 2 Aug 2023 10:32:43 -0400 Subject: [PATCH 6/6] add comments about why testing is special for mypy vs pyright --- tests/test_indexes.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_indexes.py b/tests/test_indexes.py index 82d0ab6a5..a089e9677 100644 --- a/tests/test_indexes.py +++ b/tests/test_indexes.py @@ -25,6 +25,8 @@ if TYPE_CHECKING: MYPY_CHECKING: bool = True + # See test_sorted_and_list() where mypy and pyright do different + # inference on sorted(pd.Index) if MYPY_CHECKING: from typing import Any @@ -728,6 +730,8 @@ def test_interval_index_tuples(): def test_sorted_and_list() -> None: # GH 497 i1 = pd.Index([3, 2, 1]) + # mypy infers sorted(i1) as list[Any], while pyright infers sorted(i1) as + # list[SupportsRichComparison] check( assert_type( sorted(i1),