Skip to content

Commit

Permalink
Improve documentation for config (#6847)
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin committed Jul 25, 2023
1 parent 2db6248 commit 0921bb3
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 127 deletions.
4 changes: 4 additions & 0 deletions docs/api/config.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
::: pydantic.config
options:
group_by_category: false
members:
- ConfigDict
- ExtraValues
- BaseConfig

::: pydantic.alias_generators
options:
show_root_heading: true
13 changes: 6 additions & 7 deletions docs/usage/validators.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@

## Annotated Validators

??? api "API Documentation"
[`pydantic.functional_validators.WrapValidator`][pydantic.functional_validators.WrapValidator]<br>
[`pydantic.functional_validators.PlainValidator`][pydantic.functional_validators.PlainValidator]<br>
[`pydantic.functional_validators.BeforeValidator`][pydantic.functional_validators.BeforeValidator]<br>
[`pydantic.functional_validators.AfterValidator`][pydantic.functional_validators.AfterValidator]<br>

Pydantic provides a way to apply validators via use of `Annotated`.
You should use this whenever you want to bind validation to a type instead of model or field.

Expand Down Expand Up @@ -60,12 +65,6 @@ Pydantic provides multiple types of validator functions.
* `Plain` validators are like a `mode='before'` validator but they terminate validation immediately, no further validators are called and Pydantic does not do any of it's internal validation.
* `Wrap` validators are the most flexible of all. You can run code before or after Pydantic and other validators do their thing or you can terminate validation immediately, both with a successful value or an error.

??? api "API Documentation"
[`pydantic.functional_validators.WrapValidator`][pydantic.functional_validators.WrapValidator]<br>
[`pydantic.functional_validators.PlainValidator`][pydantic.functional_validators.PlainValidator]<br>
[`pydantic.functional_validators.BeforeValidator`][pydantic.functional_validators.BeforeValidator]<br>
[`pydantic.functional_validators.AfterValidator`][pydantic.functional_validators.AfterValidator]<br>

You can use multiple before, after, or `mode='wrap'` validators, but only one `PlainValidator` since a plain validator
will not call any inner validators.

Expand Down
248 changes: 131 additions & 117 deletions pydantic/config.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
"""Configuration for Pydantic models."""
from __future__ import annotations as _annotations

from typing import TYPE_CHECKING, Any, Callable, Dict, Type, Union
from warnings import warn
from typing import Any, Callable, Dict, Type, Union

from typing_extensions import Literal, TypeAlias, TypedDict

from ._migration import getattr_migration
from .deprecated.config import BaseConfig
from .warnings import PydanticDeprecatedSince20

if not TYPE_CHECKING:
# See PyCharm issues https://youtrack.jetbrains.com/issue/PY-21915
# and https://youtrack.jetbrains.com/issue/PY-51428
DeprecationWarning = PydanticDeprecatedSince20
from .deprecated.config import Extra as _Extra

__all__ = 'BaseConfig', 'ConfigDict', 'Extra'

Expand All @@ -25,21 +19,6 @@
Callable[[Dict[str, Any], Type[Any]], None],
]


class _Extra:
allow: Literal['allow'] = 'allow'
ignore: Literal['ignore'] = 'ignore'
forbid: Literal['forbid'] = 'forbid'

def __getattribute__(self, __name: str) -> Any:
warn(
'`pydantic.config.Extra` is deprecated, use literal values instead' " (e.g. `extra='allow'`)",
DeprecationWarning,
stacklevel=2,
)
return super().__getattribute__(__name)


Extra = _Extra()

