aiida.common#

Common data structures, utility classes and functions

Note

Modules in this sub package have to run without a loaded database environment

Package Contents#

Classes#

AttributeDict

This class internally stores values in a dictionary, but exposes the keys also as attributes, i.e. asking for attrdict.key will return the value of attrdict[‘key’] and so on.

CalcInfo

This object will store the data returned by the calculation plugin and to be passed to the ExecManager.

CalcJobState

The sub state of a CalcJobNode while its Process is in an active state (i.e. Running or Waiting).

CodeInfo

This attribute-dictionary contains the information needed to execute a code. Possible attributes are:

CodeRunMode

Enum to indicate the way the codes of a calculation should be run.

DefaultFieldsAttributeDict

A dictionary with access to the keys as attributes, and with an internal value storing the ‘default’ keys to be distinguished from extra fields.

FixedFieldsAttributeDict

A dictionary with access to the keys as attributes, and with filtering of valid attributes. This is only the base class, without valid attributes; use a derived class to do the actual work. E.g.:

GraphTraversalRules

Graph traversal rules when deleting or exporting nodes.

LinkType

A simple enum of allowed link types.

ProgressReporterAbstract

An abstract class for incrementing a progress reporter.

StashMode

Mode to use when stashing files from the working directory of a completed calculation job for safekeeping.

Functions#

create_callback

Create a callback function to update the progress reporter.

get_progress_reporter

Return the progress reporter

override_log_level

Temporarily adjust the log-level of logger.

set_progress_bar_tqdm

Set a tqdm implementation of the progress reporter interface.

set_progress_reporter

Set the progress reporter implementation

validate_link_label

Validate the given link label.

Data#

AIIDA_LOGGER

GraphTraversalRule

A namedtuple that defines a graph traversal rule.

TQDM_BAR_FORMAT

API#

aiida.common.AIIDA_LOGGER = 'cast(...)'#
exception aiida.common.AiidaException#

Bases: Exception

Base class for all AiiDA exceptions.

Each module will have its own subclass, inherited from this (e.g. ExecManagerException, TransportException, …)

Initialization

Initialize self. See help(type(self)) for accurate signature.

class aiida.common.AttributeDict(dictionary=None)#

Bases: dict

This class internally stores values in a dictionary, but exposes the keys also as attributes, i.e. asking for attrdict.key will return the value of attrdict[‘key’] and so on.

Raises an AttributeError if the key does not exist, when called as an attribute, while the usual KeyError if the key does not exist and the dictionary syntax is used.

Initialization

Recursively turn the dict and all its nested dictionaries into AttributeDict instance.

__repr__()#

Representation of the object.

__getattr__(attr)#

Read a key as an attribute.

Raises:

AttributeError – if the attribute does not correspond to an existing key.

__setattr__(attr, value)#

Set a key as an attribute.

__delattr__(attr)#

Delete a key as an attribute.

Raises:

AttributeError – if the attribute does not correspond to an existing key.

__deepcopy__(memo=None)#

Deep copy.

__getstate__()#

Needed for pickling this class.

__setstate__(dictionary)#

Needed for pickling this class.

__dir__()#
class aiida.common.CalcInfo#

Bases: aiida.common.extendeddicts.DefaultFieldsAttributeDict

This object will store the data returned by the calculation plugin and to be passed to the ExecManager.

