### Navigation

- index
- modules |
- next |
- previous |
- Miscellaneous »

# Function Mangling

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 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:

  - 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)))

  `defaults_to_pos`(Args)
  `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

    > \((e_1, e_2, ..., e_k), ((n_1, v_1), ... , (n_m, v_m))\)

    where \(n_1, ... , n_m\) are the names of the arguments and \(v_1, ..., v_m\) are the values passed in; and \(e_1, ..., e_k\) are the unnamed arguments. We minimize \(k\).

    The defaults are extracted from the function and filled into the list `K` of named arguments. The names \(n_1, ..., n_t\) are in order of the function definition, where \(t\) is the number of named arguments. The remaining names, \(n_{t+1}, ..., n_m\) 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

    > \((e_1, e_2, ..., e_k), ((n_1, v_1), ... , (n_m, v_m))\)

    where \(n_1, ... , n_m\) are the names of the arguments and \(v_1, ..., v_m\) are the values passed in; and \(e_1, ..., e_k\) are the unnamed arguments. We minimize \(m\).

    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 \(n_1, ..., n_m\) 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}

### Navigation

- index
- modules |
- next |
- previous |
- Miscellaneous »