|
1 | 1 | # -*- coding: utf-8 -*- |
2 | 2 |
|
3 | 3 | import os |
| 4 | +import sys |
4 | 5 | import six |
5 | 6 | import time |
6 | 7 | import uuid |
|
10 | 11 | import platform |
11 | 12 | import threading |
12 | 13 | import traceback |
| 14 | +import collections |
| 15 | + |
13 | 16 |
|
14 | 17 | if six.PY3: |
15 | 18 | from traceback import format_exception_only |
@@ -122,7 +125,7 @@ def func_parameters(func, *args, **kwargs): |
122 | 125 | >>> def helper(func): |
123 | 126 | ... def wrapper(*args, **kwargs): |
124 | 127 | ... params = func_parameters(func, *args, **kwargs) |
125 | | - ... print(sorted(params.items())) |
| 128 | + ... print(list(params.items())) |
126 | 129 | ... return func(*args, **kwargs) |
127 | 130 | ... return wrapper |
128 | 131 |
|
@@ -215,14 +218,12 @@ def func_parameters(func, *args, **kwargs): |
215 | 218 | ... def args_kwargs_varargs_keywords(a, b=2, *c, **d): |
216 | 219 | ... pass |
217 | 220 |
|
218 | | -
|
219 | 221 | >>> args_kwargs_varargs_keywords(1) |
220 | 222 | [('a', '1'), ('b', '2')] |
221 | 223 |
|
222 | 224 | >>> args_kwargs_varargs_keywords(1, 2, 4, d=5, e=6) |
223 | 225 | [('a', '1'), ('b', '2'), ('c', '(4,)'), ('d', '5'), ('e', '6')] |
224 | 226 |
|
225 | | -
|
226 | 227 | >>> class Class(object): |
227 | 228 | ... @staticmethod |
228 | 229 | ... @helper |
@@ -252,24 +253,37 @@ def func_parameters(func, *args, **kwargs): |
252 | 253 | """ |
253 | 254 | parameters = {} |
254 | 255 | arg_spec = inspect.getargspec(func) if six.PY2 else inspect.getfullargspec(func) |
| 256 | + arg_order = list(arg_spec.args) |
255 | 257 | args_dict = dict(zip(arg_spec.args, args)) |
256 | 258 |
|
257 | 259 | if arg_spec.defaults: |
258 | 260 | kwargs_defaults_dict = dict(zip(arg_spec.args[len(args):], arg_spec.defaults)) |
259 | 261 | parameters.update(kwargs_defaults_dict) |
260 | 262 |
|
261 | 263 | if arg_spec.varargs: |
| 264 | + arg_order.append(arg_spec.varargs) |
262 | 265 | varargs = args[len(arg_spec.args):] |
263 | 266 | parameters.update({arg_spec.varargs: varargs} if varargs else {}) |
264 | 267 |
|
265 | 268 | if arg_spec.args and arg_spec.args[0] in ['cls', 'self']: |
266 | 269 | args_dict.pop(arg_spec.args[0], None) |
267 | 270 |
|
268 | | - parameters.update(kwargs) |
| 271 | + if kwargs: |
| 272 | + if sys.version_info < (3, 6): |
| 273 | + # Sort alphabetically as old python versions does |
| 274 | + # not preserve call order for kwargs |
| 275 | + arg_order.extend(sorted(list(kwargs.keys()))) |
| 276 | + else: |
| 277 | + # Keep py3.6 behaviour to preserve kwargs order |
| 278 | + arg_order.extend(list(kwargs.keys())) |
| 279 | + parameters.update(kwargs) |
| 280 | + |
269 | 281 | parameters.update(args_dict) |
270 | 282 |
|
271 | 283 | items = parameters.iteritems() if six.PY2 else parameters.items() |
272 | | - return dict(map(lambda kv: (kv[0], represent(kv[1])), items)) |
| 284 | + sorted_items = sorted(map(lambda kv: (kv[0], represent(kv[1])), items), key=lambda x: arg_order.index(x[0])) |
| 285 | + |
| 286 | + return collections.OrderedDict(sorted_items) |
273 | 287 |
|
274 | 288 |
|
275 | 289 | def format_traceback(exc_traceback): |
|
0 commit comments