@@ -775,57 +775,56 @@ def test_alias_populate_by_name(py_and_json: PyAndJson, input_value, expected):
775
775
assert v .validate_test (input_value ) == expected
776
776
777
777
778
- def validate (function ):
779
- """
780
- a demo validation decorator to test arguments
781
- """
782
- parameters = signature (function ).parameters
783
-
784
- type_hints = get_type_hints (function )
785
- mode_lookup = {
786
- Parameter .POSITIONAL_ONLY : 'positional_only' ,
787
- Parameter .POSITIONAL_OR_KEYWORD : 'positional_or_keyword' ,
788
- Parameter .KEYWORD_ONLY : 'keyword_only' ,
789
- }
790
-
791
- arguments_schema = []
792
- schema = {'type' : 'arguments' , 'arguments_schema' : arguments_schema }
793
- for i , (name , p ) in enumerate (parameters .items ()):
794
- if p .annotation is p .empty :
795
- annotation = Any
796
- else :
797
- annotation = type_hints [name ]
798
-
799
- assert annotation in (bool , int , float , str , Any ), f'schema for { annotation } not implemented'
800
- if annotation in (bool , int , float , str ):
801
- arg_schema = {'type' : annotation .__name__ }
802
- else :
803
- assert annotation is Any
804
- arg_schema = {'type' : 'any' }
805
-
806
- if p .kind in mode_lookup :
807
- if p .default is not p .empty :
808
- arg_schema = {'type' : 'default' , 'schema' : arg_schema , 'default' : p .default }
809
- s = {'name' : name , 'mode' : mode_lookup [p .kind ], 'schema' : arg_schema }
810
- arguments_schema .append (s )
811
- elif p .kind == Parameter .VAR_POSITIONAL :
812
- schema ['var_args_schema' ] = arg_schema
813
- else :
814
- assert p .kind == Parameter .VAR_KEYWORD , p .kind
815
- schema ['var_kwargs_schema' ] = arg_schema
816
-
817
- validator = SchemaValidator (schema )
818
-
819
- @wraps (function )
820
- def wrapper (* args , ** kwargs ):
821
- validated_args , validated_kwargs = validator .validate_python (ArgsKwargs (args , kwargs ))
822
- return function (* validated_args , ** validated_kwargs )
823
-
824
- return wrapper
778
+ def validate (config = None ):
779
+ def decorator (function ):
780
+ parameters = signature (function ).parameters
781
+ type_hints = get_type_hints (function )
782
+ mode_lookup = {
783
+ Parameter .POSITIONAL_ONLY : 'positional_only' ,
784
+ Parameter .POSITIONAL_OR_KEYWORD : 'positional_or_keyword' ,
785
+ Parameter .KEYWORD_ONLY : 'keyword_only' ,
786
+ }
825
787
788
+ arguments_schema = []
789
+ schema = {'type' : 'arguments' , 'arguments_schema' : arguments_schema }
790
+ for i , (name , p ) in enumerate (parameters .items ()):
791
+ if p .annotation is p .empty :
792
+ annotation = Any
793
+ else :
794
+ annotation = type_hints [name ]
795
+
796
+ assert annotation in (bool , int , float , str , Any ), f'schema for { annotation } not implemented'
797
+ if annotation in (bool , int , float , str ):
798
+ arg_schema = {'type' : annotation .__name__ }
799
+ else :
800
+ assert annotation is Any
801
+ arg_schema = {'type' : 'any' }
802
+
803
+ if p .kind in mode_lookup :
804
+ if p .default is not p .empty :
805
+ arg_schema = {'type' : 'default' , 'schema' : arg_schema , 'default' : p .default }
806
+ s = {'name' : name , 'mode' : mode_lookup [p .kind ], 'schema' : arg_schema }
807
+ arguments_schema .append (s )
808
+ elif p .kind == Parameter .VAR_POSITIONAL :
809
+ schema ['var_args_schema' ] = arg_schema
810
+ else :
811
+ assert p .kind == Parameter .VAR_KEYWORD , p .kind
812
+ schema ['var_kwargs_schema' ] = arg_schema
813
+
814
+ validator = SchemaValidator (schema , config = config )
815
+
816
+ @wraps (function )
817
+ def wrapper (* args , ** kwargs ):
818
+ # Validate arguments using the original schema
819
+ validated_args , validated_kwargs = validator .validate_python (ArgsKwargs (args , kwargs ))
820
+ return function (* validated_args , ** validated_kwargs )
821
+
822
+ return wrapper
823
+
824
+ return decorator
826
825
827
826
def test_function_any ():
828
- @validate
827
+ @validate ()
829
828
def foobar (a , b , c ):
830
829
return a , b , c
831
830
@@ -842,7 +841,7 @@ def foobar(a, b, c):
842
841
843
842
844
843
def test_function_types ():
845
- @validate
844
+ @validate ()
846
845
def foobar (a : int , b : int , * , c : int ):
847
846
return a , b , c
848
847
@@ -894,8 +893,8 @@ def test_function_positional_only(import_execute):
894
893
# language=Python
895
894
m = import_execute (
896
895
"""
897
- def create_function(validate):
898
- @validate
896
+ def create_function(validate, config = None ):
897
+ @validate(config = config)
899
898
def foobar(a: int, b: int, /, c: int):
900
899
return a, b, c
901
900
return foobar
@@ -915,15 +914,20 @@ def foobar(a: int, b: int, /, c: int):
915
914
},
916
915
{'type' : 'unexpected_keyword_argument' , 'loc' : ('b' ,), 'msg' : 'Unexpected keyword argument' , 'input' : 2 },
917
916
]
918
-
917
+ # Allowin extras using the config
918
+ foobar = m .create_function (validate , config = {'title' : 'func' , 'extra_fields_behavior' : 'allow' })
919
+ assert foobar ('1' , '2' , c = 3 , d = 4 ) == (1 , 2 , 3 )
920
+ # Ignore works similar than allow
921
+ foobar = m .create_function (validate , config = {'title' : 'func' , 'extra_fields_behavior' : 'ignore' })
922
+ assert foobar ('1' , '2' , c = 3 , d = 4 ) == (1 , 2 , 3 )
919
923
920
924
@pytest .mark .skipif (sys .version_info < (3 , 10 ), reason = 'requires python3.10 or higher' )
921
925
def test_function_positional_only_default (import_execute ):
922
926
# language=Python
923
927
m = import_execute (
924
928
"""
925
929
def create_function(validate):
926
- @validate
930
+ @validate()
927
931
def foobar(a: int, b: int = 42, /):
928
932
return a, b
929
933
return foobar
@@ -940,7 +944,7 @@ def test_function_positional_kwargs(import_execute):
940
944
m = import_execute (
941
945
"""
942
946
def create_function(validate):
943
- @validate
947
+ @validate()
944
948
def foobar(a: int, b: int, /, **kwargs: bool):
945
949
return a, b, kwargs
946
950
return foobar
@@ -953,7 +957,7 @@ def foobar(a: int, b: int, /, **kwargs: bool):
953
957
954
958
955
959
def test_function_args_kwargs ():
956
- @validate
960
+ @validate ()
957
961
def foobar (* args , ** kwargs ):
958
962
return args , kwargs
959
963
0 commit comments