Config package#

Submodules#

Base Configuration module#

class ablator.config.main.ConfigBase(*args, **kwargs)[source]#

Bases: object

Base class for configuration objects.

First, it checks if there are any unannotated variables inside the child config class. If there are, it will raise an assert error.

Parameters:
*argsAny

Positional arguments.

**kwargsAny

Keyword arguments.

Raises:
ValueError

If positional arguments are provided.

KeyError

If unexpected arguments are provided.

Notes

All config class must be decorated with @configclass

Attributes:
config_classType

The class of the configuration object.

__init__(*args, **kwargs)[source]#
property annotations: dict[str, ablator.config.types.Annotation]#

Get the parsed annotations of the configuration object.

Returns:
dict[str, Annotation]

A dictionary of parsed annotations.

assert_state(config: ConfigBase) bool[source]#

Assert that the configuration object has a valid state.

Parameters:
configConfigBase

The configuration object to compare.

Returns:
bool

True if the configuration object has a valid state, False otherwise.

assert_unambigious()[source]#

Assert that the configuration object is unambiguous and has all the required values.

Raises:
AssertionError

If the configuration object is ambiguous or missing required values.

diff(config: ConfigBase, ignore_stateless=False) list[tuple[str, tuple[type, Any], tuple[type, Any]]][source]#

Get the differences between the current configuration object and another configuration object.

Parameters:
configConfigBase

The configuration object to compare.

ignore_statelessbool, optional, default=False

Whether to ignore stateless values.

Returns:
list[tuple[str, tuple[type, Any], tuple[type, Any]]]

The list of differences as tuples.

Examples

Let’s say we have two configuration objects config1 and config2 with the following attributes:

>>> config1:
    learning_rate: 0.01
    optimizer: 'Adam'
    num_layers: 3
>>> config2:
    learning_rate: 0.02
    optimizer: 'SGD'
    num_layers: 3

The diff between these two configurations would look like:

>>> config1.diff(config2)
[('learning_rate', (float, 0.01), (float, 0.02)), ('optimizer', (str, 'Adam'), (str, 'SGD'))]

In this example, the learning_rate and optimizer values are different between the two configuration objects.

diff_str(config: ConfigBase, ignore_stateless=False)[source]#

Get the differences between the current configuration object and another configuration object as strings.

Parameters:
configConfigBase

The configuration object to compare.

ignore_statelessbool, optional, default=False

Whether to ignore stateless values.

Returns:
list[str]

The list of differences as strings.

get_annot_type_with_dot_path(dot_path: str)[source]#

Get the type of a configuration object annotation using dot notation.

Parameters:
dot_pathstr

The dot notation path to the annotation.

Returns:
Type

The type of the annotation.

get_type_with_dot_path(dot_path: str)[source]#

Get the type of a configuration object attribute using dot notation.

Parameters:
dot_pathstr

The dot notation path to the attribute.

Returns:
Type

The type of the attribute.

get_val_with_dot_path(dot_path: str)[source]#

Get the value of a configuration object attribute using dot notation.

Parameters:
dot_pathstr

The dot notation path to the attribute.

Returns:
Any

The value of the attribute.

keys()[source]#

Get the keys of the configuration dictionary.

Returns:
KeysView[str]

The keys of the configuration dictionary.

classmethod load(path: Path | str)[source]#

Load a configuration object from a file.

Parameters:
pathUnion[Path, str]

The path to the configuration file.

Returns:
ConfigBase

The loaded configuration object.

make_dict(annotations: dict[str, ablator.config.types.Annotation], ignore_stateless=False, flatten=False)[source]#

Create a dictionary representation of the configuration object.

Parameters:
annotationsdict[str, Annotation]

A dictionary of annotations.

ignore_statelessbool, optional, default=False

Whether to ignore stateless values.

flattenbool, optional, default=False

Whether to flatten nested dictionaries.

Returns:
dict

The dictionary representation of the configuration object.

merge(config: ConfigBase) ty.Self[source]#

Merge the current configuration object with another configuration object.

Parameters:
configConfigBase

The configuration object to merge.

Returns:
ty.Self

The merged configuration object.

to_dict(ignore_stateless=False)[source]#

Convert the configuration object to a dictionary.

Parameters:
ignore_statelessbool, optional, default=False

Whether to ignore stateless values.

Returns:
dict

The dictionary representation of the configuration object.

to_dot_path(ignore_stateless=False)[source]#

Convert the configuration object to a dictionary with dot notation paths as keys.

Parameters:
ignore_statelessbool, optional, default=False

Whether to ignore stateless values.

Returns:
str

The YAML representation of the configuration object in dot notation paths.

to_str()[source]#

Convert the configuration object to a string.

Returns:
str

The string representation of the configuration object.

to_yaml()[source]#

Convert the configuration object to YAML format.

