Skip to content

Commit

Permalink
v0.28.0: Minor Performance and QoL Change: Dynamically exec Datacla…
Browse files Browse the repository at this point in the history
…ss Load and Dump Functions (#141)

* loaders.py: Use `CodeBuilder` to dynamically generate code

* loaders.py: Use `CodeBuilder` to dynamically generate code

* Add serial_json.pyi

* dumpers.py: Optimize `cls_asdict` by dynamically generating it

* minor change

* minor optimizations

* minor optimizations

* minor optimizations

* Fix

* Minor changes

* add `TOMLWizard`

* add `TOMLWizard`

* update docs for `TOMLWizard`

* requirements-dev.txt: add explicit `[toml]` dependency

* Fix tests

* I was wrong; that's not needed

* Finalize load/dump hooks for pre-processing

* Add following serializer hooks
  * `_pre_from_dict`
  * `_pre_dict`
* Deprecate `DumpMixin.__pre_as_dict__`
* Add `debug` param to `JSONWizard.__init_subclass__`

* Fix typo in docs

* easier_debug_mode.rst: Add section

* update docs

* minor bump

* Bump HISTORY.rst
  • Loading branch information
rnag authored Nov 15, 2024
1 parent 69ec2cc commit a6d3eaf
Show file tree
Hide file tree
Showing 24 changed files with 1,641 additions and 270 deletions.
25 changes: 25 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@
History
=======

0.28.0 (2024-11-15)
-------------------

**Features and Improvements**

* Added :class:`TOMLWizard`.
* Introduced new (pre-process) serializer hooks:
* :meth:`_pre_from_dict`
* :meth:`_pre_dict`
* Added ``debug`` parameter to :meth:`JSONWizard.__init_subclass__`.
* Added ``*.pyi`` stub files for better Type Hinting and Autocompletion in IDEs (e.g., PyCharm):
* :file:`abstractions.pyi`
* :file:`serial_json.pyi`
* Introduced utility class :class:`FunctionBuilder` to help build and dynamically ``exec`` a function.
* Documentation/tests on the new and updated features.

**Changes**

* The returned parser for a dataclass is now the original load/dump function itself (which takes a single argument)
rather than a :class:`Parser` instance.
* Minor optimization and quality-of-life improvement: dynamically ``exec`` dataclass load and dump functions.
* Improved performance: if a class defines a :meth:`from_dict` method - equivalent to :func:`fromdict` - and a :meth:`to_dict` method
- equivalent to :func:`asdict` - replace them with dynamically generated load/dump functions.
* Deprecated the pre-process hook :meth:`DumpMixin.__pre_as_dict__`.

0.27.0 (2024-11-10)
-------------------

Expand Down
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ In addition to the ``JSONWizard``, here are a few extra Mixin_ classes that migh

* `JSONListWizard`_ -- Extends ``JSONWizard`` to return `Container`_ -- instead of *list* -- objects where possible.
* `JSONFileWizard`_ -- Makes it easier to convert dataclass instances from/to JSON files on a local drive.
* `TOMLWizard`_ -- Provides support to convert dataclass instances to/from TOML.
* `YAMLWizard`_ -- Provides support to convert dataclass instances to/from YAML, using the default ``PyYAML`` parser.


Expand Down Expand Up @@ -961,6 +962,7 @@ This package was created with Cookiecutter_ and the `rnag/cookiecutter-pypackage
.. _`open an issue`: https://github.com/rnag/dataclass-wizard/issues
.. _`JSONListWizard`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/wizard_mixins.html#jsonlistwizard
.. _`JSONFileWizard`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/wizard_mixins.html#jsonfilewizard
.. _`TOMLWizard`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/wizard_mixins.html#tomlwizard
.. _`YAMLWizard`: https://dataclass-wizard.readthedocs.io/en/latest/common_use_cases/wizard_mixins.html#yamlwizard
.. _`Container`: https://dataclass-wizard.readthedocs.io/en/latest/dataclass_wizard.html#dataclass_wizard.Container
.. _`Supported Types`: https://dataclass-wizard.readthedocs.io/en/latest/overview.html#supported-types
Expand Down
3 changes: 2 additions & 1 deletion dataclass_wizard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
# Wizard Mixins
'JSONListWizard',
'JSONFileWizard',
'TOMLWizard',
'YAMLWizard',
# Helper serializer functions + meta config
'fromlist',
Expand All @@ -104,7 +105,7 @@
Pattern, DatePattern, TimePattern, DateTimePattern)
from .property_wizard import property_wizard
from .serial_json import JSONSerializable
from .wizard_mixins import JSONListWizard, JSONFileWizard, YAMLWizard
from .wizard_mixins import JSONListWizard, JSONFileWizard, TOMLWizard, YAMLWizard


# Set up logging to ``/dev/null`` like a library is supposed to.
Expand Down
23 changes: 1 addition & 22 deletions dataclass_wizard/abstractions.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class AbstractParser(ABC, Generic[T, TT]):
# This is usually the underlying base type of the annotation (for example,
# for `List[str]` it will be `list`), though in some cases this will be
# the annotation itself.
base_type: T
base_type: type[T]

def __contains__(self, item) -> bool:
"""
Expand Down Expand Up @@ -356,24 +356,3 @@ def get_parser_for_annotation(cls, ann_type: Type[T],

class AbstractDumper(ABC):
__slots__ = ()

def __pre_as_dict__(self):
"""
Optional hook that runs before the dataclass instance is processed and
before it is converted to a dictionary object via :meth:`to_dict`.
To override this, subclasses need to extend from :class:`DumpMixIn`
and implement this method. A simple example is shown below:
>>> from dataclasses import dataclass
>>> from dataclass_wizard import JSONSerializable, DumpMixin
>>>
>>>
>>> @dataclass
>>> class MyClass(JSONSerializable, DumpMixin):
>>> my_str: str
>>>
>>> def __pre_as_dict__(self):
>>> self.my_str = self.my_str.swapcase()
"""
Loading

0 comments on commit a6d3eaf

Please sign in to comment.