text: import copy
  from typing import Any, Optional, Union
  
  from gelidum.typing import OnFreezeFuncType
  
  
  class OnFreezeCopier:
      def __call__(self, obj: Any) -> Any:
          return copy.deepcopy(obj)
  
  
  class OnFreezeIdentityFunc:
      def __call__(self, obj: Any) -> Any:
          return obj
  
  
  class OnFreezeOriginalObjTracker(OnFreezeCopier):
      """
      A callable class that stores the first object that was
      frozen. Useful for keeping track of original "hot" objects.
      """
      def __init__(self):
          self.__original_obj: Optional[Any] = None
  
      def __call__(self, obj: Any) -> Any:
          if self.__original_obj is None:
              self.__original_obj = obj
          return super().__call__(obj=obj)
  
      @property
      def original_obj(self) -> Optional[Any]:
          return self.__original_obj
  
  
  _ON_FREEZE_COPIER = OnFreezeCopier()
  _ON_FREEZE_IDENTITY_FUNC = OnFreezeIdentityFunc()
  
  
  def on_freeze_func_creator(on_freeze: Union[str, OnFreezeFuncType]) -> OnFreezeFuncType:
      if isinstance(on_freeze, str):
          if on_freeze == "copy":
              return _ON_FREEZE_COPIER
          elif on_freeze == "inplace":
              return _ON_FREEZE_IDENTITY_FUNC
          else:
              raise AttributeError(
                  f"Invalid value for on_freeze parameter, '{on_freeze}' found, "
                  f"only 'copy' and 'inplace' are valid options if passed a string"
              )
  
      elif callable(on_freeze):
          return on_freeze
  
      else:
          raise AttributeError(
              f"Invalid value for on_freeze parameter, '{on_freeze}' found, "
              f"only 'copy', 'inplace' or a callable are valid options"
          )
  