Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

why is type checking not supported for marshmallow_dataclass in PyCharm? #178

Open
sarimmehdi opened this issue Mar 10, 2022 · 5 comments
Open

Comments

@sarimmehdi
Copy link

I was using the normal dataclass before and type checking worked fine inside PyCharm for that but that doesn't seem to be the case when I use the @marshmallow_dataclass.dataclass annotation over my class instead of the usual @dataclasses.dataclass one. Is there a special reason for it being this way? Seeing my dataclass declaration become entirely yellow in PyCharm (an incorrect warning) is very annoying

@sarimmehdi
Copy link
Author

So, as a workaround, I found this. It is one extra annotation that gets rid of the annoying incorrect warnings but if someone here can explain to me why just using the @marshmallow_dataclass.dataclass doesn't give the same behavior, then that'd be great. Thanks!

@sarimmehdi
Copy link
Author

sarimmehdi commented Mar 10, 2022

It seems the @add_schema annotation gets rid of all types of PyCharm warnings entirely. If anyone has a workaround to this issue then that'd be great.

@mdesjardins
Copy link

FYI - it's not just a PyCharm thing. My code is currently not passing mypy at all.

Here's a super basic example that hopefully (it's a scaled down version of production code) reproduces it:

class BaseSchema(Schema):
    """All schema derive from this to automatically handle camelcasing fields and other goodies."""
    def on_bind_field(self, field_name: str, field_obj: Any) -> None:
        field_obj.data_key = camelcase(field_obj.data_key or field_name)

@dataclass(base_schema=BaseSchema)
class RecipientForm:
    label: str
    money_type: MoneyType = field(metadata=dict(by_value=True))
    payout_method: PayoutMethod = field(metadata=dict(by_value=True))
    enabled: bool = True

DEFAULT_MOBILE_RECIPIENT_FORM = RecipientForm(
    label="default-new-mobile-recipient",
    money_type=MoneyType.MOBILE,
    payout_method=PayoutMethod.MOBILE,
)

the above code is currently giving me a mypy error I decorate RecipientForm with @marshmallow_dataclass.dataclass:

/Users/mdesjardins/_work/recipient_forms.py:97: error: Unexpected keyword argument "label" for "RecipientForm"
/Users/mdesjardins/_work/recipient_forms.py:97: error: Unexpected keyword argument "money_type" for "RecipientForm"
/Users/mdesjardins/_work/recipient_forms.py:97: error: Unexpected keyword argument "payout_method" for "RecipientForm"

I don't get this mypy error when I decorate with @dataclasses.dataclass, but then I run into problems because my classes no longer use BaseSchema as their parent schema.

Aside: My real-world scenario is a bit gnarlier than the contrived example above - i.e., I realize that for this example, I could just create my Schema class with

RecipientFormResponseSchema = marshmallow_dataclass.class_schema(RecipientForm, BaseSchema)

and forgo the mashmallow_dataclass version of the dataclass decorator and be fine. The problem that I'm actually having is that, for my real world code, my outer RecipientForm dataclass has an inner list of FormField objects that are also dataclasses that I'm serializing... once I get into dataclasses containing lists of dataclasses, the alternative above doesn't really work, because those inner dataclasses also need to use BaseSchema as their base.

@mdesjardins
Copy link

Here's a better example showing the problem: https://gist.github.com/mdesjardins/2d2eb37bad865b8037800d0bbb07a18a

@lucatpa
Copy link

lucatpa commented Mar 30, 2022

Related to this, if you try to construct a class with a marshmallow.dataclass decorator instead of dataclasses.dataclass, the type checking for the constructor's arguments fail saying the constructor doesn't take any arguments, but using the constructor as if it were a normal dataclass works perfectly, so the type hinting is failing. Should I create a separate issue for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants