| @@ -45,7 +45,7 @@ class Node(StringMixIn): | |||||
| def __str__(self) -> str: | def __str__(self) -> str: | ||||
| raise NotImplementedError() | raise NotImplementedError() | ||||
| def __children__(self) -> Generator["Wikicode"]: | |||||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||||
| return | return | ||||
| # pylint: disable=unreachable | # pylint: disable=unreachable | ||||
| yield # pragma: no cover (this is a generator that yields nothing) | yield # pragma: no cover (this is a generator that yields nothing) | ||||
| @@ -44,7 +44,7 @@ class Argument(Node): | |||||
| return start + "|" + str(self.default) + "}}}" | return start + "|" + str(self.default) + "}}}" | ||||
| return start + "}}}" | return start + "}}}" | ||||
| def __children__(self) -> Generator["Wikicode"]: | |||||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||||
| yield self.name | yield self.name | ||||
| if self.default is not None: | if self.default is not None: | ||||
| yield self.default | yield self.default | ||||
| @@ -55,7 +55,7 @@ class ExternalLink(Node): | |||||
| return "[" + str(self.url) + "]" | return "[" + str(self.url) + "]" | ||||
| return str(self.url) | return str(self.url) | ||||
| def __children__(self) -> Generator["Wikicode"]: | |||||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||||
| yield self.url | yield self.url | ||||
| if self.title is not None: | if self.title is not None: | ||||
| yield self.title | yield self.title | ||||
| @@ -98,7 +98,7 @@ class Tag(Node): | |||||
| result += "</" + str(self.closing_tag) + ">" | result += "</" + str(self.closing_tag) + ">" | ||||
| return result | return result | ||||
| def __children__(self) -> Generator["Wikicode"]: | |||||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||||
| if not self.wiki_markup: | if not self.wiki_markup: | ||||
| yield self.tag | yield self.tag | ||||
| for attr in self.attributes: | for attr in self.attributes: | ||||
| @@ -17,19 +17,20 @@ | |||||
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| # SOFTWARE. | # SOFTWARE. | ||||
| from collections import defaultdict | |||||
| import re | import re | ||||
| from collections import defaultdict | |||||
| from typing import ( | from typing import ( | ||||
| TYPE_CHECKING, | TYPE_CHECKING, | ||||
| Any, | Any, | ||||
| Optional, | |||||
| Union, | |||||
| List, | |||||
| Dict, | |||||
| Callable, | Callable, | ||||
| Dict, | |||||
| Generator, | Generator, | ||||
| List, | |||||
| Mapping, | Mapping, | ||||
| cast, | |||||
| Optional, | |||||
| TypeVar, | |||||
| Union, | |||||
| overload, | |||||
| ) | ) | ||||
| from ._base import Node | from ._base import Node | ||||
| @@ -47,6 +48,8 @@ FLAGS = re.DOTALL | re.UNICODE | |||||
| # Used to allow None as a valid fallback value | # Used to allow None as a valid fallback value | ||||
| _UNSET = object() | _UNSET = object() | ||||
| T = TypeVar("T") | |||||
| class Template(Node): | class Template(Node): | ||||
| """Represents a template in wikicode, like ``{{foo}}``.""" | """Represents a template in wikicode, like ``{{foo}}``.""" | ||||
| @@ -62,7 +65,7 @@ class Template(Node): | |||||
| return "{{" + str(self.name) + "|" + params + "}}" | return "{{" + str(self.name) + "|" + params + "}}" | ||||
| return "{{" + str(self.name) + "}}" | return "{{" + str(self.name) + "}}" | ||||
| def __children__(self) -> Generator["Wikicode"]: | |||||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||||
| yield self.name | yield self.name | ||||
| for param in self.params: | for param in self.params: | ||||
| if param.showkey: | if param.showkey: | ||||
| @@ -235,7 +238,15 @@ class Template(Node): | |||||
| """Alias for :meth:`has`.""" | """Alias for :meth:`has`.""" | ||||
| return self.has(name, ignore_empty) | return self.has(name, ignore_empty) | ||||
| def get(self, name: Union[str, Any], default: Any = _UNSET) -> Union[Parameter, Any]: | |||||
| @overload | |||||
| def get(self, name: Union[str, Any]) -> Parameter: | |||||
| ... | |||||
| @overload | |||||
| def get(self, name: Union[str, Any], default: T) -> Union[Parameter, T]: | |||||
| ... | |||||
| def get(self, name: Union[str, Any], default: T = _UNSET) -> Union[Parameter, T]: | |||||
| """Get the parameter whose name is *name*. | """Get the parameter whose name is *name*. | ||||
| The returned object is a :class:`.Parameter` instance. Raises | The returned object is a :class:`.Parameter` instance. Raises | ||||
| @@ -312,10 +312,12 @@ class Wikicode(StringMixIn): | |||||
| self._nodes = value | self._nodes = value | ||||
| @overload | @overload | ||||
| def get(self, index: int) -> Node: ... | |||||
| def get(self, index: int) -> Node: | |||||
| ... | |||||
| @overload | @overload | ||||
| def get(self, index: slice) -> list[Node]: ... | |||||
| def get(self, index: slice) -> list[Node]: | |||||
| ... | |||||
| def get(self, index): | def get(self, index): | ||||
| """Return the *index*\\ th node within the list of nodes.""" | """Return the *index*\\ th node within the list of nodes.""" | ||||
| @@ -556,6 +558,7 @@ class Wikicode(StringMixIn): | |||||
| letter's case is normalized. Typical usage is | letter's case is normalized. Typical usage is | ||||
| ``if template.name.matches("stub"): ...``. | ``if template.name.matches("stub"): ...``. | ||||
| """ | """ | ||||
| def normalize(s: str) -> str: | def normalize(s: str) -> str: | ||||
| return (s[0].upper() + s[1:]).replace("_", " ") if s else s | return (s[0].upper() + s[1:]).replace("_", " ") if s else s | ||||
| @@ -577,7 +580,7 @@ class Wikicode(StringMixIn): | |||||
| matches: Union[Callable[[Node], bool], re.Pattern, str, None] = None, | matches: Union[Callable[[Node], bool], re.Pattern, str, None] = None, | ||||
| flags: int = FLAGS, | flags: int = FLAGS, | ||||
| forcetype: Optional[type] = None, | forcetype: Optional[type] = None, | ||||
| ) -> Generator[Node]: | |||||
| ) -> Generator[Node, None, None]: | |||||
| """Iterate over nodes in our list matching certain conditions. | """Iterate over nodes in our list matching certain conditions. | ||||
| If *forcetype* is given, only nodes that are instances of this type (or | If *forcetype* is given, only nodes that are instances of this type (or | ||||