# coding: utf-8
import abc
import array
import collections.abc
import os
import sys
import types
import typing

try:
    from typing import Literal
except ImportError:
    from typing_extensions import Literal  # type: ignore

BUFFER = typing.Union[bytes, bytearray, memoryview]
IDENTITY_FILTER_PREFERENCE = Literal["conscover", "origorder", "random"]
COMPUTE_WEIGHTS_METHOD = Literal["pb", "gsc", "blosum"]
MSA_FORMAT = Literal[
    "stockholm", "pfam", "a2m", "psiblast", "selex", "afa", "clustal", 
    "clustallike", "phylip", "phylips"
]

# --- Alphabet ---------------------------------------------------------------

class Alphabet(object):
    @classmethod
    def dna(self) -> Alphabet: ...
    @classmethod
    def rna(self) -> Alphabet: ...
    @classmethod
    def amino(self) -> Alphabet: ...
    def __repr__(self) -> str: ...
    def __eq__(self, other: object) -> bool: ...
    def __reduce__(
        self,
    ) -> typing.Tuple[typing.Callable[[], Alphabet], typing.Tuple[()]]: ...
    def __sizeof__(self) -> int: ...
    @property
    def K(self) -> int: ...
    @property
    def Kp(self) -> int: ...
    @property
    def symbols(self) -> str: ...
    def is_dna(self) -> bool: ...
    def is_rna(self) -> bool: ...
    def is_amino(self) -> bool: ...
    def is_nucleotide(self) -> bool: ...
    def encode(self, sequence: str) -> VectorU8: ...
    def decode(
        self, sequence: typing.Union[VectorU8, memoryview, bytes, bytearray]
    ) -> str: ...

# --- GeneticCode ------------------------------------------------------------

class GeneticCode(object):
    def __init__(
        self,
        translation_table: int = 1,
        *,
        nucleotide_alphabet: Alphabet = ...,
        amino_alphabet: Alphabet = ...,
    ) -> None: ...
    @property
    def translation_table(self) -> int: ...
    @translation_table.setter
    def translation_table(self, translation_table: int) -> None: ...
    @property
    def description(self) -> str: ...
    def translate(
        self, sequence: typing.Union[VectorU8, memoryview, bytes, bytearray]
    ) -> VectorU8: ...

# --- Bitfield ---------------------------------------------------------------

class Bitfield(typing.Sequence[bool]):
    @classmethod
    def zeros(cls, n: int, /) -> Bitfield: ...
    @classmethod
    def ones(cls, n: int, /) -> Bitfield: ...
    def __init__(self, iterable: typing.Iterable[object]) -> None: ...
    def __len__(self) -> int: ...
    @typing.overload
    def __getitem__(self, index: int) -> bool: ...
    @typing.overload
    def __getitem__(self, index: slice) -> typing.Sequence[bool]: ...
    def __setitem__(self, index: int, value: bool) -> None: ...
    def __eq__(self, other: object) -> bool: ...
    def __getstate__(self) -> typing.Dict[str, object]: ...
    def __setstate__(self, state: typing.Dict[str, object]) -> None: ...
    def __sizeof__(self) -> int: ...
    def __copy__(self) -> Bitfield: ...
    def __deepcopy__(self, memo: typing.Dict[int, object]) -> Bitfield: ...
    def __buffer__(self, flags: int) -> memoryview: ...
    def count(self, value: bool = True) -> int: ...
    def copy(self) -> Bitfield: ...
    def toggle(self, index: int) -> None: ...

# --- KeyHash ----------------------------------------------------------------

class KeyHash(typing.Mapping[bytes, int]):
    def __init__(self) -> None: ...
    def __copy__(self) -> KeyHash: ...
    def __len__(self) -> int: ...
    def __contains__(self, value: object) -> bool: ...
    def __getitem__(self, item: bytes) -> int: ...
    def __iter__(self) -> typing.Iterator[bytes]: ...
    def __getstate__(self) -> typing.Dict[str, object]: ...
    def __setstate__(self, state: typing.Dict[str, object]) -> None: ...
    def __sizeof__(self) -> int: ...
    def clear(self) -> None: ...
    def copy(self) -> KeyHash: ...

# --- Matrix & Vector --------------------------------------------------------

_T = typing.TypeVar("_T")
_V = typing.TypeVar("_V")
_M = typing.TypeVar("_M")

