Author: Philip Jenvey <[email protected]>
Branch: operrfmt-NT
Changeset: r64551:dcbcd0a7c467
Date: 2013-05-24 16:48 -0700
http://bitbucket.org/pypy/pypy/changeset/dcbcd0a7c467/
Log: branch for adding a couple helper format specifiers to
operationerrfmt: o add %T to return the type name. operationerrfmt
has to get space w/ an awful hack (but the hack is already necessary
for py3k) o operationerrfmt now requires a type object for its first
arg to make this simpler
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 cStringIO
+import itertools
import os
import sys
import traceback
@@ -305,6 +306,7 @@
_fmtcache = {}
_fmtcache2 = {}
+_FMTS = tuple('sdT')
def decompose_valuefmt(valuefmt):
"""Returns a tuple of string parts extracted from valuefmt,
@@ -313,7 +315,7 @@
parts = valuefmt.split('%')
i = 1
while i < len(parts):
- if parts[i].startswith('s') or parts[i].startswith('d'):
+ if parts[i].startswith(_FMTS):
formats.append(parts[i][0])
parts[i] = parts[i][1:]
i += 1
@@ -321,10 +323,21 @@
parts[i-1] += '%' + parts[i+1]
del parts[i:i+2]
else:
- raise ValueError("invalid format string (only %s or %d supported)")
+ fmts = '%%%s or %%%s' % (', %'.join(_FMTS[:-1]), _FMTS[-1])
+ raise ValueError("invalid format string (only %s supported)" %
+ fmts)
assert len(formats) > 0, "unsupported: no % command found"
return tuple(parts), tuple(formats)
+def _is_type(w_obj):
+ from pypy.objspace.std.typeobject import W_TypeObject
+ # HACK: isinstance(w_obj, W_TypeObject) won't translate under the
+ # fake objspace, but w_obj.__class__ is W_TypeObject does and short
+ # circuits to a False constant there, causing the isinstance to be
+ # ignored =[
+ return (w_obj is not None and w_obj.__class__ is W_TypeObject and
+ isinstance(w_obj, W_TypeObject))
+
def get_operrcls2(valuefmt):
strings, formats = decompose_valuefmt(valuefmt)
assert len(strings) == len(formats) + 1
@@ -333,24 +346,28 @@
except KeyError:
from rpython.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, _, attr in entries:
setattr(self, attr, args[i])
- assert w_type is not None
+ assert _is_type(w_type)
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 == 'T':
+ space = self.w_type.space
+ lst[i+i+1] = space.type(value).getname(space)
+ else:
+ lst[i+i+1] = str(value)
lst[-1] = self.xstrings[-1]
return ''.join(lst)
#
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
@@ -12,27 +12,34 @@
assert (decompose_valuefmt("%s%d%%%s") ==
(("", "", "%", ""), ('s', 'd', 's')))
-def test_get_operrcls2():
+def test_get_operrcls2(space):
cls, strings = get_operrcls2('abc %s def %d')
assert strings == ("abc ", " def ", "")
assert issubclass(cls, OperationError)
- inst = cls("w_type", strings, "hello", 42)
+ inst = cls(space.w_OSError, strings, "hello", 42)
assert inst._compute_value() == "abc hello def 42"
cls2, strings2 = get_operrcls2('a %s b %d c')
assert cls2 is cls # caching
assert strings2 == ("a ", " b ", " c")
-def test_operationerrfmt():
- operr = operationerrfmt("w_type", "abc %s def %d", "foo", 42)
+def test_operationerrfmt(space):
+ w_exc = space.w_IOError
+ operr = operationerrfmt(w_exc, "abc %s def %d", "foo", 42)
assert isinstance(operr, OperationError)
- assert operr.w_type == "w_type"
+ assert operr.w_type == w_exc
assert operr._w_value is None
assert operr._compute_value() == "abc foo def 42"
- operr2 = operationerrfmt("w_type2", "a %s b %d c", "bar", 43)
+ operr2 = operationerrfmt(w_exc, "a %s b %d c", "bar", 43)
assert operr2.__class__ is operr.__class__
- operr3 = operationerrfmt("w_type2", "a %s b %s c", "bar", "4b")
+ operr3 = operationerrfmt(w_exc, "a %s b %s c", "bar", "4b")
assert operr3.__class__ is not operr.__class__
+def test_operationerrfmt_T(space):
+ operr = operationerrfmt(space.w_AttributeError,
+ "'%T' object has no attribute '%s'",
+ space.wrap('foo'), 'foo')
+ assert operr._compute_value() == "'str' object has no attribute 'foo'"
+
def test_operationerrfmt_empty():
py.test.raises(AssertionError, operationerrfmt, "w_type", "foobar")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit