Pydantic validates the object it produces
Pydantic starts with an ordinary Python class that inherits from BaseModel. Type annotations become runtime parsing and validation rules, then the same model can return a dictionary, emit JSON, or generate JSON Schema. That makes it useful at the edge of an application, where request bodies, settings, database records, or imported files have to become values the rest of the program can trust.
The word validation needs care here. Pydantic promises that the resulting model matches its declared types, not that the input arrived in those types. Its own example turns the string '123' into the integer 123. That behavior is deliberate and often handy for HTTP parameters or environment variables. It matters more than the 11.4 MB size of the source checkout because it can change what your application accepts.
Default models coerce values and ignore extra keys
Lax conversion is the default. Strict mode can be enabled for one call, one field, or an entire model configuration. Even strict mode has differences between Python and JSON input for some types, so boundary tests should use the same input path as production. Unknown fields present another policy choice: by default, a model ignores them instead of returning an error. Set extra='forbid' when an unexpected key must fail.
A shared base model is the sensible place to make those choices consistent across a service. Without one, two endpoints can interpret the same payload differently because one model is strict and another is not. The installed environment in our sandbox was only 37 MB, but the adoption work is mainly semantic: test coercion, rejected values, aliases, unknown fields, and serialized output before replacing hand-written checks.
What happened when we ran it
Our sandbox installed 39 packages in 89 seconds, occupying 37 MB. The build command failed with exit code 1 after 2 seconds. The test command then failed with exit code 4 after 2 seconds, before pytest collected a test. Pip-audit reported 0 known vulnerabilities in the installed packages. Those results come from commit 7b15a78 in an unprivileged container with 3 CPUs and 8 GB of RAM.
The test log is specific about the immediate stop. Pytest did not recognize --benchmark-columns, --benchmark-group-by, --benchmark-warmup, or --benchmark-disable, all supplied by the repository configuration. The log does not say why those options were unavailable, so we cannot turn it into a claim about a missing package or broken test. No Pydantic assertion ran, and there is no pass or fail count to report.
The failed test command never reached Pydantic code
The pyproject file lists pytest-benchmark in the development dependency group and places the same four benchmark options in pytest's default arguments. That makes the mismatch reproducible enough to investigate, but the supplied tail stops at argument parsing. The separate build step also failed in 2 seconds, and the measurement block does not contain its error tail. Calling either failure a compiler bug would go beyond the evidence.
The checkout contained 839 files, about 213,650 source lines, and a real tests directory. It also had 10 CI workflow files and no Dockerfile. This is a mature library repository rather than a containerized service, so contributors should follow its documented environment setup and confirm the full suite locally. Our 39-package install was successful, yet it was not sufficient for the configured test command we ran.
V2 migration changes behavior as well as names
Pydantic V2 is a rewrite with breaking changes. The migration guide maps familiar methods such as dict(), json(), and parse_obj() to the newer model_dump(), model_dump_json(), and model_validate(). Equality rules changed, from_orm was deprecated, and nested subclass serialization now limits output to fields declared on the annotated type. A mechanical rename does not cover all of that.
The project offers two bridges. Pydantic V2 includes the V1 API under pydantic.v1, and bump-pydantic can transform source code, though the guide still calls that tool beta. The current package requires Python 3.10 or newer and pins pydantic-core 2.49.0. For a large V1 application, use the compatibility namespace first, then migrate behavior with tests instead of changing every import in one release.
Version 2.13.5 is active despite a large issue queue
Release 2.13.5 arrived on August 28, 2026 with fixes for validator reuse, garbage-collector traversal in pydantic-core, and smart-union field counting. GitHub recorded a push on September 16. We counted 541 open issues and 38 open pull requests, which explains the repository's combined count of 579 without pretending all 579 are defects. Issue discussions were also updated on September 16.
One open report, issue 8699, describes a V2.6 case where trying an iterator against the first branch of a union consumes values before the next branch runs. It was updated on September 16, but the report does not demonstrate the behavior on V2.13.5. Treat it as a reason to test one-shot iterators, not proof that every current union loses data. Our audit's 0 known vulnerabilities does not answer that correctness question.
Pydantic remains an easy library to justify for typed Python boundaries, provided your team chooses its input policy instead of inheriting the defaults by accident. The 89-second install was uneventful. The 2-second build and test failures were not. Application users can evaluate models now, while contributors should reproduce a passing development setup before relying on this checkout.

