Skip to content

Add visit_* and depart_* methods to docutils visitor classes #13928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
4 changes: 3 additions & 1 deletion stubs/docutils/@tests/stubtest_allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ docutils.io.FileOutput.__init__
docutils.languages.LanguageImporter.__getattr__
docutils.nodes.Element.__iter__ # doesn't exist at runtime, but the class is iterable due to __getitem__
docutils.nodes.Element.tagname # class variable is overridden in __init__ method
docutils.nodes.GenericNodeVisitor.__getattr__
docutils.nodes.NodeVisitor.depart_\w+ # Methods are discovered dynamically on commonly-used subclasses
docutils.nodes.NodeVisitor.visit_\w+ # Methods are discovered dynamically on commonly-used subclasses
# these methods take a rawsource parameter that has been deprecated and is completely ignored, so we omit it from the stub
docutils.nodes.Text.__new__
docutils.parsers.recommonmark_wrapper
Expand All @@ -18,3 +19,4 @@ docutils.statemachine.ViewList.__iter__ # doesn't exist at runtime, but the clas
docutils.transforms.Transform.__getattr__
docutils.transforms.Transformer.__getattr__
docutils.TransformSpec.unknown_reference_resolvers
docutils.writers.manpage.Translator.__getattr__
208 changes: 205 additions & 3 deletions stubs/docutils/docutils/nodes.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import sys
import xml.dom.minidom
from _typeshed import Incomplete
from abc import abstractmethod
from collections import Counter
from collections.abc import Callable, Generator, Iterable, Iterator, Mapping, Sequence
Expand Down Expand Up @@ -462,11 +461,214 @@ class NodeVisitor:
def unknown_visit(self, node: Node) -> Any: ...
def unknown_departure(self, node: Node) -> Any: ...

