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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With