-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Add back support for json_encoders
#6811
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b104956
df2a478
c469d3e
34355a4
2c900f2
a432267
917411c
8d0d38a
4e6b800
5603305
735a1dc
b0c3121
fdcd9ad
54c3f08
75b52c0
03f9fca
8b74182
efd45b5
067934d
cc1f975
2e756f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| import re | ||
| import sys | ||
| import typing | ||
| import warnings | ||
| from contextlib import contextmanager | ||
| from copy import copy | ||
| from enum import Enum | ||
|
|
@@ -24,6 +25,7 @@ | |
| Iterable, | ||
| Iterator, | ||
| Mapping, | ||
| Type, | ||
| TypeVar, | ||
| Union, | ||
| cast, | ||
|
|
@@ -34,10 +36,12 @@ | |
| from pydantic_core import CoreSchema, PydanticUndefined, core_schema | ||
| from typing_extensions import Annotated, Final, Literal, TypeAliasType, TypedDict, get_args, get_origin, is_typeddict | ||
|
|
||
| from ..config import ConfigDict | ||
| from ..config import ConfigDict, JsonEncoder | ||
| from ..errors import PydanticSchemaGenerationError, PydanticUndefinedAnnotation, PydanticUserError | ||
| from ..fields import AliasChoices, AliasPath, FieldInfo | ||
| from ..json_schema import JsonSchemaValue | ||
| from ..version import VERSION | ||
| from ..warnings import PydanticDeprecatedSince20 | ||
| from . import _decorators, _discriminated_union, _known_annotated_metadata, _typing_extra | ||
| from ._annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler | ||
| from ._config import ConfigWrapper | ||
|
|
@@ -210,6 +214,42 @@ def modify_model_json_schema( | |
| return json_schema | ||
|
|
||
|
|
||
| JsonEncoders = Dict[Type[Any], JsonEncoder] | ||
|
|
||
|
|
||
| def _add_custom_serialization_from_json_encoders( | ||
| json_encoders: JsonEncoders | None, tp: Any, schema: CoreSchema | ||
| ) -> CoreSchema: | ||
| """Iterate over the json_encoders and add the first matching encoder to the schema. | ||
|
|
||
| Args: | ||
| json_encoders: A dictionary of types and their encoder functions. | ||
| tp: The type to check for a matching encoder. | ||
| schema: The schema to add the encoder to. | ||
| """ | ||
| if not json_encoders: | ||
| return schema | ||
| if 'serialization' in schema: | ||
| return schema | ||
| # Check the class type and its superclasses for a matching encoder | ||
| # Decimal.__class__.__mro__ (and probably other cases) doesn't include Decimal itself | ||
| for base in (tp, *tp.__class__.__mro__[:-1]): | ||
| encoder = json_encoders.get(base) | ||
| if encoder is None: | ||
| continue | ||
|
|
||
| warnings.warn( | ||
| f'`json_encoders` is deprecated. See https://docs.pydantic.dev/{VERSION}/usage/serialization/#custom-serializers for alternatives', | ||
| PydanticDeprecatedSince20, | ||
|
Comment on lines
+242
to
+243
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is incorrect, it should only be the major and minor versions. Maybe the solution is to have a proper warnings page like we have for user and validation errors. I can work on this today. Fixing this should not block release. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It actually redirects, e.g. https://docs.pydantic.dev/2.0.2/usage/serialization/#custom-serializers works There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only for specific versions see #6527. I'll provide a general fix. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I see. Okay then we can just strip the patch version. |
||
| ) | ||
|
|
||
| # TODO: in theory we should check that the schema accepts a serialization key | ||
| schema['serialization'] = core_schema.plain_serializer_function_ser_schema(encoder, when_used='json') # type: ignore | ||
| return schema | ||
|
|
||
| return schema | ||
|
|
||
|
|
||
| class GenerateSchema: | ||
| """Generate core schema for a Pydantic model, dataclass and types like `str`, `datatime`, ... .""" | ||
|
|
||
|
|
@@ -317,6 +357,8 @@ def _generate_schema_for_type( | |
| if metadata_schema: | ||
| self._add_js_function(metadata_schema, metadata_js_function) | ||
|
|
||
| schema = _add_custom_serialization_from_json_encoders(self.config_wrapper.json_encoders, obj, schema) | ||
|
|
||
| return schema | ||
|
|
||
| def _model_schema(self, cls: type[BaseModel]) -> core_schema.CoreSchema: | ||
|
|
@@ -1413,7 +1455,7 @@ def inner_handler(obj: Any) -> CoreSchema: | |
| if pydantic_js_annotation_functions: | ||
| metadata = CoreMetadataHandler(schema).metadata | ||
| metadata.setdefault('pydantic_js_annotation_functions', []).extend(pydantic_js_annotation_functions) | ||
| return schema | ||
| return _add_custom_serialization_from_json_encoders(self.config_wrapper.json_encoders, source_type, schema) | ||
|
|
||
| def apply_single_annotation( # noqa: C901 | ||
| self, schema: core_schema.CoreSchema, metadata: Any | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.