# These methods only exist on the subclasses `GenericNodeVisitor` and `SparseNodeVisitor` at runtime.
# If subclassing `NodeVisitor` directly, `visit_*` methods must be implemented for nodes and children that will be called
# with `Node.walk()` and `Node.walkabout()`.
# `depart_*` methods must also be implemented for nodes and children that will be called with `Node.walkabout()`.
def visit_Text(self, node: Text) -> Any: ...
def visit_abbreviation(self, node: abbreviation) -> Any: ...
def visit_acronym(self, node: acronym) -> Any: ...
def visit_address(self, node: address) -> Any: ...
def visit_admonition(self, node: admonition) -> Any: ...
def visit_attention(self, node: attention) -> Any: ...
def visit_attribution(self, node: attribution) -> Any: ...
def visit_author(self, node: author) -> Any: ...
def visit_authors(self, node: authors) -> Any: ...
def visit_block_quote(self, node: block_quote) -> Any: ...
def visit_bullet_list(self, node: bullet_list) -> Any: ...
def visit_caption(self, node: caption) -> Any: ...
def visit_caution(self, node: caution) -> Any: ...
def visit_citation(self, node: citation) -> Any: ...
def visit_citation_reference(self, node: citation_reference) -> Any: ...
def visit_classifier(self, node: classifier) -> Any: ...
def visit_colspec(self, node: colspec) -> Any: ...
def visit_comment(self, node: comment) -> Any: ...
def visit_compound(self, node: compound) -> Any: ...
def visit_contact(self, node: contact) -> Any: ...
def visit_container(self, node: container) -> Any: ...
def visit_copyright(self, node: copyright) -> Any: ...
def visit_danger(self, node: danger) -> Any: ...
def visit_date(self, node: date) -> Any: ...
def visit_decoration(self, node: decoration) -> Any: ...
def visit_definition(self, node: definition) -> Any: ...
def visit_definition_list(self, node: definition_list) -> Any: ...
def visit_definition_list_item(self, node: definition_list_item) -> Any: ...
def visit_description(self, node: description) -> Any: ...
def visit_docinfo(self, node: docinfo) -> Any: ...
def visit_doctest_block(self, node: doctest_block) -> Any: ...
def visit_document(self, node: _Document) -> Any: ...
def visit_emphasis(self, node: emphasis) -> Any: ...
def visit_entry(self, node: entry) -> Any: ...
def visit_enumerated_list(self, node: enumerated_list) -> Any: ...
def visit_error(self, node: error) -> Any: ...
def visit_field(self, node: field) -> Any: ...
def visit_field_body(self, node: field_body) -> Any: ...
def visit_field_list(self, node: field_list) -> Any: ...
def visit_field_name(self, node: field_name) -> Any: ...
def visit_figure(self, node: figure) -> Any: ...
def visit_footer(self, node: footer) -> Any: ...
def visit_footnote(self, node: footnote) -> Any: ...
def visit_footnote_reference(self, node: footnote_reference) -> Any: ...
def visit_generated(self, node: generated) -> Any: ...
def visit_header(self, node: header) -> Any: ...
def visit_hint(self, node: hint) -> Any: ...
def visit_image(self, node: image) -> Any: ...
def visit_important(self, node: important) -> Any: ...
def visit_inline(self, node: inline) -> Any: ...
def visit_label(self, node: label) -> Any: ...
def visit_legend(self, node: legend) -> Any: ...
def visit_line(self, node: line) -> Any: ...
def visit_line_block(self, node: line_block) -> Any: ...
def visit_list_item(self, node: list_item) -> Any: ...
def visit_literal(self, node: literal) -> Any: ...
def visit_literal_block(self, node: literal_block) -> Any: ...
def visit_math(self, node: math) -> Any: ...
def visit_math_block(self, node: math_block) -> Any: ...
def visit_meta(self, node: meta) -> Any: ...
def visit_note(self, node: note) -> Any: ...
def visit_option(self, node: option) -> Any: ...
def visit_option_argument(self, node: option_argument) -> Any: ...
def visit_option_group(self, node: option_group) -> Any: ...
def visit_option_list(self, node: option_list) -> Any: ...
def visit_option_list_item(self, node: option_list_item) -> Any: ...
def visit_option_string(self, node: option_string) -> Any: ...
def visit_organization(self, node: organization) -> Any: ...
def visit_paragraph(self, node: paragraph) -> Any: ...
def visit_pending(self, node: pending) -> Any: ...
def visit_problematic(self, node: problematic) -> Any: ...
def visit_raw(self, node: raw) -> Any: ...
def visit_reference(self, node: reference) -> Any: ...
def visit_revision(self, node: revision) -> Any: ...
def visit_row(self, node: row) -> Any: ...
def visit_rubric(self, node: rubric) -> Any: ...
def visit_section(self, node: section) -> Any: ...
def visit_sidebar(self, node: sidebar) -> Any: ...
def visit_status(self, node: status) -> Any: ...
def visit_strong(self, node: strong) -> Any: ...
def visit_subscript(self, node: subscript) -> Any: ...
def visit_substitution_definition(self, node: substitution_definition) -> Any: ...
def visit_substitution_reference(self, node: substitution_reference) -> Any: ...
def visit_subtitle(self, node: subtitle) -> Any: ...
def visit_superscript(self, node: superscript) -> Any: ...
def visit_system_message(self, node: system_message) -> Any: ...
def visit_table(self, node: table) -> Any: ...
def visit_target(self, node: target) -> Any: ...
def visit_tbody(self, node: tbody) -> Any: ...
def visit_term(self, node: term) -> Any: ...
def visit_tgroup(self, node: tgroup) -> Any: ...
def visit_thead(self, node: thead) -> Any: ...
def visit_tip(self, node: tip) -> Any: ...
def visit_title(self, node: title) -> Any: ...
def visit_title_reference(self, node: title_reference) -> Any: ...
def visit_topic(self, node: topic) -> Any: ...
def visit_transition(self, node: transition) -> Any: ...
def visit_version(self, node: version) -> Any: ...
def visit_warning(self, node: warning) -> Any: ...
def depart_Text(self, node: Text) -> Any: ...
def depart_abbreviation(self, node: abbreviation) -> Any: ...
def depart_acronym(self, node: acronym) -> Any: ...
def depart_address(self, node: address) -> Any: ...
def depart_admonition(self, node: admonition) -> Any: ...
def depart_attention(self, node: attention) -> Any: ...
def depart_attribution(self, node: attribution) -> Any: ...
def depart_author(self, node: author) -> Any: ...
def depart_authors(self, node: authors) -> Any: ...
def depart_block_quote(self, node: block_quote) -> Any: ...
def depart_bullet_list(self, node: bullet_list) -> Any: ...
def depart_caption(self, node: caption) -> Any: ...
def depart_caution(self, node: caution) -> Any: ...
def depart_citation(self, node: citation) -> Any: ...
def depart_citation_reference(self, node: citation_reference) -> Any: ...
def depart_classifier(self, node: classifier) -> Any: ...
def depart_colspec(self, node: colspec) -> Any: ...
def depart_comment(self, node: comment) -> Any: ...
def depart_compound(self, node: compound) -> Any: ...
def depart_contact(self, node: contact) -> Any: ...
def depart_container(self, node: container) -> Any: ...
def depart_copyright(self, node: copyright) -> Any: ...
def depart_danger(self, node: danger) -> Any: ...
def depart_date(self, node: date) -> Any: ...
def depart_decoration(self, node: decoration) -> Any: ...
def depart_definition(self, node: definition) -> Any: ...
def depart_definition_list(self, node: definition_list) -> Any: ...
def depart_definition_list_item(self, node: definition_list_item) -> Any: ...
def depart_description(self, node: description) -> Any: ...
def depart_docinfo(self, node: docinfo) -> Any: ...
def depart_doctest_block(self, node: doctest_block) -> Any: ...
def depart_document(self, node: _Document) -> Any: ...
def depart_emphasis(self, node: emphasis) -> Any: ...
def depart_entry(self, node: entry) -> Any: ...
def depart_enumerated_list(self, node: enumerated_list) -> Any: ...
def depart_error(self, node: error) -> Any: ...
def depart_field(self, node: field) -> Any: ...
def depart_field_body(self, node: field_body) -> Any: ...
def depart_field_list(self, node: field_list) -> Any: ...
def depart_field_name(self, node: field_name) -> Any: ...
def depart_figure(self, node: figure) -> Any: ...
def depart_footer(self, node: footer) -> Any: ...
def depart_footnote(self, node: footnote) -> Any: ...
def depart_footnote_reference(self, node: footnote_reference) -> Any: ...
def depart_generated(self, node: generated) -> Any: ...
def depart_header(self, node: header) -> Any: ...
def depart_hint(self, node: hint) -> Any: ...
def depart_image(self, node: image) -> Any: ...
def depart_important(self, node: important) -> Any: ...
def depart_inline(self, node: inline) -> Any: ...
def depart_label(self, node: label) -> Any: ...
def depart_legend(self, node: legend) -> Any: ...
def depart_line(self, node: line) -> Any: ...
def depart_line_block(self, node: line_block) -> Any: ...
def depart_list_item(self, node: list_item) -> Any: ...
def depart_literal(self, node: literal) -> Any: ...
def depart_literal_block(self, node: literal_block) -> Any: ...
def depart_math(self, node: math) -> Any: ...
def depart_math_block(self, node: math_block) -> Any: ...
def depart_meta(self, node: meta) -> Any: ...
def depart_note(self, node: note) -> Any: ...
def depart_option(self, node: option) -> Any: ...
def depart_option_argument(self, node: option_argument) -> Any: ...
def depart_option_group(self, node: option_group) -> Any: ...
def depart_option_list(self, node: option_list) -> Any: ...
def depart_option_list_item(self, node: option_list_item) -> Any: ...
def depart_option_string(self, node: option_string) -> Any: ...
def depart_organization(self, node: organization) -> Any: ...
def depart_paragraph(self, node: paragraph) -> Any: ...
def depart_pending(self, node: pending) -> Any: ...
def depart_problematic(self, node: problematic) -> Any: ...
def depart_raw(self, node: raw) -> Any: ...
def depart_reference(self, node: reference) -> Any: ...
def depart_revision(self, node: revision) -> Any: ...
def depart_row(self, node: row) -> Any: ...
def depart_rubric(self, node: rubric) -> Any: ...
def depart_section(self, node: section) -> Any: ...
def depart_sidebar(self, node: sidebar) -> Any: ...
def depart_status(self, node: status) -> Any: ...
def depart_strong(self, node: strong) -> Any: ...
def depart_subscript(self, node: subscript) -> Any: ...
def depart_substitution_definition(self, node: substitution_definition) -> Any: ...
def depart_substitution_reference(self, node: substitution_reference) -> Any: ...
def depart_subtitle(self, node: subtitle) -> Any: ...
def depart_superscript(self, node: superscript) -> Any: ...
def depart_system_message(self, node: system_message) -> Any: ...
def depart_table(self, node: table) -> Any: ...
def depart_target(self, node: target) -> Any: ...
def depart_tbody(self, node: tbody) -> Any: ...
def depart_term(self, node: term) -> Any: ...
def depart_tgroup(self, node: tgroup) -> Any: ...
def depart_thead(self, node: thead) -> Any: ...
def depart_tip(self, node: tip) -> Any: ...
def depart_title(self, node: title) -> Any: ...
def depart_title_reference(self, node: title_reference) -> Any: ...
def depart_topic(self, node: topic) -> Any: ...
def depart_transition(self, node: transition) -> Any: ...
def depart_version(self, node: version) -> Any: ...
def depart_warning(self, node: warning) -> Any: ...