ExtraValues = Literal['allow', 'ignore', 'forbid']
Expand All @@ -48,134 +27,169 @@ def __getattribute__(self, __name: str) -> Any:
class ConfigDict(TypedDict, total=False):
"""Usage docs: https://docs.pydantic.dev/2.0/usage/model_config/
A dictionary-like class for configuring Pydantic models.
Attributes:
title: The title for the generated JSON schema. Defaults to `None`.
str_to_lower: Whether to convert all characters to lowercase for str & bytes types. Defaults to `False`.
str_to_upper: Whether to convert all characters to uppercase for str & bytes types. Defaults to `False`.
str_strip_whitespace: Whether to strip leading and trailing whitespace for str & bytes types.
Defaults to `False`.
str_min_length: The minimum length for str & bytes types. Defaults to `None`.
str_max_length: The maximum length for str & bytes types. Defaults to `None`.
extra: Whether to ignore, allow, or forbid extra attributes during model initialization.
Accepts the string values of `'ignore'`, `'allow'`, or `'forbid'`. Defaults to `'ignore'`.
- `'forbid'` will cause validation to fail if extra attributes are included.
- `'ignore'` will silently ignore any extra attributes.
- `'allow'` will assign the attributes to the model.
See [Extra Attributes](../usage/model_config.md#extra-attributes) for details.
frozen: Whether or not models are faux-immutable, i.e. whether `__setattr__` is allowed, and also generates
a `__hash__()` method for the model. This makes instances of the model potentially hashable if all the
attributes are hashable. Defaults to `False`.
!!! note
On V1, this setting was called `allow_mutation`, and was `True` by default.
populate_by_name: Whether an aliased field may be populated by its name as given by the model
attribute, as well as the alias. Defaults to `False`.
!!! note
The name of this configuration setting was changed in **v2.0** from
`allow_population_by_alias` to `populate_by_name`.
use_enum_values: Whether to populate models with the `value` property of enums, rather than the raw enum.
This may be useful if you want to serialize `model.model_dump()` later. Defaults to `False`.
validate_assignment: Whether to perform validation on *assignment* to attributes. Defaults to `False`.
arbitrary_types_allowed: Whether to allow arbitrary user types for fields (they are validated simply by
checking if the value is an instance of the type). If `False`, `RuntimeError` will be raised on model
declaration. Defaults to `False`.
See [Arbitrary Types Allowed](../usage/model_config.md#arbitrary-types-allowed) for details.
from_attributes: Whether to allow model creation from object attributes. Defaults to `False`.
!!! note
The name of this configuration setting was changed in **v2.0** from `orm_mode` to `from_attributes`.
loc_by_alias: Whether to use the alias for error `loc`s. Defaults to `True`.
alias_generator: a callable that takes a field name and returns an alias for it.
See [Alias Generator](../usage/model_config.md#alias-generator) for details.
ignored_types: A tuple of types that may occur as values of class attributes without annotations. This is
typically used for custom descriptors (classes that behave like `property`). If an attribute is set on a
class without an annotation and has a type that is not in this tuple (or otherwise recognized by
_pydantic_), an error will be raised. Defaults to `()`.
allow_inf_nan: Whether to allow infinity (`+inf` an `-inf`) and NaN values to float fields. Defaults to `True`.
json_schema_extra: A dict or callable to provide extra JSON schema properties. Defaults to `None`.
json_encoders: A `dict` of custom JSON encoders for specific types. Defaults to `None`.
!!! note
This config option is a carryover from v1.
We originally planned to remove it in v2 but didn't have a 1:1 replacement so we are keeping it for now.
It is still deprecated and will likely be removed in the future.
strict: If `True`, strict validation is applied to all fields on the model.
See [Strict Mode](../usage/strict_mode.md) for details.
revalidate_instances: When and how to revalidate models and dataclasses during validation. Accepts the string
values of `'never'`, `'always'` and `'subclass-instances'`. Defaults to `'never'`.
- `'never'` will not revalidate models and dataclasses during validation
- `'always'` will revalidate models and dataclasses during validation
- `'subclass-instances'` will revalidate models and dataclasses during validation if the instance is a
subclass of the model or dataclass
See [Revalidate Instances](../usage/model_config.md#revalidate-instances) for details.
ser_json_timedelta: The format of JSON serialized timedeltas. Accepts the string values of `'iso8601'` and
`'float'`. Defaults to `'iso8601'`.
- `'iso8601'` will serialize timedeltas to ISO 8601 durations.
- `'float'` will serialize timedeltas to the total number of seconds.
ser_json_bytes: The encoding of JSON serialized bytes. Accepts the string values of `'utf8'` and `'base64'`.
Defaults to `'utf8'`.
- `'utf8'` will serialize bytes to UTF-8 strings.
- `'base64'` will serialize bytes to base64 strings.
validate_default: Whether to validate default values during validation. Defaults to `False`.
protected_namespaces: A `tuple` of strings that prevent model to have field which conflict with them.
Defaults to `('model_', )`).
See [Protected Namespaces](../usage/model_config.md#protected-namespaces) for details.
hide_input_in_errors: Whether to hide inputs when printing errors. Defaults to `False`.
See [Hide Input in Errors](../usage/model_config.md#hide-input-in-errors).
defer_build: Whether to defer model validator and serializer construction until the
first model validation. This can be useful to avoid the overhead of building models which are only
used nested within other models, or when you want to manually define type namespace via
[`Model.model_rebuild(_types_namespace=...)`][pydantic.BaseModel.model_rebuild]. Defaults to False.
A TypedDict for configuring Pydantic behaviour.
"""

