@@ -47,14 +47,12 @@ def __init__(
4747 self ._creation_counter = Field ._creation_counter
4848 Field ._creation_counter += 1
4949
50- def validate (self , value : typing .Any , * , strict : bool = False ) -> typing .Any :
50+ def validate (self , value : typing .Any ) -> typing .Any :
5151 raise NotImplementedError () # pragma: no cover
5252
53- def validate_or_error (
54- self , value : typing .Any , * , strict : bool = False
55- ) -> ValidationResult :
53+ def validate_or_error (self , value : typing .Any ) -> ValidationResult :
5654 try :
57- value = self .validate (value , strict = strict )
55+ value = self .validate (value )
5856 except ValidationError as error :
5957 return ValidationResult (value = None , error = error )
6058 return ValidationResult (value = value , error = None )
@@ -112,6 +110,7 @@ def __init__(
112110 min_length : int = None ,
113111 pattern : typing .Union [str , typing .Pattern ] = None ,
114112 format : str = None ,
113+ coerce_types : bool = True ,
115114 ** kwargs : typing .Any ,
116115 ) -> None :
117116 super ().__init__ (** kwargs )
@@ -129,6 +128,7 @@ def __init__(
129128 self .max_length = max_length
130129 self .min_length = min_length
131130 self .format = format
131+ self .coerce_types = coerce_types
132132
133133 if pattern is None :
134134 self .pattern = None
@@ -140,10 +140,10 @@ def __init__(
140140 self .pattern = pattern .pattern
141141 self .pattern_regex = pattern
142142
143- def validate (self , value : typing .Any , * , strict : bool = False ) -> typing .Any :
143+ def validate (self , value : typing .Any ) -> typing .Any :
144144 if value is None and self .allow_null :
145145 return None
146- elif value is None and self .allow_blank and not strict :
146+ elif value is None and self .allow_blank and self . coerce_types :
147147 # Leniently cast nulls to empty strings if allow_blank.
148148 return ""
149149 elif value is None :
@@ -161,7 +161,7 @@ def validate(self, value: typing.Any, *, strict: bool = False) -> typing.Any:
161161 value = value .strip ()
162162
163163 if not self .allow_blank and not value :
164- if self .allow_null and not strict :
164+ if self .allow_null and self . coerce_types :
165165 # Leniently cast empty strings (after trimming) to null if allow_null.
166166 return None
167167 raise self .validation_error ("blank" )
@@ -212,6 +212,7 @@ def __init__(
212212 exclusive_maximum : typing .Union [int , float , decimal .Decimal ] = None ,
213213 precision : str = None ,
214214 multiple_of : typing .Union [int , float , decimal .Decimal ] = None ,
215+ coerce_types : bool = True ,
215216 ** kwargs : typing .Any ,
216217 ):
217218 super ().__init__ (** kwargs )
@@ -234,11 +235,12 @@ def __init__(
234235 self .exclusive_maximum = exclusive_maximum
235236 self .multiple_of = multiple_of
236237 self .precision = precision
238+ self .coerce_types = coerce_types
237239
238- def validate (self , value : typing .Any , * , strict : bool = False ) -> typing .Any :
240+ def validate (self , value : typing .Any ) -> typing .Any :
239241 if value is None and self .allow_null :
240242 return None
241- elif value == "" and self .allow_null and not strict :
243+ elif value == "" and self .allow_null and self . coerce_types :
242244 return None
243245 elif value is None :
244246 raise self .validation_error ("null" )
@@ -250,7 +252,7 @@ def validate(self, value: typing.Any, *, strict: bool = False) -> typing.Any:
250252 and not value .is_integer ()
251253 ):
252254 raise self .validation_error ("integer" )
253- elif not isinstance (value , (int , float )) and strict :
255+ elif not isinstance (value , (int , float )) and not self . coerce_types :
254256 raise self .validation_error ("type" )
255257
256258 try :
@@ -328,15 +330,19 @@ class Boolean(Field):
328330 }
329331 coerce_null_values = {"" , "null" , "none" }
330332
331- def validate (self , value : typing .Any , * , strict : bool = False ) -> typing .Any :
333+ def __init__ (self , * , coerce_types : bool = True , ** kwargs : typing .Any ) -> None :
334+ super ().__init__ (** kwargs )
335+ self .coerce_types = coerce_types
336+
337+ def validate (self , value : typing .Any ) -> typing .Any :
332338 if value is None and self .allow_null :
333339 return None
334340
335341 elif value is None :
336342 raise self .validation_error ("null" )
337343
338344 elif not isinstance (value , bool ):
339- if strict :
345+ if not self . coerce_types :
340346 raise self .validation_error ("type" )
341347
342348 if isinstance (value , str ):
@@ -364,23 +370,25 @@ def __init__(
364370 self ,
365371 * ,
366372 choices : typing .Sequence [typing .Union [str , typing .Tuple [str , str ]]] = None ,
373+ coerce_types : bool = True ,
367374 ** kwargs : typing .Any ,
368375 ) -> None :
369376 super ().__init__ (** kwargs )
370377 self .choices = [
371378 (choice if isinstance (choice , (tuple , list )) else (choice , choice ))
372379 for choice in choices or []
373380 ]
381+ self .coerce_types = coerce_types
374382 assert all (len (choice ) == 2 for choice in self .choices )
375383
376- def validate (self , value : typing .Any , * , strict : bool = False ) -> typing .Any :
384+ def validate (self , value : typing .Any ) -> typing .Any :
377385 if value is None and self .allow_null :
378386 return None
379387 elif value is None :
380388 raise self .validation_error ("null" )
381389 elif value not in Uniqueness ([key for key , value in self .choices ]):
382390 if value == "" :
383- if self .allow_null and not strict :
391+ if self .allow_null and self . coerce_types :
384392 return None
385393 raise self .validation_error ("required" )
386394 raise self .validation_error ("choice" )
@@ -443,7 +451,7 @@ def __init__(
443451 self .max_properties = max_properties
444452 self .required = required
445453
446- def validate (self , value : typing .Any , * , strict : bool = False ) -> typing .Any :
454+ def validate (self , value : typing .Any ) -> typing .Any :
447455 if value is None and self .allow_null :
448456 return None
449457 elif value is None :
@@ -492,7 +500,7 @@ def validate(self, value: typing.Any, *, strict: bool = False) -> typing.Any:
492500 validated [key ] = child_schema .get_default_value ()
493501 continue
494502 item = value [key ]
495- child_value , error = child_schema .validate_or_error (item , strict = strict )
503+ child_value , error = child_schema .validate_or_error (item )
496504 if not error :
497505 validated [key ] = child_value
498506 else :
@@ -504,9 +512,7 @@ def validate(self, value: typing.Any, *, strict: bool = False) -> typing.Any:
504512 for pattern , child_schema in self .pattern_properties .items ():
505513 if isinstance (key , str ) and re .search (pattern , key ):
506514 item = value [key ]
507- child_value , error = child_schema .validate_or_error (
508- item , strict = strict
509- )
515+ child_value , error = child_schema .validate_or_error (item )
510516 if not error :
511517 validated [key ] = child_value
512518 else :
@@ -535,7 +541,7 @@ def validate(self, value: typing.Any, *, strict: bool = False) -> typing.Any:
535541 child_schema = self .additional_properties
536542 for key in remaining :
537543 item = value [key ]
538- child_value , error = child_schema .validate_or_error (item , strict = strict )
544+ child_value , error = child_schema .validate_or_error (item )
539545 if not error :
540546 validated [key ] = child_value
541547 else :
@@ -599,7 +605,7 @@ def __init__(
599605 self .max_items = max_items
600606 self .unique_items = unique_items
601607
602- def validate (self , value : typing .Any , * , strict : bool = False ) -> typing .Any :
608+ def validate (self , value : typing .Any ) -> typing .Any :
603609 if value is None and self .allow_null :
604610 return None
605611 elif value is None :
@@ -639,7 +645,7 @@ def validate(self, value: typing.Any, *, strict: bool = False) -> typing.Any:
639645 if validator is None :
640646 validated .append (item )
641647 else :
642- item , error = validator .validate_or_error (item , strict = strict )
648+ item , error = validator .validate_or_error (item )
643649 if error :
644650 error_messages += error .messages (add_prefix = pos )
645651 else :
@@ -704,15 +710,15 @@ def __init__(self, any_of: typing.List[Field], **kwargs: typing.Any):
704710 if any ([child .allow_null for child in any_of ]):
705711 self .allow_null = True
706712
707- def validate (self , value : typing .Any , strict : bool = False ) -> typing .Any :
713+ def validate (self , value : typing .Any ) -> typing .Any :
708714 if value is None and self .allow_null :
709715 return None
710716 elif value is None :
711717 raise self .validation_error ("null" )
712718
713719 candidate_errors = []
714720 for child in self .any_of :
715- validated , error = child .validate_or_error (value , strict = strict )
721+ validated , error = child .validate_or_error (value )
716722 if error is None :
717723 return validated
718724 else :
@@ -738,7 +744,7 @@ class Any(Field):
738744 Always matches.
739745 """
740746
741- def validate (self , value : typing .Any , strict : bool = False ) -> typing .Any :
747+ def validate (self , value : typing .Any ) -> typing .Any :
742748 return value
743749
744750
@@ -754,7 +760,7 @@ def __init__(self, const: typing.Any, **kwargs: typing.Any):
754760 super ().__init__ (** kwargs )
755761 self .const = const
756762
757- def validate (self , value : typing .Any , strict : bool = False ) -> typing .Any :
763+ def validate (self , value : typing .Any ) -> typing .Any :
758764 if value != self .const :
759765 if self .const is None :
760766 raise self .validation_error ("only_null" )
0 commit comments