ipython/ipython — pull request #1910 by int3 (2012-06-11 19:13:59+00:00)
Title: Implement noninvoking attribute get for pinfo

Right now if `a.x` is a data descriptor, `a.x?` evaluates the descriptor and returns its result, instead of returning the descriptor itself. This patch fixes that by emulating Python's native property resolution lookup instead of calling `getattr` directly.

Demo:

class Test2(object):

"""testing 1 2 3"""

def __get__(self, inst, owner):
print "you called __get__"
return 3

def __set__(self, inst, owner):
print "you called __set__"

class Test3(object):

x = Test2()

a = Test3()

Running this script under IPython, `a.x?` gives us

you called __get__
you called __get__
Type: int
Base Class:
String Form:3
Namespace: Interactive
Docstring:
int(x[, base]) -> integer

Convert a string or number to an integer, if possible. ...

With the new patch, we get

Type: Test2
Base Class:
String Form:<__main__.Test2 object at 0x102efdfd0>
Namespace: Interactive
Docstring: testing 1 2 3

I have yet to write tests, but I wanted to bring this up for discussion to make sure it's really wanted -- there will probably be quite a number of tests necessary to make sure that our emulation of `object.__getattribute___()` is correct.

This deals with the 'executing the function' problem in issue #1555.

There's also the question of whether we want to print the contents of `__get__()` and `__set__()` for these descriptors, or if we want to leave it to the user to manually look up `Test2.__get__()`. If we do print these out, note that we will have to special-case it for Python's `@property` descriptors -- `__get__()` is natively implemented for them, so it makes more sense to print out the contents of `fget` in their case.