Skip to content

Commit 82ad62c

Browse files
[docs] Include a real listing of the flags strict enables in the online documentation (#19062)
Fixes #19061 Currently, https://mypy.readthedocs.io/en/stable/command_line.html just says > You can see the list of flags enabled by strict mode in the full [mypy --help](https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-h) output. Which makes cross-referencing the documentation difficult. Instead, there should be the same list there as appears when running `mypy --help`: eg > --warn-unused-configs, --disallow-any-generics, --disallow-subclassing-any, --disallow-untyped- calls, --disallow-untyped-defs, --disallow- incomplete-defs, --check-untyped-defs, --disallow- untyped-decorators, --warn-redundant-casts, --warn-unused-ignores, --warn-return-any, --no- implicit-reexport, --strict-equality, --extra- checks Ideally this section would be automatically generated from the code.
1 parent e8147f2 commit 82ad62c

File tree

3 files changed

+67
-19
lines changed

3 files changed

+67
-19
lines changed

docs/source/command_line.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,14 @@ of the above sections.
812812
Note: the exact list of flags enabled by running :option:`--strict` may change
813813
over time.
814814

815+
.. include:: strict_list.rst
816+
..
817+
The above file is autogenerated and included during html generation.
818+
(That's an include directive, and this is a comment.)
819+
It would be fine to generate it at some other time instead,
820+
theoretically, but we already had a convenient hook during html gen.
821+
822+
815823
.. option:: --disable-error-code
816824

817825
This flag allows disabling one or multiple error codes globally.

docs/source/html_builder.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,37 @@
1111
from sphinx.builders.html import StandaloneHTMLBuilder
1212
from sphinx.environment import BuildEnvironment
1313

14+
from mypy.main import define_options
15+
1416

1517
class MypyHTMLBuilder(StandaloneHTMLBuilder):
18+
strict_file: Path
19+
1620
def __init__(self, app: Sphinx, env: BuildEnvironment) -> None:
1721
super().__init__(app, env)
1822
self._ref_to_doc = {}
23+
self.strict_file = Path(self.srcdir) / "strict_list.rst"
24+
self._add_strict_list()
1925

2026
def write_doc(self, docname: str, doctree: document) -> None:
2127
super().write_doc(docname, doctree)
2228
self._ref_to_doc.update({_id: docname for _id in doctree.ids})
2329

30+
def _add_strict_list(self) -> None:
31+
strict_flags: list[str]
32+
_, strict_flags, _ = define_options()
33+
strict_part = ", ".join(f":option:`{s} <mypy {s}>`" for s in strict_flags)
34+
if (
35+
not strict_part
36+
or strict_part.isspace()
37+
or len(strict_part) < 20
38+
or len(strict_part) > 2000
39+
):
40+
raise ValueError(f"{strict_part=}, which doesn't look right (by a simple heuristic).")
41+
self.strict_file.write_text(
42+
"For this version of mypy, the list of flags enabled by strict is: " + strict_part
43+
)
44+
2445
def _verify_error_codes(self) -> None:
2546
from mypy.errorcodes import error_codes
2647

@@ -55,6 +76,7 @@ def _write_ref_redirector(self) -> None:
5576
def finish(self) -> None:
5677
super().finish()
5778
self._write_ref_redirector()
79+
self.strict_file.unlink()
5880

5981

6082
def setup(app: Sphinx) -> dict[str, Any]:

mypy/main.py

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -462,24 +462,18 @@ def __call__(
462462
parser.exit()
463463

464464

465-
def process_options(
466-
args: list[str],
467-
stdout: TextIO | None = None,
468-
stderr: TextIO | None = None,
469-
require_targets: bool = True,
470-
server_options: bool = False,
471-
fscache: FileSystemCache | None = None,
465+
def define_options(
472466
program: str = "mypy",
473467
header: str = HEADER,
474-
) -> tuple[list[BuildSource], Options]:
475-
"""Parse command line arguments.
476-
477-
If a FileSystemCache is passed in, and package_root options are given,
478-
call fscache.set_package_root() to set the cache's package root.
479-
"""
480-
stdout = stdout or sys.stdout
481-
stderr = stderr or sys.stderr
482-
468+
stdout: TextIO = sys.stdout,
469+
stderr: TextIO = sys.stderr,
470+
server_options: bool = False,
471+
) -> tuple[CapturableArgumentParser, list[str], list[tuple[str, bool]]]:
472+
"""Define the options in the parser (by calling a bunch of methods that express/build our desired command-line flags).
473+
Returns a tuple of:
474+
a parser object, that can parse command line arguments to mypy (expected consumer: main's process_options),
475+
a list of what flags are strict (expected consumer: docs' html_builder's _add_strict_list),
476+
strict_flag_assignments (expected consumer: main's process_options)."""
483477
parser = CapturableArgumentParser(
484478
prog=program,
485479
usage=header,
@@ -1342,6 +1336,32 @@ def add_invertible_flag(
13421336
dest="special-opts:files",
13431337
help="Type-check given files or directories",
13441338
)
1339+
return parser, strict_flag_names, strict_flag_assignments
1340+
1341+
1342+
def process_options(
1343+
args: list[str],
1344+
stdout: TextIO | None = None,
1345+
stderr: TextIO | None = None,
1346+
require_targets: bool = True,
1347+
server_options: bool = False,
1348+
fscache: FileSystemCache | None = None,
1349+
program: str = "mypy",
1350+
header: str = HEADER,
1351+
) -> tuple[list[BuildSource], Options]:
1352+
"""Parse command line arguments.
1353+
1354+
If a FileSystemCache is passed in, and package_root options are given,
1355+
call fscache.set_package_root() to set the cache's package root.
1356+
1357+
Returns a tuple of: a list of source files, an Options collected from flags.
1358+
"""
1359+
stdout = stdout if stdout is not None else sys.stdout
1360+
stderr = stderr if stderr is not None else sys.stderr
1361+
1362+
parser, _, strict_flag_assignments = define_options(
1363+
program, header, stdout, stderr, server_options
1364+
)
13451365

13461366
# Parse arguments once into a dummy namespace so we can get the
13471367
# filename for the config file and know if the user requested all strict options.
@@ -1526,11 +1546,9 @@ def set_strict_flags() -> None:
15261546
targets.extend(p_targets)
15271547
for m in special_opts.modules:
15281548
targets.append(BuildSource(None, m, None))
1529-
return targets, options
15301549
elif special_opts.command:
15311550
options.build_type = BuildType.PROGRAM_TEXT
15321551
targets = [BuildSource(None, None, "\n".join(special_opts.command))]
1533-
return targets, options
15341552
else:
15351553
try:
15361554
targets = create_source_list(special_opts.files, options, fscache)
@@ -1539,7 +1557,7 @@ def set_strict_flags() -> None:
15391557
# exceptions of different types.
15401558
except InvalidSourceList as e2:
15411559
fail(str(e2), stderr, options)
1542-
return targets, options
1560+
return targets, options
15431561

15441562

15451563
def process_package_roots(

0 commit comments

Comments
 (0)