From 75715de6a0e3f5d0d27f2390ee675920d6980c9d Mon Sep 17 00:00:00 2001 From: donBarbos Date: Thu, 29 May 2025 08:02:19 +0400 Subject: [PATCH 1/6] Improve `docutils.parsers` --- stubs/docutils/@tests/stubtest_allowlist.txt | 1 - stubs/docutils/docutils/parsers/__init__.pyi | 5 +- stubs/docutils/docutils/parsers/null.pyi | 1 + .../docutils/parsers/recommonmark_wrapper.pyi | 51 +++- .../docutils/parsers/rst/__init__.pyi | 10 +- .../parsers/rst/directives/__init__.pyi | 8 +- .../parsers/rst/directives/admonitions.pyi | 43 ++- .../docutils/parsers/rst/directives/body.pyi | 62 +++- .../docutils/parsers/rst/directives/html.pyi | 6 +- .../parsers/rst/directives/images.pyi | 19 +- .../docutils/parsers/rst/directives/misc.pyi | 15 +- .../docutils/parsers/rst/directives/parts.pyi | 4 + .../parsers/rst/directives/references.pyi | 4 + .../parsers/rst/directives/tables.pyi | 63 ++++- stubs/docutils/docutils/parsers/rst/roles.pyi | 5 +- .../docutils/docutils/parsers/rst/states.pyi | 265 +++++++++++++++++- .../docutils/parsers/rst/tableparser.pyi | 5 +- 17 files changed, 525 insertions(+), 42 deletions(-) diff --git a/stubs/docutils/@tests/stubtest_allowlist.txt b/stubs/docutils/@tests/stubtest_allowlist.txt index 5c15c83bb704..dc4c82d50003 100644 --- a/stubs/docutils/@tests/stubtest_allowlist.txt +++ b/stubs/docutils/@tests/stubtest_allowlist.txt @@ -11,7 +11,6 @@ docutils.nodes.NodeVisitor.visit_\w+ # Methods are discovered dynamically on co docutils.nodes.Text.__new__ docutils.parsers.recommonmark_wrapper docutils.parsers.rst.directives.admonitions.BaseAdmonition.node_class # must be overridden by base classes (pseudo-abstract) -docutils.parsers.rst.directives.misc.MetaBody.__getattr__ docutils.statemachine.State.nested_sm # is initialised in __init__ docutils.statemachine.State.nested_sm_kwargs # is initialised in __init__ docutils.statemachine.ViewList.__iter__ # doesn't exist at runtime, but the class is iterable due to __getitem__ diff --git a/stubs/docutils/docutils/parsers/__init__.pyi b/stubs/docutils/docutils/parsers/__init__.pyi index 04683301d1e2..59cebd764555 100644 --- a/stubs/docutils/docutils/parsers/__init__.pyi +++ b/stubs/docutils/docutils/parsers/__init__.pyi @@ -1,9 +1,12 @@ -from typing import Any, ClassVar +from typing import Any, ClassVar, Final from docutils import Component from docutils.nodes import document as _document +__docformat__: Final[str] + class Parser(Component): + settings_spec: ClassVar[tuple[Any, ...]] component_type: ClassVar[str] config_section: ClassVar[str] inputstring: Any # defined after call to setup_parse() diff --git a/stubs/docutils/docutils/parsers/null.pyi b/stubs/docutils/docutils/parsers/null.pyi index edc977325a1d..bd88e09cdfab 100644 --- a/stubs/docutils/docutils/parsers/null.pyi +++ b/stubs/docutils/docutils/parsers/null.pyi @@ -3,4 +3,5 @@ from typing import ClassVar from docutils import parsers class Parser(parsers.Parser): + supported: ClassVar[tuple[str, ...]] config_section_dependencies: ClassVar[tuple[str, ...]] diff --git a/stubs/docutils/docutils/parsers/recommonmark_wrapper.pyi b/stubs/docutils/docutils/parsers/recommonmark_wrapper.pyi index 5b0f74feb261..93a20f579660 100644 --- a/stubs/docutils/docutils/parsers/recommonmark_wrapper.pyi +++ b/stubs/docutils/docutils/parsers/recommonmark_wrapper.pyi @@ -1 +1,50 @@ -def __getattr__(name: str): ... # incomplete module +from types import ModuleType +from typing import ClassVar + +from docutils import nodes +from docutils.transforms import Transform + +class pending_xref(nodes.Inline, nodes.Element): ... + +sphinx: ModuleType + +def is_literal(node: nodes.Node) -> bool: ... + +class _CommonMarkParser: + default_config: ClassVar[dict[str, None]] + def __init__(self) -> None: ... + def convert_ast(self, ast): ... + def default_visit(self, mdnode): ... + def default_depart(self, mdnode): ... + def visit_heading(self, mdnode): ... + def depart_heading(self, _): ... + def visit_text(self, mdnode): ... + def visit_softbreak(self, _): ... + def visit_linebreak(self, _): ... + def visit_paragraph(self, mdnode): ... + def visit_emph(self, _): ... + def visit_strong(self, _): ... + def visit_code(self, mdnode): ... + def visit_link(self, mdnode): ... + def depart_link(self, mdnode): ... + def visit_image(self, mdnode): ... + def visit_list(self, mdnode): ... + def visit_item(self, mdnode): ... + def visit_code_block(self, mdnode): ... + def visit_block_quote(self, mdnode): ... + def visit_html(self, mdnode): ... + def visit_html_inline(self, mdnode): ... + def visit_html_block(self, mdnode): ... + def visit_thematic_break(self, _): ... + def setup_sections(self): ... + def add_section(self, section, level): ... + def is_section_level(self, level, section): ... + +class Parser(_CommonMarkParser): + supported: ClassVar[tuple[str, ...]] + config_section: ClassVar[str] + config_section_dependencies: ClassVar[tuple[str, ...]] + def get_transforms(self) -> list[type[Transform]]: ... + def parse(self, inputstring: str, document: nodes.document) -> None: ... + def visit_document(self, node) -> None: ... + def visit_text(self, mdnode) -> None: ... diff --git a/stubs/docutils/docutils/parsers/rst/__init__.pyi b/stubs/docutils/docutils/parsers/rst/__init__.pyi index 2d5d619ff873..08e70e472527 100644 --- a/stubs/docutils/docutils/parsers/rst/__init__.pyi +++ b/stubs/docutils/docutils/parsers/rst/__init__.pyi @@ -1,19 +1,22 @@ -from _typeshed import Incomplete from collections.abc import Callable, Sequence -from typing import Any, ClassVar, Literal +from typing import Any, ClassVar, Final, Literal from typing_extensions import TypeAlias from docutils import nodes, parsers from docutils.parsers.rst.states import Inliner, RSTState, RSTStateMachine from docutils.statemachine import StringList from docutils.transforms import Transform +from docutils.utils import Reporter + +__docformat__: Final[str] class Parser(parsers.Parser): - settings_spec: ClassVar[Incomplete] + settings_spec: ClassVar[tuple[Any, ...]] config_section_dependencies: ClassVar[tuple[str, ...]] initial_state: Literal["Body", "RFC2822Body"] state_classes: Sequence[type[RSTState]] inliner: Inliner | None + statemachine: RSTStateMachine def __init__(self, rfc2822: bool = False, inliner: Inliner | None = None) -> None: ... def get_transforms(self) -> list[type[Transform]]: ... def parse(self, inputstring: str, document: nodes.document) -> None: ... @@ -38,6 +41,7 @@ class Directive: block_text: str state: RSTState state_machine: RSTStateMachine = ... + reporter: Reporter def __init__( self, name: str, diff --git a/stubs/docutils/docutils/parsers/rst/directives/__init__.pyi b/stubs/docutils/docutils/parsers/rst/directives/__init__.pyi index 2de049ed5c09..70c4c07af847 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/__init__.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/__init__.pyi @@ -1,12 +1,14 @@ from collections.abc import Callable, Container, Iterable, Sequence from re import Pattern -from typing import Literal +from typing import Final, Literal from docutils.languages import _LanguageModule from docutils.nodes import document, system_message from docutils.parsers import Parser from docutils.parsers.rst import Directive +__docformat__: Final = "reStructuredText" + def register_directive(name: str, directive: type[Directive]) -> None: ... def directive( directive_name: str, language_module: _LanguageModule, document: document @@ -19,14 +21,14 @@ def uri(argument: str) -> str: ... def nonnegative_int(argument: str) -> int: ... def percentage(argument: str) -> int: ... -length_units: list[str] +length_units: Final[list[str]] def get_measure(argument: str, units: Iterable[str]) -> str: ... def length_or_unitless(argument: str) -> str: ... def length_or_percentage_or_unitless(argument: str, default: str = "") -> str: ... def class_option(argument: str) -> list[str]: ... -unicode_pattern: Pattern[str] +unicode_pattern: Final[Pattern[str]] def unicode_code(code: str) -> str: ... def single_char_or_unicode(argument: str) -> str: ... diff --git a/stubs/docutils/docutils/parsers/rst/directives/admonitions.pyi b/stubs/docutils/docutils/parsers/rst/directives/admonitions.pyi index 68a055d4e482..58c4e5debc63 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/admonitions.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/admonitions.pyi @@ -1,16 +1,39 @@ +from typing import Final + from docutils import nodes from docutils.parsers.rst import Directive +__docformat__: Final = "reStructuredText" + class BaseAdmonition(Directive): node_class: type[nodes.Admonition] # Subclasses must set this to the appropriate admonition node class. -class Admonition(BaseAdmonition): ... -class Attention(BaseAdmonition): ... -class Caution(BaseAdmonition): ... -class Danger(BaseAdmonition): ... -class Error(BaseAdmonition): ... -class Hint(BaseAdmonition): ... -class Important(BaseAdmonition): ... -class Note(BaseAdmonition): ... -class Tip(BaseAdmonition): ... -class Warning(BaseAdmonition): ... +class Admonition(BaseAdmonition): + node_class: type[nodes.admonition] + +class Attention(BaseAdmonition): + node_class: type[nodes.attention] + +class Caution(BaseAdmonition): + node_class: type[nodes.caution] + +class Danger(BaseAdmonition): + node_class: type[nodes.danger] + +class Error(BaseAdmonition): + node_class: type[nodes.error] + +class Hint(BaseAdmonition): + node_class: type[nodes.hint] + +class Important(BaseAdmonition): + node_class: type[nodes.important] + +class Note(BaseAdmonition): + node_class: type[nodes.note] + +class Tip(BaseAdmonition): + node_class: type[nodes.tip] + +class Warning(BaseAdmonition): + node_class: type[nodes.warning] diff --git a/stubs/docutils/docutils/parsers/rst/directives/body.pyi b/stubs/docutils/docutils/parsers/rst/directives/body.pyi index 5b0f74feb261..ec2b23fd66ad 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/body.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/body.pyi @@ -1 +1,61 @@ -def __getattr__(name: str): ... # incomplete module +from collections.abc import Callable +from typing import Any, ClassVar, Final + +from docutils import nodes +from docutils.parsers.rst import Directive + +__docformat__: Final = "reStructuredText" + +class BasePseudoSection(Directive): + option_spec: ClassVar[dict[str, Callable[[str], Any]]] + node_class: ClassVar[type[nodes.Node] | None] + def run(self): ... + +class Topic(BasePseudoSection): + node_class: ClassVar[type[nodes.Node]] + +class Sidebar(BasePseudoSection): + node_class: ClassVar[type[nodes.Node]] + option_spec: ClassVar[dict[str, Callable[[str], Any]]] + def run(self): ... + +class LineBlock(Directive): + option_spec: ClassVar[dict[str, Callable[[str], Any]]] + def run(self): ... + +class ParsedLiteral(Directive): + option_spec: ClassVar[dict[str, Callable[[str], Any]]] + def run(self): ... + +class CodeBlock(Directive): + option_spec: ClassVar[dict[str, Callable[[str], Any]]] + def run(self): ... + +class MathBlock(Directive): + option_spec: ClassVar[dict[str, Callable[[str], Any]]] + def run(self): ... + +class Rubric(Directive): + option_spec: ClassVar[dict[str, Callable[[str], Any]]] + def run(self): ... + +class BlockQuote(Directive): + classes: ClassVar[list[str]] + def run(self): ... + +class Epigraph(BlockQuote): + classes: ClassVar[list[str]] + +class Highlights(BlockQuote): + classes: ClassVar[list[str]] + +class PullQuote(BlockQuote): + classes: ClassVar[list[str]] + +class Compound(Directive): + option_spec: ClassVar[dict[str, Callable[[str], Any]]] + def run(self): ... + +class Container(Directive): + option_spec: ClassVar[dict[str, Callable[[str], Any]]] + def run(self): ... diff --git a/stubs/docutils/docutils/parsers/rst/directives/html.pyi b/stubs/docutils/docutils/parsers/rst/directives/html.pyi index 5b0f74feb261..d4dc9ba85ed5 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/html.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/html.pyi @@ -1 +1,5 @@ -def __getattr__(name: str): ... # incomplete module +from typing import Final + +from docutils.parsers.rst.directives.misc import Meta as Meta, MetaBody as MetaBody + +__docformat__: Final = "reStructuredText" diff --git a/stubs/docutils/docutils/parsers/rst/directives/images.pyi b/stubs/docutils/docutils/parsers/rst/directives/images.pyi index 5b0f74feb261..cd9654c65b4c 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/images.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/images.pyi @@ -1 +1,18 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Incomplete +from typing import Final + +from docutils.parsers.rst import Directive + +__docformat__: Final = "reStructuredText" + +class Image(Directive): + align_h_values: Incomplete + align_v_values: Incomplete + align_values: Incomplete + loading_values: Incomplete + def align(argument): ... + def loading(argument): ... + +class Figure(Image): + def align(argument): ... + def figwidth_value(argument): ... diff --git a/stubs/docutils/docutils/parsers/rst/directives/misc.pyi b/stubs/docutils/docutils/parsers/rst/directives/misc.pyi index 037c268f097f..bde9cf1bb97c 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/misc.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/misc.pyi @@ -1,12 +1,11 @@ -from _typeshed import Incomplete from pathlib import Path -from re import Pattern -from typing import ClassVar +from re import Match, Pattern +from typing import ClassVar, Final from docutils.parsers.rst import Directive from docutils.parsers.rst.states import SpecializedBody -__docformat__: str +__docformat__: Final = "reStructuredText" class Include(Directive): standard_include_path: Path @@ -25,9 +24,11 @@ class Role(Directive): class DefaultRole(Directive): ... class Title(Directive): ... -# SpecializedBody has not yet been stubbed -class MetaBody(SpecializedBody): # pyright: ignore[reportUntypedBaseClass] - def __getattr__(self, name: str) -> Incomplete: ... +class MetaBody(SpecializedBody): + def field_marker( # type: ignore[override] + self, match: Match[str], context: list[str], next_state: str | None + ) -> tuple[list[str], str | None, list[str]]: ... + def parsemeta(self, match: Match[str]): ... class Meta(Directive): SMkwargs: ClassVar[dict[str, tuple[MetaBody]]] diff --git a/stubs/docutils/docutils/parsers/rst/directives/parts.pyi b/stubs/docutils/docutils/parsers/rst/directives/parts.pyi index fa04acd7d954..c69296038b5b 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/parts.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/parts.pyi @@ -1,9 +1,13 @@ from collections.abc import Sequence +from typing import Final from docutils.parsers.rst import Directive +__docformat__: Final = "reStructuredText" + class Contents(Directive): backlinks_values: Sequence[str] + def backlinks(arg): ... class Sectnum(Directive): ... class Header(Directive): ... diff --git a/stubs/docutils/docutils/parsers/rst/directives/references.pyi b/stubs/docutils/docutils/parsers/rst/directives/references.pyi index 65677b399d50..412af33927d8 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/references.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/references.pyi @@ -1,3 +1,7 @@ +from typing import Final + from docutils.parsers.rst import Directive +__docformat__: Final = "reStructuredText" + class TargetNotes(Directive): ... diff --git a/stubs/docutils/docutils/parsers/rst/directives/tables.pyi b/stubs/docutils/docutils/parsers/rst/directives/tables.pyi index 5b0f74feb261..db0082a1d242 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/tables.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/tables.pyi @@ -1 +1,62 @@ -def __getattr__(name: str): ... # incomplete module +import csv +from _typeshed import Incomplete +from collections.abc import Callable +from typing import Any, ClassVar, Final + +from docutils.parsers.rst import Directive + +__docformat__: Final = "reStructuredText" + +def align(argument): ... + +class Table(Directive): + option_spec: ClassVar[dict[str, Callable[[str], Any]]] + def make_title(self): ... + def check_table_dimensions(self, rows, header_rows, stub_columns) -> None: ... + def set_table_width(self, table_node) -> None: ... + @property + def widths(self): ... + def get_column_widths(self, n_cols): ... + def extend_short_rows_with_empty_cells(self, columns, parts) -> None: ... + +class RSTTable(Table): + def run(self): ... + +class CSVTable(Table): + class DocutilsDialect(csv.Dialect): + delimiter: str + quotechar: str + doublequote: bool + skipinitialspace: bool + strict: bool + lineterminator: str + quoting: Incomplete + escapechar: Incomplete + def __init__(self, options) -> None: ... + + class HeaderDialect(csv.Dialect): + delimiter: str + quotechar: str + escapechar: str + doublequote: bool + skipinitialspace: bool + strict: bool + lineterminator: str + quoting: Incomplete + def __init__(self) -> None: ... + + @staticmethod + def check_requirements() -> None: ... + def process_header_option(self): ... + def run(self): ... + def get_csv_data(self): ... + @staticmethod + def decode_from_csv(s): ... + @staticmethod + def encode_for_csv(s): ... + def parse_csv_data_into_rows(self, csv_data, dialect, source): ... + +class ListTable(Table): + def run(self): ... + def check_list_content(self, node): ... + def build_table_from_list(self, table_data, col_widths, header_rows, stub_columns): ... diff --git a/stubs/docutils/docutils/parsers/rst/roles.pyi b/stubs/docutils/docutils/parsers/rst/roles.pyi index de9eb9a28f59..7c7eb992ec30 100644 --- a/stubs/docutils/docutils/parsers/rst/roles.pyi +++ b/stubs/docutils/docutils/parsers/rst/roles.pyi @@ -1,5 +1,5 @@ from collections.abc import Callable, Mapping, Sequence -from typing import Any +from typing import Any, Final from typing_extensions import TypeAlias import docutils.parsers.rst.states @@ -9,7 +9,8 @@ from docutils.nodes import Node, system_message from docutils.parsers.rst.states import Inliner from docutils.utils import Reporter -DEFAULT_INTERPRETED_ROLE: str +__docformat__: Final[str] +DEFAULT_INTERPRETED_ROLE: Final[str] _RoleFn: TypeAlias = Callable[ [str, str, str, int, docutils.parsers.rst.states.Inliner, Mapping[str, Any], Sequence[str]], diff --git a/stubs/docutils/docutils/parsers/rst/states.pyi b/stubs/docutils/docutils/parsers/rst/states.pyi index ae8059b595db..38c7f98945c4 100644 --- a/stubs/docutils/docutils/parsers/rst/states.pyi +++ b/stubs/docutils/docutils/parsers/rst/states.pyi @@ -2,20 +2,55 @@ from _typeshed import Incomplete from collections.abc import Callable, Iterable, Sequence from re import Match, Pattern from types import ModuleType -from typing import Any +from typing import Any, ClassVar, Final, NoReturn from typing_extensions import TypeAlias -from docutils import nodes -from docutils.statemachine import StateMachine, StateMachineWS, StateWS +from docutils import ApplicationError, DataError, nodes +from docutils.parsers.rst.languages import _RstLanguageModule +from docutils.statemachine import StateMachine, StateMachineWS, StateWS, StringList from docutils.utils import Reporter +__docformat__: Final = "reStructuredText" + +class MarkupError(DataError): ... +class UnknownInterpretedRoleError(DataError): ... +class InterpretedRoleNotImplementedError(DataError): ... +class ParserError(ApplicationError): ... +class MarkupMismatch(Exception): ... + class Struct: def __init__(self, **keywordargs) -> None: ... +class RSTStateMachine(StateMachineWS[list[str]]): + language: _RstLanguageModule + match_titles: bool + memo: Struct | None + document: nodes.document + reporter: Reporter + node: nodes.document | None + def run( # type: ignore[override] + self, + input_lines: Sequence[str] | StringList, + document: nodes.document, + input_offset: int = 0, + match_titles: bool = True, + inliner: Inliner | None = None, + ) -> None: ... + +class NestedStateMachine(StateMachineWS[list[str]]): + match_titles: bool + memo: Incomplete + document: nodes.document + reporter: Reporter + language: Incomplete + node: Incomplete + def run( # type: ignore[override] + self, input_lines: Sequence[str] | StringList, input_offset: int, memo, node, match_titles: bool = True + ) -> list[str]: ... + class RSTState(StateWS[list[str]]): - nested_sm: type[StateMachineWS[list[str]]] - nested_sm_cache: Incomplete - nested_sm_kwargs: Incomplete + nested_sm: type[NestedStateMachine] + nested_sm_cache: list[StateMachine[Incomplete]] def __init__(self, state_machine, debug: bool = False) -> None: ... memo: Incomplete reporter: Reporter @@ -68,7 +103,7 @@ class Inliner: start_string_prefix: str end_string_suffix: str parts: _DefinitionType - patterns: Any + patterns: Struct def init_customizations(self, settings: Any) -> None: ... reporter: Reporter document: nodes.document @@ -141,4 +176,218 @@ class Inliner: def implicit_inline(self, text: str, lineno: int) -> list[nodes.Text]: ... dispatch: dict[str, Callable[[Match[str], int], tuple[str, list[nodes.problematic], str, list[nodes.system_message]]]] = ... -def __getattr__(name: str): ... # incomplete module +class Body(RSTState): + double_width_pad_char: Incomplete + enum: Incomplete + grid_table_top_pat: Incomplete + simple_table_top_pat: Incomplete + simple_table_border_pat: Incomplete + pats: Incomplete + patterns: ClassVar[dict[str, str | Pattern[str]]] + initial_transitions: ClassVar[tuple[str, ...]] + def indent(self, match, context, next_state): ... + def block_quote(self, indented, line_offset): ... + attribution_pattern: Incomplete + def split_attribution(self, indented, line_offset): ... + def check_attribution(self, indented, attribution_start): ... + def parse_attribution(self, indented, line_offset): ... + def bullet(self, match, context, next_state): ... + def list_item(self, indent): ... + def enumerator(self, match, context, next_state): ... + def parse_enumerator(self, match, expected_sequence: Incomplete | None = None): ... + def is_enumerated_list_item(self, ordinal, sequence, format): ... + def make_enumerator(self, ordinal, sequence, format): ... + def field_marker(self, match, context, next_state): ... + def field(self, match): ... + def parse_field_marker(self, match): ... + def parse_field_body(self, indented, offset, node) -> None: ... + def option_marker(self, match, context, next_state): ... + def option_list_item(self, match): ... + def parse_option_marker(self, match): ... + def doctest(self, match, context, next_state): ... + def line_block(self, match, context, next_state): ... + def line_block_line(self, match, lineno): ... + def nest_line_block_lines(self, block) -> None: ... + def nest_line_block_segment(self, block) -> None: ... + def grid_table_top(self, match, context, next_state): ... + def simple_table_top(self, match, context, next_state): ... + def table_top(self, match, context, next_state, isolate_function, parser_class): ... + def table(self, isolate_function, parser_class): ... + def isolate_grid_table(self): ... + def isolate_simple_table(self): ... + def malformed_table(self, block, detail: str = "", offset: int = 0): ... + def build_table(self, tabledata, tableline, stub_columns: int = 0, widths: Incomplete | None = None): ... + def build_table_row(self, rowdata, tableline): ... + explicit: Incomplete + def footnote(self, match): ... + def citation(self, match): ... + def hyperlink_target(self, match): ... + def make_target(self, block, block_text, lineno, target_name): ... + def parse_target(self, block, block_text, lineno): ... + def is_reference(self, reference): ... + def add_target(self, targetname, refuri, target, lineno) -> None: ... + def substitution_def(self, match): ... + def disallowed_inside_substitution_definitions(self, node): ... + def directive(self, match, **option_presets): ... + def run_directive(self, directive, match, type_name, option_presets): ... + def parse_directive_block(self, indented, line_offset, directive, option_presets): ... + def parse_directive_options(self, option_presets, option_spec, arg_block): ... + def parse_directive_arguments(self, directive, arg_block): ... + def parse_extension_options(self, option_spec, datalines): ... + def unknown_directive(self, type_name): ... + def comment(self, match): ... + def explicit_markup(self, match, context, next_state): ... + def explicit_construct(self, match): ... + def explicit_list(self, blank_finish) -> None: ... + def anonymous(self, match: Match[str], context: list[str] | None, next_state: str): ... + def anonymous_target(self, match): ... + def line(self, match, context, next_state): ... + def text(self, match, context, next_state): ... + +class RFC2822Body(Body): + patterns: ClassVar[dict[str, str | Pattern[str]]] + initial_transitions: ClassVar[list[tuple[str | tuple[str, str], str]]] # type: ignore[assignment] + def rfc2822(self, match, context, next_state): ... + def rfc2822_field(self, match): ... + +class SpecializedBody(Body): + def invalid_input( + self, match: Match[str] | None = None, context: list[str] | None = None, next_state: str | None = None + ) -> NoReturn: ... + indent = invalid_input # type: ignore[assignment] + bullet = invalid_input + enumerator = invalid_input + field_marker = invalid_input + option_marker = invalid_input + doctest = invalid_input + line_block = invalid_input + grid_table_top = invalid_input + simple_table_top = invalid_input + explicit_markup = invalid_input + anonymous = invalid_input # type: ignore[assignment] + line = invalid_input + text = invalid_input + +class BulletList(SpecializedBody): + blank_finish: Incomplete + def bullet( # type: ignore[override] + self, match: Match[str], context: list[str] | None, next_state: str | None + ) -> tuple[list[str], str | None, list[str]]: ... + +class DefinitionList(SpecializedBody): + def text(self, match: Match[str], context: list[str] | None, next_state: str | None) -> tuple[list[str], str, list[str]]: ... # type: ignore[override] + +class EnumeratedList(SpecializedBody): + auto: int + blank_finish: Incomplete + lastordinal: Incomplete + def enumerator( # type: ignore[override] + self, match: Match[str], context: list[str] | None, next_state: str | None + ) -> tuple[list[str], str | None, list[str]]: ... + +class FieldList(SpecializedBody): + blank_finish: Incomplete + def field_marker( # type: ignore[override] + self, match: Match[str], context: list[str] | None, next_state: str | None + ) -> tuple[list[str], str | None, list[str]]: ... + +class OptionList(SpecializedBody): + blank_finish: Incomplete + def option_marker( # type: ignore[override] + self, match: Match[str], context: list[str] | None, next_state: str | None + ) -> tuple[list[str], str | None, list[str]]: ... + +class RFC2822List(SpecializedBody, RFC2822Body): + patterns: ClassVar[dict[str, str | Pattern[str]]] + initial_transitions: ClassVar[list[tuple[str | tuple[str, str], str]]] # type: ignore[assignment] + blank_finish: Incomplete + def rfc2822(self, match, context, next_state): ... + blank: Incomplete + +class ExtensionOptions(FieldList): + def parse_field_body(self, indented, offset, node) -> None: ... + +class LineBlock(SpecializedBody): + blank: Incomplete + blank_finish: Incomplete + def line_block( # type: ignore[override] + self, match: Match[str], context: list[str] | None, next_state: str | None + ) -> tuple[list[str], str | None, list[str]]: ... + +class Explicit(SpecializedBody): + blank_finish: Incomplete + blank: Incomplete + def explicit_markup( # type: ignore[override] + self, match: Match[str], context: list[str] | None, next_state: str | None + ) -> tuple[list[str], str | None, list[str]]: ... + def anonymous( # type: ignore[override] + self, match: Match[str], context: list[str] | None, next_state: str | None + ) -> tuple[list[str], str | None, list[str]]: ... + +class SubstitutionDef(Body): + patterns: ClassVar[dict[str, str | Pattern[str]]] + initial_transitions: ClassVar[list[str]] # type: ignore[assignment] + blank_finish: Incomplete + def embedded_directive(self, match, context, next_state) -> None: ... + def text(self, match, context, next_state) -> None: ... + +class Text(RSTState): + patterns: ClassVar[dict[str, str | Pattern[str]]] + initial_transitions: ClassVar[list[tuple[str, str]]] + def blank(self, match, context, next_state): ... + def eof(self, context): ... + def indent(self, match, context, next_state): ... + def underline(self, match, context, next_state): ... + def text(self, match, context, next_state): ... + def literal_block(self): ... + def quoted_literal_block(self): ... + def definition_list_item(self, termline): ... + classifier_delimiter: Incomplete + def term(self, lines, lineno): ... + +class SpecializedText(Text): + def eof(self, context): ... + def invalid_input( + self, match: Match[str] | None = None, context: list[str] | None = None, next_state: str | None = None + ) -> NoReturn: ... + blank = invalid_input + indent = invalid_input + underline = invalid_input + text = invalid_input + +class Definition(SpecializedText): + def eof(self, context): ... + blank_finish: Incomplete + def indent( # type: ignore[override] + self, match: Match[str] | None, context: list[str], next_state: str | None + ) -> tuple[list[str], str, list[str]]: ... + +class Line(SpecializedText): + eofcheck: int + def eof(self, context: list[str]): ... + def blank(self, match: Match[str] | None, context: list[str], next_state: str | None) -> tuple[list[str], str, list[str]]: ... # type: ignore[override] + def text(self, match: Match[str], context: list[str], next_state: str | None) -> tuple[list[str], str, list[str]]: ... # type: ignore[override] + indent = text # type: ignore[assignment] + def underline( # type: ignore[override] + self, match: Match[str] | None, context: list[str], next_state: str | None + ) -> tuple[list[str], str, list[str]]: ... + def short_overline(self, context, blocktext, lineno, lines: int = 1) -> None: ... + def state_correction(self, context, lines: int = 1) -> None: ... + +class QuotedLiteralBlock(RSTState): + patterns: ClassVar[dict[str, str | Pattern[str]]] + messages: Incomplete + initial_lineno: Incomplete + def __init__(self, state_machine, debug: bool = False) -> None: ... + def blank(self, match, context, next_state): ... + def eof(self, context): ... + def indent(self, match: Match[str] | None, context: list[str], next_state: str | None) -> NoReturn: ... + def initial_quoted( + self, match: Match[str], context: list[str] | None, next_state: str | None + ) -> tuple[list[str], str | None, list[str]]: ... + def quoted( + self, match: Match[str], context: list[str], next_state: str | None + ) -> tuple[list[str], str | None, list[str]]: ... + def text(self, match: Match[str] | None, context: list[str] | None, next_state: str | None) -> None: ... + +state_classes: tuple[type[RSTState], ...] diff --git a/stubs/docutils/docutils/parsers/rst/tableparser.pyi b/stubs/docutils/docutils/parsers/rst/tableparser.pyi index 2db35a5604bc..dfb95bff53f3 100644 --- a/stubs/docutils/docutils/parsers/rst/tableparser.pyi +++ b/stubs/docutils/docutils/parsers/rst/tableparser.pyi @@ -1,5 +1,5 @@ from re import Pattern -from typing import ClassVar +from typing import ClassVar, Final from typing_extensions import TypeAlias from docutils import DataError @@ -9,7 +9,7 @@ _Cell: TypeAlias = tuple[int, int, int, list[str]] _Row: TypeAlias = list[_Cell | None] _Colspecs: TypeAlias = list[int] -__docformat__: str +__docformat__: Final = "reStructuredText" class TableMarkupError(DataError): offset: int @@ -18,6 +18,7 @@ class TableMarkupError(DataError): class TableParser: head_body_separator_pat: ClassVar[Pattern[str] | None] double_width_pad_char: ClassVar[str] + head_body_sep: int def parse(self, block: StringList) -> tuple[_Colspecs, list[_Row], list[_Row]]: ... def find_head_body_sep(self) -> None: ... From e3e51ad956552f90cfcc4377fc7f8bb3ae6eb7a4 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Thu, 29 May 2025 08:08:10 +0400 Subject: [PATCH 2/6] Unify final str style --- stubs/docutils/docutils/parsers/__init__.pyi | 2 +- stubs/docutils/docutils/parsers/rst/__init__.pyi | 2 +- stubs/docutils/docutils/parsers/rst/roles.pyi | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/stubs/docutils/docutils/parsers/__init__.pyi b/stubs/docutils/docutils/parsers/__init__.pyi index 59cebd764555..541ef727df90 100644 --- a/stubs/docutils/docutils/parsers/__init__.pyi +++ b/stubs/docutils/docutils/parsers/__init__.pyi @@ -3,7 +3,7 @@ from typing import Any, ClassVar, Final from docutils import Component from docutils.nodes import document as _document -__docformat__: Final[str] +__docformat__: Final = "reStructuredText" class Parser(Component): settings_spec: ClassVar[tuple[Any, ...]] diff --git a/stubs/docutils/docutils/parsers/rst/__init__.pyi b/stubs/docutils/docutils/parsers/rst/__init__.pyi index 08e70e472527..59361c0f7319 100644 --- a/stubs/docutils/docutils/parsers/rst/__init__.pyi +++ b/stubs/docutils/docutils/parsers/rst/__init__.pyi @@ -8,7 +8,7 @@ from docutils.statemachine import StringList from docutils.transforms import Transform from docutils.utils import Reporter -__docformat__: Final[str] +__docformat__: Final = "reStructuredText" class Parser(parsers.Parser): settings_spec: ClassVar[tuple[Any, ...]] diff --git a/stubs/docutils/docutils/parsers/rst/roles.pyi b/stubs/docutils/docutils/parsers/rst/roles.pyi index 7c7eb992ec30..eb1b39446de0 100644 --- a/stubs/docutils/docutils/parsers/rst/roles.pyi +++ b/stubs/docutils/docutils/parsers/rst/roles.pyi @@ -9,8 +9,8 @@ from docutils.nodes import Node, system_message from docutils.parsers.rst.states import Inliner from docutils.utils import Reporter -__docformat__: Final[str] -DEFAULT_INTERPRETED_ROLE: Final[str] +__docformat__: Final = "reStructuredText" +DEFAULT_INTERPRETED_ROLE: Final = "title-reference" _RoleFn: TypeAlias = Callable[ [str, str, str, int, docutils.parsers.rst.states.Inliner, Mapping[str, Any], Sequence[str]], From 3d1338d5a1d3a063dc80324661aa2a2e88a1cc65 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Thu, 29 May 2025 08:12:09 +0400 Subject: [PATCH 3/6] Correct pre commit --- stubs/docutils/docutils/parsers/rst/states.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stubs/docutils/docutils/parsers/rst/states.pyi b/stubs/docutils/docutils/parsers/rst/states.pyi index 38c7f98945c4..8e657cd3cdad 100644 --- a/stubs/docutils/docutils/parsers/rst/states.pyi +++ b/stubs/docutils/docutils/parsers/rst/states.pyi @@ -194,7 +194,7 @@ class Body(RSTState): def bullet(self, match, context, next_state): ... def list_item(self, indent): ... def enumerator(self, match, context, next_state): ... - def parse_enumerator(self, match, expected_sequence: Incomplete | None = None): ... + def parse_enumerator(self, match, expected_sequence=None): ... def is_enumerated_list_item(self, ordinal, sequence, format): ... def make_enumerator(self, ordinal, sequence, format): ... def field_marker(self, match, context, next_state): ... @@ -216,7 +216,7 @@ class Body(RSTState): def isolate_grid_table(self): ... def isolate_simple_table(self): ... def malformed_table(self, block, detail: str = "", offset: int = 0): ... - def build_table(self, tabledata, tableline, stub_columns: int = 0, widths: Incomplete | None = None): ... + def build_table(self, tabledata, tableline, stub_columns: int = 0, widths=None): ... def build_table_row(self, rowdata, tableline): ... explicit: Incomplete def footnote(self, match): ... From ae2c255023c9b87c1d676dd6adefb8471ed8394c Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sat, 31 May 2025 15:28:04 +0400 Subject: [PATCH 4/6] Solve `Any` issues --- stubs/docutils/docutils/__init__.pyi | 2 +- stubs/docutils/docutils/parsers/__init__.pyi | 13 +++++------ .../docutils/parsers/rst/__init__.pyi | 6 ++--- .../docutils/parsers/rst/directives/body.pyi | 23 +++++++++++-------- .../parsers/rst/directives/tables.pyi | 4 ++-- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/stubs/docutils/docutils/__init__.pyi b/stubs/docutils/docutils/__init__.pyi index f1f699cdf0fb..d275e01a543b 100644 --- a/stubs/docutils/docutils/__init__.pyi +++ b/stubs/docutils/docutils/__init__.pyi @@ -26,7 +26,7 @@ class ApplicationError(Exception): ... class DataError(ApplicationError): ... class SettingsSpec: - settings_spec: ClassVar[tuple[Any, ...]] + settings_spec: ClassVar[tuple[Any, ...]] # Mixed tuple structure; uses Any for flexibility in nested option definitions settings_defaults: ClassVar[dict[Any, Any] | None] settings_default_overrides: ClassVar[dict[Any, Any] | None] relative_path_settings: ClassVar[tuple[Any, ...]] diff --git a/stubs/docutils/docutils/parsers/__init__.pyi b/stubs/docutils/docutils/parsers/__init__.pyi index 541ef727df90..1c301b050641 100644 --- a/stubs/docutils/docutils/parsers/__init__.pyi +++ b/stubs/docutils/docutils/parsers/__init__.pyi @@ -1,18 +1,17 @@ -from typing import Any, ClassVar, Final +from typing import ClassVar, Final from docutils import Component -from docutils.nodes import document as _document +from docutils.nodes import _Document __docformat__: Final = "reStructuredText" class Parser(Component): - settings_spec: ClassVar[tuple[Any, ...]] component_type: ClassVar[str] config_section: ClassVar[str] - inputstring: Any # defined after call to setup_parse() - document: Any # defined after call to setup_parse() - def parse(self, inputstring: str, document: _document) -> None: ... - def setup_parse(self, inputstring: str, document: _document) -> None: ... + inputstring: str # defined after call to setup_parse() + document: _Document # defined after call to setup_parse() + def parse(self, inputstring: str, document: _Document) -> None: ... + def setup_parse(self, inputstring: str, document: _Document) -> None: ... def finish_parse(self) -> None: ... _parser_aliases: dict[str, str] diff --git a/stubs/docutils/docutils/parsers/rst/__init__.pyi b/stubs/docutils/docutils/parsers/rst/__init__.pyi index 59361c0f7319..1b7368631b0d 100644 --- a/stubs/docutils/docutils/parsers/rst/__init__.pyi +++ b/stubs/docutils/docutils/parsers/rst/__init__.pyi @@ -1,3 +1,4 @@ +from _typeshed import Incomplete from collections.abc import Callable, Sequence from typing import Any, ClassVar, Final, Literal from typing_extensions import TypeAlias @@ -11,7 +12,6 @@ from docutils.utils import Reporter __docformat__: Final = "reStructuredText" class Parser(parsers.Parser): - settings_spec: ClassVar[tuple[Any, ...]] config_section_dependencies: ClassVar[tuple[str, ...]] initial_state: Literal["Body", "RFC2822Body"] state_classes: Sequence[type[RSTState]] @@ -34,7 +34,7 @@ class Directive: has_content: ClassVar[bool] name: str arguments: list[str] - options: dict[str, Any] + options: dict[str, Incomplete] content: StringList lineno: int content_offset: int @@ -46,7 +46,7 @@ class Directive: self, name: str, arguments: list[str], - options: dict[str, Any], + options: dict[str, Incomplete], content: StringList, lineno: int, content_offset: int, diff --git a/stubs/docutils/docutils/parsers/rst/directives/body.pyi b/stubs/docutils/docutils/parsers/rst/directives/body.pyi index ec2b23fd66ad..cbccd5221fd7 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/body.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/body.pyi @@ -1,13 +1,16 @@ from collections.abc import Callable -from typing import Any, ClassVar, Final +from typing import ClassVar, Final +from typing_extensions import TypeAlias from docutils import nodes from docutils.parsers.rst import Directive __docformat__: Final = "reStructuredText" +_DirectiveFn: TypeAlias = Callable[[str | None], str | list[str]] + class BasePseudoSection(Directive): - option_spec: ClassVar[dict[str, Callable[[str], Any]]] + option_spec: ClassVar[dict[str, _DirectiveFn]] node_class: ClassVar[type[nodes.Node] | None] def run(self): ... @@ -16,27 +19,27 @@ class Topic(BasePseudoSection): class Sidebar(BasePseudoSection): node_class: ClassVar[type[nodes.Node]] - option_spec: ClassVar[dict[str, Callable[[str], Any]]] + option_spec: ClassVar[dict[str, _DirectiveFn]] def run(self): ... class LineBlock(Directive): - option_spec: ClassVar[dict[str, Callable[[str], Any]]] + option_spec: ClassVar[dict[str, _DirectiveFn]] def run(self): ... class ParsedLiteral(Directive): - option_spec: ClassVar[dict[str, Callable[[str], Any]]] + option_spec: ClassVar[dict[str, _DirectiveFn]] def run(self): ... class CodeBlock(Directive): - option_spec: ClassVar[dict[str, Callable[[str], Any]]] + option_spec: ClassVar[dict[str, _DirectiveFn]] def run(self): ... class MathBlock(Directive): - option_spec: ClassVar[dict[str, Callable[[str], Any]]] + option_spec: ClassVar[dict[str, _DirectiveFn]] def run(self): ... class Rubric(Directive): - option_spec: ClassVar[dict[str, Callable[[str], Any]]] + option_spec: ClassVar[dict[str, _DirectiveFn]] def run(self): ... class BlockQuote(Directive): @@ -53,9 +56,9 @@ class PullQuote(BlockQuote): classes: ClassVar[list[str]] class Compound(Directive): - option_spec: ClassVar[dict[str, Callable[[str], Any]]] + option_spec: ClassVar[dict[str, _DirectiveFn]] def run(self): ... class Container(Directive): - option_spec: ClassVar[dict[str, Callable[[str], Any]]] + option_spec: ClassVar[dict[str, _DirectiveFn]] def run(self): ... diff --git a/stubs/docutils/docutils/parsers/rst/directives/tables.pyi b/stubs/docutils/docutils/parsers/rst/directives/tables.pyi index db0082a1d242..f420669e19b6 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/tables.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/tables.pyi @@ -1,7 +1,7 @@ import csv from _typeshed import Incomplete from collections.abc import Callable -from typing import Any, ClassVar, Final +from typing import ClassVar, Final from docutils.parsers.rst import Directive @@ -10,7 +10,7 @@ __docformat__: Final = "reStructuredText" def align(argument): ... class Table(Directive): - option_spec: ClassVar[dict[str, Callable[[str], Any]]] + option_spec: ClassVar[dict[str, Callable[[str | None], str | list[str]]]] def make_title(self): ... def check_table_dimensions(self, rows, header_rows, stub_columns) -> None: ... def set_table_width(self, table_node) -> None: ... From 4d876ed9c7d93be78533ccdf97f6a76c5e63ea56 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sat, 31 May 2025 15:35:21 +0400 Subject: [PATCH 5/6] Solve override issues --- stubs/docutils/docutils/parsers/rst/__init__.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/docutils/docutils/parsers/rst/__init__.pyi b/stubs/docutils/docutils/parsers/rst/__init__.pyi index 1b7368631b0d..ccdc6bd5c170 100644 --- a/stubs/docutils/docutils/parsers/rst/__init__.pyi +++ b/stubs/docutils/docutils/parsers/rst/__init__.pyi @@ -30,7 +30,7 @@ class Directive: required_arguments: ClassVar[int] optional_arguments: ClassVar[int] final_argument_whitespace: ClassVar[bool] - option_spec: ClassVar[dict[str, Callable[[str], Any]] | None] + option_spec: ClassVar[dict[str, Callable[[str | None], Incomplete]] | None] has_content: ClassVar[bool] name: str arguments: list[str] From 9ea83ebe1dbf0c8bb264ee138d2131800589cd71 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Mon, 2 Jun 2025 21:25:33 +0400 Subject: [PATCH 6/6] Revert `option_spec` class var --- stubs/docutils/docutils/parsers/rst/__init__.pyi | 2 +- stubs/docutils/docutils/parsers/rst/directives/body.pyi | 2 +- stubs/docutils/docutils/parsers/rst/directives/tables.pyi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/stubs/docutils/docutils/parsers/rst/__init__.pyi b/stubs/docutils/docutils/parsers/rst/__init__.pyi index ccdc6bd5c170..75f834719d97 100644 --- a/stubs/docutils/docutils/parsers/rst/__init__.pyi +++ b/stubs/docutils/docutils/parsers/rst/__init__.pyi @@ -30,7 +30,7 @@ class Directive: required_arguments: ClassVar[int] optional_arguments: ClassVar[int] final_argument_whitespace: ClassVar[bool] - option_spec: ClassVar[dict[str, Callable[[str | None], Incomplete]] | None] + option_spec: ClassVar[dict[str, Callable[[str], Incomplete]] | None] has_content: ClassVar[bool] name: str arguments: list[str] diff --git a/stubs/docutils/docutils/parsers/rst/directives/body.pyi b/stubs/docutils/docutils/parsers/rst/directives/body.pyi index cbccd5221fd7..d1fa231201e6 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/body.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/body.pyi @@ -7,7 +7,7 @@ from docutils.parsers.rst import Directive __docformat__: Final = "reStructuredText" -_DirectiveFn: TypeAlias = Callable[[str | None], str | list[str]] +_DirectiveFn: TypeAlias = Callable[[str], str | list[str]] class BasePseudoSection(Directive): option_spec: ClassVar[dict[str, _DirectiveFn]] diff --git a/stubs/docutils/docutils/parsers/rst/directives/tables.pyi b/stubs/docutils/docutils/parsers/rst/directives/tables.pyi index f420669e19b6..ebde406d577e 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/tables.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/tables.pyi @@ -10,7 +10,7 @@ __docformat__: Final = "reStructuredText" def align(argument): ... class Table(Directive): - option_spec: ClassVar[dict[str, Callable[[str | None], str | list[str]]]] + option_spec: ClassVar[dict[str, Callable[[str], str | list[str]]]] def make_title(self): ... def check_table_dimensions(self, rows, header_rows, stub_columns) -> None: ... def set_table_width(self, table_node) -> None: ...