QST: Invalid representation of data 
- [x] I have searched the [[pandas] tag](https://stackoverflow.com/questions/tagged/pandas) on StackOverflow for similar questions.

- [ ] I have asked my usage related question on [StackOverflow](https://stackoverflow.com).

---

#### Question about pandas

Hello,

I'm the maintainer of a Python library to store and manipulate (disjunctions of) intervals of arbitrary values (as long as they are comparable). It's called `portion` and it's available on PyPI and also on GitHub (https://github.com/AlexandreDecan/portion). 

This data type defines a `__repr__` method (e.g. the interval from 0 to 1 included is represented as "[0,1]"). When I use this data type in `pandas`, I got a representation that does not correct to what can be expected. Let me provide a very simple example:

```python
>>> import portion as P
>>> P.closed(0, 1)
[0,1]
>>> import pandas as pd
>>> df = pd.DataFrame([P.closed(0,1)])
>>> df
  | 0
-- | --
((([0,1])))
```

As you can see, the expected output has three extra "(" and three extra ")", this is:
EXPECTED OUTPUT= "[0,1]"
CURRENT_OUTPUT = "((([0,1])))"

The same occurs when I display the corresponding index:

```python
>>> df.loc[0]
0    ((([0,1])))
Name: 0, dtype: object
```

But not when I display the corresponding "cell": 
```python
>>> df.loc[0][0]
[0,1]
```

Actually, if I get the object from `df.loc[0][0]`, I got the correct instance and its expected behaviour. 

I looked at how `__repr__` is handled by `pandas` but couldn't find the reason why this occurs. 

For what is worth, here's the implementation of `__repr__` in `portion`(see https://github.com/AlexandreDecan/portion/blob/master/portion/interval.py#L584): 

```python
    def __repr__(self):
        intervals = []

        for interval in self:
            if interval.empty:
                intervals.append('()')
            elif interval.lower == interval.upper:
                intervals.append('[{}]'.format(repr(interval.lower)))
            else:
                intervals.append(
                    '{}{},{}{}'.format(
                        '[' if interval.left == Bound.CLOSED else '(',
                        repr(interval.lower),
                        repr(interval.upper),
                        ']' if interval.right == Bound.CLOSED else ')',
                    )
                )
        return ' | '.join(intervals)
```

In the above snippet, `self` is an `Interval` instance that can be iterated over. Each `interval in self` is an `Interval` instance as well (they correspond to all the atomic intervals you can have in a disjunctive one, e.g., "[0,1] | [3,4]" has two atomic intervals: [0,1] and [3,4]). Each `interval` has several attributes, but the ones of interest here are `left` and `right` (either `Bound.CLOSED` or `Bound.OPEN`, two constants from an enum based on Booleans), and `upper` and `lower` that respectively correspond to the upper bound of the interval and the lower bound of the interval (e.g., for [0,1], upper = 1, and lower = 0). 

FYI, I'm using pandas 1.2.2 but I already got this "issue" with a previous version (unfortunately, I do not remember which one). 

Thank you!
