@@ -376,17 +376,6 @@ class MutableProxy(wrapt.ObjectProxy):
376376 pydantic .BaseModel .__dict__
377377 )
378378
379- # These types will be wrapped in MutableProxy
380- __mutable_types__ = (
381- list ,
382- dict ,
383- set ,
384- Base ,
385- DeclarativeBase ,
386- BaseModelV2 ,
387- BaseModelV1 ,
388- )
389-
390379 # Dynamically generated classes for tracking dataclass mutations.
391380 __dataclass_proxies__ : dict [type , type ] = {}
392381
@@ -467,20 +456,6 @@ def _mark_dirty(
467456 return wrapped (* args , ** (kwargs or {}))
468457 return None
469458
470- @classmethod
471- def _is_mutable_type (cls , value : Any ) -> bool :
472- """Check if a value is of a mutable type and should be wrapped.
473-
474- Args:
475- value: The value to check.
476-
477- Returns:
478- Whether the value is of a mutable type.
479- """
480- return isinstance (value , cls .__mutable_types__ ) or (
481- dataclasses .is_dataclass (value ) and not isinstance (value , Var )
482- )
483-
484459 @staticmethod
485460 def _is_called_from_dataclasses_internal () -> bool :
486461 """Check if the current function is called from dataclasses helper.
@@ -512,7 +487,7 @@ def _wrap_recursive(self, value: Any) -> Any:
512487 if self ._is_called_from_dataclasses_internal ():
513488 return value
514489 # Recursively wrap mutable types, but do not re-wrap MutableProxy instances.
515- if self . _is_mutable_type ( value ) and not isinstance (value , MutableProxy ):
490+ if is_mutable_type ( type ( value ) ) and not isinstance (value , MutableProxy ):
516491 base_cls = globals ()[self .__base_proxy__ ]
517492 return base_cls (
518493 wrapped = value ,
@@ -573,7 +548,7 @@ def __getattr__(self, __name: str) -> Any:
573548 self ._wrap_recursive_decorator ,
574549 )
575550
576- if self . _is_mutable_type ( value ) and __name not in (
551+ if is_mutable_type ( type ( value ) ) and __name not in (
577552 "__wrapped__" ,
578553 "_self_state" ,
579554 "__dict__" ,
@@ -762,3 +737,30 @@ def _mark_dirty(
762737 return super ()._mark_dirty (
763738 wrapped = wrapped , instance = instance , args = args , kwargs = kwargs
764739 )
740+
741+
742+ # These types will be wrapped in MutableProxy
743+ MUTABLE_TYPES = (
744+ list ,
745+ dict ,
746+ set ,
747+ Base ,
748+ DeclarativeBase ,
749+ BaseModelV2 ,
750+ BaseModelV1 ,
751+ )
752+
753+
754+ @functools .lru_cache (maxsize = 1024 )
755+ def is_mutable_type (type_ : type ) -> bool :
756+ """Check if a type is mutable and should be wrapped.
757+
758+ Args:
759+ type_: The type to check.
760+
761+ Returns:
762+ Whether the type is mutable and should be wrapped.
763+ """
764+ return issubclass (type_ , MUTABLE_TYPES ) or (
765+ dataclasses .is_dataclass (type_ ) and not issubclass (type_ , Var )
766+ )
0 commit comments