I recently ran into a weird bug at work, and after some work managed to reduce it to the following code (note the PEP 563 “stringized” annotations):
from __future__ import annotations
from typing import get_type_hints
import sys
FIND_ME = 42
def function():
return FIND_ME
class Example:
my_function: function
my_lambda: lambda: FIND_ME
hints = get_type_hints(
Example,
# globalns=sys.modules[Example.__module__].__dict__,
# localns=dict(vars(Example)),
)
hints['my_function']() # Succeeds
hints['my_lambda']() # Fails
When I run it, calling the regular function from the annotations works as expected, but calling the lambda fails with NameError: name ‘FIND_ME’ is not defined.
However, if I pass in globalns or localns as shown in the commented out lines, both calls work as expected. This has me confused because the typing.get_type_hints() documentation states:
If globalns or localns is not given, appropriate namespace dictionaries are inferred from obj.
And as far as I can tell, those commented out lines are the exact logic typing.get_type_hints() uses to infer the namespace dictionaries.
Can you help me understand what I’m missing here?
Thanks!