Environment management

The envprobe.environment module implements the logic that allow Envprobe to keep track of the current environment it is running in. At the core of the library is the Environment class, which is instantiated together with the current shell.Shell.

create_environment_variable(name, env, pipeline=None)

Create a vartypes.EnvVar instance for a variable, using a specific pipeline in an environment.

Parameters
  • name (str) – The name of the environment variable to create.

  • env (dict) – The raw mapping of environment variables to their values, as in os.environ.

  • pipeline (HeuristicStack, optional) – The heuristics pipeline to use to decide on the variable’s type. If not specified, default_heuristic is used.

Returns

The instantiated environment variable. The variable is instantiated even if the variable is not found in env.

Return type

vartypes.EnvVar

Raises

KeyError – If the variable was not resolved to a valid type by the pipeline, either because no heuristic mapped to anything, or a heuristic mapped to False.

class Environment(shell, env, variable_type_heuristics)

Owns and manages the understanding of environment variables’ state attached to a shell.

Environment manages two “states”, the current_environment and the stamped_environment. The current environment is usually instantiated from the environment of the shell Envprobe is running in, while the stamped environment is loaded from storage and lives between executions of an Envprobe operation.

Create an environment manager.

Parameters
__getitem__(variable_name)

Retrieve a vartypes.EnvVar environment variable from the current_environment’s values.

Returns

  • env_var (.vartypes.EnvVar) – The typed environment variable object. This object is always constructed, if there is no value associated with it then to a default empty state.

  • is_defined (bool) – True if the variable was actually defined in the environment.

apply_change(variable, remove=False)

Applies the changes in variable to the stamped_environment, i.e. modifying the pristine state.

Parameters
  • variable (vartypes.EnvVar) – The environment variable which value has been modified. (If the variable does not exist in the environment, it will be added with its current value.)

  • remove (bool) – If True, the variable will be removed from the environment, otherwise, the new value is saved.

Warning

The application of the change only happens to the “knowledge” of the environment manager instance. This method does not attempt to guarantee in any way that the change of the value is respected by the underlying shell.

See also

set_variable

Note

The function does not change what is written to persistent storage, only what is in the memory of the interpreter. Please use save() to emit changes to disk.

property current_environment

Obtain the current environment, which is usually the state of variables the object was instantiated with. This is considered the “dirty state” of the environment the tool is running in.

diff()

Generate the difference between stamped_environment and current_environment.

Returns

The difference for each variable that has been added, removed, or changed when the two environments are compared.

Return type

dict(str, VariableDifference)

Note

While this method is closely related and under the hood using vartypes.EnvVar.diff() to calculate the difference, the semantics of what is considered “added”, “removed”, and “changed” differ substantially.

get_stamped_variable(variable_name)

Retrieve a vartypes.EnvVar environment variable from the stamped_environment’s values.

Returns

  • env_var (.vartypes.EnvVar) – The typed environment variable object. This object is always constructed, if there is no value associated with it then to a default empty state.

  • is_defined (bool) – True if the variable was actually defined in the environment.

load()

Load the shell’s saved environment from storage to stamped_environment.

Note

If there is no backing file associated with the current shell’s state, or an IO error happens, the stamped environment will be loaded as empty.

save()

Save the stamped_environment to the persistent storage.

Note

If there is no backing file associated with the current shell’s state, the method will do nothing.

set_variable(variable, remove=False)

Sets the value of variable in the current_environment to the parameter, i.e. storing the change to the dirty state.

Parameters
  • variable (vartypes.EnvVar) – The variable which should be saved.

  • remove (bool) – If True, the variable will be removed from the environment, otherwise the new value is saved.

Warning

The application of the change only happens to the “knowledge” of the environment manager instance. This method does not attempt to guarantee in any way that the change of the value is respected by the underlying shell.

See also

apply_change

stamp()

Stamp the current_environment, making it become the stamped_environment.

property stamped_environment

Obtain the stamped environment which which is usually the one loaded from inter-session storage. This is considered the “pristine state” of the environment the tool is running in.

Difference of environments

The environment.diff() function creates and returns a VariableDifference for each changed variable.

class VariableDifference(kind, var_name, old_value=None, new_value=None, difference_actions=None)

The difference of a single variable between two states.

Parameters
  • kind (VariableDifferenceKind) – The “direction” of the difference’s result.

  • var_name (str) – The name of the variable that was differentiated.

  • old_value (unknown) – The “old” value of the variable.

  • new_value (unknown) – The “new” value of the variable.

  • difference_actions (list(char, str)) –

    The individual changes in the variable’s value, as returned by vartypes.EnvVar.diff().

    The list contains the changes with a mode symbol (-, = or + for removed, unchanged/same, added, respectively), and the value that was affected.

