66 SPDX-License-Identifier: GPL-2.0-only
77 See LICENSES/GPL-2.0-only for more information.
88"""
9+ from __future__ import absolute_import , division , unicode_literals
10+
911
1012__all__ = (
1113 'BaseHTTPRequestHandler' ,
1214 'StringIO' ,
1315 'TCPServer' ,
1416 'ThreadingMixIn' ,
1517 'available_cpu_count' ,
16- 'byte_string_type' ,
1718 'datetime_infolabel' ,
1819 'entity_escape' ,
1920 'generate_hash' ,
2526 'range_type' ,
2627 'string_type' ,
2728 'to_str' ,
29+ 'to_unicode' ,
2830 'unescape' ,
2931 'unquote' ,
3032 'unquote_plus' ,
7274
7375 range_type = (range , list )
7476
75- byte_string_type = bytes
7677 string_type = str
7778 to_str = str
7879
7980
81+ def to_unicode (text ):
82+ if isinstance (text , bytes ):
83+ text = text .decode ('utf-8' , errors = 'ignore' )
84+ return text
85+
86+
8087 def entity_escape (text ,
8188 entities = str .maketrans ({
8289 '&' : '&' ,
@@ -133,8 +140,8 @@ def generate_hash(*args, **kwargs):
133140 urlencode as _urlencode ,
134141 )
135142 from urlparse import (
136- parse_qs ,
137- parse_qsl ,
143+ parse_qs as _parse_qs ,
144+ parse_qsl as _parse_qsl ,
138145 urljoin ,
139146 urlsplit ,
140147 urlunsplit ,
@@ -150,38 +157,103 @@ def generate_hash(*args, **kwargs):
150157 )
151158
152159
153- def quote (data , * args , ** kwargs ):
154- return _quote (to_str (data ), * args , ** kwargs )
155-
156-
157- def quote_plus (data , * args , ** kwargs ):
158- return _quote_plus (to_str (data ), * args , ** kwargs )
159-
160-
161- def unquote (data ):
162- return _unquote (to_str (data ))
163-
164-
165- def unquote_plus (data ):
166- return _unquote_plus (to_str (data ))
167-
168-
169- def urlencode (data , * args , ** kwargs ):
170- if isinstance (data , dict ):
171- data = data .items ()
172- kwargs = {
173- key : value
174- for key , value in kwargs .viewitems ()
175- if key in {'query' , 'doseq' }
176- }
177- return _urlencode ({
178- to_str (key ): (
179- [to_str (part ) for part in value ]
160+ def parse_qs (* args , ** kwargs ):
161+ num_args = len (args )
162+ query_dict = _parse_qs (
163+ to_str (args [0 ] if args else kwargs .get ('qs' )),
164+ keep_blank_values = (
165+ args [1 ]
166+ if num_args >= 2 else
167+ kwargs .get ('keep_blank_values' , 0 )
168+ ),
169+ strict_parsing = (
170+ args [2 ]
171+ if num_args >= 3 else
172+ kwargs .get ('strict_parsing' , 0 )
173+ ),
174+ # max_num_fields=(
175+ # args[3]
176+ # if num_args >= 4 else
177+ # kwargs.get('max_num_fields', 0)
178+ # ),
179+ )
180+ return {
181+ to_unicode (key ): (
182+ [to_unicode (part ) for part in value ]
180183 if isinstance (value , (list , tuple )) else
181- to_str (value )
184+ to_unicode (value )
182185 )
183- for key , value in data
184- }, * args , ** kwargs )
186+ for key , value in query_dict .viewitems ()
187+ }
188+
189+
190+ def parse_qsl (* args , ** kwargs ):
191+ num_args = len (args )
192+ query_list = _parse_qsl (
193+ to_str (args [0 ] if args else kwargs .get ('qs' )),
194+ keep_blank_values = (
195+ args [1 ]
196+ if num_args >= 2 else
197+ kwargs .get ('keep_blank_values' , 0 )
198+ ),
199+ strict_parsing = (
200+ args [2 ]
201+ if num_args >= 3 else
202+ kwargs .get ('strict_parsing' , 0 )
203+ ),
204+ # max_num_fields=(
205+ # args[3]
206+ # if num_args >= 4 else
207+ # kwargs.get('max_num_fields', 0)
208+ # ),
209+ )
210+ return [
211+ (to_unicode (key ), to_unicode (value ))
212+ for key , value in query_list
213+ ]
214+
215+
216+ def quote (* args , ** kwargs ):
217+ return _quote (
218+ to_str (args [0 ] if args else kwargs .get ('string' )),
219+ safe = args [1 ] if len (args ) >= 2 else kwargs .get ('safe' , '/' ),
220+ )
221+
222+
223+ def quote_plus (* args , ** kwargs ):
224+ return _quote_plus (
225+ to_str (args [0 ] if args else kwargs .get ('string' )),
226+ safe = args [1 ] if len (args ) >= 2 else kwargs .get ('safe' , '/' ),
227+ )
228+
229+
230+ def unquote (* args , ** kwargs ):
231+ return _unquote (
232+ to_str (args [0 ] if args else kwargs .get ('string' ))
233+ )
234+
235+
236+ def unquote_plus (* args , ** kwargs ):
237+ return _unquote_plus (
238+ to_str (args [0 ] if args else kwargs .get ('string' ))
239+ )
240+
241+
242+ def urlencode (* args , ** kwargs ):
243+ query = args [0 ] if args else kwargs .get ('query' )
244+ if isinstance (query , dict ):
245+ query = query .viewitems ()
246+ return _urlencode (
247+ query = {
248+ to_str (key ): (
249+ [to_str (part ) for part in value ]
250+ if isinstance (value , (list , tuple )) else
251+ to_str (value )
252+ )
253+ for key , value in query
254+ },
255+ doseq = args [1 ] if len (args ) >= 2 else kwargs .get ('doseq' , 0 ),
256+ )
185257
186258
187259 class StringIO (_StringIO ):
@@ -205,18 +277,23 @@ def __exit__(self, exc_type, exc_val, exc_tb):
205277
206278 range_type = (xrange , list )
207279
208- byte_string_type = (bytes , str )
209280 string_type = basestring
210281
211282
212- def to_str (value , _format = '{0!s}' .format ):
283+ def to_str (value , _format = b '{0!s}' .format ):
213284 if not isinstance (value , basestring ):
214285 value = _format (value )
215- if isinstance (value , unicode ):
216- value = value .encode ('utf-8' )
286+ elif isinstance (value , unicode ):
287+ value = value .encode ('utf-8' , errors = 'ignore' )
217288 return value
218289
219290
291+ def to_unicode (text ):
292+ if isinstance (text , (bytes , str )):
293+ text = text .decode ('utf-8' , errors = 'ignore' )
294+ return text
295+
296+
220297 def entity_escape (text ,
221298 entities = {
222299 '&' : '&' ,
@@ -231,7 +308,7 @@ def entity_escape(text,
231308
232309
233310 def generate_hash (* args , ** kwargs ):
234- return md5 ('' .join (
311+ return md5 (b '' .join (
235312 map (to_str , args or kwargs .get ('iter' ))
236313 )).hexdigest ()
237314
0 commit comments