from typing import (
    Union,
    Iterator,
    Optional,
    List,
    Iterable,
    Generator as GeneratorType,
)

class Generator:
    def __iter__(self) -> Iterator[bytes]: ...
    def __str__(self) -> str: ...
    def generate(self) -> GenValueGenerator: ...

class NullGenerator(Generator): ...

class IteratorGenerator(Generator):
    def __init__(self, iterator: Iterable[GenValue]) -> None: ...

class ChildGenerator(Generator):
    def __init__(self) -> None: ...
    def __len__(self) -> int: ...
    def append(self, child: Optional[GenValue]) -> None: ...
    def extend(self, children: Iterable[GenValue]) -> None: ...
    def remove(self, child: GenValue) -> None: ...
    def empty(self) -> None: ...
    @property
    def children(self) -> List[GenValue]: ...

class HTMLChildGenerator(Generator):
    def __init__(self) -> None: ...
    def __len__(self) -> int: ...
    def append(self, child: Optional[GenValue]) -> None: ...
    def append_raw(self, child: GenValue) -> None: ...
    def extend(self, children: Iterable[GenValue]) -> None: ...
    def extend_raw(self, children: Iterable[GenValue]) -> None: ...
    def remove(self, child: GenValue) -> None: ...
    def remove_raw(self, child: GenValue) -> None: ...
    def empty(self) -> None: ...
    @property
    def children(self) -> List[GenValue]: ...

def generate_html_string(s: GenValue) -> HTMLChildGenerator: ...

class JoinGenerator(ChildGenerator):
    def __init__(
        self, glue: GenValue, pieces: Optional[Iterable[GenValue]] = ...
    ) -> None: ...

class HTMLJoinGenerator(HTMLChildGenerator):
    def __init__(
        self, glue: GenValue, pieces: Optional[Iterable[GenValue]] = ...
    ) -> None: ...

GenValue = Union[str, bytes, Generator]
GenValueGenerator = GeneratorType[GenValue, None, None]