title: str | None
"""The title for the generated JSON schema, defaults to the model's name"""

str_to_lower: bool
"""Whether to convert all characters to lowercase for str types. Defaults to `False`."""

str_to_upper: bool
"""Whether to convert all characters to uppercase for str types. Defaults to `False`."""
str_strip_whitespace: bool
"""Whether to strip leading and trailing whitespace for str types."""

str_min_length: int
"""The minimum length for str types. Defaults to `None`."""

str_max_length: int | None
"""The maximum length for str types. Defaults to `None`."""

extra: ExtraValues | None
"""
Whether to ignore, allow, or forbid extra attributes during model initialization.
The value must be a [`ExtraValues`][pydantic.config.ExtraValues] string. Defaults to `'ignore'`.
See [Extra Attributes](../usage/model_config.md#extra-attributes) for details.
"""

frozen: bool
"""
Whether or not models are faux-immutable, i.e. whether `__setattr__` is allowed, and also generates
a `__hash__()` method for the model. This makes instances of the model potentially hashable if all the
attributes are hashable. Defaults to `False`.
!!! note
On V1, this setting was called `allow_mutation`, and was `True` by default.
"""

populate_by_name: bool
"""
Whether an aliased field may be populated by its name as given by the model
attribute, as well as the alias. Defaults to `False`.
!!! note
The name of this configuration setting was changed in **v2.0** from
`allow_population_by_alias` to `populate_by_name`.
"""

use_enum_values: bool
"""
Whether to populate models with the `value` property of enums, rather than the raw enum.
This may be useful if you want to serialize `model.model_dump()` later. Defaults to `False`.
"""

validate_assignment: bool
arbitrary_types_allowed: bool
from_attributes: bool
# whether to use the used alias (or first alias for "field required" errors) instead of field_names
# to construct error `loc`s, default True
"""
Whether to build models and look up discriminators of tagged unions using python object attributes.
"""

loc_by_alias: bool
"""Whether to use the alias for error `loc`s rather than the field's name. Defaults to `True`."""

alias_generator: Callable[[str], str] | None
"""
A callable that takes a field name and returns an alias for it.
See [Alias Generator](../usage/model_config.md#alias-generator) for details.
"""

ignored_types: tuple[type, ...]
"""A tuple of types that may occur as values of class attributes without annotations. This is
typically used for custom descriptors (classes that behave like `property`). If an attribute is set on a
class without an annotation and has a type that is not in this tuple (or otherwise recognized by
_pydantic_), an error will be raised. Defaults to `()`.
"""

allow_inf_nan: bool
"""Whether to allow infinity (`+inf` an `-inf`) and NaN values to float fields. Defaults to `True`."""

json_schema_extra: dict[str, object] | JsonSchemaExtraCallable | None
"""A dict or callable to provide extra JSON schema properties. Defaults to `None`."""

json_encoders: dict[type[object], JsonEncoder] | None
"""
A `dict` of custom JSON encoders for specific types. Defaults to `None`.
!!! warning "Deprecated"
This config option is a carryover from v1.
We originally planned to remove it in v2 but didn't have a 1:1 replacement so we are keeping it for now.
It is still deprecated and will likely be removed in the future.
"""

