typeshed
typeshed copied to clipboard
python-dateutil: respect inheritance on relativedelta.__rsub__ (#11462)
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
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉
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:
- We should file an issue against CPython so that they can fix this discrepancy.
- 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.
C implementation here: https://github.com/python/cpython/blob/015b97d19a24a169cc3c0939119e1228791e4253/Modules/_datetimemodule.c#L3220-L3245
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: ...
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.
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.
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.
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉
@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.
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉
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.
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.
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