Source code for dataclass_wizard.type_def

__all__ = [
    'Buffer',
    'PyForwardRef',
    'PyProtocol',
    'PyDeque',
    'PyTypedDict',
    'PyRequired',
    'PyNotRequired',
    'PyReadOnly',
    'PyLiteralString',
    'FrozenKeys',
    'DefFactory',
    'NoneType',
    'ExplicitNullType',
    'ExplicitNull',
    'JSONList',
    'JSONObject',
    'ListOfJSONObject',
    'JSONValue',
    'FileType',
    'EnvFileType',
    'StrCollection',
    'ParseFloat',
    'Encoder',
    'FileEncoder',
    'Decoder',
    'FileDecoder',
    'NUMBERS',
    'T',
    'E',
    'U',
    'M',
    'NT',
    'DT',
    'DD',
    'N',
    'S',
    'LT',
    'LSQ',
    'FREF',
    'dataclass_transform',
]

from collections import deque, defaultdict
from datetime import date, time, datetime
from enum import Enum
from os import PathLike
from typing import (
    Any, TypeVar, Sequence, Mapping,
    Union, NamedTuple, Callable, AnyStr, TextIO, BinaryIO,
    Deque as PyDeque,
    ForwardRef as PyForwardRef,
    Protocol as PyProtocol,
    TypedDict as PyTypedDict, Iterable, Collection,
)
from uuid import UUID

from .constants import PY310_OR_ABOVE, PY311_OR_ABOVE, PY313_OR_ABOVE, PY312_OR_ABOVE

# The class of the `None` singleton, cached for re-usability
if PY310_OR_ABOVE:
    # https://docs.python.org/3/library/types.html#types.NoneType
    from types import NoneType
else:
    NoneType = type(None)

# Type check for numeric types - needed because `bool` is technically
# a Number.
NUMBERS = int, float

# Generic type
T = TypeVar('T')
TT = TypeVar('TT')

# Enum subclass type
E = TypeVar('E', bound=Enum)

# UUID subclass type
U = TypeVar('U', bound=UUID)

# Mapping type
M = TypeVar('M', bound=Mapping)

# NamedTuple type
NT = TypeVar('NT', bound=NamedTuple)

# Date, time, or datetime type
DT = TypeVar('DT', date, time, datetime)

# DefaultDict type
DD = TypeVar('DD', bound=defaultdict)

# Numeric type
N = Union[int, float]

# Sequence type
S = TypeVar('S', bound=Sequence)

# List or Tuple type
LT = TypeVar('LT', list, tuple)

# List, Set, or Deque (Double ended queue) type
LSQ = TypeVar('LSQ', list, set, frozenset, deque)

# A fixed set of key names
FrozenKeys = frozenset[str]

# Default factory type, assuming a no-args constructor
DefFactory = Callable[[], T]

# Valid collection types in JSON.
JSONList = list[Any]
JSONObject = dict[str, Any]
ListOfJSONObject = list[JSONObject]

# Valid value types in JSON.
JSONValue = Union[None, str, bool, int, float, JSONList, JSONObject]

# File-type argument, compatible with the type of `file` for `open`
FileType = Union[str, bytes, PathLike, int]

# DotEnv file-type argument (string, tuple of string, boolean, or None)
EnvFileType = Union[bool, FileType, Iterable[FileType], None]

# Type for a string or a collection of strings.
StrCollection = Union[str, Collection[str]]

# Python 3.11 introduced `Required` and `NotRequired` wrappers for
# `TypedDict` fields (PEP 655). Python 3.9+ users can import the
# wrappers from `typing_extensions`.

if PY313_OR_ABOVE:  # pragma: no cover
    from collections.abc import Buffer

    from typing import (Required as PyRequired,
                        NotRequired as PyNotRequired,
                        ReadOnly as PyReadOnly,
                        LiteralString as PyLiteralString,
                        dataclass_transform)
elif PY311_OR_ABOVE:  # pragma: no cover
    if PY312_OR_ABOVE:
        from collections.abc import Buffer
    else:
        from typing_extensions import Buffer

    from typing import (Required as PyRequired,
                        NotRequired as PyNotRequired,
                        LiteralString as PyLiteralString,
                        dataclass_transform)
    from typing_extensions import ReadOnly as PyReadOnly
else:
    from typing_extensions import (Buffer,
                                   Required as PyRequired,
                                   NotRequired as PyNotRequired,
                                   ReadOnly as PyReadOnly,
                                   LiteralString as PyLiteralString,
                                   dataclass_transform)

# Forward references can be either strings or explicit `ForwardRef` objects.
# noinspection SpellCheckingInspection
FREF = TypeVar('FREF', str, PyForwardRef)


[docs] class ExplicitNullType: __slots__ = () # Saves memory by preventing the creation of instance dictionaries _instance = None # Class-level instance variable for singleton control def __new__(cls): if cls._instance is None: cls._instance = super(ExplicitNullType, cls).__new__(cls) return cls._instance def __bool__(self): return False def __repr__(self): return '<ExplicitNull>'
# Create the singleton instance ExplicitNull = ExplicitNullType() # Type annotations ParseFloat = Callable[[str], Any]
[docs] class Encoder(PyProtocol): """ Represents an encoder for Python object -> JSON, e.g. analogous to `json.dumps` """ def __call__(self, obj: Union[JSONObject, JSONList], /, *args, **kwargs) -> AnyStr: ...
[docs] class FileEncoder(PyProtocol): """ Represents an encoder for Python object -> JSON file, e.g. analogous to `json.dump` """ def __call__(self, obj: Union[JSONObject, JSONList], file: Union[TextIO, BinaryIO], **kwargs) -> AnyStr: ...
[docs] class Decoder(PyProtocol): """ Represents a decoder for JSON -> Python object, e.g. analogous to `json.loads` """ def __call__(self, s: AnyStr, **kwargs) -> Union[JSONObject, ListOfJSONObject]: ...
[docs] class FileDecoder(PyProtocol): """ Represents a decoder for JSON file -> Python object, e.g. analogous to `json.load` """ def __call__(self, file: Union[TextIO, BinaryIO], **kwargs) -> Union[JSONObject, ListOfJSONObject]: ...