@@ -63,42 +63,43 @@ The type `Series[Timestamp]` is the result of creating a series from `pd.to_date
63
63
the type ` TimedeltaSeries ` is the result of subtracting two ` Series[Timestamp] ` as well as
64
64
the result of ` pd.to_timedelta() ` .
65
65
66
- ### Generic Series have restricted arithmetic
66
+ ### Progressive arithmetic typing for generic Series
67
67
68
68
Consider the following Series from a DataFrame:
69
69
70
70
``` python
71
71
import pandas as pd
72
72
from typing_extensions import reveal_type
73
- from typing import TYPE_CHECKING , cast
74
73
75
- if TYPE_CHECKING :
76
- from pandas.core.series import TimestampSeries # noqa: F401
77
74
78
-
79
- frame = pd.DataFrame({" timestamp" : [pd.Timestamp(2025 , 8 , 26 )], " tag" : [" one" ], " value" : [1.0 ]})
75
+ frame = pd.DataFrame({" timestamp" : [pd.Timestamp(2025 , 9 , 15 )], " tag" : [" one" ], " value" : [1.0 ]})
80
76
values = frame[" value" ]
81
77
reveal_type(values) # type checker: Series[Any], runtime: Series
82
78
new_values = values + 2
83
79
84
80
timestamps = frame[" timestamp" ]
85
- reveal_type(timestamps) # type checker: Series[Any], runtime: Series
86
- reveal_type(timestamps - pd.Timestamp(2025 , 7 , 12 )) # type checker: Unknown and error, runtime: Series
87
- reveal_type(cast(" TimestampSeries" , timestamps) - pd.Timestamp(2025 , 7 , 12 )) # type checker: TimedeltaSeries, runtime: Series
81
+ reveal_type(timestamps - pd.Timestamp(2025 , 7 , 12 )) # type checker: TimedeltaSeries, runtime: Series
88
82
89
83
tags = frame[" tag" ]
90
- reveal_type(" suffix" + tags) # type checker: Never , runtime: Series
84
+ reveal_type(" suffix" + tags) # type checker: Series[str] , runtime: Series
91
85
```
92
86
93
- Since they are taken from a DataFrame, all three of them, ` values ` , ` timestamps `
87
+ Since these Series are taken from a DataFrame, all three of them, ` values ` , ` timestamps `
94
88
and ` tags ` , are recognized by type checkers as ` Series[Any] ` . The code snippet
95
- runs fine at runtime. In the stub for type checking, however, we restrict
96
- generic Series to perform arithmetic operations only with numeric types, and
97
- give ` Series[Any] ` for the results. For ` Timedelta ` , ` Timestamp ` , ` str ` , etc.,
98
- arithmetic is restricted to ` Series[Any] ` and the result is either undefined,
99
- showing ` Unknown ` and errors, or ` Never ` . Users are encouraged to cast such
100
- generic Series to ones with concrete types, so that type checkers can provide
101
- meaningful results.
89
+ runs fine at runtime. In the stub for type checking, when there is only one
90
+ valid outcome, we provide the typing of this outcome as the result. For
91
+ example, if a ` Timestamp ` is subtracted from a ` Series[Any] ` , or a ` str `
92
+ is added to a ` Series[Any] ` , valid outcomes can only be ` TimedeltaSeries ` and
93
+ ` Series[str] ` , respectively, which will be realized when the left operands
94
+ are actually ` Series[Timestamp] ` and ` Series[str] ` , respectively.
95
+
96
+ Note that static type checkers cannot determine the contents of a ` Series[Any] `
97
+ at runtime. Users are invited to verify the results provided progressivly by the
98
+ type checkers and be warned if they are unreasonable.
99
+
100
+ When there are several possible valid outcomes of an arithmetic expression,
101
+ for example numeric types ` Series[bool] ` , ` Series[int] ` , etc., ` Series[Any] `
102
+ will be given as the resulting typing.
102
103
103
104
### Interval is Generic
104
105
0 commit comments