{"id":13993908,"url":"https://github.com/rnag/dataclass-wizard","last_synced_at":"2025-04-14T01:50:16.214Z","repository":{"id":40382245,"uuid":"392132441","full_name":"rnag/dataclass-wizard","owner":"rnag","description":"Simple, elegant, wizarding tools for interacting with Python's dataclasses.","archived":false,"fork":false,"pushed_at":"2025-04-01T18:09:11.000Z","size":803,"stargazers_count":201,"open_issues_count":27,"forks_count":25,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-06T23:02:16.592Z","etag":null,"topics":["dataclass","dataclasses","dataclasses-json","deserialization","for-humans","json","json-api","python","python-dataclasses","python3","serialization"],"latest_commit_sha":null,"homepage":"https://dataclass-wizard.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rnag.png","metadata":{"files":{"readme":"README.rst","changelog":"HISTORY.rst","contributing":"CONTRIBUTING.rst","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["rnag"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"thanks_dev":null,"custom":null}},"created_at":"2021-08-03T00:15:04.000Z","updated_at":"2025-03-31T08:46:09.000Z","dependencies_parsed_at":"2023-02-17T11:45:50.500Z","dependency_job_id":"515aaefa-44e7-4919-8809-38f2b111ac2d","html_url":"https://github.com/rnag/dataclass-wizard","commit_stats":{"total_commits":104,"total_committers":3,"mean_commits":"34.666666666666664","dds":0.5192307692307692,"last_synced_commit":"e3fe0760422613eaf79e0236840a50f27caec064"},"previous_names":[],"tags_count":67,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnag%2Fdataclass-wizard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnag%2Fdataclass-wizard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnag%2Fdataclass-wizard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnag%2Fdataclass-wizard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rnag","download_url":"https://codeload.github.com/rnag/dataclass-wizard/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248809024,"owners_count":21164895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dataclass","dataclasses","dataclasses-json","deserialization","for-humans","json","json-api","python","python-dataclasses","python3","serialization"],"created_at":"2024-08-09T14:02:37.193Z","updated_at":"2025-04-14T01:50:16.191Z","avatar_url":"https://github.com/rnag.png","language":"Python","readme":"================\nDataclass Wizard\n================\n\nRelease v\\ |version| | 📚 Full docs on `Read the Docs`_ (`Installation`_).\n\n.. image:: https://github.com/rnag/dataclass-wizard/actions/workflows/dev.yml/badge.svg\n    :target: https://github.com/rnag/dataclass-wizard/actions/workflows/dev.yml\n    :alt: CI Status\n\n.. image:: https://img.shields.io/pypi/pyversions/dataclass-wizard.svg\n    :target: https://pypi.org/project/dataclass-wizard\n    :alt: Supported Python Versions\n\n.. image:: https://img.shields.io/pypi/l/dataclass-wizard.svg\n    :target: https://pypi.org/project/dataclass-wizard/\n    :alt: License\n\n.. image:: https://static.pepy.tech/badge/dataclass-wizard/month\n    :target: https://pepy.tech/project/dataclass-wizard\n    :alt: Monthly Downloads\n\n**Dataclass Wizard** 🪄\nSimple, elegant *wizarding* tools for Python’s ``dataclasses``.\n\nLightning-fast ⚡, pure Python, and lightweight — effortlessly\nconvert dataclass instances to/from JSON, perfect\nfor complex and *nested dataclass* models!\n\n-------------------\n\n**Behold, the power of the Dataclass Wizard**::\n\n    \u003e\u003e\u003e from __future__ import annotations\n    \u003e\u003e\u003e from dataclasses import dataclass, field\n    \u003e\u003e\u003e from dataclass_wizard import JSONWizard\n    ...\n    \u003e\u003e\u003e @dataclass\n    ... class MyClass(JSONWizard, key_case='AUTO'):\n    ...     my_str: str | None\n    ...     is_active_tuple: tuple[bool, ...]\n    ...     list_of_int: list[int] = field(default_factory=list)\n    ...\n    \u003e\u003e\u003e string = \"\"\"\n    ... {\n    ...   \"my_str\": 20,\n    ...   \"ListOfInt\": [\"1\", \"2\", 3],\n    ...   \"isActiveTuple\": [\"true\", false, 1]\n    ... }\n    ... \"\"\"\n    ...\n    \u003e\u003e\u003e instance = MyClass.from_json(string)\n    \u003e\u003e\u003e instance\n    MyClass(my_str='20', is_active_tuple=(True, False, True), list_of_int=[1, 2, 3])\n    \u003e\u003e\u003e instance.to_json()\n    '{\"myStr\": \"20\", \"isActiveTuple\": [true, false, true], \"listOfInt\": [1, 2, 3]}'\n    \u003e\u003e\u003e instance == MyClass.from_dict(instance.to_dict())\n    True\n\n---\n\n.. contents:: Contents\n   :depth: 1\n   :local:\n   :backlinks: none\n\n``v1`` Opt-In 🚀\n----------------\n\nEarly access to **V1** is available! To opt in, simply enable ``v1=True`` in the ``Meta`` settings:\n\n.. code-block:: python3\n\n    from dataclasses import dataclass\n    from dataclass_wizard import JSONPyWizard\n    from dataclass_wizard.v1 import Alias\n\n    @dataclass\n    class A(JSONPyWizard):\n        class _(JSONPyWizard.Meta):\n            v1 = True\n\n        my_str: str\n        version_info: float = Alias(load='v-info')\n\n    # Alternatively, for simple dataclasses that don't subclass `JSONPyWizard`:\n    # LoadMeta(v1=True).bind_to(A)\n\n    a = A.from_dict({'my_str': 'test', 'v-info': '1.0'})\n    assert a.version_info == 1.0\n    assert a.to_dict() == {'my_str': 'test', 'version_info': 1.0}\n\nFor more information, see the `Field Guide to V1 Opt-in`_.\n\nPerformance Improvements\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe upcoming **V1** release brings significant performance improvements in de/serialization. Personal benchmarks show that **V1** can make Dataclass Wizard\napproximately **2x faster** than ``pydantic``!\n\nWhile some features are still being refined and fully supported, **v1** positions Dataclass Wizard alongside other high-performance serialization libraries in Python.\n\nWhy Use Dataclass Wizard?\n-------------------------\n\nEffortlessly handle complex data with one of the *fastest* and *lightweight* libraries available! Perfect for APIs, JSON wrangling, and more.\n\n- 🚀 **Blazing Fast** — One of the fastest libraries out there!\n- 🪶 **Lightweight** — Pure Python, minimal dependencies\n- 👶 Easy Setup — Intuitive, hassle-free\n- ☝️ **Battle-Tested** — Proven reliability with solid test coverage\n- ⚙️ Highly Customizable — Endless de/serialization options to fit your needs\n- 🎉 Built-in Support — JSON, YAML, TOML, and environment/settings management\n- 📦 **Full Python Type Support** — Powered by type hints with full support for native types and ``typing-extensions``\n- 📝 Auto-Generate Schemas — JSON to Dataclass made easy\n\nKey Features\n------------\n\n- 🔄 Flexible (de)serialization — Marshal dataclasses to/from JSON, TOML, YAML, or ``dict`` with ease.\n- 🌿 Environment Magic — Map env vars and ``.env`` files to strongly-typed class fields effortlessly.\n- 🧑‍💻 Field Properties Made Simple — Add properties with default values to your dataclasses.\n- 🧙‍♂️ JSON-to-Dataclass Wizardry — Auto-generate a dataclass schema from any JSON file or string instantly.\n\nInstallation\n------------\n\n*Dataclass Wizard* is available on `PyPI`_. You can install it with ``pip``:\n\n.. code-block:: console\n\n    $ pip install dataclass-wizard\n\nAlso available on `conda`_ via `conda-forge`_. To install via ``conda``:\n\n.. code-block:: console\n\n    $ conda install dataclass-wizard -c conda-forge\n\nThis library supports **Python 3.9+**. Support for Python 3.6 – 3.8 was\navailable in earlier releases but is no longer maintained, as those\nversions no longer receive security updates.\n\nFor convenience, the table below outlines the last compatible release\nof *Dataclass Wizard* for unsupported Python versions (3.6 – 3.8):\n\n.. list-table::\n   :header-rows: 1\n   :widths: 15 35 15\n\n   * - Python Version\n     - Last Version of ``dataclass-wizard``\n     - Python EOL\n   * - 3.8\n     - 0.26.1_\n     - 2024-10-07\n   * - 3.7\n     - 0.26.1_\n     - 2023-06-27\n   * - 3.6\n     - 0.26.1_\n     - 2021-12-23\n\n.. _0.26.1: https://pypi.org/project/dataclass-wizard/0.26.1/\n.. _PyPI: https://pypi.org/project/dataclass-wizard/\n.. _conda: https://anaconda.org/conda-forge/dataclass-wizard\n.. _conda-forge: https://conda-forge.org/\n.. _Changelog: https://dataclass-wizard.readthedocs.io/en/latest/history.html\n\nSee the package on `PyPI`_ and the `Changelog`_ in the docs for the latest version details.\n\nWizard Mixins ✨\n----------------\n\nIn addition to ``JSONWizard``, these `Mixin`_ classes simplify common tasks and make your data handling *spellbindingly* efficient:\n\n- 🪄 `EnvWizard`_ — Load environment variables and `.env` files into typed schemas, even supporting secret files (keys as file names).\n- 🎩 `JSONPyWizard`_ — A helper for ``JSONWizard`` that preserves your keys as-is (no camelCase changes).\n- 🔮 `JSONListWizard`_ — Extend ``JSONWizard`` to convert lists into `Container`_ objects.\n- 💼 `JSONFileWizard`_ — Convert dataclass instances to/from local JSON files with ease.\n- 🌳 `TOMLWizard`_ — Map your dataclasses to/from TOML format.\n- 🧙‍♂️ `YAMLWizard`_ — Convert between YAML and dataclass instances using ``PyYAML``.\n\nSupported Types 🧑‍💻\n---------------------\n\n*Dataclass Wizard* supports:\n\n- 📋 **Collections**: Handle ``list``, ``dict``, and ``set`` effortlessly.\n- 🔢 **Typing Generics**: Manage ``Union``, ``Any``, and other types from the `typing`_ module.\n- 🌟 **Advanced Types**: Work with ``Enum``, ``defaultdict``, and ``datetime`` with ease.\n\nFor more info, check out the `Supported Types`_ section in the docs for detailed insights into each type and the load/dump process!\n\nUsage and Examples\n------------------\n\n.. rubric:: Seamless JSON De/Serialization with ``JSONWizard``\n\n.. code-block:: python3\n\n    from __future__ import annotations  # Optional in Python 3.10+\n\n    from dataclasses import dataclass, field\n    from enum import Enum\n    from datetime import date\n\n    from dataclass_wizard import JSONWizard\n\n\n    @dataclass\n    class Data(JSONWizard):\n        # Use Meta to customize JSON de/serialization\n        class _(JSONWizard.Meta):\n            key_transform_with_dump = 'LISP'  # Transform keys to LISP-case during dump\n\n        a_sample_bool: bool\n        values: list[Inner] = field(default_factory=list)\n\n\n    @dataclass\n    class Inner:\n        # Nested data with optional enums and typed dictionaries\n        vehicle: Car | None\n        my_dates: dict[int, date]\n\n\n    class Car(Enum):\n        SEDAN = 'BMW Coupe'\n        SUV = 'Toyota 4Runner'\n\n\n    # Input JSON-like dictionary\n    my_dict = {\n        'values': [{'vehicle': 'Toyota 4Runner', 'My-Dates': {'123': '2023-01-31'}}],\n        'aSampleBool': 'TRUE'\n    }\n\n    # Deserialize into strongly-typed dataclass instances\n    data = Data.from_dict(my_dict)\n    print((v := data.values[0]).vehicle)  # Prints: \u003cCar.SUV: 'Toyota 4Runner'\u003e\n    assert v.my_dates[123] == date(2023, 1, 31)  # \u003e True\n\n    # Serialize back into pretty-printed JSON\n    print(data.to_json(indent=2))\n\n.. rubric:: Map Environment Variables with ``EnvWizard``\n\nEasily map environment variables to Python dataclasses:\n\n.. code-block:: python3\n\n    import os\n    from dataclass_wizard import EnvWizard\n\n    os.environ.update({\n        'APP_NAME': 'My App',\n        'MAX_CONNECTIONS': '10',\n        'DEBUG_MODE': 'true'\n    })\n\n    class AppConfig(EnvWizard):\n        app_name: str\n        max_connections: int\n        debug_mode: bool\n\n    config = AppConfig()\n    print(config.app_name)    # My App\n    print(config.debug_mode)  # True\n\n📖 See more `on EnvWizard`_ in the full documentation.\n\n.. rubric:: Dataclass Properties with ``property_wizard``\n\nAdd field properties to your dataclasses with default values using ``property_wizard``:\n\n.. code-block:: python3\n\n    from __future__ import annotations  # This can be removed in Python 3.10+\n\n    from dataclasses import dataclass, field\n    from typing_extensions import Annotated\n\n    from dataclass_wizard import property_wizard\n\n\n    @dataclass\n    class Vehicle(metaclass=property_wizard):\n        wheels: Annotated[int | str, field(default=4)]\n        # or, alternatively:\n        #   _wheels: int | str = 4\n\n        @property\n        def wheels(self) -\u003e int:\n            return self._wheels\n\n        @wheels.setter\n        def wheels(self, value: int | str):\n            self._wheels = int(value)\n\n\n    v = Vehicle()\n    print(v.wheels)  # 4\n    v.wheels = '6'\n    print(v.wheels)  # 6\n\n    assert v.wheels == 6, 'Setter correctly handles type conversion'\n\n📖 For a deeper dive, visit the documentation on `field properties`_.\n\n.. rubric:: Generate Dataclass Schemas with CLI\n\nQuickly generate Python dataclasses from JSON input using the ``wiz-cli`` tool:\n\n.. code-block:: console\n\n    $ echo '{\"myFloat\": \"1.23\", \"Items\": [{\"created\": \"2021-01-01\"}]}' | wiz gs - output.py\n\n.. code-block:: python3\n\n    from dataclasses import dataclass\n    from datetime import date\n    from typing import List, Union\n\n    from dataclass_wizard import JSONWizard\n\n    @dataclass\n    class Data(JSONWizard):\n        my_float: Union[float, str]\n        items: List['Item']\n\n    @dataclass\n    class Item:\n        created: date\n\n📖 Check out the full CLI documentation at wiz-cli_.\n\nJSON Marshalling\n----------------\n\n``JSONSerializable`` (aliased to ``JSONWizard``) is a Mixin_ class which\nprovides the following helper methods that are useful for serializing (and loading)\na dataclass instance to/from JSON, as defined by the ``AbstractJSONWizard``\ninterface.\n\n.. list-table::\n   :widths: 10 40 35\n   :header-rows: 1\n\n   * - Method\n     - Example\n     - Description\n   * - ``from_json``\n     - `item = Product.from_json(string)`\n     - Converts a JSON string to an instance of the\n       dataclass, or a list of the dataclass instances.\n   * - ``from_list``\n     - `list_of_item = Product.from_list(l)`\n     - Converts a Python ``list`` object to a list of the\n       dataclass instances.\n   * - ``from_dict``\n     - `item = Product.from_dict(d)`\n     - Converts a Python ``dict`` object to an instance\n       of the dataclass.\n   * - ``to_dict``\n     - `d = item.to_dict()`\n     - Converts the dataclass instance to a Python ``dict``\n       object that is JSON serializable.\n   * - ``to_json``\n     - `string = item.to_json()`\n     - Converts the dataclass instance to a JSON string\n       representation.\n   * - ``list_to_json``\n     - `string = Product.list_to_json(list_of_item)`\n     - Converts a list of dataclass instances to a JSON string\n       representation.\n\nAdditionally, it adds a default ``__str__`` method to subclasses, which will\npretty print the JSON representation of an object; this is quite useful for\ndebugging purposes. Whenever you invoke ``print(obj)`` or ``str(obj)``, for\nexample, it'll call this method which will format the dataclass object as\na prettified JSON string. If you prefer a ``__str__`` method to not be\nadded, you can pass in ``str=False`` when extending from the Mixin class\nas mentioned `here \u003chttps://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/skip_the_str.html\u003e`_.\n\nNote that the ``__repr__`` method, which is implemented by the\n``dataclass`` decorator, is also available. To invoke the Python object\nrepresentation of the dataclass instance, you can instead use\n``repr(obj)`` or ``f'{obj!r}'``.\n\nTo mark a dataclass as being JSON serializable (and\nde-serializable), simply sub-class from ``JSONSerializable`` as shown\nbelow. You can also extend from the aliased name ``JSONWizard``, if you\nprefer to use that instead.\n\nCheck out a `more complete example`_ of using the ``JSONSerializable``\nMixin class.\n\nNo Inheritance Needed\n---------------------\n\nIt is important to note that the main purpose of sub-classing from\n``JSONWizard`` Mixin class is to provide helper methods like ``from_dict``\nand ``to_dict``, which makes it much more convenient and easier to load or\ndump your data class from and to JSON.\n\nThat is, it's meant to *complement* the usage of the ``dataclass`` decorator,\nrather than to serve as a drop-in replacement for data classes, or to provide type\nvalidation for example; there are already excellent libraries like `pydantic`_ that\nprovide these features if so desired.\n\nHowever, there may be use cases where we prefer to do away with the class\ninheritance model introduced by the Mixin class. In the interests of convenience\nand also so that data classes can be used *as is*, the Dataclass\nWizard library provides the helper functions ``fromlist`` and ``fromdict``\nfor de-serialization, and ``asdict`` for serialization. These functions also\nwork recursively, so there is full support for nested dataclasses -- just as with\nthe class inheritance approach.\n\nHere is an example to demonstrate the usage of these helper functions:\n\n.. note::\n  As of *v0.18.0*, the Meta config for the main dataclass will cascade down\n  and be merged with the Meta config (if specified) of each nested dataclass. To\n  disable this behavior, you can pass in ``recursive=False`` to the Meta config.\n\n.. code:: python3\n\n    from __future__ import annotations\n\n    from dataclasses import dataclass, field\n    from datetime import datetime, date\n\n    from dataclass_wizard import fromdict, asdict, DumpMeta\n\n\n    @dataclass\n    class A:\n        created_at: datetime\n        list_of_b: list[B] = field(default_factory=list)\n\n\n    @dataclass\n    class B:\n        my_status: int | str\n        my_date: date | None = None\n\n\n    source_dict = {'createdAt': '2010-06-10 15:50:00Z',\n                   'List-Of-B': [\n                       {'MyStatus': '200', 'my_date': '2021-12-31'}\n                   ]}\n\n    # De-serialize the JSON dictionary object into an `A` instance.\n    a = fromdict(A, source_dict)\n\n    print(repr(a))\n    # A(created_at=datetime.datetime(2010, 6, 10, 15, 50, tzinfo=datetime.timezone.utc),\n    #   list_of_b=[B(my_status='200', my_date=datetime.date(2021, 12, 31))])\n\n    # Set an optional dump config for the main dataclass, for example one which\n    # converts converts date and datetime objects to a unix timestamp (as an int)\n    #\n    # Note that `recursive=True` is the default, so this Meta config will be\n    # merged with the Meta config (if specified) of each nested dataclass.\n    DumpMeta(marshal_date_time_as='TIMESTAMP',\n             key_transform='SNAKE',\n             # Finally, apply the Meta config to the main dataclass.\n             ).bind_to(A)\n\n    # Serialize the `A` instance to a Python dict object.\n    json_dict = asdict(a)\n\n    expected_dict = {'created_at': 1276185000, 'list_of_b': [{'my_status': '200', 'my_date': 1640926800}]}\n\n    print(json_dict)\n    # Assert that we get the expected dictionary object.\n    assert json_dict == expected_dict\n\nCustom Key Mappings\n-------------------\n\n.. note::\n    **Important:** The functionality for **custom key mappings** (such as JSON-to-dataclass field mappings) is being re-imagined with the introduction of **V1 Opt-in**. Enhanced support for these features is now available, improving the user experience for working with custom mappings.\n\n    For more details, see the `Field Guide to V1 Opt-in`_ and the `V1 Alias`_ documentation.\n\n    This change is part of the ongoing improvements in version ``v0.35.0+``, and the old functionality will no longer be maintained in future releases.\n\nIf you ever find the need to add a `custom mapping`_ of a JSON key to a dataclass\nfield (or vice versa), the helper function ``json_field`` -- which can be\nconsidered an alias to ``dataclasses.field()`` -- is one approach that can\nresolve this.\n\nExample below:\n\n.. code:: python3\n\n    from dataclasses import dataclass\n\n    from dataclass_wizard import JSONSerializable, json_field\n\n\n    @dataclass\n    class MyClass(JSONSerializable):\n\n        my_str: str = json_field('myString1', all=True)\n\n\n    # De-serialize a dictionary object with the newly mapped JSON key.\n    d = {'myString1': 'Testing'}\n    c = MyClass.from_dict(d)\n\n    print(repr(c))\n    # prints:\n    #   MyClass(my_str='Testing')\n\n    # Assert we get the same dictionary object when serializing the instance.\n    assert c.to_dict() == d\n\nMapping Nested JSON Keys\n------------------------\n\n.. note::\n    **Important:** The current \"nested path\" functionality is being re-imagined.\n    Please refer to the new docs for **V1 Opt-in** features, which introduce enhanced support for these use\n    cases. For more details, see the `Field Guide to V1 Opt-in`_ and the `V1 Alias`_ documentation.\n\n    This change is part of the ongoing improvements in version ``v0.35.0+``, and the old functionality will no longer be maintained in future releases.\n\nThe ``dataclass-wizard`` library allows you to map deeply nested JSON keys to dataclass fields using custom path notation. This is ideal for handling complex or non-standard JSON structures.\n\nYou can specify paths to JSON keys with the ``KeyPath`` or ``path_field`` helpers. For example, the deeply nested key ``data.items.myJSONKey`` can be mapped to a dataclass field, such as ``my_str``:\n\n.. code:: python3\n\n    from dataclasses import dataclass\n    from dataclass_wizard import path_field, JSONWizard\n\n    @dataclass\n    class MyData(JSONWizard):\n        my_str: str = path_field('data.items.myJSONKey', default=\"default_value\")\n\n    input_dict = {'data': {'items': {'myJSONKey': 'Some value'}}}\n    data_instance = MyData.from_dict(input_dict)\n    print(data_instance.my_str)  # Output: 'Some value'\n\nCustom Paths for Complex JSON\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can now use `custom paths to access nested keys`_ and map them to specific fields, even when keys contain special characters or follow non-standard conventions.\n\nExample with nested and complex keys:\n\n.. code:: python3\n\n    from dataclasses import dataclass\n    from typing import Annotated\n    from dataclass_wizard import JSONWizard, path_field, KeyPath\n\n\n    @dataclass\n    class NestedData(JSONWizard):\n        my_str: str = path_field('data[0].details[\"key with space\"]', default=\"default_value\")\n        my_int: Annotated[int, KeyPath('data[0].items[3.14].True')] = 0\n\n\n    input_dict = {\n        'data': [\n            {\n                'details': {'key with space': 'Another value'},\n                'items': {3.14: {True: \"42\"}}\n            }\n        ]\n    }\n\n    # Deserialize JSON to dataclass\n    data = NestedData.from_dict(input_dict)\n    print(data.my_str)  # Output: 'Another value'\n\n    # Serialize back to JSON\n    output_dict = data.to_dict()\n    print(output_dict)  # {'data': {0: {'details': {'key with space': 'Another value'}, 'items': {3.14: {True: 42}}}}}\n\n    # Verify data consistency\n    assert data == NestedData.from_dict(output_dict)\n\n    # Handle empty input gracefully\n    data = NestedData.from_dict({'data': []})\n    print(repr(data))  # NestedData(my_str='default_value', my_int=0)\n\nExtending from ``Meta``\n-----------------------\n\nLooking to change how ``date`` and ``datetime`` objects are serialized to JSON? Or\nprefer that field names appear in *snake case* when a dataclass instance is serialized?\n\nThe inner ``Meta`` class allows easy configuration of such settings, as\nshown below; and as a nice bonus, IDEs should be able to assist with code completion\nalong the way.\n\n.. note::\n  As of *v0.18.0*, the Meta config for the main dataclass will cascade down\n  and be merged with the Meta config (if specified) of each nested dataclass. To\n  disable this behavior, you can pass in ``recursive=False`` to the Meta config.\n\n.. code:: python3\n\n    from dataclasses import dataclass\n    from datetime import date\n\n    from dataclass_wizard import JSONWizard\n    from dataclass_wizard.enums import DateTimeTo\n\n\n    @dataclass\n    class MyClass(JSONWizard):\n\n        class _(JSONWizard.Meta):\n            marshal_date_time_as = DateTimeTo.TIMESTAMP\n            key_transform_with_dump = 'SNAKE'\n\n        my_str: str\n        my_date: date\n\n\n    data = {'my_str': 'test', 'myDATE': '2010-12-30'}\n\n    c = MyClass.from_dict(data)\n\n    print(repr(c))\n    # prints:\n    #   MyClass(my_str='test', my_date=datetime.date(2010, 12, 30))\n\n    string = c.to_json()\n    print(string)\n    # prints:\n    #   {\"my_str\": \"test\", \"my_date\": 1293685200}\n\nOther Uses for ``Meta``\n~~~~~~~~~~~~~~~~~~~~~~~\n\nHere are a few additional use cases for the inner ``Meta`` class. Note that\na full list of available settings can be found in the `Meta`_ section in the docs.\n\nDebug Mode\n##########\n\n.. admonition:: **Added in v0.28.0**\n\n   There is now `Easier Debug Mode`_.\n\nEnables additional (more verbose) log output. For example, a message can be\nlogged whenever an unknown JSON key is encountered when\n``from_dict`` or ``from_json`` is called.\n\nThis also results in more helpful error messages during the JSON load\n(de-serialization) process, such as when values are an invalid type --\ni.e. they don't match the annotation for the field. This can be particularly\nuseful for debugging purposes.\n\n.. note::\n  There is a minor performance impact when DEBUG mode is enabled;\n  for that reason, I would personally advise against enabling\n  this in a *production* environment.\n\nHandle Unknown JSON Keys\n########################\n\nThe default behavior is to ignore any unknown or extraneous JSON keys that are\nencountered when ``from_dict`` or ``from_json`` is called, and emit a \"warning\"\nwhich is visible when *debug* mode is enabled (and logging is properly configured).\nAn unknown key is one that does not have a known mapping to a dataclass field.\n\nHowever, we can also raise an error in such cases if desired. The below\nexample demonstrates a use case where we want to raise an error when\nan unknown JSON key is encountered in the  *load* (de-serialization) process.\n\n.. code:: python3\n\n    import logging\n    from dataclasses import dataclass\n\n    from dataclass_wizard import JSONWizard\n    from dataclass_wizard.errors import UnknownJSONKey\n\n    # Sets up application logging if we haven't already done so\n    logging.basicConfig(level='DEBUG')\n\n\n    @dataclass\n    class Container(JSONWizard):\n\n        class _(JSONWizard.Meta):\n            # True to enable Debug mode for additional (more verbose) log output.\n            #\n            # Pass in a `str` to `int` to set the minimum log level:\n            #   logging.getLogger('dataclass_wizard').setLevel('INFO')\n            debug_enabled = logging.INFO\n            # True to raise an class:`UnknownJSONKey` when an unmapped JSON key is\n            # encountered when `from_dict` or `from_json` is called. Note that by\n            # default, this is also recursively applied to any nested dataclasses.\n            raise_on_unknown_json_key = True\n\n        element: 'MyElement'\n\n\n    @dataclass\n    class MyElement:\n        my_str: str\n        my_float: float\n\n\n    d = {\n        'element': {\n            'myStr': 'string',\n            'my_float': '1.23',\n            # Notice how this key is not mapped to a known dataclass field!\n            'my_bool': 'Testing'\n        }\n    }\n\n    # Try to de-serialize the dictionary object into a `MyClass` object.\n    try:\n        c = Container.from_dict(d)\n    except UnknownJSONKey as e:\n        print('Received error:', type(e).__name__)\n        print('Class:', e.class_name)\n        print('Unknown JSON key:', e.json_key)\n        print('JSON object:', e.obj)\n        print('Known Fields:', e.fields)\n    else:\n        print('Successfully de-serialized the JSON object.')\n        print(repr(c))\n\nSee the section on `Handling Unknown JSON Keys`_ for more info.\n\nSave or \"Catch-All\" Unknown JSON Keys\n######################################\n\nWhen calling ``from_dict`` or ``from_json``, any unknown or extraneous JSON keys\nthat are not mapped to fields in the dataclass are typically ignored or raise an error.\nHowever, you can capture these undefined keys in a catch-all field of type ``CatchAll``,\nallowing you to handle them as needed later.\n\nFor example, suppose you have the following dictionary::\n\n    dump_dict = {\n        \"endpoint\": \"some_api_endpoint\",\n        \"data\": {\"foo\": 1, \"bar\": \"2\"},\n        \"undefined_field_name\": [1, 2, 3]\n    }\n\nYou can save the undefined keys in a catch-all field and process them later.\nSimply define a field of type ``CatchAll`` in your dataclass. This field will act\nas a dictionary to store any unmapped keys and their values. If there are no\nundefined keys, the field will default to an empty dictionary.\n\n.. code:: python\n\n    from dataclasses import dataclass\n    from typing import Any\n    from dataclass_wizard import CatchAll, JSONWizard\n\n    @dataclass\n    class UnknownAPIDump(JSONWizard):\n        endpoint: str\n        data: dict[str, Any]\n        unknown_things: CatchAll\n\n    dump_dict = {\n        \"endpoint\": \"some_api_endpoint\",\n        \"data\": {\"foo\": 1, \"bar\": \"2\"},\n        \"undefined_field_name\": [1, 2, 3]\n    }\n\n    dump = UnknownAPIDump.from_dict(dump_dict)\n    print(f'{dump!r}')\n    # \u003e UnknownAPIDump(endpoint='some_api_endpoint', data={'foo': 1, 'bar': '2'},\n    #       unknown_things={'undefined_field_name': [1, 2, 3]})\n\n    print(dump.to_dict())\n    # \u003e {'endpoint': 'some_api_endpoint', 'data': {'foo': 1, 'bar': '2'}, 'undefined_field_name': [1, 2, 3]}\n\n.. note::\n    - When using a \"catch-all\" field, it is strongly recommended to define exactly **one** field of type ``CatchAll`` in the dataclass.\n\n    - ``LetterCase`` transformations do not apply to keys stored in the ``CatchAll`` field; the keys remain as they are provided.\n\n    - If you specify a default (or a default factory) for the ``CatchAll`` field, such as\n      ``unknown_things: CatchAll = None``, the default value will be used instead of an\n      empty dictionary when no undefined parameters are present.\n\n    - The ``CatchAll`` functionality is guaranteed only when using ``from_dict`` or ``from_json``.\n      Currently, unknown keyword arguments passed to ``__init__`` will not be written to a ``CatchAll`` field.\n\nDate and Time with Custom Patterns\n----------------------------------\n\n.. tip::\n    As of **v0.35.0** with V1 Opt-in, Dataclass Wizard now supports timezone-aware and UTC ``datetime``\n    and ``time`` patterns, as well as multiple pattern strings (i.e. multiple `custom formats`) for greater\n    flexibility in pattern matching. These features are **not** available in the current ``v0.*`` versions.\n\n    The new features include:\n\n    - Timezone-aware ``datetime`` and ``time`` patterns.\n    - UTC ``datetime`` and ``time`` patterns.\n    - Multiple `custom formats`_ for a single field, providing more control over pattern matching.\n\n    For more details and examples on how to use these new features, refer to the `V1 Opt-in documentation for Patterned Date and Time`_.\n\nAs of **v0.20.0**, date and time strings in `custom formats`_ can be de-serialized using the ``DatePattern``,\n``TimePattern``, and ``DateTimePattern`` type annotations, which represent patterned ``date``, ``time``, and\n``datetime`` objects, respectively.\n\nInternally, these annotations use ``datetime.strptime`` with the specified format and the ``fromisoformat()``\nmethod for ISO-8601 formatted strings. All date and time values are still serialized to ISO format strings by\ndefault. For more information, refer to the `Patterned Date and Time`_ section in the documentation.\n\nHere is an example demonstrating how to use these annotations:\n\n.. code-block:: python3\n\n    from dataclasses import dataclass\n    from datetime import time, datetime\n    from typing import Annotated\n\n    from dataclass_wizard import fromdict, asdict, DatePattern, TimePattern, Pattern\n\n\n    @dataclass\n    class MyClass:\n        # Custom format for date (Month-Year)\n        date_field: DatePattern['%m-%Y']\n        # Custom format for datetime (Month/Day/Year Hour.Minute.Second)\n        dt_field: Annotated[datetime, Pattern('%m/%d/%y %H.%M.%S')]\n        # Custom format for time (Hour:Minute)\n        time_field1: TimePattern['%H:%M']\n        # Custom format for a list of times (12-hour format with AM/PM)\n        time_field2: Annotated[list[time], Pattern('%I:%M %p')]\n\n\n    data = {'date_field': '12-2022',\n            'time_field1': '15:20',\n            'dt_field': '1/02/23 02.03.52',\n            'time_field2': ['1:20 PM', '12:30 am']}\n\n    class_obj = fromdict(MyClass, data)\n\n    # All annotated fields de-serialize to date, time, or datetime objects, as shown.\n    print(class_obj)\n    # MyClass(date_field=datetime.date(2022, 12, 1), dt_field=datetime.datetime(2023, 1, 2, 2, 3, 52),\n    #         time_field1=datetime.time(15, 20), time_field2=[datetime.time(13, 20), datetime.time(0, 30)])\n\n    # All date/time fields are serialized as ISO-8601 format strings by default.\n    print(asdict(class_obj))\n    # {'dateField': '2022-12-01', 'dtField': '2023-01-02T02:03:52',\n    #  'timeField1': '15:20:00', 'timeField2': ['13:20:00', '00:30:00']}\n\n    # The patterned date/times can be de-serialized back after serialization, which will be faster than\n    # re-parsing the custom patterns!\n    assert class_obj == fromdict(MyClass, asdict(class_obj))\n\nRecursive Types and Dataclasses with Cyclic References\n------------------------------------------------------\n\nPrior to version **0.27.0**, dataclasses with cyclic references\nor self-referential structures were not supported. This\nlimitation is shown in the following toy example:\n\n.. code:: python3\n\n    from dataclasses import dataclass\n\n    @dataclass\n    class A:\n        a: 'A | None' = None\n\n    a = A(a=A(a=A(a=A())))\n\nThis was a `longstanding issue`_, but starting with ``v0.27.0``, Dataclass Wizard now supports\nrecursive dataclasses, including cyclic references.\n\nThe example below demonstrates recursive\ndataclasses with cyclic dependencies, following the pattern ``A -\u003e B -\u003e A -\u003e B``.\nFor more details, see the `Cyclic or \"Recursive\" Dataclasses`_ section in the documentation.\n\n.. code:: python3\n\n    from __future__ import annotations  # This can be removed in Python 3.10+\n\n    from dataclasses import dataclass\n    from dataclass_wizard import JSONWizard\n\n    @dataclass\n    class A(JSONWizard):\n        class _(JSONWizard.Meta):\n            # Enable support for self-referential / recursive dataclasses\n            recursive_classes = True\n\n        b: 'B | None' = None\n\n\n    @dataclass\n    class B:\n        a: A | None = None\n\n    # Confirm that `from_dict` with a recursive, self-referential\n    # input `dict` works as expected.\n    a = A.from_dict({'b': {'a': {'b': {'a': None}}}})\n\n    assert a == A(b=B(a=A(b=B())))\n\nStarting with version **0.34.0**, recursive types are supported *out of the box* (OOTB) with ``v1`` opt-in,\nremoving the need for any ``Meta`` settings like ``recursive_classes = True``.\n\nThis makes working with recursive dataclasses even easier and more streamlined. In addition, recursive types\nare now supported for the following Python type constructs:\n\n- NamedTuple_\n- TypedDict_\n- Union_\n- Literal_\n- Nested dataclasses_\n- `Type aliases`_ (introduced in Python 3.12+)\n\n.. _NamedTuple: https://docs.python.org/3/library/typing.html#typing.NamedTuple\n.. _TypedDict: https://docs.python.org/3/library/typing.html#typing.TypedDict\n.. _Union: https://docs.python.org/3/library/typing.html#typing.Union\n.. _Literal: https://docs.python.org/3/library/typing.html#typing.Literal\n.. _Type aliases: https://docs.python.org/3/library/typing.html#type-aliases\n\nExample Usage\n~~~~~~~~~~~~~\n\nRecursive types allow handling complex nested data structures, such as deeply nested JSON objects or lists.\nWith ``v0.34.0`` of Dataclass Wizard, de/serializing these structures becomes seamless\nand more intuitive.\n\nRecursive ``Union``\n###################\n\n.. code-block:: python3\n\n    from dataclasses import dataclass\n    from dataclass_wizard import JSONWizard\n\n    # For Python 3.9, use this `Union` approach:\n    from typing_extensions import TypeAlias\n    JSON: TypeAlias = 'str | int | float | bool | dict[str, JSON] | list[JSON] | None'\n\n    # For Python 3.10 and above, use this simpler approach:\n    # JSON = str | int | float | bool | dict[str, 'JSON'] | list['JSON'] | None\n\n    # For Python 3.12+, you can use the `type` statement:\n    # type JSON = str | int | float | bool | dict[str, JSON] | list[JSON] | None\n\n    @dataclass\n    class MyTestClass(JSONWizard):\n\n        class _(JSONWizard.Meta):\n            v1 = True\n\n        name: str\n        meta: str\n        msg: JSON\n\n    x = MyTestClass.from_dict(\n        {\n            \"name\": \"name\",\n            \"meta\": \"meta\",\n            \"msg\": [{\"x\": {\"x\": [{\"x\": [\"x\", 1, 1.0, True, None]}]}}],\n        }\n    )\n    assert x == MyTestClass(\n        name=\"name\",\n        meta=\"meta\",\n        msg=[{\"x\": {\"x\": [{\"x\": [\"x\", 1, 1.0, True, None]}]}}],\n    )\n\n.. note::\n   The ``type`` statement in Python 3.12+ simplifies type alias definitions by avoiding string annotations for recursive references.\n\nRecursive ``Union`` with Nested ``dataclasses``\n###############################################\n\n.. code-block:: python3\n\n    from dataclasses import dataclass, field\n    from dataclass_wizard import JSONWizard\n\n    @dataclass\n    class A(JSONWizard):\n\n        class _(JSONWizard.Meta):\n            v1 = True\n\n        value: int\n        nested: 'B'\n        next: 'A | None' = None\n\n\n    @dataclass\n    class B:\n        items: list[A] = field(default_factory=list)\n\n\n    x = A.from_dict(\n        {\n            \"value\": 1,\n            \"next\": {\"value\": 2, \"next\": None, \"nested\": {}},\n            \"nested\": {\"items\": [{\"value\": 3, \"nested\": {}}]},\n        }\n    )\n    assert x == A(\n        value=1,\n        next=A(value=2, next=None, nested=B(items=[])),\n        nested=B(items=[A(value=3, nested=B())]),\n    )\n\n.. note::\n   Nested ``dataclasses`` are particularly useful for representing hierarchical structures, such as trees or graphs, in a readable and maintainable way.\n\nOfficial References\n~~~~~~~~~~~~~~~~~~~\n\nFor more information, see:\n\n- `Typing in Python \u003chttps://docs.python.org/3/library/typing.html\u003e`_\n- `PEP 695: Type Syntax \u003chttps://peps.python.org/pep-0695/\u003e`_\n\nThese examples illustrate the power of recursive types in simplifying complex data structures while leveraging the functionality of ``dataclass-wizard``.\n\nDataclasses in ``Union`` Types\n------------------------------\n\nThe ``dataclass-wizard`` library fully supports declaring dataclass models in\n`Union`_ types, such as ``list[Wizard | Archer | Barbarian]``.\n\nStarting from *v0.19.0*, the library introduces two key features:\n- **Auto-generated tags** for dataclass models (based on class names).\n- A customizable **tag key** (default: ``__tag__``) that identifies the model in JSON.\n\nThese options are controlled by the ``auto_assign_tags`` and ``tag_key`` attributes in the ``Meta`` config.\n\nFor example, if a JSON object looks like ``{\"type\": \"A\", ...}``, you can set ``tag_key = \"type\"`` to automatically deserialize it into the appropriate class, like `A`.\n\nLet's start out with an example, which aims to demonstrate the simplest usage of\ndataclasses in ``Union`` types. For more info, check out the\n`Dataclasses in Union Types`_ section in the docs.\n\n.. code:: python3\n\n    from __future__ import annotations\n\n    from dataclasses import dataclass\n    from dataclass_wizard import JSONWizard\n\n\n    @dataclass\n    class Container(JSONWizard):\n\n        class Meta(JSONWizard.Meta):\n            tag_key = 'type'\n            auto_assign_tags = True\n\n        objects: list[A | B | C]\n\n\n    @dataclass\n    class A:\n        my_int: int\n        my_bool: bool = False\n\n\n    @dataclass\n    class B:\n        my_int: int\n        my_bool: bool = True\n\n\n    @dataclass\n    class C:\n        my_str: str\n\n\n    data = {\n        'objects': [\n            {'type': 'A', 'my_int': 42},\n            {'type': 'C', 'my_str': 'hello world'},\n            {'type': 'B', 'my_int': 123},\n            {'type': 'A', 'my_int': 321, 'myBool': True}\n        ]\n    }\n\n    c = Container.from_dict(data)\n    print(repr(c))\n\n    # Output:\n    # Container(objects=[A(my_int=42, my_bool=False),\n    #                    C(my_str='hello world'),\n    #                    B(my_int=123, my_bool=True),\n    #                    A(my_int=321, my_bool=True)])\n\n    print(c.to_dict())\n\n    # True\n    assert c == c.from_json(c.to_json())\n\nSupercharged ``Union`` Parsing\n------------------------------\n\n**What about untagged dataclasses in** ``Union`` **types or** ``|`` **syntax?** With the major release **V1** opt-in, ``dataclass-wizard`` supercharges *Union* parsing, making it intuitive and flexible, even without tags.\n\nThis is especially useful for collections like ``list[Wizard]`` or when tags (discriminators) are not feasible.\n\nTo enable this feature, opt in to **v1** using the ``Meta`` settings. For details, see the `Field Guide to V1 Opt-in`_.\n\n.. code-block:: python3\n\n    from __future__ import annotations  # Remove in Python 3.10+\n\n    from dataclasses import dataclass\n    from typing import Literal\n\n    from dataclass_wizard import JSONWizard\n\n    @dataclass\n    class MyClass(JSONWizard):\n\n        class _(JSONWizard.Meta):\n            v1 = True  # Enable v1 opt-in\n            v1_unsafe_parse_dataclass_in_union = True\n\n        literal_or_float: Literal['Auto'] | float\n        entry: int | MoreDetails\n        collection: list[MoreDetails | int]\n\n    @dataclass\n    class MoreDetails:\n        arg: str\n\n    # OK: Union types work seamlessly\n    c = MyClass.from_dict({\n        \"literal_or_float\": 1.23,\n        \"entry\": 123,\n        \"collection\": [{\"arg\": \"test\"}]\n    })\n    print(repr(c))\n    #\u003e MyClass(literal_or_float=1.23, entry=123, collection=[MoreDetails(arg='test')])\n\n    # OK: Handles primitive and dataclass parsing\n    c = MyClass.from_dict({\n        \"literal_or_float\": \"Auto\",\n        \"entry\": {\"arg\": \"example\"},\n        \"collection\": [123]\n    })\n    print(repr(c))\n    #\u003e MyClass(literal_or_float='Auto', entry=MoreDetails(arg='example'), collection=[123])\n\nConditional Field Skipping\n--------------------------\n\n.. admonition:: **Added in v0.30.0**\n\n    Dataclass Wizard introduces `conditional skipping`_ to omit fields during JSON serialization based on user-defined conditions. This feature works seamlessly with:\n\n    - **Global rules** via ``Meta`` settings.\n    - **Per-field controls** using ``SkipIf()`` `annotations`_.\n    - **Field wrappers** for maximum flexibility.\n\nQuick Examples\n~~~~~~~~~~~~~~\n\n1. **Globally Skip Fields Matching a Condition**\n\n  Define a global skip rule using ``Meta.skip_if``:\n\n  .. code-block:: python3\n\n    from dataclasses import dataclass\n    from dataclass_wizard import JSONWizard, IS_NOT\n\n\n    @dataclass\n    class Example(JSONWizard):\n        class _(JSONWizard.Meta):\n            skip_if = IS_NOT(True)  # Skip fields if the value is not `True`\n\n        my_bool: bool\n        my_str: 'str | None'\n\n\n    print(Example(my_bool=True, my_str=None).to_dict())\n    # Output: {'myBool': True}\n\n2. **Skip Defaults Based on a Condition**\n\n  Skip fields with default values matching a specific condition using ``Meta.skip_defaults_if``:\n\n  .. code-block:: python3\n\n    from __future__ import annotations  # Can remove in PY 3.10+\n\n    from dataclasses import dataclass\n    from dataclass_wizard import JSONPyWizard, IS\n\n\n    @dataclass\n    class Example(JSONPyWizard):\n        class _(JSONPyWizard.Meta):\n            skip_defaults_if = IS(None)  # Skip default `None` values.\n\n        str_with_no_default: str | None\n        my_str: str | None = None\n        my_bool: bool = False\n\n\n    print(Example(str_with_no_default=None, my_str=None).to_dict())\n    #\u003e {'str_with_no_default': None, 'my_bool': False}\n\n\n  .. note::\n      Setting ``skip_defaults_if`` also enables ``skip_defaults=True`` automatically.\n\n3. **Per-Field Conditional Skipping**\n\n  Apply skip rules to specific fields with `annotations`_ or ``skip_if_field``:\n\n  .. code-block:: python3\n\n    from __future__ import annotations  # can be removed in Python 3.10+\n\n    from dataclasses import dataclass\n    from typing import Annotated\n\n    from dataclass_wizard import JSONWizard, SkipIfNone, skip_if_field, EQ\n\n\n    @dataclass\n    class Example(JSONWizard):\n        my_str: Annotated[str | None, SkipIfNone]  # Skip if `None`.\n        other_str: str | None = skip_if_field(EQ(''), default=None)  # Skip if empty.\n\n    print(Example(my_str=None, other_str='').to_dict())\n    # Output: {}\n\n4. **Skip Fields Based on Truthy or Falsy Values**\n\n   Use the ``IS_TRUTHY`` and ``IS_FALSY`` helpers to conditionally skip fields based on their truthiness:\n\n   .. code-block:: python3\n\n    from dataclasses import dataclass, field\n    from dataclass_wizard import JSONWizard, IS_FALSY\n\n\n    @dataclass\n    class ExampleWithFalsy(JSONWizard):\n        class _(JSONWizard.Meta):\n            skip_if = IS_FALSY()  # Skip fields if they evaluate as \"falsy\".\n\n        my_bool: bool\n        my_list: list = field(default_factory=list)\n        my_none: None = None\n\n    print(ExampleWithFalsy(my_bool=False, my_list=[], my_none=None).to_dict())\n    #\u003e {}\n\n.. note::\n\n   *Special Cases*\n\n   - **SkipIfNone**: Alias for ``SkipIf(IS(None))``, skips fields with a value of ``None``.\n   - **Condition Helpers**:\n\n     - ``IS``, ``IS_NOT``: Identity checks.\n     - ``EQ``, ``NE``, ``LT``, ``LE``, ``GT``, ``GE``: Comparison operators.\n     - ``IS_TRUTHY``, ``IS_FALSY``: Skip fields based on truthy or falsy values.\n\n   Combine these helpers for flexible serialization rules!\n\n.. _conditional skipping: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/serialization_options.html#skip-if-functionality\n\nSerialization Options\n---------------------\n\nThe following parameters can be used to fine-tune and control how the serialization of a\ndataclass instance to a Python ``dict`` object or JSON string is handled.\n\nSkip Defaults\n~~~~~~~~~~~~~\n\nA common use case is skipping fields with default values - based on the ``default``\nor ``default_factory`` argument to ``dataclasses.field`` - in the serialization\nprocess.\n\nThe attribute ``skip_defaults`` in the inner ``Meta`` class can be enabled, to exclude\nsuch field values from serialization.The ``to_dict`` method (or the ``asdict`` helper\nfunction) can also be passed an ``skip_defaults`` argument, which should have the same\nresult. An example of both these approaches is shown below.\n\n.. code:: python3\n\n    from collections import defaultdict\n    from dataclasses import field, dataclass\n\n    from dataclass_wizard import JSONWizard\n\n\n    @dataclass\n    class MyClass(JSONWizard):\n\n        class _(JSONWizard.Meta):\n            skip_defaults = True\n\n        my_str: str\n        other_str: str = 'any value'\n        optional_str: str = None\n        my_list: list[str] = field(default_factory=list)\n        my_dict: defaultdict[str, list[float]] = field(\n            default_factory=lambda: defaultdict(list))\n\n\n    print('-- Load (Deserialize)')\n    c = MyClass('abc')\n    print(f'Instance: {c!r}')\n\n    print('-- Dump (Serialize)')\n    string = c.to_json()\n    print(string)\n\n    assert string == '{\"myStr\": \"abc\"}'\n\n    print('-- Dump (with `skip_defaults=False`)')\n    print(c.to_dict(skip_defaults=False))\n\nExclude Fields\n~~~~~~~~~~~~~~\n\nYou can also exclude specific dataclass fields (and their values) from the serialization\nprocess. There are two approaches that can be used for this purpose:\n\n* The argument ``dump=False`` can be passed in to the ``json_key`` and ``json_field``\n  helper functions. Note that this is a more permanent option, as opposed to the one\n  below.\n\n* The ``to_dict`` method (or the ``asdict`` helper function ) can be passed\n  an ``exclude`` argument, containing a list of one or more dataclass field names\n  to exclude from the serialization process.\n\nAdditionally, here is an example to demonstrate usage of both these approaches:\n\n.. code:: python3\n\n    from dataclasses import dataclass\n    from typing import Annotated\n\n    from dataclass_wizard import JSONWizard, json_key, json_field\n\n\n    @dataclass\n    class MyClass(JSONWizard):\n\n        my_str: str\n        my_int: int\n        other_str: Annotated[str, json_key('AnotherStr', dump=False)]\n        my_bool: bool = json_field('TestBool', dump=False)\n\n\n    data = {'MyStr': 'my string',\n            'myInt': 1,\n            'AnotherStr': 'testing 123',\n            'TestBool': True}\n\n    print('-- From Dict')\n    c = MyClass.from_dict(data)\n    print(f'Instance: {c!r}')\n\n    # dynamically exclude the `my_int` field from serialization\n    additional_exclude = ('my_int',)\n\n    print('-- To Dict')\n    out_dict = c.to_dict(exclude=additional_exclude)\n    print(out_dict)\n\n    assert out_dict == {'myStr': 'my string'}\n\n``Environ`` Magic\n-----------------\n\nEasily map environment variables to Python dataclasses with ``EnvWizard``:\n\n.. code-block:: python3\n\n    import os\n    from dataclass_wizard import EnvWizard\n\n    # Set up environment variables\n    os.environ.update({\n        'APP_NAME': 'Env Wizard',\n        'MAX_CONNECTIONS': '10',\n        'DEBUG_MODE': 'true'\n    })\n\n    # Define dataclass using EnvWizard\n    class AppConfig(EnvWizard):\n        app_name: str\n        max_connections: int\n        debug_mode: bool\n\n    # Load config from environment variables\n    config = AppConfig()\n    print(config.app_name)    #\u003e Env Wizard\n    print(config.debug_mode)  #\u003e True\n    assert config.max_connections == 10\n\n    # Override with keyword arguments\n    config = AppConfig(app_name='Dataclass Wizard Rocks!', debug_mode='false')\n    print(config.app_name)    #\u003e Dataclass Wizard Rocks!\n    assert config.debug_mode is False\n\n.. note::\n    ``EnvWizard`` simplifies environment variable mapping with type validation, ``.env`` file support, and secret file handling (file names become keys).\n\n    *Key Features*:\n\n    - **Auto Parsing**: Supports complex types and nested structures.\n    - **Configurable**: Customize variable names, prefixes, and dotenv files.\n    - **Validation**: Errors for missing or malformed variables.\n\n    📖 `Full Documentation \u003chttps://dataclass-wizard.readthedocs.io/en/latest/env_magic.html\u003e`_\n\nAdvanced Example: Dynamic Prefix Handling\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``EnvWizard`` supports dynamic prefix application, ideal for customizable environments:\n\n.. code-block:: python3\n\n    import os\n    from dataclass_wizard import EnvWizard, env_field\n\n    # Define dataclass with custom prefix support\n    class AppConfig(EnvWizard):\n\n        class _(EnvWizard.Meta):\n            env_prefix = 'APP_'  # Default prefix for env vars\n\n        name: str = env_field('A_NAME')  # Looks for `APP_A_NAME` by default\n        debug: bool\n\n    # Set environment variables\n    os.environ['CUSTOM_A_NAME'] = 'Test!'\n    os.environ['CUSTOM_DEBUG'] = 'yes'\n\n    # Apply a dynamic prefix at runtime\n    config = AppConfig(_env_prefix='CUSTOM_')  # Looks for `CUSTOM_A_NAME` and `CUSTOM_DEBUG`\n\n    print(config)\n    # \u003e AppConfig(name='Test!', debug=True)\n\nField Properties\n----------------\n\nThe Python ``dataclasses`` library has some `key limitations`_\nwith how it currently handles properties and default values.\n\nThe ``dataclass-wizard`` package natively provides support for using\nfield properties with default values in dataclasses. The main use case\nhere is to assign an initial value to the field property, if one is not\nexplicitly passed in via the constructor method.\n\nTo use it, simply import\nthe ``property_wizard`` helper function, and add it as a metaclass on\nany dataclass where you would benefit from using field properties with\ndefault values. The metaclass also pairs well with the ``JSONSerializable``\nmixin class.\n\nFor more examples and important how-to's on properties with default values,\nrefer to the `Using Field Properties`_ section in the documentation.\n\nWhat's New in v1.0\n------------------\n\n.. admonition:: Opt-in for v1 Now Available\n\n   The early opt-in for **v1** is now available with enhanced features, including intuitive ``Union`` parsing and optimized performance. To enable this,\n   set ``v1=True`` in your ``Meta`` settings.\n\n   For more details and migration guidance, see the `Field Guide to V1 Opt-in`_.\n\n.. warning:: *Important Changes in v1.0*\n\n    - **Default Key Transformation Update**\n\n      Starting with **v1.0.0**, the default key transformation for JSON serialization\n      will change to keep keys *as-is* instead of converting them to ``camelCase``.\n\n      **New Default Behavior**:\n      The default setting for key transformation will be ``key_transform='NONE'``.\n\n      **How to Prepare**:\n      You can enforce this behavior immediately by using the ``JSONPyWizard`` helper, as shown below:\n\n      .. code-block:: python3\n\n            from dataclasses import dataclass\n            from dataclass_wizard import JSONPyWizard\n\n            @dataclass\n            class MyModel(JSONPyWizard):\n                my_field: str\n\n            print(MyModel(my_field=\"value\").to_dict())\n            # Output: {'my_field': 'value'}\n\n    - **Default __str__() Behavior Change**\n\n      Starting with **v1.0.0**, we no longer pretty-print the serialized JSON value with keys in ``camelCase``.\n      Instead, we now use the ``pprint`` module to handle serialization formatting.\n\n      **New Default Behavior**:\n      The ``__str__()`` method in the ``JSONWizard`` class will use ``pprint`` by default.\n\n      **How to Prepare**:\n      You can immediately test this new behavior using the ``JSONPyWizard`` helper, as demonstrated below:\n\n      .. code-block:: python3\n\n            from dataclasses import dataclass\n            from dataclass_wizard import JSONWizard, JSONPyWizard\n\n            @dataclass\n            class CurrentModel(JSONWizard):\n                my_field: str\n\n            @dataclass\n            class NewModel(JSONPyWizard):\n                my_field: str\n\n            print(CurrentModel(my_field=\"value\"))\n            #\u003e {\n            #   \"myField\": \"value\"\n            # }\n\n            print(NewModel(my_field=\"value\"))\n            #\u003e NewModel(my_field='value')\n\n    - **Float to Int Conversion Change**\n      Starting with **v1.0**, floats or float strings with fractional parts (e.g., ``123.4`` or ``\"123.4\"``) will no longer be silently converted to integers. Instead, they will raise an error. However, floats without fractional parts (e.g., ``3.0`` or ``\"3.0\"``) will continue to convert to integers as before.\n\n      **How to Prepare**:\n      You can opt in to **v1** via ``v1=True`` to test this behavior right now. Additionally, to ensure compatibility with the new behavior:\n\n      - Use ``float`` annotations for fields that may include fractional values.\n      - Review your data to avoid passing fractional values (e.g., ``123.4``) to fields annotated as ``int``.\n      - Update tests or logic that depend on the current rounding behavior.\n\n      .. code-block:: python3\n\n            from dataclasses import dataclass\n            from dataclass_wizard import JSONPyWizard\n\n            @dataclass\n            class Test(JSONPyWizard):\n                class _(JSONPyWizard.Meta):\n                    v1 = True\n\n                list_of_int: list[int]\n\n            input_dict = {'list_of_int': [1, '2.0', '3.', -4, '-5.00', '6', '-7']}\n            t = Test.from_dict(input_dict)\n            print(t)  #\u003e Test(list_of_int=[1, 2, 3, -4, -5, 6, -7])\n\n            # ERROR!\n            _ = Test.from_dict({'list_of_int': [123.4]})\n\nContributing\n------------\n\nContributions are welcome! Open a pull request to fix a bug, or `open an issue`_\nto discuss a new feature or change.\n\nCheck out the `Contributing`_ section in the docs for more info.\n\nTODOs\n-----\n\nAll feature ideas or suggestions for future consideration, have been currently added\n`as milestones`_ in the project's GitHub repo.\n\nCredits\n-------\n\nThis package was created with Cookiecutter_ and the `rnag/cookiecutter-pypackage`_ project template.\n\n.. _Read The Docs: https://dataclass-wizard.readthedocs.io\n.. _Installation: https://dataclass-wizard.readthedocs.io/en/latest/installation.html\n.. _Cookiecutter: https://github.com/cookiecutter/cookiecutter\n.. _`rnag/cookiecutter-pypackage`: https://github.com/rnag/cookiecutter-pypackage\n.. _`Contributing`: https://dataclass-wizard.readthedocs.io/en/latest/contributing.html\n.. _`open an issue`: https://github.com/rnag/dataclass-wizard/issues\n.. _`JSONPyWizard`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/wizard_mixins.html#jsonpywizard\n.. _`EnvWizard`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/wizard_mixins.html#envwizard\n.. _`on EnvWizard`: https://dataclass-wizard.readthedocs.io/en/latest/env_magic.html\n.. _`JSONListWizard`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/wizard_mixins.html#jsonlistwizard\n.. _`JSONFileWizard`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/wizard_mixins.html#jsonfilewizard\n.. _`TOMLWizard`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/wizard_mixins.html#tomlwizard\n.. _`YAMLWizard`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/wizard_mixins.html#yamlwizard\n.. _`Container`: https://dataclass-wizard.readthedocs.io/en/latest/dataclass_wizard.html#dataclass_wizard.Container\n.. _`Supported Types`: https://dataclass-wizard.readthedocs.io/en/latest/overview.html#supported-types\n.. _`Mixin`: https://stackoverflow.com/a/547714/10237506\n.. _`Meta`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/meta.html\n.. _`pydantic`: https://pydantic-docs.helpmanual.io/\n.. _`Using Field Properties`: https://dataclass-wizard.readthedocs.io/en/latest/using_field_properties.html\n.. _`field properties`: https://dataclass-wizard.readthedocs.io/en/latest/using_field_properties.html\n.. _`custom mapping`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/custom_key_mappings.html\n.. _`wiz-cli`: https://dataclass-wizard.readthedocs.io/en/latest/wiz_cli.html\n.. _`key limitations`: https://florimond.dev/en/posts/2018/10/reconciling-dataclasses-and-properties-in-python/\n.. _`more complete example`: https://dataclass-wizard.readthedocs.io/en/latest/examples.html#a-more-complete-example\n.. _custom formats: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes\n.. _`Patterned Date and Time`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/patterned_date_time.html\n.. _Union: https://docs.python.org/3/library/typing.html#typing.Union\n.. _`Dataclasses in Union Types`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/dataclasses_in_union_types.html\n.. _`Cyclic or \"Recursive\" Dataclasses`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/cyclic_or_recursive_dataclasses.html\n.. _as milestones: https://github.com/rnag/dataclass-wizard/milestones\n.. _longstanding issue: https://github.com/rnag/dataclass-wizard/issues/62\n.. _Easier Debug Mode: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/easier_debug_mode.html\n.. _Handling Unknown JSON Keys: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/handling_unknown_json_keys.html\n.. _custom paths to access nested keys: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/nested_key_paths.html\n.. _annotations: https://docs.python.org/3/library/typing.html#typing.Annotated\n.. _typing: https://docs.python.org/3/library/typing.html\n.. _dataclasses: https://docs.python.org/3/library/dataclasses.html\n.. _V1 Opt-in documentation for Patterned Date and Time: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/v1_patterned_date_time.html\n.. _`Field Guide to V1 Opt-in`: https://github.com/rnag/dataclass-wizard/wiki/Field-Guide-to-V1-Opt%E2%80%90in\n.. _V1 Alias: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/v1_alias.html\n","funding_links":["https://github.com/sponsors/rnag"],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frnag%2Fdataclass-wizard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frnag%2Fdataclass-wizard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frnag%2Fdataclass-wizard/lists"}