Show More
@@ -39,8 +39,8 b' from IPython.utils import py3compat' | |||||
39 | from IPython.utils.dir2 import safe_hasattr |
|
39 | from IPython.utils.dir2 import safe_hasattr | |
40 | from IPython.utils.text import indent |
|
40 | from IPython.utils.text import indent | |
41 | from IPython.utils.wildcard import list_namespace |
|
41 | from IPython.utils.wildcard import list_namespace | |
42 |
from IPython.utils.coloransi import |
|
42 | from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable | |
43 | from IPython.utils.py3compat import cast_unicode, string_types |
|
43 | from IPython.utils.py3compat import cast_unicode, string_types, PY3 | |
44 |
|
44 | |||
45 | # builtin docstrings to ignore |
|
45 | # builtin docstrings to ignore | |
46 | _func_call_docstring = types.FunctionType.__call__.__doc__ |
|
46 | _func_call_docstring = types.FunctionType.__call__.__doc__ | |
@@ -181,26 +181,17 b' def getsource(obj,is_binary=False):' | |||||
181 | return cast_unicode(src, encoding=encoding) |
|
181 | return cast_unicode(src, encoding=encoding) | |
182 |
|
182 | |||
183 | def getargspec(obj): |
|
183 | def getargspec(obj): | |
184 | """Get the names and default values of a function's arguments. |
|
184 | """Wrapper around :func:`inspect.getfullargspec` on Python 3, and | |
185 |
|
185 | :func:inspect.getargspec` on Python 2. | ||
186 | A tuple of four things is returned: (args, varargs, varkw, defaults). |
|
186 | ||
187 | 'args' is a list of the argument names (it may contain nested lists). |
|
187 | In addition to functions and methods, this can also handle objects with a | |
188 | 'varargs' and 'varkw' are the names of the * and ** arguments or None. |
|
188 | ``__call__`` attribute. | |
189 | 'defaults' is an n-tuple of the default values of the last n arguments. |
|
189 | """ | |
190 |
|
190 | if not (inspect.isfunction(obj) or inspect.ismethod(obj)) \ | ||
191 | Modified version of inspect.getargspec from the Python Standard |
|
191 | and safe_hasattr(obj, '__call__'): | |
192 | Library.""" |
|
192 | obj = obj.__call__ | |
193 |
|
193 | |||
194 | if inspect.isfunction(obj): |
|
194 | return inspect.getfullargspec(obj) if PY3 else inspect.getargspec(obj) | |
195 | func_obj = obj |
|
|||
196 | elif inspect.ismethod(obj): |
|
|||
197 | func_obj = obj.__func__ |
|
|||
198 | elif hasattr(obj, '__call__'): |
|
|||
199 | func_obj = obj.__call__ |
|
|||
200 | else: |
|
|||
201 | raise TypeError('arg is not a Python function') |
|
|||
202 | args, varargs, varkw = inspect.getargs(func_obj.__code__) |
|
|||
203 | return args, varargs, varkw, func_obj.__defaults__ |
|
|||
204 |
|
195 | |||
205 |
|
196 | |||
206 | def format_argspec(argspec): |
|
197 | def format_argspec(argspec): | |
@@ -354,7 +345,6 b' class Inspector:' | |||||
354 |
|
345 | |||
355 | If any exception is generated, None is returned instead and the |
|
346 | If any exception is generated, None is returned instead and the | |
356 | exception is suppressed.""" |
|
347 | exception is suppressed.""" | |
357 |
|
||||
358 | try: |
|
348 | try: | |
359 | hdef = oname + inspect.formatargspec(*getargspec(obj)) |
|
349 | hdef = oname + inspect.formatargspec(*getargspec(obj)) | |
360 | return cast_unicode(hdef) |
|
350 | return cast_unicode(hdef) | |
@@ -613,7 +603,6 b' class Inspector:' | |||||
613 |
|
603 | |||
614 | obj_type = type(obj) |
|
604 | obj_type = type(obj) | |
615 |
|
605 | |||
616 | header = self.__head |
|
|||
617 | if info is None: |
|
606 | if info is None: | |
618 | ismagic = 0 |
|
607 | ismagic = 0 | |
619 | isalias = 0 |
|
608 | isalias = 0 | |
@@ -803,13 +792,18 b' class Inspector:' | |||||
803 |
|
792 | |||
804 | if callable_obj: |
|
793 | if callable_obj: | |
805 | try: |
|
794 | try: | |
806 |
args |
|
795 | argspec = getargspec(callable_obj) | |
807 | except (TypeError, AttributeError): |
|
796 | except (TypeError, AttributeError): | |
808 | # For extensions/builtins we can't retrieve the argspec |
|
797 | # For extensions/builtins we can't retrieve the argspec | |
809 | pass |
|
798 | pass | |
810 | else: |
|
799 | else: | |
811 | out['argspec'] = dict(args=args, varargs=varargs, |
|
800 | # named tuples' _asdict() method returns an OrderedDict, but we | |
812 | varkw=varkw, defaults=defaults) |
|
801 | # we want a normal | |
|
802 | out['argspec'] = argspec_dict = dict(argspec._asdict()) | |||
|
803 | # We called this varkw before argspec became a named tuple. | |||
|
804 | # With getfullargspec it's also called varkw. | |||
|
805 | if 'varkw' not in argspec_dict: | |||
|
806 | argspec_dict['varkw'] = argspec_dict.pop('keywords') | |||
813 |
|
807 | |||
814 | return object_info(**out) |
|
808 | return object_info(**out) | |
815 |
|
809 |
@@ -27,6 +27,7 b' from IPython.core.magic import (Magics, magics_class, line_magic,' | |||||
27 | register_line_magic, register_cell_magic, |
|
27 | register_line_magic, register_cell_magic, | |
28 | register_line_cell_magic) |
|
28 | register_line_cell_magic) | |
29 | from IPython.external.decorator import decorator |
|
29 | from IPython.external.decorator import decorator | |
|
30 | from IPython.testing.decorators import skipif | |||
30 | from IPython.utils import py3compat |
|
31 | from IPython.utils import py3compat | |
31 |
|
32 | |||
32 |
|
33 | |||
@@ -45,7 +46,7 b' ip = get_ipython()' | |||||
45 | # defined, if any code is inserted above, the following line will need to be |
|
46 | # defined, if any code is inserted above, the following line will need to be | |
46 | # updated. Do NOT insert any whitespace between the next line and the function |
|
47 | # updated. Do NOT insert any whitespace between the next line and the function | |
47 | # definition below. |
|
48 | # definition below. | |
48 |
THIS_LINE_NUMBER = 4 |
|
49 | THIS_LINE_NUMBER = 49 # Put here the actual number of this line | |
49 | def test_find_source_lines(): |
|
50 | def test_find_source_lines(): | |
50 | nt.assert_equal(oinspect.find_source_lines(test_find_source_lines), |
|
51 | nt.assert_equal(oinspect.find_source_lines(test_find_source_lines), | |
51 | THIS_LINE_NUMBER+1) |
|
52 | THIS_LINE_NUMBER+1) | |
@@ -270,6 +271,14 b' def test_info_awkward():' | |||||
270 | # Just test that this doesn't throw an error. |
|
271 | # Just test that this doesn't throw an error. | |
271 | i = inspector.info(Awkward()) |
|
272 | i = inspector.info(Awkward()) | |
272 |
|
273 | |||
|
274 | if py3compat.PY3: | |||
|
275 | exec("def f_kwarg(pos, *, kwonly): pass") | |||
|
276 | ||||
|
277 | @skipif(not py3compat.PY3) | |||
|
278 | def test_definition_kwonlyargs(): | |||
|
279 | i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore | |||
|
280 | nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)\n") | |||
|
281 | ||||
273 | def test_getdoc(): |
|
282 | def test_getdoc(): | |
274 | class A(object): |
|
283 | class A(object): | |
275 | """standard docstring""" |
|
284 | """standard docstring""" |
General Comments 0
You need to be logged in to leave comments.
Login now