Issue5382
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.
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) * ![]() |
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) * ![]() |
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) * ![]() |
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:46 | admin | set | github: 49632 |
2009-02-27 19:30:05 | mrabarnett | set | messages: + msg82862 |
2009-02-27 18:45:05 | Imagist | set | messages: + msg82859 |
2009-02-27 17:27:24 | georg.brandl | set | status: open -> closed nosy: + georg.brandl resolution: wont fix messages: + msg82851 |
2009-02-27 17:14:00 | LambertDW | set | messages: + msg82848 |
2009-02-27 17:01:27 | mrabarnett | set | nosy:
+ mrabarnett messages: + msg82846 |
2009-02-27 17:00:33 | LambertDW | set | nosy:
+ LambertDW messages: + msg82845 |
2009-02-27 16:25:23 | Imagist | create |