code: def finish(self) -> None:
      logger.info("shutting down directory watcher")
      try:
          # avoid hanging if we crashed before the observer was started
          if self._file_observer.is_alive():
              # rather unfortunately we need to manually do a final scan of the dir
              # with `queue_events`, then iterate through all events before stopping
              # the observer to catch all files written.  First we need to prevent the
              # existing thread from consuming our final events, then we process them
              self._file_observer._timeout = 0
              self._file_observer._stopped_event.set()
              self._file_observer.join()
              self.emitter.queue_events(0)  # type: ignore[union-attr]
              while True:
                  try:
                      self._file_observer.dispatch_events(
                          self._file_observer.event_queue, 0
                      )
                  except queue.Empty:
                      break
              # Calling stop unschedules any inflight events so we handled them above
              self._file_observer.stop()
      # TODO: py2 TypeError: PyCObject_AsVoidPtr called with null pointer
      except TypeError:
          pass
      # TODO: py3 SystemError: <built-in function stop> returned an error
      except SystemError:
          pass
  
      # Ensure we've at least noticed every file in the run directory. Sometimes
      # we miss things because asynchronously watching filesystems isn't reliable.
      logger.info("scan: %s", self._dir)
  
      for dirpath, _, filenames in os.walk(self._dir):
          for fname in filenames:
              file_path = os.path.join(dirpath, fname)
              save_name = LogicalPath(
                  os.path.relpath(file_path, self._dir)
              )
              ignored = False
              for glb in self._settings.ignore_globs:
                  if len(fnmatch.filter([save_name], glb)) > 0:
                      ignored = True
                      logger.info(
                          "ignored: %s matching glob %s", save_name, glb
                      )
                      break
              if ignored:
                  continue
              logger.info("scan save: %s %s", file_path, save_name)
              self._get_file_event_handler(
                  file_path, save_name
              ).finish()
  
imports: import abc
  import fnmatch
  import glob
  import logging
  import os
  import queue
  import time
  from typing import TYPE_CHECKING, Any, Mapping, MutableMapping, MutableSet, Optional
  from wandb import util
  from wandb.sdk.interface.interface import GlobStr
  from wandb.sdk.lib.paths import LogicalPath
label_desc: Use image node_id 9 for calling the DirWatcher obj's underlying member method code with example usage: obj.finish() without return types