diff --git a/HISTORY.rst b/HISTORY.rst index 2b289b4..a195a23 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -10,6 +10,7 @@ v0.20.0 (unreleased) however the variadic key word argument ("``**kwargs``") **must** be called ``kwargs``, #388 by @samuelcolvin * Adds ``skip_defaults`` argument to ``BaseModel.dict()`` to allow skipping of fields that were not explicitly set, #389 by @dgasmith +* Fix ``extra`` behaviour for multiple inheritance/mix-ins, #394 by @YaraslauZhylko v0.19.0 (2019-02-04) .................... diff --git a/pydantic/main.py b/pydantic/main.py index f3a1033..f5f9e29 100644 --- a/pydantic/main.py +++ b/pydantic/main.py @@ -120,7 +120,7 @@ def set_extra(config: BaseConfig, cls_name: str) -> None: warnings.warn( f'{cls_name}: "allow_extra" is deprecated and replaced by "extra", see {EXTRA_LINK}', DeprecationWarning ) - else: + elif not isinstance(config.extra, Extra): try: config.extra = Extra(config.extra) except ValueError: diff --git a/tests/test_edge_cases.py b/tests/test_edge_cases.py index 9ef6ef8..d2fc9c5 100644 --- a/tests/test_edge_cases.py +++ b/tests/test_edge_cases.py @@ -793,3 +793,58 @@ def test_illegal_extra_value(): class Config: extra = 'foo' + + +def test_multiple_inheritance_config(): + class Parent(BaseModel): + class Config: + allow_mutation = False + extra = Extra.forbid + + class Mixin(BaseModel): + class Config: + use_enum_values = True + + class Child(Mixin, Parent): + class Config: + allow_population_by_alias = True + + assert BaseModel.__config__.allow_mutation is True + assert BaseModel.__config__.allow_population_by_alias is False + assert BaseModel.__config__.extra is Extra.ignore + assert BaseModel.__config__.use_enum_values is False + + assert Parent.__config__.allow_mutation is False + assert Parent.__config__.allow_population_by_alias is False + assert Parent.__config__.extra is Extra.forbid + assert Parent.__config__.use_enum_values is False + + assert Mixin.__config__.allow_mutation is True + assert Mixin.__config__.allow_population_by_alias is False + assert Mixin.__config__.extra is Extra.ignore + assert Mixin.__config__.use_enum_values is True + + assert Child.__config__.allow_mutation is False + assert Child.__config__.allow_population_by_alias is True + assert Child.__config__.extra is Extra.forbid + assert Child.__config__.use_enum_values is True + + +def test_multiple_inheritance_config_legacy_extra(): + with pytest.warns(DeprecationWarning, match='Parent: "ignore_extra" and "allow_extra" are deprecated and'): + + class Parent(BaseModel): + class Config: + allow_extra = False + ignore_extra = False + + class Mixin(BaseModel): + pass + + class Child(Mixin, Parent): + pass + + assert BaseModel.__config__.extra is Extra.ignore + assert Parent.__config__.extra is Extra.forbid + assert Mixin.__config__.extra is Extra.ignore + assert Child.__config__.extra is Extra.forbid