from typing import (
    Any, IO, Mapping, MutableMapping, Optional, overload, Union,
    Type, TypeVar, Text
)
from typing import Dict as DictT
import sys
if sys.version_info >= (3,):
    from enum import Enum

    class PlistFormat(Enum):
        FMT_XML: int
        FMT_BINARY: int
    FMT_XML = PlistFormat.FMT_XML
    FMT_BINARY = PlistFormat.FMT_BINARY

mm = MutableMapping[str, Any]
_D = TypeVar('_D', bound=mm)
_Path = Union[str, Text]

if sys.version_info >= (3, 9):
    @overload
    def load(fp: IO[bytes], *, fmt: Optional[PlistFormat] = ...) -> DictT[str, Any]: ...
    @overload
    def load(fp: IO[bytes], *, fmt: Optional[PlistFormat] = ..., dict_type: Type[_D]) -> _D: ...
    @overload
    def loads(value: bytes, *, fmt: Optional[PlistFormat] = ...) -> DictT[str, Any]: ...
    @overload
    def loads(value: bytes, *, fmt: Optional[PlistFormat] = ..., dict_type: Type[_D]) -> _D: ...
elif sys.version_info >= (3, 4):
    @overload
    def load(fp: IO[bytes], *, fmt: Optional[PlistFormat] = ...,
             use_builtin_types: bool = ...) -> DictT[str, Any]: ...
    @overload
    def load(fp: IO[bytes], *, fmt: Optional[PlistFormat] = ...,
             use_builtin_types: bool = ..., dict_type: Type[_D]) -> _D: ...
    @overload
    def loads(value: bytes, *, fmt: Optional[PlistFormat] = ...,
              use_builtin_types: bool = ...) -> DictT[str, Any]: ...
    @overload
    def loads(value: bytes, *, fmt: Optional[PlistFormat] = ...,
              use_builtin_types: bool = ..., dict_type: Type[_D]) -> _D: ...

if sys.version_info >= (3, 4):
    def dump(value: Mapping[str, Any], fp: IO[bytes], *,
             fmt: PlistFormat = ..., sort_keys: bool = ...,
             skipkeys: bool = ...) -> None: ...
    def dumps(value: Mapping[str, Any], *, fmt: PlistFormat = ...,
              skipkeys: bool = ..., sort_keys: bool = ...) -> bytes: ...

if sys.version_info < (3, 9):
    def readPlist(pathOrFile: Union[_Path, IO[bytes]]) -> DictT[str, Any]: ...
    def writePlist(value: Mapping[str, Any], pathOrFile: Union[_Path, IO[bytes]]) -> None: ...
    def readPlistFromBytes(data: bytes) -> DictT[str, Any]: ...
    def writePlistToBytes(value: Mapping[str, Any]) -> bytes: ...
if sys.version_info < (3,):
    def readPlistFromResource(path: _Path, restype: str = ...,
                              resid: int = ...) -> DictT[str, Any]: ...
    def writePlistToResource(rootObject: Mapping[str, Any], path: _Path,
                             restype: str = ...,
                             resid: int = ...) -> None: ...
    def readPlistFromString(data: str) -> DictT[str, Any]: ...
    def writePlistToString(rootObject: Mapping[str, Any]) -> str: ...

if sys.version_info < (3, 7):
    class Dict(DictT[str, Any]):
        def __getattr__(self, attr: str) -> Any: ...
        def __setattr__(self, attr: str, value: Any) -> None: ...
        def __delattr__(self, attr: str) -> None: ...

if sys.version_info < (3, 9):
    class Data:
        data: bytes
        def __init__(self, data: bytes) -> None: ...

if sys.version_info >= (3, 8):
    class UID:
        data: int
        def __init__(self, data: int) -> None: ...
        def __index__(self) -> int: ...
        def __reduce__(self) -> Any: ...
        def __hash__(self) -> int: ...

class InvalidFileException(ValueError):
    def __init__(self, message: str = ...) -> None: ...
