jrjohansson / version_information

IPython magic command for showing version information for dependency modules in a notebook.
54 stars 17 forks source link

Unicode Exception #11

Open martinATtug opened 8 years ago

martinATtug commented 8 years ago

With WinPython 2.7 (both 2.7.9.3 and 2.7.10.2) on Windows 10 I get this exception.

---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-14-6487eb462c4a> in <module>()
      1 #%install_ext http://raw.github.com/jrjohansson/version_information/master/version_information.py>
      2 get_ipython().magic(u'reload_ext version_information')
----> 3 get_ipython().magic(u'version_information')

L:\Andere Software\WinPython-32bit-2.7.9.3\python-2.7.9\lib\site-packages\IPython\core\displayhook.pyc in __call__(self, result)
    254             self.update_user_ns(result)
    255             self.log_output(format_dict)
--> 256             self.finish_displayhook()
    257 
    258     def flush(self):

L:\Andere Software\WinPython-32bit-2.7.9.3\python-2.7.9\lib\site-packages\IPython\kernel\zmq\displayhook.pyc in finish_displayhook(self)
     63         sys.stdout.flush()
     64         sys.stderr.flush()
---> 65         self.session.send(self.pub_socket, self.msg, ident=self.topic)
     66         self.msg = None
     67 

L:\Andere Software\WinPython-32bit-2.7.9.3\python-2.7.9\lib\site-packages\IPython\kernel\zmq\session.pyc in send(self, stream, msg_or_type, content, parent, ident, buffers, track, header, metadata)
    642             return
    643         buffers = [] if buffers is None else buffers
--> 644         to_send = self.serialize(msg, ident)
    645         to_send.extend(buffers)
    646         longest = max([ len(s) for s in to_send ])

L:\Andere Software\WinPython-32bit-2.7.9.3\python-2.7.9\lib\site-packages\IPython\kernel\zmq\session.pyc in serialize(self, msg, ident)
    549             content = self.none
    550         elif isinstance(content, dict):
--> 551             content = self.pack(content)
    552         elif isinstance(content, bytes):
    553             # content is already packed, as in a relayed message

L:\Andere Software\WinPython-32bit-2.7.9.3\python-2.7.9\lib\site-packages\IPython\kernel\zmq\session.pyc in <lambda>(obj)
     90 
     91 # ISO8601-ify datetime objects
---> 92 json_packer = lambda obj: jsonapi.dumps(obj, default=date_default)
     93 json_unpacker = lambda s: jsonapi.loads(s)
     94 

L:\Andere Software\WinPython-32bit-2.7.9.3\python-2.7.9\lib\site-packages\zmq\utils\jsonapi.pyc in dumps(o, **kwargs)
     38         kwargs['separators'] = (',', ':')
     39 
---> 40     s = jsonmod.dumps(o, **kwargs)
     41 
     42     if isinstance(s, unicode):

L:\Andere Software\WinPython-32bit-2.7.9.3\python-2.7.9\lib\site-packages\simplejson\__init__.pyc in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, encoding, default, use_decimal, namedtuple_as_object, tuple_as_array, bigint_as_string, sort_keys, item_sort_key, for_json, ignore_nan, int_as_string_bitcount, **kw)
    384         ignore_nan=ignore_nan,
    385         int_as_string_bitcount=int_as_string_bitcount,
--> 386         **kw).encode(obj)
    387 
    388 

L:\Andere Software\WinPython-32bit-2.7.9.3\python-2.7.9\lib\site-packages\simplejson\encoder.pyc in encode(self, o)
    267         # exceptions aren't as detailed.  The list call should be roughly
    268         # equivalent to the PySequence_Fast that ''.join() would do.
--> 269         chunks = self.iterencode(o, _one_shot=True)
    270         if not isinstance(chunks, (list, tuple)):
    271             chunks = list(chunks)

L:\Andere Software\WinPython-32bit-2.7.9.3\python-2.7.9\lib\site-packages\simplejson\encoder.pyc in iterencode(self, o, _one_shot)
    346                 Decimal=Decimal)
    347         try:
--> 348             return _iterencode(o, 0)
    349         finally:
    350             key_memo.clear()

UnicodeDecodeError: 'utf8' codec can't decode byte 0xe4 in position 263: invalid continuation byte

Peeking into the source and changing at line 131

        try:
            html += "<tr><td colspan='2'>%s</td></tr>" % time.strftime(timefmt)
        except:
            html += "<tr><td colspan='2'>%s</td></tr>" % \
                time.strftime(timefmt).decode(_date_format_encoding())

into the except clause only

        html += "<tr><td colspan='2'>%s</td></tr>" % \
            time.strftime(timefmt).decode(_date_format_encoding())

did the trick for me:

Software Version
Python 2.7.10 64bit [MSC v.1500 64 bit (AMD64)]
IPython 3.2.1
OS Windows 8 6.2.9200
Sat Dec 05 20:57:30 2015 Mitteleuropäische Zeit

It seems the try clause interpolates a CP1252 umlaut into the html and that causes simplejson to throw later on. Python 3 is not affected.

UPDATE: The above hack fails on WindowsXP. Changing timefmt on line 64 from '%a %b %d %H:%M:%S %Y %Z' to '%a %b %d %H:%M:%S %Y' (i.e. dropping %Z) is a remedy.