gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / wrapt / arguments.py @ 745
History | View | Annotate | Download (3.95 KB)
1 |
# This is a copy of the inspect.getcallargs() function from Python 2.7
|
---|---|
2 |
# so we can provide it for use under Python 2.6. As the code in this
|
3 |
# file derives from the Python distribution, it falls under the version
|
4 |
# of the PSF license used for Python 2.7.
|
5 |
|
6 |
from inspect import getargspec, ismethod |
7 |
|
8 |
def getcallargs(func, *positional, **named): |
9 |
"""Get the mapping of arguments to values.
|
10 |
|
11 |
A dict is returned, with keys the function argument names (including the
|
12 |
names of the * and ** arguments, if any), and values the respective bound
|
13 |
values from 'positional' and 'named'."""
|
14 |
args, varargs, varkw, defaults = getargspec(func) |
15 |
f_name = func.__name__ |
16 |
arg2value = {} |
17 |
|
18 |
# The following closures are basically because of tuple parameter unpacking.
|
19 |
assigned_tuple_params = [] |
20 |
def assign(arg, value): |
21 |
if isinstance(arg, str): |
22 |
arg2value[arg] = value |
23 |
else:
|
24 |
assigned_tuple_params.append(arg) |
25 |
value = iter(value)
|
26 |
for i, subarg in enumerate(arg): |
27 |
try:
|
28 |
subvalue = next(value)
|
29 |
except StopIteration: |
30 |
raise ValueError('need more than %d %s to unpack' % |
31 |
(i, 'values' if i > 1 else 'value')) |
32 |
assign(subarg,subvalue) |
33 |
try:
|
34 |
next(value)
|
35 |
except StopIteration: |
36 |
pass
|
37 |
else:
|
38 |
raise ValueError('too many values to unpack') |
39 |
def is_assigned(arg): |
40 |
if isinstance(arg,str): |
41 |
return arg in arg2value |
42 |
return arg in assigned_tuple_params |
43 |
if ismethod(func) and func.im_self is not None: |
44 |
# implicit 'self' (or 'cls' for classmethods) argument
|
45 |
positional = (func.im_self,) + positional |
46 |
num_pos = len(positional)
|
47 |
num_total = num_pos + len(named)
|
48 |
num_args = len(args)
|
49 |
num_defaults = len(defaults) if defaults else 0 |
50 |
for arg, value in zip(args, positional): |
51 |
assign(arg, value) |
52 |
if varargs:
|
53 |
if num_pos > num_args:
|
54 |
assign(varargs, positional[-(num_pos-num_args):]) |
55 |
else:
|
56 |
assign(varargs, ()) |
57 |
elif 0 < num_args < num_pos: |
58 |
raise TypeError('%s() takes %s %d %s (%d given)' % ( |
59 |
f_name, 'at most' if defaults else 'exactly', num_args, |
60 |
'arguments' if num_args > 1 else 'argument', num_total)) |
61 |
elif num_args == 0 and num_total: |
62 |
if varkw:
|
63 |
if num_pos:
|
64 |
# XXX: We should use num_pos, but Python also uses num_total:
|
65 |
raise TypeError('%s() takes exactly 0 arguments ' |
66 |
'(%d given)' % (f_name, num_total))
|
67 |
else:
|
68 |
raise TypeError('%s() takes no arguments (%d given)' % |
69 |
(f_name, num_total)) |
70 |
for arg in args: |
71 |
if isinstance(arg, str) and arg in named: |
72 |
if is_assigned(arg):
|
73 |
raise TypeError("%s() got multiple values for keyword " |
74 |
"argument '%s'" % (f_name, arg))
|
75 |
else:
|
76 |
assign(arg, named.pop(arg)) |
77 |
if defaults: # fill in any missing values with the defaults |
78 |
for arg, value in zip(args[-num_defaults:], defaults): |
79 |
if not is_assigned(arg): |
80 |
assign(arg, value) |
81 |
if varkw:
|
82 |
assign(varkw, named) |
83 |
elif named:
|
84 |
unexpected = next(iter(named)) |
85 |
if isinstance(unexpected, unicode): |
86 |
unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace')
|
87 |
raise TypeError("%s() got an unexpected keyword argument '%s'" % |
88 |
(f_name, unexpected)) |
89 |
unassigned = num_args - len([arg for arg in args if is_assigned(arg)]) |
90 |
if unassigned:
|
91 |
num_required = num_args - num_defaults |
92 |
raise TypeError('%s() takes %s %d %s (%d given)' % ( |
93 |
f_name, 'at least' if defaults else 'exactly', num_required, |
94 |
'arguments' if num_required > 1 else 'argument', num_total)) |
95 |
return arg2value
|