class SparseNodeVisitor(NodeVisitor): ...

class GenericNodeVisitor(NodeVisitor):
# all the visit_<node_class_name> methods
def __getattr__(self, name: str, /) -> Incomplete: ...
def default_visit(self, node: Node) -> None: ...
def default_departure(self, node: Node) -> None: ...

class TreeCopyVisitor(GenericNodeVisitor):
parent_stack: list[Node]
Expand Down
16 changes: 16 additions & 0 deletions stubs/docutils/docutils/writers/manpage.pyi
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
import re
from _typeshed import Incomplete
from collections.abc import Callable
from typing import Protocol, type_check_only
from typing_extensions import Never

from docutils import nodes

@type_check_only
class _RegexPatternSub(Protocol):
# Matches the signature of the bound instance method `re.Pattern[str].sub` exactly
def __call__(self, /, repl: str | Callable[[re.Match[str]], str], string: str, count: int = 0) -> str: ...

class Translator(nodes.NodeVisitor):
def visit_admonition(self, node: nodes.admonition, name: str | None = None) -> None: ...
def visit_comment(self, node: nodes.comment, sub: _RegexPatternSub = ...) -> Never: ...
def __getattr__(self, name: str, /) -> Incomplete: ...

def __getattr__(name: str) -> Incomplete: ...