Compatibility layer for pydantic v1/v2
Project description
pydantic-compat
Motivation
Pydantic 2 was a major release that completely changed the pydantic API.
For applications, this is not a big deal, as they can pin to whatever version of pydantic they need. But for libraries that want to exist in a broader environment, pinning to a specific version of pydantic is not always an option (as it limits the ability to co-exist with other libraries).
This package provides (unofficial) compatibility mixins and function adaptors for pydantic v1-v2 cross compatibility. It allows you to use either v1 or v2 API names, regardless of the pydantic version installed. (Prefer using v2 names when possible)
The API conversion is not exhaustive, but suffices for many of the use cases I have come across. I will be using it in:
Feel free to open an issue or PR if you find it useful, but lacking features you need.
What does it do?
Not much! :joy:
Mostly serves to translate names from one API to another. While pydantic2 does offer deprecated access to the v1 API, if you explicitly wish to support pydantic1 without your users seeing deprecation warnings, then you need to do a lot of name adaptation depending on the runtime pydantic version. This package does that for you.
It does not do any significantly complex translation of API logic. For custom types, you will still likely need to add class methods to support both versions of pydantic.
It also does not prevent you from needing to know a what's changing under the hood in pydantic 2. You should be running tests on both versions of pydantic to ensure your library works as expected. This library just makes it much easier to support both versions in a single codebase without a lot of ugly conditionals and boilerplate.
Usage
from pydantic import BaseModel
from pydantic_compat import PydanticCompatMixin
from pydantic_compat import field_validator # or 'validator'
from pydantic_compat import model_validator # or 'root_validator'
class MyModel(PydanticCompatMixin, BaseModel):
x: int
y: int = 2
# prefer v2 dict, but v1 class Config is supported
model_config = {'frozen': True}
@field_validator('x', mode='after')
def _check_x(cls, v):
if v != 42:
raise ValueError("That's not the answer!")
return v
@model_validator('x', mode='after')
def _check_x(cls, v: MyModel):
# ...
return v
You can now use the following attributes and methods regardless of the pydantic version installed (without deprecation warnings):
v1 name | v2 name |
---|---|
obj.dict() |
obj.model_dump() |
obj.json() |
obj.model_dump_json() |
obj.copy() |
obj.model_copy() |
Model.construct |
Model.model_construct |
Model.schema |
Model.model_json_schema |
Model.validate |
Model.model_validate |
Model.parse_obj |
Model.model_validate |
Model.parse_raw |
Model.model_validate_json |
Model.update_forward_refs |
Model.model_rebuild |
Model.__fields__ |
Model.model_fields |
Model.__fields_set__ |
Model.model_fields_set |
API rules
- both V1 and V2 names may be used (regardless of pydantic version), but usage of V2 names are strongly recommended.
- But the API must match the pydantic version matching the name you are using.
For example, if you are using
pydantic_compat.field_validator
then the signature must match the pydantic (v2)field_validator
signature (regardless) of the pydantic version installed. Similarly, if you choose to usepydantic_compat.validator
then the signature must match the pydantic (v1)validator
signature.
Notable differences
-
BaseModel.__fields__
in v1 is a dict of{'field_name' -> ModelField}
whereas in v2BaseModel.model_fields
is a dict of{'field_name' -> FieldInfo}
.FieldInfo
is a much simpler object that ModelField, so it is difficult to directly support complicated v1 usage of__fields__
.pydantic-compat
simply provides a name addaptor that lets you access many of the attributes you may have accessed onModelField
in v1 while operating in a v2 world, butModelField
methods will not be made available. You'll need to update your usage accordingly. -
in V2,
pydantic.model_validator(..., mode='after')
passes a model instance to the validator function, whereaspydantic.v1.root_validator(..., pre=False)
passes a dict of{'field_name' -> validated_value}
to the validator function. In pydantic-compat, both decorators follow the semantics of their corresponding pydantic versions, butroot_validator
gains parameterconstruct_object: bool=False
that matches themodel_validator
behavior (only whenmode=='after'
). If you want that behavior though, prefer usingmodel_validator
directly.
TODO:
Field()
objects- Serialization decorators
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file pydantic_compat-0.0.3.tar.gz
.
File metadata
- Download URL: pydantic_compat-0.0.3.tar.gz
- Upload date:
- Size: 10.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1f709192aa384cfb88c63cb0182a1e65c9e60794f21bc923020c5bd0a9de0af7 |
|
MD5 | 3d205eea3f5e33f25793cfbc8e8a7de6 |
|
BLAKE2b-256 | 9304f8905d92cabb64328eccd7e48a60597ff40509d7941a1b11be9722373839 |
File details
Details for the file pydantic_compat-0.0.3-py3-none-any.whl
.
File metadata
- Download URL: pydantic_compat-0.0.3-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 76c8ff1a295d257f8ea3a0d987c0104884d0d4105ac098996d31424a87c3f149 |
|
MD5 | 5b76b3a581091cbbf1e82c942f0ac1c1 |
|
BLAKE2b-256 | 90ba4707e74d41ffda1e8a08f004bec223e7c2713a3355364e4c50dedc7143d8 |