dataclass support
Need to get 3.7 building on my machine first. but this was the original motivation for all the work that's gone into this lib.
I came here from the original issue on marshmallow. Can I help move this forward? I'd really like to avoid defining dataclasses and (verbose) schema classes.
Right now it'll work with dataclasses out of the box. The plan for dataclass would converting default values and factories as well as validators for those values into stuff marshmallow can use, as well as a postload that'll return instances of the class.
If you don't need those right now, this'll work for you.
I suppose validators would be nice but for the most part I can live with this. I hit one problem, though, I have an attribute which is a dictionary that gets filled post init.
import typing
from dataclasses import dataclass, field
@dataclass
class Foo:
params: typing.Dict[str, typing.Any] = field(init=False)
def __post_init__(self):
self.params = self.get_query_parameters()
At the moment, I logically get AnnotationConversionError: No field factory found for <class 'dict'> but I don't want to define a converter. Should I wrap the annotation in typing.Optional or is there a better way to ignore the field?
Edit: Just tried and using typing.Optional still requires a converter. I would simply like to ignore it completely.
I guess the things you talk about in #8 would be sweet to have and if you let me know how, I'm happy to help.
At the moment, I logically get AnnotationConversionError: No field factory found for <class 'dict'> but I don't want to define a converter. Should I wrap the annotation in typing.Optional or is there a better way to ignore the field?
Right now no default converter is registered for Dictionary[TKey, TValue] but there could be one, probably looks very similar to the default List converter. Should probably register one for Tuple[T] as well, I think this has been brought up before, but I'm ambivalent about that since tuple are meant to be heterogeneous rather than strictly an immutable List.
I guess the things you talk about in #8 would be sweet to have and if you let me know how, I'm happy to help.
For me, it's an issue of finding time to do these things. However, I'll always gladly review PRs. The PR attached to #8 is probably a good base to start with the dataclass integration if you need some inspiration.
I started messing around with this. For the most part, everything works except the InitVar type hint, which doesn't propagate subtype information. Looks like this is true of 3.7 and the 3.6 backport. Since it's a public part of the dataclass API AND folks will want to use this for load_only vars with marshmallow, I'm gonna say this is on hold until that portion can be figured out.
I don't feel like it's a bug in the dataclass implementation because it looks deliberate, but I also didn't follow the development of the dataclass module either.
Edit: I pushed up the current unfinished implementation as the branch fb/dataclass-support
It might be worth taking a look at https://github.com/lidatong/dataclasses-json , which generates marshmallow schema from dataclasses.
So @sloria, to me marshmallow-annotations and dataclasses-json look like direct competitors in terms of features they provide. Is that a wrong impression, can they supplement each other?
Hmm, taking a second look dataclasses-json it doesn't have a license yet :confused: So is it going to be open source eventually?
@justanr what's still missing from https://github.com/justanr/marshmallow-annotations/compare/fb/add-dictionary-converter in your opinion? I have some time this week to help out.
@Midnighter that's already been merged.
@sloria I'll check it out, thanks.
https://bugs.python.org/issue33569 this is the relevant BPO Issue holding this up as well as https://github.com/python/cpython/pull/8927 being the relevant PR to fix it. Sadly that means 3.6 isn't likely to receive this fix since the RC cutoff looks like 12-03 and the release is 12-16. It'd be good to see in before then but :woman_shrugging:
But short of that PR it looks retrieving typing information outta InitVar isn't possible without doing stuff like looking at the raw class code or asking the user to provide the type information twice. I'm tempted to peek into the guts of dataclasses and grift that but that seems brittle.
For those interested, I created a small library that converts dataclasses to marshmallow schemas. It's called marshmallow_dataclass (documentation), and it supports a very dry syntax:
from dataclasses import field
from marshmallow_dataclass import dataclass # Importing from marshmallow_dataclass instead of dataclasses
from typing import List
@dataclass
class Building:
names: List[str]
height: float = field(metadata=dict(
required=True,
description="Height of the building in meters",
))
Building.Schema # This is a marshmallow Schema class
Annotated type from https://github.com/python/typing/issues/600 could be of use.