# new in V2
strict: bool
"""
_(new in V2)_ If `True`, strict validation is applied to all fields on the model.
See [Strict Mode](../usage/strict_mode.md) for details.
"""
# whether instances of models and dataclasses (including subclass instances) should re-validate, default 'never'
revalidate_instances: Literal['always', 'never', 'subclass-instances']
"""
When and how to revalidate models and dataclasses during validation. Accepts the string
values of `'never'`, `'always'` and `'subclass-instances'`. Defaults to `'never'`.
- `'never'` will not revalidate models and dataclasses during validation
- `'always'` will revalidate models and dataclasses during validation
- `'subclass-instances'` will revalidate models and dataclasses during validation if the instance is a
subclass of the model or dataclass
See [Revalidate Instances](../usage/model_config.md#revalidate-instances) for details.
"""

ser_json_timedelta: Literal['iso8601', 'float']
"""
The format of JSON serialized timedeltas. Accepts the string values of `'iso8601'` and
`'float'`. Defaults to `'iso8601'`.
- `'iso8601'` will serialize timedeltas to ISO 8601 durations.
- `'float'` will serialize timedeltas to the total number of seconds.
"""

ser_json_bytes: Literal['utf8', 'base64']
"""
The encoding of JSON serialized bytes. Accepts the string values of `'utf8'` and `'base64'`.
Defaults to `'utf8'`.
- `'utf8'` will serialize bytes to UTF-8 strings.
- `'base64'` will serialize bytes to base64 strings.
"""

# whether to validate default values during validation, default False
validate_default: bool
# whether to validate the return value from call validator
"""Whether to validate default values during validation. Defaults to `False`."""

validate_return: bool
"""whether to validate the return value from call validators."""

protected_namespaces: tuple[str, ...]
"""
A `tuple` of strings that prevent model to have field which conflict with them.
Defaults to `('model_', )`).
See [Protected Namespaces](../usage/model_config.md#protected-namespaces) for details.
"""

hide_input_in_errors: bool
"""
Whether to hide inputs when printing errors. Defaults to `False`.
See [Hide Input in Errors](../usage/model_config.md#hide-input-in-errors).
"""
defer_build: bool
"""
Whether to defer model validator and serializer construction until the first model validation.
This can be useful to avoid the overhead of building models which are only
used nested within other models, or when you want to manually define type namespace via
[`Model.model_rebuild(_types_namespace=...)`][pydantic.BaseModel.model_rebuild]. Defaults to False.
"""


__getattr__ = getattr_migration(__name__)
20 changes: 17 additions & 3 deletions pydantic/deprecated/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import warnings
from typing import TYPE_CHECKING, Any

from typing_extensions import deprecated
from typing_extensions import Literal, deprecated

from .._internal import _config
from ..warnings import PydanticDeprecatedSince20
Expand All @@ -13,7 +13,7 @@
# and https://youtrack.jetbrains.com/issue/PY-51428
DeprecationWarning = PydanticDeprecatedSince20

__all__ = ('BaseConfig',)
__all__ = 'BaseConfig', 'Extra'


class _ConfigMetaclass(type):
Expand All @@ -31,7 +31,7 @@ class BaseConfig(metaclass=_ConfigMetaclass):
"""This class is only retained for backwards compatibility.
!!! Warning "Deprecated"
BaseConfig is deprecated. Use the `pydantic.ConfigDict` instead.
BaseConfig is deprecated. Use the [`pydantic.ConfigDict`][pydantic.ConfigDict] instead.
"""

def __getattr__(self, item: str) -> Any:
Expand All @@ -48,3 +48,17 @@ def __getattr__(self, item: str) -> Any:
def __init_subclass__(cls, **kwargs: Any) -> None:
warnings.warn(_config.DEPRECATION_MESSAGE, DeprecationWarning)
return super().__init_subclass__(**kwargs)


class Extra:
allow: Literal['allow'] = 'allow'
ignore: Literal['ignore'] = 'ignore'
forbid: Literal['forbid'] = 'forbid'

def __getattribute__(self, __name: str) -> Any:
warnings.warn(
"`pydantic.config.Extra` is deprecated, use literal values instead (e.g. `extra='allow'`)",
DeprecationWarning,
stacklevel=2,
)
return super().__getattribute__(__name)

0 comments on commit 0921bb3

Please sign in to comment.