Skip to content

Commit 36b5367

Browse files
committed
ensure_type: cache the type adaptors
for a much more efficient type checking of complex types (using pydantic) at runtime: before: 124 μs ± 82.5 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each) after: 1.81 μs ± 4.74 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each) for comparison, when using isinstance: 629 ns ± 9.26 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each) Signed-off-by: Gaëtan Lehmann <[email protected]>
1 parent eba2403 commit 36b5367

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

lib/common.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ def expand_scope_relative_nodeid(scoped_nodeid, scope, ref_nodeid):
7171

7272
T = TypeVar("T")
7373

74+
_ensure_type_cache: Dict[type, TypeAdapter] = {}
75+
7476
def ensure_type(typ: Type[T], value: Any) -> T:
7577
"""
7678
Converts a value to the specified type.
@@ -84,7 +86,8 @@ def ensure_type(typ: Type[T], value: Any) -> T:
8486
except TypeError:
8587
# not just a simple type, lets try with pydantic
8688
with suppress(ValidationError):
87-
TypeAdapter(typ).validate_python(value)
89+
ta = _ensure_type_cache.setdefault(typ, TypeAdapter(typ))
90+
ta.validate_python(value)
8891
ok = True
8992
if not ok:
9093
raise TypeError(f"'{type(value).__name__}' object is not of the expected type '{typ.__name__}'")

0 commit comments

Comments
 (0)