code: def _create_deprecated_obj_wrapper(
      obj: TObj, show_warning: Callable[[], Any]
  ) -> TObj:
      """Create a wrapper for an object that has been deprecated. The first
      time one of the object's properties or functions is accessed, the
      given `show_warning` callback will be called.
      """
      has_shown_warning = False
  
      def maybe_show_warning() -> None:
          # Call `show_warning` if it hasn't already been called once.
          nonlocal has_shown_warning
          if not has_shown_warning:
              has_shown_warning = True
              show_warning()
  
      class Wrapper:
          def __init__(self):
              # Override all the Wrapped object's magic functions
              for name in Wrapper._get_magic_functions(obj.__class__):
                  setattr(
                      self.__class__,
                      name,
                      property(self._make_magic_function_proxy(name)),
                  )
  
          def __getattr__(self, attr):
              # We handle __getattr__ separately from our other magic
              # functions. The wrapped class may not actually implement it,
              # but we still need to implement it to call all its normal
              # functions.
              if attr in self.__dict__:
                  return getattr(self, attr)
  
              maybe_show_warning()
              return getattr(obj, attr)
  
          @staticmethod
          def _get_magic_functions(cls) -> List[str]:
              # ignore the handful of magic functions we cannot override without
              # breaking the Wrapper.
              ignore = (
                  "__class__",
                  "__dict__",
                  "__getattribute__",
                  "__getattr__",
              )
              return [
                  name
                  for name in dir(cls)
                  if name not in ignore and name.startswith("__")
              ]
  
          @staticmethod
          def _make_magic_function_proxy(name):
              def proxy(self, *args):
                  maybe_show_warning()
                  return getattr(obj, name)
  
              return proxy
  
      return cast(TObj, Wrapper())
  
file_path: streamlit/lib/streamlit/deprecation_util.py
imports: from __future__ import annotations
  import functools
  from typing import Any, Callable, List, TypeVar, cast
  import streamlit
  from streamlit import config
  from streamlit.logger import get_logger
label_desc: Use image node_id 6 for calling a global function with example usage: _create_deprecated_obj_wrapper(obj, show_warning) and returns: cast, getattr, unknown, proxy, getattr, getattr