Author: Armin Rigo <[email protected]>
Branch:
Changeset: r78730:f467823cb467
Date: 2015-07-31 17:43 +0200
http://bitbucket.org/pypy/pypy/changeset/f467823cb467/
Log: Issue #2095: test and fix
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -711,11 +711,17 @@
w_item = self.popvalue()
if self.space.is_w(w_stream, self.space.w_None):
w_stream = sys_stdout(self.space) # grumble grumble special cases
- print_item_to(self.space, w_item, w_stream)
+ print_item_to(self.space, self._printable_object(w_item), w_stream)
def PRINT_ITEM(self, oparg, next_instr):
w_item = self.popvalue()
- print_item(self.space, w_item)
+ print_item(self.space, self._printable_object(w_item))
+
+ def _printable_object(self, w_obj):
+ space = self.space
+ if not space.isinstance_w(w_obj, space.w_unicode):
+ w_obj = space.str(w_obj)
+ return w_obj
def PRINT_NEWLINE_TO(self, oparg, next_instr):
w_stream = self.popvalue()
@@ -1535,9 +1541,9 @@
stream.write(" ")
# give to write() an argument which is either a string or a unicode
- # (and let it deals itself with unicode handling)
- if not isinstance(x, unicode):
- x = str(x)
+ # (and let it deals itself with unicode handling). The check "is
+ # unicode" should not use isinstance() at app-level, because that
+ # could be fooled by strange objects, so it is done at interp-level.
stream.write(x)
# add a softspace unless we just printed a string which ends in a '\t'
diff --git a/pypy/interpreter/test/test_interpreter.py
b/pypy/interpreter/test/test_interpreter.py
--- a/pypy/interpreter/test/test_interpreter.py
+++ b/pypy/interpreter/test/test_interpreter.py
@@ -299,6 +299,30 @@
finally:
sys.stdout = save
+ def test_print_strange_object(self):
+ import sys
+
+ class A(object):
+ def __getattribute__(self, name):
+ print "seeing", name
+ def __str__(self):
+ return 'A!!'
+ save = sys.stdout
+ class Out(object):
+ def __init__(self):
+ self.data = []
+ def write(self, x):
+ self.data.append((type(x), x))
+ sys.stdout = out = Out()
+ try:
+ a = A()
+ assert out.data == []
+ print a
+ assert out.data == [(str, 'A!!'),
+ (str, '\n')]
+ finally:
+ sys.stdout = save
+
def test_identity(self):
def f(x): return x
assert f(666) == 666
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit