@@ -69,12 +69,12 @@ def _cli_patch(cli_args): # pragma: no coverage
69
69
# Imports and Python 2/3 unification ##########################################
70
70
###############################################################################
71
71
72
- import base64 , calendar , cgi , email .utils , functools , hmac , imp , itertools ,\
72
+ import base64 , calendar , cgi , email .utils , functools , hmac , itertools ,\
73
73
mimetypes , os , re , tempfile , threading , time , warnings , weakref , hashlib
74
74
75
75
from types import FunctionType
76
76
from datetime import date as datedate , datetime , timedelta
77
- from tempfile import TemporaryFile
77
+ from tempfile import NamedTemporaryFile
78
78
from traceback import format_exc , print_exc
79
79
from unicodedata import normalize
80
80
@@ -83,34 +83,6 @@ def _cli_patch(cli_args): # pragma: no coverage
83
83
except ImportError :
84
84
from json import dumps as json_dumps , loads as json_lds
85
85
86
- # inspect.getargspec was removed in Python 3.6, use
87
- # Signature-based version where we can (Python 3.3+)
88
- try :
89
- from inspect import signature
90
- def getargspec (func ):
91
- params = signature (func ).parameters
92
- args , varargs , keywords , defaults = [], None , None , []
93
- for name , param in params .items ():
94
- if param .kind == param .VAR_POSITIONAL :
95
- varargs = name
96
- elif param .kind == param .VAR_KEYWORD :
97
- keywords = name
98
- else :
99
- args .append (name )
100
- if param .default is not param .empty :
101
- defaults .append (param .default )
102
- return (args , varargs , keywords , tuple (defaults ) or None )
103
- except ImportError :
104
- try :
105
- from inspect import getfullargspec
106
- def getargspec (func ):
107
- spec = getfullargspec (func )
108
- kwargs = makelist (spec [0 ]) + makelist (spec .kwonlyargs )
109
- return kwargs , spec [1 ], spec [2 ], spec [3 ]
110
- except ImportError :
111
- from inspect import getargspec
112
-
113
-
114
86
py = sys .version_info
115
87
py3k = py .major > 2
116
88
@@ -123,9 +95,17 @@ def getargspec(func):
123
95
urlunquote = functools .partial (urlunquote , encoding = 'latin1' )
124
96
from http .cookies import SimpleCookie , Morsel , CookieError
125
97
from collections .abc import MutableMapping as DictMixin
98
+ from types import ModuleType as new_module
126
99
import pickle
127
100
from io import BytesIO
128
101
import configparser
102
+ # getfullargspec was deprecated in 3.5 and un-deprecated in 3.6
103
+ # getargspec was deprecated in 3.0 and removed in 3.11
104
+ from inspect import getfullargspec
105
+ def getargspec (func ):
106
+ spec = getfullargspec (func )
107
+ kwargs = makelist (spec [0 ]) + makelist (spec .kwonlyargs )
108
+ return kwargs , spec [1 ], spec [2 ], spec [3 ]
129
109
130
110
basestring = str
131
111
unicode = str
@@ -143,9 +123,12 @@ def _raise(*a):
143
123
from Cookie import SimpleCookie , Morsel , CookieError
144
124
from itertools import imap
145
125
import cPickle as pickle
126
+ from imp import new_module
146
127
from StringIO import StringIO as BytesIO
147
128
import ConfigParser as configparser
148
129
from collections import MutableMapping as DictMixin
130
+ from inspect import getargspec
131
+
149
132
unicode = unicode
150
133
json_loads = json_lds
151
134
exec (compile ('def _raise(*a): raise a[0], a[1], a[2]' , '<py3fix>' , 'exec' ))
@@ -256,6 +239,7 @@ def __get__(self, obj, cls):
256
239
setattr (cls , self .__name__ , value )
257
240
return value
258
241
242
+
259
243
###############################################################################
260
244
# Exceptions and Events #######################################################
261
245
###############################################################################
@@ -1353,7 +1337,7 @@ def _body(self):
1353
1337
body .write (part )
1354
1338
body_size += len (part )
1355
1339
if not is_temp_file and body_size > self .MEMFILE_MAX :
1356
- body , tmp = TemporaryFile (mode = 'w+b' ), body
1340
+ body , tmp = NamedTemporaryFile (mode = 'w+b' ), body
1357
1341
body .write (tmp .getvalue ())
1358
1342
del tmp
1359
1343
is_temp_file = True
@@ -2010,6 +1994,7 @@ def apply(self, callback, route):
2010
1994
dumps = self .json_dumps
2011
1995
if not self .json_dumps : return callback
2012
1996
1997
+ @functools .wraps (callback )
2013
1998
def wrapper (* a , ** ka ):
2014
1999
try :
2015
2000
rv = callback (* a , ** ka )
@@ -2057,7 +2042,7 @@ def __init__(self, name, impmask):
2057
2042
""" Create a virtual package that redirects imports (see PEP 302). """
2058
2043
self .name = name
2059
2044
self .impmask = impmask
2060
- self .module = sys .modules .setdefault (name , imp . new_module (name ))
2045
+ self .module = sys .modules .setdefault (name , new_module (name ))
2061
2046
self .module .__dict__ .update ({
2062
2047
'__file__' : __file__ ,
2063
2048
'__path__' : [],
@@ -2066,10 +2051,15 @@ def __init__(self, name, impmask):
2066
2051
})
2067
2052
sys .meta_path .append (self )
2068
2053
2054
+ def find_spec (self , fullname , path , target = None ):
2055
+ if '.' not in fullname : return
2056
+ if fullname .rsplit ('.' , 1 )[0 ] != self .name : return
2057
+ from importlib .util import spec_from_loader
2058
+ return spec_from_loader (fullname , self )
2059
+
2069
2060
def find_module (self , fullname , path = None ):
2070
2061
if '.' not in fullname : return
2071
- packname = fullname .rsplit ('.' , 1 )[0 ]
2072
- if packname != self .name : return
2062
+ if fullname .rsplit ('.' , 1 )[0 ] != self .name : return
2073
2063
return self
2074
2064
2075
2065
def load_module (self , fullname ):
@@ -2825,18 +2815,15 @@ def redirect(url, code=None):
2825
2815
raise res
2826
2816
2827
2817
2828
- def _file_iter_range (fp , offset , bytes , maxread = 1024 * 1024 , close = False ):
2829
- """ Yield chunks from a range in a file, optionally closing it at the end.
2830
- No chunk is bigger than maxread. """
2818
+ def _rangeiter (fp , offset , limit , bufsize = 1024 * 1024 ):
2819
+ """ Yield chunks from a range in a file. """
2831
2820
fp .seek (offset )
2832
- while bytes > 0 :
2833
- part = fp .read (min (bytes , maxread ))
2821
+ while limit > 0 :
2822
+ part = fp .read (min (limit , bufsize ))
2834
2823
if not part :
2835
2824
break
2836
- bytes -= len (part )
2825
+ limit -= len (part )
2837
2826
yield part
2838
- if close :
2839
- fp .close ()
2840
2827
2841
2828
2842
2829
def static_file (filename , root ,
@@ -2940,9 +2927,10 @@ def static_file(filename, root,
2940
2927
if not ranges :
2941
2928
return HTTPError (416 , "Requested Range Not Satisfiable" )
2942
2929
offset , end = ranges [0 ]
2930
+ rlen = end - offset
2943
2931
headers ["Content-Range" ] = "bytes %d-%d/%d" % (offset , end - 1 , clen )
2944
- headers ["Content-Length" ] = str (end - offset )
2945
- if body : body = _file_iter_range ( body , offset , end - offset , close = True )
2932
+ headers ["Content-Length" ] = str (rlen )
2933
+ if body : body = _closeiter ( _rangeiter ( body , offset , rlen ), body . close )
2946
2934
return HTTPResponse (body , status = 206 , ** headers )
2947
2935
return HTTPResponse (body , ** headers )
2948
2936
@@ -3359,7 +3347,7 @@ def run(self, handler):
3359
3347
3360
3348
3361
3349
class FapwsServer (ServerAdapter ):
3362
- """ Extremely fast webserver using libev. See http ://www.fapws.org/ """
3350
+ """ Extremely fast webserver using libev. See https ://github.com/william-os4y/fapws3 """
3363
3351
3364
3352
def run (self , handler ): # pragma: no cover
3365
3353
depr (0 , 13 , "fapws3 is not maintained and support will be dropped." )
@@ -4276,7 +4264,7 @@ def wrapper(*args, **kwargs):
4276
4264
tplvars .update (result )
4277
4265
return template (tpl_name , ** tplvars )
4278
4266
elif result is None :
4279
- return template (tpl_name , defaults )
4267
+ return template (tpl_name , ** defaults )
4280
4268
return result
4281
4269
4282
4270
return wrapper
0 commit comments