diff --git a/pydantic/dataclasses.py b/pydantic/dataclasses.py index 1a9008cc6ce..36529a88fa9 100644 --- a/pydantic/dataclasses.py +++ b/pydantic/dataclasses.py @@ -385,6 +385,10 @@ def create_pydantic_model_from_dataclass( def _dataclass_validate_values(self: 'Dataclass') -> None: + # validation errors can occur if this function is called twice on an already initialised dataclass. + # for example if Extra.forbid is enabled, it would consider __pydantic_initialised__ an invalid extra property + if getattr(self, '__pydantic_initialised__'): + return if getattr(self, '__pydantic_has_field_info_default__', False): # We need to remove `FieldInfo` values since they are not valid as input # It's ok to do that because they are obviously the default values! diff --git a/tests/test_dataclasses.py b/tests/test_dataclasses.py index f74b0874854..53bde45cba9 100644 --- a/tests/test_dataclasses.py +++ b/tests/test_dataclasses.py @@ -1360,3 +1360,27 @@ class A: A(1, '') assert A(b='hi').b == 'hi' + + +def test_extra_forbid_list_no_error(): + @pydantic.dataclasses.dataclass(config=dict(extra=Extra.forbid)) + class Bar: + ... + + @pydantic.dataclasses.dataclass + class Foo: + a: list[Bar] + + assert isinstance(Foo(a=[Bar()]).a[0], Bar) + + +def test_extra_forbid_list_error(): + @pydantic.dataclasses.dataclass(config=dict(extra=Extra.forbid)) + class Bar: + ... + + with pytest.raises(TypeError, match="__init__() got an unexpected keyword argument 'a'"): + + @pydantic.dataclasses.dataclass + class Foo: + a: list[Bar(a=1)]