On Saturday, June 2, 2012 2:20:50 PM UTC-4, Tomas Schertel wrote: > > I saw a few posts talking about web.py run with python 3 and noticed one > that said there's no reason in porting web.py to python 3 if wsgi layers > still runs with python 2. > Why don't make web.py able to run on both python, 2.X and 3.x? > Bottle and Cherrypy does that. > Flup already has a branch for python 3. >
I'm not sure if the developers have any sort of Python 3 comparability roadmap (I didn't see anything on the issue tracker, and only this note https://bugs.launchpad.net/webpy/+bug/277266 from 2008) but I agree, I think it should be possible to enable web.py to support both. I just discovered web.py in the last week, and I'm totally hooked! It's exactly what I imagined wanting out of a Python web-framework. I have a Python project I've been working on, that I'd love to have hook into web.py, but it's Python 3 :( So I spent a few hours today trying to figure out what needed to be done to get it working, and it doesn't seem all that bad. 1. Pull in CherryPy's updated web server code, which is now 2/3 compatible. 2. Run python -3: I ran this on a small test setup and saw the following: $ python -3 code.py http://0.0.0.0:8080/ /usr/lib/python2.6/site-packages/web/template.py:925: DeprecationWarning: the compiler package has been removed in Python 3.0 import compiler /usr/lib/python2.6/site-packages/markdown/blockprocessors.py:163: DeprecationWarning: classic int division indent_level = len(m.group(1))/markdown.TAB_LENGTH 127.0.0.1:57576 - - [22/Jul/2012 01:03:37] "HTTP/1.1 GET /Welcome" - 200 OK 127.0.0.1:57576 - - [22/Jul/2012 01:03:38] "HTTP/1.1 GET /" - 200 OK This seems pretty promising to me. I think the compiler error can be resolved by switching to http://docs.python.org/library/ast.html#ast.parse but even if it's more complicated than that, the import is in a try block, and fails reasonably gracefully. It looks like Jython supports AST as well, which would make this an even better switch: http://www.jython.org/docs/library/ast.html . The markdown error is of no concern, since Python Markdown has a 3.0 compatible version available: http://freewisdom.org/projects/python-markdown/News 3. Run 2to3: 2to3 runs successfully, and by and large cleans things up well. It runs into a fair bit of trouble with web.py's unicode handling, such as utils.safestr and utils.safeunicode, generating this diff of safestr: @@ -364,12 +364,12 @@ >>> safestr(2) '2' """ - if isinstance(obj, unicode): + if isinstance(obj, str): return obj.encode(encoding) elif isinstance(obj, str): return obj elif hasattr(obj, 'next'): # iterator - return itertools.imap(safestr, obj) + return map(safestr, obj) else: return str(obj) You'll notice that it replaces unicode with str, breaking the method's expected behavior. I'm not sure if it makes more sense to define a custom 2to3 fixer, or figure out a better way to define / compartmentalize this code, but this will need to be cleaned up. 4. Fix runtime exceptions: Running 2to3 isn't enough to kick of the server though, I got a handful of stack traces that I was able to correct with the following patch: Series of fixes to resolve stack traces in 3.2. Fixed bad reference to __builtin__: http://pydev.blogspot.com/2008/11/making-code-work-in-python-2-and-3.html #5 Changed UserDict.DictMixin to collections.MutableMapping per http://bugs.python.org/issue2876 but this may not be enough: http://bugs.python.org/issue7975 Removed 'object' parent from TemplateResult: http://stackoverflow.com/questions/3003053/metaclass-multiple-inheritance-inconsistency Removed 'exceptions' import ---- Enough to start the server Removed str decode('UTF-8') call diff -r 1b5bb3b5399b -r c823902ee50f application.py --- a/application.py Sat Jul 21 23:27:20 2012 -0400 +++ b/application.py Sat Jul 21 23:37:09 2012 -0400 @@ -15,7 +15,6 @@ import itertools import os import types -from exceptions import SystemExit try: import wsgiref.handlers @@ -374,12 +373,6 @@ ctx.fullpath = ctx.path + ctx.query - for k, v in ctx.items(): - # convert all string values to unicode values and replace - # malformed data with a suitable replacement marker. - if isinstance(v, str): - ctx[k] = v.decode('utf-8', 'replace') - # status must always be str ctx.status = '200 OK' diff -r 1b5bb3b5399b -r c823902ee50f template.py --- a/template.py Sat Jul 21 23:27:20 2012 -0400 +++ b/template.py Sat Jul 21 23:37:09 2012 -0400 @@ -40,7 +40,7 @@ import sys import glob import re -from UserDict import DictMixin +from collections import MutableMapping import warnings from .utils import storage, safeunicode, safestr, re_compile @@ -721,8 +721,8 @@ "__import__", # some c-libraries like datetime requires __import__ to present in the namespace ] -import builtins -TEMPLATE_BUILTINS = dict([(name, getattr(__builtin__, name)) for name in TEMPLATE_BUILTIN_NAMES if name in builtins.__dict__]) +import builtins as __builtin__ +TEMPLATE_BUILTINS = dict([(name, getattr(__builtin__, name)) for name in TEMPLATE_BUILTIN_NAMES if name in __builtin__.__dict__]) class ForLoop: """ @@ -1209,7 +1209,7 @@ e = SecurityError("%s:%d - execution of '%s' statements is denied" % (self.filename, lineno, nodename)) self.errors.append(e) -class TemplateResult(object, DictMixin): +class TemplateResult(MutableMapping): """Dictionary like object for storing template output. The result of a template execution is usally a string, but sometimes it diff -r 1b5bb3b5399b -r c823902ee50f utils.py --- a/utils.py Sat Jul 21 23:27:20 2012 -0400 +++ b/utils.py Sat Jul 21 23:37:09 2012 -0400 @@ -259,7 +259,7 @@ counter = Counter iters = [list, tuple] -import builtins +import builtins as __builtin__ if hasattr(__builtin__, 'set'): iters.append(set) if hasattr(__builtin__, 'frozenset'): This was enough to start a server, but there are likely more robust ways of solving these exceptions. 5. Update test suite I saw 4 failures running the test suite locally on Python 2.7, and 41 failures and 12 errors on 3.2. Most of these were just encoding issues, like: File ".\web\utils.py", line 337, in web.utils.safeunicode Failed example: safeunicode('hello') Expected: u'hello' Got: 'hello' But the tests will need to be updated and expanded to ensure no regressions. Needless to say, it looks to me like there's still work to be done, but it's not impossible. To the maintainers, do you have any plans to move towards Python 3? I would be happy to help make this possible. Michael -- You received this message because you are subscribed to the Google Groups "web.py" group. To view this discussion on the web visit https://groups.google.com/d/msg/webpy/-/WeOvy-V51sgJ. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/webpy?hl=en.
