diff -r 7f43b10449df jython/Lib/test/test_str_jy.py --- a/jython/Lib/test/test_str_jy.py Tue Jun 10 17:05:31 2008 -0400 +++ b/jython/Lib/test/test_str_jy.py Thu Jun 12 16:18:00 2008 -0400 @@ -4,11 +4,11 @@ class WrappedStrCmpTest(unittest.TestCas class WrappedStrCmpTest(unittest.TestCase): def testWrappedWorksAsKey(self): - '''Test for http://jython.org/bugs/1816134 + """Test for http://jython.org/bugs/1816134 PyString's equal used to check for str explicitly, so Wrapper's __cmp__ wasn't used and a KeyError would be raised by the lookup on ABC. - ''' + """ class Wrapper(object): def __init__(self, content): self.content = content @@ -69,6 +69,27 @@ class FormatTest(unittest.TestCase): s = '%d%d' % (1,) except TypeError, e: self.failUnless("not enough arguments for format string" in str(e)) + + def test_unicode_arg(self): + # When the right-side operand is a unicode, the result should be unicode + # too + self.assertEquals("%s" % u"foo", u"foo") + self.assertEquals("%s" % u"\u00e7", u"\u00e7") + + def test_unicode_in_args(self): + # When at least one of the right-side operands is a unicode, the result + # should be unicode too + self.assertEquals("%s %s" % (u"foo", "bar"), u"foo bar") + self.assertEquals("%s %s" % ("foo", u"bar"), u"foo bar") + + class S(object): + def __str__(self): return "str" + def __unicode__(self): return "unicode" + + # Also, once a unicode has been found, next args should be __unicode__'d + self.assertEquals("%s %s %s" % ("foo", u"bar", S()), u"foo bar unicode") + # But, args found before the first unicode should not be __unicode__'d + self.assertEquals("%s %s %s" % (S(), u"bar", S()), u"str bar unicode") class DisplayTest(unittest.TestCase): diff -r 7f43b10449df jython/src/org/python/core/PyString.java --- a/jython/src/org/python/core/PyString.java Tue Jun 10 17:05:31 2008 -0400 +++ b/jython/src/org/python/core/PyString.java Thu Jun 12 16:18:00 2008 -0400 @@ -2418,7 +2418,7 @@ final class StringFormatter public PyString format(PyObject args) { PyObject dict = null; this.args = args; - boolean needUnicode = false; + boolean needUnicode = unicodeCoercion; if (args instanceof PyTuple) { argIndex = 0; } else { @@ -2512,9 +2512,12 @@ final class StringFormatter switch(c) { case 's': case 'r': + if (arg instanceof PyUnicode) { + needUnicode = true; + } fill = ' '; if (c == 's') - if (unicodeCoercion) + if (needUnicode) string = arg.__unicode__().toString(); else string = arg.__str__().toString(); @@ -2522,9 +2525,6 @@ final class StringFormatter string = arg.__repr__().toString(); if (precision >= 0 && string.length() > precision) { string = string.substring(0, precision); - } - if (arg instanceof PyUnicode) { - needUnicode = true; } break; case 'i':