You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/migration.md
+63Lines changed: 63 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -180,6 +180,69 @@ Model(x=1)
180
180
To work around this, use an `IsInstance` validator (more details to come).
181
181
* Subclasses of built-ins won't validate into their subclass types; you'll need to use an `IsInstance` validator to validate these types.
182
182
183
+
### Input types are not preserved
184
+
185
+
In Pydantic V1 we made great efforts to preserve the types of all field inputs for generic collections when they were proper subtypes of the field annotations.
186
+
For example, given the annotation `Mapping[str, int]` if you passed in a `collection.Counter()` you'd get a `collection.Counter()` as the value.
187
+
188
+
Supporting this behavior in V2 would have negative performance implications for the general case (we'd have to check types every time) and would add a lot of complexity to validation. Further, even in V1 this behavior was inconsistent and partially broken: it did not work for most types (`str`, `UUID`, etc.) and even for generic collections it's impossible to re-build the original input correctly without a lot of special casing (consider `ChainMap`; rebuilding the input is necessary because we need to replace values after validation, e.g. if coercing strings to ints).
189
+
190
+
In Pydantic V2 we no longer attempt to preserve the input type.
191
+
Instead, we only promise that the output type will match the type annotations.
192
+
Going back to the `Mapping` example, we promise the output will be a valid `Mapping`, in practice it will be a plain `dict`.
193
+
194
+
```python
195
+
from typing import Mapping
196
+
197
+
from pydantic import TypeAdapter
198
+
199
+
200
+
classMyDict(dict):
201
+
pass
202
+
203
+
204
+
ta = TypeAdapter(Mapping[str, int])
205
+
v = ta.validate_python(MyDict())
206
+
print(type(v))
207
+
#> <class 'dict'>
208
+
```
209
+
210
+
If you want the output type to be a specific type, consider annotating it as such or implementing a custom validator:
0 commit comments