From c4405af4ab689633a0bef268fb8518e30194ab6b Mon Sep 17 00:00:00 2001 From: bzoracler <50305397+bzoracler@users.noreply.github.com> Date: Sat, 3 May 2025 19:28:42 +1200 Subject: [PATCH 01/11] feat: add `visit_*` and `depart_*` methods --- stubs/docutils/@tests/stubtest_allowlist.txt | 1 + stubs/docutils/docutils/nodes.pyi | 198 +++++++++++++++++++ 2 files changed, 199 insertions(+) diff --git a/stubs/docutils/@tests/stubtest_allowlist.txt b/stubs/docutils/@tests/stubtest_allowlist.txt index 7e7784921b80..675e6aa6dca4 100644 --- a/stubs/docutils/@tests/stubtest_allowlist.txt +++ b/stubs/docutils/@tests/stubtest_allowlist.txt @@ -7,6 +7,7 @@ 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.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 diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index f9a15b5a936a..610d1216043e 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -461,6 +461,204 @@ class NodeVisitor: def dispatch_departure(self, node: Node) -> Any: ... def unknown_visit(self, node: Node) -> Any: ... def unknown_departure(self, node: Node) -> Any: ... + 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): ... From b9e1e869dbaceafca89cb3789c2e6697099d2f7d Mon Sep 17 00:00:00 2001 From: bzoracler <50305397+bzoracler@users.noreply.github.com> Date: Sat, 3 May 2025 19:30:06 +1200 Subject: [PATCH 02/11] improvement: dynamic attribute getter no longer needed --- stubs/docutils/@tests/stubtest_allowlist.txt | 1 - stubs/docutils/docutils/nodes.pyi | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/stubs/docutils/@tests/stubtest_allowlist.txt b/stubs/docutils/@tests/stubtest_allowlist.txt index 675e6aa6dca4..085b83245fd8 100644 --- a/stubs/docutils/@tests/stubtest_allowlist.txt +++ b/stubs/docutils/@tests/stubtest_allowlist.txt @@ -6,7 +6,6 @@ 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.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__ diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 610d1216043e..84abc053242b 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -661,10 +661,7 @@ class NodeVisitor: def depart_warning(self, node: warning) -> Any: ... class SparseNodeVisitor(NodeVisitor): ... - -class GenericNodeVisitor(NodeVisitor): - # all the visit_ methods - def __getattr__(self, name: str, /) -> Incomplete: ... +class GenericNodeVisitor(NodeVisitor): ... class TreeCopyVisitor(GenericNodeVisitor): parent_stack: list[Node] From e8b060517882fb69923ff38450483a5406762451 Mon Sep 17 00:00:00 2001 From: bzoracler <50305397+bzoracler@users.noreply.github.com> Date: Sat, 3 May 2025 19:50:45 +1200 Subject: [PATCH 03/11] docs: add usage notes --- stubs/docutils/docutils/nodes.pyi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 84abc053242b..909a6a32f0d2 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -461,6 +461,11 @@ class NodeVisitor: def dispatch_departure(self, node: Node) -> Any: ... 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: ... From f0fdd051d00e036052dc1611f899d5106588ecc5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 3 May 2025 08:08:50 +0000 Subject: [PATCH 04/11] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/docutils/docutils/nodes.pyi | 1 - 1 file changed, 1 deletion(-) diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 909a6a32f0d2..8fcb7feef7b9 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -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 From 25b410176555e5ecaca35a1d3248c2dc97737c97 Mon Sep 17 00:00:00 2001 From: bzoracler <50305397+bzoracler@users.noreply.github.com> Date: Sat, 3 May 2025 20:16:32 +1200 Subject: [PATCH 05/11] fix: Avoid usage of shadowed `document` class member --- stubs/docutils/docutils/nodes.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 8fcb7feef7b9..d5f95e0d4db9 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -496,7 +496,7 @@ class NodeVisitor: 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_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: ... @@ -595,7 +595,7 @@ class NodeVisitor: 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_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: ... From bda672fcf0c297c0328e4aa1490b2c86e156754b Mon Sep 17 00:00:00 2001 From: bzoracler <50305397+bzoracler@users.noreply.github.com> Date: Sat, 3 May 2025 20:21:41 +1200 Subject: [PATCH 06/11] fix: line length --- stubs/docutils/docutils/nodes.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index d5f95e0d4db9..e427ed3a43ca 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -462,8 +462,8 @@ class NodeVisitor: 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()`. + # 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: ... From fc1a140452872fd185c6f656845357599b3a8567 Mon Sep 17 00:00:00 2001 From: bzoracler <50305397+bzoracler@users.noreply.github.com> Date: Sat, 3 May 2025 20:25:17 +1200 Subject: [PATCH 07/11] fix: Missing `depart_*` methods in allowlist --- stubs/docutils/@tests/stubtest_allowlist.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/stubs/docutils/@tests/stubtest_allowlist.txt b/stubs/docutils/@tests/stubtest_allowlist.txt index 085b83245fd8..118244c7829b 100644 --- a/stubs/docutils/@tests/stubtest_allowlist.txt +++ b/stubs/docutils/@tests/stubtest_allowlist.txt @@ -6,6 +6,7 @@ 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.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__ From a66570cc3416a8a1cb9d75893555e6105343391f Mon Sep 17 00:00:00 2001 From: bzoracler <50305397+bzoracler@users.noreply.github.com> Date: Sun, 4 May 2025 12:36:12 +1200 Subject: [PATCH 08/11] improvement: add basic signature override for sphinx usage --- stubs/docutils/@tests/stubtest_allowlist.txt | 1 + stubs/docutils/docutils/writers/manpage.pyi | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/stubs/docutils/@tests/stubtest_allowlist.txt b/stubs/docutils/@tests/stubtest_allowlist.txt index 118244c7829b..d38fd12824e5 100644 --- a/stubs/docutils/@tests/stubtest_allowlist.txt +++ b/stubs/docutils/@tests/stubtest_allowlist.txt @@ -19,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__ \ No newline at end of file diff --git a/stubs/docutils/docutils/writers/manpage.pyi b/stubs/docutils/docutils/writers/manpage.pyi index 0f6820f054ea..65d28beb8641 100644 --- a/stubs/docutils/docutils/writers/manpage.pyi +++ b/stubs/docutils/docutils/writers/manpage.pyi @@ -1,3 +1,9 @@ from _typeshed import Incomplete +from docutils import nodes + +class Translator(nodes.NodeVisitor): + def visit_admonition(self, node: nodes.admonition, name: str | None = None) -> None: ... + def __getattr__(self, name: str, /) -> Incomplete: ... + def __getattr__(name: str) -> Incomplete: ... From 48f604b50bb990d82550660b923666a3f792880e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 4 May 2025 00:37:47 +0000 Subject: [PATCH 09/11] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/docutils/@tests/stubtest_allowlist.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/docutils/@tests/stubtest_allowlist.txt b/stubs/docutils/@tests/stubtest_allowlist.txt index d38fd12824e5..422f80995bb3 100644 --- a/stubs/docutils/@tests/stubtest_allowlist.txt +++ b/stubs/docutils/@tests/stubtest_allowlist.txt @@ -19,4 +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__ \ No newline at end of file +docutils.writers.manpage.Translator.__getattr__ From 9bd953588e37a0822bec926c67649dd95c6b1acf Mon Sep 17 00:00:00 2001 From: bzoracler <50305397+bzoracler@users.noreply.github.com> Date: Sun, 4 May 2025 12:45:33 +1200 Subject: [PATCH 10/11] fix: Add signature override for `visit_comment` --- stubs/docutils/docutils/writers/manpage.pyi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/stubs/docutils/docutils/writers/manpage.pyi b/stubs/docutils/docutils/writers/manpage.pyi index 65d28beb8641..d53cb09fbbfd 100644 --- a/stubs/docutils/docutils/writers/manpage.pyi +++ b/stubs/docutils/docutils/writers/manpage.pyi @@ -1,9 +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: ... From 5c44ffed92f31f5e6186dadad42123855859121b Mon Sep 17 00:00:00 2001 From: bzoracler <50305397+bzoracler@users.noreply.github.com> Date: Sun, 4 May 2025 14:06:26 +1200 Subject: [PATCH 11/11] improvement: add default visit/departure methods --- stubs/docutils/docutils/nodes.pyi | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index e427ed3a43ca..8e356892b0bd 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -665,7 +665,10 @@ class NodeVisitor: def depart_warning(self, node: warning) -> Any: ... class SparseNodeVisitor(NodeVisitor): ... -class GenericNodeVisitor(NodeVisitor): ... + +class GenericNodeVisitor(NodeVisitor): + def default_visit(self, node: Node) -> None: ... + def default_departure(self, node: Node) -> None: ... class TreeCopyVisitor(GenericNodeVisitor): parent_stack: list[Node]