MCPcopy Create free account
hub / github.com/ActiveState/code / decorator

Function decorator

recipes/Python/578993_Keywordonly_arguments/recipe-578993.py:28–118  ·  view source on GitHub ↗

The decorator itself, assigns arguments as keyword-only and calculates sets for error checking. Args: wrapped: The function to decorate. Returns: A function wrapped so that it has keyword-only arguments.

(wrapped)

Source from the content-addressed store, hash-verified

26
27 """
28 def decorator(wrapped):
29 """The decorator itself, assigns arguments as keyword-only and
30 calculates sets for error checking.
31
32 Args:
33 wrapped: The function to decorate.
34
35 Returns:
36 A function wrapped so that it has keyword-only arguments.
37
38 """
39
40 # Each Python 3 argument has two independent properties: it is
41 # positional-and-keyword *or* keyword-only, and it has a
42 # default value or it doesn't.
43 names, varargs, _, defaults = inspect.getargspec(wrapped)
44
45 # If there are no default values getargpsec() returns None
46 # rather than an empty iterable for some reason.
47 if defaults is None:
48 defaults = ()
49 names_with_defaults = frozenset(names[len(names) - len(defaults):])
50 names_to_defaults = dict(zip(reversed(names), reversed(defaults)))
51 if kw_only_parameters:
52 kw_only_names = frozenset(kw_only_parameters)
53 else:
54 kw_only_names = names_with_defaults.copy()
55
56 @functools.wraps(wrapped)
57 def wrapper(*args, **kws):
58 """Wrapper function, checks arguments with set operations, moves args
59 from **kws into *args, and then calls wrapped().
60
61 Args:
62 *args, **kws: The arguments passed to the original function.
63
64 Returns:
65 The original function's result when it's called with the
66 modified arguments.
67
68 Raises:
69 TypeError: When there is a mismatch between the supplied
70 and expected arguments.
71
72 """
73
74 new_args = []
75 args_index = 0
76 for name in names:
77 if name in kws:
78 # Check first if there's a bound keyword for this name
79 new_args.append(kws.pop(name))
80 elif name in kw_only_names:
81 # If this name is keyword-only, check for a
82 # default or raise.
83 if name in names_to_defaults:
84 new_args.append(names_to_defaults[name])
85 else:

Callers

nothing calls this directly

Calls 3

dictFunction · 0.50
reversedFunction · 0.50
copyMethod · 0.45

Tested by

no test coverage detected