Repository: ipython/ipython

Issue:
test_oinspect fails with python3.4
test_oinspect fails with python3.4 in current git head and 1.x branch, e.g.

```
$ python3.4 /local/bin/iptest3 IPython.core.tests.test_oinspect
...
======================================================================
FAIL: IPython.core.tests.test_oinspect.test_calltip_method
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
    self.test(*self.arg)
  File "/local/lib/python3.4/site-packages/IPython/core/tests/test_oinspect.py", line 188, in test_calltip_method
    check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
  File "/local/lib/python3.4/site-packages/IPython/core/tests/test_oinspect.py", line 171, in check_calltip
    nt.assert_equal(ds, docstring)
nose.proxy.AssertionError: 'Calls self as a function.' != "Some method's docstring"
- Calls self as a function.
+ Some method's docstring

    """Fail immediately, with the given message."""
>>  raise self.failureException('\'Calls self as a function.\' != "Some method\'s docstring"\n- Calls self as a function.\n+ Some method\'s docstring\n')
```

8 of these fail.
they succeed with 3.3



Discussion:
They're all passing on my system (Debian, Python 3.4b2)

Hm, `iptest core` passes here (OS X 10.9.1) on 3.4.0b2.

I get the failures in ubuntu with 3.4.0b3, debian with 3.4.0b2 it works

updated debian to b3 and also get the failure, might be a python regression

Just updated to b3 and it started failing. Looks like a Python regression. Will look into what's actually responsible.

Yep, I see the failures here as well.


Resolving patch:
diff --git a/IPython/core/oinspect.py b/IPython/core/oinspect.py
--- a/IPython/core/oinspect.py
+++ b/IPython/core/oinspect.py
@@ -42,6 +42,12 @@
 from IPython.utils.coloransi import *
 from IPython.utils.py3compat import cast_unicode, string_types
 
+# builtin docstrings to ignore
+_func_call_docstring = types.FunctionType.__call__.__doc__
+_object_init_docstring = object.__init__.__doc__
+_builtin_type_docstrings = {
+    t.__doc__ for t in (types.ModuleType, types.MethodType, types.FunctionType)
+}
 #****************************************************************************
 # Builtin color schemes
 
@@ -732,8 +738,8 @@ def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
                 init_def = self._getdef(obj_init,oname)
                 init_ds  = getdoc(obj_init)
                 # Skip Python's auto-generated docstrings
-                if init_ds and \
-                       init_ds.startswith('x.__init__(...) initializes'):
+                print(init_ds)
+                if init_ds == _object_init_docstring:
                     init_ds = None
 
             if init_def or init_ds:
@@ -756,10 +762,7 @@ def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
                 else:
                     class_ds = getdoc(cls)
                 # Skip Python's auto-generated docstrings
-                if class_ds and \
-                       (class_ds.startswith('function(code, globals[,') or \
-                   class_ds.startswith('instancemethod(function, instance,') or \
-                   class_ds.startswith('module(name[,') ):
+                if class_ds in _builtin_type_docstrings:
                     class_ds = None
                 if class_ds and ds != class_ds:
                     out['class_docstring'] = class_ds
@@ -768,8 +771,7 @@ def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
             try:
                 init_ds = getdoc(obj.__init__)
                 # Skip Python's auto-generated docstrings
-                if init_ds and \
-                       init_ds.startswith('x.__init__(...) initializes'):
+                if init_ds == _object_init_docstring:
                     init_ds = None
             except AttributeError:
                 init_ds = None
@@ -783,7 +785,7 @@ def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
                     out['call_def'] = self.format(call_def)
                 call_ds = getdoc(obj.__call__)
                 # Skip Python's auto-generated docstrings
-                if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
+                if call_ds == _func_call_docstring:
                     call_ds = None
                 if call_ds:
                     out['call_docstring'] = call_ds


Test patch: