Customize Class representation lib.pretty #2379

Open
jbvsmo opened this Issue Sep 4, 2012 · 8 comments

Projects

None yet

4 participants

@jbvsmo
jbvsmo commented Sep 4, 2012

I have a project with metaclasses setting the __repr__ method of my classes with nice information. It seems to not be possible to show this kind of thing because the classes are printed with lib.pretty._type_pprint and the lib.pretty.for_type function does nothing at all.

Also adding _repr_pretty_ to the metaclass does not work at all

Maybe I'm using the wrong functions, but this is all that I tried.

Some example code:

#Py3k syntax
class Meta(type):
    def __repr__(self):
        return "This information"

class C(metaclass=Meta):
    pass

So, using C in IPython will print the_module.C instead of This information

@rkern rkern was assigned Sep 4, 2012
@rkern
rkern commented Sep 4, 2012

_repr_pretty_ works for me:

[~]
|8> class A(type):
..>     def _repr_pretty_(self, p, cycle):
..>         p.text('This information')
..>         

[~]
|9> class B(object):
..>     __metaclass__ = A
..>     

[~]
|10> B
This information

I'm not entirely sure how to formulate a robust test that _type_pprint() could use to detect if the __repr__ is overridden for the metaclass. If you can formulate one, let me know.

IPython.lib.pretty.for_type() is left over from the third-party implementation. It is not part of IPython's API. Instead, you use the methods on PlainTextFormatter:
http://ipython.org/ipython-doc/rel-0.13/api/generated/IPython.core.formatters.html#IPython.core.formatters.BaseFormatter
http://ipython.org/ipython-doc/rel-0.13/api/generated/IPython.core.formatters.html#IPython.core.formatters.PlainTextFormatter.for_type

@jbvsmo
jbvsmo commented Sep 4, 2012

Maybe it is my version of IPython (0.12) but this is what I get:

In [1]: class A(type):
   ...:      def _repr_pretty_(self, p, cycle):
   ...:          p.text('This information')
   ...:

In [2]: class B(object):
   ...:     __metaclass__ = A
   ...:

In [3]: B
Out[3]: __main__.B

I tried with both Python2 and Python3 versions and had the same result.


As for a test, you can do:

if type(the_class).__repr__ is not type.__repr__:
    print('it was changed in the metaclass!')

It will guarantee it was overhidden by some metaclass

@takluyver
Member

Definining repr_pretty on the metaclass like that works for me with the
development version, both in Python 2 and 3 (using the appropriate syntax
for metaclasses in each case). So maybe we have fixed something since 0.12.

@Carreau
Member
Carreau commented Sep 4, 2012

using git bisect the other way around

bbd672e1bcb210622befa0e094a4e17e160ea2ba is the first bad commit
commit bbd672e1bcb210622befa0e094a4e17e160ea2ba
Author: Walter Doerwald <walter@livinglogic.de>
Date:   Fri Mar 30 15:25:49 2012 +0200

    Don't use getattr() when searching for the _repr_pretty_ method.

    Using getattr() might find a method in a base class, when a registered
    printer for a baseclass later in the mro is the better fit.

:040000 040000 f64e6179c9111775972473836962149bb7f901e8 25211ca93b372e1c55650d35dc700c6781a70455 M  IPython

rel-0.12-425-gbbd672e, pr #1535

@Carreau
Member
Carreau commented Sep 4, 2012

closing.

@Carreau Carreau closed this Sep 4, 2012
@takluyver
Member

Do we need to clean up the API of IPython.lib.pretty? It seems from earlier comments that there's a top level for_type() function that isn't effective, and class methods should be used instead.

Also, is it worth trying to work it out so that pretty respects __repr__ defined on a metaclass?

@jbvsmo
jbvsmo commented Sep 4, 2012

I would appreciate to see that because it is weird to add code to a generic class to make it IPython friendly.
BTW, thanks for the help.

@takluyver
Member

OK, I'll reopen this for now, as it sounds like there's still something to be improved on.

@takluyver takluyver reopened this Sep 4, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment