__init__.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. """Usage docs: https://docs.pydantic.dev/2.10/concepts/plugins#build-a-plugin
  2. Plugin interface for Pydantic plugins, and related types.
  3. """
  4. from __future__ import annotations
  5. from typing import Any, Callable, NamedTuple
  6. from pydantic_core import CoreConfig, CoreSchema, ValidationError
  7. from typing_extensions import Literal, Protocol, TypeAlias
  8. __all__ = (
  9. 'PydanticPluginProtocol',
  10. 'BaseValidateHandlerProtocol',
  11. 'ValidatePythonHandlerProtocol',
  12. 'ValidateJsonHandlerProtocol',
  13. 'ValidateStringsHandlerProtocol',
  14. 'NewSchemaReturns',
  15. 'SchemaTypePath',
  16. 'SchemaKind',
  17. )
  18. NewSchemaReturns: TypeAlias = 'tuple[ValidatePythonHandlerProtocol | None, ValidateJsonHandlerProtocol | None, ValidateStringsHandlerProtocol | None]'
  19. class SchemaTypePath(NamedTuple):
  20. """Path defining where `schema_type` was defined, or where `TypeAdapter` was called."""
  21. module: str
  22. name: str
  23. SchemaKind: TypeAlias = Literal['BaseModel', 'TypeAdapter', 'dataclass', 'create_model', 'validate_call']
  24. class PydanticPluginProtocol(Protocol):
  25. """Protocol defining the interface for Pydantic plugins."""
  26. def new_schema_validator(
  27. self,
  28. schema: CoreSchema,
  29. schema_type: Any,
  30. schema_type_path: SchemaTypePath,
  31. schema_kind: SchemaKind,
  32. config: CoreConfig | None,
  33. plugin_settings: dict[str, object],
  34. ) -> tuple[
  35. ValidatePythonHandlerProtocol | None, ValidateJsonHandlerProtocol | None, ValidateStringsHandlerProtocol | None
  36. ]:
  37. """This method is called for each plugin every time a new [`SchemaValidator`][pydantic_core.SchemaValidator]
  38. is created.
  39. It should return an event handler for each of the three validation methods, or `None` if the plugin does not
  40. implement that method.
  41. Args:
  42. schema: The schema to validate against.
  43. schema_type: The original type which the schema was created from, e.g. the model class.
  44. schema_type_path: Path defining where `schema_type` was defined, or where `TypeAdapter` was called.
  45. schema_kind: The kind of schema to validate against.
  46. config: The config to use for validation.
  47. plugin_settings: Any plugin settings.
  48. Returns:
  49. A tuple of optional event handlers for each of the three validation methods -
  50. `validate_python`, `validate_json`, `validate_strings`.
  51. """
  52. raise NotImplementedError('Pydantic plugins should implement `new_schema_validator`.')
  53. class BaseValidateHandlerProtocol(Protocol):
  54. """Base class for plugin callbacks protocols.
  55. You shouldn't implement this protocol directly, instead use one of the subclasses with adds the correctly
  56. typed `on_error` method.
  57. """
  58. on_enter: Callable[..., None]
  59. """`on_enter` is changed to be more specific on all subclasses"""
  60. def on_success(self, result: Any) -> None:
  61. """Callback to be notified of successful validation.
  62. Args:
  63. result: The result of the validation.
  64. """
  65. return
  66. def on_error(self, error: ValidationError) -> None:
  67. """Callback to be notified of validation errors.
  68. Args:
  69. error: The validation error.
  70. """
  71. return
  72. def on_exception(self, exception: Exception) -> None:
  73. """Callback to be notified of validation exceptions.
  74. Args:
  75. exception: The exception raised during validation.
  76. """
  77. return
  78. class ValidatePythonHandlerProtocol(BaseValidateHandlerProtocol, Protocol):
  79. """Event handler for `SchemaValidator.validate_python`."""
  80. def on_enter(
  81. self,
  82. input: Any,
  83. *,
  84. strict: bool | None = None,
  85. from_attributes: bool | None = None,
  86. context: dict[str, Any] | None = None,
  87. self_instance: Any | None = None,
  88. ) -> None:
  89. """Callback to be notified of validation start, and create an instance of the event handler.
  90. Args:
  91. input: The input to be validated.
  92. strict: Whether to validate the object in strict mode.
  93. from_attributes: Whether to validate objects as inputs by extracting attributes.
  94. context: The context to use for validation, this is passed to functional validators.
  95. self_instance: An instance of a model to set attributes on from validation, this is used when running
  96. validation from the `__init__` method of a model.
  97. """
  98. pass
  99. class ValidateJsonHandlerProtocol(BaseValidateHandlerProtocol, Protocol):
  100. """Event handler for `SchemaValidator.validate_json`."""
  101. def on_enter(
  102. self,
  103. input: str | bytes | bytearray,
  104. *,
  105. strict: bool | None = None,
  106. context: dict[str, Any] | None = None,
  107. self_instance: Any | None = None,
  108. ) -> None:
  109. """Callback to be notified of validation start, and create an instance of the event handler.
  110. Args:
  111. input: The JSON data to be validated.
  112. strict: Whether to validate the object in strict mode.
  113. context: The context to use for validation, this is passed to functional validators.
  114. self_instance: An instance of a model to set attributes on from validation, this is used when running
  115. validation from the `__init__` method of a model.
  116. """
  117. pass
  118. StringInput: TypeAlias = 'dict[str, StringInput]'
  119. class ValidateStringsHandlerProtocol(BaseValidateHandlerProtocol, Protocol):
  120. """Event handler for `SchemaValidator.validate_strings`."""
  121. def on_enter(
  122. self, input: StringInput, *, strict: bool | None = None, context: dict[str, Any] | None = None
  123. ) -> None:
  124. """Callback to be notified of validation start, and create an instance of the event handler.
  125. Args:
  126. input: The string data to be validated.
  127. strict: Whether to validate the object in strict mode.
  128. context: The context to use for validation, this is passed to functional validators.
  129. """
  130. pass