[Python-Dev] Python keywords
Guido van Rossum
guido@beopen.com
Mon, 28 Aug 2000 05:54:13 -0500
[Thomas Wouters]
> There was a thread here a few weeks ago (or so, I seem to have misplaced
> that particular thread :P) about using Python keywords as identifiers in
> some cases. You needed that ability for .NET-Python, where the specs say any
> identifier should be possible as methods and attributes, and there were some
> comments on the list on how to do that (by Guido, for one.)
>
> Well, the attached patch sort-of does that. I tried making it a bit nicer,
> but that involved editing all places that currently use the NAME-type node,
> and most of those don't advertise that they're doing that :-S The attached
> patch is in no way nice, but it does work:
>
> >>> class X:
> ... def print(self, x):
> ... print "printing", x
> ...
> >>> x = X()
> >>> x.print(1)
> printing 1
> >>> x.print
> <method X.print of X instance at 0x8207fc4>
> >>> x.assert = 1
> >>>
>
> However, it also allows this at the top level, currently:
> >>> def print(x):
> ... print "printing", x
> ...
Initially I thought this would be fine, but on second thought I'm not
so sure. To a newbie who doesn't know all the keywords, this would be
confusing:
>>> def try(): # my first function
... print "hello"
...
>>> try()
File "<stdin>", line 1
try()
^
SyntaxError: invalid syntax
>>>
I don't know how best to fix this -- using different syntax for 'def'
inside a class than outside would require a complete rewrite of the
grammar, which is not a good idea. Perhaps a 2nd pass compile-time
check would be sufficient.
> which results in some unexpected behaviour:
> >>> print(1)
> 1
> >>> globals()['print'](1)
> printing 1
>
> But when combining it with modules, it does work as expected, of course:
>
> # printer.py:
> def print(x, y):
> print "printing", x, "and", y
> #
>
> >>> import printer
> >>> printer.print
> <function print at 0x824120c>
> >>> printer.print(1, 2)
> printing 1 and 2
>
> Another plus-side of this particular method is that it's simple and
> straightforward, if a bit maintenance-intensive :-) But the big question is:
> is this enough for what you need ? Or do you need the ability to use
> keywords in *all* identifiers, including variable names and such ? Because
> that is quite a bit harder ;-P
I believe that one other thing is needed: keyword parameters (only in
calls, not in definitions). Also, I think you missed a few reserved
words, e.g. 'and', 'or'. See Lib/keyword.py!
A comment on the patch: wouldn't it be *much* better to change the
grammar to introduce a new nonterminal, e.g. unres_name, as follows:
unres_name; NAME | 'for' | 'if' | 'while' | 'else' | 'elif' | 'def' | \
'class' | 'print' | 'del' | 'raise' | 'exec' | 'in' | 'is' | 'from' | \
'pass' | 'import' | 'global' | 'assert' | 'return' | 'break' | \
'continue' | 'try' | 'except' | 'not' | 'lambda' | 'finally'
and use this elsewhere in the rules:
funcdef: 'def' unres_name parameters ':' suite
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' unres_name
Then you'd have to fix compile.c of course, but only in two places (I
think?).
--Guido van Rossum (home page: http://www.pythonlabs.com/~guido/)