Type annotation is still only a convenience, unfortunately, though it'd be nice to mandatory enable them by a Python interpreter flag.
However, they can be used for a static analysis with mypy or for a dynamic, runtime analysis (quite efficient for running in combination with unittesting) with ensure.
Taken from ensure
's doc:
from ensure import ensure_annotations
@ensure_annotations
def f(x: int, y: float) -> float:
return x + y
or in your DateType case:
>>> from ensure import ensure_annotations
>>> from datetime import datetime, timedelta
>>> @ensure_annotations
... def myfunc(param: datetime) -> datetime:
... return 123
...
>>> @ensure_annotations
... def mycorrectfunc(param: datetime) -> datetime:
... return param + timedelta(days=1)
...
>>> myfunc(datetime.now())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../lib/python3.8/site-packages/ensure/main.py", line 855, in __call__
raise EnsureError(msg.format(
ensure.main.EnsureError: Return value of <function myfunc at 0x7f28325d7310> of type <class 'int'> does not match annotation type <class 'datetime.datetime'>
>>> mycorrectfunc(datetime.now())
datetime.datetime(2021, 3, 15, 10, 53, 37, 888834)
>>>
and this is applicable for all other classes or type aliases (very!) roughly in a similar way typedef
or rather assert isinstance(...)
are used.