[pypy-commit] pypy py3k: make all the messages computed by operationerrfmt as unicode, even if the source message is a byte string
antocuni
noreply at buildbot.pypy.org
Sat Aug 4 15:01:17 CEST 2012
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: py3k
Changeset: r56568:de80c62c47f3
Date: 2012-08-04 15:00 +0200
http://bitbucket.org/pypy/pypy/changeset/de80c62c47f3/
Log: make all the messages computed by operationerrfmt as unicode, even
if the source message is a byte string
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -1,4 +1,5 @@
import os, sys
+import itertools
from pypy.rlib import jit
from pypy.rlib.objectmodel import we_are_translated
from errno import EINTR
@@ -327,27 +328,30 @@
except KeyError:
from pypy.rlib.unroll import unrolling_iterable
attrs = ['x%d' % i for i in range(len(formats))]
- entries = unrolling_iterable(enumerate(attrs))
+ entries = unrolling_iterable(zip(itertools.count(), formats, attrs))
#
class OpErrFmt(OperationError):
def __init__(self, w_type, strings, *args):
self.setup(w_type)
assert len(args) == len(strings) - 1
self.xstrings = strings
- for i, attr in entries:
+ for i, fmt, attr in entries:
setattr(self, attr, args[i])
if not we_are_translated() and w_type is None:
from pypy.tool.error import FlowingError
raise FlowingError(self._compute_value())
def _compute_value(self):
lst = [None] * (len(formats) + len(formats) + 1)
- for i, attr in entries:
+ for i, fmt, attr in entries:
string = self.xstrings[i]
value = getattr(self, attr)
lst[i+i] = string
- lst[i+i+1] = str(value)
+ if fmt == 'd':
+ lst[i+i+1] = str(value).encode('ascii')
+ else:
+ lst[i+i+1] = unicode(value)
lst[-1] = self.xstrings[-1]
- return ''.join(lst)
+ return u''.join(lst)
#
_fmtcache2[formats] = OpErrFmt
return OpErrFmt, strings
@@ -363,7 +367,12 @@
def operationerrfmt(w_type, valuefmt, *args):
"""Equivalent to OperationError(w_type, space.wrap(valuefmt % args)).
More efficient in the (common) case where the value is not actually
- needed."""
+ needed.
+ Note that:
+ 1. in the py3k branch the exception message will always be unicode
+ 2. only %s and %d are supported
+ """
+ valuefmt = valuefmt.decode('ascii')
OpErrFmt, strings = get_operationerr_class(valuefmt)
return OpErrFmt(w_type, strings, *args)
operationerrfmt._annspecialcase_ = 'specialize:arg(1)'
diff --git a/pypy/interpreter/test/test_error.py b/pypy/interpreter/test/test_error.py
--- a/pypy/interpreter/test/test_error.py
+++ b/pypy/interpreter/test/test_error.py
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+
import py, os, errno
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.error import decompose_valuefmt, get_operrcls2
@@ -27,7 +29,9 @@
assert isinstance(operr, OperationError)
assert operr.w_type == "w_type"
assert operr._w_value is None
- assert operr._compute_value() == "abc foo def 42"
+ val = operr._compute_value()
+ assert val == u"abc foo def 42"
+ assert isinstance(val, unicode)
operr2 = operationerrfmt("w_type2", "a %s b %d c", "bar", 43)
assert operr2.__class__ is operr.__class__
operr3 = operationerrfmt("w_type2", "a %s b %s c", "bar", "4b")
@@ -36,6 +40,11 @@
def test_operationerrfmt_empty():
py.test.raises(AssertionError, operationerrfmt, "w_type", "foobar")
+def test_operationerrfmt_unicode():
+ operr = operationerrfmt("w_type", "abc %s", u"àèìòù")
+ val = operr._compute_value()
+ assert val == u"abc àèìòù"
+
def test_errorstr(space):
operr = OperationError(space.w_ValueError, space.wrap("message"))
assert operr.errorstr(space) == "ValueError: message"
More information about the pypy-commit
mailing list