# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['serdelicacy']

package_data = \
{'': ['*']}

setup_kwargs = {
    'name': 'serdelicacy',
    'version': '0.16.0',
    'description': 'Serialize/deserialize Python objects from/to typed structures.',
    'long_description': '# serdelicacy\n\n[![image-version](https://img.shields.io/pypi/v/serdelicacy.svg)](https://python.org/pypi/serdelicacy)\n[![image-license](https://img.shields.io/pypi/l/serdelicacy.svg)](https://python.org/pypi/serdelicacy)\n[![image](https://img.shields.io/pypi/pyversions/serdelicacy.svg)](https://python.org/pypi/serdelicacy)\n[![image-ci](https://github.com/pappasam/serdelicacy/workflows/serdelicacy%20ci/badge.svg)](https://github.com/pappasam/serdelicacy/actions?query=workflow%3A%22serdelicacy+ci%22)\n\nSerialize (`serdelicacy.dump`) and deserialize (`serdelicacy.load`) from/to strongly-typed, native Python data structures.\n\n## Features\n\n1. Effortless deserialization of unstructured Python types into structured, type-hinted Python types (`dataclasses.dataclass`, `typing.NamedTuple`)\n2. Effortless serialization of structured, type-hinted Python objects into unstructured Python types (eg, the reverse)\n3. Clear error messages when serde fails at runtime\n4. No inherited, non-standard types. dataclasses, NamedTuples, and other standard Python types are bread and butter\n5. Editor support: I like my autocompletion, so I jump through lots of hoops to make this library compatible with Jedi\n6. Handle [optional properties](https://www.typescriptlang.org/docs/handbook/interfaces.html#optional-properties) with a domain-specific `serdelicacy.OptionalProperty`\n7. Enable customization through sophisticated validation, deserialization overrides, and serialization overrides for dataclasses.\n8. Require no 3rd party dependencies; Python 3.8+\n\n## Installation\n\n```bash\n# With pip\npip install serdelicacy\n\n# With poetry\npoetry add serdelicacy\n```\n\n## Usage\n\nSee [examples folder](https://github.com/pappasam/serdelicacy/tree/master/example).\n\n## Validation / transformation for dataclasses\n\nCustomization override options are available for validations and transformations on both deserialization and serialization. Custom overrides are available for `dataclasses` through the `metadata` argument to the `dataclasses.field` function:\n\n```python\nfrom dataclasses import dataclass, field\n\nimport serdelicacy\nfrom serdelicacy import Override\n\ndef _is_long_enough(value) -> None:\n    if len(value) < 4:\n        raise ValueError(f"\'{value}\' is not enough characters")\n\nVALUE = {"firstname": "richard", "lastname": "spencerson"}\n\n@dataclass\nclass Person:\n    firstname: str = field(\n        metadata={\n            "serdelicacy": Override(\n                validate=_is_long_enough,\n                transform_load=str.title,\n            )\n        }\n    )\n    lastname: str = field(\n        metadata={\n            "serdelicacy": Override(\n                validate=_is_long_enough,\n                transform_load=str.title,\n                transform_dump=str.upper,\n            )\n        }\n    )\n\nprint(serdelicacy.load(VALUE, Person))\n```\n\nAs suggested by the Python [dataclasses.field documentation](https://docs.python.org/3/library/dataclasses.html#dataclasses.field), all `serdelicacy`-related field metadata is namespaced to 1 dictionary key: `serdelicacy`. Its value should be of type `serdelicacy.Override`, a dataclass itself whose fields are the following:\n\n- `validate`: `Callable[[Any], NoReturn], Callable[[Any], bool]`: a function that either a) returns a boolean where False indicates failed validation or b) nothing, but raises Python exceptions on validation failure. Is executed as the final step of a value\'s load, after all transformations have been completed. By default, this is a function that does nothing.\n- `transform_load`: `Callable[[Any], Any]`. This transformation is executed before any other loading takes place. By default, this is an [identity function](https://en.wikipedia.org/wiki/Identity_function)\n- `transform_postload`: this should be `Callable[[T], T]]`, where `T` is the type of the field. This transformation is executed after all recursive loading takes place as the final step before the value is returned for upstream processing. By default, this is an [identity function](https://en.wikipedia.org/wiki/Identity_function)\n\nFinally, you may not need to use these tools initially, but if you have strict validation or transformation requirements on your project, you\'ll be extremely happy they\'re here\n\n## FAQ\n\n### My JSON keys contain whitespace, etc\n\nSimple solution: use `typeing.TypeDict`\'s [backwards-compatibility syntax](https://www.python.org/dev/peps/pep-0589/#alternative-syntax).\n\n```python\nfrom pprint import pprint\nfrom typing import List, TypedDict\n\nimport serdelicacy\nfrom serdelicacy import OptionalProperty\n\nDATA = [\n    {\n        "weird, key": 1,\n        "normal": 2,\n    },\n    {\n        "normal": 3,\n    },\n]\n\nDataItem = TypedDict(\n    "DataItem",\n    {\n        "weird, key": OptionalProperty[int],\n        "normal": int,\n    },\n)\n\nLOADED = serdelicacy.load(DATA, List[DataItem])\n\nprint("Loaded data:")\npprint(LOADED)\n\nprint("Re-serialized data:")\npprint(serdelicacy.dump(LOADED))\n```\n\nThis prints the following to the console.\n\n```text\nLoaded data:\n[{\'normal\': 2, \'weird, key\': 1},\n {\'normal\': 3, \'weird, key\': <Missing property>}]\nRe-serialized data:\n[{\'normal\': 2, \'weird, key\': 1}, {\'normal\': 3}]\n```\n\nTry changing values in your JSON data; you\'ll get runtime errors if your data does not conform to the above schema. Additionally, `mypy` should call out any misused variable keys / types. In short, this has enabled a type-safe load and a perfectly sane dump.\n\n## Local Development\n\nLocal development for this project is simple.\n\n**Dependencies**\n\nInstall the following tools manually.\n\n- [Poetry](https://github.com/sdispater/poetry#installation)\n- [GNU Make](https://www.gnu.org/software/make/)\n\n_Recommended_\n\n- [asdf](https://github.com/asdf-vm/asdf)\n\n**Set up development environment**\n\n```bash\nmake setup\n```\n\n**Run Tests**\n\n```bash\nmake test\n```\n\n## Notes\n\n- Initially inspired by [undictify](https://github.com/Dobiasd/undictify) and a PR I helped with. serdelicacy\'s goals are different; it\'s focused on serde instead of general function signature overrides.\n- I also notice some striking similarities with a library called [typedload](https://github.com/ltworf/typedload) (great minds think alike, I guess :p). I renamed my top-level functions to "load" and "dump" in typedload\'s homage. Unfortunately, as of version `1.20`, typedload does not handle all types of dataclasses elegantly (mainly, InitVar). Since typedload supports Python 3.5+, it never will elegantly handle all dataclasses without lots of unfortunate conditionals in the codebase. If you must use Python 3.7-, I suggest looking into typedload.\n\n## Written by\n\nSamuel Roeca *samuel.roeca@gmail.com*\n',
    'author': 'Sam Roeca',
    'author_email': 'samuel.roeca@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/pappasam/serdelicacy',
    'packages': packages,
    'package_data': package_data,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
