code: def scandir_walk(top, skip_dirs=(), on_skip=None):
      
      # We may not have read permission for top, in which case we can't
      # get a list of the files the directory contains.  os.walk
      # always suppressed the exception then, rather than blow up for a
      # minor reason when (say) a thousand readable directories are still
      # left to visit.  That logic is copied here.
      try:
          scandir_it = Path2(top).scandir()
      except PermissionError as err:
          log.error("scandir error: %s" % err)
          return
  
      for entry in scandir_it:
          if entry.is_dir(follow_symlinks=False):
              if entry.name in skip_dirs:
                  on_skip(entry, entry.name)
              else:
                  yield from scandir_walk(entry.path, skip_dirs, on_skip)
          else:
              yield entry
docs: Just walk the filesystem tree top-down with os.scandir() and don't follow symlinks.
      :param top: path to scan
      :param skip_dirs: List of dir names to skip
          e.g.: "__pycache__", "temp", "tmp"
      :param on_skip: function that will be called if 'skip_dirs' match.
          e.g.:
          def on_skip(entry, pattern):
              log.error("Skip pattern %r hit: %s" % (pattern, entry.path))
      :return: yields os.DirEntry() instances