1
- #!/usr/bin/env python
1
+ #!/usr/bin/env python3
2
2
3
3
import typing
4
4
from inspect import signature
@@ -39,6 +39,7 @@ def nested_func(**kwargs):
39
39
param_type = arg .default # ie. Route(), Json()
40
40
param_name = arg .name # ie. id, username
41
41
param_annotation = arg .annotation or typing .Any # ie. str, int
42
+ is_list_or_union = hasattr (param_annotation , "__args__" )
42
43
# Ensure param type is valid
43
44
if param_type .__class__ not in request_inputs .keys ():
44
45
return self .error_function ("Invalid parameter type." )
@@ -55,9 +56,15 @@ def nested_func(**kwargs):
55
56
# If no default and no input, error
56
57
elif user_input is None :
57
58
ptype = param_type .name
58
- return self .error_function (
59
+ error_response = self .error_function (
59
60
f"Required { ptype } parameter '{ param_name } ' not given."
60
61
)
62
+ # If "None" is allowed in Union, then continue
63
+ if is_list_or_union :
64
+ if type (None ) not in param_annotation .__args__ :
65
+ return error_response
66
+ else :
67
+ return error_response
61
68
62
69
# If typing's Any, ClassVar or Optional, don't validate type
63
70
if isinstance (param_annotation , typing ._SpecialForm ):
@@ -68,7 +75,7 @@ def nested_func(**kwargs):
68
75
else :
69
76
allowed_types = []
70
77
# If List or Union, get all "inner" types
71
- if hasattr ( param_annotation , "__args__" ) :
78
+ if is_list_or_union :
72
79
allowed_types = param_annotation .__args__
73
80
else :
74
81
allowed_types = (param_annotation ,)
@@ -82,6 +89,9 @@ def nested_func(**kwargs):
82
89
valid = all (
83
90
isinstance (i , allowed_types ) for i in user_input
84
91
)
92
+ elif type (user_input ) != list and annotation_is_list :
93
+ allowed_types = [list ]
94
+ valid = False
85
95
else :
86
96
# If not list, just validate singular data type
87
97
valid = isinstance (user_input , allowed_types )
@@ -96,9 +106,17 @@ def nested_func(**kwargs):
96
106
f"Parameter '{ param_name } ' { e } "
97
107
)
98
108
else :
109
+ if type (None ) in allowed_types :
110
+ allowed_types = list (allowed_types )
111
+ allowed_types .remove (type (None ))
112
+ startphrase = "Optional parameter"
113
+ else :
114
+ startphrase = "Parameter"
99
115
types = "/" .join (t .__name__ for t in allowed_types )
116
+ if annotation_is_list :
117
+ types = "List[" + types + "]"
100
118
return decorator_self .error_function (
101
- f"Parameter '{ param_name } ' should be type { types } ."
119
+ f"{ startphrase } '{ param_name } ' should be type { types } ."
102
120
)
103
121
104
122
return f (** parsed_inputs )
0 commit comments