class Vector(typing.Sequence[_T], typing.Generic[_T], abc.ABC):
    def __reduce__(
        self: _V,
    ) -> typing.Tuple[typing.Type[_V], typing.Tuple[array.array[typing.Any]]]: ...
    @abc.abstractmethod
    @classmethod
    def zeros(cls: typing.Type[_V], n: int) -> _V: ...
    @abc.abstractmethod
    def __init__(self, iterable: typing.Iterable[_T] = ()): ...
    def __copy__(self: _V) -> _V: ...
    @abc.abstractmethod
    def __eq__(self, other: object) -> bool: ...
    @typing.overload
    @abc.abstractmethod
    def __getitem__(self, index: int) -> _T: ...
    @typing.overload
    @abc.abstractmethod
    def __getitem__(self, index: slice) -> Vector[_T]: ...
    @typing.overload
    @abc.abstractmethod
    def __setitem__(self, index: int, value: _T) -> None: ...
    @typing.overload
    @abc.abstractmethod
    def __setitem__(self, index: slice, value: _T) -> None: ...
    @abc.abstractmethod
    def __iadd__(self: _V, other: typing.Union[_T, _V]) -> _V: ...
    @abc.abstractmethod
    def __imul__(self: _V, other: typing.Union[_T, _V]) -> _V: ...
    @abc.abstractmethod
    def __matmul__(self: _V, other: _V) -> _T: ...
    def __sizeof__(self) -> int: ...
    def __repr__(self) -> str: ...
    def __len__(self) -> int: ...
    def __buffer__(self, flags: int) -> memoryview: ...
    @property
    def shape(self) -> typing.Tuple[int]: ...
    @property
    def strides(self) -> typing.Tuple[int]: ...
    @property
    @abc.abstractmethod
    def itemsize(self) -> int: ...
    @property
    @abc.abstractmethod
    def format(self) -> str: ...
    @abc.abstractmethod
    def argmax(self) -> int: ...
    @abc.abstractmethod
    def argmin(self) -> int: ...
    @abc.abstractmethod
    def copy(self: _V) -> _V: ...
    @abc.abstractmethod
    def max(self) -> _T: ...
    @abc.abstractmethod
    def min(self) -> _T: ...
    @abc.abstractmethod
    def reverse(self) -> None: ...
    @abc.abstractmethod
    def sum(self) -> _T: ...

class VectorD(Vector[float]):
    @classmethod
    def zeros(cls, n: int) -> VectorD: ...
    def __init__(self, iterable: typing.Iterable[float] = ()): ...
    def __copy__(self) -> VectorD: ...
    def __eq__(self, other: object) -> bool: ...
    @typing.overload
    def __getitem__(self, index: int) -> float: ...
    @typing.overload
    def __getitem__(self, index: slice) -> VectorD: ...
    @typing.overload
    def __setitem__(self, index: int, value: float) -> None: ...
    @typing.overload
    def __setitem__(self, index: slice, value: float) -> None: ...
    def __neg__(self) -> VectorD: ...
    def __abs__(self) -> VectorD: ...
    def __add__(self, other: typing.Union[float, VectorD]) -> VectorD: ...
    def __iadd__(self, other: typing.Union[float, VectorD]) -> VectorD: ...
    def __sub__(self, other: typing.Union[float, VectorD]) -> VectorD: ...
    def __isub__(self, other: typing.Union[float, VectorD]) -> VectorD: ...
    def __mul__(self, other: typing.Union[float, VectorD]) -> VectorD: ...
    def __imul__(self, other: typing.Union[float, VectorD]) -> VectorD: ...
    def __truediv__(self, other: typing.Union[float, VectorD]) -> VectorD: ...
    def __itruediv__(self, other: typing.Union[float, VectorD]) -> VectorD: ...
    def __matmul__(self, other: VectorD) -> float: ...
    def argmax(self) -> int: ...
    def argmin(self) -> int: ...
    def copy(self) -> VectorD: ...
    def entropy(self) -> float: ...
    def max(self) -> float: ...
    def min(self) -> float: ...
    def normalize(self) -> None: ...
    def relative_entropy(self, other: VectorD) -> float: ...
    def reverse(self) -> None: ...
    def sum(self) -> float: ...
    @property
    def itemsize(self) -> int: ...
    @property
    def format(self) -> str: ...

class VectorF(Vector[float]):
    @classmethod
    def zeros(cls, n: int) -> VectorF: ...
    def __init__(self, iterable: typing.Iterable[float] = ()): ...
    def __copy__(self) -> VectorF: ...
    def __eq__(self, other: object) -> bool: ...
    @typing.overload
    def __getitem__(self, index: int) -> float: ...
    @typing.overload
    def __getitem__(self, index: slice) -> VectorF: ...
    @typing.overload
    def __setitem__(self, index: int, value: float) -> None: ...
    @typing.overload
    def __setitem__(self, index: slice, value: float) -> None: ...
    def __neg__(self) -> VectorF: ...
    def __abs__(self) -> VectorF: ...
    def __add__(self, other: typing.Union[float, VectorF]) -> VectorF: ...
    def __iadd__(self, other: typing.Union[float, VectorF]) -> VectorF: ...
    def __sub__(self, other: typing.Union[float, VectorF]) -> VectorF: ...
    def __isub__(self, other: typing.Union[float, VectorF]) -> VectorF: ...
    def __mul__(self, other: typing.Union[float, VectorF]) -> VectorF: ...
    def __imul__(self, other: typing.Union[float, VectorF]) -> VectorF: ...
    def __truediv__(self, other: typing.Union[float, VectorF]) -> VectorF: ...
    def __itruediv__(self, other: typing.Union[float, VectorF]) -> VectorF: ...
    def __matmul__(self, other: VectorF) -> float: ...
    def argmax(self) -> int: ...
    def argmin(self) -> int: ...
    def copy(self) -> VectorF: ...
    def entropy(self) -> float: ...
    def max(self) -> float: ...
    def min(self) -> float: ...
    def normalize(self) -> None: ...
    def relative_entropy(self, other: VectorF) -> float: ...
    def reverse(self) -> None: ...
    def sum(self) -> float: ...
    @property
    def itemsize(self) -> int: ...
    @property
    def format(self) -> str: ...

