from collections.abc import Callable, Container, Hashable, Iterable
from io import TextIOWrapper
from re import Pattern
from typing import Any, Final, Protocol, TypeVar, type_check_only

_T = TypeVar("_T")
_H = TypeVar("_H", bound=Hashable)

split_path_re: Final[Pattern[str]]
doctype_lookup_re: Final[Pattern[str]]
tag_re: Final[Pattern[str]]
xml_decl_re: Final[Pattern[str]]

class ClassNotFound(ValueError): ...
class OptionError(Exception): ...

@type_check_only
class _SupportsGetStrWithDefault(Protocol):
    def get(self, item: str, default: Any, /) -> Any: ...

# 'options' contains the **kwargs of an arbitrary function.
def get_choice_opt(
    options: _SupportsGetStrWithDefault, optname: str, allowed: Container[_T], default: _T | None = None, normcase: bool = False
) -> _T: ...
def get_bool_opt(options: _SupportsGetStrWithDefault, optname: str, default: bool | None = None) -> bool: ...
def get_int_opt(options: _SupportsGetStrWithDefault, optname: str, default: int | None = None) -> int: ...

# Return type and type of 'default' depend on the signature of the function whose **kwargs
# are being processed.
def get_list_opt(
    options: _SupportsGetStrWithDefault, optname: str, default: list[Any] | tuple[Any, ...] | None = None
) -> list[Any]: ...
def docstring_headline(obj: object) -> str: ...
def make_analysator(f: Callable[[str], float]) -> Callable[[str], float]: ...
def shebang_matches(text: str, regex: str) -> bool: ...
def doctype_matches(text: str, regex: str) -> bool: ...
def html_doctype_matches(text: str) -> bool: ...
def looks_like_xml(text: str) -> bool: ...
def surrogatepair(c: int) -> int: ...
def format_lines(var_name: str, seq: Iterable[str], raw: bool = False, indent_level: int = 0) -> str: ...
def duplicates_removed(it: Iterable[_H], already_seen: Container[_H] = ()) -> list[_H]: ...

class Future:
    def get(self) -> None: ...

def guess_decode(text: bytes) -> tuple[str, str]: ...

# If 'term' has an 'encoding' attribute, it should be a str. Otherwise any object is accepted.
def guess_decode_from_terminal(text: bytes, term: Any) -> tuple[str, str]: ...
def terminal_encoding(term: Any) -> str: ...

class UnclosingTextIOWrapper(TextIOWrapper):
    def close(self) -> None: ...
