Skip to content

Conversation

davidhewitt
Copy link
Contributor

Change Summary

Adds more testing and fixes to two bugs with RootModel:

  • field_serializer not respected with serialize_as_any in 2.12
  • RootModel no longer serializes incompatible types with a "root" field, e.g. Path

Related issue number

Xref pydantic/pydantic#12379
Fixes pydantic/pydantic#8963

Checklist

  • Unit tests for the changes exist
  • Documentation reflects the changes where applicable
  • Pydantic tests pass with this pydantic-core (except for expected changes)
  • My PR is ready to review, please add a comment including the phrase "please review" to assign reviewers

@davidhewitt davidhewitt requested a review from Viicos October 13, 2025 12:47
let inner_value = self.get_inner_value(value, &model_extra)?;
do_serialize(Some((&self.serializer, &inner_value)), &model_extra)
}
_ => do_serialize(None, &model_extra),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it's a bug that the fallback uses the model_extra? (This preserved existing behaviour.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a MRE that hits this code path? I'm having trouble understanding what is this logic for here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like only field serializers care about the extra.model, I'm going to tidy up and not worry.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this would be a case that warns about expecting a model and not getting it, and then somehow falling to type inference which calls a field serializer. I'm pretty sure that's impossible.)

Comment on lines +164 to +165
/// apply any type inference. (`Model` serialization is strongly coupled with its child
/// serializer, and in the few cases where `serialize_as_any` applies, it is handled here.)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// apply any type inference. (`Model` serialization is strongly coupled with its child
/// serializer, and in the few cases where `serialize_as_any` applies, it is handled here.)
/// apply any type inference. (`Model` serialization is strongly coupled with its child
/// serializer, and in the few cases where `serialize_as_any` applies, it is handled here.)

I wondered if it actually made sense to have the 'model' core schema having an inner 'schema' item, that should be of type 'model-fields' although it is typed as any CoreSchema in the TypedDict definitions 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It exists for "wrap" model serializers (and maybe "before"), in both of those cases the inference should not be used there either.

If I was improving this (maybe another day):

  • I would make root model schema completely separate, it works so differently.
  • model schema would directly take the fields, no model_fields schema
  • model schema would contain any model validators / serializers as special keys in the schema

This would also be much better for performance, the critical model pathways could then just produce the model values without having to go through CombinedValidator / CombinedSerializer abstractions

Copy link

codspeed-hq bot commented Oct 13, 2025

CodSpeed Performance Report

Merging #1836 will not alter performance

Comparing dh/root-model-fixes (309f09a) with main (d90a93b)

Summary

✅ 163 untouched

davidhewitt and others added 2 commits October 13, 2025 14:05
Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com>
@davidhewitt
Copy link
Contributor Author

The failing integration test is not a concern IMO, the case currently raises an AttributeError and the new logic here has downgraded that to a warning and inference fallback, which is more consistent with how serialization works everywhere else.

@davidhewitt davidhewitt enabled auto-merge (squash) October 13, 2025 14:01
@davidhewitt davidhewitt merged commit 0344763 into main Oct 13, 2025
30 of 31 checks passed
@davidhewitt davidhewitt deleted the dh/root-model-fixes branch October 13, 2025 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Serializing Union field that includes a RootModel fails (dumping returns root of path object)

2 participants