class VectorU8(Vector[int]):
    @classmethod
    def zeros(cls, n: int) -> VectorU8: ...
    def __init__(self, iterable: typing.Iterable[int] = ()): ...
    def __copy__(self) -> VectorU8: ...
    def __eq__(self, other: object) -> bool: ...
    @typing.overload
    def __getitem__(self, index: int) -> int: ...
    @typing.overload
    def __getitem__(self, index: slice) -> VectorU8: ...
    @typing.overload
    def __setitem__(self, index: int, value: int) -> None: ...
    @typing.overload
    def __setitem__(self, index: slice, value: int) -> None: ...
    def __add__(self, other: typing.Union[int, VectorU8]) -> VectorU8: ...
    def __iadd__(self, other: typing.Union[int, VectorU8]) -> VectorU8: ...
    def __sub__(self, other: typing.Union[int, VectorU8]) -> VectorU8: ...
    def __isub__(self, other: typing.Union[int, VectorU8]) -> VectorU8: ...
    def __mul__(self, other: typing.Union[int, VectorU8]) -> VectorU8: ...
    def __imul__(self, other: typing.Union[int, VectorU8]) -> VectorU8: ...
    def __floordiv__(self, other: typing.Union[int, VectorU8]) -> VectorU8: ...
    def __ifloordiv__(self, other: typing.Union[int, VectorU8]) -> VectorU8: ...
    def __matmul__(self, other: VectorU8) -> int: ...
    def argmax(self) -> int: ...
    def argmin(self) -> int: ...
    def copy(self) -> VectorU8: ...
    def max(self) -> int: ...
    def min(self) -> int: ...
    def reverse(self) -> None: ...
    def sum(self) -> int: ...
    @property
    def itemsize(self) -> int: ...
    @property
    def format(self) -> str: ...

class Matrix(typing.Sequence[Vector[_T]], typing.Generic[_T], abc.ABC):
    def __reduce__(
        self: _V,
    ) -> typing.Tuple[typing.Type[_V], typing.Tuple[typing.List[Vector[_T]]]]: ...
    @abc.abstractmethod
    @classmethod
    def zeros(cls: typing.Type[_M], m: int, n: int) -> _M: ...
    @abc.abstractmethod
    def __init__(self, iterable: typing.Iterable[typing.Iterable[_T]] = ()): ...
    @abc.abstractmethod
    def __copy__(self: _M) -> _M: ...
    def __len__(self) -> int: ...
    @abc.abstractmethod
    @typing.overload
    def __getitem__(self, index: int) -> Vector[_T]: ...
    @abc.abstractmethod
    @typing.overload
    def __getitem__(self, index: slice) -> Matrix[_T]: ...
    @abc.abstractmethod
    @typing.overload
    def __getitem__(self, index: typing.Tuple[int, int]) -> _T: ...
    @abc.abstractmethod
    def __setitem__(self, index: typing.Tuple[int, int], value: _T) -> None: ...
    @abc.abstractmethod
    def __add__(self: _M, other: typing.Union[_T, _M]) -> _M: ...
    @abc.abstractmethod
    def __iadd__(self: _M, other: typing.Union[_T, _M]) -> _M: ...
    @abc.abstractmethod
    def __mul__(self: _M, other: typing.Union[_T, _M]) -> _M: ...
    @abc.abstractmethod
    def __imul__(self: _M, other: typing.Union[_T, _M]) -> _M: ...
    @abc.abstractmethod
    def __repr__(self) -> str: ...
    def __buffer__(self, flags: int) -> memoryview: ...
    @property
    def shape(self) -> typing.Tuple[int, int]: ...
    @property
    def strides(self) -> typing.Tuple[int, int]: ...
    @property
    @abc.abstractmethod
    def itemsize(self) -> int: ...
    @property
    @abc.abstractmethod
    def format(self) -> str: ...
    @abc.abstractmethod
    def argmax(self) -> typing.Tuple[int, int]: ...
    @abc.abstractmethod
    def argmin(self) -> typing.Tuple[int, int]: ...
    @abc.abstractmethod
    def copy(self: _M) -> _M: ...
    @abc.abstractmethod
    def max(self) -> _T: ...
    @abc.abstractmethod
    def min(self) -> _T: ...
    @abc.abstractmethod
    def sum(self) -> _T: ...

class MatrixD(Matrix[float]):
    @classmethod
    def zeros(cls, m: int, n: int) -> MatrixD: ...
    def __init__(self, iterable: typing.Iterable[typing.Iterable[float]] = ()): ...
    def __copy__(self) -> MatrixD: ...
    def __eq__(self, other: object) -> bool: ...
    @typing.overload
    def __getitem__(self, index: int) -> VectorD: ...
    @typing.overload
    def __getitem__(self, index: slice) -> MatrixD: ...
    @typing.overload
    def __getitem__(self, index: typing.Tuple[int, int]) -> float: ...
    def __setitem__(self, index: typing.Tuple[int, int], value: float) -> None: ...
    def __abs__(self) -> MatrixD: ...
    def __add__(self, other: typing.Union[float, MatrixD]) -> MatrixD: ...
    def __iadd__(self, other: typing.Union[float, MatrixD]) -> MatrixD: ...
    def __mul__(self, other: typing.Union[float, MatrixD]) -> MatrixD: ...
    def __imul__(self, other: typing.Union[float, MatrixD]) -> MatrixD: ...
    def __repr__(self) -> str: ...
    def __sizeof__(self) -> int: ...
    def argmax(self) -> typing.Tuple[int, int]: ...
    def argmin(self) -> typing.Tuple[int, int]: ...
    def copy(self) -> MatrixD: ...
    def max(self) -> float: ...
    def min(self) -> float: ...
    def sum(self) -> float: ...
    @property
    def itemsize(self) -> int: ...
    @property
    def format(self) -> str: ...

class MatrixF(Matrix[float]):
    @classmethod
    def zeros(cls, m: int, n: int) -> MatrixF: ...
    def __init__(self, iterable: typing.Iterable[typing.Iterable[float]] = ()): ...
    def __copy__(self) -> MatrixF: ...
    def __eq__(self, other: object) -> bool: ...
    @typing.overload
    def __getitem__(self, index: int) -> VectorF: ...
    @typing.overload
    def __getitem__(self, index: slice) -> MatrixF: ...
    @typing.overload
    def __getitem__(self, index: typing.Tuple[int, int]) -> float: ...
    def __setitem__(self, index: typing.Tuple[int, int], value: float) -> None: ...
    def __abs__(self) -> MatrixF: ...
    def __add__(self, other: typing.Union[float, MatrixF]) -> MatrixF: ...
    def __iadd__(self, other: typing.Union[float, MatrixF]) -> MatrixF: ...
    def __mul__(self, other: typing.Union[float, MatrixF]) -> MatrixF: ...
    def __imul__(self, other: typing.Union[float, MatrixF]) -> MatrixF: ...
    def __repr__(self) -> str: ...
    def __sizeof__(self) -> int: ...
    def argmax(self) -> typing.Tuple[int, int]: ...
    def argmin(self) -> typing.Tuple[int, int]: ...
    def copy(self) -> MatrixF: ...
    def max(self) -> float: ...
    def min(self) -> float: ...
    def sum(self) -> float: ...
    @property
    def itemsize(self) -> int: ...
    @property
    def format(self) -> str: ...

class MatrixU8(Matrix[int]):
    @classmethod
    def zeros(cls, m: int, n: int) -> MatrixU8: ...
    def __init__(self, iterable: typing.Iterable[typing.Iterable[int]] = ()): ...
    def __copy__(self) -> MatrixU8: ...
    def __eq__(self, other: object) -> bool: ...
    @typing.overload
    def __getitem__(self, index: int) -> VectorU8: ...
    @typing.overload
    def __getitem__(self, index: slice) -> MatrixU8: ...
    @typing.overload
    def __getitem__(self, index: typing.Tuple[int, int]) -> int: ...
    def __setitem__(self, index: typing.Tuple[int, int], value: int) -> None: ...
    def __add__(self, other: typing.Union[int, MatrixU8]) -> MatrixU8: ...
    def __iadd__(self, other: typing.Union[int, MatrixU8]) -> MatrixU8: ...
    def __mul__(self, other: typing.Union[int, MatrixU8]) -> MatrixU8: ...
    def __imul__(self, other: typing.Union[int, MatrixU8]) -> MatrixU8: ...
    def __repr__(self) -> str: ...
    def __sizeof__(self) -> int: ...
    def argmax(self) -> typing.Tuple[int, int]: ...
    def argmin(self) -> typing.Tuple[int, int]: ...
    def copy(self) -> MatrixU8: ...
    def max(self) -> int: ...
    def min(self) -> int: ...
    def sum(self) -> int: ...
    @property
    def itemsize(self) -> int: ...
    @property
    def format(self) -> str: ...

# --- Multiple Sequences Alignment -------------------------------------------

class MSA(abc.ABC, typing.Sized):
    @abc.abstractmethod
    def __init__(
        self, nsequences: int, length: typing.Optional[int] = None
    ) -> None: ...
    def __copy__(self: _M) -> _M: ...
    def __eq__(self, other: object) -> bool: ...
    def __len__(self) -> int: ...
    @property
    def accession(self) -> typing.Optional[bytes]: ...
    @accession.setter
    def accession(self, accession: typing.Optional[bytes]) -> None: ...
    @property
    def author(self) -> typing.Optional[bytes]: ...
    @author.setter
    def author(self, author: typing.Optional[bytes]) -> None: ...
    @property
    def name(self) -> typing.Optional[bytes]: ...
    @name.setter
    def name(self, name: typing.Optional[bytes]) -> None: ...
    @property
    def description(self) -> typing.Optional[bytes]: ...
    @description.setter
    def description(self, description: typing.Optional[bytes]) -> None: ...
    @property
    def names(self) -> typing.Tuple[bytes]: ...
    @property
    def reference(self) -> typing.Optional[bytes]: ...
    @reference.setter
    def reference(self, reference: typing.Optional[bytes]) -> None: ...
    @property
    def model_mask(self) -> typing.Optional[bytes]: ...
    @model_mask.setter
    def model_mask(self, model_mask: typing.Optional[bytes]) -> None: ...
    @property
    def secondary_structure(self) -> typing.Optional[bytes]: ...
    @secondary_structure.setter
    def secondary_structure(self, secondary_structure: typing.Optional[bytes]) -> None: ...
    @property
    def surface_accessibility(self) -> typing.Optional[bytes]: ...
    @surface_accessibility.setter
    def surface_accessibility(self, surface_accessibility: typing.Optional[bytes]) -> None: ...
    @property
    def posterior_probabilities(self) -> typing.Optional[bytes]: ...
    @posterior_probabilities.setter
    def posterior_probabilities(self, posterior_probabilities: typing.Optional[bytes]) -> None: ...
    @property
    def sequence_weights(self) -> VectorD: ...
    @sequence_weights.setter
    def sequence_weights(self, sequence_weights: VectorD) -> None: ...
    @sequence_weights.deleter
    def sequence_weights(self) -> None: ...
    @property
    def indexed(self) -> typing.Mapping[bytes, Sequence]: ...
    @abc.abstractmethod
    def copy(self: _M) -> _M: ...
    def checksum(self) -> int: ...
    def compute_weights(
        self, 
        method: COMPUTE_WEIGHTS_METHOD = "pb", 
        max_identity: float = 0.62,
    ) -> VectorD: ...
    def mark_fragments(self, threshold: float) -> Bitfield: ...
    def select(self: _M, sequences: typing.Optional[typing.Iterable[int]] = None, columns: typing.Optional[typing.Iterable[int]] = None) -> _M: ...
    def write(self, fh: typing.BinaryIO, format: MSA_FORMAT) -> None: ...

class TextMSA(MSA):
    def __init__(
        self,
        *,
        name: typing.Optional[bytes] = None,
        description: typing.Optional[bytes] = None,
        accession: typing.Optional[bytes] = None,
        sequences: typing.Optional[typing.Iterable[TextSequence]] = None,
        author: typing.Optional[bytes] = None,
    ) -> None: ...
    def __copy__(self) -> TextMSA: ...
    def copy(self) -> TextMSA: ...
    def digitize(self, alphabet: Alphabet) -> DigitalMSA: ...
    @property
    def alignment(self) -> typing.Sequence[str]: ...
    @property
    def sequences(self) -> typing.Sequence[TextSequence]: ...
    @property
    def indexed(self) -> typing.Mapping[bytes, TextSequence]: ...

class DigitalMSA(MSA):
    alphabet: Alphabet
    @classmethod
    def sample(
        cls,
        alphabet: Alphabet,
        max_sequences: int,
        max_length: int,
        randomness: typing.Union[Randomness, int, None] = None,
    ) -> DigitalMSA: ...
    def __init__(
        self,
        *,
        alphabet: Alphabet,
        name: typing.Optional[bytes] = None,
        description: typing.Optional[bytes] = None,
        accession: typing.Optional[bytes] = None,
        sequences: typing.Optional[typing.Iterable[DigitalSequence]] = None,
        author: typing.Optional[bytes] = None,
    ) -> None: ...
    def __copy__(self) -> DigitalMSA: ...
    def copy(self) -> DigitalMSA: ...
    def textize(self) -> TextMSA: ...
    @property
    def alignment(self) -> typing.Sequence[VectorU8]: ...
    @property
    def sequences(self) -> typing.Sequence[DigitalSequence]: ...
    @property
    def indexed(self) -> typing.Mapping[bytes, DigitalSequence]: ...
    def compute_weights(
        self, 
        method: COMPUTE_WEIGHTS_METHOD = "pb", 
        max_identity: float = 0.62,
        *,
        fragment_threshold: float = 0.5,
        consensus_fraction: float = 0.5,
        ignore_rf: bool = False,
        sample: bool = True,
        sample_threshold: int = 50000,
        sample_count: int = 10000,
        max_fragments: int = 5000,
        seed: int = 42,
        preference: IDENTITY_FILTER_PREFERENCE = "conscover",
    ) -> VectorD: ...
    def identity_filter(
        self,
        max_identity: float = 0.8,
        *,
        fragment_threshold: float = 0.5,
        consensus_fraction: float = 0.5,
        ignore_rf: bool = False,
        sample: bool = True,
        sample_threshold: int = 50000,
        sample_count: int = 10000,
        max_fragments: int = 5000,
        seed: int = 42,
        preference: IDENTITY_FILTER_PREFERENCE = "conscover",
    ) -> DigitalMSA: ...
    @typing.overload
    def reverse_complement(self, inplace: Literal[True]) -> None: ...
    @typing.overload
    def reverse_complement(self, inplace: Literal[False] = False) -> DigitalMSA: ...


# --- MSA File ---------------------------------------------------------------

M = typing.TypeVar("M", TextMSA, DigitalMSA)

class MSAFile(typing.Generic[M], typing.ContextManager[MSAFile[M]], typing.Iterator[M]):
    _FORMATS: typing.ClassVar[typing.Dict[MSA_FORMAT, int]]
    alphabet: typing.Optional[Alphabet]
    name: typing.Optional[str]
    @typing.overload
    def __init__(
        self: MSAFile[DigitalMSA],
        file: typing.Union[typing.AnyStr, os.PathLike[typing.AnyStr], typing.BinaryIO],
        format: typing.Optional[MSA_FORMAT] = None,
        *,
        digital: Literal[True],
        alphabet: typing.Optional[Alphabet] = None,
    ) -> None: ...
    @typing.overload
    def __init__(
        self: MSAFile[TextMSA],
        file: typing.Union[typing.AnyStr, os.PathLike[typing.AnyStr], typing.BinaryIO],
        format: typing.Optional[str] = None,
        *,
        digital: Literal[False] = False,
        alphabet: typing.Optional[Alphabet] = None,
    ) -> None: ...
    def __enter__(self) -> MSAFile[M]: ...
    def __exit__(
        self,
        exc_type: typing.Optional[typing.Type[BaseException]],
        exc_value: typing.Optional[BaseException],
        traceback: typing.Optional[types.TracebackType],
    ) -> bool: ...
    def __iter__(self) -> MSAFile[M]: ...
    def __next__(self) -> M: ...
    def __repr__(self) -> str: ...
    @property
    def closed(self) -> bool: ...
    @property
    def digital(self) -> bool: ...
    @property
    def format(self) -> MSA_FORMAT: ...
    def read(self) -> typing.Optional[M]: ...
    def close(self) -> None: ...

# --- Randomness -------------------------------------------------------------

class Randomness(object):
    def __init__(
        self, seed: typing.Optional[int] = None, fast: bool = False
    ) -> None: ...
    def __copy__(self) -> Randomness: ...
    def __getstate__(self) -> typing.Tuple[typing.Any, ...]: ...
    def __setstate__(self, state: typing.Tuple[typing.Any, ...]) -> None: ...
    def __sizeof__(self) -> int: ...
    def __repr__(self) -> str: ...
    @property
    def fast(self) -> bool: ...
    def getstate(self) -> typing.Tuple[typing.Any, ...]: ...
    def setstate(self, state: typing.Tuple[typing.Any, ...]) -> None: ...
    def seed(self, n: typing.Optional[int] = None) -> None: ...
    def copy(self) -> Randomness: ...
    def random(self) -> float: ...
    def normalvariate(self, mu: float, sigma: float) -> float: ...

# --- Sequence ---------------------------------------------------------------

class Sequence(typing.Sized, abc.ABC):
    @abc.abstractmethod
    def __init__(self) -> None: ...
    def __copy__(self) -> Sequence: ...
    def __len__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    @property
    def accession(self) -> bytes: ...
    @accession.setter
    def accession(self, accession: bytes) -> None: ...
    @property
    def description(self) -> bytes: ...
    @description.setter
    def description(self, description: bytes) -> None: ...
    @property
    def name(self) -> bytes: ...
    @name.setter
    def name(self, name: bytes) -> None: ...
    @property
    def source(self) -> bytes: ...
    @source.setter
    def source(self, src: bytes) -> None: ...
    @property
    def residue_markups(self) -> typing.Dict[bytes, bytes]: ...
    @residue_markups.setter
    def residue_markups(self, xr: typing.Dict[bytes, bytes]) -> None: ...
    def checksum(self) -> int: ...
    def clear(self) -> None: ...
    @abc.abstractmethod
    def copy(self) -> Sequence: ...
    def write(self, fh: typing.BinaryIO) -> None: ...
    @typing.overload
    def reverse_complement(self, inplace: Literal[True]) -> None: ...
    @typing.overload
    def reverse_complement(self, inplace: Literal[False] = False) -> Sequence: ...

