##// END OF EJS Templates
add Mode menu to editor
add Mode menu to editor

File last commit:

r17023:783754ce
r19319:c847b345
Show More
test_oinspect.py
373 lines | 10.4 KiB | text/x-python | PythonLexer
Fernando Perez
Add function signature info to calltips....
r3051 """Tests for the object inspection functionality.
"""
#-----------------------------------------------------------------------------
Matthias BUSSONNIER
update copyright to 2011/20xx-2011...
r5390 # Copyright (C) 2010-2011 The IPython Development Team.
Fernando Perez
Add function signature info to calltips....
r3051 #
# Distributed under the terms of the BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
from __future__ import print_function
# Stdlib imports
Fernando Perez
Fix finding of file info for magics and decorated functions....
r7290 import os
Fernando Perez
Fix failure due to .pyc/.py mismatch detected by test_pr.
r7434 import re
Fernando Perez
Add function signature info to calltips....
r3051
# Third-party imports
import nose.tools as nt
# Our own imports
from .. import oinspect
Fernando Perez
Add tests for object inspector with magics of all types.
r6995 from IPython.core.magic import (Magics, magics_class, line_magic,
cell_magic, line_cell_magic,
register_line_magic, register_cell_magic,
register_line_cell_magic)
Fernando Perez
Add extra tests for checking decorator logic with __wrapped__.
r7432 from IPython.external.decorator import decorator
Thomas Kluyver
Fix the display of functions with keyword-only arguments on Python 3.
r15335 from IPython.testing.decorators import skipif
Thomas Kluyver
test_oinspect works with Python 3.
r4760 from IPython.utils import py3compat
Fernando Perez
Add function signature info to calltips....
r3051
Fernando Perez
Add extra tests for checking decorator logic with __wrapped__.
r7432
Fernando Perez
Add function signature info to calltips....
r3051 #-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------
inspector = oinspect.Inspector()
Fernando Perez
Add tests for object inspector with magics of all types.
r6995 ip = get_ipython()
Fernando Perez
Add function signature info to calltips....
r3051
#-----------------------------------------------------------------------------
# Local utilities
#-----------------------------------------------------------------------------
Fernando Perez
Fix finding of file info for magics and decorated functions....
r7290 # WARNING: since this test checks the line number where a function is
# defined, if any code is inserted above, the following line will need to be
# updated. Do NOT insert any whitespace between the next line and the function
# definition below.
Thomas Kluyver
Fix the display of functions with keyword-only arguments on Python 3.
r15335 THIS_LINE_NUMBER = 49 # Put here the actual number of this line
Fernando Perez
Fix finding of file info for magics and decorated functions....
r7290 def test_find_source_lines():
nt.assert_equal(oinspect.find_source_lines(test_find_source_lines),
THIS_LINE_NUMBER+1)
Fernando Perez
Fix failure due to .pyc/.py mismatch detected by test_pr.
r7434 # A couple of utilities to ensure these tests work the same from a source or a
# binary install
def pyfile(fname):
Jörgen Stenarson
Moving os.path.normcase call to pyfile function.
r7452 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
Fernando Perez
Fix failure due to .pyc/.py mismatch detected by test_pr.
r7434
def match_pyfiles(f1, f2):
Jörgen Stenarson
Moving os.path.normcase call to pyfile function.
r7452 nt.assert_equal(pyfile(f1), pyfile(f2))
Fernando Perez
Fix failure due to .pyc/.py mismatch detected by test_pr.
r7434
Fernando Perez
Fix finding of file info for magics and decorated functions....
r7290 def test_find_file():
Fernando Perez
Fix failure due to .pyc/.py mismatch detected by test_pr.
r7434 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
Fernando Perez
Fix finding of file info for magics and decorated functions....
r7290
Fernando Perez
Add extra tests for checking decorator logic with __wrapped__.
r7432 def test_find_file_decorated1():
@decorator
def noop1(f):
def wrapper():
return f(*a, **kw)
return wrapper
@noop1
def f(x):
"My docstring"
Fernando Perez
Fix failure due to .pyc/.py mismatch detected by test_pr.
r7434 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
Fernando Perez
Add extra tests for checking decorator logic with __wrapped__.
r7432 nt.assert_equal(f.__doc__, "My docstring")
def test_find_file_decorated2():
@decorator
def noop2(f, *a, **kw):
return f(*a, **kw)
@noop2
def f(x):
"My docstring 2"
Fernando Perez
Fix failure due to .pyc/.py mismatch detected by test_pr.
r7434 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
Fernando Perez
Add extra tests for checking decorator logic with __wrapped__.
r7432 nt.assert_equal(f.__doc__, "My docstring 2")
Fernando Perez
Fix finding of file info for magics and decorated functions....
r7290 def test_find_file_magic():
run = ip.find_line_magic('run')
nt.assert_not_equal(oinspect.find_file(run), None)
Fernando Perez
Add function signature info to calltips....
r3051 # A few generic objects we can then inspect in the tests below
class Call(object):
"""This is the class docstring."""
def __init__(self, x, y=1):
"""This is the constructor docstring."""
def __call__(self, *a, **kw):
"""This is the call docstring."""
def method(self, x, z=2):
"""Some method's docstring"""
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Don't introspect __call__ for simple callables...
r15362 class SimpleClass(object):
def method(self, x, z=2):
"""Some method's docstring"""
Fernando Perez
Add tests for object inspector with magics of all types.
r6995
Thomas Kluyver
Tweak Inspector.info() so it doesn't fail on old style classes. Added test....
r3867 class OldStyle:
"""An old-style class for testing."""
pass
Fernando Perez
Add function signature info to calltips....
r3051
Fernando Perez
Add tests for object inspector with magics of all types.
r6995
Fernando Perez
Add function signature info to calltips....
r3051 def f(x, y=2, *a, **kw):
"""A simple function."""
Fernando Perez
Add tests for object inspector with magics of all types.
r6995
Fernando Perez
Add function signature info to calltips....
r3051 def g(y, z=3, *a, **kw):
pass # no docstring
Fernando Perez
Add tests for object inspector with magics of all types.
r6995 @register_line_magic
def lmagic(line):
"A line magic"
@register_cell_magic
def cmagic(line, cell):
"A cell magic"
@register_line_cell_magic
def lcmagic(line, cell=None):
"A line/cell magic"
@magics_class
class SimpleMagics(Magics):
@line_magic
def Clmagic(self, cline):
"A class-based line magic"
@cell_magic
def Ccmagic(self, cline, ccell):
"A class-based cell magic"
@line_cell_magic
def Clcmagic(self, cline, ccell=None):
"A class-based line/cell magic"
Thomas Kluyver
Catch some pathological cases inside oinspect...
r11058 class Awkward(object):
def __getattr__(self, name):
raise Exception(name)
Fernando Perez
Add function signature info to calltips....
r3051 def check_calltip(obj, name, call, docstring):
"""Generic check pattern all calltip tests will use"""
info = inspector.info(obj, name)
call_line, ds = oinspect.call_tip(info)
nt.assert_equal(call_line, call)
Bernardo B. Marques
remove all trailling spaces
r4872 nt.assert_equal(ds, docstring)
Fernando Perez
Add function signature info to calltips....
r3051
#-----------------------------------------------------------------------------
# Tests
#-----------------------------------------------------------------------------
def test_calltip_class():
check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
def test_calltip_instance():
c = Call(1)
check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
def test_calltip_method():
c = Call(1)
check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
def test_calltip_function():
check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
def test_calltip_function2():
check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
def test_calltip_builtin():
check_calltip(sum, 'sum', None, sum.__doc__)
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Add tests for object inspector with magics of all types.
r6995
def test_calltip_line_magic():
check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
def test_calltip_cell_magic():
check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
Thomas Kluyver
Remove unused imports from IPython.core
r11124 def test_calltip_line_cell_magic():
Fernando Perez
Add tests for object inspector with magics of all types.
r6995 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
"A line/cell magic")
def test_class_magics():
cm = SimpleMagics(ip)
ip.register_magics(cm)
check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
"A class-based line magic")
check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
"A class-based cell magic")
check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
"A class-based line/cell magic")
Thomas Kluyver
Add test that Inspector.info fills out various fields as expected.
r3859 def test_info():
"Check that Inspector.info fills out various fields as expected."
i = inspector.info(Call, oname='Call')
nt.assert_equal(i['type_name'], 'type')
Thomas Kluyver
test_oinspect works with Python 3.
r4760 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
nt.assert_equal(i['base_class'], expted_class)
Thomas Kluyver
Add test that Inspector.info fills out various fields as expected.
r3859 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
fname = __file__
if fname.endswith(".pyc"):
fname = fname[:-1]
Min RK
fix various tests on Windows...
r4105 # case-insensitive comparison needed on some filesystems
# e.g. Windows:
nt.assert_equal(i['file'].lower(), fname.lower())
MinRK
Update signature presentation in pinfo classes...
r15711 nt.assert_equal(i['definition'], None)
Thomas Kluyver
Add test that Inspector.info fills out various fields as expected.
r3859 nt.assert_equal(i['docstring'], Call.__doc__)
Thomas Kluyver
Tweak test_oinspect to only use a common subset of nt.assert_* functions.
r3869 nt.assert_equal(i['source'], None)
Thomas Kluyver
Add test that Inspector.info fills out various fields as expected.
r3859 nt.assert_true(i['isclass'])
nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Add test that Inspector.info fills out various fields as expected.
r3859 i = inspector.info(Call, detail_level=1)
Thomas Kluyver
Tweak test_oinspect to only use a common subset of nt.assert_* functions.
r3869 nt.assert_not_equal(i['source'], None)
nt.assert_equal(i['docstring'], None)
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Add test that Inspector.info fills out various fields as expected.
r3859 c = Call(1)
c.__doc__ = "Modified instance docstring"
i = inspector.info(c)
nt.assert_equal(i['type_name'], 'Call')
nt.assert_equal(i['docstring'], "Modified instance docstring")
nt.assert_equal(i['class_docstring'], Call.__doc__)
nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
MinRK
Update signature presentation in pinfo classes...
r15711 nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Tweak Inspector.info() so it doesn't fail on old style classes. Added test....
r3867 # Test old-style classes, which for example may not have an __init__ method.
Thomas Kluyver
test_oinspect works with Python 3.
r4760 if not py3compat.PY3:
i = inspector.info(OldStyle)
nt.assert_equal(i['type_name'], 'classobj')
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
test_oinspect works with Python 3.
r4760 i = inspector.info(OldStyle())
nt.assert_equal(i['type_name'], 'instance')
nt.assert_equal(i['docstring'], OldStyle.__doc__)
Thomas Kluyver
Add test for oinspect.getdoc
r5538
Thomas Kluyver
Catch some pathological cases inside oinspect...
r11058 def test_info_awkward():
# Just test that this doesn't throw an error.
i = inspector.info(Awkward())
Thomas Kluyver
Don't introspect __call__ for simple callables...
r15362 def test_calldef_none():
# We should ignore __call__ for all of these.
for obj in [f, SimpleClass().method, any, str.upper]:
print(obj)
i = inspector.info(obj)
nt.assert_is(i['call_def'], None)
Thomas Kluyver
Fix the display of functions with keyword-only arguments on Python 3.
r15335 if py3compat.PY3:
exec("def f_kwarg(pos, *, kwonly): pass")
@skipif(not py3compat.PY3)
def test_definition_kwonlyargs():
i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)\n")
Thomas Kluyver
Add test for oinspect.getdoc
r5538 def test_getdoc():
class A(object):
"""standard docstring"""
pass
class B(object):
"""standard docstring"""
def getdoc(self):
return "custom docstring"
Thomas Kluyver
Test for getdoc() returning None.
r5573 class C(object):
"""standard docstring"""
def getdoc(self):
return None
Thomas Kluyver
Add test for oinspect.getdoc
r5538 a = A()
b = B()
Thomas Kluyver
Test for getdoc() returning None.
r5573 c = C()
Thomas Kluyver
Add test for oinspect.getdoc
r5538
nt.assert_equal(oinspect.getdoc(a), "standard docstring")
nt.assert_equal(oinspect.getdoc(b), "custom docstring")
Thomas Kluyver
Test for getdoc() returning None.
r5573 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
Thomas Kluyver
Add failing test for gh-1914
r7460
immerrr
Print sources for property fget/fset/fdel methods...
r17023
def test_empty_property_has_no_source():
i = inspector.info(property(), detail_level=1)
nt.assert_is(i['source'], None)
def test_property_sources():
import zlib
class A(object):
@property
def foo(self):
return 'bar'
foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
id = property(id)
compress = property(zlib.compress)
i = inspector.info(A.foo, detail_level=1)
nt.assert_in('def foo(self):', i['source'])
nt.assert_in('lambda self, v:', i['source'])
i = inspector.info(A.id, detail_level=1)
nt.assert_in('fget = <function id>', i['source'])
i = inspector.info(A.compress, detail_level=1)
nt.assert_in('fget = <function zlib.compress>', i['source'])
def test_property_docstring_is_in_info_for_detail_level_0():
class A(object):
@property
def foobar():
"""This is `foobar` property."""
pass
ip.user_ns['a_obj'] = A()
nt.assert_equals(
'This is `foobar` property.',
ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
ip.user_ns['a_cls'] = A
nt.assert_equals(
'This is `foobar` property.',
ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
Thomas Kluyver
Add failing test for gh-1914
r7460 def test_pdef():
# See gh-1914
def foo(): pass
inspector.pdef(foo, 'foo')
Thomas Kluyver
Add test for non-ascii characters in docstrings...
r11067
def test_pinfo_nonascii():
# See gh-1177
from . import nonascii2
ip.user_ns['nonascii2'] = nonascii2
ip._inspect('pinfo', 'nonascii2', detail_level=1)