Problems with _repr_*_ in IPython when using SymPy
- 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
Assessment
This issue has not been assessed yet.