code: def __get__(self, instance, owner=None):
      if instance is None:
          return self
      if self.attrname is None:
          raise TypeError(
              "Cannot use cached_property instance without calling __set_name__ on it."
          )
      try:
          cache = instance.__dict__
      except (
          AttributeError
      ):  # not all objects have __dict__ (e.g. class defines slots)
          msg = (
              f"No '__dict__' attribute on {type(instance).__name__!r} "
              f"instance to cache {self.attrname!r} property."
          )
          raise TypeError(msg) from None
      val = cache.get(self.attrname, _NOT_FOUND)
      if val is _NOT_FOUND:
          with self.lock:
              # check if another thread filled cache while we awaited lock
              val = cache.get(self.attrname, _NOT_FOUND)
              if val is _NOT_FOUND:
                  val = self.func(instance)
                  try:
                      cache[self.attrname] = val
                  except TypeError:
                      msg = (
                          f"The '__dict__' attribute on {type(instance).__name__!r} instance "
                          f"does not support item assignment for caching {self.attrname!r} property."
                      )
                      raise TypeError(msg) from None
      return val
  
imports: from abc import get_cache_token
  from collections import namedtuple
  from reprlib import recursive_repr
  from _thread import RLock
  from types import GenericAlias
label_desc: Use image node_id 3 for calling the cached_property obj's underlying member method code with example usage: obj.__get__(instance, owner) and returns: val, self