Pythoncially check if a variable name is valid
Question: tldr; see the final line; the rest is just preamble.

* * *

I am developing a test harness, which parses user scripts and generates a
Python script which it then runs. The idea is for non-techie folks to be able
to write high-level test scripts.

I have introduced the idea of variables, so a user can use the `LET` keyword
in his script. E.g. `LET X = 42`, which I simply expand to `X = 42`. They can
then use X later in their scripts - `RELEASE CONNECTION X`

But what if someone writes `LET 2 = 3`? That's going to generate invalid
Python.

If I have that `X` in a variable `variableName`, then how can I check whether
`variableName` is a valid Python variable?


Answer: In Python 3 you can use
[`str.isidentifier()`](https://docs.python.org/3/library/stdtypes.html?highlight=identifier#str.isidentifier)
to test whether a given string is a valid Python identifier/name.

    
    
    >>> 'X'.isidentifier()
    True
    >>> 'X123'.isidentifier()
    True
    >>> '2'.isidentifier()
    False
    >>> 'while'.isidentifier()
    True
    

The last example shows that you should also check whether the variable name
clashes with a Python keyword:

    
    
    >>> from keyword import iskeyword
    >>> iskeyword('X')
    False
    >>> iskeyword('while')
    True
    

So you could put that together in a function:

    
    
    from keyword import iskeyword
    
    def is_valid_variable_name(name):
        return name.isidentifier() and not iskeyword(name)
    

* * *

Another option, which works in Python 2 and 3, is to use the `ast` module:

    
    
    from ast import parse
    
    def is_valid_variable_name(name):
        try:
            parse('{} = None'.format(name))
            return True
        except SyntaxError, ValueError, TypeError:
            return False
    
    >>> is_valid_variable_name('X')
    True
    >>> is_valid_variable_name('123')
    False
    >>> is_valid_variable_name('for')
    False
    >>> is_valid_variable_name('')
    False
    >>> is_valid_variable_name(42)
    False
    

This will parse the assignment statement without actually executing it. It
will pick up invalid identifiers as well as attempts to assign to a keyword.
In the above code `None` is an arbitrary value to assign to the given name -
it could be any valid expression for the RHS.

