code: def get_matching_files(
      dirname: str | os.PathLike[str],
      include_patterns: Iterable[str] = ("**",),
      exclude_patterns: Iterable[str] = (),
  ) -> Iterator[str]:
      """Get all file names in a directory, recursively.
  
      Filter file names by the glob-style include_patterns and exclude_patterns.
      The default values include all files ("**") and exclude nothing ("").
  
      Only files matching some pattern in *include_patterns* are included, and
      exclusions from *exclude_patterns* take priority over inclusions.
  
      """
      # dirname is a normalized absolute path.
      dirname = os.path.normpath(os.path.abspath(dirname))
  
      exclude_matchers = compile_matchers(exclude_patterns)
      include_matchers = compile_matchers(include_patterns)
  
      for root, dirs, files in os.walk(dirname, followlinks=True):
          relative_root = os.path.relpath(root, dirname)
          if relative_root == ".":
              relative_root = (
                  ""  # suppress dirname for files on the target dir
              )
  
          # Filter files
          included_files = []
          for entry in sorted(files):
              entry = path_stabilize(os.path.join(relative_root, entry))
              keep = False
              for matcher in include_matchers:
                  if matcher(entry):
                      keep = True
                      break  # break the inner loop
  
              for matcher in exclude_matchers:
                  if matcher(entry):
                      keep = False
                      break  # break the inner loop
  
              if keep:
                  included_files.append(entry)
  
          # Filter directories
          filtered_dirs = []
          for dir_name in sorted(dirs):
              normalised = path_stabilize(
                  os.path.join(relative_root, dir_name)
              )
              for matcher in exclude_matchers:
                  if matcher(normalised):
                      break  # break the inner loop
              else:
                  # if the loop didn't break
                  filtered_dirs.append(dir_name)
  
          dirs[:] = filtered_dirs
  
          # Yield filtered files
          yield from included_files
  
file_path: sphinx/sphinx/util/matching.py
imports: from __future__ import annotations
  import os.path
  import re
  from typing import TYPE_CHECKING, Callable
  from sphinx.util.osutil import canon_path, path_stabilize
label_desc: Use image node_id 5 for calling a global function with example usage: get_matching_files(dirname, include_patterns, exclude_patterns) without return types