docs: def GetRendererForValueOrClass(cls, value, limit_lists=-1):
      """Returns renderer corresponding to a given value and rendering args."""
  
      if inspect.isclass(value):
        value_cls = value
      else:
        value_cls = value.__class__
  
      cache_key = "%s_%d" % (value_cls.__name__, limit_lists)
      try:
        renderer_cls = cls._renderers_cache[cache_key]
      except KeyError:
        candidates = []
        for candidate in itervalues(ApiValueRenderer.classes):
          if candidate.value_class:
            candidate_class = candidate.value_class
          else:
            continue
  
          if inspect.isclass(value):
            if issubclass(value_cls, candidate_class):
              candidates.append((candidate, candidate_class))
          else:
            if isinstance(value, candidate_class):
              candidates.append((candidate, candidate_class))
  
        if not candidates:
          raise RuntimeError(
              "No renderer found for value %s." % value.__class__.__name__)
  
        candidates = sorted(
            candidates, key=lambda candidate: len(candidate[1].mro()))
        renderer_cls = candidates[-1][0]
        cls._renderers_cache[cache_key] = renderer_cls
  
      return renderer_cls(limit_lists=limit_lists)