@@ -69,12 +69,12 @@ def _cli_patch(cli_args): # pragma: no coverage
6969# Imports and Python 2/3 unification ##########################################
7070###############################################################################
7171
72- import base64 , calendar , cgi , email .utils , functools , hmac , imp , itertools ,\
72+ import base64 , calendar , cgi , email .utils , functools , hmac , itertools ,\
7373 mimetypes , os , re , tempfile , threading , time , warnings , weakref , hashlib
7474
7575from types import FunctionType
7676from datetime import date as datedate , datetime , timedelta
77- from tempfile import TemporaryFile
77+ from tempfile import NamedTemporaryFile
7878from traceback import format_exc , print_exc
7979from unicodedata import normalize
8080
@@ -83,34 +83,6 @@ def _cli_patch(cli_args): # pragma: no coverage
8383except ImportError :
8484 from json import dumps as json_dumps , loads as json_lds
8585
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-
11486py = sys .version_info
11587py3k = py .major > 2
11688
@@ -123,9 +95,17 @@ def getargspec(func):
12395 urlunquote = functools .partial (urlunquote , encoding = 'latin1' )
12496 from http .cookies import SimpleCookie , Morsel , CookieError
12597 from collections .abc import MutableMapping as DictMixin
98+ from types import ModuleType as new_module
12699 import pickle
127100 from io import BytesIO
128101 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 ]
129109
130110 basestring = str
131111 unicode = str
@@ -143,9 +123,12 @@ def _raise(*a):
143123 from Cookie import SimpleCookie , Morsel , CookieError
144124 from itertools import imap
145125 import cPickle as pickle
126+ from imp import new_module
146127 from StringIO import StringIO as BytesIO
147128 import ConfigParser as configparser
148129 from collections import MutableMapping as DictMixin
130+ from inspect import getargspec
131+
149132 unicode = unicode
150133 json_loads = json_lds
151134 exec (compile ('def _raise(*a): raise a[0], a[1], a[2]' , '<py3fix>' , 'exec' ))
@@ -256,6 +239,7 @@ def __get__(self, obj, cls):
256239 setattr (cls , self .__name__ , value )
257240 return value
258241
242+
259243###############################################################################
260244# Exceptions and Events #######################################################
261245###############################################################################
@@ -1353,7 +1337,7 @@ def _body(self):
13531337 body .write (part )
13541338 body_size += len (part )
13551339 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
13571341 body .write (tmp .getvalue ())
13581342 del tmp
13591343 is_temp_file = True
@@ -2010,6 +1994,7 @@ def apply(self, callback, route):
20101994 dumps = self .json_dumps
20111995 if not self .json_dumps : return callback
20121996
1997+ @functools .wraps (callback )
20131998 def wrapper (* a , ** ka ):
20141999 try :
20152000 rv = callback (* a , ** ka )
@@ -2057,7 +2042,7 @@ def __init__(self, name, impmask):
20572042 """ Create a virtual package that redirects imports (see PEP 302). """
20582043 self .name = name
20592044 self .impmask = impmask
2060- self .module = sys .modules .setdefault (name , imp . new_module (name ))
2045+ self .module = sys .modules .setdefault (name , new_module (name ))
20612046 self .module .__dict__ .update ({
20622047 '__file__' : __file__ ,
20632048 '__path__' : [],
@@ -2066,10 +2051,15 @@ def __init__(self, name, impmask):
20662051 })
20672052 sys .meta_path .append (self )
20682053
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+
20692060 def find_module (self , fullname , path = None ):
20702061 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
20732063 return self
20742064
20752065 def load_module (self , fullname ):
@@ -2825,18 +2815,15 @@ def redirect(url, code=None):
28252815 raise res
28262816
28272817
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. """
28312820 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 ))
28342823 if not part :
28352824 break
2836- bytes -= len (part )
2825+ limit -= len (part )
28372826 yield part
2838- if close :
2839- fp .close ()
28402827
28412828
28422829def static_file (filename , root ,
@@ -2940,9 +2927,10 @@ def static_file(filename, root,
29402927 if not ranges :
29412928 return HTTPError (416 , "Requested Range Not Satisfiable" )
29422929 offset , end = ranges [0 ]
2930+ rlen = end - offset
29432931 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 )
29462934 return HTTPResponse (body , status = 206 , ** headers )
29472935 return HTTPResponse (body , ** headers )
29482936
@@ -3359,7 +3347,7 @@ def run(self, handler):
33593347
33603348
33613349class 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 """
33633351
33643352 def run (self , handler ): # pragma: no cover
33653353 depr (0 , 13 , "fapws3 is not maintained and support will be dropped." )
@@ -4276,7 +4264,7 @@ def wrapper(*args, **kwargs):
42764264 tplvars .update (result )
42774265 return template (tpl_name , ** tplvars )
42784266 elif result is None :
4279- return template (tpl_name , defaults )
4267+ return template (tpl_name , ** defaults )
42804268 return result
42814269
42824270 return wrapper
0 commit comments