Skip to main content

Pydantic++ | Utilities to improve on the core Pydantic library

Project description

Pydantic++

CI Release PyPI version

Pydantic++ is a suite of utilities to improve upon the core Pydantic library. We stand on the shoulders of giants here. Huge kudos to the Pydantic team for all their hard work building an amazing product.

Utilities

  • Partial Models — type-safe "partial" Pydantic models where some or all fields are optional
  • Model Updater — type-safe immutable builder for updating model instances
  • Model Registry — discover all BaseModel subclasses in a module tree
  • Dummy Models — generate dummy model instances with random data for testing
  • Mypy Plugin — full mypy integration for partial models and model updates

Installation

pip install pydantic-plus-plus

Requires Python 3.10+ and Pydantic 2.0+.

If you use mypy for type checking, please also add our plugin to your mypy configuration.

[tool.mypy]
plugins = ["pydantic.mypy", "pydantic_plus_plus.mypy"]

Partial Models

partial creates a PartialBaseModel, a variant of the given Pydantic BaseModel where every field is Optional with a default of None. This is the type-safe way to represent partial updates (PATCH payloads, upsert data, sparse sync records) without manually duplicating each model with every field made optional.

Model Updater

update provides a type-safe, immutable builder for updating Pydantic model instances. Pydantic's built-in model_copy(update={"field": value}) takes a dict[str, Any] — you lose all type safety, typos are invisible, and nested updates are painful. update fixes all of this.

Model Registry

ModelRegistry scans one or more Python modules (and all submodules) and collects every BaseModel subclass it finds. This is useful when you have a base class — say BasePrompt, AgentConfig, or BaseEvent — and you need to discover all concrete implementations at runtime for dispatching, serialization, CLI tooling, or documentation generation.

Dummy Models

dummy generates an instance of any Pydantic BaseModel populated with random data. This is useful for testing — round-trip serialization, factory fixtures, property-based tests — anywhere you need a valid model instance without hand-writing every field.

Mypy Plugin

Pydantic++ ships a mypy plugin that gives partial models and model updates full type safety. Without it, mypy sees partial(User) as returning a generic type and can't validate field access or constructor arguments. Similarly, ModelUpdater methods like .set() and .append() would accept any keyword argument without type checking.

With the plugin enabled:

  • Partial models get field-level type checking, constructor validation, and IDE autocompletion.
  • ModelUpdater methods get typed keyword arguments — mypy validates field names, value types, and restricts operations to applicable fields (e.g., .append() only accepts sequence fields).

Comparable Packages

Why Pydantic++ over pydantic-partial?

Pydantic++ offers a similar feature set, but takes a different philosophical approach than pydantic-partial that is more aligned with SOLID Object Oriented design principles.

Here's how the two differ:

Pydantic++ pydantic-partial
Partial models All fields optional All fields optional
Selective fields Yes Yes
Dot-notation nesting Yes Yes
Wildcard nesting Yes Yes
Field metadata preservation Yes Yes
Caching Yes Yes
Recursive by default Yes No (opt-in)
Mypy plugin Yes No
.apply() deep merge Yes No
Standalone partial classes Yes — partials don't subclass the original No — partials subclass the original

Philosophical Differences

pydantic-partial's partials subclass the original model, so isinstance(patch, User) is True. This violates the Liskov Substitution Principle — a partial User weakens the preconditions of the original (required fields become optional), meaning code that expects a complete User can silently receive one with None fields. In addition to breaking LSP, this also causes problems for type checkers because the subclass relationship tells type checkers the partial is a User.

Pydantic++ takes a different philosophical approach, where partials are standalone classes. This preserves LSP. Additionally, because isinstance(patch, User) is False, the type checker can enforce the boundary between partial and complete data. Users must go through .apply() to produce a real User, making the conversion explicit and safe.

Mypy plugin

This is a well known limitation of pydantic-partial. Pydantic++ ships a mypy plugin that synthesizes full TypeInfo objects, giving users field-level type checking and constructor validation with zero # type: ignore comments.

.apply() deep merge

pydantic-partial creates partial models but has no built-in way to merge a partial back into an existing instance. Pydantic++ provides .apply() which recursively merges only explicitly-set fields, preserving untouched nested data.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydantic_plus_plus-0.5.0.tar.gz (121.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pydantic_plus_plus-0.5.0-py3-none-any.whl (37.7 kB view details)

Uploaded Python 3

File details

Details for the file pydantic_plus_plus-0.5.0.tar.gz.

File metadata

  • Download URL: pydantic_plus_plus-0.5.0.tar.gz
  • Upload date:
  • Size: 121.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pydantic_plus_plus-0.5.0.tar.gz
Algorithm Hash digest
SHA256 a105c517814bbefa22e17fb72d1e9ac3a889c68aa4110359b50b661848e78e64
MD5 1cd47841003eee93529c528b1f272b6c
BLAKE2b-256 4b23d48445abd57935c2c1438ba7aa6c5755eed95818a523615e5a73ec9bd78b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydantic_plus_plus-0.5.0.tar.gz:

Publisher: release.yml on andonimichael/pydantic-plus-plus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydantic_plus_plus-0.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pydantic_plus_plus-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e3a28860230796fc1f344b2f58921cd215d12d96552bb8d2abfa1e8c3701e8b9
MD5 907ab8db6d06f897a4df820c08ee2f94
BLAKE2b-256 83cff042282c49ac2733e1e58c01664928914c2679af68a38a4c0ea9b32ae0cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydantic_plus_plus-0.5.0-py3-none-any.whl:

Publisher: release.yml on andonimichael/pydantic-plus-plus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page