Skip to content
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

stdlib/xml: fix return types for toxml/toprettyxml methods #10061

Merged
merged 8 commits into from
Apr 22, 2023
66 changes: 61 additions & 5 deletions stdlib/xml/dom/minidom.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sys
import xml.dom
from _typeshed import Incomplete, ReadableBuffer, SupportsRead, SupportsWrite
from typing import NoReturn, TypeVar
from typing import NoReturn, TypeVar, overload
from typing_extensions import Literal, Self
from xml.dom.minicompat import NodeList
from xml.dom.xmlbuilder import DocumentLS, DOMImplementationLS
Expand Down Expand Up @@ -30,13 +30,69 @@ class Node(xml.dom.Node):
def localName(self) -> str | None: ...
def __bool__(self) -> Literal[True]: ...
if sys.version_info >= (3, 9):
def toxml(self, encoding: str | None = None, standalone: bool | None = None) -> str: ...
@overload
def toxml(self, encoding: str, standalone: bool | None = None) -> bytes: ...
@overload
def toxml(self, encoding: None = None, standalone: bool | None = None) -> str: ...
@overload
def toprettyxml(
self, indent: str = "\t", newl: str = "\n", encoding: str | None = None, standalone: bool | None = None
self,
indent: str = "\t",
newl: str = "\n",
# Handle any case where encoding is not provided or where it is passed with None
encoding: None = None,
standalone: bool | None = None,
) -> str: ...
@overload
def toprettyxml(
self,
indent: str,
newl: str,
# Handle cases where encoding is passed as str *positionally*
encoding: str,
standalone: bool | None = None,
) -> bytes: ...
@overload
def toprettyxml(
self,
indent: str = "\t",
newl: str = "\n",
# Handle all cases where encoding is passed as a keyword argument; because standalone
# comes after, it will also have to be a keyword arg if encoding is
*,
encoding: str,
standalone: bool | None = None,
) -> bytes: ...
else:
def toxml(self, encoding: str | None = None): ...
def toprettyxml(self, indent: str = "\t", newl: str = "\n", encoding: str | None = None): ...
@overload
def toxml(self, encoding: str) -> bytes: ...
@overload
def toxml(self, encoding: None = None) -> str: ...
@overload
def toprettyxml(
self,
indent: str = "\t",
newl: str = "\n",
# Handle any case where encoding is not provided or where it is passed with None
encoding: None = None,
) -> str: ...
@overload
def toprettyxml(
self,
indent: str,
newl: str,
# Handle cases where encoding is passed as str *positionally*
encoding: str,
) -> bytes: ...
@overload
def toprettyxml(
self,
indent: str = "\t",
newl: str = "\n",
# Handle all cases where encoding is passed as a keyword argument
*,
encoding: str,
) -> bytes: ...

def hasChildNodes(self) -> bool: ...
def insertBefore(self, newChild, refChild): ...
Expand Down
35 changes: 35 additions & 0 deletions test_cases/stdlib/check_xml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from __future__ import annotations

import sys
from typing_extensions import assert_type
from xml.dom.minidom import Document

document = Document()

assert_type(document.toxml(), str)
assert_type(document.toxml(encoding=None), str)
assert_type(document.toxml(encoding="UTF8"), bytes)
assert_type(document.toxml("UTF8"), bytes)
if sys.version_info >= (3, 9):
assert_type(document.toxml(standalone=True), str)
assert_type(document.toxml("UTF8", True), bytes)
assert_type(document.toxml(encoding="UTF8", standalone=True), bytes)


# Because toprettyxml can mix positional and keyword variants of the "encoding" argument, which
# determines the return type, the proper stub typing isn't immediately obvious. This is a basic
# brute-force sanity check.
# Test cases like toxml
assert_type(document.toprettyxml(), str)
assert_type(document.toprettyxml(encoding=None), str)
assert_type(document.toprettyxml(encoding="UTF8"), bytes)
if sys.version_info >= (3, 9):
assert_type(document.toprettyxml(standalone=True), str)
assert_type(document.toprettyxml(encoding="UTF8", standalone=True), bytes)
# Test cases unique to toprettyxml
assert_type(document.toprettyxml(" "), str)
assert_type(document.toprettyxml(" ", "\r\n"), str)
assert_type(document.toprettyxml(" ", "\r\n", "UTF8"), bytes)
if sys.version_info >= (3, 9):
assert_type(document.toprettyxml(" ", "\r\n", "UTF8", True), bytes)
assert_type(document.toprettyxml(" ", "\r\n", standalone=True), str)