Skip to content

Commit 0d11d70

Browse files
committed
Improve performance by leveraging cache
1 parent 01774eb commit 0d11d70

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

dacite/types.py

+32-7
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def is_valid_generic_class(value: Any, type_: Type) -> bool:
102102
origin = get_origin(type_)
103103
if not (origin and isinstance(value, origin)):
104104
return False
105-
type_hints = get_type_hints(type(value))
105+
type_hints = cache(get_type_hints)(type(value))
106106
for field_name, field_type in type_hints.items():
107107
if isinstance(field_type, TypeVar):
108108
return (
@@ -121,6 +121,31 @@ def extract_init_var(type_: Type) -> Union[Type, Any]:
121121
return Any
122122

123123

124+
@cache
125+
def get_constraints(type_: TypeVar) -> Optional[Any]:
126+
return type_.__constraints__
127+
128+
129+
@cache
130+
def is_constrained(type_: TypeVar) -> bool:
131+
return hasattr(type_, "__constraints__") and get_constraints(type_)
132+
133+
134+
@cache
135+
def get_bound(type_: TypeVar) -> Optional[Any]:
136+
return type_.__bound__
137+
138+
139+
@cache
140+
def is_bound(type_: TypeVar) -> bool:
141+
return hasattr(type_, "__bound__") and get_bound(type_)
142+
143+
144+
@cache
145+
def is_generic_bound(type_: TypeVar) -> bool:
146+
return is_bound(type_) and get_bound(type_) is not None and is_generic(get_bound(type_))
147+
148+
124149
def is_instance(value: Any, type_: Type) -> bool:
125150
try:
126151
# As described in PEP 484 - section: "The numeric tower"
@@ -164,13 +189,13 @@ def is_instance(value: Any, type_: Type) -> bool:
164189
elif isclass(type(type_)) and is_generic_alias(type(type_)):
165190
return is_valid_generic_class(value, type_)
166191
elif isinstance(type_, TypeVar):
167-
if hasattr(type_, "__constraints__") and type_.__constraints__:
192+
if is_constrained(type_):
168193
return any(is_instance(value, t) for t in type_.__constraints__)
169-
if hasattr(type_, "__bound__") and type_.__bound__:
170-
if isinstance(type_.__bound__, tuple):
171-
return any(is_instance(value, t) for t in type_.__bound__)
172-
if type_.__bound__ is not None and is_generic(type_.__bound__):
173-
return isinstance(value, extract_generic(type_.__bound__))
194+
if is_bound(type_):
195+
if isinstance(get_bound(type_), tuple):
196+
return any(is_instance(value, t) for t in get_bound(type_))
197+
if is_generic_bound(type_):
198+
return isinstance(value, extract_generic(get_bound(type_)))
174199
return True
175200
elif is_type_generic(type_):
176201
return is_subclass(value, extract_generic(type_)[0])

0 commit comments

Comments
 (0)