11use std:: ptr:: null_mut;
2+ use std:: sync:: Arc ;
23
34use pyo3:: exceptions:: PyTypeError ;
45use pyo3:: types:: { PyDict , PySet , PyString , PyTuple , PyType } ;
@@ -8,7 +9,7 @@ use pyo3::{intern, prelude::*};
89use super :: function:: convert_err;
910use super :: validation_state:: Exactness ;
1011use super :: {
11- build_validator, BuildValidator , CombinedValidator , DefinitionsBuilder , Extra , ValidationState , Validator ,
12+ build_validator, BuildValidator , CombinedValidator , DefinitionsBuilder , Extra , ValidationState , Validator , SchemaValidator
1213} ;
1314use crate :: build_tools:: py_schema_err;
1415use crate :: build_tools:: schema_or_config_same;
@@ -53,7 +54,7 @@ impl Revalidate {
5354#[ derive( Debug ) ]
5455pub struct ModelValidator {
5556 revalidate : Revalidate ,
56- validator : Box < CombinedValidator > ,
57+ validator : Arc < CombinedValidator > ,
5758 class : Py < PyType > ,
5859 generic_origin : Option < Py < PyType > > ,
5960 post_init : Option < Py < PyString > > ,
@@ -79,7 +80,18 @@ impl BuildValidator for ModelValidator {
7980 let class: Bound < ' _ , PyType > = schema. get_as_req ( intern ! ( py, "cls" ) ) ?;
8081 let generic_origin: Option < Bound < ' _ , PyType > > = schema. get_as ( intern ! ( py, "generic_origin" ) ) ?;
8182 let sub_schema = schema. get_as_req ( intern ! ( py, "schema" ) ) ?;
82- let validator = build_validator ( & sub_schema, config. as_ref ( ) , definitions) ?;
83+
84+ let validator = if class. getattr ( "__pydantic_complete__" ) ?. extract :: < bool > ( ) ? {
85+ if let Ok ( prebuilt_validator) = class. getattr ( "__pydantic_validator__" ) {
86+ let schema_validator: PyRef < SchemaValidator > = prebuilt_validator. extract ( ) ?;
87+ schema_validator. validator . clone ( )
88+ } else {
89+ Arc :: new ( build_validator ( & sub_schema, config. as_ref ( ) , definitions) ?)
90+ }
91+ } else {
92+ Arc :: new ( build_validator ( & sub_schema, config. as_ref ( ) , definitions) ?)
93+ } ;
94+
8395 let name = class. getattr ( intern ! ( py, "__name__" ) ) ?. extract ( ) ?;
8496
8597 Ok ( Self {
@@ -93,7 +105,7 @@ impl BuildValidator for ModelValidator {
93105 . map ( |s| s. to_str ( ) )
94106 . transpose ( ) ?,
95107 ) ?,
96- validator : Box :: new ( validator ) ,
108+ validator,
97109 class : class. into ( ) ,
98110 generic_origin : generic_origin. map ( std:: convert:: Into :: into) ,
99111 post_init : schema. get_as ( intern ! ( py, "post_init" ) ) ?,
0 commit comments