How to find hidden attributes of Python objects? (attributes that don't appear in the dir(obj) list)

python, reflection

Solution

The `dir()` does not try to provide a complete output, just a reasonable approximation that is useful in the interactive interpreter.

The reason for `dir` to not include `__mro__` and `mro` in the output can be found in the source code, under `Objects/object.c` at line 1812:

/* Helper for PyObject_Dir of type objects: returns __dict__ and __bases__.
   We deliberately don't suck up its __class__, as methods belonging to the
   metaclass would probably be more confusing than helpful.
*/
static PyObject *
_specialized_dir_type(PyObject *obj)

And turns out that the `mro` method and the `__mro__` attribute are actually attributes of the metaclass, i.e. of `type`:

>>> '__mro__' in object.__dict__
False
>>> '__mro__' in type.__dict__
True
>>> 'mro' in object.__dict__
False
>>> 'mro' in type.__dict__
True

Hence they are not shown in the output of `dir`. Whether this is sensible or not depends. I believe most of the time you really do not want to see what the metaclass defines, since they are internals of the metaclass.

As explained in the documentation for dir() you can customize its output defining a `__dir__` method. However this applies to the instances of the class:

class A(object):
  def __dir__(self):
    return ['a', 'b', 'c']

print(dir(A()), dir(A))

Output:

(['a', 'b', 'c'], ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'])

If you want to customize also the output of `dir(A)` you have to use a custom metaclass:

class MyMeta(type):
  def __dir__(self):
    return ['a', 'b', 'c']


class A(object, metaclass=MyMeta):
  # __metaclass__ = MyMeta   # in python 2

  def __dir__(self):
    return ['a', 'b', 'c', 'd']


print(dir(A()), dir(A))

Output:

(['a', 'b', 'c', 'd'], ['a', 'b', 'c'])

Problem

I'm using IPython. I declared a simple class `MyClass(object)`, and in the console, when using the name MyClass, after the `dot` operator, i hit `Tab`. One of the first suggestions i got was `mro`, meaning `MyClass.mro`. I hit enter, and the output i get is: ``` > <function mro> ``` Now i didn't define this method, and of course it returns the method resolution order of my class. This method doesn't appear in the list returned by `dir(MyClass)`, and so here comes my question: How would I find any other such hidden features of classes or other objects?

Original source

Related problems