In the following descriptions all paths have to be considered relative

  • retrieve_list: a list of strings or tuples that indicate files that are to be retrieved from the remote after the

    calculation has finished and stored in the retrieved_folder output node of type FolderData. If the entry in the list is just a string, it is assumed to be the filepath on the remote and it will be copied to the base directory of the retrieved folder, where the name corresponds to the basename of the remote relative path. This means that any remote folder hierarchy is ignored entirely.

    Remote folder hierarchy can be (partially) maintained by using a tuple instead, with the following format

    (source, target, depth)

    The source and target elements are relative filepaths in the remote and retrieved folder. The contents of source (whether it is a file or folder) are copied in its entirety to the target subdirectory in the retrieved folder. If no subdirectory should be created, '.' should be specified for target.

    The source filepaths support glob patterns * in case the exact name of the files that are to be retrieved are not know a priori.

    The depth element can be used to control what level of nesting of the source folder hierarchy should be maintained. If depth equals 0 or 1 (they are equivalent), only the basename of the source filepath is kept. For each additional level, another subdirectory of the remote hierarchy is kept. For example:

    (‘path/sub/file.txt’, ‘.’, 2)

    will retrieve the file.txt and store it under the path:

    sub/file.txt

  • retrieve_temporary_list: a list of strings or tuples that indicate files that will be retrieved

    and stored temporarily in a FolderData, that will be available only during the parsing call. The format of the list is the same as that of ‘retrieve_list’

  • local_copy_list: a list of tuples with format (‘node_uuid’, ‘filename’, relativedestpath’)

  • remote_copy_list: a list of tuples with format (‘remotemachinename’, ‘remoteabspath’, ‘relativedestpath’)

  • remote_symlink_list: a list of tuples with format (‘remotemachinename’, ‘remoteabspath’, ‘relativedestpath’)

  • provenance_exclude_list: a sequence of relative paths of files in the sandbox folder of a CalcJob instance that

    should not be stored permanantly in the repository folder of the corresponding CalcJobNode that will be created, but should only be copied to the remote working directory on the target computer. This is useful for input files that should be copied to the working directory but should not be copied as well to the repository either, for example, because they contain proprietary information or because they are big and their content is already indirectly present in the repository through one of the data nodes passed as input to the calculation.

  • codes_info: a list of dictionaries used to pass the info of the execution of a code

  • codes_run_mode: the mode of execution in which the codes will be run (CodeRunMode.SERIAL by default,

    but can also be CodeRunMode.PARALLEL)

  • skip_submit: a flag that, when set to True, orders the engine to skip the submit/update steps (so no code will

    run, it will only upload the files and then retrieve/parse).

