Print sources for fget/fset/fdel property methods

This is a work-in-progress fixing issue #1555 which has been bugging me for quite a while. Here's what it is capable of now:

```python

In [1]: def foo(x): return id(x)

In [2]: p = property(foo, lambda x,val: None, id)

In [3]: p?
Type:       property
String Form:<property object at 0x2c52c00>
File:       /home/immerrr/sources/<ipython-input-1-8d2e34e1a2b1>
Docstring:  <no docstring>

In [4]: p??
Type:       property
String Form:<property object at 0x2c52c00>
File:       /home/immerrr/sources/<ipython-input-1-8d2e34e1a2b1>
Getter:     def foo(x): return id(x)

Setter:     p = property(foo, lambda x,val: None, id)

Deleter:    <function id>

In [5]: class Foo(object):
   ...:     @property
   ...:     def bar(self):
   ...:         return None
   ...:     

In [6]: f = Foo()

In [7]: f.bar?
Type:       property
String Form:<property object at 0x2f84aa0>
File:       /home/immerrr/sources/<ipython-input-5-64d3245b5460>
Docstring:  <no docstring>

In [8]: f.bar??
Type:       property
String Form:<property object at 0x2f84aa0>
File:       /home/immerrr/sources/<ipython-input-5-64d3245b5460>
Getter:
    @property
    def bar(self):
        return None

```

Admittedly, this is not perfect, so ideas about what's missing are welcome. What I think is missing:
- [x] tests (didn't look how testing is done in IPython, nor do I have an idea how to test this properly)
- [x] get rid of newlines that still appear after one-liner source snippets
- [x] stop invoking property getter when querying as it may cause unintended side-effects and/or raise an error rendering the property inaccessible 
re: single-? — Apparently, `inspect.getdoc(property(...))` already looks up proper docstring and so, as long as property objects are found via `ofind`, it should work. It doesn't currently work for other descriptors, like slot attributes, though:
```python
In [66]: ar = np.array([1])

In [67]: ar.shape?
Type:        tuple
String form: (1,)
Length:      1
Docstring:
tuple() -> empty tuple
tuple(iterable) -> tuple initialized from iterable's items

If the argument is a tuple, the return value is the same object.

In [68]: np.ndarray.shape?
Type:        getset_descriptor
String form: <attribute 'shape' of 'numpy.ndarray' objects>
Docstring:
Tuple of array dimensions.

Notes
-----
May be used to "reshape" the array, as long as this would not
require a change in the total number of elements

Examples
--------
>>> x = np.array([1, 2, 3, 4])
>>> x.shape
(4,)
>>> y = np.zeros((2, 3, 4))
>>> y.shape
(2, 3, 4)
>>> y.shape = (3, 8)
>>> y
array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])
>>> y.shape = (3, 6)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: total size of new array must be unchanged


```