diff options
Diffstat (limited to 'wsgitools')
-rw-r--r-- | wsgitools/applications.py | 19 | ||||
-rw-r--r-- | wsgitools/authentication.py | 2 | ||||
-rw-r--r-- | wsgitools/digest.py | 9 | ||||
-rw-r--r-- | wsgitools/filters.py | 11 | ||||
-rw-r--r-- | wsgitools/internal.py | 30 | ||||
-rw-r--r-- | wsgitools/middlewares.py | 28 | ||||
-rw-r--r-- | wsgitools/scgi/__init__.py | 4 | ||||
-rw-r--r-- | wsgitools/scgi/asynchronous.py | 9 | ||||
-rw-r--r-- | wsgitools/scgi/forkpool.py | 22 |
9 files changed, 45 insertions, 89 deletions
diff --git a/wsgitools/applications.py b/wsgitools/applications.py index df304db..9894cf8 100644 --- a/wsgitools/applications.py +++ b/wsgitools/applications.py @@ -2,13 +2,8 @@ import os.path __all__ = [] -try: - basestring -except NameError: - basestring = str - __all__.append("StaticContent") -class StaticContent(object): +class StaticContent: """ This wsgi application provides static content on whatever request it receives with method GET or HEAD (content stripped). If not present, a @@ -60,7 +55,7 @@ class StaticContent(object): return self.content __all__.append("StaticFile") -class StaticFile(object): +class StaticFile: """ This wsgi application provides the content of a static file on whatever request it receives with method GET or HEAD (content stripped). If not @@ -94,7 +89,7 @@ class StaticFile(object): if not data: break yield data - if isinstance(self.filelike, basestring): + if isinstance(self.filelike, str): stream.close() def __call__(self, environ, start_response): @@ -110,7 +105,7 @@ class StaticFile(object): stream = None size = -1 try: - if isinstance(self.filelike, basestring): + if isinstance(self.filelike, str): # raises IOError stream = open(self.filelike, "rb") size = os.path.getsize(self.filelike) @@ -133,16 +128,16 @@ class StaticFile(object): start_response(self.status, headers) if environ["REQUEST_METHOD"].upper() == "HEAD": - if isinstance(self.filelike, basestring): + if isinstance(self.filelike, str): stream.close() return [] - if isinstance(self.filelike, basestring) and 'wsgi.file_wrapper' in environ: + if isinstance(self.filelike, str) and 'wsgi.file_wrapper' in environ: return environ['wsgi.file_wrapper'](stream, self.blocksize) if 0 <= size <= self.blocksize: data = stream.read(size) - if isinstance(self.filelike, basestring): + if isinstance(self.filelike, str): stream.close() return [data] return self._serve_in_chunks(stream) diff --git a/wsgitools/authentication.py b/wsgitools/authentication.py index 59747e0..c076d7f 100644 --- a/wsgitools/authentication.py +++ b/wsgitools/authentication.py @@ -9,7 +9,7 @@ class AuthenticationRequired(Exception): class ProtocolViolation(AuthenticationRequired): pass -class AuthenticationMiddleware(object): +class AuthenticationMiddleware: """Base class for HTTP authorization schemes. @cvar authorization_method: the implemented Authorization method. It will diff --git a/wsgitools/digest.py b/wsgitools/digest.py index 5b101e5..6eb4cb3 100644 --- a/wsgitools/digest.py +++ b/wsgitools/digest.py @@ -47,8 +47,7 @@ def gen_rand_str(bytesentropy=33): True """ randnum = randbits(bytesentropy*8) - randstr = ("%%0%dX" % (2*bytesentropy)) % randnum - randbytes = str2bytes(randstr) + randbytes = (b"%%0%dX" % (2*bytesentropy)) % randnum randbytes = base64.b16decode(randbytes) randbytes = base64.b64encode(randbytes) randstr = bytes2str(randbytes) @@ -146,7 +145,7 @@ class StaleNonce(AuthenticationRequired): pass __all__.append("AbstractTokenGenerator") -class AbstractTokenGenerator(object): +class AbstractTokenGenerator: """Interface class for generating authentication tokens for L{AuthDigestMiddleware}. @@ -300,7 +299,7 @@ class UpdatingHtdigestTokenGenerator(HtdigestTokenGenerator): return HtdigestTokenGenerator.__call__(self, user, algo) __all__.append("NonceStoreBase") -class NonceStoreBase(object): +class NonceStoreBase: """Nonce storage interface.""" def __init__(self): pass @@ -516,7 +515,7 @@ class MemoryNonceStore(NonceStoreBase): return True __all__.append("LazyDBAPI2Opener") -class LazyDBAPI2Opener(object): +class LazyDBAPI2Opener: """ Connects to database on first request. Otherwise it behaves like a dbapi2 connection. This may be usefull in combination with L{scgi.forkpool}, diff --git a/wsgitools/filters.py b/wsgitools/filters.py index 2a97066..7f8543d 100644 --- a/wsgitools/filters.py +++ b/wsgitools/filters.py @@ -15,7 +15,7 @@ import io from wsgitools.internal import str2bytes __all__.append("CloseableIterator") -class CloseableIterator(object): +class CloseableIterator: """Concatenating iterator with close attribute.""" def __init__(self, close_function, *iterators): """If close_function is not C{None}, it will be the C{close} attribute @@ -40,8 +40,7 @@ class CloseableIterator(object): except StopIteration: self.iterators.pop(0) return next(self) - def next(self): - return self.__next__() + __all__.append("CloseableList") class CloseableList(list): @@ -61,7 +60,7 @@ class CloseableList(list): list.__iter__(self)) __all__.append("BaseWSGIFilter") -class BaseWSGIFilter(object): +class BaseWSGIFilter: """Generic WSGI filter class to be used with L{WSGIFilterMiddleware}. For each request a filter object gets created. @@ -138,7 +137,7 @@ class BaseWSGIFilter(object): """This method is invoked after the request has finished.""" __all__.append("WSGIFilterMiddleware") -class WSGIFilterMiddleware(object): +class WSGIFilterMiddleware: """This wsgi middleware can be used with specialized L{BaseWSGIFilter}s to modify wsgi requests and/or reponses.""" def __init__(self, app, filterclass): @@ -322,7 +321,7 @@ class TimerWSGIFilter(BaseWSGIFilter): @rtype: bytes """ if data == self.pattern: - return str2bytes("%8.3g" % (time.time() - self.start)) + return b"%8.3g" % (time.time() - self.start) return data __all__.append("EncodeWSGIFilter") diff --git a/wsgitools/internal.py b/wsgitools/internal.py index c4f1da1..9bf7ded 100644 --- a/wsgitools/internal.py +++ b/wsgitools/internal.py @@ -1,19 +1,11 @@ -if bytes is str: - def bytes2str(bstr): - assert isinstance(bstr, bytes) - return bstr - def str2bytes(sstr): - assert isinstance(sstr, str) - return sstr - def textopen(filename, mode): - return open(filename, mode) -else: - def bytes2str(bstr): - assert isinstance(bstr, bytes) - return bstr.decode("iso-8859-1") # always successful - def str2bytes(sstr): - assert isinstance(sstr, str) - return sstr.encode("iso-8859-1") # might fail, but spec says it doesn't - def textopen(filename, mode): - # We use the same encoding as for all wsgi strings here. - return open(filename, mode, encoding="iso-8859-1") +def bytes2str(bstr): + assert isinstance(bstr, bytes) + return bstr.decode("iso-8859-1") # always successful + +def str2bytes(sstr): + assert isinstance(sstr, str) + return sstr.encode("iso-8859-1") # might fail, but spec says it doesn't + +def textopen(filename, mode): + # We use the same encoding as for all wsgi strings here. + return open(filename, mode, encoding="iso-8859-1") diff --git a/wsgitools/middlewares.py b/wsgitools/middlewares.py index 32ecb59..ef9fe84 100644 --- a/wsgitools/middlewares.py +++ b/wsgitools/middlewares.py @@ -8,20 +8,12 @@ import collections import io from wsgitools.internal import bytes2str, str2bytes - -if sys.version_info[0] >= 3: - def exc_info_for_raise(exc_info): - return exc_info[1].with_traceback(exc_info[2]) -else: - def exc_info_for_raise(exc_info): - return exc_info[0], exc_info[1], exc_info[2] - from wsgitools.filters import CloseableList, CloseableIterator from wsgitools.authentication import AuthenticationRequired, \ ProtocolViolation, AuthenticationMiddleware __all__.append("SubdirMiddleware") -class SubdirMiddleware(object): +class SubdirMiddleware: """Middleware choosing wsgi applications based on a dict.""" def __init__(self, default, mapping={}): """ @@ -54,7 +46,7 @@ class SubdirMiddleware(object): return app(environ, start_response) __all__.append("NoWriteCallableMiddleware") -class NoWriteCallableMiddleware(object): +class NoWriteCallableMiddleware: """This middleware wraps a wsgi application that needs the return value of C{start_response} function to a wsgi application that doesn't need one by writing the data to a C{BytesIO} and then making it be the first result @@ -78,7 +70,7 @@ class NoWriteCallableMiddleware(object): try: if sio.tell() > 0 or gotiterdata: assert exc_info is not None - raise exc_info_for_raise(exc_info) + raise exc_info[1].with_traceback(exc_info[2]) finally: exc_info = None assert isinstance(status, str) @@ -121,7 +113,7 @@ class NoWriteCallableMiddleware(object): (data,), ret) __all__.append("ContentLengthMiddleware") -class ContentLengthMiddleware(object): +class ContentLengthMiddleware: """Guesses the content length header if possible. @note: The application used must not use the C{write} callable returned by C{start_response}.""" @@ -149,7 +141,7 @@ class ContentLengthMiddleware(object): try: if gotdata: assert exc_info is not None - raise exc_info_for_raise(exc_info) + raise exc_info[1].with_traceback(exc_info[2]) finally: exc_info = None assert isinstance(status, str) @@ -216,11 +208,11 @@ def cacheable(environ): return True __all__.append("CachingMiddleware") -class CachingMiddleware(object): +class CachingMiddleware: """Caches reponses to requests based on C{SCRIPT_NAME}, C{PATH_INFO} and C{QUERY_STRING}.""" - class CachedRequest(object): + class CachedRequest: def __init__(self, timestamp): self.timestamp = timestamp self.status = "" @@ -291,7 +283,7 @@ class CachingMiddleware(object): try: if cache_object.body: assert exc_info is not None - raise exc_info_for_raise(exc_info) + raise exc_info[1].with_traceback(exc_info[2]) finally: exc_info = None assert isinstance(status, str) @@ -319,7 +311,7 @@ class CachingMiddleware(object): return CloseableIterator(getattr(ret, "close", None), pass_through()) __all__.append("DictAuthChecker") -class DictAuthChecker(object): +class DictAuthChecker: """Verifies usernames and passwords by looking them up in a dict.""" def __init__(self, users): """ @@ -390,7 +382,7 @@ class BasicAuthMiddleware(AuthenticationMiddleware): self, environ, start_response, exception) __all__.append("TracebackMiddleware") -class TracebackMiddleware(object): +class TracebackMiddleware: """In case the application throws an exception this middleware will show an html-formatted traceback using C{cgitb}.""" def __init__(self, app): diff --git a/wsgitools/scgi/__init__.py b/wsgitools/scgi/__init__.py index f651264..e2a68c2 100644 --- a/wsgitools/scgi/__init__.py +++ b/wsgitools/scgi/__init__.py @@ -7,7 +7,7 @@ except ImportError: else: have_sendfile = True -class FileWrapper(object): +class FileWrapper: """ @ivar offset: Initially 0. Becomes -1 when reading using next and becomes positive when reading using next. In the latter case it @@ -52,8 +52,6 @@ class FileWrapper(object): if data: return data raise StopIteration - def next(self): - return self.__next__() def _convert_environ(environ, multithread=False, multiprocess=False, run_once=False): diff --git a/wsgitools/scgi/asynchronous.py b/wsgitools/scgi/asynchronous.py index 0b014bf..61bbc6b 100644 --- a/wsgitools/scgi/asynchronous.py +++ b/wsgitools/scgi/asynchronous.py @@ -9,13 +9,6 @@ import errno from wsgitools.internal import bytes2str, str2bytes from wsgitools.scgi import _convert_environ, FileWrapper -if sys.version_info[0] >= 3: - def exc_info_for_raise(exc_info): - return exc_info[1].with_traceback(exc_info[2]) -else: - def exc_info_for_raise(exc_info): - return exc_info[0], exc_info[1], exc_info[2] - class SCGIConnection(asyncore.dispatcher): """SCGI connection class used by L{SCGIServer}.""" # connection states @@ -147,7 +140,7 @@ class SCGIConnection(asyncore.dispatcher): if exc_info: if self.outheaders == True: try: - raise exc_info_for_raise(exc_info) + raise exc_info[1].with_traceback(exc_info[2]) finally: exc_info = None assert self.outheaders != True # unsent diff --git a/wsgitools/scgi/forkpool.py b/wsgitools/scgi/forkpool.py index 752f0e7..df8a92f 100644 --- a/wsgitools/scgi/forkpool.py +++ b/wsgitools/scgi/forkpool.py @@ -5,10 +5,7 @@ It works with multiple processes that are periodically cleaned up to prevent memory leaks having an impact to the system. """ -try: - import resource -except ImportError: - resource = None +import resource import socket import os import select @@ -19,16 +16,9 @@ import signal from wsgitools.internal import bytes2str, str2bytes from wsgitools.scgi import _convert_environ, FileWrapper -if sys.version_info[0] >= 3: - def exc_info_for_raise(exc_info): - return exc_info[1].with_traceback(exc_info[2]) -else: - def exc_info_for_raise(exc_info): - return exc_info[0], exc_info[1], exc_info[2] - __all__ = [] -class SocketFileWrapper(object): +class SocketFileWrapper: """Wraps a socket to a wsgi-compliant file-like object.""" def __init__(self, sock, toread): """@param sock: is a C{socket.socket()}""" @@ -149,8 +139,6 @@ class SocketFileWrapper(object): if not data: raise StopIteration return data - def next(self): - return self.__next__() def flush(self): """see pep333""" def write(self, data): @@ -167,10 +155,10 @@ class SocketFileWrapper(object): self.write(line) __all__.append("SCGIServer") -class SCGIServer(object): +class SCGIServer: """Usage: create an L{SCGIServer} object and invoke the run method which will then turn this process into an scgi server.""" - class WorkerState(object): + class WorkerState: """state: 0 means idle and 1 means working. These values are also sent as strings '0' and '1' over the socket.""" def __init__(self, pid, sock, state): @@ -472,7 +460,7 @@ class SCGIServer(object): def start_response(status, headers, exc_info=None): if exc_info and response_head[0]: try: - raise exc_info_for_raise(exc_info) + raise exc_info[1].with_traceback(exc_info[2]) finally: exc_info = None assert isinstance(status, str) |