from typing import IO, Any, Collection, Dict, Iterable, Optional, Sequence, Type, Union

from django.db.models.base import Model
from django.db.models.fields import Field
from django.db.models.fields.related import ForeignKey, ManyToManyField

DEFER_FIELD: object = ...

class SerializerDoesNotExist(KeyError): ...
class SerializationError(Exception): ...

class DeserializationError(Exception):
    @classmethod
    def WithData(
        cls, original_exc: Exception, model: str, fk: Union[int, str], field_value: Optional[Union[Sequence[str], str]]
    ) -> DeserializationError: ...

class M2MDeserializationError(Exception):
    original_exc: Exception = ...
    pk: Any = ...
    def __init__(self, original_exc: Exception, pk: Any) -> None: ...

class ProgressBar:
    progress_width: int = ...
    output: Optional[IO[str]] = ...
    total_count: int = ...
    prev_done: int = ...
    def __init__(self, output: Optional[IO[str]], total_count: int) -> None: ...
    def update(self, count: int) -> None: ...

class Serializer:
    internal_use_only: bool = ...
    progress_class: Type[ProgressBar] = ...
    stream_class: Type[IO[str]] = ...
    options: Dict[str, Any] = ...
    stream: IO[str] = ...
    selected_fields: Optional[Collection[str]] = ...
    use_natural_foreign_keys: bool = ...
    use_natural_primary_keys: bool = ...
    first: bool = ...
    def serialize(
        self,
        queryset: Iterable[Model],
        *,
        stream: Optional[IO[str]] = ...,
        fields: Optional[Collection[str]] = ...,
        use_natural_foreign_keys: bool = ...,
        use_natural_primary_keys: bool = ...,
        progress_output: Optional[IO[str]] = ...,
        object_count: int = ...,
        **options: Any
    ) -> Any: ...
    def start_serialization(self) -> None: ...
    def end_serialization(self) -> None: ...
    def start_object(self, obj: Any) -> None: ...
    def end_object(self, obj: Any) -> None: ...
    def handle_field(self, obj: Any, field: Any) -> None: ...
    def handle_fk_field(self, obj: Any, field: Any) -> None: ...
    def handle_m2m_field(self, obj: Any, field: Any) -> None: ...
    def getvalue(self) -> Optional[Union[bytes, str]]: ...

class Deserializer:
    options: Dict[str, Any] = ...
    stream: Union[IO[str], IO[bytes]] = ...
    def __init__(self, stream_or_string: Union[bytes, str, IO[bytes], IO[str]], **options: Any) -> None: ...
    def __iter__(self) -> Deserializer: ...
    def __next__(self) -> Any: ...

class DeserializedObject:
    object: Any = ...
    m2m_data: Optional[Dict[str, Sequence[Any]]] = ...
    deferred_fields: Dict[Field, Any]
    def __init__(
        self,
        obj: Model,
        m2m_data: Optional[Dict[str, Sequence[Any]]] = ...,
        deferred_fields: Optional[Dict[Field, Any]] = ...,
    ) -> None: ...
    def save(self, save_m2m: bool = ..., using: Optional[str] = ..., **kwargs: Any) -> None: ...
    def save_deferred_fields(self, using: Optional[str] = ...) -> None: ...

def build_instance(Model: Type[Model], data: Dict[str, Any], db: str) -> Model: ...
def deserialize_m2m_values(
    field: ManyToManyField, field_value: Iterable[Any], using: Optional[str], handle_forward_references: bool
) -> Union[Sequence[Any], object]: ...
def deserialize_fk_value(
    field: ForeignKey, field_value: Any, using: Optional[str], handle_forward_references: bool
) -> Union[Any, object]: ...
