@@ -449,7 +449,7 @@ def test_all_optional_fields_with_required_fields():
449
449
450
450
def test_field_required_and_default ():
451
451
"""A field cannot be required and have a default value"""
452
- with pytest .raises (SchemaError , match = ' Field "x" : a required field cannot have a default value' ):
452
+ with pytest .raises (SchemaError , match = " Field 'x' : a required field cannot have a default value" ):
453
453
SchemaValidator (
454
454
{'type' : 'typed-dict' , 'fields' : {'x' : {'schema' : {'type' : 'str' }, 'required' : True , 'default' : 'pika' }}}
455
455
)
@@ -1077,7 +1077,7 @@ def test_default_and_default_factory():
1077
1077
1078
1078
def test_field_required_and_default_factory ():
1079
1079
"""A field cannot be required and have a default factory"""
1080
- with pytest .raises (SchemaError , match = ' Field "x" : a required field cannot have a default value' ):
1080
+ with pytest .raises (SchemaError , match = " Field 'x' : a required field cannot have a default value" ):
1081
1081
SchemaValidator (
1082
1082
{
1083
1083
'type' : 'typed-dict' ,
@@ -1099,3 +1099,115 @@ def test_bad_default_factory(default_factory, error_message):
1099
1099
)
1100
1100
with pytest .raises (TypeError , match = re .escape (error_message )):
1101
1101
v .validate_python ({})
1102
+
1103
+
1104
+ class TestOnError :
1105
+ def test_on_error_bad_name (self ):
1106
+ with pytest .raises (SchemaError , match = "Input should be one of: 'raise', 'omit', 'fallback_on_default'" ):
1107
+ SchemaValidator ({'type' : 'typed-dict' , 'fields' : {'x' : {'schema' : {'type' : 'str' }, 'on_error' : 'rais' }}})
1108
+
1109
+ def test_on_error_bad_omit (self ):
1110
+ with pytest .raises (SchemaError , match = "Field 'x': 'on_error = omit' cannot be set for required fields" ):
1111
+ SchemaValidator ({'type' : 'typed-dict' , 'fields' : {'x' : {'schema' : {'type' : 'str' }, 'on_error' : 'omit' }}})
1112
+
1113
+ def test_on_error_bad_fallback_on_default (self ):
1114
+ with pytest .raises (
1115
+ SchemaError , match = "Field 'x': 'on_error = fallback_on_default' requires a `default` or `default_factory`"
1116
+ ):
1117
+ SchemaValidator (
1118
+ {'type' : 'typed-dict' , 'fields' : {'x' : {'schema' : {'type' : 'str' }, 'on_error' : 'fallback_on_default' }}}
1119
+ )
1120
+
1121
+ def test_on_error_raise_by_default (self , py_and_json : PyAndJson ):
1122
+ v = py_and_json ({'type' : 'typed-dict' , 'fields' : {'x' : {'schema' : {'type' : 'str' }}}})
1123
+ assert v .validate_test ({'x' : 'foo' }) == {'x' : 'foo' }
1124
+ with pytest .raises (ValidationError ) as exc_info :
1125
+ v .validate_test ({'x' : ['foo' ]})
1126
+ assert exc_info .value .errors () == [
1127
+ {'input_value' : ['foo' ], 'kind' : 'str_type' , 'loc' : ['x' ], 'message' : 'Input should be a valid string' }
1128
+ ]
1129
+
1130
+ def test_on_error_raise_explicit (self , py_and_json : PyAndJson ):
1131
+ v = py_and_json ({'type' : 'typed-dict' , 'fields' : {'x' : {'schema' : {'type' : 'str' }, 'on_error' : 'raise' }}})
1132
+ assert v .validate_test ({'x' : 'foo' }) == {'x' : 'foo' }
1133
+ with pytest .raises (ValidationError ) as exc_info :
1134
+ v .validate_test ({'x' : ['foo' ]})
1135
+ assert exc_info .value .errors () == [
1136
+ {'input_value' : ['foo' ], 'kind' : 'str_type' , 'loc' : ['x' ], 'message' : 'Input should be a valid string' }
1137
+ ]
1138
+
1139
+ def test_on_error_omit (self , py_and_json : PyAndJson ):
1140
+ v = py_and_json (
1141
+ {'type' : 'typed-dict' , 'fields' : {'x' : {'schema' : {'type' : 'str' }, 'on_error' : 'omit' , 'required' : False }}}
1142
+ )
1143
+ assert v .validate_test ({'x' : 'foo' }) == {'x' : 'foo' }
1144
+ assert v .validate_test ({}) == {}
1145
+ assert v .validate_test ({'x' : ['foo' ]}) == {}
1146
+
1147
+ def test_on_error_omit_with_default (self , py_and_json : PyAndJson ):
1148
+ v = py_and_json (
1149
+ {
1150
+ 'type' : 'typed-dict' ,
1151
+ 'fields' : {'x' : {'schema' : {'type' : 'str' }, 'on_error' : 'omit' , 'default' : 'pika' , 'required' : False }},
1152
+ }
1153
+ )
1154
+ assert v .validate_test ({'x' : 'foo' }) == {'x' : 'foo' }
1155
+ assert v .validate_test ({}) == {'x' : 'pika' }
1156
+ assert v .validate_test ({'x' : ['foo' ]}) == {}
1157
+
1158
+ def test_on_error_fallback_on_default (self , py_and_json : PyAndJson ):
1159
+ v = py_and_json (
1160
+ {
1161
+ 'type' : 'typed-dict' ,
1162
+ 'fields' : {'x' : {'schema' : {'type' : 'str' }, 'on_error' : 'fallback_on_default' , 'default' : 'pika' }},
1163
+ }
1164
+ )
1165
+ assert v .validate_test ({'x' : 'foo' }) == {'x' : 'foo' }
1166
+ assert v .validate_test ({'x' : ['foo' ]}) == {'x' : 'pika' }
1167
+
1168
+ def test_on_error_fallback_on_default_factory (self , py_and_json : PyAndJson ):
1169
+ v = py_and_json (
1170
+ {
1171
+ 'type' : 'typed-dict' ,
1172
+ 'fields' : {
1173
+ 'x' : {
1174
+ 'schema' : {'type' : 'str' },
1175
+ 'on_error' : 'fallback_on_default' ,
1176
+ 'default_factory' : lambda : 'pika' ,
1177
+ }
1178
+ },
1179
+ }
1180
+ )
1181
+ assert v .validate_test ({'x' : 'foo' }) == {'x' : 'foo' }
1182
+ assert v .validate_test ({'x' : ['foo' ]}) == {'x' : 'pika' }
1183
+
1184
+ def test_wrap_on_error (self , py_and_json : PyAndJson ):
1185
+ def wrap_function (input_value , * , validator , ** kwargs ):
1186
+ try :
1187
+ return validator (input_value )
1188
+ except ValidationError :
1189
+ if isinstance (input_value , list ):
1190
+ return str (len (input_value ))
1191
+ else :
1192
+ return repr (input_value )
1193
+
1194
+ v = py_and_json (
1195
+ {
1196
+ 'type' : 'typed-dict' ,
1197
+ 'fields' : {
1198
+ 'x' : {
1199
+ 'schema' : {
1200
+ 'type' : 'function' ,
1201
+ 'mode' : 'wrap' ,
1202
+ 'function' : wrap_function ,
1203
+ 'schema' : {'type' : 'str' },
1204
+ },
1205
+ 'on_error' : 'raise' ,
1206
+ }
1207
+ },
1208
+ }
1209
+ )
1210
+ assert v .validate_test ({'x' : 'foo' }) == {'x' : 'foo' }
1211
+ assert v .validate_test ({'x' : ['foo' ]}) == {'x' : '1' }
1212
+ assert v .validate_test ({'x' : ['foo' , 'bar' ]}) == {'x' : '2' }
1213
+ assert v .validate_test ({'x' : {'a' : 'b' }}) == {'x' : "{'a': 'b'}" }
0 commit comments