From 1eaa0abdf0fccf7244c67cedfba64473e914cf5d Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Fri, 25 Feb 2022 10:42:28 +0100 Subject: [PATCH 1/7] docutils: complete nodes.Node & bump version to 0.18.* The version bump is necessary because Node.findall() was introduced in 0.18.1. --- stubs/docutils/@tests/stubtest_allowlist.txt | 2 +- stubs/docutils/METADATA.toml | 2 +- stubs/docutils/docutils/nodes.pyi | 62 +++++++++++++++++++- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/stubs/docutils/@tests/stubtest_allowlist.txt b/stubs/docutils/@tests/stubtest_allowlist.txt index 5b0f264c1591..77b064b19ca7 100644 --- a/stubs/docutils/@tests/stubtest_allowlist.txt +++ b/stubs/docutils/@tests/stubtest_allowlist.txt @@ -8,7 +8,7 @@ docutils.io.Input.__getattr__ docutils.io.Input.__init__ docutils.languages.LanguageImporter.__getattr__ docutils.nodes.Element.__getattr__ -docutils.nodes.Node.__getattr__ +docutils.nodes.NodeVisitor.__getattr__ docutils.nodes.document.__getattr__ docutils.nodes.document.__init__ docutils.parsers.rst.Directive.__getattr__ diff --git a/stubs/docutils/METADATA.toml b/stubs/docutils/METADATA.toml index 17d320a94b90..9550463d6ca4 100644 --- a/stubs/docutils/METADATA.toml +++ b/stubs/docutils/METADATA.toml @@ -1 +1 @@ -version = "0.17.*" +version = "0.18.*" diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 7df55c0bd92c..3b9a32938cb8 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -1,15 +1,73 @@ +import xml.dom.minidom from _typeshed import Self from collections.abc import Iterable -from typing import Any, overload +from types import ModuleType +from typing import Any, Callable, Generator, TypeVar, overload +from typing_extensions import Literal from docutils.transforms import Transformer +class NodeVisitor: + def __init__(self, document: document): ... + def __getattr__(self, __name: str) -> Any: ... # incomplete + +_N = TypeVar("_N", bound=Node) + class Node: parent: Node | None source: str | None line: int | None document: document | None - def __getattr__(self, __name: str) -> Any: ... # incomplete + def __bool__(self) -> Literal[True]: ... + def asdom(self, dom: ModuleType | None = ...) -> xml.dom.minidom.Element: ... + # ModuleType is inaccurate, you cannot pass any module, but it's the best we can express + def pformat(self, indent: str = ..., level: int = ...) -> str: ... + def copy(self: Self) -> Self: ... + def deepcopy(self: Self) -> Self: ... + def astext(self) -> str: ... + def setup_child(self, child: Node) -> None: ... + def walk(self, visitor: NodeVisitor) -> bool: ... + def walkabout(self, visitor: NodeVisitor) -> bool: ... + @overload + def findall( + self, condition: type[_N], include_self: bool = ..., descend: bool = ..., siblings: bool = ..., ascend: bool = ... + ) -> Generator[_N, None, None]: ... + @overload + def findall( + self, + condition: Callable[[Node], bool] = ..., + include_self: bool = ..., + descend: bool = ..., + siblings: bool = ..., + ascend: bool = ..., + ) -> Generator[Node, None, None]: ... + @overload + def traverse( + self, condition: type[_N], include_self: bool = ..., descend: bool = ..., siblings: bool = ..., ascend: bool = ... + ) -> list[_N]: ... + @overload + def traverse( + self, + condition: Callable[[Node], bool] = ..., + include_self: bool = ..., + descend: bool = ..., + siblings: bool = ..., + ascend: bool = ..., + ) -> list[Node]: ... + @overload + def next_node( + self, condition: type[_N], include_self: bool = ..., descend: bool = ..., siblings: bool = ..., ascend: bool = ... + ) -> _N: ... + @overload + def next_node( + self, + condition: Callable[[Node], bool] = ..., + include_self: bool = ..., + descend: bool = ..., + siblings: bool = ..., + ascend: bool = ..., + ) -> Node: ... + def previous_sibling(self) -> Node | None: ... class Element(Node): children: list[Node] From 699f8dd5799fe1a914827e63fd0d5983c4e375c8 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Fri, 25 Feb 2022 15:07:14 +0100 Subject: [PATCH 2/7] docutils: add missing | None --- stubs/docutils/docutils/nodes.pyi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 3b9a32938cb8..23813299a3b0 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -35,7 +35,7 @@ class Node: @overload def findall( self, - condition: Callable[[Node], bool] = ..., + condition: Callable[[Node], bool] | None = ..., include_self: bool = ..., descend: bool = ..., siblings: bool = ..., @@ -48,7 +48,7 @@ class Node: @overload def traverse( self, - condition: Callable[[Node], bool] = ..., + condition: Callable[[Node], bool] | None = ..., include_self: bool = ..., descend: bool = ..., siblings: bool = ..., @@ -61,7 +61,7 @@ class Node: @overload def next_node( self, - condition: Callable[[Node], bool] = ..., + condition: Callable[[Node], bool] | None = ..., include_self: bool = ..., descend: bool = ..., siblings: bool = ..., From 203114a778210c94912053800be1e90c1fd21f3b Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Fri, 25 Feb 2022 18:55:08 +0100 Subject: [PATCH 3/7] docutils: use Protocol to accurately model Node.asdom dom parameter --- stubs/docutils/docutils/nodes.pyi | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 23813299a3b0..328cfbb0eac9 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -1,8 +1,7 @@ import xml.dom.minidom from _typeshed import Self from collections.abc import Iterable -from types import ModuleType -from typing import Any, Callable, Generator, TypeVar, overload +from typing import Any, Callable, Generator, Protocol, TypeVar, overload from typing_extensions import Literal from docutils.transforms import Transformer @@ -13,14 +12,16 @@ class NodeVisitor: _N = TypeVar("_N", bound=Node) +class _DomModule(Protocol): + Document: type[xml.dom.minidom.Document] + class Node: parent: Node | None source: str | None line: int | None document: document | None def __bool__(self) -> Literal[True]: ... - def asdom(self, dom: ModuleType | None = ...) -> xml.dom.minidom.Element: ... - # ModuleType is inaccurate, you cannot pass any module, but it's the best we can express + def asdom(self, dom: _DomModule | None = ...) -> xml.dom.minidom.Element: ... def pformat(self, indent: str = ..., level: int = ...) -> str: ... def copy(self: Self) -> Self: ... def deepcopy(self: Self) -> Self: ... From 443d6fe77a331725f38b22e4a9634036cdfaf62e Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Sat, 26 Feb 2022 07:16:02 +0100 Subject: [PATCH 4/7] docutils: add Node.children --- stubs/docutils/docutils/nodes.pyi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 328cfbb0eac9..72f3b1f790cf 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -1,6 +1,6 @@ import xml.dom.minidom from _typeshed import Self -from collections.abc import Iterable +from collections.abc import Iterable, Sequence from typing import Any, Callable, Generator, Protocol, TypeVar, overload from typing_extensions import Literal @@ -16,6 +16,7 @@ class _DomModule(Protocol): Document: type[xml.dom.minidom.Document] class Node: + children: Sequence[Node] parent: Node | None source: str | None line: int | None From a511354ee7e3e92579e73483c184be33a61ecd6a Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Sat, 26 Feb 2022 07:46:23 +0100 Subject: [PATCH 5/7] docutils: add nodes.Text --- stubs/docutils/@tests/stubtest_allowlist.txt | 4 ++++ stubs/docutils/docutils/nodes.pyi | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/stubs/docutils/@tests/stubtest_allowlist.txt b/stubs/docutils/@tests/stubtest_allowlist.txt index 77b064b19ca7..662f1d33707a 100644 --- a/stubs/docutils/@tests/stubtest_allowlist.txt +++ b/stubs/docutils/@tests/stubtest_allowlist.txt @@ -18,3 +18,7 @@ docutils.utils.Reporter.__getattr__ # the constructor appears to be mostly internal API, public API users are meant to use docutils.utils.new_reporter instead docutils.utils.Reporter.__init__ + +# 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.nodes.Text.__init__ diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 72f3b1f790cf..5f8159955917 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -94,6 +94,17 @@ class Element(Node): def __iadd__(self: Self, other: Node | Iterable[Node]) -> Self: ... def __getattr__(self, __name: str) -> Any: ... # incomplete +class Text(Node, str): + tagname: str + children: tuple[()] + + # we omit the rawsource parameter because it has been deprecated and is ignored + def __new__(cls: type[Self], data: str) -> Self: ... + def __init__(self, data: str) -> None: ... + def shortrepr(self, maxlen: int = ...) -> str: ... + def rstrip(self, chars: str | None = ...) -> str: ... + def lstrip(self, chars: str | None = ...) -> str: ... + class Structural: ... class Root: ... From 071fa17187a3a7803abe4bb77989e0c03cbf621b Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Mon, 28 Feb 2022 14:15:50 +0100 Subject: [PATCH 6/7] docutils: address feedback by Sebastian --- stubs/docutils/docutils/nodes.pyi | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 5f8159955917..2a369e7d1f6b 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -1,21 +1,18 @@ import xml.dom.minidom from _typeshed import Self -from collections.abc import Iterable, Sequence -from typing import Any, Callable, Generator, Protocol, TypeVar, overload +from collections.abc import Callable, Generator, Iterable, Sequence +from typing import Any, ClassVar, Protocol, TypeVar, overload from typing_extensions import Literal from docutils.transforms import Transformer -class NodeVisitor: - def __init__(self, document: document): ... - def __getattr__(self, __name: str) -> Any: ... # incomplete - _N = TypeVar("_N", bound=Node) class _DomModule(Protocol): Document: type[xml.dom.minidom.Document] class Node: + # children is initialized by the subclasses children: Sequence[Node] parent: Node | None source: str | None @@ -95,7 +92,7 @@ class Element(Node): def __getattr__(self, __name: str) -> Any: ... # incomplete class Text(Node, str): - tagname: str + tagname: ClassVar[str] children: tuple[()] # we omit the rawsource parameter because it has been deprecated and is ignored @@ -112,4 +109,8 @@ class document(Root, Structural, Element): transformer: Transformer def __getattr__(self, __name: str) -> Any: ... # incomplete +class NodeVisitor: + def __init__(self, document: document): ... + def __getattr__(self, __name: str) -> Any: ... # incomplete + def __getattr__(name: str) -> Any: ... # incomplete From 041ddaa07b067f878a05c1cf39a000bc2384621f Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Mon, 28 Feb 2022 16:39:59 +0100 Subject: [PATCH 7/7] docutils: make Node.{copy,deepcopy,astext,pformat} abstract --- stubs/docutils/docutils/nodes.pyi | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 2a369e7d1f6b..6efe7c5e2b63 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -1,5 +1,6 @@ import xml.dom.minidom from _typeshed import Self +from abc import abstractmethod from collections.abc import Callable, Generator, Iterable, Sequence from typing import Any, ClassVar, Protocol, TypeVar, overload from typing_extensions import Literal @@ -20,9 +21,17 @@ class Node: document: document | None def __bool__(self) -> Literal[True]: ... def asdom(self, dom: _DomModule | None = ...) -> xml.dom.minidom.Element: ... - def pformat(self, indent: str = ..., level: int = ...) -> str: ... + # While docutils documents the Node class to be abstract it does not + # actually use the ABCMeta metaclass. We still set @abstractmethod here + # (although it's not used in the docutils implementation) because it + # makes Mypy reject Node() with "Cannot instantiate abstract class". + @abstractmethod def copy(self: Self) -> Self: ... + @abstractmethod def deepcopy(self: Self) -> Self: ... + @abstractmethod + def pformat(self, indent: str = ..., level: int = ...) -> str: ... + @abstractmethod def astext(self) -> str: ... def setup_child(self, child: Node) -> None: ... def walk(self, visitor: NodeVisitor) -> bool: ... @@ -89,6 +98,10 @@ class Element(Node): def __add__(self, other: list[Node]) -> list[Node]: ... def __radd__(self, other: list[Node]) -> list[Node]: ... def __iadd__(self: Self, other: Node | Iterable[Node]) -> Self: ... + def copy(self: Self) -> Self: ... + def deepcopy(self: Self) -> Self: ... + def pformat(self, indent: str = ..., level: int = ...) -> str: ... + def astext(self) -> str: ... def __getattr__(self, __name: str) -> Any: ... # incomplete class Text(Node, str): @@ -99,6 +112,10 @@ class Text(Node, str): def __new__(cls: type[Self], data: str) -> Self: ... def __init__(self, data: str) -> None: ... def shortrepr(self, maxlen: int = ...) -> str: ... + def copy(self: Self) -> Self: ... + def deepcopy(self: Self) -> Self: ... + def pformat(self, indent: str = ..., level: int = ...) -> str: ... + def astext(self) -> str: ... def rstrip(self, chars: str | None = ...) -> str: ... def lstrip(self, chars: str | None = ...) -> str: ... @@ -107,6 +124,10 @@ class Root: ... class document(Root, Structural, Element): transformer: Transformer + def copy(self: Self) -> Self: ... + def deepcopy(self: Self) -> Self: ... + def pformat(self, indent: str = ..., level: int = ...) -> str: ... + def astext(self) -> str: ... def __getattr__(self, __name: str) -> Any: ... # incomplete class NodeVisitor: