class_docstr: Helper to figure out/use versions of the externals (modules, cmdline tools, etc).
  
  To avoid collision between names of python modules and command line tools,
  prepend names for command line tools with `cmd:`.
  
  It maintains a dictionary of `distuil.version.LooseVersion`s to make
  comparisons easy. Note that even if version string conform the StrictVersion
  "standard", LooseVersion will be used.  If version can't be deduced for the
  external, `UnknownVersion()` is assigned.  If external is not present (can't
  be imported, or custom check throws exception), None is returned without
  storing it, so later call will re-evaluate fully.
class_docstr_tok: ["Helper","to","figure","out\/use","versions","of","the","externals","(","modules",",","cmdline","tools",",","etc",")",".","To","avoid","collision","between","names","of","python","modules","and","command","line","tools",",","prepend","names","for","command","line","tools","with","`","cmd",":","`",".","It","maintains","a","dictionary","of","`","distuil.version.LooseVersion","`","s","to","make","comparisons","easy",".","Note","that","even","if","version","string","conform","the","StrictVersion","''","standard","''",",","LooseVersion","will","be","used",".","If","version","ca","n't","be","deduced","for","the","external",",","`","UnknownVersion","(",")","`","is","assigned",".","If","external","is","not","present","(","can't","be","imported",",","or","custom","check","throws","exception",")",",","None","is","returned","without","storing","it",",","so","later","call","will","re-evaluate","fully","."]
docstr: Return listing of versions as a string
  
  Parameters
  ----------
  indent: bool or str, optional
    If set would instruct on how to indent entries (if just True, ' '
    is used). Otherwise returned in a single line
  preamble: str, optional
    What preamble to the listing to use
  query : bool, optional
    To query for versions of all "registered" custom externals, so to
    get those which weren't queried for yet
docstr_tok: ["Return","listing","of","versions","as","a","string","Parameters","--","--","--","--","--","indent",":","bool","or","str",",","optional","If","set","would","instruct","on","how","to","indent","entries","(","if","just","True",",","'","'","is","used",")",".","Otherwise","returned","in","a","single","line","preamble",":","str",",","optional","What","preamble","to","the","listing","to","use","query",":","bool",",","optional","To","query","for","versions","of","all","``","registered","''","custom","externals",",","so","to","get","those","which","were","n't","queried","for","yet"]
code: def dumps(self, indent=None, preamble="Versions:", query=False):
      """Return listing of versions as a string
  
      Parameters
      ----------
      indent: bool or str, optional
        If set would instruct on how to indent entries (if just True, ' '
        is used). Otherwise returned in a single line
      preamble: str, optional
        What preamble to the listing to use
      query : bool, optional
        To query for versions of all "registered" custom externals, so to
        get those which weren't queried for yet
      """
      if indent and (indent is True):
          indent = " "
      items = [
          "%s=%s" % (k, self._versions[k])
          for k in sorted(self.keys(query=query))
      ]
      out = "%s" % preamble if preamble else ""
      if indent is not None:
          if preamble:
              preamble += linesep
          indent = " " if indent is True else str(indent)
          out += (linesep + indent).join(items) + linesep
      else:
          out += " " + " ".join(items)
      return out
  
imports: import os.path
  import re
  import sys
  from itertools import chain
  from os import linesep
  from looseversion import LooseVersion
  from datalad.config import get_git_version
  from datalad.log import lgr
  from .exceptions import CapturedException, CommandError
  from datalad.cmd import GitWitlessRunner, StdOutErrCapture, WitlessRunner
  from datalad.support.exceptions import MissingExternalDependency, OutdatedExternalDependency
label_desc: Use image node_id 8 for calling the ExternalVersions obj's underlying member method code with example usage: obj.dumps(indent, preamble, query) and returns: out