Repository navigation
fix(pydantic): avoid returning stale cached models on custom config, validators, or module - #2325
Conversation
…dators, or module (tortoise#2310)
Merging this PR will not alter performance1 warning
Comparing |
|
@Fire162 Looks OK. Cloud you update the changelog? BTW: Currently, the Pydantic creator does not yet support mypy checking well: from tortoise.contrib.pydantic.creator import PydanticMeta
if TYPE_CHECKING:
class Event_Pydantic(Event, PydanticMeta): ...
else:
Event_Pydantic = pydantic_model_creator(Event)Is there any way to make |
…ydantic-creator-cache-args
…ydantic-creator-cache-args
|
Thanks for working on this — the We've decided to go with the approach in #2312, and I want to explain why so it doesn't look like the work here is being dismissed. The core difference is how
Bypassing the cache for validators trades a small perf win for a hard guarantee that a model never reuses another caller's validators. Validators are usually passed once at definition time, not in a hot loop, so the rebuild cost is rarely visible. So we'll go with #2312 for the cache strategy. Thanks again for the analysis here — the |
|
Separate note on the tests — I've carried them over to #2312 with one adjustment, and also bumped the pydantic dependency while I was there.
With validators bypassing the cache, two calls with the same validators return different model objects, so the assertion is now I also upgraded the pinned pydantic version as part of this — the new tests exercise Thanks again for the tests — they cover behavior neither PR's original suite locked in, and the credit for that coverage belongs here. |
- Add more regression tests covering model_config, validators, and module combinations. - Switch read-only cases in tests/contrib/test_pydantic.py from db to db_simple — they don't need the transaction/rollback behavior. - Bump pydantic (2.13.5 on Python 3.10, 2.14.1 on 3.11+).
Description
pydantic_model_creatorcaches generated pydantic models so repeat calls for the same Tortoise model reuse the created class.However,
_is_defaultonly checked parameters likeexclude,include,computed,allow_cycles,meta_override, andexclude_readonly. Whenmodel_config,validators, or custommodulewere supplied without overriding other arguments,_is_defaultevaluated toTrueand returned the default model fromcls._pydantic_model. Furthermore, the non-default hash calculation did not incorporatemodel_config,validators, ormodule, so differing configurations with the same subset of fields produced identical cache keys.This patch:
_is_defaultto ensuremodel_config is None,validators is None, andmodule == __name__.model_config,validators, and non-defaultmoduleto the hash calculation so distinct models are keyed independently while preserving legacy hash stability for default models.tests/contrib/test_pydantic.pycovering custom configs, custom validators, and custom modules.Motivation and Context
Fixes #2310
How Has This Been Tested?
Ran the test suite locally with
pytest tests/contrib/test_pydantic.py(50 tests passing) and checked formatting withruff checkandruff format --check.Checklist: