Let's say I have this function:
def subtract_dates(date1: datetime.date, date2: datetime.date):
return date1 - date2
If I try to call subtract_dates(datetime.date.today(), datetime.datetime.now()) this will raise a TypeError because I'm trying to subtract a datetime object from a date object.
However, because datetime inherits from date (see for instance this issue), MyPy does not raise an error on the above call to subtract_dates.
Is there a way to add a MyPy type hint that allows a date object but not a datetime object?
I'd solve it by function overloading. Example:
import datetime
from typing import NoReturn, overload
@overload
def subtract_dates(date1: datetime.date, date2: datetime.datetime) -> NoReturn: ...
@overload
def subtract_dates(date1: datetime.datetime, date2: datetime.date) -> NoReturn: ...
@overload
def subtract_dates(date1: datetime.date, date2: datetime.date) -> datetime.timedelta: ...
# this is your original function implementation
def subtract_dates(date1: datetime.date, date2: datetime.date):
return date1 - date2
Now, subtracting dates is still allowed, while using datetime objects will be caught:
subtract_dates(datetime.date.today(), datetime.datetime.now()).days
will give you an error
<string>:1: error: "NoReturn" has no attribute "days"
Found 1 error in 1 file (checked 1 source file)
The only way to really do this definitively is to recreate all the stubs for datetime in such a way that it pretends not to be a subclass of date. This is really tedious though.
That's why I did it for you and put it into an open source library.
You can see some examples of how to use it here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With