From 5c0a3965cdb9cac87d0b0ea773a6276c73a27ba6 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sun, 29 Mar 2009 17:42:48 +0200 Subject: quite some changes for py3 These changes introduce some compatibility code. They don't make wsgitools usable with Python 3.0, but they also don't break compatibility with Python 2.5. --- wsgitools/adapters.py | 8 +++++++- wsgitools/applications.py | 5 +++++ wsgitools/digest.py | 8 ++++++-- wsgitools/filters.py | 34 ++++++++++++++++++++++------------ wsgitools/middlewares.py | 22 +++++++++++++++------- wsgitools/scgi/asynchronous.py | 13 ++++++++++--- wsgitools/scgi/forkpool.py | 14 ++++++++++---- 7 files changed, 75 insertions(+), 29 deletions(-) diff --git a/wsgitools/adapters.py b/wsgitools/adapters.py index 6f9c203..6c6bbca 100644 --- a/wsgitools/adapters.py +++ b/wsgitools/adapters.py @@ -9,6 +9,12 @@ __all__ = [] from wsgitools.filters import CloseableIterator, CloseableList +try: + next +except NameError: + def next(it): + return it.next() + __all__.append("WSGI2to1Adapter") class WSGI2to1Adapter: """Adapts an application with an interface that might somewhen be known as @@ -57,7 +63,7 @@ class WSGI1to2Adapter: close_function = getattr(iterable, "close", None) iterable = iter(iterable) try: - first = iterable.next() + first = next(iterable) except StopIteration: return (results[0], results[1], CloseableList(close_function, results[2])) diff --git a/wsgitools/applications.py b/wsgitools/applications.py index f90e395..286ab9b 100644 --- a/wsgitools/applications.py +++ b/wsgitools/applications.py @@ -2,6 +2,11 @@ import os.path __all__ = [] +try: + basestring +except NameError: + basestring = str + __all__.append("StaticContent") class StaticContent: """ diff --git a/wsgitools/digest.py b/wsgitools/digest.py index d99f67d..a4d2e4f 100755 --- a/wsgitools/digest.py +++ b/wsgitools/digest.py @@ -10,6 +10,10 @@ except ImportError: import binascii import base64 import time +try: + long +except NameError: + long = int sysrand = random.SystemRandom() @@ -33,7 +37,7 @@ def parse_digest_response(data, ret=dict()): >>> try: ... parse_digest_response('spam') ... except ValueError: - ... print "ValueError" + ... print("ValueError") ValueError """ data = data.strip() @@ -45,7 +49,7 @@ def parse_digest_response(data, ret=dict()): ret[key] = value return ret if rest[0] != ',': - raise ValueError, "invalid digest response" + raise ValueError("invalid digest response") rest = rest[1:] else: if ',' not in rest: diff --git a/wsgitools/filters.py b/wsgitools/filters.py index 5821c00..5b97e27 100644 --- a/wsgitools/filters.py +++ b/wsgitools/filters.py @@ -11,9 +11,18 @@ import sys import time import gzip try: - import cStringIO as StringIO -except ImportError: - import StringIO + import io +except NameError: + try: + import cStringIO as io + except ImportError: + import StringIO as io + +try: + next +except NameError: + def next(it): + return it.next() __all__.append("CloseableIterator") class CloseableIterator: @@ -26,7 +35,7 @@ class CloseableIterator: """ if close_function is not None: self.close = close_function - self.iterators = map(iter, iterators) + self.iterators = list(map(iter, iterators)) def __iter__(self): """iterator interface @rtype: gen() @@ -37,10 +46,10 @@ class CloseableIterator: if not self.iterators: raise StopIteration try: - return self.iterators[0].next() + return next(self.iterators[0]) except StopIteration: self.iterators.pop(0) - return self.next() + return next(self) __all__.append("CloseableList") class CloseableList(list): @@ -165,7 +174,7 @@ class WSGIFilterMiddleware: exc_info = reqfilter.filter_exc_info(exc_info) status = reqfilter.filter_status(status) headers = (reqfilter.filter_header(h, v) for h, v in headers) - headers = filter(None, headers) + headers = [h for h in headers if h] headers = reqfilter.filter_headers(headers) write = start_response(status, headers, exc_info) def modified_write(data): @@ -180,7 +189,8 @@ class WSGIFilterMiddleware: getattr(ret, "close", lambda:0)() if isinstance(ret, list): - return CloseableList(modified_close, map(reqfilter.filter_data, ret) + return CloseableList(modified_close, + list(map(reqfilter.filter_data, ret)) + list(reqfilter.append_data())) ret = iter(ret) def late_append_data(): @@ -257,7 +267,7 @@ class RequestLogWSGIFilter(BaseWSGIFilter): line = '%s "%s"' % (line, self.useragent) else: line += " -" - print >> self.log, line + self.log.write("%s\n", line) __all__.append("TimerWSGIFilter") class TimerWSGIFilter(BaseWSGIFilter): @@ -357,7 +367,7 @@ class GzipWSGIFilter(BaseWSGIFilter): acceptenc = map(str.strip, acceptenc) if "gzip" in acceptenc: self.compress = True - self.sio = StringIO.StringIO() + self.sio = io.StringIO() self.gzip = gzip.GzipFile(fileobj=self.sio, mode="w") return environ def filter_header(self, headername, headervalue): @@ -434,12 +444,12 @@ class ReusableWSGIInputFilter(BaseWSGIFilter): @type environ: {str: str} """ - if isinstance(environ["wsgi.input"], StringIO): + if isinstance(environ["wsgi.input"], io.StringIO): return environ # nothing to be done # XXX: is this really a good idea? use with care environ["wsgitools.oldinput"] = environ["wsgi.input"] - data = StringIO(environ["wsgi.input"].read(self.maxrequestsize)) + data = io.StringIO(environ["wsgi.input"].read(self.maxrequestsize)) environ["wsgi.input"] = data return environ diff --git a/wsgitools/middlewares.py b/wsgitools/middlewares.py index 297e646..38e2e67 100644 --- a/wsgitools/middlewares.py +++ b/wsgitools/middlewares.py @@ -6,9 +6,17 @@ import cgitb import binascii from wsgitools.filters import CloseableList, CloseableIterator try: - import cStringIO as StringIO + import io except ImportError: - import StringIO + try: + import cStringIO as io + except ImportError: + import StringIO as io +try: + next +except NameError: + def next(it): + return it.next() __all__.append("SubdirMiddleware") class SubdirMiddleware: @@ -66,7 +74,7 @@ class NoWriteCallableMiddleware: todo.append(None) return start_response(status, headers, exc_info) else: - sio = StringIO.StringIO() + sio = io.StringIO() todo.append((status, headers, sio)) return sio.write @@ -92,7 +100,7 @@ class NoWriteCallableMiddleware: ret = iter(ret) stopped = False try: - first = ret.next() + first = next(ret) except StopIteration: stopped = True @@ -156,7 +164,7 @@ class ContentLengthMiddleware: data = CloseableList(getattr(ret, "close", None)) length = 0 try: - data.append(ret.next()) # fills todo + data.append(next(ret)) # fills todo length += len(data[-1]) except StopIteration: stopped = True @@ -165,7 +173,7 @@ class ContentLengthMiddleware: while (not stopped) and length < self.maxstore: try: - data.append(ret.next()) + data.append(next(ret)) length += len(data[-1]) except StopIteration: stopped = True @@ -354,7 +362,7 @@ class TracebackMiddleware: # exception there. ret = iter(ret) try: - first = ret.next() + first = next(ret) except StopIteration: return CloseableList(getattr(ret, "close", None), []) return CloseableIterator(getattr(ret, "close", None), [first], ret) diff --git a/wsgitools/scgi/asynchronous.py b/wsgitools/scgi/asynchronous.py index 9fedb87..33d5130 100644 --- a/wsgitools/scgi/asynchronous.py +++ b/wsgitools/scgi/asynchronous.py @@ -4,9 +4,16 @@ import asyncore import socket import sys try: - import cStringIO as StringIO + import io except ImportError: - import StringIO + try: + import cStringIO as io + except ImportError: + import StringIO as io +try: + long +except NameError: + long = int class SCGIConnection(asyncore.dispatcher): """SCGI connection class used by L{SCGIServer}.""" @@ -32,7 +39,7 @@ class SCGIConnection(asyncore.dispatcher): self.wsgihandler = None # wsgi application iterator self.outheaders = () # headers to be sent # () -> unset, (..,..) -> set, True -> sent - self.body = StringIO.StringIO() # request body + self.body = io.StringIO() # request body def _wsgi_headers(self): return {"wsgi.version": (1, 0), diff --git a/wsgitools/scgi/forkpool.py b/wsgitools/scgi/forkpool.py index 26de9ef..b913190 100644 --- a/wsgitools/scgi/forkpool.py +++ b/wsgitools/scgi/forkpool.py @@ -11,6 +11,11 @@ import select import sys import errno +try: + long +except NameError: + long = int + class SocketFileWrapper: """Wraps a socket to a wsgi-compliant file-like object.""" def __init__(self, sock, toread): @@ -153,7 +158,8 @@ class SocketFileWrapper: return def writelines(self, lines): """see pep333""" - map(self.write, lines) + for line in lines: + self.write(line) class SCGIServer: """Usage: create an L{SCGIServer} object and invoke the run method which @@ -228,7 +234,7 @@ class SCGIServer: elif data in ('0', '1'): self.workers[s].state = int(data) else: - raise RuntimeError, "unexpected data from worker" + raise RuntimeError("unexpected data from worker") try: pid = 1 while pid > 0: @@ -263,7 +269,7 @@ class SCGIServer: self.workers[srvsock.fileno()] = SCGIServer.\ WorkerState(pid, srvsock, 0) else: - raise RuntimeError, "fork failed" + raise RuntimeError("fork failed") def work(self, worksock): """ @@ -299,7 +305,7 @@ class SCGIServer: if not length.isdigit(): # clear protocol violation con.close() return - length = long(length) + length = int(length) while len(data) != length + 1: # read one byte beyond try: -- cgit v1.2.3