Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Customize Class representation lib.pretty #2379

Open
jbvsmo opened this Issue · 8 comments

4 participants

@jbvsmo

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
@rkern

_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

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
Owner
@Carreau
Owner

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
Owner

closing.

@Carreau Carreau closed this
@takluyver
Owner

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

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
Owner

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

@takluyver takluyver reopened this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.