code: def walk(top, topdown=True, onerror=None):
      
      top = compat.as_str_any(top)
      fs = get_filesystem(top)
      try:
          listing = listdir(top)
      except errors.NotFoundError as err:
          if onerror:
              onerror(err)
          else:
              return
  
      files = []
      subdirs = []
      for item in listing:
          full_path = fs.join(top, compat.as_str_any(item))
          if isdir(full_path):
              subdirs.append(item)
          else:
              files.append(item)
  
      here = (top, subdirs, files)
  
      if topdown:
          yield here
  
      for subdir in subdirs:
          joined_subdir = fs.join(top, compat.as_str_any(subdir))
          for subitem in walk(joined_subdir, topdown, onerror=onerror):
              yield subitem
  
      if not topdown:
          yield here
docs: Recursive directory tree generator for directories.
  
      Args:
        top: string, a Directory name
        topdown: bool, Traverse pre order if True, post order if False.
        onerror: optional handler for errors. Should be a function, it will be
          called with the error as argument. Rethrowing the error aborts the walk.
  
      Errors that happen while listing directories are ignored.
  
      Yields:
        Each yield is a 3-tuple:  the pathname of a directory, followed by lists of
        all its subdirectories and leaf files.
        (dirname, [subdirname, subdirname, ...], [filename, filename, ...])
        as strings