Skip to content

Commit

Permalink
Convert CliOptions to a dataclass
Browse files Browse the repository at this point in the history
  • Loading branch information
AA-Turner committed Jan 7, 2025
1 parent 8732b23 commit fd3e7d3
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 37 deletions.
19 changes: 11 additions & 8 deletions sphinx/ext/apidoc/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,18 +263,19 @@ def main(argv: Sequence[str] = (), /) -> int:
sphinx.locale.init_console()

parser = get_parser()
args: CliOptions = parser.parse_args(argv or sys.argv[1:])
args = parser.parse_args(argv or sys.argv[1:])

rootpath = os.path.abspath(args.module_path)
args.module_path = rootpath = Path(args.module_path).resolve()

# normalize opts

if args.header is None:
args.header = rootpath.split(os.path.sep)[-1]
args.header = str(rootpath).split(os.path.sep)[-1]
args.suffix = args.suffix.removeprefix('.')
if not Path(rootpath).is_dir():
logger.error(__('%s is not a directory.'), rootpath)
raise SystemExit(1)
args.destdir = destdir = Path(args.destdir)
if not args.dryrun:
ensuredir(args.destdir)
excludes = tuple(
Expand All @@ -285,7 +286,9 @@ def main(argv: Sequence[str] = (), /) -> int:
args.automodule_options = set()
elif isinstance(args.automodule_options, str):
args.automodule_options = set(args.automodule_options.split(','))
written_files, modules = recurse_tree(rootpath, excludes, args, args.templatedir)

opts = CliOptions(**args.__dict__)
written_files, modules = recurse_tree(rootpath, excludes, opts, args.templatedir)

if args.full:
from sphinx.cmd import quickstart as qs
Expand All @@ -299,7 +302,7 @@ def main(argv: Sequence[str] = (), /) -> int:
prev_module = module
text += f' {module}\n'
d: dict[str, Any] = {
'path': args.destdir,
'path': str(destdir),
'sep': False,
'dot': '_',
'project': args.header,
Expand All @@ -320,7 +323,7 @@ def main(argv: Sequence[str] = (), /) -> int:
'mastertocmaxdepth': args.maxdepth,
'mastertoctree': text,
'language': 'en',
'module_path': rootpath,
'module_path': str(rootpath),
'append_syspath': args.append_syspath,
}
if args.extensions:
Expand All @@ -339,10 +342,10 @@ def main(argv: Sequence[str] = (), /) -> int:
)
elif args.tocfile:
written_files.append(
create_modules_toc_file(modules, args, args.tocfile, args.templatedir)
create_modules_toc_file(modules, opts, args.tocfile, args.templatedir)
)

if args.remove_old and not args.dryrun:
_remove_old_files(written_files, Path(args.destdir), args.suffix)
_remove_old_files(written_files, destdir, args.suffix)

return 0
61 changes: 32 additions & 29 deletions sphinx/ext/apidoc/_generate.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from __future__ import annotations

import dataclasses
import glob
import os
import os.path
from importlib.machinery import EXTENSION_SUFFIXES
from pathlib import Path
from typing import TYPE_CHECKING, Protocol
from typing import TYPE_CHECKING

from sphinx import package_dir
from sphinx.ext.apidoc import logger
Expand Down Expand Up @@ -267,7 +268,7 @@ def has_child_module(


def recurse_tree(
rootpath: str,
rootpath: str | os.PathLike[str],
excludes: Sequence[re.Pattern[str]],
opts: CliOptions,
user_template_dir: str | None = None,
Expand All @@ -277,6 +278,7 @@ def recurse_tree(
ReST files.
"""
# check if the base directory is a package and get its name
rootpath = os.fspath(rootpath)
if is_packagedir(rootpath) or opts.implicit_namespaces:
root_package = rootpath.split(os.path.sep)[-1]
else:
Expand Down Expand Up @@ -349,34 +351,35 @@ def is_excluded(root: str | Path, excludes: Sequence[re.Pattern[str]]) -> bool:
return any(exclude.match(root_str) for exclude in excludes)


class CliOptions(Protocol):
"""Arguments parsed from the command line."""
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
class CliOptions:
"""Options for apidoc."""

module_path: str
module_path: Path
exclude_pattern: list[str]
destdir: str
quiet: bool
maxdepth: int
force: bool
followlinks: bool
dryrun: bool
separatemodules: bool
includeprivate: bool
tocfile: str
noheadings: bool
modulefirst: bool
implicit_namespaces: bool
automodule_options: set[str]
suffix: str

remove_old: bool
destdir: Path
quiet: bool = False
maxdepth: int = 4
force: bool = False
followlinks: bool = False
dryrun: bool = False
separatemodules: bool = False
includeprivate: bool = False
tocfile: str = 'modules'
noheadings: bool = False
modulefirst: bool = False
implicit_namespaces: bool = False
automodule_options: set[str] = dataclasses.field(default_factory=set)
suffix: str = 'rst'

remove_old: bool = False

# --full only
full: bool
append_syspath: bool
header: str
author: str | None
version: str | None
release: str | None
extensions: list[str] | None
templatedir: str | None
full: bool = False
append_syspath: bool = False
header: str = ''
author: str | None = None
version: str | None = None
release: str | None = None
extensions: list[str] | None = None
templatedir: str | None = None

0 comments on commit fd3e7d3

Please sign in to comment.