Search code examples
pythonexceptionunicodenon-english

possible to raise exception that includes non-english characters in python 2?


I'm trying to raise exception in python 2.7.x which includes a unicode in the message. I can't seem to make it work.

Is it not supported or not recommended to include unicode in error msg? Or do i need to be looking at sys.stderr?

 # -*- coding: utf-8 -*-
 class MyException(Exception):
  def __init__(self, value):
    self.value = value
  def __str__(self):
    return self.value
  def __repr__(self):
    return self.value
  def __unicode__(self):
    return self.value

desc = u'something bad with field \u4443'

try:
  raise MyException(desc)
except MyException as e:
  print(u'Inside try block : ' + unicode(e))

# here is what i wish to make work 
raise MyException(desc)

Running script produces the output below. Inside my try/except i can print the string without problem.

My problem is outside the try/except.

Inside try block : something bad with field 䑃
Traceback (most recent call last):
  File "C:\Python27\lib\bdb.py", line 387, in run
    exec cmd in globals, locals
  File "C:\Users\ghis3080\r.py", line 25, in <module>
    raise MyException(desc)
MyException: something bad with field \u4443

Thanks in advance.


Solution

  • The behaviour depends on Python version and the environment. On Python 3 the character encoding error handler for sys.stderr is always 'backslashreplace':

    from __future__ import unicode_literals, print_function
    import sys
    
    s = 'unicode "\u2323" smile'
    print(s)
    print(s, file=sys.stderr)
    try:
        raise RuntimeError(s)
    except Exception as e:
        print(e.args[0])
        print(e.args[0], file=sys.stderr)
        raise
    

    python3:

    $ PYTHONIOENCODING=ascii:ignore python3 raise_unicode.py
    unicode "" smile
    unicode "\u2323" smile
    unicode "" smile
    unicode "\u2323" smile
    Traceback (most recent call last):
      File "raise_unicode.py", line 8, in <module>
        raise RuntimeError(s)
    RuntimeError: unicode "\u2323" smile
    

    python2:

    $ PYTHONIOENCODING=ascii:ignore python2 raise_unicode.py
    unicode "" smile
    unicode "" smile
    unicode "" smile
    unicode "" smile
    Traceback (most recent call last):
      File "raise_unicode.py", line 8, in <module>
        raise RuntimeError(s)
    RuntimeError
    

    That is on my system the error message is eaten on python2.

    Note: on Windows you could try:

    T:\> set PYTHONIOENCODING=ascii:ignore
    T:\> python raise_unicode.py
    

    For comparison:

    $ python3 raise_unicode.py
    unicode "⌣" smile
    unicode "⌣" smile
    unicode "⌣" smile
    unicode "⌣" smile
    Traceback (most recent call last):
      File "raise_unicode.py", line 8, in <module>
        raise RuntimeError(s)
    RuntimeError: unicode "⌣" smile