From ee9977df2f13099d9823bd242cee8f2c52718f85 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 19 Aug 2024 14:27:50 -0700 Subject: [PATCH] card: fix memory leak from nested function scoping (#33328) * stash * no other leaks! pm.send grows memory usage by ~20mb but that's it * undo * clean up --- selfdrive/car/card.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/selfdrive/car/card.py b/selfdrive/car/card.py index 47bef0349..1ef7a44ef 100755 --- a/selfdrive/car/card.py +++ b/selfdrive/car/card.py @@ -66,6 +66,18 @@ def is_dataclass(obj): return hasattr(obj, _FIELDS) +def _asdictref_inner(obj) -> dict[str, Any] | Any: + if is_dataclass(obj): + ret = {} + for field in getattr(obj, _FIELDS): # similar to dataclasses.fields() + ret[field] = _asdictref_inner(getattr(obj, field)) + return ret + elif isinstance(obj, (tuple, list)): + return type(obj)(_asdictref_inner(v) for v in obj) + else: + return obj + + def asdictref(obj) -> dict[str, Any]: """ Similar to dataclasses.asdict without recursive type checking and copy.deepcopy @@ -74,17 +86,6 @@ def asdictref(obj) -> dict[str, Any]: if not is_dataclass(obj): raise TypeError("asdictref() should be called on dataclass instances") - def _asdictref_inner(obj) -> dict[str, Any] | Any: - if is_dataclass(obj): - ret = {} - for field in getattr(obj, _FIELDS): # similar to dataclasses.fields() - ret[field] = _asdictref_inner(getattr(obj, field)) - return ret - elif isinstance(obj, (tuple, list)): - return type(obj)(_asdictref_inner(v) for v in obj) - else: - return obj - return _asdictref_inner(obj)