Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timestamp -> datetime and Timedelta -> timedelta #841

Merged
merged 5 commits into from
Dec 26, 2023

Conversation

twoertwein
Copy link
Member

Could probably benefit by adding tests where the arguments became wider.

Copy link
Collaborator

@Dr-Irv Dr-Irv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had a discussion in #341 (comment) where we preferred redundancy for documentation purposes. So I think it would be better to have timedelta | Timedelta rather than timedelta and datetime | Timestamp instead of datetime.

The other thing I'm concerned about is that with this change we have widened all the accepted types for many methods, and we don't have tests to see if the wider types are accepted. For example, maybe there is some method that accepts pd.Timedelta, but not datetime.timedelta. But that would be a lot of work to duplicate all the tests we have that use pd.Timedelta and pd.Timestamp as arguments and see if they work with datetime.timedelta and datetime.datetime as well.

Open to discussion on both of these points.

Copy link
Collaborator

@Dr-Irv Dr-Irv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whenever I said "put back Timedelta", etc., I mean to include make it where it reads Timedelta | dt.timedelta (in case that wasn't clear)

@@ -210,7 +210,7 @@ class Timedelta(timedelta):
@overload
def __rsub__(self, other: timedelta | Timedelta | np.timedelta64) -> Timedelta: ...
@overload
def __rsub__(self, other: Timestamp | np.datetime64) -> Timestamp: ...
def __rsub__(self, other: dt.datetime | np.datetime64) -> Timestamp: ... # type: ignore[misc]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put back Timestamp

Comment on lines 102 to 103
@classmethod
def fromtimestamp(cls, t: float, tz: _tzinfo | str | None = ...) -> Self: ...
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to rebase against main

@@ -1941,7 +1940,7 @@ class DataFrame(NDFrame, OpsMixin):
level: Level | None = ...,
origin: Timestamp
| Literal["epoch", "start", "start_day", "end", "end_day"] = ...,
offset: Timedelta | _str | None = ...,
offset: dt.timedelta | _str | None = ...,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put back Timedelta

@@ -166,21 +169,21 @@ class _DatetimeRoundingMethods(Generic[_DTRoundingMethodReturnType]):
freq: str | BaseOffset | None,
ambiguous: Literal["raise", "infer", "NaT"] | np_ndarray_bool = ...,
nonexistent: Literal["shift_forward", "shift_backward", "NaT", "raise"]
| Timedelta = ...,
| timedelta = ...,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put back Timedelta

) -> _DTRoundingMethodReturnType: ...
def floor(
self,
freq: str | BaseOffset | None,
ambiguous: Literal["raise", "infer", "NaT"] | np_ndarray_bool = ...,
nonexistent: Literal["shift_forward", "shift_backward", "NaT", "raise"]
| Timedelta = ...,
| timedelta = ...,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put back Timedelta

@@ -1485,7 +1485,7 @@ class Series(IndexOpsMixin[S1], NDFrame):
) -> Series[_bool]: ...
@overload
def __mul__(
self, other: Timedelta | TimedeltaSeries | np.timedelta64
self, other: timedelta | TimedeltaSeries | np.timedelta64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put back Timedelta

@@ -2043,18 +2043,18 @@ class TimedeltaSeries(Series[Timedelta]):
def __add__(self, other: Period) -> PeriodSeries: ...
@overload
def __add__(
self, other: Timestamp | TimestampSeries | DatetimeIndex
self, other: datetime | TimestampSeries | DatetimeIndex
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put back Timestamp

) -> TimestampSeries: ...
@overload
def __add__( # pyright: ignore[reportIncompatibleMethodOverride]
self, other: Timedelta | np.timedelta64
self, other: timedelta | np.timedelta64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put back Timedelta

) -> TimedeltaSeries: ...
def __radd__(self, other: Timestamp | TimestampSeries) -> TimestampSeries: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
def __radd__(self, other: datetime | TimestampSeries) -> TimestampSeries: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put back Timestamp

def __mul__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
self, other: num | Sequence[num] | Series[int] | Series[float]
) -> TimedeltaSeries: ...
def __sub__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
self, other: Timedelta | TimedeltaSeries | TimedeltaIndex | np.timedelta64
self, other: timedelta | TimedeltaSeries | TimedeltaIndex | np.timedelta64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put back Timedelta

@twoertwein
Copy link
Member Author

I'm working on the test and re-adding the redundancy. I might have a few intermediate commits.

About the redundancy: I personally would not add them as it is inconsistent with the best practices of int | float | complex, it is unnecessarily complex/verbose, and it might even be misleading as it implies that they are not sub-classes.

@Dr-Irv
Copy link
Collaborator

Dr-Irv commented Dec 26, 2023

I'm working on the test and re-adding the redundancy. I might have a few intermediate commits.

OK - ping me when I should review it next.

About the redundancy: I personally would not add them as it is inconsistent with the best practices of int | float | complex, it is unnecessarily complex/verbose, and it might even be misleading as it implies that they are not sub-classes.

We debated this before. See the discussion at #341 (comment)

Another possibility is to define some internal types for typing purposes:

TimedeltaArg: TypeAlias = pd.Timedelta | datetime.timedelta | np.timedelta64
TimestampArg: TypeAlias = pd.Timestamp | datetime.datetime | np.datetime64

Then use them as arguments throughout. To avoid any issue with regards to subclass confusion, we could put comments above those aliases to indicate why we document it that way.

@twoertwein
Copy link
Member Author

TimedeltaArg: TypeAlias = pd.Timedelta | datetime.timedelta | np.timedelta64
TimestampArg: TypeAlias = pd.Timestamp | datetime.datetime | np.datetime64

I like this idea (but not for this PR), assuming that the numpy types are accepted everywhere (I'm not sure - I believe they are not actual sub-classes)

@twoertwein
Copy link
Member Author

I think I added all the test and all the redundant unions

Copy link
Collaborator

@Dr-Irv Dr-Irv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @twoertwein . Not sure if we caught all the tests, but this will do for now.

@Dr-Irv
Copy link
Collaborator

Dr-Irv commented Dec 26, 2023

I like this idea (but not for this PR), assuming that the numpy types are accepted everywhere (I'm not sure - I believe they are not actual sub-classes)

Yes, that is the part I'm not sure about either.

@Dr-Irv Dr-Irv merged commit 52384d3 into pandas-dev:main Dec 26, 2023
13 checks passed
@twoertwein twoertwein deleted the time branch February 10, 2024 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BUG: Type stubs only support pd.Timedelta, but could (should?) also support datetime.timedelta
2 participants