Returns:
str

The YAML representation of the configuration object.

property uid#

Get the unique identifier for the configuration object.

Returns:
str

The unique identifier for the configuration object.

write(path: Path | str)[source]#

Write the configuration object to a file.

Parameters:
pathUnion[Path, str]

The path to the file.

class ablator.config.main.Missing[source]#

Bases: object

This type is defined only for raising an error

ablator.config.main.configclass(cls)[source]#

Decorator for ConfigBase subclasses, adds the config_class attribute to the class.

Parameters:
clsType[ConfigBase]

The class to be decorated.

Returns:
Type[ConfigBase]

The decorated class with the config_class attribute.

Configuration Types module#

class ablator.config.types.Annotation(state, optional, collection, variable_type)#

Bases: tuple

collection#

Alias for field number 2

optional#

Alias for field number 1

state#

Alias for field number 0

variable_type#

Alias for field number 3

class ablator.config.types.Derived[source]#

Bases: Generic[T]

This type is for attributes are derived during the experiment.

class ablator.config.types.Dict[source]#

Bases: Dict[str, T]

class ablator.config.types.Enum(value)[source]#

Bases: Enum

A custom Enum class that provides additional equality and hashing methods.

Examples

>>> from enum import Enum as _Enum
>>> class Color(Enum):
...     RED = 1
...     GREEN = 2
...     BLUE = 3
...
>>> Color.RED == Color.RED
True
>>> Color.RED == 1
True
>>> hash(Color.RED) == hash(Color.RED)
True

Methods

__eq__(self, __o: object) -> bool:

Checks for equality between the Enum instance and another object.

__hash__(self) -> int:

Calculates the hash of the Enum instance.

class ablator.config.types.List(iterable=(), /)[source]#

Bases: List[T]

class ablator.config.types.Optional[source]#

Bases: Generic[T]

class ablator.config.types.Stateful[source]#

Bases: Generic[T]

This is for attributes that are fixed between experiments. By default all type_hints are stateful. Do not need to use.

class ablator.config.types.Stateless[source]#

Bases: Generic[T]

This type is for attributes that can take different value assignments between experiments

class ablator.config.types.Tuple(iterable=(), /)[source]#

Bases: Tuple[T]

ablator.config.types.get_annotation_state(annotation)[source]#

Get state of an annotation

Parameters:
annotation

type annotation

Returns:
Stateful, Derived, Stateless, or None
(Stateful is the default)
ablator.config.types.parse_type_hint(type_hint)[source]#

Parses a type hint and returns a parsed annotation.

Parameters:
type_hintType

The input type hint to parse.

Returns:
Annotation

A namedtuple containing state, optional, collection, and variable_type information.

Examples

>>> parse_type_hint(Optional[List[int]])
Annotation(state=Stateful, optional=True, collection=List, variable_type=int)
ablator.config.types.parse_value(val, annot: Annotation, name=None)[source]#

Parses a value based on the given annotation.

Parameters:
valAny

The input value to parse.

annotAnnotation

The annotation namedtuple to guide the parsing.

namestr, optional

The name of the value, by default None.

Returns:
Any

The parsed value.

Raises:
RuntimeError

If the required value is missing and it is not optional or derived or stateless.

ValueError

If the value type in dict is not valid If the value of a list is no valid

Examples

>>> annotation = parse_type_hint(Optional[List[int]])
>>> parse_value([1, 2, 3], annotation)
[1, 2, 3]

Configuration Utils module#

ablator.config.utils.dict_hash(*dictionaries: list[dict[str, Any]], hash_len=4)[source]#

Calculates the MD5 hash of one or more dictionaries.

Parameters:
*dictionarieslist[dict[str, ty.Any]]

One or more dictionaries to calculate the hash for.

hash_lenint, optional

The length of the hash to return, by default 4.

Returns:
str

The MD5 hash of the dictionaries.

Examples

>>> dict1 = {"a": 1, "b": 2}
>>> dict2 = {"c": 3, "d": 4}
>>> dict_hash(dict1, dict2)
'6d75e6'
ablator.config.utils.flatten_nested_dict(_dict: dict, expand_list=True, seperator='.') dict[str, Any][source]#

Flattens a nested dictionary, expanding lists and tuples if specified.

Parameters:
_dictdict

The input dictionary to be flattened.

expand_listbool, optional

Whether to expand lists and tuples in the dictionary, by default True.

seperatorstr, optional

The separator used for joining the keys, by default ".".

Returns:
dict[str, ty.Any]

The flattened dictionary.

Examples

>>> nested_dict = {"a": {"b": 1, "c": {"d": 2}}, "e": [3, 4]}
>>> flatten_nested_dict(nested_dict)
{'a.b': 1, 'a.c.d': 2, 'e.0': 3, 'e.1': 4}

Module contents#