code: def compiled_objects_cache(attribute_name):
      def decorator(func):
          """
          This decorator caches just the ids, oopposed to caching the object itself.
          Caching the id has the advantage that an object doesn't need to be
          hashable.
          """
  
          def wrapper(evaluator, obj, parent_context=None):
              cache = getattr(evaluator, attribute_name)
              # Do a very cheap form of caching here.
              key = id(obj)
              try:
                  cache[key]
                  return cache[key][0]
              except KeyError:
                  # TODO wuaaaarrghhhhhhhh
                  if attribute_name == "mixed_cache":
                      result = func(evaluator, obj, parent_context)
                  else:
                      result = func(evaluator, obj)
                  # Need to cache all of them, otherwise the id could be overwritten.
                  cache[key] = result, obj, parent_context
                  return result
  
          return wrapper
  
      return decorator
  
imports: import inspect
  import types
  import sys
  from textwrap import dedent
  import operator
  from collections import namedtuple
  from jedi._compatibility import unicode, is_py3, builtins, py_version, force_unicode, print_to_stderr
  from jedi.evaluate.compiled.getattr_static import getattr_static
label_desc: Use image node_id 3 for calling a global function with example usage: compiled_objects_cache(attribute_name) and returns: decorator, wrapper, cache, result