Skip to content

Commit

Permalink
Ensure original exclude value is not modified
Browse files Browse the repository at this point in the history
This commit also fixes some weird cases in the recursive
`update_normalized_all` call and Ellipsis values.
  • Loading branch information
xspirus committed Jun 2, 2020
1 parent 7ee0a64 commit cce334a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
12 changes: 8 additions & 4 deletions pydantic/utils.py
Expand Up @@ -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 __all__ is ... (in recursive calls).
return item


class PyObjectStr(str):
Expand Down
12 changes: 12 additions & 0 deletions tests/test_edge_cases.py
Expand Up @@ -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': []}]
Expand Down Expand Up @@ -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}]}]
Expand Down

0 comments on commit cce334a

Please sign in to comment.