Author: Antonio Cuni <[email protected]>
Branch: py3k
Changeset: r56193:401f486a2982
Date: 2012-07-18 21:34 +0200
http://bitbucket.org/pypy/pypy/changeset/401f486a2982/
Log: add a decorator which allows to selectively use the equivalent of
"from __future__ import unicode_literals" on a per-function basis
diff --git a/pypy/tool/sourcetools.py b/pypy/tool/sourcetools.py
--- a/pypy/tool/sourcetools.py
+++ b/pypy/tool/sourcetools.py
@@ -6,6 +6,7 @@
# XXX We should try to generalize and single out one approach to dynamic
# XXX code compilation.
+import types
import sys, os, inspect, new
import autopath, py
@@ -268,3 +269,29 @@
except AttributeError:
firstlineno = -1
return "(%s:%d)%s" % (mod or '?', firstlineno, name or 'UNKNOWN')
+
+def with_unicode_literals(fn=None, **kwds):
+ encoding = kwds.pop('encoding', 'ascii')
+ if kwds:
+ raise TypeError("Unexpected keyword argument(s): %s" % ',
'.join(kwds.keys()))
+ def decorator(fn):
+ co = fn.func_code
+ new_consts = []
+ for const in co.co_consts:
+ if isinstance(const, str):
+ const = const.decode(encoding)
+ new_consts.append(const)
+ new_consts = tuple(new_consts)
+ new_code = types.CodeType(co.co_argcount, co.co_nlocals,
co.co_stacksize,
+ co.co_flags, co.co_code, new_consts,
co.co_names,
+ co.co_varnames, co.co_filename, co.co_name,
+ co.co_firstlineno, co.co_lnotab)
+ fn.func_code = new_code
+ return fn
+ #
+ # support the usage of @with_unicode_literals instead of
@with_unicode_literals()
+ if fn is not None:
+ assert type(fn) is types.FunctionType
+ return decorator(fn)
+ else:
+ return decorator
diff --git a/pypy/tool/test/test_sourcetools.py
b/pypy/tool/test/test_sourcetools.py
--- a/pypy/tool/test/test_sourcetools.py
+++ b/pypy/tool/test/test_sourcetools.py
@@ -1,4 +1,6 @@
-from pypy.tool.sourcetools import func_with_new_name, func_renamer
+# -*- encoding: utf-8 -*-
+import py
+from pypy.tool.sourcetools import func_with_new_name, func_renamer,
with_unicode_literals
def test_rename():
def f(x, y=5):
@@ -34,3 +36,24 @@
bar3 = func_with_new_name(bar, 'bar3')
assert bar3.func_doc == 'new doc'
assert bar2.func_doc != bar3.func_doc
+
+
+def test_with_unicode_literals():
+ @with_unicode_literals()
+ def foo():
+ return 'hello'
+ assert type(foo()) is unicode
+ #
+ @with_unicode_literals
+ def foo():
+ return 'hello'
+ assert type(foo()) is unicode
+ #
+ def foo():
+ return 'hello àèì'
+ py.test.raises(UnicodeDecodeError, "with_unicode_literals(foo)")
+ #
+ @with_unicode_literals(encoding='utf-8')
+ def foo():
+ return 'hello àèì'
+ assert foo() == u'hello àèì'
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit