Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a standard class / type that represents valid Python identifiers?

Being interpreted and lassez-faire, Python often blurs the boundary between what's an entity in the language (like a variable or class) or simply an entry in a runtime dictionary. The perhaps most prominent example are keyword arguments: one can switch between calling a function with individual arguments, whose names are Python identifiers, or with a single dict, whose keys are strings:

In [1]: def viking(spam, eggs):
   ...:     print(f"Eating {spam}")
   ...:     print(f"Eating {eggs}")
   ...:     print(f"Eating more {spam}")
   ...: 

In [2]: viking(spam="spammedy", eggs="eggedy")
Eating spammedy
Eating eggedy
Eating more spammedy

In [3]: viking(**{"spam": "spammedy", "eggs": "eggedy"})
Eating spammedy
Eating eggedy
Eating more spammedy

Both styles aren't equi-general though: while spam and eggs are valid identifiers, a string like "5+a.@))" does not correspond to something that could actually be a Python variable name.

As discussed elsewhere, Python itself makes a point of not preventing an attribute to be set as something that wouldn't be a legal identifier, but assume I wish to write some macro code that does enforce this. Is there somewhere in the standard libraries a class whose values correspond precisely to legal identifiers? Or at least a function that can be called to check whether or not a string represents such an identifier?

After all, these sort of considerations matter – if not elsewhere then at least when it comes to parsing Python code from plain text.

It turns out rather tricky to search the internet for something like that!

like image 606
leftaroundabout Avatar asked Dec 23 '25 02:12

leftaroundabout


1 Answers

I think the closest thing you could get to that is using typeguards:

from typing import TypeGuard

class Identifier(str):
    pass

def is_identifier(s: str) -> TypeGuard[Identifier]:
   return s.isidentifier()

This way you could annotate variables that should be valid identifiers with Identifier, and use is_identifier checks on the boundaries where you accept arbitrary strings, and you could use static type checkers like mypy to help enforce the constraints.

You could also define a __new__ to disallow direct instantiation of invalid Identifier instances.

like image 113
Jasmijn Avatar answered Dec 24 '25 23:12

Jasmijn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!