[Jython-checkins] jython: Exceptions with non-ascii args should not cause in exception when displayed

jim.baker jython-checkins at python.org
Sat Mar 14 04:08:19 CET 2015


https://hg.python.org/jython/rev/e23b59d070c0
changeset:   7612:e23b59d070c0
user:        Jim Baker <jim.baker at rackspace.com>
date:        Fri Mar 13 21:08:02 2015 -0600
summary:
  Exceptions with non-ascii args should not cause in exception when displayed

sys.excepthook, via Py#displayException, was failing with
UnicodeEncodeError when printing such exceptions (since that's the
behavior of __str__). Now conforms to what CPython does in this case:
only display the exception type if any exception is raised by __str__.

files:
  Lib/test/test_exceptions_jy.py         |  22 +++++++++++++-
  src/org/python/core/Py.java            |   6 +++-
  src/org/python/core/PyException.java   |   4 +-
  src/org/python/core/StdoutWrapper.java |   4 +-
  4 files changed, 30 insertions(+), 6 deletions(-)


diff --git a/Lib/test/test_exceptions_jy.py b/Lib/test/test_exceptions_jy.py
--- a/Lib/test/test_exceptions_jy.py
+++ b/Lib/test/test_exceptions_jy.py
@@ -2,9 +2,10 @@
 
 Made for Jython.
 """
-from test import test_support
+import sys
 import unittest
 from javatests import StackOverflowErrorTest
+from test import test_support
 
 
 class C:
@@ -56,6 +57,25 @@
             cm.exception.message,
             "maximum recursion depth exceeded (Java StackOverflowError)")
 
+    def test_unicode_args(self):
+        e = RuntimeError(u"Drink \u2615")  # coffee emoji
+        # Can take the repr of any object
+        self.assertEqual(repr(e), "RuntimeError(u'Drink \u2615',)")
+        # Cannot of course turn a non-ascii Unicode object into a str, even if it's an exception object
+        with self.assertRaises(UnicodeEncodeError) as cm:
+            str(e)
+        self.assertEqual(
+            str(cm.exception),
+            "'ascii' codec can't encode character u'\u2615' in position 6: ordinal not in range(128)")
+        # But the exception hook, via Py#displayException, does not fail when attempting to __str__ the exception args
+        with test_support.captured_stderr() as s:
+            sys.excepthook(RuntimeError, u"Drink \u2615", None)
+        self.assertEqual(s.getvalue(), "RuntimeError\n")  
+        # It is fine with ascii values, of course
+        with test_support.captured_stderr() as s:
+            sys.excepthook(RuntimeError, u"Drink java", None)
+        self.assertEqual(s.getvalue(), "RuntimeError: Drink java\n")  
+
 
 def test_main():
     test_support.run_unittest(ExceptionsTestCase)
diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java
--- a/src/org/python/core/Py.java
+++ b/src/org/python/core/Py.java
@@ -1185,7 +1185,11 @@
                 stderr.println(getStackTrace((Throwable) javaError));
             }
         }
-        stderr.println(formatException(type, value));
+        try {
+            stderr.println(formatException(type, value));
+        } catch (Exception ex) {
+            stderr.println(formatException(type, Py.None));
+        }
     }
 
     /**
diff --git a/src/org/python/core/PyException.java b/src/org/python/core/PyException.java
--- a/src/org/python/core/PyException.java
+++ b/src/org/python/core/PyException.java
@@ -3,7 +3,7 @@
 import java.io.*;
 
 /**
- * A wrapper for all python exception. Note that the wellknown python exception are <b>not</b>
+ * A wrapper for all python exception. Note that the well-known python exceptions are <b>not</b>
  * subclasses of PyException. Instead the python exception class is stored in the <code>type</code>
  * field and value or class instance is stored in the <code>value</code> field.
  */
@@ -58,7 +58,7 @@
     }
 
     public PyException(PyObject type, String value) {
-        this(type, new PyString(value));
+        this(type, Py.newStringOrUnicode(value));
     }
 
     private boolean printingStackTrace = false;
diff --git a/src/org/python/core/StdoutWrapper.java b/src/org/python/core/StdoutWrapper.java
--- a/src/org/python/core/StdoutWrapper.java
+++ b/src/org/python/core/StdoutWrapper.java
@@ -248,11 +248,11 @@
     }
 
     public void print(String s) {
-        print(new PyString(s), false, false);
+        print(Py.newStringOrUnicode(s), false, false);
     }
 
     public void println(String s) {
-        print(new PyString(s), false, true);
+        print(Py.newStringOrUnicode(s), false, true);
     }
 
     public void print(PyObject o) {

-- 
Repository URL: https://hg.python.org/jython


More information about the Jython-checkins mailing list