diff options
author | Marcel Hellkamp <marc@gsites.de> | 2009-07-24 22:30:36 +0200 |
---|---|---|
committer | Marcel Hellkamp <marc@gsites.de> | 2009-07-24 22:30:36 +0200 |
commit | 1c15aaf2ee01dc11662e2c02c072e8d218012c6e (patch) | |
tree | 3cda74e5c7cc38e87b65a206cb936be78203f6e8 | |
parent | 30c1dfcf354e756ebe3454f5697bcaa0c48419a1 (diff) | |
download | bottle-1c15aaf2ee01dc11662e2c02c072e8d218012c6e.tar.gz |
Made bottle work with python >= 2.6 and python >= 3.0. Dropped support for python <= 2.5 and lower. Sorry.0.4.14
-rw-r--r-- | bottle.py | 60 | ||||
-rw-r--r-- | setup.py | 3 | ||||
-rw-r--r-- | test/test_db.py | 2 | ||||
-rw-r--r-- | test/test_environ.py | 9 | ||||
-rw-r--r-- | test/test_routes.py | 2 |
5 files changed, 45 insertions, 31 deletions
@@ -62,10 +62,10 @@ Example """ __author__ = 'Marcel Hellkamp' -__version__ = '0.4.14' +__version__ = '0.4.15' __license__ = 'MIT' - +import sys import cgi import mimetypes import os @@ -73,14 +73,24 @@ import os.path import traceback import re import random -from Cookie import SimpleCookie import threading import time -from urlparse import parse_qs -import cPickle as pickle -import anydbm as dbm from wsgiref.headers import Headers as HeaderWrapper +if (2,6) <= sys.version_info < (3,0): + from Cookie import SimpleCookie + from urlparse import parse_qs + import cPickle as pickle + import anydbm as dbm +elif (3,0) <= sys.version_info: + from http.cookies import SimpleCookie + from urllib.parse import parse_qs + import pickle + import dbm +else: + raise NotImplementedError("Sorry, you need at least Python 2.6 or Python 3.x to use bottle.") + + @@ -133,9 +143,9 @@ def WSGIHandler(environ, start_response): if not handler: raise HTTPError(404, "Not found") output = handler(**args) - except BreakTheBottle, e: + except BreakTheBottle as e: output = e.output - except Exception, e: + except Exception as e: response.status = getattr(e, 'http_status', 500) errorhandler = ERROR_HANDLER.get(response.status, error_default) try: @@ -198,7 +208,7 @@ class Request(threading.local): if self._GET is None: raw_dict = parse_qs(self.query_string, keep_blank_values=1) self._GET = {} - for key, value in raw_dict.iteritems(): + for key, value in raw_dict.items(): if len(value) == 1: self._GET[key] = value[0] else: @@ -235,7 +245,7 @@ class Request(threading.local): if self._COOKIES is None: raw_dict = SimpleCookie(self._environ.get('HTTP_COOKIE','')) self._COOKIES = {} - for cookie in raw_dict.itervalues(): + for cookie in raw_dict.values(): self._COOKIES[cookie.key] = cookie.value return self._COOKIES @@ -254,7 +264,7 @@ class Response(threading.local): def wsgiheaders(self): ''' Returns a wsgi conform list of header/value pairs ''' - for c in self.COOKIES.itervalues(): + for c in self.COOKIES.values(): self.header.add_header('Set-Cookie', c.OutputString()) return [(h.title(), v) for h, v in self.header_list] @@ -358,7 +368,7 @@ def match_url(url, method='GET'): # Now search regexp routes routes = ROUTES_REGEXP.get(method,[]) - for i in xrange(len(routes)): + for i in range(len(routes)): match = routes[i][0].match(url) if match: handler = routes[i][1] @@ -397,7 +407,7 @@ def validate(**vkargs): abort(403, 'Missing parameter: %s' % key) try: kargs[key] = vkargs[key](kargs[key]) - except ValueError, e: + except ValueError as e: abort(403, 'Wrong parameter format for: %s' % key) return func(**kargs) return wrapper @@ -506,15 +516,15 @@ def run(server=WSGIRefServer, host='127.0.0.1', port=8080, optinmize = False, ** raise RuntimeError("Server must be a subclass of ServerAdapter") if not quiet: - print 'Bottle server starting up (using %s)...' % repr(server) - print 'Listening on http://%s:%d/' % (server.host, server.port) - print 'Use Ctrl-C to quit.' - print + print('Bottle server starting up (using %s)...' % repr(server)) + print('Listening on http://%s:%d/' % (server.host, server.port)) + print('Use Ctrl-C to quit.') + print() try: server.run(WSGIHandler) except KeyboardInterrupt: - print "Shuting down..." + print("Shuting down...") @@ -602,7 +612,7 @@ class SimpleTemplate(BaseTemplate): strbuffer.append(line) else: flush() - for i in xrange(1, len(splits), 2): + for i in range(1, len(splits), 2): splits[i] = PyStmt(splits[i]) splits = [x for x in splits if bool(x)] code.append(" " * indent + "stdout.extend(%s)\n" % repr(splits)) @@ -617,7 +627,7 @@ class SimpleTemplate(BaseTemplate): ''' Returns the rendered template using keyword arguments as local variables. ''' args['stdout'] = [] args['_subtemplates'] = self.subtemplates - exec self.co in args + eval(self.co, args) return ''.join(args['stdout']) @@ -692,14 +702,14 @@ class BottleBucket(object): return list(self.ukeys()) def ukeys(self): - return set(self.db.keys() + self.mmap.keys()) + return set(self.db.keys()) | set(self.mmap.keys()) def save(self): self.close() self.__init__(self.name) def close(self): - for key in self.mmap.iterkeys(): + for key in self.mmap.keys(): pvalue = pickle.dumps(self.mmap[key], pickle.HIGHEST_PROTOCOL) if key not in self.db or pvalue != self.db[key]: self.db[key] = pvalue @@ -707,7 +717,7 @@ class BottleBucket(object): self.db.close() def clear(self): - for key in self.db.iterkeys(): + for key in self.db.keys(): del self.db[key] self.mmap.clear() @@ -740,7 +750,7 @@ class BottleDB(threading.local): if key not in self.open: self.open[key] = BottleBucket(key) self.open[key].clear() - for k, v in value.iteritems(): + for k, v in value.items(): self.open[key][k] = v else: raise ValueError("Only dicts and BottleBuckets are allowed.") @@ -767,7 +777,7 @@ class BottleDB(threading.local): self.__init__() def close(self): - for db in self.open.itervalues(): + for db in self.open.values(): db.close() self.open.clear() @@ -22,7 +22,8 @@ setup(name='bottle', 'Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware', 'Topic :: Internet :: WWW/HTTP :: WSGI :: Server', 'Topic :: Software Development :: Libraries :: Application Frameworks', - 'Programming Language :: Python :: 2'] + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 3'] ) diff --git a/test/test_db.py b/test/test_db.py index 2341d38..a627cbc 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -15,7 +15,7 @@ class TestDB(unittest.TestCase): def test_save(self): """ DB: Save to disk """ - data = [1, 1.5, 'a', u'ä'] + data = [1, 1.5, 'a', 'ä'] bottle.db.db1.value1 = data bottle.db['db2']['value2'] = data diff --git a/test/test_environ.py b/test/test_environ.py index fe43188..e4805de 100644 --- a/test/test_environ.py +++ b/test/test_environ.py @@ -32,8 +32,11 @@ class TestEnviron(unittest.TestCase): self.assertEqual(qd, request.POST) def test_multipart(self): - """ Environ: POST (multipart) """ - import StringIO + """ Environ: POST (multipart) """ + if sys.version_info[0] == 2: + from StringIO import StringIO + else: + from io import StringIO e = {} e['SERVER_PROTOCOL'] = "HTTP/1.1" e['REQUEST_METHOD'] = 'POST' @@ -50,7 +53,7 @@ class TestEnviron(unittest.TestCase): e['wsgi.input'] += 'Content-Transfer-Encoding: binary\n' e['wsgi.input'] += 'This is a sample\n' e['wsgi.input'] += '------------------314159265358979323846--\n' - e['wsgi.input'] = StringIO.StringIO(e['wsgi.input']) + e['wsgi.input'] = StringIO(e['wsgi.input']) e['wsgi.input'].seek(0) request.bind(e) self.assertTrue('test.txt' in request.POST) diff --git a/test/test_routes.py b/test/test_routes.py index d9a93f2..fa33f57 100644 --- a/test/test_routes.py +++ b/test/test_routes.py @@ -19,7 +19,7 @@ class TestRoutes(unittest.TestCase): for r in routes: add_route(r, token, simple=True) self.assertTrue('GET' in ROUTES_SIMPLE) - r = [r for r in ROUTES_SIMPLE['GET'].itervalues() if r == 'abc'] + r = [r for r in ROUTES_SIMPLE['GET'].values() if r == 'abc'] self.assertEqual(5, len(r)) for r in routes: self.assertEqual(token, match_url(r)[0]) |