in tfx/dsl/component/experimental/json_compat.py [0:0]
def check_strict_json_compat(
in_type: Any, expect_type: Type) -> bool: # pylint: disable=g-bare-generic
"""Check if in_type conforms with expect_type.
Args:
in_type: Input type hint. It can be any JSON-compatible type. It can also be
an instance.
expect_type: Expected type hint. It can be any JSON-compatible type.
Returns:
True if in_type is valid w.r.t. expect_type.
"""
check_instance = False
if getattr(in_type, '__module__', None) not in {'typing', 'builtins'}:
check_instance = True
def _check(in_type: Any, expect_type: Type) -> bool: # pylint: disable=g-bare-generic
"""Check if in_type conforms with expect_type."""
if in_type is Any:
return expect_type is Any
elif expect_type is Any:
return True
in_obj = None
if check_instance:
in_obj, in_type = in_type, type(in_type)
in_args = getattr(in_type, '__args__', ())
in_origin = getattr(in_type, '__origin__', in_type)
expect_args = getattr(expect_type, '__args__', ())
expect_origin = getattr(expect_type, '__origin__', expect_type)
if in_origin is Union:
return all(_check(arg, expect_type) for arg in in_args)
if expect_origin is Union:
if check_instance:
return any(_check(in_obj, arg) for arg in expect_args)
else:
return any(_check(in_type, arg) for arg in expect_args)
if in_origin != expect_origin:
return False
elif in_origin in (
dict, list
) and expect_args and expect_args[0].__class__.__name__ == 'TypeVar':
return True
elif check_instance:
if isinstance(in_obj, list):
return not expect_args or all(
[_check(o, expect_args[0]) for o in in_obj])
elif isinstance(in_obj, dict):
return not expect_args or (
all(_check(k, expect_args[0]) for k in in_obj.keys()) and
all(_check(v, expect_args[1]) for v in in_obj.values()))
else:
return True
# For List -> List[X] and Dict -> Dict[X, Y].
elif len(in_args) < len(expect_args):
return False
# For Python 3.7, where Dict and List have args KT, KV, T. Return True
# whenever the expect type is Dict or List.
else:
return all(_check(*arg) for arg in zip(in_args, expect_args))
return _check(in_type, expect_type)