mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Pre-compile all `excludes
regular expressions in
apidoc
` (#10981)
Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
This commit is contained in:
parent
f0fead5351
commit
eb3fffc3e9
@ -12,12 +12,13 @@ https://sat.qc.ca/
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import fnmatch
|
||||||
import glob
|
import glob
|
||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from fnmatch import fnmatch
|
|
||||||
from importlib.machinery import EXTENSION_SUFFIXES
|
from importlib.machinery import EXTENSION_SUFFIXES
|
||||||
from os import path
|
from os import path
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
@ -30,7 +31,7 @@ from sphinx.util.osutil import FileAvoidWrite, ensuredir
|
|||||||
from sphinx.util.template import ReSTRenderer
|
from sphinx.util.template import ReSTRenderer
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator, Sequence
|
||||||
|
|
||||||
# automodule options
|
# automodule options
|
||||||
if 'SPHINX_APIDOC_OPTIONS' in os.environ:
|
if 'SPHINX_APIDOC_OPTIONS' in os.environ:
|
||||||
@ -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,
|
def create_package_file(root: str, master_package: str | None, subroot: str,
|
||||||
py_files: list[str],
|
py_files: list[str],
|
||||||
opts: Any, subs: list[str], is_namespace: bool,
|
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:
|
) -> None:
|
||||||
"""Build the text of the file and write the file."""
|
"""Build the text of the file and write the file."""
|
||||||
# build a list of sub packages (directories containing an __init__ file)
|
# build a list of sub packages (directories containing an __init__ file)
|
||||||
@ -183,7 +185,8 @@ def create_modules_toc_file(modules: list[str], opts: Any, name: str = 'modules'
|
|||||||
write_file(name, text, opts)
|
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."""
|
"""Check if we want to skip this module."""
|
||||||
if not path.isdir(dirname):
|
if not path.isdir(dirname):
|
||||||
return False
|
return False
|
||||||
@ -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)
|
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."""
|
"""Check if we want to skip this module."""
|
||||||
if not path.exists(filename):
|
if not path.exists(filename):
|
||||||
# skip if the file doesn't exist
|
# skip if the file doesn't exist
|
||||||
@ -209,7 +212,7 @@ def is_skipped_module(filename: str, opts: Any, excludes: list[str]) -> bool:
|
|||||||
return False
|
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]:
|
) -> Generator[tuple[str, list[str], list[str]], None, None]:
|
||||||
"""Walk through the directory and list files and subdirectories up."""
|
"""Walk through the directory and list files and subdirectories up."""
|
||||||
followlinks = getattr(opts, 'followlinks', False)
|
followlinks = getattr(opts, 'followlinks', False)
|
||||||
@ -234,7 +237,7 @@ def walk(rootpath: str, excludes: list[str], opts: Any,
|
|||||||
yield root, subs, files
|
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)."""
|
"""Check the given directory contains child module/s (at least one)."""
|
||||||
return any(
|
return any(
|
||||||
files
|
files
|
||||||
@ -242,7 +245,7 @@ def has_child_module(rootpath: str, excludes: list[str], opts: Any) -> bool:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
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]:
|
user_template_dir: str | None = None) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Look for every file in the directory tree and create the corresponding
|
Look for every file in the directory tree and create the corresponding
|
||||||
@ -297,16 +300,13 @@ def recurse_tree(rootpath: str, excludes: list[str], opts: Any,
|
|||||||
return toplevels
|
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.
|
"""Check if the directory is in the exclude list.
|
||||||
|
|
||||||
Note: by having trailing slashes, we avoid common prefix issues, like
|
Note: by having trailing slashes, we avoid common prefix issues, like
|
||||||
e.g. an exclude "foo" also accidentally excluding "foobar".
|
e.g. an exclude "foo" also accidentally excluding "foobar".
|
||||||
"""
|
"""
|
||||||
return any(
|
return any(exclude.match(root) for exclude in excludes)
|
||||||
fnmatch(root, exclude)
|
|
||||||
for exclude in excludes
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_parser() -> argparse.ArgumentParser:
|
def get_parser() -> argparse.ArgumentParser:
|
||||||
@ -427,7 +427,10 @@ def main(argv: list[str] = sys.argv[1:]) -> int:
|
|||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
if not args.dryrun:
|
if not args.dryrun:
|
||||||
ensuredir(args.destdir)
|
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)
|
modules = recurse_tree(rootpath, excludes, args, args.templatedir)
|
||||||
|
|
||||||
if args.full:
|
if args.full:
|
||||||
|
Loading…
Reference in New Issue
Block a user