Skip to content

Commit 341fab4

Browse files
authored
Add visit_* and depart_* methods to docutils visitor classes (#13928)
1 parent 855999e commit 341fab4

3 files changed

Lines changed: 226 additions & 4 deletions

File tree

stubs/docutils/@tests/stubtest_allowlist.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ docutils.io.FileOutput.__getattr__
55
docutils.io.FileOutput.__init__
66
docutils.nodes.Element.__iter__ # doesn't exist at runtime, but the class is iterable due to __getitem__
77
docutils.nodes.Element.tagname # class variable is overridden in __init__ method
8-
docutils.nodes.GenericNodeVisitor.__getattr__
8+
docutils.nodes.NodeVisitor.depart_\w+ # Methods are discovered dynamically on commonly-used subclasses
9+
docutils.nodes.NodeVisitor.visit_\w+ # Methods are discovered dynamically on commonly-used subclasses
910
# these methods take a rawsource parameter that has been deprecated and is completely ignored, so we omit it from the stub
1011
docutils.nodes.Text.__new__
1112
docutils.parsers.recommonmark_wrapper
@@ -17,3 +18,4 @@ docutils.statemachine.ViewList.__iter__ # doesn't exist at runtime, but the clas
1718
docutils.transforms.Transform.__getattr__
1819
docutils.transforms.Transformer.__getattr__
1920
docutils.TransformSpec.unknown_reference_resolvers
21+
docutils.writers.manpage.Translator.__getattr__

stubs/docutils/docutils/nodes.pyi

Lines changed: 205 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import sys
22
import xml.dom.minidom
3-
from _typeshed import Incomplete
43
from abc import abstractmethod
54
from collections import Counter
65
from collections.abc import Callable, Generator, Iterable, Iterator, Mapping, Sequence
@@ -463,11 +462,214 @@ class NodeVisitor:
463462
def unknown_visit(self, node: Node) -> Any: ...
464463
def unknown_departure(self, node: Node) -> Any: ...
465464

465+
# These methods only exist on the subclasses `GenericNodeVisitor` and `SparseNodeVisitor` at runtime.
466+
# If subclassing `NodeVisitor` directly, `visit_*` methods must be implemented for nodes and children that will be called
467+
# with `Node.walk()` and `Node.walkabout()`.
468+
# `depart_*` methods must also be implemented for nodes and children that will be called with `Node.walkabout()`.
469+
def visit_Text(self, node: Text) -> Any: ...
470+
def visit_abbreviation(self, node: abbreviation) -> Any: ...
471+
def visit_acronym(self, node: acronym) -> Any: ...
472+
def visit_address(self, node: address) -> Any: ...
473+
def visit_admonition(self, node: admonition) -> Any: ...
474+
def visit_attention(self, node: attention) -> Any: ...
475+
def visit_attribution(self, node: attribution) -> Any: ...
476+
def visit_author(self, node: author) -> Any: ...
477+
def visit_authors(self, node: authors) -> Any: ...
478+
def visit_block_quote(self, node: block_quote) -> Any: ...
479+
def visit_bullet_list(self, node: bullet_list) -> Any: ...
480+
def visit_caption(self, node: caption) -> Any: ...
481+
def visit_caution(self, node: caution) -> Any: ...
482+
def visit_citation(self, node: citation) -> Any: ...
483+
def visit_citation_reference(self, node: citation_reference) -> Any: ...
484+
def visit_classifier(self, node: classifier) -> Any: ...
485+
def visit_colspec(self, node: colspec) -> Any: ...
486+
def visit_comment(self, node: comment) -> Any: ...
487+
def visit_compound(self, node: compound) -> Any: ...
488+
def visit_contact(self, node: contact) -> Any: ...
489+
def visit_container(self, node: container) -> Any: ...
490+
def visit_copyright(self, node: copyright) -> Any: ...
491+
def visit_danger(self, node: danger) -> Any: ...
492+
def visit_date(self, node: date) -> Any: ...
493+
def visit_decoration(self, node: decoration) -> Any: ...
494+
def visit_definition(self, node: definition) -> Any: ...
495+
def visit_definition_list(self, node: definition_list) -> Any: ...
496+
def visit_definition_list_item(self, node: definition_list_item) -> Any: ...
497+
def visit_description(self, node: description) -> Any: ...
498+
def visit_docinfo(self, node: docinfo) -> Any: ...
499+
def visit_doctest_block(self, node: doctest_block) -> Any: ...
500+
def visit_document(self, node: _Document) -> Any: ...
501+
def visit_emphasis(self, node: emphasis) -> Any: ...
502+
def visit_entry(self, node: entry) -> Any: ...
503+
def visit_enumerated_list(self, node: enumerated_list) -> Any: ...
504+
def visit_error(self, node: error) -> Any: ...
505+
def visit_field(self, node: field) -> Any: ...
506+
def visit_field_body(self, node: field_body) -> Any: ...
507+
def visit_field_list(self, node: field_list) -> Any: ...
508+
def visit_field_name(self, node: field_name) -> Any: ...
509+
def visit_figure(self, node: figure) -> Any: ...
510+
def visit_footer(self, node: footer) -> Any: ...
511+
def visit_footnote(self, node: footnote) -> Any: ...
512+
def visit_footnote_reference(self, node: footnote_reference) -> Any: ...
513+
def visit_generated(self, node: generated) -> Any: ...
514+
def visit_header(self, node: header) -> Any: ...
515+
def visit_hint(self, node: hint) -> Any: ...
516+
def visit_image(self, node: image) -> Any: ...
517+
def visit_important(self, node: important) -> Any: ...
518+
def visit_inline(self, node: inline) -> Any: ...
519+
def visit_label(self, node: label) -> Any: ...
520+
def visit_legend(self, node: legend) -> Any: ...
521+
def visit_line(self, node: line) -> Any: ...
522+
def visit_line_block(self, node: line_block) -> Any: ...
523+
def visit_list_item(self, node: list_item) -> Any: ...
524+
def visit_literal(self, node: literal) -> Any: ...
525+
def visit_literal_block(self, node: literal_block) -> Any: ...
526+
def visit_math(self, node: math) -> Any: ...
527+
def visit_math_block(self, node: math_block) -> Any: ...
528+
def visit_meta(self, node: meta) -> Any: ...
529+
def visit_note(self, node: note) -> Any: ...
530+
def visit_option(self, node: option) -> Any: ...
531+
def visit_option_argument(self, node: option_argument) -> Any: ...
532+
def visit_option_group(self, node: option_group) -> Any: ...
533+
def visit_option_list(self, node: option_list) -> Any: ...
534+
def visit_option_list_item(self, node: option_list_item) -> Any: ...
535+
def visit_option_string(self, node: option_string) -> Any: ...
536+
def visit_organization(self, node: organization) -> Any: ...
537+
def visit_paragraph(self, node: paragraph) -> Any: ...
538+
def visit_pending(self, node: pending) -> Any: ...
539+
def visit_problematic(self, node: problematic) -> Any: ...
540+
def visit_raw(self, node: raw) -> Any: ...
541+
def visit_reference(self, node: reference) -> Any: ...
542+
def visit_revision(self, node: revision) -> Any: ...
543+
def visit_row(self, node: row) -> Any: ...
544+
def visit_rubric(self, node: rubric) -> Any: ...
545+
def visit_section(self, node: section) -> Any: ...
546+
def visit_sidebar(self, node: sidebar) -> Any: ...
547+
def visit_status(self, node: status) -> Any: ...
548+
def visit_strong(self, node: strong) -> Any: ...
549+
def visit_subscript(self, node: subscript) -> Any: ...
550+
def visit_substitution_definition(self, node: substitution_definition) -> Any: ...
551+
def visit_substitution_reference(self, node: substitution_reference) -> Any: ...
552+
def visit_subtitle(self, node: subtitle) -> Any: ...
553+
def visit_superscript(self, node: superscript) -> Any: ...
554+
def visit_system_message(self, node: system_message) -> Any: ...
555+
def visit_table(self, node: table) -> Any: ...
556+
def visit_target(self, node: target) -> Any: ...
557+
def visit_tbody(self, node: tbody) -> Any: ...
558+
def visit_term(self, node: term) -> Any: ...
559+
def visit_tgroup(self, node: tgroup) -> Any: ...
560+
def visit_thead(self, node: thead) -> Any: ...
561+
def visit_tip(self, node: tip) -> Any: ...
562+
def visit_title(self, node: title) -> Any: ...
563+
def visit_title_reference(self, node: title_reference) -> Any: ...
564+
def visit_topic(self, node: topic) -> Any: ...
565+
def visit_transition(self, node: transition) -> Any: ...
566+
def visit_version(self, node: version) -> Any: ...
567+
def visit_warning(self, node: warning) -> Any: ...
568+
def depart_Text(self, node: Text) -> Any: ...
569+
def depart_abbreviation(self, node: abbreviation) -> Any: ...
570+
def depart_acronym(self, node: acronym) -> Any: ...
571+
def depart_address(self, node: address) -> Any: ...
572+
def depart_admonition(self, node: admonition) -> Any: ...
573+
def depart_attention(self, node: attention) -> Any: ...
574+
def depart_attribution(self, node: attribution) -> Any: ...
575+
def depart_author(self, node: author) -> Any: ...
576+
def depart_authors(self, node: authors) -> Any: ...
577+
def depart_block_quote(self, node: block_quote) -> Any: ...
578+
def depart_bullet_list(self, node: bullet_list) -> Any: ...
579+
def depart_caption(self, node: caption) -> Any: ...
580+
def depart_caution(self, node: caution) -> Any: ...
581+
def depart_citation(self, node: citation) -> Any: ...
582+
def depart_citation_reference(self, node: citation_reference) -> Any: ...
583+
def depart_classifier(self, node: classifier) -> Any: ...
584+
def depart_colspec(self, node: colspec) -> Any: ...
585+
def depart_comment(self, node: comment) -> Any: ...
586+
def depart_compound(self, node: compound) -> Any: ...
587+
def depart_contact(self, node: contact) -> Any: ...
588+
def depart_container(self, node: container) -> Any: ...
589+
def depart_copyright(self, node: copyright) -> Any: ...
590+
def depart_danger(self, node: danger) -> Any: ...
591+
def depart_date(self, node: date) -> Any: ...
592+
def depart_decoration(self, node: decoration) -> Any: ...
593+
def depart_definition(self, node: definition) -> Any: ...
594+
def depart_definition_list(self, node: definition_list) -> Any: ...
595+
def depart_definition_list_item(self, node: definition_list_item) -> Any: ...
596+
def depart_description(self, node: description) -> Any: ...
597+
def depart_docinfo(self, node: docinfo) -> Any: ...
598+
def depart_doctest_block(self, node: doctest_block) -> Any: ...
599+
def depart_document(self, node: _Document) -> Any: ...
600+
def depart_emphasis(self, node: emphasis) -> Any: ...
601+
def depart_entry(self, node: entry) -> Any: ...
602+
def depart_enumerated_list(self, node: enumerated_list) -> Any: ...
603+
def depart_error(self, node: error) -> Any: ...
604+
def depart_field(self, node: field) -> Any: ...
605+
def depart_field_body(self, node: field_body) -> Any: ...
606+
def depart_field_list(self, node: field_list) -> Any: ...
607+
def depart_field_name(self, node: field_name) -> Any: ...
608+
def depart_figure(self, node: figure) -> Any: ...
609+
def depart_footer(self, node: footer) -> Any: ...
610+
def depart_footnote(self, node: footnote) -> Any: ...
611+
def depart_footnote_reference(self, node: footnote_reference) -> Any: ...
612+
def depart_generated(self, node: generated) -> Any: ...
613+
def depart_header(self, node: header) -> Any: ...
614+
def depart_hint(self, node: hint) -> Any: ...
615+
def depart_image(self, node: image) -> Any: ...
616+
def depart_important(self, node: important) -> Any: ...
617+
def depart_inline(self, node: inline) -> Any: ...
618+
def depart_label(self, node: label) -> Any: ...
619+
def depart_legend(self, node: legend) -> Any: ...
620+
def depart_line(self, node: line) -> Any: ...
621+
def depart_line_block(self, node: line_block) -> Any: ...
622+
def depart_list_item(self, node: list_item) -> Any: ...
623+
def depart_literal(self, node: literal) -> Any: ...
624+
def depart_literal_block(self, node: literal_block) -> Any: ...
625+
def depart_math(self, node: math) -> Any: ...
626+
def depart_math_block(self, node: math_block) -> Any: ...
627+
def depart_meta(self, node: meta) -> Any: ...
628+
def depart_note(self, node: note) -> Any: ...
629+
def depart_option(self, node: option) -> Any: ...
630+
def depart_option_argument(self, node: option_argument) -> Any: ...
631+
def depart_option_group(self, node: option_group) -> Any: ...
632+
def depart_option_list(self, node: option_list) -> Any: ...
633+
def depart_option_list_item(self, node: option_list_item) -> Any: ...
634+
def depart_option_string(self, node: option_string) -> Any: ...
635+
def depart_organization(self, node: organization) -> Any: ...
636+
def depart_paragraph(self, node: paragraph) -> Any: ...
637+
def depart_pending(self, node: pending) -> Any: ...
638+
def depart_problematic(self, node: problematic) -> Any: ...
639+
def depart_raw(self, node: raw) -> Any: ...
640+
def depart_reference(self, node: reference) -> Any: ...
641+
def depart_revision(self, node: revision) -> Any: ...
642+
def depart_row(self, node: row) -> Any: ...
643+
def depart_rubric(self, node: rubric) -> Any: ...
644+
def depart_section(self, node: section) -> Any: ...
645+
def depart_sidebar(self, node: sidebar) -> Any: ...
646+
def depart_status(self, node: status) -> Any: ...
647+
def depart_strong(self, node: strong) -> Any: ...
648+
def depart_subscript(self, node: subscript) -> Any: ...
649+
def depart_substitution_definition(self, node: substitution_definition) -> Any: ...
650+
def depart_substitution_reference(self, node: substitution_reference) -> Any: ...
651+
def depart_subtitle(self, node: subtitle) -> Any: ...
652+
def depart_superscript(self, node: superscript) -> Any: ...
653+
def depart_system_message(self, node: system_message) -> Any: ...
654+
def depart_table(self, node: table) -> Any: ...
655+
def depart_target(self, node: target) -> Any: ...
656+
def depart_tbody(self, node: tbody) -> Any: ...
657+
def depart_term(self, node: term) -> Any: ...
658+
def depart_tgroup(self, node: tgroup) -> Any: ...
659+
def depart_thead(self, node: thead) -> Any: ...
660+
def depart_tip(self, node: tip) -> Any: ...
661+
def depart_title(self, node: title) -> Any: ...
662+
def depart_title_reference(self, node: title_reference) -> Any: ...
663+
def depart_topic(self, node: topic) -> Any: ...
664+
def depart_transition(self, node: transition) -> Any: ...
665+
def depart_version(self, node: version) -> Any: ...
666+
def depart_warning(self, node: warning) -> Any: ...
667+
466668
class SparseNodeVisitor(NodeVisitor): ...
467669

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

472674
class TreeCopyVisitor(GenericNodeVisitor):
473675
parent_stack: list[Node]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,19 @@
1+
import re
2+
from _typeshed import Incomplete
3+
from collections.abc import Callable
4+
from typing import Protocol, type_check_only
5+
from typing_extensions import Never
6+
7+
from docutils import nodes
8+
9+
@type_check_only
10+
class _RegexPatternSub(Protocol):
11+
# Matches the signature of the bound instance method `re.Pattern[str].sub` exactly
12+
def __call__(self, /, repl: str | Callable[[re.Match[str]], str], string: str, count: int = 0) -> str: ...
13+
14+
class Translator(nodes.NodeVisitor):
15+
def visit_admonition(self, node: nodes.admonition, name: str | None = None) -> None: ...
16+
def visit_comment(self, node: nodes.comment, sub: _RegexPatternSub = ...) -> Never: ...
17+
def __getattr__(self, name: str, /) -> Incomplete: ...
18+
119
def __getattr__(name: str): ... # incomplete module

0 commit comments

Comments
 (0)