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

Improvements to unify the functionality from decorator & Dataclass in a single class #2764

Merged
merged 4 commits into from
Dec 5, 2024

Conversation

eos87
Copy link

@eos87 eos87 commented Dec 2, 2024

Purpose

The intention to avoid needing to have both a Dataclass and a @dataclass decorator

What has changed

  • Introduced DataclassBase for reusable utility methods (to_dict, from_dict, ser_model).
  • Added DataclassMeta to handle automatic Pydantic dataclass wrapping and custom Config merging.
  • Enabled per-class custom configuration via a Config dictionary in child classes.

Example usage

class RingBearer(Dataclass):
    name: str
    race: str

    # custom configuration that will merge/override default one
    Config = {
        "extra": "allow",
    }

frodo = RingBearer(name="Frodo Baggins", race="Hobbit")

# unexpected fields are allowed due to 'extra': 'allow' (allowed by default, this is just for tests)
frodo.unknown_item = "Mithril Coat" 
frodo.secret_mission = "Destroy the One Ring"

@MarkLark86 following up on our conversation here what do you think? If you think it looks good I'd merge it and replace the usages of the decorator. Also extend the documentation a little bit to make it clear what is the intention.

Thanks for checking!

@eos87 eos87 requested a review from MarkLark86 December 2, 2024 13:56
The intention is to avoid having both the `dataclass` decorator and the `Dataclass` which feels a bit redundant.
@eos87 eos87 force-pushed the hg/dataclass-enhancements branch from e125189 to c1b7e9d Compare December 2, 2024 13:58
@BrianMwangi21
Copy link

LGTM!

@MarkLark86
Copy link
Contributor

@eos87 How does this work with the IDE predictions/suggestions when typing field names?

@eos87
Copy link
Author

eos87 commented Dec 3, 2024

@eos87 How does this work with the IDE predictions/suggestions when typing field names?

It does. This is vscode below. I would assume it would also work on PyCharm and others.
image

@MarkLark86
Copy link
Contributor

Testing this locally, and I found 2 things (1 of those is probably an issue with my original code).

  • from_dict and from_json return an instance of dict and not an instance of the class
  • mypy fails to recognise arguments to __init__.
from superdesk.core.resources import Dataclass

class Person(Dataclass):
    name: str

assert type(Person(name="Monkeys")) == Person  # True
assert type(Person.from_dict(dict(name="Monkeys"))) == Person  # False
assert type(Person.from_dict(dict(name="Monkeys"))) == dict  # True
assert type(Person.from_json('{"name": "Monkeys"}')) == Person  # False
assert type(Person.from_json('{"name": "Monkeys"}')) == dict  # False

Person(name="Monkeys")  # mypy error: Unexpected keyword argument "name" for "Person"  [call-arg]

Might be good to add some tests with using this new datatype of ours

@eos87
Copy link
Author

eos87 commented Dec 4, 2024

from_dict and from_json return an instance of dict and not an instance of the class

yeah, it was already a dict indeed. I'll take a look to return the proper model instance.

Person(name="Monkeys") # mypy error: Unexpected keyword argument "name" for "Person" [call-arg]

interesting, I've just tried this locally and it worked for me. Maybe we have a different version of mypy?

@eos87
Copy link
Author

eos87 commented Dec 4, 2024

Improvements added so editor will autocomplete the attributes inline when creating an instance of a class. Also added some tests to double check the functionality of the utility methods from_dict, from_json, to_dict and to_json.

Copy link
Contributor

@MarkLark86 MarkLark86 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good improvement, thanks mate

@eos87 eos87 merged commit 8eb7185 into async Dec 5, 2024
21 of 33 checks passed
@eos87 eos87 deleted the hg/dataclass-enhancements branch December 5, 2024 09:02
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

Successfully merging this pull request may close these issues.

3 participants