class_docstr: Pretty Printer class for estimator objects.
  
  This extends the pprint.PrettyPrinter class, because:
  - we need estimators to be printed with their parameters, e.g.
    Estimator(param1=value1, ...) which is not supported by default.
  - the 'compact' parameter of PrettyPrinter is ignored for dicts, which
    may lead to very long representations that we want to avoid.
  
  Quick overview of pprint.PrettyPrinter (see also
  https://stackoverflow.com/questions/49565047/pprint-with-hex-numbers):
  
  - the entry point is the _format() method which calls format() (overridden
    here)
  - format() directly calls _safe_repr() for a first try at rendering the
    object
  - _safe_repr formats the whole object recursively, only calling itself,
    not caring about line length or anything
  - back to _format(), if the output string is too long, _format() then calls
    the appropriate _pprint_TYPE() method (e.g. _pprint_list()) depending on
    the type of the object. This where the line length and the compact
    parameters are taken into account.
  - those _pprint_TYPE() methods will internally use the format() method for
    rendering the nested objects of an object (e.g. the elements of a list)
  
  In the end, everything has to be implemented twice: in _safe_repr and in
  the custom _pprint_TYPE methods. Unfortunately PrettyPrinter is really not
  straightforward to extend (especially when we want a compact output), so
  the code is a bit convoluted.
  
  This class overrides:
  - format() to support the changed_only parameter
  - _safe_repr to support printing of estimators (for when they fit on a
    single line)
  - _format_dict_items so that dict are correctly 'compacted'
  - _format_items so that ellipsis is used on long lists and tuples
  
  When estimators cannot be printed on a single line, the builtin _format()
  will call _pprint_estimator() because it was registered to do so (see
  _dispatch[BaseEstimator.__repr__] = _pprint_estimator).
  
  both _format_dict_items() and _pprint_estimator() use the
  _format_params_or_dict_items() method that will format parameters and
  key-value pairs respecting the compact parameter. This method needs another
  subroutine _pprint_key_val_tuple() used when a parameter or a key-value
  pair is too long to fit on a single line. This subroutine is called in
  _format() and is registered as well in the _dispatch dict (just like
  _pprint_estimator). We had to create the two classes KeyValTuple and
  KeyValTupleParam for this.
docstr: Format dict items or parameters respecting the compact=True
  parameter. For some reason, the builtin rendering of dict items doesn't
  respect compact=True and will use one line per key-value if all cannot
  fit in a single line.
  Dict items will be rendered as <'key': value> while params will be
  rendered as <key=value>. The implementation is mostly copy/pasting from
  the builtin _format_items().
  This also adds ellipsis if the number of items is greater than
  self.n_max_elements_to_show.
docstr_tok: ["Format","dict","items","or","parameters","respecting","the","compact=True","parameter",".","For","some","reason",",","the","builtin","rendering","of","dict","items","doesn't","respect","compact=True","and","will","use","one","line","per","key-value","if","all","can","not","fit","in","a","single","line",".","Dict","items","will","be","rendered","as","<","'key","'",":","value",">","while","params","will","be","rendered","as","<","key=value",">",".","The","implementation","is","mostly","copy\/pasting","from","the","builtin","_format_items","(",")",".","This","also","adds","ellipsis","if","the","number","of","items","is","greater","than","self.n_max_elements_to_show","."]
code: def _format_params_or_dict_items(
      self, object, stream, indent, allowance, context, level, is_dict
  ):
      """Format dict items or parameters respecting the compact=True
      parameter. For some reason, the builtin rendering of dict items doesn't
      respect compact=True and will use one line per key-value if all cannot
      fit in a single line.
      Dict items will be rendered as <'key': value> while params will be
      rendered as <key=value>. The implementation is mostly copy/pasting from
      the builtin _format_items().
      This also adds ellipsis if the number of items is greater than
      self.n_max_elements_to_show.
      """
      write = stream.write
      indent += self._indent_per_level
      delimnl = ",\n" + " " * indent
      delim = ""
      width = max_width = self._width - indent + 1
      it = iter(object)
      try:
          next_ent = next(it)
      except StopIteration:
          return
      last = False
      n_items = 0
      while not last:
          if n_items == self.n_max_elements_to_show:
              write(", ...")
              break
          n_items += 1
          ent = next_ent
          try:
              next_ent = next(it)
          except StopIteration:
              last = True
              max_width -= allowance
              width -= allowance
          if self._compact:
              k, v = ent
              krepr = self._repr(k, context, level)
              vrepr = self._repr(v, context, level)
              if not is_dict:
                  krepr = krepr.strip("'")
              middle = ": " if is_dict else "="
              rep = krepr + middle + vrepr
              w = len(rep) + 2
              if width < w:
                  width = max_width
                  if delim:
                      delim = delimnl
              if width >= w:
                  width -= w
                  write(delim)
                  delim = ", "
                  write(rep)
                  continue
          write(delim)
          delim = delimnl
          class_ = KeyValTuple if is_dict else KeyValTupleParam
          self._format(
              class_(ent),
              stream,
              indent,
              allowance if last else 1,
              context,
              level,
          )
  
imports: import inspect
  import pprint
  from collections import OrderedDict
  from .._config import get_config
  from ..base import BaseEstimator
  from .None import is_scalar_nan
label_desc: Use image node_id 6 for calling the _EstimatorPrettyPrinter obj's underlying member method code with example usage: obj._format_params_or_dict_items(object, stream, indent, allowance, context, level, is_dict) without return types