Skip to content

Commit

Permalink
Fixed issue with Any, empty Dict/List and None in `callback_t…
Browse files Browse the repository at this point in the history
…ypecheck` (#639)
  • Loading branch information
rubenthoms authored Oct 5, 2022
1 parent 940a089 commit 77a82b2
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 8 deletions.
28 changes: 27 additions & 1 deletion tests/test_callback_typecheck.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, List, Optional, TypedDict, Union
from typing import Any, Dict, List, Optional, TypedDict, Union
from enum import Enum
from webviz_config.utils import callback_typecheck, ConversionError

Expand Down Expand Up @@ -168,3 +168,29 @@ def expect_union_string_list(
assert callback_typecheck(expect_union_string_list)({"1": "1"}) == {"1": "1"}
assert callback_typecheck(expect_union_string_list)(None) is None
assert callback_typecheck(expect_union_string_list)(1) == 1

############################################################

def expect_optional_dict(arg: Optional[Dict[str, str]]) -> Optional[Dict[str, str]]:
return arg

assert callback_typecheck(expect_optional_dict)({"1": "1"}) == {"1": "1"}
assert callback_typecheck(expect_optional_dict)(None) is None

############################################################

def expect_optional_dict_without_types(arg: Optional[Dict]) -> Optional[Dict]:
return arg

assert callback_typecheck(expect_optional_dict_without_types)({"1": "1"}) == {
"1": "1"
}
assert callback_typecheck(expect_optional_dict_without_types)(None) is None

############################################################

def expect_optional_dict_with_any(arg: Optional[Dict[Any, Any]]) -> Optional[dict]:
return arg

assert callback_typecheck(expect_optional_dict_with_any)({"1": "1"}) == {"1": "1"}
assert callback_typecheck(expect_optional_dict_with_any)(None) is None
21 changes: 14 additions & 7 deletions webviz_config/utils/_callback_typecheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ class ConversionError(Exception):


def _isinstance(arg: Any, annotation: Any) -> bool:
# pylint: disable=too-many-return-statements
if annotation is None:
# pylint: disable=too-many-return-statements, too-many-branches
if annotation is type(None) or annotation is None:
return arg is None

if annotation is Any:
return True

if get_origin(annotation) is None:
try:
return isinstance(arg, annotation)
Expand All @@ -27,15 +30,19 @@ def _isinstance(arg: Any, annotation: Any) -> bool:

if get_origin(annotation) is list and isinstance(arg, list):
result = True
for annotation_arg in arg:
result &= _isinstance(annotation_arg, get_args(annotation)[0])
type_args = get_args(annotation)
if len(type_args) == 1:
for annotation_arg in arg:
result &= _isinstance(annotation_arg, type_args[0])
return result

if get_origin(annotation) is dict and isinstance(arg, dict):
result = True
for key, value in arg.items():
result &= _isinstance(key, get_args(annotation)[0])
result &= _isinstance(value, get_args(annotation)[1])
type_args = get_args(annotation)
if len(type_args) == 2:
for key, value in arg.items():
result &= _isinstance(key, type_args[0])
result &= _isinstance(value, type_args[1])
return result

return False
Expand Down

0 comments on commit 77a82b2

Please sign in to comment.