def _write_options_page(options: OptionsDataDict, linter: PyLinter) -> None: """Create or overwrite the options page.""" sections: list[str] = [ ".. This file is auto-generated. Make any changes to the associated\n" ".. docs extension in 'doc/exts/pylint_options.py'.\n\n" ".. _all-options:", get_rst_title("Standard Checkers", "^"), ] found_extensions = False for checker, checker_options in options.items(): if not found_extensions and checker_options[0].extension: sections.append(get_rst_title("Extensions", "^")) found_extensions = True sections.append(_create_checker_section(checker, checker_options, linter)) sections_string = "\n\n".join(sections) with open( PYLINT_USERGUIDE_PATH / "configuration" / "all-options.rst", "w", encoding="utf-8", ) as stream: stream.write( f""" {sections_string}""" )
def get_full_documentation(self, msgs, options, reports, doc=None, module=None): result = "" checker_title = "%s checker" % (self.name.replace("_", " ").title()) if module: # Provide anchor to link against result += ".. _%s:\n\n" % module result += "%s\n" % get_rst_title(checker_title, "~") if module: result += "This checker is provided by ``%s``.\n" % module result += "Verbatim name of the checker is ``%s``.\n\n" % self.name if doc: # Provide anchor to link against result += get_rst_title("{} Documentation".format(checker_title), "^") result += "%s\n\n" % cleandoc(doc) # options might be an empty generator and not be False when casted to boolean options = list(options) if options: result += get_rst_title("{} Options".format(checker_title), "^") result += "%s\n" % get_rst_section(None, options) if msgs: result += get_rst_title("{} Messages".format(checker_title), "^") for msgid, msg in sorted( msgs.items(), key=lambda kv: (_MSG_ORDER.index(kv[0][0]), kv[1]) ): msg = self.create_message_definition_from_tuple(msgid, msg) result += "%s\n" % msg.format_help(checkerref=False) result += "\n" if reports: result += get_rst_title("{} Reports".format(checker_title), "^") for report in reports: result += ":%s: %s\n" % report[:2] result += "\n" result += "\n" return result
def get_full_documentation( self, msgs: dict[str, MessageDefinitionTuple], options: Iterator[tuple[str, OptionDict, Any]], reports: tuple[tuple[str, str, ReportsCallable], ...], doc: str | None = None, module: str | None = None, show_options: bool = True, ) -> str: result = "" checker_title = f"{self.name.replace('_', ' ').title()} checker" if module: # Provide anchor to link against result += f".. _{module}:\n\n" result += f"{get_rst_title(checker_title, '~')}\n" if module: result += f"This checker is provided by ``{module}``.\n" result += f"Verbatim name of the checker is ``{self.name}``.\n\n" if doc: # Provide anchor to link against result += get_rst_title(f"{checker_title} Documentation", "^") result += f"{cleandoc(doc)}\n\n" # options might be an empty generator and not be False when cast to boolean options_list = list(options) if options_list: if show_options: result += get_rst_title(f"{checker_title} Options", "^") result += f"{get_rst_section(None, options_list)}\n" else: result += f"See also :ref:`{self.name} checker's options' documentation <{self.name}-options>`\n\n" if msgs: result += get_rst_title(f"{checker_title} Messages", "^") for msgid, msg in sorted(msgs.items(), key=lambda kv: (_MSG_ORDER.index(kv[0][0]), kv[1])): msg_def = self.create_message_definition_from_tuple(msgid, msg) result += f"{msg_def.format_help(checkerref=False)}\n" result += "\n" if reports: result += get_rst_title(f"{checker_title} Reports", "^") for report in reports: result += ( ":%s: %s\n" % report[:2] # pylint: disable=consider-using-f-string ) result += "\n" result += "\n" return result
def get_full_documentation(self, msgs, options, reports, doc=None, module=None): result = "" checker_title = f"{self.name.replace('_', ' ').title()} checker" if module: # Provide anchor to link against result += f".. _{module}:\n\n" result += f"{get_rst_title(checker_title, '~')}\n" if module: result += f"This checker is provided by ``{module}``.\n" result += f"Verbatim name of the checker is ``{self.name}``.\n\n" if doc: # Provide anchor to link against result += get_rst_title(f"{checker_title} Documentation", "^") result += f"{cleandoc(doc)}\n\n" # options might be an empty generator and not be False when casted to boolean options = list(options) if options: result += get_rst_title(f"{checker_title} Options", "^") result += f"{get_rst_section(None, options)}\n" if msgs: result += get_rst_title(f"{checker_title} Messages", "^") for msgid, msg in sorted(msgs.items(), key=lambda kv: (_MSG_ORDER.index(kv[0][0]), kv[1])): msg = self.create_message_definition_from_tuple(msgid, msg) result += f"{msg.format_help(checkerref=False)}\n" result += "\n" if reports: result += get_rst_title(f"{checker_title} Reports", "^") for report in reports: result += ( ":%s: %s\n" % report[:2] # pylint: disable=consider-using-f-string ) result += "\n" result += "\n" return result
def get_checkers_documentation(self): result = get_rst_title("Pylint global options and switches", "-") result += """ Pylint provides global options and switches. """ for checker in self.get_checkers(): name = checker.name if name == MAIN_CHECKER_NAME: if checker.options: for section, options in checker.options_by_section(): if section is None: title = "General options" else: title = "%s options" % section.capitalize() result += get_rst_title(title, "~") result += "%s\n" % get_rst_section(None, options) result += get_rst_title("Pylint checkers' options and switches", "-") result += """\ Pylint checkers can provide three set of features: * options that control their execution, * messages that they can raise, * reports that they can generate. Below is a list of all checkers and their features. """ by_checker = self._get_checkers_infos() for checker in sorted(by_checker): information = by_checker[checker] checker = information["checker"] del information["checker"] result += checker.get_full_documentation(**information) return result
def builder_inited(app: Optional[Sphinx]) -> None: """Output full documentation in ReST format for all extension modules.""" # PACKAGE/docs/exts/pylint_extensions.py --> PACKAGE/ base_path = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # PACKAGE/ --> PACKAGE/pylint/extensions ext_path = os.path.join(base_path, "pylint", "extensions") modules = [] doc_files = {} for filename in os.listdir(ext_path): name, ext = os.path.splitext(filename) if name[0] == "_": continue if ext == ".py": modules.append(f"pylint.extensions.{name}") elif ext == ".rst": doc_files["pylint.extensions." + name] = os.path.join( ext_path, filename) modules.sort() if not modules: sys.exit("No Pylint extensions found?") linter = PyLinter() linter.load_plugin_modules(modules) extensions_doc = os.path.join(base_path, "doc", "technical_reference", "extensions.rst") with open(extensions_doc, "w", encoding="utf-8") as stream: stream.write( get_rst_title("Optional Pylint checkers in the extensions module", "=")) stream.write("Pylint provides the following optional plugins:\n\n") for module in modules: stream.write(f"- :ref:`{module}`\n") stream.write("\n") stream.write("You can activate any or all of these extensions " "by adding a ``load-plugins`` line to the ``MASTER`` " "section of your ``.pylintrc``, for example::\n") stream.write("\n load-plugins=pylint.extensions.docparams," "pylint.extensions.docstyle\n\n") # Print checker documentation to stream by_checker = get_plugins_info(linter, doc_files) for checker, information in sorted(by_checker.items()): checker = information["checker"] del information["checker"] print(checker.get_full_documentation(**information)[:-1], file=stream)
def builder_inited(app: Optional[Sphinx]) -> None: # PACKAGE/docs/exts/pylint_extensions.py --> PACKAGE/ base_path = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) linter = PyLinter() linter.load_default_plugins() features = os.path.join(base_path, "doc", "user_guide", "checkers", "features.rst") with open(features, "w", encoding="utf-8") as stream: stream.write(get_rst_title("Pylint features", "=")) stream.write(""" .. This file is auto-generated. Make any changes to the associated .. docs extension in 'doc/exts/pylint_features.py'. """) print_full_documentation(linter, stream, False)
def builder_inited(app: Optional[Sphinx]) -> None: """Output full documentation in ReST format for all extension modules.""" # PACKAGE/docs/exts/pylint_extensions.py --> PACKAGE/ base_path = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ) # PACKAGE/ --> PACKAGE/pylint/extensions ext_path = os.path.join(base_path, "pylint", "extensions") modules = [] doc_files = {} for filename in os.listdir(ext_path): name, ext = os.path.splitext(filename) if name[0] == "_": continue if ext == ".py": modules.append(f"pylint.extensions.{name}") elif ext == ".rst": doc_files["pylint.extensions." + name] = os.path.join(ext_path, filename) modules.sort() if not modules: sys.exit("No Pylint extensions found?") linter = PyLinter() linter.load_plugin_modules(modules) extensions_doc = os.path.join( base_path, "doc", "user_guide", "checkers", "extensions.rst" ) with open(extensions_doc, "w", encoding="utf-8") as stream: stream.write(get_rst_title("Optional checkers", "=")) stream.write( """ .. This file is auto-generated. Make any changes to the associated .. docs extension in 'doc/exts/pylint_extensions.py'. """ ) stream.write("Pylint provides the following optional plugins:\n\n") for module in modules: stream.write(f"- :ref:`{module}`\n") stream.write("\n") stream.write( "You can activate any or all of these extensions " "by adding a ``load-plugins`` line to the ``MAIN`` " "section of your ``.pylintrc``, for example::\n" ) stream.write( "\n load-plugins=pylint.extensions.docparams," "pylint.extensions.docstyle\n\n" ) # Print checker documentation to stream by_checker = get_plugins_info(linter, doc_files) max_len = len(by_checker) for i, checker_information in enumerate(sorted(by_checker.items())): checker, information = checker_information j = -1 checker = information["checker"] del information["checker"] if i == max_len - 1: # Remove the \n\n at the end of the file j = -3 print( checker.get_full_documentation(**information, show_options=False)[:j], file=stream, )
def _create_checker_section( checker: str, options: list[OptionsData], linter: PyLinter ) -> str: checker_string = f".. _{checker}-options:\n\n" checker_string += get_rst_title(f"``{checker.capitalize()}`` **Checker**", "-") toml_doc = tomlkit.document() pylint_tool_table = tomlkit.table(is_super_table=True) toml_doc.add(tomlkit.key(["tool", "pylint"]), pylint_tool_table) checker_table = tomlkit.table() for option in sorted(options, key=lambda x: x.name): checker_string += get_rst_title(f"--{option.name}", '"') checker_string += f"*{option.optdict.get('help')}*\n\n" if option.optdict.get("default") == "": checker_string += '**Default:** ``""``\n\n\n' else: checker_string += f"**Default:** ``{option.optdict.get('default')}``\n\n\n" # Start adding the option to the toml example if option.optdict.get("hide_from_config_file"): continue # Get current value of option value = getattr(linter.config, option.name.replace("-", "_")) # Create a comment if the option has no value if value is None: checker_table.add(tomlkit.comment(f"{option.name} =")) checker_table.add(tomlkit.nl()) continue # Tomlkit doesn't support regular expressions if isinstance(value, re.Pattern): value = value.pattern elif ( isinstance(value, (list, tuple)) and value and isinstance(value[0], re.Pattern) ): value = [i.pattern for i in value] # Add to table checker_table.add(option.name, value) checker_table.add(tomlkit.nl()) pylint_tool_table.add(options[0].checker.name.lower(), checker_table) toml_string = "\n".join( f" {i}" if i else "" for i in tomlkit.dumps(toml_doc).split("\n") ) checker_string += f""" .. raw:: html <details> <summary><a>Example configuration section</a></summary> **Note:** Only ``pylint.tool`` is required, the section title is not. These are the default values. .. code-block:: toml {toml_string} .. raw:: html </details> """ return checker_string