From: Fredrik Tolf Date: Wed, 22 Mar 2017 04:40:43 +0000 (+0100) Subject: Merge branch 'master' into python2 X-Git-Url: http://dolda2000.com/gitweb/?p=wrw.git;a=commitdiff_plain;h=bdc80241ffb5b50b1c9fb6500778e97b3f7170e6;hp=15dfd641773374daefdcffe73bc1b56b6bab0b7b Merge branch 'master' into python2 --- diff --git a/setup.py b/setup.py index d8eb073..3775c63 100755 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/python from distutils.core import setup, Extension diff --git a/wrw/__init__.py b/wrw/__init__.py index eb4a0a0..95ff4cd 100644 --- a/wrw/__init__.py +++ b/wrw/__init__.py @@ -1,7 +1,7 @@ __all__ = ["wsgiwrap", "restart", "cookie", "formdata"] -from . import proto -from .util import wsgiwrap, stringwrap, formparams, funplex, persession, sessiondata, autodirty, manudirty, specdirty -from .dispatch import restart -from . import cookie -from .form import formdata +import proto +from util import wsgiwrap, formparams, funplex, persession, sessiondata, autodirty, manudirty, specdirty +from dispatch import restart +import cookie +from form import formdata diff --git a/wrw/auth.py b/wrw/auth.py index 27e2a98..bb0e0cd 100644 --- a/wrw/auth.py +++ b/wrw/auth.py @@ -1,9 +1,9 @@ import binascii, hashlib, threading, time -from . import resp, proto +import resp, proto class unauthorized(resp.httperror): def __init__(self, challenge, message=None, detail=None): - super().__init__(401, message, detail) + super(unauthorized, self).__init__(401, message, detail) if isinstance(challenge, str): challenge = [challenge] self.challenge = challenge @@ -11,11 +11,11 @@ class unauthorized(resp.httperror): def handle(self, req): for challenge in self.challenge: req.ohead.add("WWW-Authenticate", challenge) - return super().handle(req) + return super(unauthorized, self).handle(req) class forbidden(resp.httperror): def __init__(self, message=None, detail=None): - super().__init__(403, message, detail) + super(forbidden, self).__init__(403, message, detail) def parsemech(req): h = req.ihead.get("Authorization", None) @@ -34,10 +34,6 @@ def parsebasic(req): raw = proto.unb64(data) except binascii.Error: return None, None - try: - raw = raw.decode("utf-8") - except UnicodeError: - raw = raw.decode("latin1") p = raw.find(":") if p < 0: return None, None @@ -55,9 +51,9 @@ class basiccache(object): def _obscure(self, nm, pw): dig = hashlib.sha256() - dig.update(self.realm.encode("utf-8")) - dig.update(nm.encode("utf-8")) - dig.update(pw.encode("utf-8")) + dig.update(self.realm) + dig.update(nm) + dig.update(pw) return dig.digest() def check(self, req): @@ -80,7 +76,7 @@ class basiccache(object): with lock: try: ret = self.auth(req, nm, pw) - except forbidden as exc: + except forbidden, exc: with self._lock: self._cache[nm, pwh] = (lock, now, "f", exc) raise diff --git a/wrw/cookie.py b/wrw/cookie.py index c6e848f..140ba8f 100644 --- a/wrw/cookie.py +++ b/wrw/cookie.py @@ -1,5 +1,5 @@ -import http.cookies, time -from . import proto +import Cookie, time +import proto __all__ = ["cookies", "get", "add"] @@ -11,10 +11,10 @@ def addcookies(req): class cookiedict(object): def __init__(self, req): try: - self.bk = http.cookies.SimpleCookie(req.ihead.get("Cookie")) - except http.cookies.CookieError: - self.bk = http.cookies.SimpleCookie() - self.codec = http.cookies.SimpleCookie() + self.bk = Cookie.SimpleCookie(req.ihead.get("Cookie")) + except Cookie.CookieError: + self.bk = Cookie.SimpleCookie() + self.codec = Cookie.SimpleCookie() req.oncommit(addcookies) def __getitem__(self, name): @@ -30,7 +30,7 @@ class cookiedict(object): def add(self, name, value, **kw): self.codec[name] = value - for key, value in kw.items(): + for key, value in kw.iteritems(): self.codec[name][key] = value def __setitem__(self, name, value): diff --git a/wrw/dispatch.py b/wrw/dispatch.py index 2c97b9f..666d7a7 100644 --- a/wrw/dispatch.py +++ b/wrw/dispatch.py @@ -1,5 +1,5 @@ import sys, traceback -from . import env, req, proto +import env, req, proto __all__ = ["restart"] @@ -17,7 +17,7 @@ def mangle(result): return [str(result)] def defaulterror(req, excinfo): - from . import resp + import resp traceback.print_exception(*excinfo) sys.stderr.flush() raise resp.httperror(500) @@ -38,9 +38,9 @@ def handle(req, startreq, handler): try: resp = handler(req) break - except restart as i: + except restart, i: handler = i.handle - except Exception as i: + except Exception, i: if eh is None: raise handler = wraphandler(eh, sys.exc_info()) @@ -58,7 +58,7 @@ def handleenv(env, startreq, handler): def exterror(env, startreq): def handler(req): - from . import resp + import resp code = 404 if "Response-Code" in req.ihead: try: diff --git a/wrw/filesys.py b/wrw/filesys.py index 56d58aa..dcdc802 100644 --- a/wrw/filesys.py +++ b/wrw/filesys.py @@ -1,5 +1,5 @@ import os -from . import resp +import resp pj = os.path.join __all__ = ["filehandler"] @@ -29,7 +29,7 @@ class filehandler(object): elif ext == "html": ctype = "text/html" req.ohead["Content-Type"] = ctype - return open(path, "rb") + return open(path, "r") def resolvefile(self, req, curpath, el): if os.path.isfile(pj(curpath, el)): diff --git a/wrw/form.py b/wrw/form.py index 7905dc6..76abab6 100644 --- a/wrw/form.py +++ b/wrw/form.py @@ -1,11 +1,11 @@ -import urllib.parse -from . import proto +import urlparse +import proto __all__ = ["formdata"] def formparse(req): buf = {} - buf.update(urllib.parse.parse_qsl(req.query)) + buf.update(urlparse.parse_qsl(req.query)) if req.ihead.get("Content-Type") == "application/x-www-form-urlencoded": try: rbody = req.input.read(2 ** 20) @@ -13,7 +13,7 @@ def formparse(req): return exc if len(rbody) >= 2 ** 20: return ValueError("x-www-form-urlencoded data is absurdly long") - buf.update(urllib.parse.parse_qsl(rbody.decode("latin1"))) + buf.update(urlparse.parse_qsl(rbody)) return buf class badmultipart(Exception): @@ -22,7 +22,7 @@ class badmultipart(Exception): class formpart(object): def __init__(self, form): self.form = form - self.buf = b"" + self.buf = "" self.eof = False self.head = {} @@ -31,8 +31,8 @@ class formpart(object): def fillbuf(self, sz): req = self.form.req - mboundary = b"\r\n--" + self.form.boundary + b"\r\n" - lboundary = b"\r\n--" + self.form.boundary + b"--\r\n" + mboundary = "\r\n--" + self.form.boundary + "\r\n" + lboundary = "\r\n--" + self.form.boundary + "--\r\n" while not self.eof: p = self.form.buf.find(mboundary) if p >= 0: @@ -53,7 +53,7 @@ class formpart(object): break while len(self.form.buf) <= len(lboundary): ret = req.input.read(8192) - if ret == b"": + if ret == "": raise badmultipart("Missing last multipart boundary") self.form.buf += ret @@ -64,17 +64,17 @@ class formpart(object): self.buf = self.buf[limit:] else: ret = self.buf - self.buf = b"" + self.buf = "" return ret def readline(self, limit=-1): last = 0 while True: - p = self.buf.find(b'\n', last) + p = self.buf.find('\n', last) if p < 0: if self.eof: ret = self.buf - self.buf = b"" + self.buf = "" return ret last = len(self.buf) self.fillbuf(last + 128) @@ -85,7 +85,7 @@ class formpart(object): def close(self): while True: - if self.read(8192) == b"": + if self.read(8192) == "": break def __enter__(self): @@ -95,15 +95,12 @@ class formpart(object): self.close() return False - def parsehead(self, charset): + def parsehead(self): def headline(): ln = self.readline(256) - if ln[-1] != ord(b'\n'): + if ln[-1] != '\n': raise badmultipart("Too long header line in part") - try: - return ln.decode(charset).rstrip() - except UnicodeError: - raise badmultipart("Form part header is not in assumed charset") + return ln.rstrip() ln = headline() while True: @@ -135,33 +132,29 @@ class formpart(object): raise badmultipart("Form part uses unexpected transfer encoding: %r" % encoding) class multipart(object): - def __init__(self, req, charset): + def __init__(self, req): val, par = proto.pmimehead(req.ihead.get("Content-Type", "")) if req.method != "POST" or val != "multipart/form-data": raise badmultipart("Request is not a multipart form") if "boundary" not in par: raise badmultipart("Multipart form lacks boundary") - try: - self.boundary = par["boundary"].encode("us-ascii") - except UnicodeError: - raise badmultipart("Multipart boundary must be ASCII string") + self.boundary = par["boundary"] self.req = req - self.buf = b"\r\n" + self.buf = "\r\n" self.eof = False - self.headcs = charset self.lastpart = formpart(self) self.lastpart.close() def __iter__(self): return self - def __next__(self): + def next(self): if not self.lastpart.eof: raise RuntimeError("All form parts must be read entirely") if self.eof: raise StopIteration() self.lastpart = formpart(self) - self.lastpart.parsehead(self.headcs) + self.lastpart.parsehead() return self.lastpart def formdata(req, onerror=Exception): diff --git a/wrw/proto.py b/wrw/proto.py index 628bfc9..7cb6d31 100644 --- a/wrw/proto.py +++ b/wrw/proto.py @@ -98,20 +98,19 @@ def simpleerror(env, startreq, code, title, msg): """ % (title, title, htmlq(msg)) - buf = buf.encode("us-ascii") startreq("%i %s" % (code, title), [("Content-Type", "text/html"), ("Content-Length", str(len(buf)))]) return [buf] def urlq(url): - if isinstance(url, str): + if isinstance(url, unicode): url = url.encode("utf-8") ret = "" - invalid = b"%;&=#?/\"'" + invalid = "%;&=#?/\"'" for c in url: - if c in invalid or (c <= 32) or (c >= 128): - ret += "%%%02X" % c + if c in invalid or (ord(c) <= 32) or (ord(c) >= 128): + ret += "%%%02X" % ord(c) else: - ret += chr(c) + ret += c return ret class urlerror(ValueError): @@ -198,34 +197,19 @@ def parurl(url, pars={}, **augment): # Wrap these, since binascii is a bit funky. :P def enhex(bs): - return base64.b16encode(bs).decode("us-ascii") + return base64.b16encode(bs) def unhex(es): - if not isinstance(es, collections.ByteString): - try: - es = es.encode("us-ascii") - except UnicodeError: - raise binascii.Error("non-ascii character in hex-string") return base64.b16decode(es) def enb32(bs): - return base64.b32encode(bs).decode("us-ascii") + return base64.b32encode(bs) def unb32(es): - if not isinstance(es, collections.ByteString): - try: - es = es.encode("us-ascii") - except UnicodeError: - raise binascii.Error("non-ascii character in base32-string") if (len(es) % 8) != 0: es += b"=" * (8 - (len(es) % 8)) es = es.upper() # The whole point of Base32 is that it's case-insensitive :P return base64.b32decode(es) def enb64(bs): - return base64.b64encode(bs).decode("us-ascii") + return base64.b64encode(bs) def unb64(es): - if not isinstance(es, collections.ByteString): - try: - es = es.encode("us-ascii") - except UnicodeError: - raise binascii.Error("non-ascii character in base64-string") if (len(es) % 4) != 0: es += b"=" * (4 - (len(es) % 4)) return base64.b64decode(es) diff --git a/wrw/req.py b/wrw/req.py index b08afae..ebc3fd8 100644 --- a/wrw/req.py +++ b/wrw/req.py @@ -19,7 +19,7 @@ class headdict(object): del self.dict[key.lower()] def __iter__(self): - return iter((list[0] for list in self.dict.values())) + return iter((list[0] for list in self.dict.itervalues())) def get(self, key, default=""): if key.lower() in self.dict: @@ -67,29 +67,29 @@ class limitreader(object): ra = min(ra, size) while len(self.buf) < ra: ret = self.bk.read(ra - len(self.buf)) - if ret == b"": + if ret == "": raise IOError("Unexpected EOF") self.buf.extend(ret) self.rb += len(ret) - ret = bytes(self.buf[:ra]) + ret = str(self.buf[:ra]) self.buf = self.buf[ra:] return ret def readline(self, size=-1): off = 0 while True: - p = self.buf.find(b'\n', off) + p = self.buf.find('\n', off) if p >= 0: - ret = bytes(self.buf[:p + 1]) + ret = str(self.buf[:p + 1]) self.buf = self.buf[p + 1:] return ret off = len(self.buf) if size >= 0 and len(self.buf) >= size: - ret = bytes(self.buf[:size]) + ret = str(self.buf[:size]) self.buf = self.buf[size:] return ret if self.rb == self.limit: - ret = bytes(self.buf) + ret = str(self.buf) self.buf = bytearray() return ret ra = self.limit - self.rb @@ -97,7 +97,7 @@ class limitreader(object): ra = min(ra, size) ra = min(ra, 1024) ret = self.bk.read(ra) - if ret == b"": + if ret == "": raise IOError("Unpexpected EOF") self.buf.extend(ret) self.rb += len(ret) @@ -109,9 +109,9 @@ class limitreader(object): class lineiter(object): def __iter__(self): return self - def __next__(self): + def next(self): ret = rd.readline() - if ret == b"": + if ret == "": raise StopIteration() return ret return lineiter() @@ -148,7 +148,7 @@ class origrequest(request): self.input = limitreader(env["wsgi.input"], int(clen)) else: # XXX: What to do? - self.input = io.BytesIO(b"") + self.input = io.BytesIO("") else: # Assume input is chunked and read until ordinary EOF. self.input = env["wsgi.input"] diff --git a/wrw/resp.py b/wrw/resp.py index 965df6c..7fae787 100644 --- a/wrw/resp.py +++ b/wrw/resp.py @@ -1,5 +1,5 @@ -from . import dispatch, proto, env -from .sp import xhtml +import dispatch, proto, env +from sp import xhtml h = xhtml.cons() __all__ = ["skeleton", "skelfor", "setskel", "usererror"] @@ -28,7 +28,7 @@ def setskel(req, skel): class usererror(dispatch.restart): def __init__(self, message, *detail): - super().__init__() + super(usererror, self).__init__() self.message = message self.detail = detail @@ -36,9 +36,9 @@ class usererror(dispatch.restart): return skelfor(req).error(req, self.message, *self.detail) class message(dispatch.restart): - def __init__(self, message, *detail): - super().__init__() - self.message = message + def __init__(self, msg, *detail): + super(message, self).__init__() + self.message = msg self.detail = detail def handle(self, req): @@ -50,16 +50,16 @@ class httperror(usererror): message = proto.statusinfo[status][0] if detail is None: detail = (proto.statusinfo[status][1],) - super().__init__(message, *detail) + super(httperror, self).__init__(message, *detail) self.status = status def handle(self, req): req.status(self.status, self.message) - return super().handle(req) + return super(httperror, self).handle(req) class notfound(httperror): def __init__(self): - return super().__init__(404) + return super(notfound, self).__init__(404) class redirect(dispatch.restart): bases = {"url": proto.requrl, @@ -67,7 +67,7 @@ class redirect(dispatch.restart): "site": proto.siteurl} def __init__(self, url, status=303, base="url"): - super().__init__() + super(redirect, self).__init__() self.url = url self.status = status self.bases[base] diff --git a/wrw/session.py b/wrw/session.py index 8141827..476113a 100644 --- a/wrw/session.py +++ b/wrw/session.py @@ -1,5 +1,9 @@ import threading, time, pickle, random, os +<<<<<<< HEAD +import cookie, env +======= from . import cookie, env, proto +>>>>>>> master __all__ = ["db", "get"] @@ -77,7 +81,7 @@ class db(object): def clean(self): now = int(time.time()) with self.lock: - clist = list(self.live.keys()) + clist = self.live.keys() for sessid in clist: with self.lock: try: @@ -195,7 +199,7 @@ class db(object): data = self.backdb[sessid] try: return pickle.loads(data) - except: + except Exception, e: raise KeyError() def freeze(self, sess): diff --git a/wrw/sp/cons.py b/wrw/sp/cons.py index d8b30a8..1cc93ea 100644 --- a/wrw/sp/cons.py +++ b/wrw/sp/cons.py @@ -4,18 +4,18 @@ import xml.dom.minidom class node(object): pass -class text(node, str): +class text(node, unicode): def __todom__(self, doc): return doc.createTextNode(self) -class raw(node, str): +class raw(node, unicode): def __todom__(self, doc): raise Exception("Cannot convert raw code to DOM objects") class element(node): def __init__(self, ns, name, ctx): self.ns = ns - self.name = str(name) + self.name = unicode(name) self.ctx = ctx self.attrs = {} self.children = [] @@ -23,13 +23,13 @@ class element(node): def __call__(self, *children, **attrs): for child in children: self.ctx.addchild(self, child) - for k, v in attrs.items(): + for k, v in attrs.iteritems(): self.ctx.addattr(self, k, v) return self def __todom__(self, doc): el = doc.createElementNS(self.ns, self.name) - for k, v in self.attrs.items(): + for k, v in self.attrs.iteritems(): el.setAttribute(k, v) for child in self.children: el.appendChild(child.__todom__(doc)) @@ -44,9 +44,10 @@ class context(object): def __init__(self): self.nodeconv = {} - self.nodeconv[bytes] = lambda ob: text(ob, self.charset) - self.nodeconv[str] = text + self.nodeconv[str] = lambda ob: text(ob, self.charset) + self.nodeconv[unicode] = text self.nodeconv[int] = text + self.nodeconv[long] = text self.nodeconv[float] = text def nodefrom(self, ob): @@ -72,7 +73,7 @@ class context(object): def addattr(self, node, k, v): if v is not None: - node.attrs[str(k)] = str(v) + node.attrs[unicode(k)] = unicode(v) class constructor(object): def __init__(self, ns, elcls=element, ctx=None): diff --git a/wrw/sp/util.py b/wrw/sp/util.py index 931cbdb..2599206 100644 --- a/wrw/sp/util.py +++ b/wrw/sp/util.py @@ -1,6 +1,6 @@ -import itertools, io -from .. import dispatch -from . import cons +import itertools, StringIO +from wrw import dispatch +import cons def findnsnames(el): names = {} @@ -8,7 +8,7 @@ def findnsnames(el): def proc(el): if isinstance(el, cons.element): if el.ns not in names: - names[el.ns] = "n" + str(nid[0]) + names[el.ns] = u"n" + unicode(nid[0]) nid[:] = [nid[0] + 1] for ch in el.children: proc(ch) @@ -56,9 +56,9 @@ class formatter(object): self.buf.extend(text.encode(self.charset)) def quotewrite(self, buf): - buf = buf.replace('&', "&") - buf = buf.replace('<', "<") - buf = buf.replace('>', ">") + buf = buf.replace(u'&', u"&") + buf = buf.replace(u'<', u"<") + buf = buf.replace(u'>', u">") self.write(buf) def __iter__(self): @@ -69,53 +69,53 @@ class formatter(object): if ns is None: return el.name else: - return ns + ":" + el.name + return ns + u":" + el.name def attrval(self, v): - qc, qt = ("'", "'") if '"' in v else ('"', """) + qc, qt = (u"'", u"'") if u'"' in v else (u'"', u""") self.write(qc) - v = v.replace('&', "&") - v = v.replace('<', "<") - v = v.replace('>', ">") + v = v.replace(u'&', u"&") + v = v.replace(u'<', u"<") + v = v.replace(u'>', u">") v = v.replace(qc, qt) self.write(v) self.write(qc) def attr(self, k, v): self.write(k) - self.write("=") + self.write(u"=") self.attrval(v) def attrs(self, attrs): for k, v in attrs: - self.write(" ") + self.write(u" ") self.attr(k, v) def inittag(self, el): - self.write("<" + self.elname(el)) - attrs = el.attrs.items() + self.write(u"<" + self.elname(el)) + attrs = el.attrs.iteritems() if self.first: nsnames = [] - for ns, name in self.nsnames.items(): + for ns, name in self.nsnames.iteritems(): if ns is None: if name is not None: raise Exception("null namespace must have null name, not" + name) continue - nsnames.append(("xmlns" if name is None else ("xmlns:" + name), ns)) + nsnames.append((u"xmlns" if name is None else (u"xmlns:" + name), ns)) attrs = itertools.chain(attrs, iter(nsnames)) self.first = False self.attrs(attrs) def starttag(self, el): self.inittag(el) - self.write(">") + self.write(u">") def shorttag(self, el): self.inittag(el) - self.write(" />") + self.write(u" />") def endtag(self, el): - self.write("") + self.write(u"") def text(self, el): self.quotewrite(el) @@ -124,9 +124,9 @@ class formatter(object): self.write(el) def start(self, el): - self.write('\n') + self.write(u'\n') if isinstance(el, cons.doctype): - self.write('\n' % (el.rootname, + self.write(u'\n' % (el.rootname, el.pubid, el.dtdid)) self.first = True @@ -150,7 +150,7 @@ class formatter(object): elif ev == "$": self.end(el) - def __next__(self): + def next(self): if self.src is None: raise StopIteration() try: @@ -159,8 +159,8 @@ class formatter(object): self.src = None ev, el = "$", None self.handle(ev, el) - ret = bytes(self.buf) - self.buf[:] = b"" + ret = str(self.buf) + self.buf[:] = "" return ret def nsname(self, el): @@ -170,7 +170,7 @@ class formatter(object): return ret if el.ns is None: return None - ret = "n" + str(self.nextns) + ret = u"n" + unicode(self.nextns) self.nextns += 1 return ret @@ -215,16 +215,16 @@ class formatter(object): @classmethod def format(cls, root, **kw): - buf = io.BytesIO() + buf = StringIO.StringIO() cls.output(buf, root, **kw) return buf.getvalue() class indenter(formatter): - def __init__(self, indent=" ", *args, **kw): - super().__init__(*args, **kw) + def __init__(self, indent=u" ", *args, **kw): + super(indenter, self).__init__(*args, **kw) self.indent = indent self.col = 0 - self.curind = "" + self.curind = u"" self.atbreak = True self.inline = False self.stack = [] @@ -232,11 +232,11 @@ class indenter(formatter): self.lastendbr = True def write(self, text): - lines = text.split("\n") + lines = text.split(u"\n") if len(lines) > 1: for ln in lines[:-1]: self.buf.extend(ln.encode(self.charset)) - self.buf.extend(b"\n") + self.buf.extend("\n") self.col = 0 self.buf.extend(lines[-1].encode(self.charset)) self.col += len(lines[-1]) @@ -244,7 +244,7 @@ class indenter(formatter): def br(self): if not self.atbreak: - self.buf.extend(("\n" + self.curind).encode(self.charset)) + self.buf.extend((u"\n" + self.curind).encode(self.charset)) self.col = 0 self.atbreak = True @@ -270,12 +270,12 @@ class indenter(formatter): self.push(el) self.inline = self.inline or self.inlinep(el) self.curind += self.indent - super().starttag(el) + super(indenter, self).starttag(el) def shorttag(self, el): if not self.inline: self.br() - super().shorttag(el) + super(indenter, self).shorttag(el) def endtag(self, el): il = self.inline @@ -285,33 +285,33 @@ class indenter(formatter): else: self.br() self.lastendbr = True - super().endtag(el) + super(indenter, self).endtag(el) def start(self, el): - super().start(el) + super(indenter, self).start(el) self.atbreak = True def end(self, el): self.br() def handle(self, ev, el): - super().handle(ev, el) + super(indenter, self).handle(ev, el) self.last = ev, el class textindenter(indenter): maxcol = 70 def text(self, el): - left = str(el) + left = unicode(el) while True: if len(left) + self.col > self.maxcol: bp = max(self.maxcol - self.col, 0) - for i in range(bp, -1, -1): + for i in xrange(bp, -1, -1): if left[i].isspace(): while i > 0 and left[i - 1].isspace(): i -= 1 break else: - for i in range(bp + 1, len(left)): + for i in xrange(bp + 1, len(left)): if left[i].isspace(): break else: @@ -333,7 +333,7 @@ class response(dispatch.restart): formatter = indenter def __init__(self, root): - super().__init__() + super(response, self).__init__() self.root = root @property diff --git a/wrw/sp/xhtml.py b/wrw/sp/xhtml.py index eb82f57..a2c1eb1 100644 --- a/wrw/sp/xhtml.py +++ b/wrw/sp/xhtml.py @@ -1,11 +1,11 @@ -import xml.dom.minidom, io -from . import cons as _cons -from . import util +import xml.dom.minidom, StringIO +import cons as _cons +import util dom = xml.dom.minidom.getDOMImplementation() -ns = "http://www.w3.org/1999/xhtml" -doctype = "-//W3C//DTD XHTML 1.1//EN" -dtd = "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" +ns = u"http://www.w3.org/1999/xhtml" +doctype = u"-//W3C//DTD XHTML 1.1//EN" +dtd = u"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" class htmlelement(_cons.element): def __todoc__(self): @@ -15,11 +15,11 @@ class htmlelement(_cons.element): return doc class xhtmlcontext(_cons.context): - attrmap = {"klass": "class"} + attrmap = {u"klass": u"class"} def addattr(self, node, k, v): - k = str(k) - super().addattr(node, self.attrmap.get(k, k), v) + k = unicode(k) + super(xhtmlcontext, self).addattr(node, self.attrmap.get(k, k), v) def cons(ctx=None): if ctx is None: ctx = xhtmlcontext() @@ -30,7 +30,7 @@ def head(title=None, css=None): head = h.head if title: head(h.title(title)) - if isinstance(css, str) or isinstance(css, bytes): + if isinstance(css, str) or isinstance(css, unicode): head(h.link(rel="stylesheet", type="text/css", href=css)) elif css: for ss in css: @@ -38,10 +38,10 @@ def head(title=None, css=None): return head class htmlformatter(util.formatter): - allowshort = {"br", "hr", "img", "input", "meta", "link"} + allowshort = set([u"br", u"hr", u"img", u"input", u"meta", u"link"]) def shorttag(self, el): if el.name in self.allowshort: - super().shorttag(el) + super(htmlformatter, self).shorttag(el) else: self.handle(">", el) self.handle("<", el) @@ -52,7 +52,7 @@ class htmlindenter(util.textindenter, htmlformatter): def forreq(req, tree): # XXX: Use proper Content-Type for clients accepting it. req.ohead["Content-Type"] = "text/html; charset=utf-8" - buf = io.BytesIO() + buf = StringIO.StringIO() htmlindenter.output(buf, tree, doctype=(doctype, dtd), charset="utf-8") ret = buf.getvalue() req.ohead["Content-Length"] = len(ret) diff --git a/wrw/util.py b/wrw/util.py index a1dcc6c..22bce9d 100644 --- a/wrw/util.py +++ b/wrw/util.py @@ -1,5 +1,5 @@ import inspect, math -from . import req, dispatch, session, form, resp, proto +import req, dispatch, session, form, resp, proto def wsgiwrap(callable): def wrapper(env, startreq): @@ -20,7 +20,7 @@ def formparams(callable): for arg in list(args): if arg not in spec.args: del args[arg] - for i in range(len(spec.args) - (len(spec.defaults) if spec.defaults else 0)): + for i in xrange(len(spec.args) - (len(spec.defaults) if spec.defaults else 0)): if spec.args[i] not in args: raise resp.httperror(400, "Missing parameter", ("The query parameter `", resp.h.code(spec.args[i]), "' is required but not supplied.")) return callable(**args) @@ -90,12 +90,12 @@ class preiter(object): self.bk = real self.bki = iter(real) self._next = None - self.__next__() + self.next() def __iter__(self): return self - def __next__(self): + def next(self): if self._next is self.end: raise StopIteration() ret = self._next @@ -115,16 +115,6 @@ def pregen(callable): wrapper.__wrapped__ = callable return wrapper -def stringwrap(charset): - def dec(callable): - @pregen - def wrapper(*args, **kwargs): - for string in callable(*args, **kwargs): - yield string.encode(charset) - wrapper.__wrapped__ = callable - return wrapper - return dec - class sessiondata(object): @classmethod def get(cls, req, create=True): @@ -146,7 +136,7 @@ class sessiondata(object): class autodirty(sessiondata): @classmethod def get(cls, req): - ret = super().get(req) + ret = super(autodirty, cls).get(req) if "_is_dirty" not in ret.__dict__: ret.__dict__["_is_dirty"] = False return ret @@ -158,18 +148,18 @@ class autodirty(sessiondata): return self._is_dirty def __setattr__(self, name, value): - super().__setattr__(name, value) + super(autodirty, self).__setattr__(name, value) if "_is_dirty" in self.__dict__: self.__dict__["_is_dirty"] = True def __delattr__(self, name): - super().__delattr__(name, value) + super(autodirty, self).__delattr__(name, value) if "_is_dirty" in self.__dict__: self.__dict__["_is_dirty"] = True class manudirty(object): def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + super(manudirty, self).__init__(*args, **kwargs) self.__dirty = False def sessfrozen(self): @@ -212,7 +202,7 @@ class specslot(object): class specclass(type): def __init__(self, name, bases, tdict): - super().__init__(name, bases, tdict) + super(specclass, self).__init__(name, bases, tdict) sslots = set() dslots = set() for cls in self.__mro__: @@ -224,7 +214,8 @@ class specclass(type): for i, slot in enumerate(self.__sslots_a__): setattr(self, slot, specslot(slot, i, slot in dslots)) -class specdirty(sessiondata, metaclass=specclass): +class specdirty(sessiondata): + __metaclass__ = specclass __slots__ = ["session", "__sslots__", "_is_dirty"] def __specinit__(self): @@ -232,7 +223,7 @@ class specdirty(sessiondata, metaclass=specclass): @staticmethod def __new__(cls, req, sess): - self = super().__new__(cls) + self = super(specdirty, cls).__new__(cls) self.session = sess self.__sslots__ = [specslot.unbound] * len(cls.__sslots_a__) self.__specinit__() diff --git a/wrw/wmako.py b/wrw/wmako.py index ef886fb..13ce342 100644 --- a/wrw/wmako.py +++ b/wrw/wmako.py @@ -1,6 +1,6 @@ import os, threading from mako import template, lookup, filters -from . import util, form, session, env, resp +import util, form, session, env, resp # It seems Mako isn't thread-safe. makolock = threading.Lock()