Function Mangling
This module provides utilities for extracting information about python functions.
AUTHORS:
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 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.
INPUTS:
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)))
Normalize the arguments with a preference for named arguments.
INPUT:
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 names
are 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)))
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 names are given in alphabetical
order.
EXAMPLE:
sage: from sage.misc.function_mangling import ArgumentFixer
sage: def do_something(a,b,c=3,*args,**kwargs):
... print 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); print 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}