11from inspect import isclass
2+ from unittest .mock import Mock , MagicMock
23
34try :
4- from types import UnionType # type: ignore[attr-defined]
5+ from types import UnionType # type: ignore[attr-defined, unused-ignore ]
56except ImportError : # pragma: no cover
6- from typing import Union as UnionType # type: ignore[assignment]
7+ from typing import Union as UnionType # type: ignore[assignment, unused-ignore ]
78
89try :
9- from typing import TypeIs # type: ignore[attr-defined]
10+ from typing import TypeIs # type: ignore[attr-defined, unused-ignore ]
1011except ImportError : # pragma: no cover
1112 from typing_extensions import TypeIs
1213
1516from simtypes .typing import ExpectedType
1617
1718
18- def check (value : Any , type : Type [ExpectedType ], strict : bool = False , lists_are_tuples : bool = False ) -> TypeIs [ExpectedType ]:
19- if type is Any : # type: ignore[attr-defined ]
19+ def check (value : Any , type_hint : Type [ExpectedType ], strict : bool = False , lists_are_tuples : bool = False , pass_mocks : bool = True ) -> TypeIs [ExpectedType ]:
20+ if type_hint is Any : # type: ignore[comparison-overlap ]
2021 return True
2122
22- elif type is None :
23+ elif (isinstance (value , Mock ) or isinstance (value , MagicMock )) and pass_mocks :
24+ return True
25+
26+ elif type_hint is None :
2327 return value is None
2428
25- origin_type = get_origin (type )
29+ origin_type = get_origin (type_hint )
2630
2731 if origin_type is Union or origin_type is UnionType :
28- return any (check (value , argument , strict = strict , lists_are_tuples = lists_are_tuples ) for argument in get_args (type ))
32+ return any (check (value , argument , strict = strict , lists_are_tuples = lists_are_tuples ) for argument in get_args (type_hint ))
2933
3034 elif origin_type is list and strict :
3135 if not isinstance (value , list ):
3236 return False
33- arguments = get_args (type )
37+ arguments = get_args (type_hint )
3438 if not arguments :
3539 return True
3640 return all (check (subvalue , arguments [0 ], strict = strict , lists_are_tuples = lists_are_tuples ) for subvalue in value )
3741
3842 elif origin_type is dict and strict :
3943 if not isinstance (value , dict ):
4044 return False
41- arguments = get_args (type )
45+ arguments = get_args (type_hint )
4246 if not arguments :
4347 return True
4448 return all (check (key , arguments [0 ], strict = strict , lists_are_tuples = lists_are_tuples ) and check (subvalue , arguments [1 ], strict = strict , lists_are_tuples = lists_are_tuples ) for key , subvalue in value .items ())
4549
4650 elif origin_type is tuple and strict :
47- types_to_check : List [Union [Type [list ], Type [tuple ]]] = [tuple ] if not lists_are_tuples else [tuple , list ]
51+ types_to_check : List [Union [Type [list ], Type [tuple ]]] = [tuple ] if not lists_are_tuples else [tuple , list ] # type: ignore[type-arg]
4852 if all (not isinstance (value , x ) for x in types_to_check ):
4953 return False
5054
51- arguments = get_args (type )
55+ arguments = get_args (type_hint )
5256
5357 if not arguments :
5458 return True
@@ -65,10 +69,10 @@ def check(value: Any, type: Type[ExpectedType], strict: bool = False, lists_are_
6569 if origin_type is not None :
6670 return isinstance (value , origin_type )
6771
68- if not isclass (type ):
72+ if not isclass (type_hint ):
6973 raise ValueError ('Type must be a valid type object.' )
7074
71- if type is tuple and lists_are_tuples :
75+ if type_hint is tuple and lists_are_tuples :
7276 return isinstance (value , tuple ) or isinstance (value , list ) # pragma: no cover
7377
74- return isinstance (value , type )
78+ return isinstance (value , type_hint )
0 commit comments