Function Mangling¶
This module provides utilities for extracting information about python functions.
AUTHORS:
- Tom Boothby (2009): Original version in Python
- Simon King (2011): Use Cython. Speedup of
fix_to_pos
, cleaning documentation.
-
class
sage.misc.function_mangling.
ArgumentFixer
¶ Bases:
object
This class provides functionality to normalize the arguments passed into a function. While the various ways of calling a function are perfectly equivalent from the perspective of the callee, they don’t always look the same for an object watching the caller. For example,
sage: def f(x = 10): ... return min(1,x)
the following calls are equivalent,
sage: f() 1 sage: f(10) 1 sage: f(x=10) 1
but from the perspective of a wrapper, they are different:
sage: def wrap(g): ....: def _g(*args,**kwargs): ....: print("{} {}".format(args, kwargs)) ....: return g(*args, **kwargs) ....: return _g sage: h = wrap(f) sage: t = h() () {} sage: t = h(10) (10,) {} sage: t = h(x=10) () {'x': 10}
For the purpose of cached functions, it is important not to distinguish between these uses.
INPUT:
- f – a function
- classmethod – boolean (default False) – True if the function is a classmethod and therefore the first argument is expected to be the class instance. In that case, we ignore the first argument.
EXAMPLES:
sage: from sage.misc.function_mangling import ArgumentFixer sage: def wrap2(g): ... af = ArgumentFixer(g) ... def _g(*args, **kwargs): ... print(af.fix_to_pos()) ... return g(*args,**kwargs) ... return _g sage: h2 = wrap2(f) sage: t = h2() ((10,), ()) sage: t = h2(10) ((10,), ()) sage: t = h2(x=10) ((10,), ())
sage: class one: ... def __init__(self, x = 1): ... self.x = x sage: af = ArgumentFixer(one.__init__.__func__, classmethod=True) sage: af.fix_to_pos(1,2,3,a=31,b=2,n=3) ((1, 2, 3), (('a', 31), ('b', 2), ('n', 3)))
-
f
¶
-
fix_to_named
(*args, **kwargs)¶ Normalize the arguments with a preference for named arguments.
INPUT:
- any positional and named arguments.
OUTPUT:
We return a tuple
where
are the names of the arguments and
are the values passed in; and
are the unnamed arguments. We minimize
.
The defaults are extracted from the function and filled into the list
K
of named arguments. The namesare in order of the function definition, where
is the number of named arguments. The remaining names,
are given in alphabetical order. This is useful to extract the names of arguments, but does not maintain equivalence of
A,K = self.fix_to_pos(...) self.f(*A,**dict(K))`
and
self.f(...)
in all cases.
EXAMPLE:
sage: from sage.misc.function_mangling import ArgumentFixer sage: def sum3(a,b,c=3,*args,**kwargs): ... return a+b+c sage: AF = ArgumentFixer(sum3) sage: AF.fix_to_named(1,2,3,4,5,6,f=14,e=16) ((4, 5, 6), (('a', 1), ('b', 2), ('c', 3), ('e', 16), ('f', 14))) sage: AF.fix_to_named(1,2,f=14) ((), (('a', 1), ('b', 2), ('c', 3), ('f', 14)))
-
fix_to_pos
(*args, **kwds)¶ Normalize the arguments with a preference for positional arguments.
INPUT:
Any positional or named arguments
OUTPUT:
We return a tuple
where
are the names of the arguments and
are the values passed in; and
are the unnamed arguments. We minimize
.
The commands
A,K = self.fix_to_pos(...) self.f(*A,**dict(K))
are equivalent to
self.f(...)
though defaults are extracted from the function and appended to the tuple
A
of positional arguments. The namesare given in alphabetical order.
EXAMPLE:
sage: from sage.misc.function_mangling import ArgumentFixer sage: def do_something(a,b,c=3,*args,**kwargs): ....: print("{} {} {} {} {}".format(a,b,c, args, kwargs)) sage: AF = ArgumentFixer(do_something) sage: A,K = AF.fix_to_pos(1,2,3,4,5,6,f=14,e=16) sage: print("{} {}".format(A, K)) (1, 2, 3, 4, 5, 6) (('e', 16), ('f', 14)) sage: do_something(*A,**dict(K)) 1 2 3 (4, 5, 6) {'e': 16, 'f': 14} sage: do_something(1,2,3,4,5,6,f=14,e=16) 1 2 3 (4, 5, 6) {'e': 16, 'f': 14}