Search code examples
pythonsyntaxprogramming-languagespep

Python syntactic sugar: function arg aliases


Is there any syntax for aliasing function args? If not, are there any PEP proposals? I'm not a programming languages theorist, so my opinion is probably uninformed, but I think implementing some sort of function arg aliasing could be useful.

I'm doing some changes to libcloud and my idea would help me avoid breaking others while making changes to the APIs.

For example, say I'm refactoring and would like to rename a function arg 'foo' to 'bar':

Original:

def fn(foo):
    <code (using 'foo')>

I could:

def fn(foo, bar=None):
    if foo and bar:
        raise Exception('Please use foo and bar mutually exclusively.')
    bar = foo or bar
    <code (using 'bar')>

# But this is undesirable because it changes the method signature to allow
# a new parameter slot.
fn('hello world', 'goodbye world')

My unrefined syntactic sugar idea:

def fn(bar|foo|baz):
    # Callers can use foo, bar, or baz, but only the leftmost arg name
    # is used in the method code block. In this case, it would be bar.
    # The python runtime would enforce mutual exclusion between foo,
    # bar, and baz.
    <code (using 'bar')>

# Valid uses:
fn(foo='hello world')
fn(bar='hello world')
fn(baz='hello world')
fn('hello world')

# Invalid uses (would raise some exception):
fn(foo='hello world', bar='goodbye world')
fn('hello world', baz='goodbye world')

Solution

  • No perhapses, you can do that with decorators (as shown above), or for first hand with kwargs:

    def fn (**kw):
        arg = kw.get("foo") or kw.get("bar") or kw.get("baz")
        if arg==None: raise TypeError, "foo nor bar nor baz given az argument"
        print arg
    
    Here the order of precedence is: "if foo exists, arg is foo. if it doesn't but bar exists, arg is bar, if neither foo nor bar exists, the arg is baz. If baz doesn't, i.e. all 3 are missing, arg is None.
    
    Of course, you may check whether either one exists and force the mutual exclusion, but I don't see why would you need such a thing.
    
    You are clever and you will never pass them in together. Even if you do, some will be ignored.
    

    You can also do it with callable objects, even introduce your syntax and behavior into the interpreter at runtime if you want.

    But in my opinion, introducing this as a valid Python syntax is not Pythonic and would never happen, even if there is a PEP.

    As you can see, you can do what you want without dirtying Python syntax.

    I don't mean that your example is not syntactically clear, just unnecessary.