antonagestam / phantom-types

Phantom types for Python.
https://pypi.org/project/phantom-types/
BSD 3-Clause "New" or "Revised" License
204 stars 9 forks source link

Support Pydantic V2 #286

Open antonagestam opened 1 year ago

antonagestam commented 1 year ago

Pydantic V2 is highly incompatible with V1, and will likely require a complete rewrite of the integration. #285 pins Pydantic to <2 for now. Support for V2 will likely be released in a future major version of phantom-types, that won't support V1.

flaeppe commented 7 months ago

FWIW below is a port of the TZAware type I did, that worked with Pydantic v2 (2.7.0)

from typing import Any

from phantom.datetime import TZAware as PhantomTZAware
from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler
from pydantic.json_schema import JsonSchemaValue
from pydantic_core import PydanticCustomError, core_schema

class TZAware(PhantomTZAware):
    @classmethod
    def __get_pydantic_core_schema__(
        cls, source: type[Any], handler: GetCoreSchemaHandler
    ) -> core_schema.CoreSchema:
        return core_schema.no_info_wrap_validator_function(
            cls._validate, core_schema.datetime_schema()
        )

    @classmethod
    def _validate(
        cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler
    ) -> Any:
        try:
            return handler(cls.parse(value))
        except Exception as exc:
            raise PydanticCustomError(
                "value_error", "value is not a valid, timezone aware, timestamp"
            ) from exc

    @classmethod
    def __get_pydantic_json_schema__(
        cls, core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler
    ) -> JsonSchemaValue:
        json_schema = handler(core_schema)
        json_schema = handler.resolve_ref_schema(json_schema)
        json_schema.update(cls.__schema__())
        return json_schema