[IPython-dev] UTF-8, SVG, _repr_svg_, Python 2

Akim Demaille akim at lrde.epita.fr
Fri Mar 6 02:56:01 EST 2015


Hi!

Congratulations on your efforts!

I have a regression since 3.0 (well, I'm pretty sure it's
a regression, but I no longer have a 2.3 or 2.4 to make sure).
Belong is a scaled down version.  In reality, vcsn is a platform
for automata (vcsn-sandbox.lrde.epita.fr); it renders automata
as SVG graphs via dot.  We have a problem with the rendering of
UTF-8 labels.


This does not work as I would expect:

from IPython.display import SVG
class Foo:
    def _repr_svg_(self):
        return '''<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" encoding="UTF-8" width="400px" height="150px">
<text x="20px" y="55px" font-family="VTCLettererProRegular" font-size="2em">ééééé</text>
</svg>'''
Foo()

I expect to get my string displayed, but I get:

> ---------------------------------------------------------------------------
> UnicodeDecodeError
>                         Traceback (most recent call last)
> 
> <ipython-input-26-56d739c30db3> in <module>()
>      10 <text x="20px" y="55px" font-family="VTCLettererProRegular" font-size="2em">ééééé</text>
>      11
>  </svg>'''
> 
> ---> 12 Foo()
> 
> 
> 
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/IPython/core/displayhook.pyc in __call__(self, result)
>     236                 self.write_format_data(format_dict, md_dict)
>     237                 self.log_output(format_dict)
> --> 238             self.finish_displayhook()
>     239 
>     240     def cull_cache(self):
> 
> 
> 
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/IPython/kernel/zmq/displayhook.pyc in finish_displayhook(self)
>      70         sys.stderr.flush()
>      71         if self.msg['content']['data']:
> ---> 72             self.session.send(self.pub_socket, self.msg, ident=self.topic)
>      73         self.msg = None
>      74 
> 
> 
> 
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/IPython/kernel/zmq/session.pyc in send(self, stream, msg_or_type, content, parent, ident, buffers, track, header, metadata)
>     647         if self.adapt_version:
>     648             msg = adapt(msg, self.adapt_version)
> --> 649         to_send = self.serialize(msg, ident)
>     650         to_send.extend(buffers)
>     651         longest = max([ len(s) for s in to_send ])
> 
> 
> 
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/IPython/kernel/zmq/session.pyc in serialize(self, msg, ident)
>     551             content = self.none
>     552         elif isinstance(content, dict):
> --> 553             content = self.pack(content)
>     554         elif isinstance(content, bytes):
>     555             # content is already packed, as in a relayed message
> 
> 
> 
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/IPython/kernel/zmq/session.pyc in <lambda>(obj)
>      83 # disallow nan, because it's not actually valid JSON
>      84
>  json_packer = lambda obj: jsonapi.dumps(obj, default=date_default,
> 
> ---> 85     ensure_ascii=False, allow_nan=False,
>      86
>  )
> 
>      87 json_unpacker = lambda s: jsonapi.loads(s)
> 
> 
> 
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/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):
> 
> 
> 
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.pyc in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, encoding, default, sort_keys, **kw)
>     248         check_circular=check_circular, allow_nan=allow_nan, indent=indent,
>     249         separators=separators, encoding=encoding, default=default,
> --> 250
>          sort_keys=sort_keys, **kw).encode(obj)
> 
>     251 
>     252 
> 
> 
> 
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.pyc in encode(self, o)
>     208         if not isinstance(chunks, (list, tuple)):
>     209             chunks = list(chunks)
> --> 210         return ''.join(chunks)
>     211 
>     212     def iterencode(self, o, _one_shot=False):
> 
> 
> 
> UnicodeDecodeError
> : 'ascii' codec can't decode byte 0xc3 in position 226: ordinal not in range(128)


However, this works: the SVG is correctly rendered.

SVG(Foo()._repr_svg_())

So there is something somewhere that does not behave as I
would expect.  What am I doing wrong?  Where should I look
for more precise documentation?

Thanks in advance!


More information about the IPython-dev mailing list