Skip to content

Commit

Permalink
Argument conversion: Accept dicts matching TypedDicts as-is
Browse files Browse the repository at this point in the history
Fixes #5114.
  • Loading branch information
pekkaklarck committed Apr 21, 2024
1 parent fb099c9 commit ede9ccd
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 1 deletion.
3 changes: 3 additions & 0 deletions atest/robot/keywords/type_conversion/unions.robot
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ Union with subscripted generics and str
Union with TypedDict
Check Test Case ${TESTNAME}

Union with str and TypedDict
Check Test Case ${TESTNAME}

Union with item not liking isinstance
Check Test Case ${TESTNAME}

Expand Down
4 changes: 4 additions & 0 deletions atest/testdata/keywords/type_conversion/unions.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ def union_with_typeddict(argument: Union[XD, None], expected):
assert argument == eval(expected), '%r != %s' % (argument, expected)


def union_with_str_and_typeddict(argument: Union[str, XD], expected):
assert argument == eval(expected), '%r != %s' % (argument, expected)


def union_with_item_not_liking_isinstance(argument: Union[BadRational, int], expected):
assert argument == expected, '%r != %r' % (argument, expected)

Expand Down
7 changes: 7 additions & 0 deletions atest/testdata/keywords/type_conversion/unions.robot
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ Union with TypedDict
NONE None
${NONE} None

Union with str and TypedDict
[Template] Union with str and TypedDict
{'x': 1} "{'x': 1}"
${{{'x': 1}}} {'x': 1}
${{{'bad': 1}}} "{'bad': 1}"
${{{'x': '1'}}} "{'x': '1'}"

Union with item not liking isinstance
[Template] Union with item not liking isinstance
42 ${42}
Expand Down
12 changes: 11 additions & 1 deletion src/robot/running/arguments/typeconverters.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,17 @@ def handles(cls, type_info: 'TypeInfo') -> bool:
return type_info.is_typed_dict

def no_conversion_needed(self, value):
return False
if not isinstance(value, dict):
return False
for key in value:
try:
converter = self.converters[key]
except KeyError:
return False
else:
if not converter.no_conversion_needed(value[key]):
return False
return set(value).issuperset(self.type_info.required)

def _non_string_convert(self, value):
return self._convert_items(value)
Expand Down

0 comments on commit ede9ccd

Please sign in to comment.