ipython / ipython/ipython

Problems with _repr_*_ in IPython when using SymPy

Open
#8,938 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
16.8k
Forks
4.5k
Avg merge
1d 2h
Merged PRs (30d)
6

Description

Hi all,

This is modified from an issue in the SymPy repository (sympy/sympy#10062) as it was a bit unclear to me whether it is a SymPy issue or an IPython issue. I've been trying to get some objects to output with LaTeX rendering in IPython notebooks, and I have been getting some sort of collision with the state of the sympy printing system (regardless of whether my objects actually use sympy). That is to say, if I call `sympy.init_printing()`, it can break the rendering of other objects. In general, is this to be expected?

To be more concrete, here is a minimal example: Consider a `Parameter` class which knows how to render to LaTex using the IPython function `_repr_latex_()`:

```
class Parameter(object):
def __init__(self, symbol):
self.symbol = symbol
def _repr_latex_(self):
return '$'+self.symbol+'$'
```

If I create some instances of this, e.g.

```
density = Parameter('\\rho')
gravity = Parameter('g')
```

they output as expected. If I make a list of these, they do not render, as expected, since it is a list:

```
[gravity, density]
```

No matter, I can try to subclass the builtin `list` with a `_repr_latex_()` function:

```
class ParameterList(list):
def _repr_latex_(self):
string = '$'
for n in range(len(self)):
string += self.__getitem__(n).symbol
if n != len(self)-1:
string += ', '
string += '$'
return string
```

and this allows me to do what I want with interactive IPython development:

```
plist = ParameterList([density,gravity])
plist
```

which nicely renders the list.

My problem is when `sympy.init_printing()` is called, this code breaks. Instead of printing a list of LaTeX typeset strings, it seems to fall back on the default python list `__repr__()`.

A fix that I have found involves calling the `for_type()` function in the IPython latex formatter. Defining the `ParameterList` class using

```
class ParameterList(list):
def latex_print(self):
string = '$'
for n in range(len(self)):
string += self.__getitem__(n).symbol
if n != len(self)-1:
string += ', '
string += '$'
return string

get_ipython().display_formatter.formatters['text/latex'].for_type(ParameterList,\
ParameterList.latex_print)

plist = ParameterList([density,gravity])
plist
```

produces the desired output.

So I am getting different behavior depending upon whether I register the latex output using `for_type()` or whether I register it using `_repr_latex_()`, and it has some complicated interactions with the SymPy printing system. Any ideas as to what could be causing this, and if there is a simple fix?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.