class TextSequence(Sequence):
    @classmethod
    def sample(
        cls,
        max_length: int,
        randomness: typing.Union[Randomness, int, None] = None,
    ) -> TextSequence: ...
    def __init__(
        self,
        *,
        name: typing.Optional[bytes] = None,
        description: typing.Optional[bytes] = None,
        accession: typing.Optional[bytes] = None,
        sequence: typing.Optional[str] = None,
        source: typing.Optional[bytes] = None,
        residue_markups: typing.Optional[typing.Dict[bytes, BUFFER]] = None,
    ) -> None: ...
    def __reduce__(
        self,
    ) -> typing.Tuple[typing.Type[TextSequence], typing.Tuple[object, ...]]: ...
    def __buffer__(self, flags: int) -> memoryview: ...
    @property
    def sequence(self) -> str: ...
    def copy(self) -> TextSequence: ...
    def digitize(self, alphabet: Alphabet) -> DigitalSequence: ...
    @typing.overload
    def reverse_complement(self, inplace: Literal[True]) -> None: ...
    @typing.overload
    def reverse_complement(self, inplace: Literal[False] = False) -> TextSequence: ...

class DigitalSequence(Sequence):
    alphabet: Alphabet
    @classmethod
    def sample(
        cls,
        alphabet: Alphabet,
        max_length: int,
        randomness: typing.Union[Randomness, int, None] = None,
    ) -> DigitalSequence: ...
    def __init__(
        self,
        alphabet: Alphabet,
        *,
        name: typing.Optional[bytes] = None,
        description: typing.Optional[bytes] = None,
        accession: typing.Optional[bytes] = None,
        sequence: typing.Union[BUFFER, VectorU8, None] = None,
        source: typing.Optional[bytes] = None,
        residue_markups: typing.Optional[typing.Dict[bytes, BUFFER]] = None,
    ) -> None: ...
    def __reduce__(
        self,
    ) -> typing.Tuple[typing.Type[DigitalSequence], typing.Tuple[object, ...]]: ...
    def __buffer__(self, flags: int) -> memoryview: ...
    @property
    def sequence(self) -> VectorU8: ...
    def copy(self) -> DigitalSequence: ...
    def textize(self) -> TextSequence: ...
    def translate(self, genetic_code: GeneticCode = ...) -> DigitalSequence: ...
    @typing.overload
    def reverse_complement(self, inplace: Literal[True]) -> None: ...
    @typing.overload
    def reverse_complement(
        self, inplace: Literal[False] = False
    ) -> DigitalSequence: ...

# --- Sequence block ---------------------------------------------------------

S = typing.TypeVar("S", TextSequence, DigitalSequence)
B = typing.TypeVar("B", SequenceBlock[TextSequence], SequenceBlock[DigitalSequence])

class SequenceBlock(typing.Generic[S], typing.MutableSequence[S]):
    def __len__(self) -> int: ...
    @typing.overload
    def __getitem__(self, index: int) -> S: ...
    @typing.overload
    def __getitem__(self: B, index: slice) -> B: ...
    @typing.overload
    def __setitem__(self, index: int, sequence: S) -> None: ...
    @typing.overload
    def __setitem__(self, index: slice, sequence: typing.Iterable[S]) -> None: ...
    @typing.overload
    def __delitem__(self, index: int) -> None: ...
    @typing.overload
    def __delitem__(self, index: slice) -> None: ...
    def __repr__(self) -> str: ...
    def __contains__(self, item: object) -> bool: ...
    def __eq__(self, other: object) -> bool: ...
    def __copy__(self: B) -> B: ...
    @property
    def indexed(self) -> typing.Mapping[bytes, S]: ...
    def clear(self) -> None: ...
    def append(self, sequence: S) -> None: ...
    def extend(self, iterable: typing.Iterable[S]) -> None: ...
    def pop(self, index: int = -1) -> S: ...
    def insert(self, index: int, sequence: S) -> None: ...
    def index(self, sequence: S, start: int = 0, end: int = sys.maxsize) -> int: ...
    def remove(self, sequence: S) -> None: ...
    def largest(self) -> S: ...

class TextSequenceBlock(SequenceBlock[TextSequence]):
    def __init__(self, iterable: typing.Iterable[TextSequence] = ()) -> None: ...
    def digitize(self, alphabet: Alphabet) -> DigitalSequenceBlock: ...

