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
fix: Allow inheriting dataclasses with defaults #7184
Conversation
please review |
Looks like #7193 addressed the immediate issue. I am however keen on letting the test and extra logic be reviewed and if ok to merge to avoid the warning and ensure compat. |
def test_can_inherit_stdlib_dataclasses_with_dataclass_fields(): | ||
@dataclasses.dataclass | ||
class Base: | ||
a: int = dataclasses.field(default=5) | ||
|
||
class Model(BaseModel, Base): | ||
pass | ||
|
||
assert Model().a == 5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also add a test for default_factory
? I'm assuming it doesn't work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adriangb I added a test that xfails. The internals of stdlib dataclasses does not assign default factory attributes to the class instance (meaning the warning isnt triggered in this case). It also means that you are right, the default factory is not propagated to the resulting FieldInfo
instance (because the dataclass.Field
isnt assigned to Base
but rather Base.__dataclass_fields__
.
@dataclasses.dataclass
class Base:
a: int = dataclasses.field(default_factory=lambda: 5)
assert hasattr(Base, 'a') # this fails
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inheritance works fine if you provide a value, so for my usecase this isn't an important feature to support. I added a test for what we need to work, though.
5135319
to
8056cc6
Compare
tests/test_dataclasses.py
Outdated
@pytest.mark.xfail(raises=ValidationError, require=True) | ||
def test_can_inherit_stdlib_dataclasses_default_factories_and_use_them(): | ||
"""This test documents that default factories are not supported""" | ||
|
||
@dataclasses.dataclass | ||
class Base: | ||
a: str = dataclasses.field(default_factory=lambda: 'TEST') | ||
|
||
class Model(BaseModel, Base): | ||
pass | ||
|
||
assert Model().a == 'TEST' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather see with pytest.raises(...)
since that's what we use elsewhere
@adriangb Done! |
please review |
Change Summary
This patch allows for a
pydantic.Basemodel
class to inherit a "pure" stdlib dataclass, even when the attribute name is set on the class instance, as is the case withdataclasses.field
and default assignments.Related issue number
fix #6984
Checklist
Selected Reviewer: @hramezani