typeshed icon indicating copy to clipboard operation
typeshed copied to clipboard

python-dateutil: respect inheritance on relativedelta.__rsub__ (#11462)

Open MaicoTimmerman opened this issue 1 year ago • 1 comments

Support inheritance for relativedelta.__rsub__ by setting the TypeVar upper bound to datetime.date (parent of datetime.datetime), instead of having both those as constraint.

Resolved #11462

MaicoTimmerman avatar Feb 23 '24 08:02 MaicoTimmerman

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

github-actions[bot] avatar Feb 23 '24 08:02 github-actions[bot]

The reason the tests fail is that date.__sub__ has an overload def __sub__(self, __value: Self) -> timedelta: ..., which of course matches the tested line and therefore returns a timedelta. This seems consistent with the implementation of date.__sub__ in Python 3.11:

https://github.com/python/cpython/blob/0f7f5a4a6c2b9bffe973e4b36a217b5a0fbbc7bb/Lib/datetime.py#L1150-L1158

The reason it does work differently at runtime is probably that the C _datetime module handles this differently. (I haven't investigated.)

How to fix this:

  1. We should file an issue against CPython so that they can fix this discrepancy.
  2. If CPython decides to change the Python implementation to match to C implementation of the module, we should change our datetime stubs accordingly.

I'm marking this PR as deferred for now.

srittau avatar Feb 26 '24 14:02 srittau

C implementation here: https://github.com/python/cpython/blob/015b97d19a24a169cc3c0939119e1228791e4253/Modules/_datetimemodule.c#L3220-L3245

srittau avatar Feb 26 '24 14:02 srittau

Please ignore my comments about date.__sub__. The stubs, the C, and Python implementation all override it in datetime.__sub__. Our stubs shouldn't match:

class datetime(date):
    # ...
    @overload  # type: ignore[override]
    def __sub__(self, __value: Self) -> timedelta: ...
    @overload
    def __sub__(self, __value: timedelta) -> Self: ...

srittau avatar Feb 26 '24 14:02 srittau

The reason the tests fail is that date.sub has an overload def sub(self, __value: Self) -> timedelta: ..., which of course matches the tested line and therefore returns a timedelta.

~~__value: Self would match if the RHS is a (subclass of) date, right? But in this case it's dateutil.relativedelta.relativedelta(days=1), which doesn't match. So I think there is some other reason here.~~

Oddly enough, I wasn't able to reproduce the issue locally using pyright==1.1.342 yet.

edit: just saw your newly added comment.

MaicoTimmerman avatar Feb 26 '24 14:02 MaicoTimmerman

I'm not sure what's going on. Maybe @erictraut has an idea as it seems that only pyright fails while mypy accepts the tests.

srittau avatar Feb 26 '24 14:02 srittau

I'm not able to repro this issue with the latest version of pyright (1.1.351). To try to repro, I manually applied the change in relativedelta.pyi and then verified that the test code in this PR passes without any type errors.

I also tried to repro it with 1.1.342, which is the version of pyright that typeshed is currently pinned to. So I'm not sure what's happening here.

erictraut avatar Feb 26 '24 20:02 erictraut

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

github-actions[bot] avatar Feb 26 '24 21:02 github-actions[bot]

@srittau anything I can do to push this forward? The failures persist with the re-run. It almost seems like the test is running without the updated stubs? That was exactly the case I'm trying to fix in this MR.

MaicoTimmerman avatar Mar 01 '24 11:03 MaicoTimmerman

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

github-actions[bot] avatar Mar 01 '24 11:03 github-actions[bot]

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

github-actions[bot] avatar Mar 15 '24 14:03 github-actions[bot]

I'm still stumped what the problem here is. I have the same results as @erictraut when testing this PR locally. It really behaves as if the changes to the python-dateutil stubs were ignored.

srittau avatar Mar 15 '24 15:03 srittau

Here's what I'm going to do: Comment out the offending line in the test cases and merge this PR if the tests pass. Then I'm going to open another PR restoring the line in the tests. If these pass, it will confirm the suspicion that the current stubs are not picked up.

srittau avatar Mar 15 '24 15:03 srittau

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

github-actions[bot] avatar Mar 15 '24 15:03 github-actions[bot]

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

github-actions[bot] avatar Mar 15 '24 15:03 github-actions[bot]