1

I am looking for an easy test to see if a given string is a valid Python identifier that is not a reserved keyword. It will be used in an exec statement in a function call.

Checking with a regex for an identifier, e.g. [A-Za-z_][A-Za-z0-9_]*, isn't enough, because it could be a Python keyword like for or and:

>>> def f(**kwargs):
...   return kwargs
...
>>> f(x=3, y=4)
{'y': 4, 'x': 3}
>>> f(zip-zop=4)
  File "<stdin>", line 1
SyntaxError: keyword can't be an expression
>>> f(for=4)
  File "<stdin>", line 1
    f(for=4)
        ^
SyntaxError: invalid syntax
>>> f(and=4)
  File "<stdin>", line 1
    f(and=4)
        ^
SyntaxError: invalid syntax

Is there a way to do this without using an additional exec call? (or other evaluation-based method; see below for an exec-based approach)

>>> import re
>>> ident_re = re.compile('[A-Za-z_][A-Za-z0-9_]*')
>>> def testarg(arg):
...   if not ident_re.match(arg):
...     return False
...   try:
...     exec('dict(%s=None)' % arg)    # safe because we know it's an identifier
...   except SyntaxError:
...     return False
...   return True
...
>>> testarg('!!')
False
>>> testarg('hey')
True
>>> testarg('for')
False
>>> testarg('in')
False
>>> testarg('and')
False
Jason S
  • 184,598
  • 164
  • 608
  • 970

0 Answers0