94 """Build dict from list containing positional and keyword arguments |
94 """Build dict from list containing positional and keyword arguments |
95 |
95 |
96 Invalid keywords or too many positional arguments are rejected, but |
96 Invalid keywords or too many positional arguments are rejected, but |
97 missing arguments are just omitted. |
97 missing arguments are just omitted. |
98 """ |
98 """ |
|
99 kwstart = next((i for i, x in enumerate(trees) if x[0] == keyvaluenode), |
|
100 len(trees)) |
99 if len(trees) > len(keys): |
101 if len(trees) > len(keys): |
100 raise error.ParseError(_("%(func)s takes at most %(nargs)d arguments") |
102 raise error.ParseError(_("%(func)s takes at most %(nargs)d arguments") |
101 % {'func': funcname, 'nargs': len(keys)}) |
103 % {'func': funcname, 'nargs': len(keys)}) |
102 args = {} |
104 args = {} |
103 # consume positional arguments |
105 # consume positional arguments |
104 for k, x in zip(keys, trees): |
106 for k, x in zip(keys, trees[:kwstart]): |
105 if x[0] == keyvaluenode: |
|
106 break |
|
107 args[k] = x |
107 args[k] = x |
|
108 assert len(args) == kwstart |
108 # remainder should be keyword arguments |
109 # remainder should be keyword arguments |
109 for x in trees[len(args):]: |
110 for x in trees[kwstart:]: |
110 if x[0] != keyvaluenode or x[1][0] != keynode: |
111 if x[0] != keyvaluenode or x[1][0] != keynode: |
111 raise error.ParseError(_("%(func)s got an invalid argument") |
112 raise error.ParseError(_("%(func)s got an invalid argument") |
112 % {'func': funcname}) |
113 % {'func': funcname}) |
113 k = x[1][1] |
114 k = x[1][1] |
114 if k not in keys: |
115 if k not in keys: |