This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Allow Python keywords as keyword arguments for functions.
Type: enhancement Stage:
Components: Interpreter Core Versions: Python 3.0, Python 3.1
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: Imagist, LambertDW, georg.brandl, mrabarnett
Priority: normal Keywords:

Created on 2009-02-27 16:25 by Imagist, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (7)
msg82837 - (view) Author: David Kerkeslager (Imagist) Date: 2009-02-27 16:25
This problem arose in this thread:
http://www.python-forum.org/pythonforum/viewtopic.php?f=2&t=11606

Basically, we have the following function which will generate an XHTML 
node:

def xhtmlNode(tag, **attr):...

If we call:

xhtmlNode('div',class='sidebar')

... it should generate the xhtml:

<div class='sidebar'></div>

However, this isn't possible because the 'class' keyword in Python 
blocks it.  Since this is a key in a dictionary (attr['class']) this 
shouldn't be a problem.  As far as I know, there is no parsing issue 
with this either.

Could we allow Python keywords to be keyword arguments?  The use case 
above shows that this is useful in a real-life situation.
msg82845 - (view) Author: David W. Lambert (LambertDW) Date: 2009-02-27 17:00
Use cases are easy to find.
So easily found that there's probably a sound reason for reserved words.
The proposal couples lexical analysis to the parser.

# syntax error or name error?

def f():
    class
    return

def f(class):
    class
    return
msg82846 - (view) Author: Matthew Barnett (mrabarnett) * (Python triager) Date: 2009-02-27 17:01
The usual trick is to append "_":

xhtmlNode('div',class_='sidebar')

Could you modify the function to remove the trailing "_"?
msg82848 - (view) Author: David W. Lambert (LambertDW) Date: 2009-02-27 17:14
You can sneak them in thusly:


def f(**kwargs):
    print(kwargs)

f(**{'class':'sidebar'})
msg82851 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2009-02-27 17:27
This is not going to happen:

First, function call syntax is nicely parallel to parameter definition
syntax, and it is obviously not possible to define parameters named like
keywords.

Second, making exceptions like this leads to more exceptions and finally
inconsistencies. People will say "if it's allowed here, why not there
too, where it is grammatically unambiguous". Quoting the Zen: Special
cases aren't special enough to break the rules.


PS: In addition to what David Lambert and Matthew said, you could also
lower() all attributes on generation and use

xhtmlNode('div', Class='sidebar')
msg82859 - (view) Author: David Kerkeslager (Imagist) Date: 2009-02-27 18:45
Thank you all for reading and responding to my submission.

I post the following without expectation of results, only to expand my 
reasoning:

The following aren't applicable to the situation I described:

def f():
    class
    return

def f(class):
    class
    return

The are not applicable because inside the function, "class" would always 
be contained in a string (as a key of the kwargs dictionary).

To explain further, for:

def f(**kwargs):
     print(kwargs['foo'])
f(foo='bar')

This isn't a problem.  So why is this a problem?

def f(**kwargs):
     print(kwargs['class'])
f(class='foo')

In response to Mr. Brandl's statements:

> First, function call syntax is nicely parallel to parameter definition
> syntax, and it is obviously not possible to define parameters named 
like
> keywords.

For normal arguments this is true:  def a(b,c) is called with 
a(<b>,<c>).  But this parallel breaks down when you introduce variable 
arguments def a(*b) is called a(<b0>,<b1>,<b2>).  And it breaks down 
even more when you add keyword arguments.  def a(**b) is called 
a(<b0name>=<b0value>,<b1name>=<b1value>) At this point, where's the 
parallel?

If anything, there's a parallel between the keywords and the dictionary 
keys, which, as strings, can contain anything.  We obviously have to 
limit this a bit to keep the overall syntax unambiguous, but restricting 
out keywords isn't necessary.  You're essentially preventing us from 
putting keywords in a string.

> Second, making exceptions like this leads to more exceptions and 
finally
> inconsistencies. People will say "if it's allowed here, why not there
> too, where it is grammatically unambiguous". Quoting the Zen: Special
> cases aren't special enough to break the rules.

Allowing keywords as keyword arguments isn't an exception to the rule; 
NOT allowing them is the exception.  "class" is a perfectly valid 
dictionary key, and given that there's no syntactic reason not to allow 
this, why do so?
msg82862 - (view) Author: Matthew Barnett (mrabarnett) * (Python triager) Date: 2009-02-27 19:30
The normal use of a keyword argument is to refer to a formal argument,
which is an identifier. Being able to wrap it up into a dict is a later
addition, and it's necessary to turn the identifier into a string
because it's not possible to use a bare word (as Perl would call it) as
a key (I can't think of any other place where something is automatically
turned into a string). Of course, another approach would've been to make
them attributes of the formal argument:

def foo(**args):
    print "a is %s" % args.a

foo(a=1)

As for it being an exception to the rule, well, many things can be a
key: an integer could be a key. Would foo(0="zero") be OK? There's no
syntactic reason why it couldn't be allowed.

-1 from me.
History
Date User Action Args
2022-04-11 14:56:46adminsetgithub: 49632
2009-02-27 19:30:05mrabarnettsetmessages: + msg82862
2009-02-27 18:45:05Imagistsetmessages: + msg82859
2009-02-27 17:27:24georg.brandlsetstatus: open -> closed
nosy: + georg.brandl
resolution: wont fix
messages: + msg82851
2009-02-27 17:14:00LambertDWsetmessages: + msg82848
2009-02-27 17:01:27mrabarnettsetnosy: + mrabarnett
messages: + msg82846
2009-02-27 17:00:33LambertDWsetnosy: + LambertDW
messages: + msg82845
2009-02-27 16:25:23Imagistcreate