diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index b455e287017e..496a112fc0d2 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -766,6 +766,14 @@ of the above sections. Note: the exact list of flags enabled by running :option:`--strict` may change over time. + .. include:: strict_list.rst + .. + The above file is autogenerated and included during html generation. + (That's an include directive, and this is a comment.) + It would be fine to generate it at some other time instead, + theoretically, but we already had a convenient hook during html gen. + + .. option:: --disable-error-code This flag allows disabling one or multiple error codes globally. diff --git a/docs/source/html_builder.py b/docs/source/html_builder.py index ea3594e0617b..387f7f13b4c2 100644 --- a/docs/source/html_builder.py +++ b/docs/source/html_builder.py @@ -11,16 +11,37 @@ from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.environment import BuildEnvironment +from mypy.main import define_options + class MypyHTMLBuilder(StandaloneHTMLBuilder): + strict_file: Path + def __init__(self, app: Sphinx, env: BuildEnvironment) -> None: super().__init__(app, env) self._ref_to_doc = {} + self.strict_file = Path(self.srcdir) / "strict_list.rst" + self._add_strict_list() def write_doc(self, docname: str, doctree: document) -> None: super().write_doc(docname, doctree) self._ref_to_doc.update({_id: docname for _id in doctree.ids}) + def _add_strict_list(self) -> None: + strict_flags: list[str] + _, strict_flags, _ = define_options() + strict_part = ", ".join(f":option:`{s} `" for s in strict_flags) + if ( + not strict_part + or strict_part.isspace() + or len(strict_part) < 20 + or len(strict_part) > 2000 + ): + raise ValueError(f"{strict_part=}, which doesn't look right (by a simple heuristic).") + self.strict_file.write_text( + "For this version of mypy, the list of flags enabled by strict is: " + strict_part + ) + def _verify_error_codes(self) -> None: from mypy.errorcodes import error_codes @@ -55,6 +76,7 @@ def _write_ref_redirector(self) -> None: def finish(self) -> None: super().finish() self._write_ref_redirector() + self.strict_file.unlink() def setup(app: Sphinx) -> dict[str, Any]: diff --git a/mypy/main.py b/mypy/main.py index 7bd7215bbe2a..f785020b38a0 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -462,24 +462,18 @@ def __call__( parser.exit() -def process_options( - args: list[str], - stdout: TextIO | None = None, - stderr: TextIO | None = None, - require_targets: bool = True, - server_options: bool = False, - fscache: FileSystemCache | None = None, +def define_options( program: str = "mypy", header: str = HEADER, -) -> tuple[list[BuildSource], Options]: - """Parse command line arguments. - - If a FileSystemCache is passed in, and package_root options are given, - call fscache.set_package_root() to set the cache's package root. - """ - stdout = stdout or sys.stdout - stderr = stderr or sys.stderr - + stdout: TextIO = sys.stdout, + stderr: TextIO = sys.stderr, + server_options: bool = False, +) -> tuple[CapturableArgumentParser, list[str], list[tuple[str, bool]]]: + """Define the options in the parser (by calling a bunch of methods that express/build our desired command-line flags). + Returns a tuple of: + a parser object, that can parse command line arguments to mypy (expected consumer: main's process_options), + a list of what flags are strict (expected consumer: docs' html_builder's _add_strict_list), + strict_flag_assignments (expected consumer: main's process_options).""" parser = CapturableArgumentParser( prog=program, usage=header, @@ -1321,6 +1315,32 @@ def add_invertible_flag( dest="special-opts:files", help="Type-check given files or directories", ) + return parser, strict_flag_names, strict_flag_assignments + + +def process_options( + args: list[str], + stdout: TextIO | None = None, + stderr: TextIO | None = None, + require_targets: bool = True, + server_options: bool = False, + fscache: FileSystemCache | None = None, + program: str = "mypy", + header: str = HEADER, +) -> tuple[list[BuildSource], Options]: + """Parse command line arguments. + + If a FileSystemCache is passed in, and package_root options are given, + call fscache.set_package_root() to set the cache's package root. + + Returns a tuple of: a list of source files, an Options collected from flags. + """ + stdout = stdout if stdout is not None else sys.stdout + stderr = stderr if stderr is not None else sys.stderr + + parser, _, strict_flag_assignments = define_options( + program, header, stdout, stderr, server_options + ) # Parse arguments once into a dummy namespace so we can get the # filename for the config file and know if the user requested all strict options. @@ -1502,11 +1522,9 @@ def set_strict_flags() -> None: targets.extend(p_targets) for m in special_opts.modules: targets.append(BuildSource(None, m, None)) - return targets, options elif special_opts.command: options.build_type = BuildType.PROGRAM_TEXT targets = [BuildSource(None, None, "\n".join(special_opts.command))] - return targets, options else: try: targets = create_source_list(special_opts.files, options, fscache) @@ -1515,7 +1533,7 @@ def set_strict_flags() -> None: # exceptions of different types. except InvalidSourceList as e2: fail(str(e2), stderr, options) - return targets, options + return targets, options def process_package_roots(