1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
.. highlight:: shell
================
Py Compatibility
================
Python 3.9+
-----------
Just a quick note that even though this library supports Python 3.9+,
some of the new features introduced in the latest Python
versions might not be available from the ``typing`` module, depending on
the Python version installed.
To work around that, there's a great library called ``typing-extensions`` (you can
find it on PyPI `here`_) that backports all the new
``typing`` features introduced so that earlier Python versions can also
benefit from them. Note that the ``dataclass-wizard`` package already requires
this dependency for **Python version 3.10 or earlier**, so there's no need
to install this library separately.
With the ``typing-extensions`` module, you can take advantage of the
following new types from the ``typing`` module for Python 3.9+. Most of them are currently
supported by the ``JSONSerializable`` class, however the ones that are *not*
are marked with an asterisk (``*``) below.
Introduced in *Python 3.10*:
* `is_typeddict`_
* `Concatenate`_
* `ParamSpec`_
* `TypeAlias`_
* `TypeGuard`_
Introduced in *Python 3.9*:
* `Annotated`_ (added by `PEP 593`_)
Introduced in *Python 3.8*:
* `Literal`_
* `TypedDict`_
* `Final`_ ``*``
``*`` - Currently not supported by ``JSONSerializable`` at this time, though this
may change in a future release.
.. _here: https://pypi.org/project/typing-extensions/
.. _Annotated: https://docs.python.org/3.9/library/typing.html#typing.Annotated
.. _PEP 593: https://www.python.org/dev/peps/pep-0593/
.. _Final: https://docs.python.org/3.8/library/typing.html#typing.Final
.. _Literal: https://docs.python.org/3.8/library/typing.html#typing.Literal
.. _TypedDict: https://docs.python.org/3.8/library/typing.html#typing.TypedDict
.. _TypeAlias: https://docs.python.org/3/library/typing.html#typing.TypeAlias
.. _Concatenate: https://docs.python.org/3/library/typing.html#typing.Concatenate
.. _TypeGuard: https://docs.python.org/3/library/typing.html#typing.TypeGuard
.. _ParamSpec: https://docs.python.org/3/library/typing.html#typing.ParamSpec
.. _is_typeddict: https://docs.python.org/3/library/typing.html#typing.is_typeddict
Importing the New Types
~~~~~~~~~~~~~~~~~~~~~~~
You can import the new types (for example, the ones mentioned above) using the below
syntax:
.. code-block:: python3
from typing_extensions import Literal, TypedDict, Annotated
Python 3.7+
-----------
The Dataclass Wizard library supports the parsing of *future annotations* (also
known as forward-declared annotations) which are enabled via a
``from __future__ import annotations`` import added at the top of a module; this
declaration allows `PEP 585`_ and `PEP 604`_- style annotations to be used in
Python 3.7 and higher. The one main benefit, is that static type checkers and
IDEs such as PyCharm appear to have solid support for using new-style
annotations in this way.
The following Python code illustrates the paradigm of future annotations in
Python 3.7+ code; notice that a ``__future__`` import is added at the top, for
compatibility with versions earlier than 3.10. In the annotations, we also prefer
to use parameterized standard collections, and the new pipe ``|`` syntax to
represent ``Union`` and ``Optional`` types.
.. code:: python3
from __future__ import annotations
import datetime
from dataclasses import dataclass
from decimal import Decimal
from dataclass_wizard import JSONWizard
@dataclass
class A(JSONWizard):
field_1: str | int | bool
field_2: int | tuple[str | int] | bool
field_3: Decimal | datetime.date | str
field_4: str | int | None
field_6: dict[str | int, list[B | C | D | None]]
@dataclass
class B:
...
@dataclass
class C:
...
@dataclass
class D:
...
The Latest and Greatest
-----------------------
If you already have Python 3.10 or higher, you can leverage the new support for parameterized
standard collections that was added as part of `PEP 585`_, as well as the ability to write
Union types as ``X | Y`` which is introduced in `PEP 604`_, and avoid these imports from
the ``typing`` module altogether:
.. code:: python3
from collections import defaultdict
from dataclasses import dataclass
from dataclass_wizard import JSONWizard
@dataclass
class MyClass(JSONWizard):
my_list: list[str]
my_dict: defaultdict[str, list[int]]
my_tuple: tuple[int | str, ...]
if __name__ == '__main__':
data = {'my_list': ['testing'], 'my_dict': {'key': [1, 2, '3']}, 'my_tuple': (1, '2')}
c = MyClass.from_dict(data)
print(repr(c))
# prints:
# MyClass(my_list=['testing'], my_dict=defaultdict(<class 'list'>, {'key': [1, 2, 3]}), my_tuple=(1, '2'))
.. _PEP 585: https://www.python.org/dev/peps/pep-0585/
.. _PEP 604: https://www.python.org/dev/peps/pep-0604/
|