Environment variable utilities management.

This module provides a flexible system for defining and managing environment variables with automatic type conversion and validation. It implements a approach where class attributes can be bound to environment variables and automatically resolved when accessed.

The module includes two main components:

  • evar — A type that binds class attributes to environment variables with automatic type conversion and default value support.

  • Environment — A mutable mapping that provides a namespace for organizing and managing multiple environment variables with support for merging, serialization, and subprocess integration.

Key features:

  • Automatic type conversion for Python’s built-in types (str, int, float, bool, Path, and lists of these types).

  • Arithmetic operations for creating derived environment variables.

  • Support for boolean conversion with configurable truthy values.

  • List parsing with configurable separators.

  • Dictionary-like interface for managing environment variables.

  • Automatic conversion to string dictionaries for subprocess execution.

  • Protected attributes that cannot be modified after initialization.

Examples:

from deluxe import Environment, evar
from pathlib import Path

class Config(Environment):
    DEBUG = evar(default=False, truthy=("yes", "1", "true"))
    PORT = evar(default=8080)
    FOLDER = evar(default=Path("/tmp/data"))
    PATHS = evar(default=["/usr/bin"], separator=":")

# Create and use environment configuration
env = Config(DEBUG="yes", PORT=9000, FOLDER=Path("/home/user"))
print(env.DEBUG)  # True
print(env.PORT)   # 9000

# Export for subprocess execution
env_dict = env.env  # Converts all values to strings

# Arithmetic operations for derived values
HALF_PORT = Config.PORT / 2  # Creates new evar that divides PORT by 2

Module Contents

Classes

evar

Declare a class variable to be bind to an…

Environment

A mutable mapping for environment variables.

Attributes

EnvValue

Type alias representing supported environment…

Separator

Type alias representing supported separator…

SEPARATOR

Default separator character for parsing list…

Operator

Type alias representing binary operators for…

EnvValue

Type alias representing supported environment variable value types.

This union type includes all Python types that can be used as environment variable values in the Environment class. It supports:

  • str — String values (most common for environment variables)

  • int — Integer values

  • float — Floating-point values

  • bool — Boolean values (converted from strings like “true”, “1”, “on”)

  • Path — File system paths

  • list [ str ] — Lists of strings (parsed from separated values)

  • list [ Path ] — Lists of paths (parsed from separated values)

Separator

Type alias representing supported separator characters for list values.

This literal type defines the allowed separator characters used when parsing environment variable strings into lists. Supported separators are:

  • ";" — Semicolon

  • ":" — Colon (default)

  • "," — Comma

  • " " — Space

SEPARATOR : Separator = "':'"

Default separator character for parsing list values from environment variables.

This constant defines the default separator used when converting environment variable strings to lists. It can be overridden per-attribute using the separator argument in evar or via Environment.add_list_separator().

Operator

Type alias representing binary operators for environment variable arithmetic.

This callable type represents binary operations that can be performed on evar instances to create derived environment variables. The operator takes two values of the same type and returns a value of that type.

Examples include addition, subtraction, multiplication, division, and path concatenation operations.

class evar(
default: _E | evar[_E] = Unset,
*,
truthy: tuple[str, Ellipsis] = ('true', '1', 'on'),
separator: Separator = SEPARATOR,
)[source]

Extends: deluxe.functional.Lazy[_E]

Declare a class variable to be bind to an environment variable of the same name.

The evar class binds a class attribute to an environment variable. When the attribute is accessed via unwrap(), it retrieves the value from the environment, converts it to the type of default argument, and returns it. If the environment variable is not set, the default value is returned.

The evar instance type is taken from the given default argument and is Unset by default.

This class supports various Python types including str, int, float, bool, Path, and lists of these types. Boolean and list conversions are configurable via the truthy and separator arguments.

The class also supports arithmetic operations to create derived environment variables. Available operations depends on the type of the evar instance. For example, FOLDER / "subdir" creates a new evar that resolves to the concatenation of FOLDER and "subdir".

Examples

Simple string variable:

class Config:
    USER = evar(default="guest")

# If USER env var is not set, returns "guest"
username = Config.USER.unwrap()

Numeric operations:

class Config:
    PORT = evar(default=8080)
    # Creates a new evar augmenting PORT by 1
    ALT_PORT = PORT + 1

