from typing import (
    Dict,
    Iterator,
    List,
    Literal,
    Optional,
    Tuple,
    TypeVar,
    Union,
    overload,
)

URI = str
Name = str
QName = Tuple[Optional[URI], Name]
AttributeKey = Union[QName, Name]
Attributes = Dict[AttributeKey, str]
Prefix = str

D = TypeVar("D")

# Note: these typings are incomplete and evolve as needed.
class Element:
    uri: Optional[URI]
    name: Name
    defaultUri: Optional[URI]
    children: List[Union["Element", str]]
    attributes: Attributes

    def __init__(
        self,
        qname: QName,
        defaultUri: Optional[URI] = None,
        attribs: Optional[Attributes] = None,
        localPrefixes: Optional[Dict[URI, Prefix]] = None,
    ) -> None: ...
    def __getitem__(self, key: AttributeKey) -> str: ...
    def __setitem__(self, key: AttributeKey, value: str) -> None: ...
    @overload
    def getAttribute(
        self, attribname: AttributeKey, default: None = None
    ) -> Union[str, None]: ...
    @overload
    def getAttribute(self, attribname: AttributeKey, default: D) -> Union[str, D]: ...
    def addChild(self, node: "Element") -> "Element": ...
    def addContent(self, text: str) -> str: ...
    def addElement(
        self,
        name: Union[QName, Name],
        defaultUri: Optional[URI] = None,
        content: Optional[str] = None,
    ) -> "Element": ...
    def elements(
        self, uri: Optional[URI] = None, name: Optional[Name] = None
    ) -> Iterator["Element"]: ...
    def toXml(
        self,
        prefixes: Optional[Dict[URI, Prefix]] = None,
        closeElement: Literal[0, 1] = 1,
        defaultUri: str = "",
        prefixesInScope: Optional[List[Prefix]] = None,
    ) -> str: ...
