Skip to content

Commit 4bf4f90

Browse files
committed
Improve testing for TypedDict
1 parent a42bd4f commit 4bf4f90

File tree

4 files changed

+48
-5
lines changed

4 files changed

+48
-5
lines changed

atest/lib_future_annotation.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from __future__ import annotations
2+
3+
from typing_extensions import TypedDict
4+
5+
from robotlibcore import DynamicCore, keyword
6+
7+
8+
class Location(TypedDict):
9+
longitude: float
10+
latitude: float
11+
12+
13+
class lib_future_annotation(DynamicCore):
14+
15+
def __init__(self) -> None:
16+
DynamicCore.__init__(self, [])
17+
18+
@keyword
19+
def future_annotations(self, arg: Location):
20+
longitude = arg["longitude"]
21+
latitude = arg["latitude"]
22+
return f'{longitude} type({type(longitude)}), {latitude} {type(latitude)}'

requirements-dev.txt

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ wheel
1111
rellu >= 0.7
1212
twine
1313
wheel
14+
typing-extensions >= 4.5.0

src/robotlibcore.py

+13-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import inspect
2222
import os
2323
from dataclasses import dataclass
24-
from typing import Any, Callable, List, Optional, Union, get_type_hints
24+
from typing import Any, Callable, List, Optional, Union, get_type_hints, ForwardRef
2525

2626
from robot.api.deco import keyword # noqa: F401
2727
from robot.errors import DataError
@@ -223,6 +223,17 @@ def _get_arguments(cls, function):
223223
def _get_arg_spec(cls, function: Callable) -> inspect.FullArgSpec:
224224
return inspect.getfullargspec(function)
225225

226+
@classmethod
227+
def _get_type_hint(cls, function: Callable):
228+
try:
229+
hints = get_type_hints(function)
230+
except Exception: # noqa: BLE001
231+
hints = function.__annotations__
232+
for arg, hint in hints.items():
233+
if isinstance(hint, ForwardRef):
234+
hint = hint.__forward_arg__
235+
return hints
236+
226237
@classmethod
227238
def _get_args(cls, arg_spec: inspect.FullArgSpec, function: Callable) -> list:
228239
args = cls._drop_self_from_args(function, arg_spec)
@@ -279,10 +290,7 @@ def _get_types(cls, function):
279290
@classmethod
280291
def _get_typing_hints(cls, function):
281292
function = cls.unwrap(function)
282-
try:
283-
hints = get_type_hints(function)
284-
except Exception: # noqa: BLE001
285-
hints = function.__annotations__
293+
hints = cls._get_type_hint(function)
286294
arg_spec = cls._get_arg_spec(function)
287295
all_args = cls._args_as_list(function, arg_spec)
288296
for arg_with_hint in list(hints):

utest/test_get_keyword_types.py

+12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import pytest
55
from DynamicTypesAnnotationsLibrary import CustomObject, DynamicTypesAnnotationsLibrary
66
from DynamicTypesLibrary import DynamicTypesLibrary
7+
from lib_future_annotation import lib_future_annotation, Location
78

89

910
@pytest.fixture(scope="module")
@@ -16,6 +17,11 @@ def lib_types():
1617
return DynamicTypesAnnotationsLibrary("aaa")
1718

1819

20+
@pytest.fixture(scope="module")
21+
def lib_annotation():
22+
return lib_future_annotation()
23+
24+
1925
def test_using_keyword_types(lib):
2026
types = lib.get_keyword_types("keyword_with_types")
2127
assert types == {"arg1": str}
@@ -204,3 +210,9 @@ def test_kw_with_many_named_arguments_with_default(lib_types: DynamicTypesAnnota
204210
assert types == {"arg1": int, "arg2": str}
205211
types = lib_types.get_keyword_types("kw_with_positional_and_named_arguments")
206212
assert types == {"arg2": int}
213+
214+
215+
def test_lib_annotations(lib_annotation: lib_future_annotation):
216+
types = lib_annotation.get_keyword_types("future_annotations")
217+
expected = {"arg1": Location}
218+
assert types == expected

0 commit comments

Comments
 (0)