Metadata-Version: 2.1
Name: dataclass-mapper
Version: 1.2.0
Summary: Autogenerate mappings between dataclasses
Home-page: https://dataclass-mapper.readthedocs.io
License: MIT
Keywords: dataclass,pydantic,python,automation
Author: Jakob Kogler
Author-email: jakob.kogler@gmail.com
Requires-Python: >=3.9,<4.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Software Development :: Code Generators
Provides-Extra: pydantic
Requires-Dist: pydantic (>=1.9.0,<2.0.0); extra == "pydantic"
Project-URL: Documentation, https://dataclass-mapper.readthedocs.io
Project-URL: Repository, https://github.com/dataclass-mapper/dataclass-mapper
Description-Content-Type: text/x-rst

dataclass-mapper
================

|pypi| |support| |licence| |readthedocs| |build| |coverage|

.. |pypi| image:: https://img.shields.io/pypi/v/dataclass-mapper.svg?style=flat-square
    :target: https://pypi.org/project/dataclass-mapper/
    :alt: pypi version

.. |support| image:: https://img.shields.io/pypi/pyversions/dataclass-mapper.svg?style=flat-square
    :target: https://pypi.org/project/dataclass-mapper/
    :alt: supported Python version

.. |build| image:: https://github.com/dataclass-mapper/dataclass-mapper/actions/workflows/test.yml/badge.svg
    :target: https://github.com/dataclass-mapper/dataclass-mapper/actions
    :alt: build status

.. |coverage| image:: https://codecov.io/gh/dataclass-mapper/dataclass-mapper/branch/main/graphs/badge.svg?branch=main
    :target: https://codecov.io/gh/dataclass-mapper/dataclass-mapper?branch=main
    :alt: Code coverage

.. |licence| image:: https://img.shields.io/pypi/l/dataclass-mapper.svg?style=flat-square
    :target: https://pypi.org/project/dataclass-mapper/
    :alt: licence

.. |readthedocs| image:: https://img.shields.io/readthedocs/dataclass-mapper/latest.svg?style=flat-square&label=Read%20the%20Docs
   :alt: Read the documentation at https://dataclass-mapper.readthedocs.io/en/latest/
   :target: https://dataclass-mapper.readthedocs.io/en/latest/

Writing mapper methods between two similar dataclasses is boring, need to be actively maintained and are error-prone.
Much better to let a library auto-generate them for you.

This library makes it easy to autogenerate mappers, makes sure that the types between source and target class match, and that all fields of the target class are actually mapped to.
Most of those checks are already done at class definition time, not when the mappings are run.
It supports Python's dataclasses and also Pydantic models, and can also map between those two.

Installation
------------

``dataclass-mapper`` can be installed using:

.. code-block:: bash

    pip install dataclass-mapper
    # or for Pydantic support
    pip install dataclass-mapper[pydantic]

Small Example
-------------

We have the following target data structure, a class called ``Person``.

.. code-block:: python

    from dataclasses import dataclass

    @dataclass
    class Person:
        first_name: str
        second_name: str
        age: int

We want to have a mapper from the source data structure, a class called ``ContactInfo``.
Notice that the attribute ``second_name`` of `Person` is called ``surname`` in `ContactInfo`.
Other than that, all the attribute names are the same.

Instead of writing a mapper `to_Person` by hand:

.. code-block:: python

    @dataclass
    class ContactInfo:
        first_name: str
        surname: str
        age: int

        def to_Person(self) -> Person:
            return Person(
                first_name=self.first_name,
                second_name=self.surname,
                age=self.age,
            )

    person = some_contact.to_Person()

you can let the mapper autogenerate with:

.. code-block:: python

    from dataclass_mapper import map_to, mapper

    @mapper(Person, {"second_name": "surname"})
    @dataclass
    class ContactInfo:
        first_name: str
        surname: str
        age: int

    person = map_to(some_contact, Person)

The ``dataclass-mapper`` library autogenerated some a mapper, that can be used with the ``map_to`` function.
All we had to specify was the name of the target class, and optionally specify which fields map to which other fields.
Notice that we only had to specify that the ``second_name`` field has to be mapped to ``surname``,
all other fields were mapped automatically because the field names didn't change.

And the ``dataclass-mapper`` library will perform a lot of checks around this mapping.
It will check if the data types match, if some fields would be left uninitialized, etc.

Features
--------

The current version has support for:

* Python's ``dataclass``
* ``pydantic`` classes
* Checks if all target fields are actually initialized.
  Raises a ``ValueError`` at class definition time when the type is different.
* Checks if the type on the target field is the same as the source field.
  Raises a ``TypeError`` at class definition time when the type is different.
* Recursive dataclasses
* ``IGNORE_MISSING_MAPPING`` for values that you don't wanna set but have a default value/factory.
* ``Optional`` types (mapping from an non-optional to an optional field, or to an optional field with default values/fields).
  Raises a ``TypeError`` at class definition time when an optional type is mapped to a non-optional type.
* ``List`` types
* Mapper in both direction with ``mapper`` and ``mapper_from``.
* Assign Values with lambdas (e.g. ``{"x": lambda: 42}``)
* Custom mapping computations with with lambdas (e.g. ``{"x": lambda self: self.x + 1}``)
* For Optional fields in Pydantic classes, only set those target fields that actually set in the source (`__fields_set__`).

Still missing features:

* ``Union`` types
* ``Dict`` types
* Aliases in `pydantic` classes
* Checking if all source attributes were used
* SQLAlchemy ORM / attr

License
-------

The project is released under the `MIT license <https://github.com/dataclass-mapper/dataclass-mapper/blob/main/LICENSE.md>`_.

