[Python-Dev] Python keywords

Thomas Wouters thomas@xs4all.net
Mon, 28 Aug 2000 01:16:24 +0200


--3MwIy2ne0vdjdPXF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


Mark, (and the rest of python-dev)

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

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

-- 
Thomas Wouters <thomas@xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!

--3MwIy2ne0vdjdPXF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="grammar.patch"

Index: Grammar/Grammar
===================================================================
RCS file: /cvsroot/python/python/dist/src/Grammar/Grammar,v
retrieving revision 1.41
diff -c -r1.41 Grammar
*** Grammar/Grammar	2000/08/24 20:11:30	1.41
--- Grammar/Grammar	2000/08/27 23:15:53
***************
*** 19,24 ****
--- 19,28 ----
  #diagram:output\textwidth 20.04cm\oddsidemargin  0.0cm\evensidemargin 0.0cm
  #diagram:rules
  
+ # for reference: everything allowed in a 'def' or trailer expression.
+ # (I might have missed one or two ;)
+ # ( 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')
+ 
  # Start symbols for the grammar:
  #	single_input is a single interactive statement;
  #	file_input is a module or sequence of commands read from an input file;
***************
*** 28,34 ****
  file_input: (NEWLINE | stmt)* ENDMARKER
  eval_input: testlist NEWLINE* ENDMARKER
  
! funcdef: 'def' NAME parameters ':' suite
  parameters: '(' [varargslist] ')'
  varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
  fpdef: NAME | '(' fplist ')'
--- 32,38 ----
  file_input: (NEWLINE | stmt)* ENDMARKER
  eval_input: testlist NEWLINE* ENDMARKER
  
! funcdef: 'def' ( 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') parameters ':' suite
  parameters: '(' [varargslist] ')'
  varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
  fpdef: NAME | '(' fplist ')'
***************
*** 87,93 ****
  atom: '(' [testlist] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
  listmaker: test ( list_for | (',' test)* [','] )
  lambdef: 'lambda' [varargslist] ':' test
! trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
  subscriptlist: subscript (',' subscript)* [',']
  subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
  sliceop: ':' [test]
--- 91,97 ----
  atom: '(' [testlist] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
  listmaker: test ( list_for | (',' test)* [','] )
  lambdef: 'lambda' [varargslist] ':' test
! trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' ( 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')
  subscriptlist: subscript (',' subscript)* [',']
  subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
  sliceop: ':' [test]

--3MwIy2ne0vdjdPXF--