Yet another serialization library on top of dataclasses, inspired by serde-rs.

Overview

pyserde

Yet another serialization library on top of dataclasses, inspired by serde-rs.

image image Tests codecov

Guide | API Docs | Examples

Overview

Declare a class with pyserde's @serde decorator.

@serde
class Foo:
    i: int
    s: str
    f: float
    b: bool

You can serialize Foo object into JSON.

>>> to_json(Foo(i=10, s='foo', f=100.0, b=True))
{"i": 10, "s": "foo", "f": 100.0, "b": true}

You can deserialize JSON into Foo object.

>>> from_json(Foo, '{"i": 10, "s": "foo", "f": 100.0, "b": true}')
Foo(i=10, s='foo', f=100.0, b=True)

Features

LICENSE

This project is licensed under the MIT license.

Comments
  • feat: Support numpy types

    feat: Support numpy types

    • Adds support for numpy types specified in dataclasses, converting them to and from standard python types as needed.
    • ~Note that this commit does NOT handle the case where a numpy type is misrepresented as a standard python type. In most cases, these values will fail to serialize, or may be serialized incorrectly.~

    The second commit now supports serialization of untyped or incorrectly typed numpy values (i.e., where the type of a variable is a regular Python type, but the contents are a numpy scalar or array) for json and toml only. Deserialization is unaffected in these cases--i.e., the value will be deserialized to the declared (non-numpy) type. (Deserialization to declared numpy types is handled in the first commit).

    It should be possible to add support for yaml and toml, but the mechanism for doing so is different and not as obvious.

    Closes #145

    opened by kmsquire 22
  • More types & some refactoring

    More types & some refactoring

    This pull request adds support for more types and also utilizes the code generation capabilities for them.

    The following types where added:

    • uuid.UUID
    • PosixPath, WindowsPath, PurePath, PurePosixPath, PureWindowsPath from pathlib
    • IPv4Address, IPv6Address, IPv4Network, IPv6Network, IPv4Interface, IPv6Interface from ipaddress
    • date & datetime from datetime

    I needed these types because I wanted to use pyserde in combination with asyncpg. asyncpg returns dict like objects which can be converted to dataclasses by pyserde's from_dict function.

    Since asyncpg also supports the above mentioned types, the dicts already contain instances of them. That is the reason why I also added a new argument reuse_instances for from_dict & from_tuple. When this is set to True these functions check if the field already contains an instances of the target type and reuse it when possible.

    This is faster for Path & IPAddress then calling the constructor again. For UUID it is also the only way to handle existing instances because uuid.UUID() does not accept them as an argument. It is also possible to change the default value of reuse_instances via the serialize & deserialize decorators.

    To not cause slowdowns when serializing or deserializing to json/msgpack/toml/yaml reuse_instances is always set to False there, because we will never see existing instances there.

    That is the part where this pull request drifted into refactoring. Since I had to add the reuse_instances argument at all these places, I also used the opportunity to remove some unused arguments (named & strict) and renamed asdict to to_dict and astuple to to_tuple. These are breaking changes, but I felt it was worth the gained similarity between serialization and deserialization code. In my option the public exposed functions are now also named more uniformly.

    For msgpack external types I also changed the behaviour slightly. It is not required anymore that the dataclasses have a special meaning _type attribute. Instead to_msgpack & from_msgpack search the ext_dict for the correct type or type code and also throw exceptions if they can not find them.

    I am sorry that this became so intertwined, I understand if you don't want to merge the breaking changes. I tried to make the commits cherry-pickable so maybe you only want to use some commits.

    During development, I also noticed that Unions do not work properly for these types. I will make a separate pull request to fix that.

    Finally, I have a question: What is the purpose of setting SE_NAME and why is it used in is_serializable? Could it be removed? is_serializable could use TO_ITER and TO_DICT for the check like is_deserializable.

    opened by ydylla 17
  • Switch from TravisCI to Github Action workflows

    Switch from TravisCI to Github Action workflows

    Hi!

    I've tried to rewrite your Travis CI workflow with Github Actions but your feedback needed.

    Current status:

    • there are two workflows:
      • test.yml workflow
        • fires on every push to non-master branch and every pull request
        • runs tests on multiple python versions in parallel
        • runs benchmark if all tests are passed
        • checks coverage if all tests are passed
      • build.yml
        • fires only if master branch was updated
        • do everything test.yml does + build docs and updates gh-pages branch (only if all tests are passed also)
    • tests run smoothly on all defined Python versions (3.6 - 3.9, pypy3)
    • coverage check and benchmark run are decoupled into two separate steps for better maintainability
    • gh-pages update is now slightly more elegant thanks to "GitHub Pages Deploy Action" (https://github.com/JamesIves/github-pages-deploy-action)

    Drawbacks:

    • workflows are not optimised yet in terms of speed (no cache etc.)
    • same codeblocks are used in test.yml and build.yml. This is avoidable, though. If you will never push directly to master branch you can safely remove 'test', 'check_coverage' and 'run_benchmark' steps from build.yml
    • gh-pages commit message is always "docs: Update docs". I beleive this is also fixable
    • .travis.yml should be removed because it will push changes in gh-pages branch instead

    Questions:

    1. Is decoupling coverage check from brnchmark OK for you?
    2. make coverage also run tests. This is usable during local developement, but slow things up in CI. Maybe you can add a separate Makefile command just for checking coverage in CI?
    3. Do you absolutely need gh-pages commit messages to be verbose (with a reference to commit or pull request)?

    Please review the PR and let me know if anything else needed.

    opened by alexmisk 11
  • Add support for lazy type annotations PEP563 (#112)

    Add support for lazy type annotations PEP563 (#112)

    Hi @yukinarit, I added basic support for from __future__ import annotations.

    Do you have any ideas how we could tell pytest to skip test_lazy_type_evaluation.py when using python 3.6 since the annotations future does not exist there?

    Closes #112

    opened by ydylla 9
  • msgpack and nested serialization

    msgpack and nested serialization

    Trying to figure out how to resolve this problem:

    >>> from serde.msgpack import from_msgpack, to_msgpack
    >>> from simpleRaft.messages.append_entries import AppendEntriesMessage, LogEntry
    >>> a = LogEntry(term=0)
    
    # Can serialize LogEntry below
    
    >>> to_msgpack(a)
    b'\x85\xa4term\x00\xa5index\x00\xa7command\x00\xa3key\xc0\xa5value\xc0'
    
    # Just not when it's nested in another serializable object
    
    >>> b = AppendEntriesMessage(sender=1, receiver=2, term=3, entries=[a])
    >>> to_msgpack(b)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/arun/.local/lib/python3.8/site-packages/pyserde-0.2.1-py3.8.egg/serde/msgpack.py", line 34, in to_msgpack
        return se.serialize(obj, **opts)
      File "/home/arun/.local/lib/python3.8/site-packages/pyserde-0.2.1-py3.8.egg/serde/msgpack.py", line 23, in serialize
        return msgpack.packb(maybe_ext, use_bin_type=use_bin_type, **opts)
      File "/home/arun/.local/lib/python3.8/site-packages/msgpack/__init__.py", line 35, in packb
        return Packer(**kwargs).pack(o)
      File "msgpack/_packer.pyx", line 286, in msgpack._cmsgpack.Packer.pack
      File "msgpack/_packer.pyx", line 292, in msgpack._cmsgpack.Packer.pack
      File "msgpack/_packer.pyx", line 289, in msgpack._cmsgpack.Packer.pack
      File "msgpack/_packer.pyx", line 225, in msgpack._cmsgpack.Packer._pack
      File "msgpack/_packer.pyx", line 258, in msgpack._cmsgpack.Packer._pack
      File "msgpack/_packer.pyx", line 283, in msgpack._cmsgpack.Packer._pack
    TypeError: can not serialize 'LogEntry' object
    
    opened by adsharma 9
  • Support generics

    Support generics

    Hi @jennydaman!

    It's tricky but possible to support Generics. Here is POC implementation.

    Since I am not a heavy user of typing.Generics, I would like to ask you to confirm few things. It would be great if you could know.

    1. What is the best way to check the type inheriting typing.Generics.

    I use this code in the POC.

    def is_generic(typ) -> bool:
        return typing.get_origin(typ) is not None
    
    1. When a generic type is not specified like MyClass instead of MyClass[Nested], what do you expect the type of thing? Is it any? 🤔
    opened by yukinarit 8
  • Improve Union type support

    Improve Union type support

    This tries to add support for Unions with complex types like UUID or IPv4Address.

    The basic idea is to use the code generation to add function for each Union the dataclass uses. This union function then tries to serialize or deserialize the field according to the order of types defined in the Union. The first one that works is used.

    Using the code generation for this has the advantage that the user can influence the order of checks and that only types are checked that are defined in the Union. Which should be faster, then always checking against all types that pyserde supports.

    Currently, not all tests work. I have not found a good solution for nested Unions or container types within Unions, e.g. Union[List[int],List[str]]. We probably need some form of recursion.

    Some notable other changes:

    • Implemented is_set in compat.py
    • The rendered dict & iter functions now define a variable serde_scope which I needed to pass it to the union functions.
    • The render functions now render NoneType as None. I think this broke the test_union_optional test, but I still have to look into it.

    @yukinarit If you have time, I would appreciate a review and your opinion about the general idea? Also I noticed you increased the version to 0.2.3 so only at patch level. Do you use semantic versioning? Then it should be 0.3.0 in my opinion because the new type support is a feature :smile:.

    Closes #60

    opened by ydylla 8
  • Support inference of types on deserialization

    Support inference of types on deserialization

    The API as it stands now needs the caller to explicitly specify the type to be decoded. Sometimes its desirable to infer that from the serialized bytes.

    from simpleRaft.messages.append_entries import AppendEntriesMessage
    from simpleRaft.messages.request_vote import RequestVoteMessage
    from simpleRaft.messages.base import BaseMessage
    from serde.msgpack import from_msgpack, to_msgpack
    
    ext_dict = {
      BaseMessage.MessageType.AppendEntries: AppendEntriesMessage,
      BaseMessage.MessageType.RequestVote: RequestVoteMessage,
    }
    
    a = AppendEntriesMessage("alice", "Bob", 123, 0, 0)
    x = to_msgpack(a)
    print(x)
    b = from_msgpack(BaseMessage, x)
    print(b, type(b))  # prints BaseMessage
    
    a = RequestVoteMessage("alice", "Bob", 123, 0, 0)
    x = to_msgpack(a, ext_dict=ext_dict)
    print(x)
    b = from_msgpack(BaseMessage, x, ext_dict=ext_dict)
    print(b, type(b))  # prints RequestVoteMessage
    a == b  # prints True
    
    opened by adsharma 8
  • Add support for orjson, including direct numpy support

    Add support for orjson, including direct numpy support

    This pull request builds on #209, adding support for orjson and modifying numpy support to pass values through to orjson when that module is chosen as the (de)serializer and the appropriate flags are passed.

    Still needs tests and probably discussion around how much of orjson to pull in.

    opened by kmsquire 7
  • mypy: Unexpected keyword argument

    mypy: Unexpected keyword argument

    Hi,

    This is very cool!

    Unfortunately, when I use mypy, I get Unexpected keyword argument when I try to return a @serdeed class from a function. I'm not sure if serde would need to have a mypy plugin or if I'm making a mistake.

    I can make a minimal test case if needed.

    Thank you!

    bug 
    opened by gitpushdashf 7
  • Missing types with custom class deserializers

    Missing types with custom class deserializers

    The code generation doesn't put Optional or Union in scope when calling a custom class deserializer. This results in a NameError during deserialization.

    Example

    from dataclasses import dataclass
    from typing import Optional
    
    from serde import deserialize, from_dict
    
    
    def deserialize_maybe_str(_typ, value):
        return value
    
    
    @deserialize(deserializer=deserialize_maybe_str)
    @dataclass
    class CustomDe:
        maybe_str: Optional[str]
    
    
    if __name__ == "__main__":
        data = {"maybe_str": "bye"}
        print(f"from_dict({data}) = {from_dict(CustomDe, data)}")
    

    Output

    Traceback (most recent call last):
      File "C:\Users\mauve\dev\modlunky2\src\union_demo.py", line 19, in <module>
        print(f"from_dict({data}) = {from_dict(CustomDe, data)}")
      File "C:\Users\mauve\dev\modlunky2\.venv\lib\site-packages\serde\de.py", line 319, in from_dict
        return from_obj(cls, o, named=True, reuse_instances=reuse_instances)
      File "C:\Users\mauve\dev\modlunky2\.venv\lib\site-packages\serde\de.py", line 253, in from_obj
        return serde_scope.funcs[FROM_DICT](o, reuse_instances=reuse_instances)
      File "<string>", line 10, in from_dict
    NameError: name 'Optional' is not defined
    
    bug 
    opened by mauvealerts 7
  • `ClassVar`s don't get serialized?

    `ClassVar`s don't get serialized?

    Example:

    from serde.se import serialize, to_dict
    
    @serialize
    class Foo:
        value: ClassVar[str] = "abc"
    
    print(to_dict(Foo()))  # Prints {}
    
    opened by AustinScola 0
  • NewType affects untagged Union deserialization

    NewType affects untagged Union deserialization

    A rather complex bug which I struggle to describe. Here's an example:

    from typing import Union, Optional, NewType
    from serde import deserialize, Untagged, from_dict
    from dataclasses import dataclass
    
    OtherNewtypeThing = NewType('OtherNewtypeThing', str)
    
    
    @deserialize
    class SupposedlyUnrelated:
        name: OtherNewtypeThing  # works if you change type to str
    
    @deserialize
    class Innerclass:
        inner_value: str = 'SHOULD_NOT_APPEAR'
    
    
    @deserialize(tagging=Untagged)
    class MyDataclass:
        unrelateds: list[SupposedlyUnrelated]
        buggy_field: list[Union[str, Innerclass]]
    
    
    data = {'unrelateds': [], 'buggy_field':[{'inner_value': 'value'}, 'something']}
    actual = from_dict(MyDataclass, data)
    
    print(actual)
    

    Expected

    MyDataclass(unrelateds=[], buggy_field=[Innerclass(inner_value='value'), 'something'])
    

    Actual

    MyDataclass(unrelateds=[], buggy_field=[Innerclass(inner_value='value'), Innerclass(optional_inner='SHOULD_NOT_APPEAR')])
    

    Instead of deserializing "something" to str which matches Union[str, Innerclass], instead the value is mistakenly interpreted as Innerclass. This happens despite that "something" is not deserializable to Innerclass

    Affected Version

    pyserde 0.9.6 is affected.

    This is a regression from pyserde 0.8.3

    Workaround

    Downgrade to pyserde 0.8.3

    opened by jennydaman 0
  • Add prefix, suffix class attribute

    Add prefix, suffix class attribute

    It would be convenient if pyserde could do like

    @serde(prefix="foo", suffix="key")
    class Foo:
        a: str
    

    Then Foo can be deserialized from {"foo_a_key": "..."}.

    If we set rename_all="camelcase", it will be {"fooAKey": "..."}.

    enhancement 
    opened by yukinarit 0
  • Custom class serializer doesn't work for nested data?

    Custom class serializer doesn't work for nested data?

    Hey @yukinarit,

    I'm running into an issue with a custom class level serializer. I have a dataclass with a field that is a dictionary and I want all datetimes in the dict to be serialized using .timestamp(). This seems to work for top level values, but not for anything nested ? I'm not sure exactly what the expected behavior is here? Is there a different way to accomplish this or is it a bug?

    Example

    from dataclasses import dataclass
    from datetime import datetime
    from typing import Any
    
    from serde import SerdeSkip, serde
    from serde.json import to_json
    
    
    def serializer(cls, o):
        if cls is datetime or isinstance(o, datetime):
            return o.timestamp()
        else:
            raise SerdeSkip()
    
    
    @serde(serializer=serializer)
    @dataclass
    class Foo:
        bar: dict[str, Any]
    
    
    def main():
        d = datetime(2021, 1, 1, 0, 0, 0)
        foo = Foo(bar={"d": d})
        print(to_json(foo))  # prints {"bar":{"d":1609477200.0}}
    
        # The nested datetime here isn't serialized as I would expect it to be?
        d = datetime(2021, 1, 1, 0, 0, 0)
        foo = Foo(bar={"a": {"d": d}})
        print(to_json(foo))  # prints {"bar":{"a":{"d":"2021-01-01T00:00:00"}}}
    
    
    
    if __name__ == '__main__':
        main()
    
    opened by AustinScola 1
  • Support native datetime types in toml and yaml

    Support native datetime types in toml and yaml

    toml and yaml support native datetime types (see e.g., https://toml.io/en/v1.0.0#offset-date-time). Currently pyserde converts all datetime types to string, which prevents tomli and pyyaml from handling these types directly.

    opened by kngwyu 1
  • field skips don't work with custom serializer?

    field skips don't work with custom serializer?

    I think that skip_if_default, skip_if_false, and skip_if don't work if there is a custom serializer?

    Example:

    from serde import serde, field
    from dataclasses import dataclass
    from serde.json import to_json
    
    @serde
    @dataclass
    class Foo:
        bar: str = field(
            default="bar",
            serializer=lambda x: "...",
            skip_if_default=True,
        )
    
    print(to_json(Foo()))  # prints '{"bar":"..."}'
    
    enhancement 
    opened by AustinScola 1
Releases(v0.9.7)
  • v0.9.7(Dec 15, 2022)

    A bug for optional unions was fixed, Thanks @soaxelbrooke!

    @serde
    @dataclass(frozen=True)
    class Bar:
        request: Optional[Union[str, int]]
    
    • docs: add @soaxelbrooke as a contributor (063e705)
    • Add support for optional unions (075949b)
    • Add typing-utils for compatibility with python ver < 3.8 (620b9f6)
    • Rely on compay.get_args instead of adding dependency (d93f894)
    Source code(tar.gz)
    Source code(zip)
  • v0.9.6(Dec 5, 2022)

    • Recursive dataclasses are supported in #290
      @dataclass
      class Recur:
          f: Optional['Recur']
      
      serde(Recur)
      
    • typing.FrozenSet and typing.DefaultDict are supported in #285,#286
      @serde
      @dataclass
      class Foo:
          a: FrozenSet[int]
          b: DefaultDict[str, List[int]]
      
    • Pickle serializer and deserializer support is added in #284. Thanks @DoeringChristian!

    Full Changelog: https://github.com/yukinarit/pyserde/compare/v0.9.5...v0.9.6

    Source code(tar.gz)
    Source code(zip)
  • v0.9.5(Nov 26, 2022)

  • v0.9.4(Nov 20, 2022)

  • v0.9.3(Nov 10, 2022)

  • v0.9.2(Sep 3, 2022)

  • v0.9.1(Aug 30, 2022)

  • v0.9.0(Aug 26, 2022)

    pyserde v0.9 adds one of the most awaited features, the type checking functionality 🎉 If you add Coerce or Strict in serde decorator, pyserde will do type coercing or type checking based on the declared types.

    Coerce

    Type coercing automatically converts a value into the declared type during (de)serialization. If the value is incompatible e.g. value is "foo" and type is int, pyserde raises an SerdeError.

    @serde(type_check=Coerce)
    @dataclass
    class Foo
        s: str
    
    foo = Foo(10)
    # pyserde automatically coerce the int value 10 into "10".
    # {"s": "10"} will be printed.
    print(to_json(foo))
    
    Strict

    Strict type checking is to check every value against the declared type during (de)serialization. We plan to make Strict a default type checker in the future release.

    @serde(type_check=Strict)
    @dataclass
    class Foo
        s: str
    
    foo = Foo(10)
    # pyserde checks the value 10 is instance of `str`.
    # SerdeError will be raised in this case because of the type mismatch.
    print(to_json(foo))
    
    • refactor: Change default type_check from Coerce to NoCheck (23ea180)
    • refactor: Change to pass "type_check" parameter in decorator (fbe8dc8)
    • feat: Add type coercion feature make it default (dabb777)
    • feat: Implement strict type checking (0273b9a)

    Another notable change is switching toml library from toml to tomli. tomli is used in a handful of major products e.g. pip and pytest and will be the part of Python standard library in Python 3.11.

    • feat: Switch toml library to tomli (11b4df6)
    • Better documentation about generic alias (fd4e5a5)
    • Ensure union_func_name produces a valid function name (eddf250)
    • Import 'Literal' from serde.compat (a7450c1)
    • Support NumPy 1.23 in Python 3.7/3.8 (3309a73)
    • Use str instead of repr in typename, fixing Union[Literal["str"], ...] (b3905ef)
    • fix: from_json return returns T not Optional[T] (9e50fb7)

    This release had contributions from 1 person: @kngwyu. Thank you so much! :tada: :joy:

    Source code(tar.gz)
    Source code(zip)
  • v0.8.3(Jun 28, 2022)

  • v0.8.2(Jun 18, 2022)

  • v0.8.1(Jun 15, 2022)

  • v0.8.0(Jun 1, 2022)

    Thanks to the contribution by @kigawas, pyserde can optionally use orjson as JSON serializer!

    pip install pyserde[orjson]
    

    If orjson is installed in the system, pyserde automatically use orjson in to_json/from_json.

    NOTE: In order to align the JSON (de)serializer to orjson, a few parameters are passed in json.dumps internally. This would lead to a breaking change in some cases. If you need the same behaviour as in pyserde<0.8, please explicitely pass those parameters in serde.json.to_json. 🙇‍♂️

    to_json(obj, ensure_ascii=True, separators=(", ", ": "))
    

    Other noteble chage is we have @dataclass decorator back in the all example and test code in the repository as shown below. It's because we found mypy isn't able to deduce the type correctly without @dataclass decorator. If you are not mypy user, you can still declare a class with only @serde decorator. 👍 For more information, please read the docs.

    @serde
    @dataclass  # <-- Recommended to add @dataclass if you are mypy user.
    class Foo:
        i: int
        s: str
        f: float
        b: bool
    
    • build: Add "orjson" extras (ea70ec1)
    • orjson support (2744675)
    • Update json.py (2d67b65)
    • feat: Support class declaration w/wo dataclass (a35f909)
    • fix: Add dataclass decorator for all example code (60567ab)
    • fix: Treat |None as Optional (5555452)
    • Fix the default deserializer for custom class deserializer (6c2245b)

    This release had contributions from 1 person: @kigawas. Thank you so much! :tada: :joy:

    Source code(tar.gz)
    Source code(zip)
  • v0.7.3(May 10, 2022)

    Thanks to the great contribution by @kmsquire, pyserde supports some numpy types!

    @serde
    class NPFoo:
        i: np.int32
        j: np.int64
        f: np.float32
        g: np.float64
        h: np.bool_
        u: np.ndarray
        v: npt.NDArray
        w: npt.NDArray[np.int32]
        x: npt.NDArray[np.int64]
        y: npt.NDArray[np.float32]
        z: npt.NDArray[np.float64]
    
    • feat: Remove try-catch from is_numpy_array() (unnecessary) (731876f)
    • feat: Support Literal[...] type annotation (e50c958)
    • feat: Support numpy types (78eb22e)
    • feat(compat): Only define np_get_origin() for python 3.8 or earlier (02c5af2)
    • feat(numpy): Support serialization of numpy.datetime64 (5e521cf)
    • Don't import tests module from pyserde package (d664426)
    • fix: Recognized numpy arrays on Python 3.7, 3.8 (a0fa36f)
    • fix(numpy): Fix direct numpy array deserialization (8f9f71c)
    • ci: Remove pypy-3.8 until a numpy wheel is released for it (61b6130)
    • chore: Update black, fix test_union formatting (4a708fd)
    • chore: Update numpy version specification based on numpy compatibility with python (1fa5e07)

    This release had contributions from 2 people: @kmsquire and @chagui. Thank you so much! :tada: :joy:

    Source code(tar.gz)
    Source code(zip)
  • v0.7.2(Apr 11, 2022)

  • v0.7.1(Mar 17, 2022)

  • v0.7.0(Feb 14, 2022)

    • fix: Optional in custom class deserializer (181b2f1)
    • fix: raise SerdeError from serde's APIs (76b0aee)
      • pyserde (de)serialize method used to raise various Exceptions such as KeyError. pyserde always raises SerdeError since v0.7.0
    • core: using black formatting only if debug is enabled (e596a84)
    • feat: Add _make_serialize and _make_deserialize (a71c5d5)
    • feat: Implement Union tagging system (c884dc4)
      • This will change the default tagging for dataclasses with Union from Untagged to ExternalTagging. This may break the existing code, so please be aware if you use dataclasses with Union. For more information, check the documentation
    • build: Update mypy to workaround typed_ast error (0ea33a7)

    This release had contributions from 1 person: @tardyp. Thank you so much! :tada: :joy:

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Dec 20, 2021)

    • feat: Add @serde decorator (523dc9c)
    • feat: Add serde field function (488bf00)
    • feat: Add serde_skip_default field attribute (0f0b212)
    • feat: Automatically put dataclass decorator (2f0cf01)

    With serde decorator and field function, you can declare pyserde class more easily.

    from serde import serde, field
    
    @serde
    class Foo:
        a : List[str] = field(default_factory=list, skip_if_false=True)
    

    The declaration until v0.5.3 still works.

    from dataclasses import dataclass
    from serde import serialize, deserialize
    
    @deserialize
    @serialize
    @dataclass
    class Foo:
        a : List[str] = field(default_factory=list, metadata={'serde_skip_if_false': True})
    
    Source code(tar.gz)
    Source code(zip)
  • v0.5.3(Nov 24, 2021)

    • feat: Add more dataclass Field's attrs to Field (7b57c53)
    • feat: Support python 3.10 (2f0c557)
    • refactor: Delete unused imports (629d040)
    • refactor: Remove type references from SerdeScope (bdd8784)
    • refactor: Speficy correct type bound for serde.core.fields (c3b555c)
    • fix: Add types in typing module to scope (e12e802)
    • fix: Never use default value for from_tuple (3ce4f6b)
    • fix: Use default value only if key isn't present (3fa4ab6)
    • Fix typo in README (5f957d0)

    This release had contributions from 2 people: @rnestler, @mauvealerts. Thank you so much! :tada: :joy:

    Source code(tar.gz)
    Source code(zip)
  • v0.5.2(Oct 21, 2021)

  • v0.5.1(Oct 10, 2021)

  • v0.5.0(Sep 30, 2021)

    @deserialize
    @serialize
    @dataclass
    class Bar:
        c: float
        d: bool
    
    @deserialize
    @serialize
    @dataclass
    class Foo:
        a: int
        b: str
        bar: Bar = field(metadata={'serde_flatten': True})
    

    This release had contributions from 1 person: @alexmisk. Thank you so much! :tada: :joy:

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Jun 17, 2021)

    • feat: add support for lazy annotations PEP563 (#112) (f7f6996), closes #112
    from __future__ import annotations
    from dataclasses import dataclass
    from serde import deserialize, serialize
    
    @deserialize
    @serialize
    @dataclass
    class Foo:
        i: int
        s: str
        f: float
        b: bool
    
        def foo(self, cls: Foo):  # You can use "Foo" type before it's defined.
            print('foo')
    
    • feat: Implement custom class (de)serializer (3484d46)
    • feat: Implement custom field (de)serializer (14b791c)
    def serializer(cls, o):
        ...
    
    def deserializer(cls, o):
        ...
    
    @deserialize(deserializer=deserializer)
    @serialize(serializer=serializer)
    @dataclass
    class Foo:
        i: int
        # Class serializer/deserializer is used as default.
        dt1: datetime
        # Override by field serializer/deserializer.
        dt2: datetime = field(
            metadata={
                'serde_serializer': lambda x: x.strftime('%y.%m.%d'),
                'serde_deserializer': lambda x: datetime.strptime(x, '%y.%m.%d'),
            }
        )
    
    • feat: Improve error description for union type (8abb549)
    • feat: Improve serde.inspect (8b8635a)
    • feat: Support typing.any (988a621)
    • feat: Support typing.NewType for primitives (731ed79)
    • refactor: Add lvalue renderer for serialization (665dc77)
    • refactor: Remove arg template filter from se.py (0377655)
    • refactor: Remove self class from scope (da81f1f)
    • refactor: Rename custom (de)serializer attributes (03b2274)
    • ci: Add python 3.10-dev to CI pipeline (1f33e59)
    • ci: Don't cache pip to workaround pip error (c912429)
    • build: add pre-commit to test requirements (a88ea40)
    • fix: correctly render single element tuples (a8a6456)
    • fix: pass convert_sets argument to union functions (ab40cc9)
    • fix: support unions with nested unions in containers (#113) (c26e828), closes #113
    Source code(tar.gz)
    Source code(zip)
  • v0.3.2(May 7, 2021)

    • feat: Improve error description for union type (8abb549)
    • feat: Improve serde.inspect (8b8635a)
    • feat: Support typing.any (988a621)
    • feat: Support typing.NewType for primitives (731ed79)
    • build: add pre-commit to test requirements (a88ea40)
    • fix: correctly render single element tuples (a8a6456)
    • fix: pass convert_sets argument to union functions (ab40cc9)
    • fix: support unions with nested unions in containers (#113) (c26e828), closes #113
    • ci: Don't cache pip to workaround pip error (c912429)
    • refactor: Remove self class from scope (da81f1f)

    This release had contibutions from 1 person: @ydylla. Thank you so much! :tada: :joy:

    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Mar 21, 2021)

    • fix: Add type annotation to serde decorators (f885a27)

    You can get the code completion from the class with serialize and deserialize decorators. I would recommend everyone to upgrade to v0.3.1.

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Mar 20, 2021)

    • feat: Support PEP585 type hint annotation (81d3f4f)
      @deserialize
      @serialize
      @dataclass
      class Foo:
          l: list[str]
          t: tuple[str, bool]
          d: dict[str, list[int]]
      
    • feat: add support for typing.Set & set (20a4cdc)
    • feat: add more types & use code generation (d352d2d)
      • IPv4Address, IPv6Address, IPv4Network, IPv6Network, IPv4Interface, IPv6Interface
      • PosixPath, WindowsPath, PurePath, PurePosixPath, PureWindowsPath
      • UUID
    • feat: add convert_sets option required for to_json & to_msgpack (f954586)
    • feat: add union support for complex types (434edf6)
      @deserialize
      @serialize
      @dataclass
      class Foo:
          v: Union[int, str]
          c: Union[Dict[str, int], List[int]]
      
    • fix: Ellipsis overwriting configured default for reuse_instances (b0366e5)
    • fix: forward reuse_instances & fix call order for optionals (c56128c)
    • fix: compatibility with python 3.6 (7ae87b4)
    • fix: this pytest option does not exist #58 (c5938da), closes #58
    • fix: scope should not be shared between classes (889ada1)
    • fix: use iter_unions to recursively collect all unions of dataclass (577aeb9)
    • build: Add PEP561 py.typed marker file (c0f46b9)
    • build: Don't install dataclasses for python>3.6 (f47caa9)
    • build: setup pre-commit as formatting tool (2876de4)
    • ci: add code style check (c52f7e9)

    This release had contibutions from 2 people: @ydylla, @alexmisk. Thank you so much! :tada: :joy:

    Source code(tar.gz)
    Source code(zip)
Ultra fast JSON decoder and encoder written in C with Python bindings

UltraJSON UltraJSON is an ultra fast JSON encoder and decoder written in pure C with bindings for Python 3.6+. Install with pip: $ python -m pip insta

3.9k Dec 31, 2022
A lightweight library for converting complex objects to and from simple Python datatypes.

marshmallow: simplified object serialization marshmallow is an ORM/ODM/framework-agnostic library for converting complex datatypes, such as objects, t

marshmallow-code 6.4k Jan 05, 2023
Yet another serialization library on top of dataclasses, inspired by serde-rs.

pyserde Yet another serialization library on top of dataclasses, inspired by serde-rs. Guide | API Docs | Examples Overview Declare a class with pyser

yukinarit 164 Jan 05, 2023
Python bindings for the simdjson project.

pysimdjson Python bindings for the simdjson project, a SIMD-accelerated JSON parser. If SIMD instructions are unavailable a fallback parser is used, m

Tyler Kennedy 562 Jan 01, 2023
Python wrapper around rapidjson

python-rapidjson Python wrapper around RapidJSON Authors: Ken Robbins [email prot

469 Jan 04, 2023