# What changed in pydantic-core

> 110 changes in pydantic-core 2 from its official release notes, upgrade guides and advisories: 72 breaking, 8 deprecations, 10 new APIs and options. Each one cited. Sources checked 2026-10-21. HTML: https://unstale.sh/pypi/pydantic-core/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## pydantic-core 2

### Breaking changes

- Fields annotated as Any no longer default to None and are required unless an explicit default is provided. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Url and Dsn types no longer inherit from str; convert them with str(url) when using APIs that expect a string. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Coercing int, float, and Decimal values to strings is optional and disabled by default. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Color Types have moved to the separately installable Pydantic Extra Types package. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- This config setting has been removed. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Vanilla dataclasses no longer inherit the parent type's config; override config with the config parameter on the @dataclass decorator. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Pydantic dataclasses no longer support extra='allow'; extra='ignore' remains supported but does not store extra fields. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Dataclasses used as fields no longer accept tuples as validation inputs; use dictionaries instead. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Decimal is represented as a string in generated JSON schema and serialization. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- This config setting has been removed. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Arbitrary keyword arguments are no longer added to JSON schema; pass extra schema data through json_schema_extra instead. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Use frozen instead. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- The const property has been removed. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Constraints are no longer automatically pushed down to generic parameters; use typing.Annotated to annotate the parameter type. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Use the typing.Final type hint instead. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Use max_length instead. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Use min_length instead. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Use pattern instead. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Introduced as the replacement for validator, with new features; annotate generic container item types to validate their contents. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Validator functions no longer receive the config argument; access configuration through info.config instead. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Validator functions no longer receive the field argument; use info.field_name to look up the field in cls.model_fields. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Returns None when no alias is set, rather than returning the field name. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- This config setting has been removed; use Annotated on fields to modify them. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Float values convert to integers only when their decimal part is zero, avoiding loss of fractional data. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Renamed from orm_mode. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Removed; generic BaseModel subclasses can now inherit from Generic directly. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Custom types should use __get_pydantic_core_schema__ in place of __get_validators__. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Custom JSON schema hooks use __get_pydantic_json_schema__ in place of __modify_schema__. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Removed because orm_mode and its implementation detail are no longer supported. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Removed along with orm_mode; it was an implementation detail of that feature. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Renamed from keep_untouched. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Validated generic collections are no longer guaranteed to preserve their input subtype; output types match the annotations, while BaseModel subclasses and dataclasses retain their types. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Iterables of pairs, including empty iterables, are no longer coerced to dictionaries during validation. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- This config setting has been removed. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- JSON serialization of non-string dictionary keys generally uses str(key), changing output for values such as None. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- This config setting has been removed. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Renamed from schema_extra; also used to pass extra JSON schema data to Field. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces construct() as the model construction method. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces copy() as the model copying method. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces dict() as the method for dumping model data. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces json() for JSON serialization; output is compacted and may not exactly match json.dumps() output. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Models are equal only to BaseModel instances with matching type, field values, extra values, and private attribute values; they are no longer equal to dictionaries containing their data. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces __fields__ as the name for model fields. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces json_schema() as the model JSON schema method. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces update_forward_refs() as the model rebuilding method. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Provides the JSON-loading behavior that previously came from parse_raw. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Generated JSON schema no longer preserves namedtuples as namedtuples. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- An Optional-annotated field without a default is required but accepts None; Optional no longer implies a default of None. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- The parse_env_var classmethod has been removed; customize settings sources to provide a parsing function. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Payment Card Numbers have moved to the separately installable Pydantic Extra Types package. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Renamed from allow_population_by_field_name. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Pydantic dataclass __post_init__ is now called after validation rather than before. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- This config setting has been removed. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Removed because it became redundant after __post_init__ moved after validation. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Pydantic dataclasses no longer expose this attribute or use an underlying BaseModel; use TypeAdapter for related functionality. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces __private_attributes__ as the name for private attributes. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces __validators__ as the model validator attribute. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Deprecated in favor of model_validator; even when retained, skip_on_failure=False is no longer supported. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces the __root__ field for defining a custom root model; RootModel types do not support arbitrary_types_allowed. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Removed; the default union_mode in Pydantic V2 is 'smart'. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Renamed from max_anystr_length. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Renamed from min_anystr_length. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Renamed from anystr_strip_whitespace. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Renamed from anystr_lower. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Renamed from anystr_upper. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Nested model serialization includes only fields defined on the annotated field type, rather than all fields from a subclass instance. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- A TypeError raised in a validator is no longer converted into a ValidationError, preventing programming errors from being reported as validation failures. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Removed because Pydantic V2 behaves as though this setting were always True. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Set union_mode='left_to_right' on Field to restore the non-short-circuiting left-to-right union behavior. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- URL validation appends a slash when a URL has no path, even if the input omitted the slash. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- The decorator formerly named @validate_arguments is now @validate_call; attributes such as raw_function and validate are not preserved. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Renamed from validate_all and can be used to validate defaults, including as an alternative to validator always=True behavior. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)

