question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Dataclasses do not implement __iter__, causing webargs.use_kwargs to fail

See original GitHub issue

webargs will attempt to combine the results of schema.load into the resulting kwargs to be passed into a function, as seen here:

https://github.com/marshmallow-code/webargs/blob/5.5.1/src/webargs/core.py#L446-L448

In order to repair this assumption, while still using dataclasses, I had to implement a mixin for my dataclasses to allow them to appear as iterables for the purposes of kwargs.update(dataclass)

class Iterable:
    def __iter__(self):
        """When extending a dataclass, yields all key value pairs as if it were a dictionary"""
        for attr, value in self.__dict__.items():
            if value is not None:
                yield attr, value

@dataclass
class Building(Iterable):
    # field metadata is used to instantiate the marshmallow field
    height: float = field(metadata={"validate": marshmallow.validate.Range(min=0)})
    name: str = field(default="anonymous")

Should I go make noise over in webargs saying they should accept dataclasses? or is this something that we can safely hack in here, as we’re are actively transforming the resulting dictionary INTO a dataclass.

Another acceptable solution would be to add a meta argument to allow a developer to skip the post_load step, and allow load to return a dictionary and NOT a dataclass, which is honestly more optimal IMO.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
CptSpaceToastercommented, Oct 7, 2019

It looks fine for now!

from flask import Flask
from marshmallow_dataclass import dataclass
from webargs.flaskparser import use_args
from typing import Optional

app = Flask(__name__)

@dataclass
class Person:
  name: str
  greeting: Optional[str] = "Hello"

@app.route("/", methods=['POST'])
@use_args(Person.Schema)
def index(person: Person):
    return f"{person.greeting} {person.name}"

It definitely wasn’t on my radar to move away from use_kwargs but I can’t come up with anything that would be break this yet. I guess you’ll hear from me if there’s an issue.

2reactions
sloriacommented, Oct 7, 2019

That should already work. @CptSpaceToaster can you try that out?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Make Python dataclass iterable? - Stack Overflow
The OP asked "I have a dataclass and I want to iterate over in in a loop to spit out each of the...
Read more >
Possibility to make dataclasses iterable or indexable · Issue #21
Imagine users who are currently using named tuples or dictionaries as ... I am not sure, but I think both flags should be...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found