import types
from test import mod_generics_cache
+from test import _typed_dict_helper
class BaseTestCase(TestCase):
x: int
y: int
+class Bar(_typed_dict_helper.Foo, total=False):
+ b: int
+
class LabelPoint2D(Point2D, Label): ...
class Options(TypedDict, total=False):
# classes, not instances
assert is_typeddict(Point2D()) is False
+ def test_get_type_hints(self):
+ self.assertEqual(
+ get_type_hints(Bar),
+ {'a': typing.Optional[int], 'b': int}
+ )
+
class IOTests(BaseTestCase):
# legitimate imports of those modules.
-def _type_convert(arg):
+def _type_convert(arg, module=None):
"""For converting None to type(None), and strings to ForwardRef."""
if arg is None:
return type(None)
if isinstance(arg, str):
- return ForwardRef(arg)
+ return ForwardRef(arg, module=module)
return arg
-def _type_check(arg, msg, is_argument=True):
+def _type_check(arg, msg, is_argument=True, module=None):
"""Check that the argument is a type, and return it (internal helper).
As a special case, accept None and return type(None) instead. Also wrap strings
if is_argument:
invalid_generic_forms = invalid_generic_forms + (ClassVar, Final)
- arg = _type_convert(arg)
+ arg = _type_convert(arg, module=module)
if (isinstance(arg, _GenericAlias) and
arg.__origin__ in invalid_generic_forms):
raise TypeError(f"{arg} is not valid as type argument")
__slots__ = ('__forward_arg__', '__forward_code__',
'__forward_evaluated__', '__forward_value__',
- '__forward_is_argument__')
+ '__forward_is_argument__', '__forward_module__')
- def __init__(self, arg, is_argument=True):
+ def __init__(self, arg, is_argument=True, module=None):
if not isinstance(arg, str):
raise TypeError(f"Forward reference must be a string -- got {arg!r}")
try:
self.__forward_evaluated__ = False
self.__forward_value__ = None
self.__forward_is_argument__ = is_argument
+ self.__forward_module__ = module
def _evaluate(self, globalns, localns, recursive_guard):
if self.__forward_arg__ in recursive_guard:
globalns = localns
elif localns is None:
localns = globalns
+ if self.__forward_module__ is not None:
+ globalns = getattr(
+ sys.modules.get(self.__forward_module__, None), '__dict__', globalns
+ )
type_ =_type_check(
eval(self.__forward_code__, globalns, localns),
"Forward references must evaluate to types.",
own_annotation_keys = set(own_annotations.keys())
msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
own_annotations = {
- n: _type_check(tp, msg) for n, tp in own_annotations.items()
+ n: _type_check(tp, msg, module=tp_dict.__module__)
+ for n, tp in own_annotations.items()
}
required_keys = set()
optional_keys = set()