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","."]
code: def __getitem__(self, module):
      # when ran straight in its source code -- fails to discover nipy's version.. TODO
      # if module == 'nipy':
      #    import pdb; pdb.set_trace()
      if not isinstance(module, str):
          modname = module.__name__
      else:
          modname = module
          module = None
  
      lgr.log(5, "Requested to provide version for %s", modname)
      # Early returns None so we do not store prev result for  them
      # and allow users to install things at run time, so later check
      # doesn't pick it up from the _versions
      if modname not in self._versions:
          version = None  # by default -- not present
          if modname in self.CUSTOM:
              try:
                  version = self.CUSTOM[modname]()
                  version = self._deduce_version(version)
              except Exception as exc:
                  lgr.debug(
                      "Failed to deduce version of %s due to %s"
                      % (modname, CapturedException(exc))
                  )
                  return None
          else:
              if module is None:
                  if modname not in sys.modules:
                      try:
                          module = __import__(modname)
                      except ImportError:
                          lgr.debug(
                              "Module %s seems to be not present",
                              modname,
                          )
                          return None
                      except Exception as exc:
                          lgr.warning(
                              "Failed to import module %s due to %s",
                              modname,
                              CapturedException(exc),
                          )
                          return None
                  else:
                      module = sys.modules[modname]
              if module:
                  version = self._deduce_version(module)
          self._versions[modname] = version
  
      return self._versions.get(modname, self.UNKNOWN)
  
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 3 for calling the ExternalVersions obj's underlying member method code with example usage: obj.__getitem__(module) and returns: self, None, None, None