Skip to content

Commit

Permalink
Pre-compile all excludes regular expressions in apidoc (#10981)
Browse files Browse the repository at this point in the history
Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
  • Loading branch information
progval and AA-Turner committed Jul 28, 2023
1 parent f0fead5 commit eb3fffc
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions sphinx/ext/apidoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
from __future__ import annotations

import argparse
import fnmatch
import glob
import locale
import os
import re
import sys
from copy import copy
from fnmatch import fnmatch
from importlib.machinery import EXTENSION_SUFFIXES
from os import path
from typing import TYPE_CHECKING, Any
Expand All @@ -30,7 +31,7 @@
from sphinx.util.template import ReSTRenderer

if TYPE_CHECKING:
from collections.abc import Generator
from collections.abc import Generator, Sequence

# automodule options
if 'SPHINX_APIDOC_OPTIONS' in os.environ:
Expand Down Expand Up @@ -116,7 +117,8 @@ def create_module_file(package: str | None, basename: str, opts: Any,
def create_package_file(root: str, master_package: str | None, subroot: str,
py_files: list[str],
opts: Any, subs: list[str], is_namespace: bool,
excludes: list[str] = [], user_template_dir: str | None = None,
excludes: Sequence[re.Pattern[str]] = (),
user_template_dir: str | None = None,
) -> None:
"""Build the text of the file and write the file."""
# build a list of sub packages (directories containing an __init__ file)
Expand Down Expand Up @@ -183,7 +185,8 @@ def create_modules_toc_file(modules: list[str], opts: Any, name: str = 'modules'
write_file(name, text, opts)


def is_skipped_package(dirname: str, opts: Any, excludes: list[str] = []) -> bool:
def is_skipped_package(dirname: str, opts: Any,
excludes: Sequence[re.Pattern[str]] = ()) -> bool:
"""Check if we want to skip this module."""
if not path.isdir(dirname):
return False
Expand All @@ -198,7 +201,7 @@ def is_skipped_package(dirname: str, opts: Any, excludes: list[str] = []) -> boo
return all(is_excluded(path.join(dirname, f), excludes) for f in files)


def is_skipped_module(filename: str, opts: Any, excludes: list[str]) -> bool:
def is_skipped_module(filename: str, opts: Any, _excludes: Sequence[re.Pattern[str]]) -> bool:
"""Check if we want to skip this module."""
if not path.exists(filename):
# skip if the file doesn't exist
Expand All @@ -209,7 +212,7 @@ def is_skipped_module(filename: str, opts: Any, excludes: list[str]) -> bool:
return False


def walk(rootpath: str, excludes: list[str], opts: Any,
def walk(rootpath: str, excludes: Sequence[re.Pattern[str]], opts: Any,
) -> Generator[tuple[str, list[str], list[str]], None, None]:
"""Walk through the directory and list files and subdirectories up."""
followlinks = getattr(opts, 'followlinks', False)
Expand All @@ -234,15 +237,15 @@ def walk(rootpath: str, excludes: list[str], opts: Any,
yield root, subs, files


def has_child_module(rootpath: str, excludes: list[str], opts: Any) -> bool:
def has_child_module(rootpath: str, excludes: Sequence[re.Pattern[str]], opts: Any) -> bool:
"""Check the given directory contains child module/s (at least one)."""
return any(
files
for _root, _subs, files in walk(rootpath, excludes, opts)
)


def recurse_tree(rootpath: str, excludes: list[str], opts: Any,
def recurse_tree(rootpath: str, excludes: Sequence[re.Pattern[str]], opts: Any,
user_template_dir: str | None = None) -> list[str]:
"""
Look for every file in the directory tree and create the corresponding
Expand Down Expand Up @@ -297,16 +300,13 @@ def recurse_tree(rootpath: str, excludes: list[str], opts: Any,
return toplevels


def is_excluded(root: str, excludes: list[str]) -> bool:
def is_excluded(root: str, excludes: Sequence[re.Pattern[str]]) -> bool:
"""Check if the directory is in the exclude list.
Note: by having trailing slashes, we avoid common prefix issues, like
e.g. an exclude "foo" also accidentally excluding "foobar".
"""
return any(
fnmatch(root, exclude)
for exclude in excludes
)
return any(exclude.match(root) for exclude in excludes)


def get_parser() -> argparse.ArgumentParser:
Expand Down Expand Up @@ -427,7 +427,10 @@ def main(argv: list[str] = sys.argv[1:]) -> int:
raise SystemExit(1)
if not args.dryrun:
ensuredir(args.destdir)
excludes = [path.abspath(exclude) for exclude in args.exclude_pattern]
excludes = tuple(
re.compile(fnmatch.translate(path.abspath(exclude)))
for exclude in dict.fromkeys(args.exclude_pattern)
)
modules = recurse_tree(rootpath, excludes, args, args.templatedir)

if args.full:
Expand Down

0 comments on commit eb3fffc

Please sign in to comment.