Source code for flutils.validators

import keyword
from collections import UserString
from typing import Union


_BUILTIN_NAMES = tuple(dir('__builtins__'))


[docs]def validate_identifier( identifier: Union[str, UserString], allow_underscore: bool = True ) -> None: """Validate the given string is a proper identifier. This validator will also raise an error if the given identifier is a keyword or a builtin identifier. Args: identifier (str): The value to be tested. allow_underscore (bool, optional): A value of ``False`` will raise an error when the ``identifier`` has a value that starts with an underscore ``_``. (Use :obj:`False` when validating potential :obj:`namedtuple <collections.namedtuple>` keys) Default: :obj:`True`. Raises: SyntaxError: If the given identifier is invalid. TypeError: If the given identifier is not a :obj:`str`. """ if isinstance(identifier, UserString): identifier = str(identifier) if not isinstance(identifier, str): raise TypeError( "The given 'identifier' must be a 'str'. Got: %r" % type(identifier).__name__ ) identifier = identifier.strip() if not identifier: raise SyntaxError("The given 'identifier' cannot be empty") if allow_underscore is False and identifier[0:1] == '_': raise SyntaxError( f"The given 'identifier', {identifier!r}, cannot start with an " "underscore '_'" ) if identifier[0:1].isdigit(): raise SyntaxError( f"The given 'identifier', {identifier!r}, cannot start with a " "number" ) if not identifier.isidentifier(): raise SyntaxError( f"The given 'identifier', {identifier!r}, is invalid." ) if keyword.iskeyword(identifier): raise SyntaxError( f"The given 'identifier', {identifier!r}, cannot be a keyword" ) if identifier in _BUILTIN_NAMES: raise SyntaxError( f"The given 'identifier', {identifier!r}, cannot be a builtin name" )