### Deprecations

- Invalid *after* model validator function signatures now emit a deprecation warning instead of raising an error. (2.12.3) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.12.3)
- The V1 pattern of defining a Config class in a BaseModel subclass is deprecated; use model_config instead. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Deprecated; model_validate can provide similar behavior when from_attributes=True is set in the model config. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Support for specifying json_encoders in model config is deprecated; serialization decorators are recommended for common custom serialization scenarios. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- The notes advise against isinstance checks against parametrized generics; subclass the parametrized generic if such checks are needed. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Deprecated; load the data and pass it to model_validate. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Deprecated; use model_validate_json for JSON input or load the data before passing it to model_validate. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Deprecated in favor of field_validator; the each_item keyword is unavailable on field_validator, and validator signatures can no longer include field or config arguments. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)

### New APIs and options

- Adds a method to convert FieldInfo to a dictionary. (2.12.3) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.12.3)
- Adds a decorator for customizing serialization. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Generic BaseModel subclasses can be declared by adding Generic as a parent class; mixing V1 and V2 models is not supported. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Choose whether generated JSON schema represents validation inputs or serialization outputs. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Specify model configuration with a class attribute dictionary; inherited configuration is merged across BaseModel parents, with later parents taking precedence for duplicate settings. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Replaces parse_obj() for validating model input and can be used in place of from_orm when from_attributes=True. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Introduced as the replacement for root_validator; under some circumstances it receives a model instance rather than a values dictionary. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- JSON schema generation methods accept schema_generator so callers can provide a custom GenerateJsonSchema subclass. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Wrap dataclasses with TypeAdapter to validate, generate JSON schema, or access functionality previously requiring __pydantic_model__. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Use typing.Annotated to add custom validation or provide custom core-schema and JSON-schema functions without modifying the type itself. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)

### Behavior and default changes

- The allow_reuse keyword argument is no longer necessary; repeated-function detection now errors only for redefinition within a single class. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Generated JSON schema now targets draft 2020-12 by default, with some OpenAPI extensions. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Constructor arguments may be copied during validation and coercion, which matters when passing mutable objects. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
- Union validation preserves the input type when it matches a choice, even when that choice is not first in the union. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)

### Fixes and other changes

- Fix missing GC traversal on some struct fields and in GeneralFieldsSerializer. (2.13.5) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.13.5)
- Validated model fields are counted once in smart unions. (2.13.5) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.13.5)
- Validators can be reused when plugins are set. (2.13.5) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.13.5)
- Preserve RootModel core metadata. (2.13.4) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.13.4)
- Handle AttributeError subclasses when from_attributes is used. (2.13.3) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.13.3)
- Fixes `ValidationInfo.field_name` being missing when using `model_validate_json()`. (2.13.2) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.13.2)
- Fixes `ValidationInfo.data` being missing when using `model_validate_json()`. (2.13.1) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.13.1)
- Fixes a pickle error when using model_construct() on a model with MISSING as a default value. (2.12.5) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.12.5)
- Reverted URL credential percent-encoding in the `build()` method of `AnyUrl` and `Dsn` types. (2.12.4) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.12.4)
- Validation no longer gets default values from `defaultdict`, fixing a regression in its validation behavior. (2.12.4) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.12.4)
- Fields with `exclude_if` are excluded from JSON Schema required fields. (2.12.4) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.12.4)
- Fixed serialization of IP address types to JSON when `serialize_as_any` is used by adding type inference. (2.12.4) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.12.4)
- Fixed forward references in parent TypedDict classes on Python 3.14 and greater. (2.12.4) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.12.4)
- Fixed field serializers on nested typed dictionaries. (2.12.4) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.12.4)
- Mutations on FieldInfo classes reused as Annotated metadata are supported again, although this remains an unsupported pattern. (2.12.3) — [release notes](https://github.com/pydantic/pydantic/releases/tag/v2.12.3)
- Generated JSON schema for Optional fields now indicates that null is allowed. (2.0.0) — [upgrade guide](https://pydantic.dev/docs/validation/2.12/get-started/migration)
