[pypy-commit] pypy operrfmt-NT: fix ztranslation: try some fallbacks when we can't grab a space during tests
pjenvey
noreply at buildbot.pypy.org
Sun May 26 21:35:34 CEST 2013
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: operrfmt-NT
Changeset: r64572:ef8b5a2f97b4
Date: 2013-05-26 12:27 -0700
http://bitbucket.org/pypy/pypy/changeset/ef8b5a2f97b4/
Log: fix ztranslation: try some fallbacks when we can't grab a space
during tests
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -298,6 +298,17 @@
"""
self._application_traceback = traceback
+def _space_from_type(w_type):
+ """Grab a space if a W_TypeObject, or None"""
+ from pypy.objspace.std.typeobject import W_TypeObject
+ # HACK: isinstance(w_type, W_TypeObject) won't translate under the
+ # fake objspace, but w_type.__class__ is W_TypeObject does and short
+ # circuits to a False constant there, causing the isinstance to be
+ # ignored =[
+ if (w_type is not None and w_type.__class__ is W_TypeObject and
+ isinstance(w_type, W_TypeObject)):
+ return w_type.space
+
# ____________________________________________________________
# optimization only: avoid the slowest operation -- the string
# formatting with '%' -- in the common case were we don't
@@ -305,7 +316,7 @@
_fmtcache = {}
_fmtcache2 = {}
-_FMTS = tuple('sdNT')
+_FMTS = tuple('dsNT')
def decompose_valuefmt(valuefmt):
"""Returns a tuple of string parts extracted from valuefmt,
@@ -328,14 +339,24 @@
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 _format_NT(space, fmt, w_value):
+ """Process operationerrfmt's %N/T formats"""
+ if space is not None:
+ if fmt == 'T':
+ w_value = space.type(w_value)
+ return w_value.getname(space)
+ elif not we_are_translated():
+ # may not be able to grab space due to testing environments,
+ # fallback
+ if fmt == 'T':
+ tp = type(w_value)
+ typedef = getattr(tp, 'typedef', None)
+ return tp.__name__ if typedef is None else typedef.name
+ for attr in 'name', '__name__':
+ name = getattr(w_value, attr, None)
+ if name is not None:
+ return name
+ return '?'
def get_operrcls2(valuefmt):
strings, formats = decompose_valuefmt(valuefmt)
@@ -355,21 +376,16 @@
for i, _, attr in entries:
setattr(self, attr, args[i])
assert w_type is not None
- # space may be None during tests
- self.space = w_type.space if _is_type(w_type) else None
def _compute_value(self):
- space = self.space
lst = [None] * (len(formats) + len(formats) + 1)
for i, fmt, attr in entries:
string = self.xstrings[i]
value = getattr(self, attr)
lst[i+i] = string
- if fmt == 'T':
- type_ = type if space is None else space.type
- value = type_(value)
- if fmt in 'NT' and space is not None:
- lst[i+i+1] = value.getname(space)
+ if fmt in 'NT':
+ lst[i+i+1] = _format_NT(_space_from_type(self.w_type),
+ fmt, value)
else:
lst[i+i+1] = str(value)
lst[-1] = self.xstrings[-1]
@@ -391,10 +407,10 @@
More efficient in the (common) case where the value is not actually
needed.
- Also supports the following extra format characters:
+ Supports the standard %s and %d formats, plus the following:
- %N - The result of arg.getname(space)
- %T - The result of space.type(arg).getname(space)
+ %N - The result of w_arg.getname(space)
+ %T - The result of space.type(w_arg).getname(space)
"""
OpErrFmt, strings = get_operationerr_class(valuefmt)
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
@@ -38,16 +38,28 @@
"'%T' object has no attribute '%s'",
space.wrap('foo'), 'foo')
assert operr._compute_value() == "'str' object has no attribute 'foo'"
+ operr = operationerrfmt("w_type",
+ "'%T' object has no attribute '%s'",
+ space.wrap('foo'), 'foo')
+ assert operr._compute_value() == "'str' object has no attribute 'foo'"
def test_operationerrfmt_N(space):
operr = operationerrfmt(space.w_AttributeError,
"'%N' object has no attribute '%s'",
space.type(space.wrap('foo')), 'foo')
assert operr._compute_value() == "'str' object has no attribute 'foo'"
+ operr = operationerrfmt("w_type",
+ "'%N' object has no attribute '%s'",
+ space.type(space.wrap('foo')), 'foo')
+ assert operr._compute_value() == "'str' object has no attribute 'foo'"
operr = operationerrfmt(space.w_AttributeError,
"'%N' object has no attribute '%s'",
space.wrap('foo'), 'foo')
assert operr._compute_value() == "'?' object has no attribute 'foo'"
+ operr = operationerrfmt("w_type",
+ "'%N' object has no attribute '%s'",
+ space.wrap('foo'), 'foo')
+ assert operr._compute_value() == "'?' object has no attribute 'foo'"
def test_operationerrfmt_empty():
py.test.raises(AssertionError, operationerrfmt, "w_type", "foobar")
More information about the pypy-commit
mailing list