Although variable current_timestamp
(and thus also the function return value) and variable time
are datetime.datetime
class objects, the following code raises AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
from datetime import datetime
def current_time() -> datetime.datetime:
current_timestamp: datetime.datetime = datetime.now()
return current_timestamp
time: datetime.datetime = current_time()
print(time)
Changing only the annotation for the function return value and the time
variable solves the problem.
from datetime import datetime
def current_time() -> datetime:
current_timestamp: datetime.datetime = datetime.now()
return current_timestamp
time: datetime = current_time()
print(time)
Can anyone explain why the annotation datetime.datetime
raises only an AttributeError for the function return value and the time
variable, but not for the current_timestamp
variable?
I am running Python 3.8.
From PEP 526, where this syntax is defined
Annotating a local variable will cause the interpreter to treat it as a local, even if it was never assigned to. Annotations for local variables will not be evaluated:
def f(): x: NonexistentName # No error.
However, if it is at a module or class level, then the type will be evaluated:
x: NonexistentName # Error! class X: var: NonexistentName # Error!
In addition, at the module or class level, if the item being annotated is a simple name, then it and the annotation will be stored in the
__annotations__
attribute of that module or class (mangled if private) as an ordered mapping from names to evaluated annotations.
So the reason is that annotations are meant to be a general-purpose tool, leaving open the possibility of using them for things other than type signatures. At the module or class level, you can get access to this information at runtime using reflection techniques, so the value has to exist and will be evaluated. When applied to a local variable, however, no reflection is available on local variables so the annotation is only useful to third-party tools parsing the code, hence Python itself has no reason to evaluate it.
It's worth noting that mypy
will fail on the second example, and if you want to use an actual type checker you will have to correct the annotation in every place.
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