[pypy-svn] r38647 - in pypy/dist/pypy/objspace: . test
arigo at codespeak.net
arigo at codespeak.net
Mon Feb 12 22:57:06 CET 2007
Author: arigo
Date: Mon Feb 12 22:57:05 2007
New Revision: 38647
Modified:
pypy/dist/pypy/objspace/descroperation.py
pypy/dist/pypy/objspace/test/test_descroperation.py
Log:
(pedronis, arigo)
More longish templates, because string-returning special methods need
to do things slightly differently than int- or float-returning ones
(namely, encode unicode results).
Modified: pypy/dist/pypy/objspace/descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/descroperation.py (original)
+++ pypy/dist/pypy/objspace/descroperation.py Mon Feb 12 22:57:05 2007
@@ -515,11 +515,7 @@
for targetname, specialname, checkerspec in [
('int', '__int__', ("space.w_int", "space.w_long")),
('long', '__long__', ("space.w_int", "space.w_long")),
- ('float', '__float__', ("space.w_float",)),
- ('str', '__str__', ("space.w_str",)),
- ('repr', '__repr__', ("space.w_str",)),
- ('oct', '__oct__', ("space.w_str",)),
- ('hex', '__hex__', ("space.w_str",))]:
+ ('float', '__float__', ("space.w_float",))]:
l = ["space.is_true(space.isinstance(w_result, %s))" % x
for x in checkerspec]
@@ -544,6 +540,40 @@
\n""" % locals()
exec compile2(source)
+for targetname, specialname in [
+ ('str', '__str__'),
+ ('repr', '__repr__'),
+ ('oct', '__oct__'),
+ ('hex', '__hex__')]:
+
+ source = """if 1:
+ def %(targetname)s(space, w_obj):
+ w_impl = space.lookup(w_obj, %(specialname)r)
+ if w_impl is None:
+ raise OperationError(space.w_TypeError,
+ space.wrap("operand does not support unary %(targetname)s"))
+ w_result = space.get_and_call_function(w_impl, w_obj)
+
+ if space.is_true(space.isinstance(w_result, space.w_str)):
+ return w_result
+ try:
+ result = space.str_w(w_result)
+ except OperationError, e:
+ if not e.match(space, space.w_TypeError):
+ raise
+ typename = space.str_w(space.getattr(space.type(w_result),
+ space.wrap('__name__')))
+ msg = '%(specialname)s returned non-%(targetname)s (type %%s)' %% (typename,)
+ raise OperationError(space.w_TypeError, space.wrap(msg))
+ else:
+ # re-wrap the result as a real string
+ return space.wrap(result)
+ assert not hasattr(DescrOperation, %(targetname)r)
+ DescrOperation.%(targetname)s = %(targetname)s
+ del %(targetname)s
+ \n""" % locals()
+ exec compile2(source)
+
# add default operation implementations for all still missing ops
for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable:
Modified: pypy/dist/pypy/objspace/test/test_descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/test/test_descroperation.py (original)
+++ pypy/dist/pypy/objspace/test/test_descroperation.py Mon Feb 12 22:57:05 2007
@@ -247,3 +247,24 @@
check(iexpr, c, a)
check(iexpr, c, b)
check(iexpr, c, 5)
+
+ def test_string_results(self):
+ class A(object):
+ def __str__(self):
+ return answer * 2
+ def __repr__(self):
+ return answer * 3
+ def __hex__(self):
+ return answer * 4
+ def __oct__(self):
+ return answer * 5
+
+ for operate, n in [(str, 2), (repr, 3), (hex, 4), (oct, 5)]:
+ answer = "hello"
+ assert operate(A()) == "hello" * n
+ if operate not in (hex, oct):
+ answer = u"world"
+ assert operate(A()) == "world" * n
+ assert type(operate(A())) is str
+ answer = 42
+ raises(TypeError, operate, A())
More information about the Pypy-commit
mailing list