Skip to content

Improve performance of GenerateSchema.generate_schema() dispatching - #13614

Merged
Viicos merged 1 commit into
mainfrom
vp/generate-schema-perf
Aug 18, 2026
Merged

Viicos merged 1 commit into
mainfrom
vp/generate-schema-perf

Conversation

@Viicos

@Viicos Viicos commented Aug 9, 2026

Copy link
Copy Markdown
Member

Further improvements by doing a single get_origin() call early, and deciding whether to find a __get_pydantic_core_schema__() method based on the presence/absence of the origin.

Misc improvements around this logic included too.

Change Summary

Related issue number

Checklist

  • The pull request title is a good summary of the changes - it will be used in the changelog
  • Unit tests for the changes exist
  • Tests pass on CI
  • Documentation reflects the changes where applicable
  • My PR is ready to review, please add a comment including the phrase "please review" to assign reviewers

Further improvements by doing a single `get_origin()` call early, and
deciding whether to find a `__get_pydantic_core_schema__()` method based
on the presence/absence of the origin.

Misc improvements around this logic included too.
@Viicos Viicos added the relnotes-performance Used for performance improvements. label Aug 9, 2026
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying pydantic-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 029c106
Status: ✅  Deploy successful!
Preview URL: https://25f693db.pydantic-docs.pages.dev
Branch Preview URL: https://vp-generate-schema-perf.pydantic-docs.pages.dev

View logs

@codspeed

codspeed Bot commented Aug 9, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 8.11%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 12 improved benchmarks
✅ 204 untouched benchmarks
⏩ 163 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
⚡ test_simple_model_schema_lots_of_fields_generation 14.6 ms 12.7 ms +15.33%
⚡ test_complex_model_schema_generation 1.1 ms 1 ms +13.36%
⚡ test_interconnected_models 5.6 ms 5.1 ms +9.31%
⚡ test_lots_of_models_with_lots_of_fields 1.8 s 1.7 s +8.37%
⚡ test_tagged_union_with_callable_discriminator_schema_generation 1,044.8 µs 964.7 µs +8.31%
⚡ test_fastapi_startup_perf 85.7 ms 79.8 ms +7.38%
⚡ test_recursive_model_schema_generation 728.8 µs 685.4 µs +6.34%
⚡ test_schema_build 2.4 ms 2.3 ms +6.2%
⚡ test_nested_recursive_model_schema_generation 1.3 ms 1.2 ms +6.15%
⚡ test_nested_recursive_generic_model_schema_generation 1.2 ms 1.1 ms +5.82%
⚡ test_model_subclass 2.9 ms 2.7 ms +5.66%
⚡ test_recursive_discriminated_union_with_base_model 1.3 ms 1.2 ms +5.57%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing vp/generate-schema-perf (029c106) with main (796b6d8)

Open in CodSpeed

Footnotes

  1. 163 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@Viicos
Viicos requested a review from davidhewitt August 9, 2026 19:57
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  pydantic/_internal
  _generate_schema.py 1073
Project Total  

This report was generated by python-coverage-comment-action

@Viicos
Viicos merged commit 2151025 into main Aug 18, 2026
90 checks passed
@Viicos
Viicos deleted the vp/generate-schema-perf branch August 18, 2026 19:23
jimmyjbling pushed a commit to jimmyjbling/pydantic that referenced this pull request Oct 23, 2026
Since pydantic#13614, `generate_schema()` and `_apply_annotations.inner_handler()`
compute `origin = get_origin(obj)` once and pass it to
`_generate_schema_inner()`. When `obj` is `Self`, the substitution with the
type on `model_type_stack` happens inside `_generate_schema_inner()`, so the
pre-computed origin (`None`) is stale. For a parametrized generic dataclass
such as `Node[int]`, `match_type()` then takes the plain-type branch, where
`dataclasses.is_dataclass()` is false for the generic alias, and raises
`PydanticSchemaGenerationError`.

Recompute the origin after substituting `Self`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

relnotes-performance Used for performance improvements.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant