@@ -378,17 +378,6 @@ class MutableProxy(wrapt.ObjectProxy):
378378 pydantic .BaseModel .__dict__
379379 )
380380
381- # These types will be wrapped in MutableProxy
382- __mutable_types__ = (
383- list ,
384- dict ,
385- set ,
386- Base ,
387- DeclarativeBase ,
388- BaseModelV2 ,
389- BaseModelV1 ,
390- )
391-
392381 # Dynamically generated classes for tracking dataclass mutations.
393382 __dataclass_proxies__ : dict [type , type ] = {}
394383
@@ -469,20 +458,6 @@ def _mark_dirty(
469458 return wrapped (* args , ** (kwargs or {}))
470459 return None
471460
472- @classmethod
473- def _is_mutable_type (cls , value : Any ) -> bool :
474- """Check if a value is of a mutable type and should be wrapped.
475-
476- Args:
477- value: The value to check.
478-
479- Returns:
480- Whether the value is of a mutable type.
481- """
482- return isinstance (value , cls .__mutable_types__ ) or (
483- dataclasses .is_dataclass (value ) and not isinstance (value , Var )
484- )
485-
486461 @staticmethod
487462 def _is_called_from_dataclasses_internal () -> bool :
488463 """Check if the current function is called from dataclasses helper.
@@ -514,7 +489,7 @@ def _wrap_recursive(self, value: Any) -> Any:
514489 if self ._is_called_from_dataclasses_internal ():
515490 return value
516491 # Recursively wrap mutable types, but do not re-wrap MutableProxy instances.
517- if self . _is_mutable_type (value ) and not isinstance (value , MutableProxy ):
492+ if is_mutable_type (value ) and not isinstance (value , MutableProxy ):
518493 base_cls = globals ()[self .__base_proxy__ ]
519494 return base_cls (
520495 wrapped = value ,
@@ -575,7 +550,7 @@ def __getattr__(self, __name: str) -> Any:
575550 self ._wrap_recursive_decorator ,
576551 )
577552
578- if self . _is_mutable_type (value ) and __name not in (
553+ if is_mutable_type (value ) and __name not in (
579554 "__wrapped__" ,
580555 "_self_state" ,
581556 "__dict__" ,
@@ -764,3 +739,30 @@ def _mark_dirty(
764739 return super ()._mark_dirty (
765740 wrapped = wrapped , instance = instance , args = args , kwargs = kwargs
766741 )
742+
743+
744+ # These types will be wrapped in MutableProxy
745+ MUTABLE_TYPES = (
746+ list ,
747+ dict ,
748+ set ,
749+ Base ,
750+ DeclarativeBase ,
751+ BaseModelV2 ,
752+ BaseModelV1 ,
753+ )
754+
755+
756+ @functools .lru_cache (maxsize = 1024 )
757+ def is_mutable_type (type_ : type ) -> bool :
758+ """Check if a type is mutable and should be wrapped.
759+
760+ Args:
761+ type_: The type to check.
762+
763+ Returns:
764+ Whether the type is mutable and should be wrapped.
765+ """
766+ return issubclass (type_ , MUTABLE_TYPES ) or (
767+ dataclasses .is_dataclass (type_ ) and not issubclass (type_ , Var )
768+ )
0 commit comments