1919#
2020#
2121
22- """ This module contains base REST classes for constructing REST servlets. """
22+ """This module contains base REST classes for constructing REST servlets."""
23+
2324import enum
2425import logging
2526from http import HTTPStatus
@@ -65,17 +66,49 @@ def parse_integer(request: Request, name: str, default: int) -> int: ...
6566
6667
6768@overload
68- def parse_integer (request : Request , name : str , * , required : Literal [True ]) -> int : ...
69+ def parse_integer (
70+ request : Request , name : str , * , default : int , negative : bool
71+ ) -> int : ...
72+
73+
74+ @overload
75+ def parse_integer (
76+ request : Request , name : str , * , default : int , negative : bool = False
77+ ) -> int : ...
78+
79+
80+ @overload
81+ def parse_integer (
82+ request : Request , name : str , * , required : Literal [True ], negative : bool = False
83+ ) -> int : ...
84+
85+
86+ @overload
87+ def parse_integer (
88+ request : Request , name : str , * , default : Literal [None ], negative : bool = False
89+ ) -> None : ...
90+
91+
92+ @overload
93+ def parse_integer (request : Request , name : str , * , negative : bool ) -> Optional [int ]: ...
6994
7095
7196@overload
7297def parse_integer (
73- request : Request , name : str , default : Optional [int ] = None , required : bool = False
98+ request : Request ,
99+ name : str ,
100+ default : Optional [int ] = None ,
101+ required : bool = False ,
102+ negative : bool = False ,
74103) -> Optional [int ]: ...
75104
76105
77106def parse_integer (
78- request : Request , name : str , default : Optional [int ] = None , required : bool = False
107+ request : Request ,
108+ name : str ,
109+ default : Optional [int ] = None ,
110+ required : bool = False ,
111+ negative : bool = False ,
79112) -> Optional [int ]:
80113 """Parse an integer parameter from the request string
81114
@@ -85,16 +118,17 @@ def parse_integer(
85118 default: value to use if the parameter is absent, defaults to None.
86119 required: whether to raise a 400 SynapseError if the parameter is absent,
87120 defaults to False.
88-
121+ negative: whether to allow negative integers, defaults to True.
89122 Returns:
90123 An int value or the default.
91124
92125 Raises:
93- SynapseError: if the parameter is absent and required, or if the
94- parameter is present and not an integer.
126+ SynapseError: if the parameter is absent and required, if the
127+ parameter is present and not an integer, or if the
128+ parameter is illegitimate negative.
95129 """
96130 args : Mapping [bytes , Sequence [bytes ]] = request .args # type: ignore
97- return parse_integer_from_args (args , name , default , required )
131+ return parse_integer_from_args (args , name , default , required , negative )
98132
99133
100134@overload
@@ -120,6 +154,7 @@ def parse_integer_from_args(
120154 name : str ,
121155 default : Optional [int ] = None ,
122156 required : bool = False ,
157+ negative : bool = False ,
123158) -> Optional [int ]: ...
124159
125160
@@ -128,6 +163,7 @@ def parse_integer_from_args(
128163 name : str ,
129164 default : Optional [int ] = None ,
130165 required : bool = False ,
166+ negative : bool = True ,
131167) -> Optional [int ]:
132168 """Parse an integer parameter from the request string
133169
@@ -137,33 +173,37 @@ def parse_integer_from_args(
137173 default: value to use if the parameter is absent, defaults to None.
138174 required: whether to raise a 400 SynapseError if the parameter is absent,
139175 defaults to False.
176+ negative: whether to allow negative integers, defaults to True.
140177
141178 Returns:
142179 An int value or the default.
143180
144181 Raises:
145- SynapseError: if the parameter is absent and required, or if the
146- parameter is present and not an integer.
182+ SynapseError: if the parameter is absent and required, if the
183+ parameter is present and not an integer, or if the
184+ parameter is illegitimate negative.
147185 """
148186 name_bytes = name .encode ("ascii" )
149187
150- if name_bytes in args :
151- try :
152- return int (args [name_bytes ][0 ])
153- except Exception :
154- message = "Query parameter %r must be an integer" % (name ,)
155- raise SynapseError (
156- HTTPStatus .BAD_REQUEST , message , errcode = Codes .INVALID_PARAM
157- )
158- else :
159- if required :
160- message = "Missing integer query parameter %r" % (name ,)
161- raise SynapseError (
162- HTTPStatus .BAD_REQUEST , message , errcode = Codes .MISSING_PARAM
163- )
164- else :
188+ if name_bytes not in args :
189+ if not required :
165190 return default
166191
192+ message = f"Missing required integer query parameter { name } "
193+ raise SynapseError (HTTPStatus .BAD_REQUEST , message , errcode = Codes .MISSING_PARAM )
194+
195+ try :
196+ integer = int (args [name_bytes ][0 ])
197+ except Exception :
198+ message = f"Query parameter { name } must be an integer"
199+ raise SynapseError (HTTPStatus .BAD_REQUEST , message , errcode = Codes .INVALID_PARAM )
200+
201+ if not negative and integer < 0 :
202+ message = f"Query parameter { name } must be a positive integer."
203+ raise SynapseError (HTTPStatus .BAD_REQUEST , message , errcode = Codes .INVALID_PARAM )
204+
205+ return integer
206+
167207
168208@overload
169209def parse_boolean (request : Request , name : str , default : bool ) -> bool : ...
0 commit comments