@@ -654,3 +654,153 @@ def _validator(cls, v, info):
654654 gc .collect ()
655655
656656 assert ref () is None
657+
658+
659+ validate_default_raises_examples = [
660+ (
661+ {},
662+ [
663+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
664+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
665+ {'type' : 'missing' , 'loc' : ('z' ,), 'msg' : 'Field required' , 'input' : {}},
666+ ],
667+ ),
668+ (
669+ {'z' : 'some str' },
670+ [
671+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
672+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
673+ ],
674+ ),
675+ (
676+ {'x' : None },
677+ [
678+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
679+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
680+ {'type' : 'missing' , 'loc' : ('z' ,), 'msg' : 'Field required' , 'input' : {'x' : None }},
681+ ],
682+ ),
683+ (
684+ {'x' : None , 'z' : 'some str' },
685+ [
686+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
687+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
688+ ],
689+ ),
690+ (
691+ {'y' : None },
692+ [
693+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
694+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
695+ {'type' : 'missing' , 'loc' : ('z' ,), 'msg' : 'Field required' , 'input' : {'y' : None }},
696+ ],
697+ ),
698+ (
699+ {'y' : None , 'z' : 'some str' },
700+ [
701+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
702+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
703+ ],
704+ ),
705+ (
706+ {'x' : None , 'y' : None },
707+ [
708+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
709+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
710+ {'type' : 'missing' , 'loc' : ('z' ,), 'msg' : 'Field required' , 'input' : {'x' : None , 'y' : None }},
711+ ],
712+ ),
713+ (
714+ {'x' : None , 'y' : None , 'z' : 'some str' },
715+ [
716+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
717+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
718+ ],
719+ ),
720+ (
721+ {'x' : 1 , 'y' : None , 'z' : 'some str' },
722+ [
723+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : 1 },
724+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
725+ ],
726+ ),
727+ (
728+ {'x' : None , 'y' : 1 , 'z' : 'some str' },
729+ [
730+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : None },
731+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : 1 },
732+ ],
733+ ),
734+ (
735+ {'x' : 1 , 'y' : 1 , 'z' : 'some str' },
736+ [
737+ {'type' : 'assertion_error' , 'loc' : ('x' ,), 'msg' : 'Assertion failed, ' , 'input' : 1 },
738+ {'type' : 'assertion_error' , 'loc' : ('y' ,), 'msg' : 'Assertion failed, ' , 'input' : 1 },
739+ ],
740+ ),
741+ ]
742+
743+
744+ @pytest .mark .parametrize (
745+ 'core_schema_constructor,field_constructor' ,
746+ [
747+ (core_schema .model_fields_schema , core_schema .model_field ),
748+ (core_schema .typed_dict_schema , core_schema .typed_dict_field ),
749+ ],
750+ )
751+ @pytest .mark .parametrize ('input_value,expected' , validate_default_raises_examples )
752+ def test_validate_default_raises (
753+ core_schema_constructor : Union [core_schema .ModelFieldsSchema , core_schema .TypedDictSchema ],
754+ field_constructor : Union [core_schema .model_field , core_schema .typed_dict_field ],
755+ input_value : dict ,
756+ expected : Any ,
757+ ) -> None :
758+ def _raise (ex : Exception ) -> None :
759+ raise ex ()
760+
761+ inner_schema = core_schema .no_info_after_validator_function (
762+ lambda x : _raise (AssertionError ), core_schema .nullable_schema (core_schema .int_schema ())
763+ )
764+
765+ v = SchemaValidator (
766+ core_schema_constructor (
767+ {
768+ 'x' : field_constructor (
769+ core_schema .with_default_schema (inner_schema , default = None , validate_default = True )
770+ ),
771+ 'y' : field_constructor (
772+ core_schema .with_default_schema (inner_schema , default = None , validate_default = True )
773+ ),
774+ 'z' : field_constructor (core_schema .str_schema ()),
775+ }
776+ )
777+ )
778+
779+ with pytest .raises (ValidationError ) as exc_info :
780+ v .validate_python (input_value )
781+ assert exc_info .value .errors (include_url = False , include_context = False ) == expected
782+
783+
784+ @pytest .mark .parametrize ('input_value,expected' , validate_default_raises_examples )
785+ def test_validate_default_raises_dataclass (input_value : dict , expected : Any ) -> None :
786+ def _raise (ex : Exception ) -> None :
787+ raise ex ()
788+
789+ inner_schema = core_schema .no_info_after_validator_function (
790+ lambda x : _raise (AssertionError ), core_schema .nullable_schema (core_schema .int_schema ())
791+ )
792+
793+ x = core_schema .dataclass_field (
794+ name = 'x' , schema = core_schema .with_default_schema (inner_schema , default = None , validate_default = True )
795+ )
796+ y = core_schema .dataclass_field (
797+ name = 'y' , schema = core_schema .with_default_schema (inner_schema , default = None , validate_default = True )
798+ )
799+ z = core_schema .dataclass_field (name = 'z' , schema = core_schema .str_schema ())
800+
801+ v = SchemaValidator (core_schema .dataclass_args_schema ('XYZ' , [x , y , z ]))
802+
803+ with pytest .raises (ValidationError ) as exc_info :
804+ v .validate_python (input_value )
805+
806+ assert exc_info .value .errors (include_url = False , include_context = False ) == expected
0 commit comments