Show More
@@ -0,0 +1,86 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | """ | |||
|
3 | getargspec excerpted from: | |||
|
4 | ||||
|
5 | sphinx.util.inspect | |||
|
6 | ~~~~~~~~~~~~~~~~~~~ | |||
|
7 | Helpers for inspecting Python modules. | |||
|
8 | :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. | |||
|
9 | :license: BSD, see LICENSE for details. | |||
|
10 | """ | |||
|
11 | ||||
|
12 | import inspect | |||
|
13 | from IPython.utils.py3compat import PY3 | |||
|
14 | ||||
|
15 | # Unmodified from sphinx below this line | |||
|
16 | ||||
|
17 | if PY3: | |||
|
18 | from functools import partial | |||
|
19 | ||||
|
20 | def getargspec(func): | |||
|
21 | """Like inspect.getargspec but supports functools.partial as well.""" | |||
|
22 | if inspect.ismethod(func): | |||
|
23 | func = func.__func__ | |||
|
24 | if type(func) is partial: | |||
|
25 | orig_func = func.func | |||
|
26 | argspec = getargspec(orig_func) | |||
|
27 | args = list(argspec[0]) | |||
|
28 | defaults = list(argspec[3] or ()) | |||
|
29 | kwoargs = list(argspec[4]) | |||
|
30 | kwodefs = dict(argspec[5] or {}) | |||
|
31 | if func.args: | |||
|
32 | args = args[len(func.args):] | |||
|
33 | for arg in func.keywords or (): | |||
|
34 | try: | |||
|
35 | i = args.index(arg) - len(args) | |||
|
36 | del args[i] | |||
|
37 | try: | |||
|
38 | del defaults[i] | |||
|
39 | except IndexError: | |||
|
40 | pass | |||
|
41 | except ValueError: # must be a kwonly arg | |||
|
42 | i = kwoargs.index(arg) | |||
|
43 | del kwoargs[i] | |||
|
44 | del kwodefs[arg] | |||
|
45 | return inspect.FullArgSpec(args, argspec[1], argspec[2], | |||
|
46 | tuple(defaults), kwoargs, | |||
|
47 | kwodefs, argspec[6]) | |||
|
48 | while hasattr(func, '__wrapped__'): | |||
|
49 | func = func.__wrapped__ | |||
|
50 | if not inspect.isfunction(func): | |||
|
51 | raise TypeError('%r is not a Python function' % func) | |||
|
52 | return inspect.getfullargspec(func) | |||
|
53 | ||||
|
54 | else: # 2.6, 2.7 | |||
|
55 | from functools import partial | |||
|
56 | ||||
|
57 | def getargspec(func): | |||
|
58 | """Like inspect.getargspec but supports functools.partial as well.""" | |||
|
59 | if inspect.ismethod(func): | |||
|
60 | func = func.__func__ | |||
|
61 | parts = 0, () | |||
|
62 | if type(func) is partial: | |||
|
63 | keywords = func.keywords | |||
|
64 | if keywords is None: | |||
|
65 | keywords = {} | |||
|
66 | parts = len(func.args), keywords.keys() | |||
|
67 | func = func.func | |||
|
68 | if not inspect.isfunction(func): | |||
|
69 | raise TypeError('%r is not a Python function' % func) | |||
|
70 | args, varargs, varkw = inspect.getargs(func.__code__) | |||
|
71 | func_defaults = func.__defaults__ | |||
|
72 | if func_defaults is None: | |||
|
73 | func_defaults = [] | |||
|
74 | else: | |||
|
75 | func_defaults = list(func_defaults) | |||
|
76 | if parts[0]: | |||
|
77 | args = args[parts[0]:] | |||
|
78 | if parts[1]: | |||
|
79 | for arg in parts[1]: | |||
|
80 | i = args.index(arg) - len(args) | |||
|
81 | del args[i] | |||
|
82 | try: | |||
|
83 | del func_defaults[i] | |||
|
84 | except IndexError: | |||
|
85 | pass | |||
|
86 | return inspect.ArgSpec(args, varargs, varkw, func_defaults) |
@@ -53,6 +53,7 b' except:' | |||||
53 | ClassTypes = (type,) |
|
53 | ClassTypes = (type,) | |
54 | from warnings import warn |
|
54 | from warnings import warn | |
55 |
|
55 | |||
|
56 | from .getargspec import getargspec | |||
56 | from .importstring import import_item |
|
57 | from .importstring import import_item | |
57 | from IPython.utils import py3compat |
|
58 | from IPython.utils import py3compat | |
58 | from IPython.utils import eventful |
|
59 | from IPython.utils import eventful | |
@@ -294,6 +295,7 b' class directional_link(object):' | |||||
294 |
|
295 | |||
295 | dlink = directional_link |
|
296 | dlink = directional_link | |
296 |
|
297 | |||
|
298 | ||||
297 | #----------------------------------------------------------------------------- |
|
299 | #----------------------------------------------------------------------------- | |
298 | # Base TraitType for all traits |
|
300 | # Base TraitType for all traits | |
299 | #----------------------------------------------------------------------------- |
|
301 | #----------------------------------------------------------------------------- | |
@@ -625,7 +627,8 b' class HasTraits(py3compat.with_metaclass(MetaHasTraits, object)):' | |||||
625 | for c in callables: |
|
627 | for c in callables: | |
626 | # Traits catches and logs errors here. I allow them to raise |
|
628 | # Traits catches and logs errors here. I allow them to raise | |
627 | if callable(c): |
|
629 | if callable(c): | |
628 |
argspec = |
|
630 | argspec = getargspec(c) | |
|
631 | ||||
629 | nargs = len(argspec[0]) |
|
632 | nargs = len(argspec[0]) | |
630 | # Bound methods have an additional 'self' argument |
|
633 | # Bound methods have an additional 'self' argument | |
631 | # I don't know how to treat unbound methods, but they |
|
634 | # I don't know how to treat unbound methods, but they |
General Comments 0
You need to be logged in to leave comments.
Login now