Path operations:

class Config:
    FOLDER = evar(default=Path("/tmp"))
    SUB_FOLDER = FOLDER / "data"

Boolean conversion:

class Config:
    DEBUG = evar(default=False, truthy=("yes", "1", "true"))

# If DEBUG="yes", returns True
is_debug = Config.DEBUG.unwrap()

List parsing:

class Config:
    PATHS = evar(default=["/usr/bin"], separator=":")

# If PATHS="/bin:/usr/bin", returns ["/bin", "/usr/bin"]
paths = Config.PATHS.unwrap()
Parameters:
default: _E | evar[_E] = Unset

Default value for the environment variable. If another evar is provided, it will be resolved recursively. If Unset, the environment variable is required.

truthy: tuple[str, Ellipsis] = ('true', '1', 'on')

Tuple of string values considered as True for boolean type conversion. Defaults to ("true", "1", "on").

separator: Separator = SEPARATOR

Separator character for parsing list values from strings. Defaults to ":".

type

The Python type that this evar resolves to.

Raises:

NotImplementedError – When using arithmetic operations on unsupported types (e.g., abs() on a string).

Unwraping evar:

Resolve and return the environment variable value.

Retrieves the environment variable corresponding to this evar’s name. If found, the value is converted to the specified type. If not found or conversion fails, returns the default value.

For arithmetic-derived evar instances, applies the stored operator to resolve the final value.

If no default value was provided (self.type is Unset) and a value is found in the environment, value will be evaluated as a str, otherwise Unset is return.

inherited Members

type

Return the Python type that this Lazy

classmethod pure(value)

Wrap a plain value into the lazy monadic context.

map(func, type)

Apply a function to the lazy value using…

bind(func, type)

Chain a function that returns a lazy value…

join()

Flatten this lazy value by wrapping it again.

unwrap()

Execute the lazy computation and return its…

class Environment(
other: _SupportsKeysAndGetItem | collections.abc.Iterable[tuple[str, EnvValue | evar[EnvValue]]] = (),
/,
**kwargs: EnvValue,
)[source]

Extends: collections.abc.MutableMapping[str, EnvValue | evar[EnvValue]], types.SimpleNamespace

A mutable mapping for environment variables.

The Environment class provides a way to define and manipulate environment variables with various Python types. It implements the MutableMapping abc, making it compatible with standard dictionary operations and other mapping abstractions.

Instances acts either as a regular MutableMapping or a SimpleNamespace, so setting instance attribute with ‘instance.a = value’ is equivalent to ‘instance[name] = value’.

This class supports storing environment variables as native Python types such as str, int, float, bool, Path, and lists of these types. When exporting to a dictionary for use with subprocesses or other system calls, use the env property which converts all values to strings.

The env property also automatically resolves any evar defined in the class hierarchy or set as an instance’s attribute and includes them in the exported dictionary.

Basic Usage

Creating an Environment instance:

from deluxe import Environment, evar
from pathlib import Path

class Config(Environment):
    DEBUG = evar(default=False, truthy=("yes", "1", "true"))
    PORT = evar(default=8080)
    FOLDER = evar(default=Path("/tmp/data"))

# Instantiate and populate
env = Config(DEBUG="yes", PORT=9000, FOLDER=Path("/home/user"))
print(env.DEBUG)  # True
print(env.PORT)   # 9000

Using the env property for subprocess:

import subprocess
env_dict = env.env  # Converts all values to str
subprocess.run(["my_command"], env=env_dict)

Merging environments:

base = Config(DEBUG=False)
overrides = {"DEBUG": "true", "PORT": "3000"}
merged = base | overrides

List Deduplication

When setting a list value, duplicates are automatically removed while preserving order. The first occurrence of each element is kept. This deduplication applies whenever a list value is provided to the environment: at instantiation, via update(), or by direct attribute assignment.

Deduplication at instantiation:

env = Environment(PATHS=["/usr/bin", "/bin", "/usr/bin"])
# env.PATHS is now ["/usr/bin", "/bin"]

Deduplication via update:

env = Environment(PATHS=["/usr/bin"])
env.update({"PATHS": ["/bin", "/usr/bin"]})
# env.PATHS is now ["/usr/bin", "/bin"]

Deduplication on attribute assignment:

env = Environment()
env.PATHS = ["/usr/bin", "/bin", "/usr/bin"]
# env.PATHS is now ["/usr/bin", "/bin"]

Assigning to an existing list attribute appends new values and deduplicates the combined result:

env = Environment()
env.PATHS = ["/usr/bin"]
env.PATHS = ["/bin", "/usr/bin"]
# env.PATHS is now ["/usr/bin", "/bin"]

This append-on-assign behavior means list assignment is not idempotent. Use clear() or pop() to replace a list entirely:

env.clear()
env.PATHS = ["/usr/bin", "/bin"]

See also

  • evar: Type for binding class attributes to environment variables.

property env : dict[str, str]

Returns self as a dict with all values converted to str.

Returns:

dict[str, str] – A dictionary containing the environment variables.

static add_list_separator(attribute: str, separator: Separator) None[source]

Adds a list separator for a specific attribute.

Parameters:
attribute : str

The attribute to add the separator for.

separator : str

The separator character.

get(name: str, default: EnvValue | evar[EnvValue] = '') EnvValue | evar[EnvValue][source]

Retrieve the value associated with a name.

Retrieve the value associated with the given name.

Parameters:
name : str

The name to retrieve the value for.

default : EnvValue, optional

The default value to return

string. : if name is not found. Defaults to an empty

Returns:

EnvValue – The value associated with name if found, otherwise the default value.

items() collections.abc.ItemsView[str, EnvValue | evar[EnvValue]][source]

Returns a view of the name-value pairs of this Mapping.

Returns:

An ItemsView that provides a dynamic view on this Mapping.

keys() collections.abc.KeysView[str][source]

Returns a view of the keys this Mapping.

Returns:

A KeysView that provides a dynamic view on this Mapping’s keys.

values() collections.abc.ValuesView[EnvValue | evar[EnvValue]][source]

Returns a view of the values in this Mapping.

Returns:

A ValuesView that provides a dynamic view on this Mapping’s values.

copy() Environment[source]

Creates a shallow copy of this mapping.

Returns:

EnvMapping – A new EnvMapping object that is a deep copy of the original.

update(
other: Environment | collections.abc.Mapping[str, EnvValue | evar[EnvValue]],
clear: list[str] | None = None,
) None[source]

Update this Mapping.

Update this Mapping with the values from another Mapping.

Parameters:
other : EnvMapping | dict[str, Any]

The object or mapping

with. : containing the values to update the EnvMapping

clear : list[str], optional

A list of names to set as empty lists

list. : in the EnvMapping. Defaults to an empty

clear() None[source]

Clears all attributes.

pop(name: str, default: object | None = None) EnvValue | evar[EnvValue][source]

Removes and returns the value associated with a name.

If name is in the mapping, remove it and return its value, else return default. If default is not given and name is not in the mapping, a KeyError is raised..

Parameters:
name : str

The name of the attribute to remove.

default : str

A default value to return.

Returns:

Any – The value associated with the name.

Raises:

KeyError – If the name is not found.

popitem() tuple[str, EnvValue | evar[EnvValue]][source]

Removes and returns a name-value pair from the mapping.

Returns:

tuple[str, Any] – A name-value pair from the mapping.

Raises:

KeyError – If the mapping is empty.

setdefault(name: str, default: EnvValue | evar[EnvValue] = Unset) EnvValue | evar[EnvValue][source]

Sets the value associated with a name.

If name is defined in the mapping, return its value. If not, defined it with a value of default and return default. default defaults to None.

Parameters:
name : str

The name of the attribute to set.

default : Any, optional

The default value to set if name is not found.

Returns:

Any – The value associated with name.

static env_hook(env: dict[str, EnvValue | evar[EnvValue]]) dict[str, EnvValue | evar[EnvValue]][source]

Called by the env property getter function.

Does nothing by default. Subclasses can override this method. This method is called by the env property getter function, just before beginning to return the environment variables. A working dictionary is passed to this method, so subclass can manipulate it before returning it.

Returns:

dict[str, EnvValue] – the altered mapping.

dump(file: IO[str] = sys.stdout) None[source]

Dump the environment variables to a file.

Parameters:
file : IO[str], optional

The file to write the environment

sys.stdout. : variables to. Defaults to