class DigitalSequenceBlock(SequenceBlock[DigitalSequence]):
    alphabet: Alphabet
    def __init__(
        self, alphabet: Alphabet, iterable: typing.Iterable[DigitalSequence] = ()
    ) -> None: ...
    def textize(self) -> TextSequenceBlock: ...
    def translate(self, genetic_code: GeneticCode = ...) -> DigitalSequence: ...

# --- Sequence File ----------------------------------------------------------

class SequenceFile(typing.Generic[S], typing.ContextManager[SequenceFile[S]], typing.Iterator[S]):
    _FORMATS: typing.ClassVar[typing.Dict[str, int]]
    alphabet: typing.Optional[Alphabet]
    name: typing.Optional[str]
    @classmethod
    def parse(
        cls, buffer: BUFFER, format: str, *, alphabet: typing.Optional[Alphabet] = None
    ) -> Sequence: ...
    @classmethod
    def parseinto(cls, seq: Sequence, buffer: BUFFER, format: str) -> Sequence: ...
    @typing.overload
    def __init__(
        self: SequenceFile[DigitalSequence],
        file: typing.Union[typing.AnyStr, os.PathLike[typing.AnyStr], typing.BinaryIO],
        format: typing.Optional[str] = None,
        *,
        ignore_gaps: bool = False,
        digital: Literal[True],
        alphabet: typing.Optional[Alphabet] = None,
    ) -> None: ...
    @typing.overload
    def __init__(
        self: SequenceFile[TextSequence],
        file: typing.Union[typing.AnyStr, os.PathLike[typing.AnyStr], typing.BinaryIO],
        format: typing.Optional[str] = None,
        *,
        ignore_gaps: bool = False,
        digital: Literal[False] = False,
        alphabet: typing.Optional[Alphabet] = None,
    ) -> None: ...
    def __enter__(self) -> SequenceFile[S]: ...
    def __exit__(
        self,
        exc_type: typing.Optional[typing.Type[BaseException]],
        exc_value: typing.Optional[BaseException],
        traceback: typing.Optional[types.TracebackType],
    ) -> bool: ...
    def __iter__(self) -> SequenceFile[S]: ...
    def __next__(self) -> S: ...
    def __repr__(self) -> str: ...
    @property
    def closed(self) -> bool: ...
    @property
    def digital(self) -> bool: ...
    @property
    def format(self) -> str: ...
    def read(
        self, skip_info: bool = False, skip_sequence: bool = False
    ) -> typing.Optional[S]: ...
    def readinto(
        self, seq: Sequence, skip_info: bool = False, skip_sequence: bool = False
    ) -> typing.Optional[S]: ...
    @typing.overload
    def read_block(
        self: SequenceFile[TextSequence],
        sequences: typing.Optional[int] = None,
        residues: typing.Optional[int] = None,
    ) -> TextSequenceBlock: ...
    @typing.overload
    def read_block(
        self: SequenceFile[DigitalSequence],
        sequences: typing.Optional[int] = None,
        residues: typing.Optional[int] = None,
    ) -> DigitalSequenceBlock: ...
    @typing.overload
    def read_block(
        self,
        sequences: typing.Optional[int] = None,
        residues: typing.Optional[int] = None,
    ) -> SequenceBlock[S]: ...
    def rewind(self) -> None: ...
    def close(self) -> None: ...
    def guess_alphabet(self) -> typing.Optional[Alphabet]: ...

# --- Sequence/Subsequence Index ---------------------------------------------

class SSIReader(object):
    class Entry(typing.NamedTuple):
        fd: int
        record_offset: int
        data_offset: int
        record_length: int

    class FileInfo(typing.NamedTuple):
        name: str
        format: int
    def __init__(
        self, file: typing.Union[typing.AnyStr, os.PathLike[typing.AnyStr]]
    ) -> None: ...
    def __enter__(self) -> SSIReader: ...
    def __exit__(
        self,
        exc_type: typing.Optional[typing.Type[BaseException]],
        exc_value: typing.Optional[BaseException],
        traceback: typing.Optional[types.TracebackType],
    ) -> bool: ...
    def close(self) -> None: ...

class SSIWriter(object):
    def __init__(
        self, file: typing.Union[typing.AnyStr, os.PathLike[typing.AnyStr]]
    ) -> None: ...
    def __enter__(self) -> SSIWriter: ...
    def __exit__(
        self,
        exc_type: typing.Optional[typing.Type[BaseException]],
        exc_value: typing.Optional[BaseException],
        traceback: typing.Optional[types.TracebackType],
    ) -> bool: ...
    def add_alias(self, alias: bytes, key: bytes) -> None: ...
    def add_file(self, filename: str, format: int = 0) -> int: ...
    def add_key(
        self,
        key: bytes,
        fd: int,
        record_offset: int,
        data_offset: int = 0,
        record_length: int = 0,
    ) -> None: ...
    def close(self) -> None: ...
