| author | Sandro Knauß <bugs@sandroknauss.de> |
| Tue, 15 Apr 2025 01:22:19 +0200 | |
| changeset 316 | 63c681b8e92c |
| parent 294 | 0e75bd39767d |
| permissions | -rw-r--r-- |
|
294
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
1 |
# Copyright (c) 2012 netzguerilla.net <iro@netzguerilla.net> |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
2 |
# |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
3 |
# This file is part of Iro. |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
4 |
# |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
5 |
# Permission is hereby granted, free of charge, to any person obtaining a copy of |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
6 |
# this software and associated documentation files (the "Software"), to deal in |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
7 |
# the Software without restriction, including without limitation the rights to use, |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
8 |
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
9 |
# #Software, and to permit persons to whom the Software is furnished to do so, |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
10 |
# subject to the following conditions: |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
11 |
# |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
12 |
# The above copyright notice and this permission notice shall be included in |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
13 |
# all copies or substantial portions of the Software. |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
14 |
# |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
15 |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
16 |
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
17 |
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
18 |
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
19 |
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
20 |
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
0e75bd39767d
adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents:
282
diff
changeset
|
21 |
|
|
282
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
22 |
from inspect import getargspec, ismethod |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
23 |
import sys |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
24 |
|
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
25 |
#code just copied form python 2.7.3 |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
26 |
|
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
27 |
def getcallargs(func, *positional, **named): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
28 |
"""Get the mapping of arguments to values. |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
29 |
|
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
30 |
A dict is returned, with keys the function argument names (including the |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
31 |
names of the * and ** arguments, if any), and values the respective bound |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
32 |
values from 'positional' and 'named'.""" |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
33 |
args, varargs, varkw, defaults = getargspec(func) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
34 |
f_name = func.__name__ |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
35 |
arg2value = {} |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
36 |
|
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
37 |
# The following closures are basically because of tuple parameter unpacking. |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
38 |
assigned_tuple_params = [] |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
39 |
def assign(arg, value): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
40 |
if isinstance(arg, str): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
41 |
arg2value[arg] = value |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
42 |
else: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
43 |
assigned_tuple_params.append(arg) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
44 |
value = iter(value) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
45 |
for i, subarg in enumerate(arg): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
46 |
try: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
47 |
subvalue = next(value) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
48 |
except StopIteration: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
49 |
raise ValueError('need more than %d %s to unpack' % |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
50 |
(i, 'values' if i > 1 else 'value')) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
51 |
assign(subarg,subvalue) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
52 |
try: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
53 |
next(value) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
54 |
except StopIteration: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
55 |
pass |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
56 |
else: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
57 |
raise ValueError('too many values to unpack') |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
58 |
def is_assigned(arg): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
59 |
if isinstance(arg,str): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
60 |
return arg in arg2value |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
61 |
return arg in assigned_tuple_params |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
62 |
if ismethod(func) and func.im_self is not None: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
63 |
# implicit 'self' (or 'cls' for classmethods) argument |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
64 |
positional = (func.im_self,) + positional |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
65 |
num_pos = len(positional) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
66 |
num_total = num_pos + len(named) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
67 |
num_args = len(args) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
68 |
num_defaults = len(defaults) if defaults else 0 |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
69 |
for arg, value in zip(args, positional): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
70 |
assign(arg, value) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
71 |
if varargs: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
72 |
if num_pos > num_args: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
73 |
assign(varargs, positional[-(num_pos-num_args):]) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
74 |
else: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
75 |
assign(varargs, ()) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
76 |
elif 0 < num_args < num_pos: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
77 |
raise TypeError('%s() takes %s %d %s (%d given)' % ( |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
78 |
f_name, 'at most' if defaults else 'exactly', num_args, |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
79 |
'arguments' if num_args > 1 else 'argument', num_total)) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
80 |
elif num_args == 0 and num_total: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
81 |
if varkw: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
82 |
if num_pos: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
83 |
# XXX: We should use num_pos, but Python also uses num_total: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
84 |
raise TypeError('%s() takes exactly 0 arguments ' |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
85 |
'(%d given)' % (f_name, num_total)) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
86 |
else: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
87 |
raise TypeError('%s() takes no arguments (%d given)' % |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
88 |
(f_name, num_total)) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
89 |
for arg in args: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
90 |
if isinstance(arg, str) and arg in named: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
91 |
if is_assigned(arg): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
92 |
raise TypeError("%s() got multiple values for keyword " |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
93 |
"argument '%s'" % (f_name, arg)) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
94 |
else: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
95 |
assign(arg, named.pop(arg)) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
96 |
if defaults: # fill in any missing values with the defaults |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
97 |
for arg, value in zip(args[-num_defaults:], defaults): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
98 |
if not is_assigned(arg): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
99 |
assign(arg, value) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
100 |
if varkw: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
101 |
assign(varkw, named) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
102 |
elif named: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
103 |
unexpected = next(iter(named)) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
104 |
if isinstance(unexpected, unicode): |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
105 |
unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace') |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
106 |
raise TypeError("%s() got an unexpected keyword argument '%s'" % |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
107 |
(f_name, unexpected)) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
108 |
unassigned = num_args - len([arg for arg in args if is_assigned(arg)]) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
109 |
if unassigned: |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
110 |
num_required = num_args - num_defaults |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
111 |
raise TypeError('%s() takes %s %d %s (%d given)' % ( |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
112 |
f_name, 'at least' if defaults else 'exactly', num_required, |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
113 |
'arguments' if num_required > 1 else 'argument', num_total)) |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
114 |
return arg2value |
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
115 |
|
|
50cc13814bfb
make iro working with python v2.6
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff
changeset
|
116 |