_default_fields = ('job_environment', 'email', 'email_on_started', 'email_on_terminated', 'uuid', 'prepend_text', 'app...#
class aiida.common.CalcJobState#

Bases: enum.Enum

The sub state of a CalcJobNode while its Process is in an active state (i.e. Running or Waiting).

UPLOADING = 'uploading'#
SUBMITTING = 'submitting'#
WITHSCHEDULER = 'withscheduler'#
STASHING = 'stashing'#
RETRIEVING = 'retrieving'#
PARSING = 'parsing'#
exception aiida.common.ClosedStorage#

Bases: aiida.common.exceptions.AiidaException

Raised when trying to access data from a closed storage backend.

Initialization

Initialize self. See help(type(self)) for accurate signature.

class aiida.common.CodeInfo#

Bases: aiida.common.extendeddicts.DefaultFieldsAttributeDict

This attribute-dictionary contains the information needed to execute a code. Possible attributes are:

  • cmdline_params: a list of strings, containing parameters to be written on the command line right after the call to the code, as for example:

    code.x cmdline_params[0] cmdline_params[1] ... < stdin > stdout
    
  • stdin_name: (optional) the name of the standard input file. Note, it is only possible to use the stdin with the syntax:

    code.x < stdin_name
    

    If no stdin_name is specified, the string “< stdin_name” will not be passed to the code. Note: it is not possible to substitute/remove the ‘<’ if stdin_name is specified; if that is needed, avoid stdin_name and use instead the cmdline_params to specify a suitable syntax.

  • stdout_name: (optional) the name of the standard output file. Note, it is only possible to pass output to stdout_name with the syntax:

    code.x ... > stdout_name
    

    If no stdout_name is specified, the string “> stdout_name” will not be passed to the code. Note: it is not possible to substitute/remove the ‘>’ if stdout_name is specified; if that is needed, avoid stdout_name and use instead the cmdline_params to specify a suitable syntax.

  • stderr_name: (optional) a string, the name of the error file of the code.

  • join_files: (optional) if True, redirects the error to the output file. If join_files=True, the code will be called as:

    code.x ... > stdout_name 2>&1
    

    otherwise, if join_files=False and stderr is passed:

    code.x ... > stdout_name 2> stderr_name
    
  • withmpi: if True, executes the code with mpirun (or another MPI installed on the remote computer)

  • code_uuid: the uuid of the code associated to the CodeInfo

_default_fields = ('cmdline_params', 'stdin_name', 'stdout_name', 'stderr_name', 'join_files', 'withmpi', 'code_uuid')#
class aiida.common.CodeRunMode#

Bases: enum.IntEnum

Enum to indicate the way the codes of a calculation should be run.

For PARALLEL, the codes for a given calculation will be run in parallel by running them in the background:

code1.x &
code2.x &

For the SERIAL option, codes will be executed sequentially by running for example the following:

code1.x
code2.x

Initialization

Initialize self. See help(type(self)) for accurate signature.

SERIAL = 0#
PARALLEL = 1#
exception aiida.common.ConfigurationError#

Bases: aiida.common.exceptions.AiidaException

Error raised when there is a configuration error in AiiDA.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.ConfigurationVersionError#

Bases: aiida.common.exceptions.ConfigurationError

Configuration error raised when the configuration file version is not compatible with the current version.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.ContentNotExistent#

Bases: aiida.common.exceptions.NotExistent

Raised when trying to access an attribute, a key or a file in the result nodes that is not present

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.CorruptStorage#

Bases: aiida.common.exceptions.ConfigurationError

Raised when the storage is not found to be internally consistent on validation.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.DbContentError#

Bases: aiida.common.exceptions.AiidaException

Raised when the content of the DB is not valid. This should never happen if the user does not play directly with the DB.

Initialization

Initialize self. See help(type(self)) for accurate signature.

class aiida.common.DefaultFieldsAttributeDict(dictionary=None)#

Bases: aiida.common.extendeddicts.AttributeDict

A dictionary with access to the keys as attributes, and with an internal value storing the ‘default’ keys to be distinguished from extra fields.

Extra methods defaultkeys() and extrakeys() divide the set returned by keys() in default keys (i.e. those defined at definition time) and other keys. There is also a method get_default_fields() to return the internal list.

Moreover, for undefined default keys, it returns None instead of raising a KeyError/AttributeError exception.

Remember to define the _default_fields in a subclass! E.g.:

class TestExample(DefaultFieldsAttributeDict):
    _default_fields = ('a','b','c')

When the validate() method is called, it calls in turn all validate_KEY methods, where KEY is one of the default keys. If the method is not present, the field is considered to be always valid. Each validate_KEY method should accept a single argument ‘value’ that will contain the value to be checked.

It raises a ValidationError if any of the validate_KEY function raises an exception, otherwise it simply returns. NOTE: the validate_* functions are called also for unset fields, so if the field can be empty on validation, you have to start your validation function with something similar to:

if value is None:
    return

Initialization

Recursively turn the dict and all its nested dictionaries into AttributeDict instance.

_default_fields = 'tuple(...)'#
validate()#

Validate the keys, if any validate_* method is available.

__setattr__(attr, value)#

Overridden to allow direct access to fields with underscore.

__getitem__(key)#

Return None instead of raising an exception if the key does not exist but is in the list of default fields.

classmethod get_default_fields()#

Return the list of default fields, either defined in the instance or not.

defaultkeys()#

Return the default keys defined in the instance.

extrakeys()#

Return the extra keys defined in the instance.

exception aiida.common.EntryPointError#

Bases: aiida.common.exceptions.AiidaException

Raised when an entry point cannot be uniquely resolved and imported.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.FailedError#

Bases: aiida.common.exceptions.AiidaException

Raised when accessing a calculation that is in the FAILED status

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.FeatureDisabled#

Bases: aiida.common.exceptions.AiidaException

Raised when a feature is requested, but the user has chosen to disable it (e.g., for submissions on disabled computers).

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.FeatureNotAvailable#

Bases: aiida.common.exceptions.AiidaException

Raised when a feature is requested from a plugin, that is not available.

Initialization

Initialize self. See help(type(self)) for accurate signature.

class aiida.common.FixedFieldsAttributeDict(init=None)#

Bases: aiida.common.extendeddicts.AttributeDict

A dictionary with access to the keys as attributes, and with filtering of valid attributes. This is only the base class, without valid attributes; use a derived class to do the actual work. E.g.:

class TestExample(FixedFieldsAttributeDict):
    _valid_fields = ('a','b','c')

Initialization

Recursively turn the dict and all its nested dictionaries into AttributeDict instance.

_valid_fields = 'tuple(...)'#
__setitem__(item, value)#

Set a key as an attribute.

__setattr__(attr, value)#

Overridden to allow direct access to fields with underscore.

classmethod get_valid_fields()#

Return the list of valid fields.

__dir__()#
aiida.common.GraphTraversalRule = 'namedtuple(...)'#

A namedtuple that defines a graph traversal rule.

When starting from a certain sub set of nodes, the graph traversal rules specify which links should be followed to add adjacent nodes to finally arrive at a set of nodes that represent a valid and consistent sub graph.

Parameters:
  • link_type – the LinkType that the rule applies to

  • direction – whether the link type should be followed backwards or forwards

  • toggleable – boolean to indicate whether the rule can be changed from the default value. If this is False it means the default value can never be changed as it will result in an inconsistent graph.

  • default – boolean, the default value of the rule, if True means that the link type for the given direction should be followed.

class aiida.common.GraphTraversalRules#

Bases: enum.Enum

Graph traversal rules when deleting or exporting nodes.

DEFAULT = None#
DELETE = None#
EXPORT = None#
exception aiida.common.HashingError#

Bases: aiida.common.exceptions.AiidaException

Raised when an attempt to hash an object fails via a known failure mode

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.IncompatibleStorageSchema#

Bases: aiida.common.exceptions.IncompatibleDatabaseSchema

Raised when the storage schema is incompatible with that of the code.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.InputValidationError#

Bases: aiida.common.exceptions.ValidationError

The input data for a calculation did not validate (e.g., missing required input data, wrong data, …)

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.IntegrityError#

Bases: aiida.common.exceptions.AiidaException

Raised when there is an underlying data integrity error. This can be database related or a general data integrity error. This can happen if, e.g., a foreign key check fails. See PEP 249 for details.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.InternalError#

Bases: aiida.common.exceptions.AiidaException

Error raised when there is an internal error of AiiDA.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.InvalidEntryPointTypeError#

Bases: aiida.common.exceptions.EntryPointError

Raised when a loaded entry point has a type that is not supported by the corresponding entry point group.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.InvalidOperation#

Bases: aiida.common.exceptions.AiidaException

The allowed operation is not valid (e.g., when trying to add a non-internal attribute before saving the entry), or deleting an entry that is protected (e.g., because it is referenced by foreign keys)

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.LicensingException#

Bases: aiida.common.exceptions.AiidaException

Raised when requirements for data licensing are not met.

Initialization

Initialize self. See help(type(self)) for accurate signature.

class aiida.common.LinkType#

Bases: enum.Enum

A simple enum of allowed link types.

CREATE = 'create'#
RETURN = 'return'#
INPUT_CALC = 'input_calc'#
INPUT_WORK = 'input_work'#
CALL_CALC = 'call_calc'#
CALL_WORK = 'call_work'#
exception aiida.common.LoadingEntryPointError#

Bases: aiida.common.exceptions.EntryPointError

Raised when the resource corresponding to requested entry point cannot be imported.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.LockedProfileError#

Bases: aiida.common.exceptions.AiidaException

Raised if attempting to access a locked profile

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.LockingProfileError#

Bases: aiida.common.exceptions.AiidaException

Raised if the profile can`t be locked

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.MissingConfigurationError#

Bases: aiida.common.exceptions.ConfigurationError

Configuration error raised when the configuration file is missing.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.MissingEntryPointError#

Bases: aiida.common.exceptions.EntryPointError

Raised when the requested entry point is not registered with the entry point manager.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.ModificationNotAllowed#

Bases: aiida.common.exceptions.AiidaException

Raised when the user tries to modify a field, object, property, … that should not be modified.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.MultipleEntryPointError#

Bases: aiida.common.exceptions.EntryPointError

Raised when the requested entry point cannot uniquely be resolved by the entry point manager.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.MultipleObjectsError#

Bases: aiida.common.exceptions.AiidaException

Raised when more than one entity is found in the DB, but only one was expected.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.NotExistent#

Bases: aiida.common.exceptions.AiidaException

Raised when the required entity does not exist.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.NotExistentAttributeError#

Bases: AttributeError, aiida.common.exceptions.NotExistent

Raised when the required entity does not exist, when fetched as an attribute.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.NotExistentKeyError#

Bases: KeyError, aiida.common.exceptions.NotExistent

Raised when the required entity does not exist, when fetched as a dictionary key.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.OutputParsingError#

Bases: aiida.common.exceptions.ParsingError

Can be raised by a Parser when it fails to parse the output generated by a CalcJob process.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.ParsingError#

Bases: aiida.common.exceptions.AiidaException

Generic error raised when there is a parsing error

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.PluginInternalError#

Bases: aiida.common.exceptions.InternalError

Error raised when there is an internal error which is due to a plugin and not to the AiiDA infrastructure.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.ProfileConfigurationError#

Bases: aiida.common.exceptions.ConfigurationError

Configuration error raised when a wrong/inexistent profile is requested.

Initialization

Initialize self. See help(type(self)) for accurate signature.

class aiida.common.ProgressReporterAbstract(*, total: int, desc: Optional[str] = None, **kwargs: Any)#

An abstract class for incrementing a progress reporter.

This class provides the base interface for any ProgressReporter class.

Example Usage:

with ProgressReporter(total=10, desc="A process:") as progress:
    for i in range(10):
        progress.set_description_str(f"A process: {i}")
        progress.update()

Initialization

Initialise the progress reporting contextmanager.

Parameters:
  • total – The number of expected iterations.

  • desc – A description of the process

property total: int#

Return the total iterations expected.

property desc: Optional[str]#

Return the description of the process.

property n: int#

Return the current iteration.

__enter__() aiida.common.progress_reporter.ProgressReporterAbstract#

Enter the contextmanager.

__exit__(exctype: Optional[Type[BaseException]], excinst: Optional[BaseException], exctb: Optional[types.TracebackType])#

Exit the contextmanager.

set_description_str(text: Optional[str] = None, refresh: bool = True)#

Set the text shown by the progress reporter.

Parameters:
  • text – The text to show

  • refresh – Force refresh of the progress reporter

update(n: int = 1)#

Update the progress counter.

Parameters:

n – Increment to add to the internal counter of iterations

reset(total: Optional[int] = None)#

Resets current iterations to 0.

Parameters:

total – If not None, update number of expected iterations.

exception aiida.common.RemoteOperationError#

Bases: aiida.common.exceptions.AiidaException

Raised when an error in a remote operation occurs, as in a failed kill() of a scheduler job.

Initialization

Initialize self. See help(type(self)) for accurate signature.

class aiida.common.StashMode#

Bases: enum.Enum

Mode to use when stashing files from the working directory of a completed calculation job for safekeeping.

COPY = 'copy'#
exception aiida.common.StorageMigrationError#

Bases: aiida.common.exceptions.DatabaseMigrationError

Raised if a critical error is encountered during a storage migration.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.StoringNotAllowed#

Bases: aiida.common.exceptions.AiidaException

Raised when the user tries to store an unstorable node (e.g. a base Node class)

Initialization

Initialize self. See help(type(self)) for accurate signature.

aiida.common.TQDM_BAR_FORMAT = '{desc:40.40}{percentage:6.1f}%|{bar}| {n_fmt}/{total_fmt}'#
exception aiida.common.TestsNotAllowedError#

Bases: aiida.common.exceptions.AiidaException

Raised when tests are required to be run/loaded, but we are not in a testing environment.

This is to prevent data loss.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.TransportTaskException#

Bases: aiida.common.exceptions.AiidaException

Raised when a TransportTask, an task to be completed by the engine that requires transport, fails

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.UniquenessError#

Bases: aiida.common.exceptions.AiidaException

Raised when the user tries to violate a uniqueness constraint (on the DB, for instance).

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.UnsupportedSpeciesError#

Bases: ValueError

Raised when StructureData operations are fed species that are not supported by AiiDA such as Deuterium

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception aiida.common.ValidationError#

Bases: aiida.common.exceptions.AiidaException

Error raised when there is an error during the validation phase of a property.

Initialization

Initialize self. See help(type(self)) for accurate signature.

aiida.common.create_callback(progress_reporter: aiida.common.progress_reporter.ProgressReporterAbstract) Callable[[str, Any], None]#

Create a callback function to update the progress reporter.

Returns:

a callback to report on the process, callback(action, value), with the following callback signatures:

  • callback('init', {'total': <int>, 'description': <str>}),

    to reset the progress with a new total iterations and description

  • callback('update', <int>),

    to update the progress by a certain number of iterations

aiida.common.get_progress_reporter() Type[aiida.common.progress_reporter.ProgressReporterAbstract]#

Return the progress reporter

Example Usage:

with get_progress_reporter()(total=10, desc="A process:") as progress:
    for i in range(10):
        progress.set_description_str(f"A process: {i}")
        progress.update()
aiida.common.override_log_level(level=logging.CRITICAL)#

Temporarily adjust the log-level of logger.

aiida.common.set_progress_bar_tqdm(bar_format: Optional[str] = TQDM_BAR_FORMAT, leave: Optional[bool] = False, **kwargs: Any)#

Set a tqdm implementation of the progress reporter interface.

See set_progress_reporter() for details.

Parameters:
  • bar_format – Specify a custom bar string format.

  • leave – If True, keeps all traces of the progressbar upon termination of iteration. If None, will leave only if position is 0.

  • kwargs – pass to the tqdm init

aiida.common.set_progress_reporter(reporter: Optional[Type[aiida.common.progress_reporter.ProgressReporterAbstract]] = None, **kwargs: Any)#

Set the progress reporter implementation

Parameters:
  • reporter – A progress reporter for a process. If None, reset to ProgressReporterNull.

  • kwargs – If present, set a partial function with these kwargs

The reporter should be a context manager that implements the ProgressReporterAbstract() interface.

Example Usage:

set_progress_reporter(ProgressReporterNull)
with get_progress_reporter()(total=10, desc="A process:") as progress:
    for i in range(10):
        progress.set_description_str(f"A process: {i}")
        progress.update()

Validate the given link label.

Valid link labels adhere to the following restrictions:

  • Has to be a valid python identifier

  • Can only contain alphanumeric characters and underscores

  • Can not start or end with an underscore

Raises:
  • TypeError – if the link label is not a string type

  • ValueError – if the link label is invalid