Very nice Michael. I hope web.py changes to work with python 3. On Sunday, 22 July 2012 02:44:14 UTC-3, Michael Diamond wrote: > > 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/-/R94Y_vTVtoAJ. To post to this group, send email to webpy@googlegroups.com. To unsubscribe from this group, send email to webpy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/webpy?hl=en.