docs: def str(self, value, tolerant=False, limit=1000, seen=frozenset()):
          """Transform value into a representation suitable for substitution."""
          if value is None:
              if tolerant:
                  return ""
  
              raise ValueError("value is None")
  
          if isinstance(value, (bool, numbers.Number, basestring)):
              return str(value)
  
          if not isinstance(value, collections.Iterable):
              if not tolerant:
                  raise ValueError("unknown value type")
  
              try:
                  name = value.name
              except AttributeError:
                  try:
                      name = value.__name__
                  except AttributeError:
                      try:
                          name = value.__class__.__name__
                      except AttributeError:
                          return "<?>"
  
              return "<%s>" % (name,)
  
          is_mapping = isinstance(value, collections.Mapping)
  
          if not seen:
              wrap = "%s"
          elif is_mapping:
              wrap = "{%s}"
          else:
              wrap = "[%s]"
  
          id_ = id(value)
          if id_ in seen:
              if tolerant:
                  return wrap % ("...",)
              raise ValueError("recursive representation")
          seen = seen.union((id_,))
  
          if is_mapping:
              items = [(self.str(n, tolerant=tolerant, limit=limit, seen=seen),
                        self.str(v, tolerant=tolerant, limit=limit, seen=seen))
                       for n, v in value.items()]
              items.sort()
              items = ("%s=%s" for n, v in items)
          else:
              it = iter(value)
              items = [self.str(item, tolerant=tolerant, limit=limit, seen=seen)
                       for item in itertools.islice(
                           it,
                           len(value)
                           if isinstance(value, collections.Sized)
                           else limit)]
              items.sort()
              try:
                  next(it)
              except StopIteration:
                  pass
              else:
                  if not tolerant:
                      raise ValueError("iterable too long")
                  items.append("...")
  
          return wrap % (", ".join(items),)