diff --git a/pydantic/utils.py b/pydantic/utils.py index cf29cc81fe1..2c0f468e63e 100644 --- a/pydantic/utils.py +++ b/pydantic/utils.py @@ -228,20 +228,24 @@ def update_normalized_all( if not item: return all_items if isinstance(item, dict) and isinstance(all_items, dict): + item = dict(item) item.update({k: update_normalized_all(item[k], v) for k, v in all_items.items() if k in item}) item.update({k: v for k, v in all_items.items() if k not in item}) return item if isinstance(item, set) and isinstance(all_items, set): + item = set(item) item.update(all_items) return item if isinstance(item, dict) and isinstance(all_items, set): + item = dict(item) item.update({k: ... for k in all_items if k not in item}) return item if isinstance(item, set) and isinstance(all_items, dict): - new_item = {k: ... for k in item} - new_item.update({k: v for k, v in all_items.items() if k not in item}) - return new_item - return all_items # pragma: no cover + item = {k: ... for k in item} + item.update({k: v for k, v in all_items.items() if k not in item}) + return item + # Case when item or all_items is ... (in recursive calls). + return item class PyObjectStr(str): diff --git a/tests/test_edge_cases.py b/tests/test_edge_cases.py index f1ab5516d7c..4d72c28841e 100644 --- a/tests/test_edge_cases.py +++ b/tests/test_edge_cases.py @@ -536,6 +536,12 @@ class Model(BaseModel): assert m.dict( exclude={'subs': {'__all__': {'subsubs': {'__all__': {'i'}}}, 0: {'subsubs': {'__all__': {'j'}}}}} ) == {'subs': [{'k': 1, 'subsubs': [{}, {}]}, {'k': 2, 'subsubs': [{'j': 3}]}]} + assert m.dict(exclude={'subs': {'__all__': {'subsubs': ...}, 0: {'subsubs': {'__all__': {'j'}}}}}) == { + 'subs': [{'k': 1, 'subsubs': [{'i': 1}, {'i': 2}]}, {'k': 2}] + } + assert m.dict(exclude={'subs': {'__all__': {'subsubs': {'__all__': {'j'}}}, 0: {'subsubs': ...}}}) == { + 'subs': [{'k': 1}, {'k': 2, 'subsubs': [{'i': 3}]}] + } # Merge sub sets assert m.dict(exclude={'subs': {'__all__': {'subsubs': {0}}, 0: {'subsubs': {1}}}}) == { 'subs': [{'k': 1, 'subsubs': []}, {'k': 2, 'subsubs': []}] @@ -595,6 +601,12 @@ class Model(BaseModel): assert m.dict( include={'subs': {'__all__': {'subsubs': {'__all__': {'i'}}}, 0: {'subsubs': {'__all__': {'j'}}}}} ) == {'subs': [{'subsubs': [{'i': 1, 'j': 1}, {'i': 2, 'j': 2}]}, {'subsubs': [{'i': 3}]}]} + assert m.dict(include={'subs': {'__all__': {'subsubs': ...}, 0: {'subsubs': {'__all__': {'j'}}}}}) == { + 'subs': [{'subsubs': [{'j': 1}, {'j': 2}]}, {'subsubs': [{'i': 3, 'j': 3}]}] + } + assert m.dict(include={'subs': {'__all__': {'subsubs': {'__all__': {'j'}}}, 0: {'subsubs': ...}}}) == { + 'subs': [{'subsubs': [{'i': 1, 'j': 1}, {'i': 2, 'j': 2}]}, {'subsubs': [{'j': 3}]}] + } # Merge sub sets assert m.dict(include={'subs': {'__all__': {'subsubs': {0}}, 0: {'subsubs': {1}}}}) == { 'subs': [{'subsubs': [{'i': 1, 'j': 1}, {'i': 2, 'j': 2}]}, {'subsubs': [{'i': 3, 'j': 3}]}]