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 names of the known modules
  
  Parameters
  ----------
  query: bool, optional
    If True, we will first query all CUSTOM and INTERESTING entries
    to make sure we have them known.
docstr_tok: ["Return","names","of","the","known","modules","Parameters","--","--","--","--","--","query",":","bool",",","optional","If","True",",","we","will","first","query","all","CUSTOM","and","INTERESTING","entries","to","make","sure","we","have","them","known","."]
code: def keys(self, query=False):
      """Return names of the known modules
  
      Parameters
      ----------
      query: bool, optional
        If True, we will first query all CUSTOM and INTERESTING entries
        to make sure we have them known.
      """
      if query:
          [self[k] for k in chain(self.CUSTOM, self.INTERESTING)]
      return self._versions.keys()
  
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 4 for calling the ExternalVersions obj's underlying member method code with example usage: obj.keys(query) and returns: self