Raises

TypeErrorkind must be one of the constants in VariableDifferenceKind.

property is_new

Whether the current instance represents the definition of a new variable.

property is_simple_change

Whether the current instance represents a simple change.

A simple change is either the creation or removal of a value, or a single-step modification of a value from one value to another.

property is_unset

Whether the current instance represents the removal/unsetting of an existing variable.

class VariableDifferenceKind(value)

Named enumeration to indicate the “direction” of the VariableDifference.

ADDED

The variable is not defined in “old” but defined in “new”.

CHANGED

The variable is defined on both sides (“old” and “new”) of the difference, but to different values.

REMOVED

The variable is defined in “old” but not defined in “new”.

Type heuristics

To ensure that environment variables (which are in almost all cases handled simply as strings until they are parsed by a program) can be managed in a type-safe manner, heuristics that map a raw environment variable to a proper type can be passed to create_environment_variable() and Environment.

class EnvVarTypeHeuristic

A heuristic maps a variable’s name and it’s potential value in the environment to an envprobe.vartypes type.

__call__(name, env=None)

Resolve the variable of name (in the env environment) to an envprobe.vartype type identifier (as registered by vartypes.register_type()).

The default implementation resolves everything to be 'string', corresponding to vartypes.string.String.

Parameters
  • name (str) – The name of the environment variable.

  • env (dict, optional) – The raw mapping of environment variables to their values, as in os.environ.

Returns

  • vartype_name (str) – The name of an envprobe.vartypes implementation, if the heuristic resolved successfully.

  • NoneNone is returned if the heuristic could not resolve a type to be used.

  • False (bool) – False is returned if the heuristic resolved the variable not to be managed by Envprobe.

class HeuristicStack

A stack of EnvVarTypeHeuristic objects which resolve a variable in a set order.

Example

# Build the pipeline.
pipeline = HeuristicStack()
pipeline += HeuristicThatAlwaysReturnsString()
pipeline += HeuristicThatMapsTESTVarToFalse()

# (HeuristicStack executes the added heuristics in reverse order.)

# Use the pipeline to resolve.
pipeline("TEST", env)
>>> False

pipeline("OTHER_VAR", env)
>>> 'string'
__call__(name, env=None)

Resolve the variable of name (in the env environment) to an envprobe.vartype type identifier, using the heuristics in the order of the stack.

The resolution is run until a heuristic returns non-None (either False or an identifier).

Parameters
  • name (str) – The name of the environment variable.

  • env (dict, optional) – The raw mapping of environment variables to their values, as in os.environ.

Returns

  • vartype_name (str) – The name of an envprobe.vartypes implementation, if a heuristic resolved successfully.

  • NoneNone is returned if no heuristic could resolve a type to use.

  • False (bool) – False is returned if a heuristic resolved the variable not to be managed by Envprobe.

default_heuristic

Provides the default EnvVarTypeHeuristic added to an instantiated HeuristicStack.

The default heuristic maps every variable to a pure vartypes.string.String.

Available heuristics

The following heuristics are implemented in the vartype_heuristics module. All these classes are subclasses of EnvVarTypeHeuristic.

ConfigurationResolvedHeuristic

Implements a heuristic that reads from a settings.variable_information.VariableInformation configuration manager, and resolves the type of the variable based on these settings contained therein.

EnvprobeEnvVarHeuristic

Disable access to internal variables that begin with ENVPROBE_.

HiddenEnvVarHeuristic

Disable access to every variable that begins with _, similar to how files named as such are considered "hidden".

NumericalNameEnvVarHeuristic

Regard commonly numeric-only variables as vartypes.numeric.Numeric.

NumericalValueEnvVarHeuristic

Regard environment variables that currently have a numeric value as vartypes.numeric.Numeric.

PathNameEnvVarHeuristic

Regard PATH and variables that end with _PATH as vartypes.path.Path.

assemble_standard_type_heuristics_pipeline(varcfg_user_loader, varcfg_description_loader)

Creates the standard environment.HeuristicStack pipeline that decides the type for an environment variable.

This pipeline uses the configuration of the user and the community first, and then the heuristics pre-implemented in Envprobe to deduce a vartype for an environment variable.

Parameters
  • varcfg_user_loader (str -> object) – The function used for the ConfigurationResolvedHeuristic internally. This function is called with the name of a variable and should return an object similar to settings.variable_information.VariableInformation in which the type can be looked up.

  • varcfg_description_loader (str -> object) – The function used for the ConfigurationResolvedHeuristic internally. This function is called with the name of a variable and should return an object similar to settings.variable_information.VariableInformation in which the type can be looked up.