cfx.types.config_field

Base descriptor class for self-documenting configuration fields.

This module defines ConfigField, which implements the Python descriptor protocol to provide validated, documented configuration fields that live directly on Config class definitions. Subclass ConfigField and override ConfigField.validate to add type or value constraints.

Classes

ConfigField

Base descriptor for a single configuration field.

Module Contents

class cfx.types.config_field.ConfigField(default_value, doc, static=False, env=None, transient=None)[source]

Bases: Generic[T]

Base descriptor for a single configuration field.

Implements __get__, __set__, and __set_name__ so that instances assigned as class attributes behave as managed, validated attributes on Config subclasses.

The default value may be a plain object or a callable that accepts the owning instance as its sole argument (a lazy factory). When a lazy factory is provided, the computed value is returned on every access until the user explicitly sets the attribute, after which the stored value is used instead.

Parameters:
default_valueobject or callable

Default value for the field. If callable, it is treated as a lazy factory: default_value(instance) is called on each __get__ invocation until an explicit value is stored on the instance.

docstr

Human-readable description shown in __str__ tables and Jupyter _repr_html_ output.

staticbool, optional

If True the value is frozen to default_value at class-definition time and cannot be changed on instances. Any attempted __set__ raises AttributeError. Default is False.

envstr or None, optional

Name of an environment variable to consult when no explicit value has been stored on the instance. When set, the priority chain is: explicit assignment > environment variable > default. The raw string from os.environ is coerced by _from_env_str and then validated. The env value is not stored on the instance - it is re-read on every access, matching the behaviour of callable defaults. None means no environment variable is consulted. Default is None.

Raises:
TypeError

If default_value (when not callable) fails validate.

ValueError

If default_value (when not callable) fails validate.

Examples

>>> from cfx import Config
>>> from cfx.types import ConfigField
>>> class MyConfig(Config):
...     name = ConfigField("default", "A simple untyped field")
>>> cfg = MyConfig()
>>> cfg.name
'default'
>>> cfg.name = "something else"
>>> cfg.name
'something else'
doc
static = False
env = None
property transient

True when the field is skipped on serialization if no value stored.

normalize(value)[source]

Transform value to canonical form before validation and storage.

Called before validate in both __init__ (for non-callable defaults) and __set__. Must be idempotent: applying normalize twice yields the same result as applying it once.

Override in subclasses to coerce common input types to the field’s canonical type. Examples: str -> pathlib.Path, list -> tuple, angular wrap-around to [0, 360).

The default implementation returns the value unchanged.

Parameters:
valueobject

The raw value to normalize.

Returns:
object

The normalized value, ready to pass to validate.

validate(value)[source]

Validate a value against this field’s constraints.

Called after normalize. Override in subclasses to enforce correct type or range of values. Raise TypeError for wrong type, and ValueError for out-of-range error. The base implementation accepts any value.

Parameters:
valueobject

The normalized value to validate.

Raises:
TypeError

If the value has the wrong type.

ValueError

If the value is outside the allowed range or set.

from_string(s)[source]

Parse a raw string into this field’s type.

Override in subclasses to coerce the raw string to the appropriate type for a particular ConfigField. The default implementation returns the unchanged string.

Called by __get__ when env is set and the variable is present in the environment but the instance has no explicitly stored value, and by the CLI integration as the argparse type= callable. The result is then passed to validate.

Parameters:
sstr

Raw string value.

Returns:
valueobject

The coerced value, ready to pass to validate.

to_string(value)[source]

Format a field value as a human-readable string for display.

Called by the display layer when rendering the config table. Override in subclasses to produce cleaner output than Python’s default str(). The default implementation returns str(value).

Parameters:
valueobject

The current field value.

Returns:
sstr

Display string for the value.

serialize(value)[source]

Serialize value to a JSON/YAML-safe form for to_dict().

Override in subclasses for types that need a different on-disk representation (e.g. pathlib.Path -> str, set -> sorted list, datetime.time -> ISO string). The default returns the value unchanged.

Parameters:
valueobject

The current field value (already normalized/canonical).

Returns:
object

A JSON/YAML-safe value.

deserialize(value)[source]

Deserialize a value from dict form back to the field’s type.

Logical inverse of serialize. Called by from_dict() before setattr; the result is then passed through normalize and validate via __set__. The default returns the value unchanged.

Parameters:
valueobject

The value from the dict.

Returns:
object

The deserialized value, ready to be set on the instance.

is_set(obj)[source]

Return True if an explicit value is stored on obj.

Returns False when the field is still using its default, env var, or callable factory.

Parameters:
objConfig

Instance to check.

unset(obj)[source]

Remove the stored value, reverting to default/env/callable.

After calling this, __get__ will re-evaluate the default, environment variable, or callable factory on the next access.

Parameters:
objConfig

Instance to modify.

reset(obj, value=None)[source]

Reset to default or set a new value with full normalize/validate.

If value is None, equivalent to unset. Otherwise, sets a new value going through the full normalize -> validate pipeline.

Parameters:
objConfig

Instance to modify.

valueobject, optional

New value. If None, reverts to default.

to_argparse_kwargs(name, prefix='')[source]

Return kwargs dict for parser.add_argument().

The returned dict always contains a "flag" key with the full option string (e.g. "--search.n-sigma"). Pull it out before calling argparse:

kwargs = descriptor.to_argparse_kwargs(name, prefix)
flag = kwargs.pop("flag")
parser.add_argument(flag, **kwargs)

Override in subclasses to customize the argparse representation (add "choices", "nargs", "action", "metavar").

Parameters:
namestr

Field attribute name.

prefixstr, optional

Dot-separated prefix for nested configs (e.g. "search").

Returns:
dict
to_click_option(name, prefix='')[source]

Return a click.option() decorator for this field.

Override in subclasses to customize the click representation.

Parameters:
namestr

Field attribute name.

prefixstr, optional

Dot-separated prefix for nested configs.

Returns:
decorator

A click.option(...) decorator ready to stack on a command.

Raises:
ImportError

If click is not installed.

__repr__()[source]
__str__()[source]
__set_name__(owner, name)[source]

Record the attribute name assigned by the owning class.

Called automatically by the metaclass machinery when the descriptor is assigned as a class attribute. Sets public_name (the name as written in the class body) and private_name (the name used to store the per-instance value in instance.__dict__).

Parameters:
ownertype

The class that owns this descriptor.

namestr

The attribute name under which this descriptor was assigned.

__get__(obj, objtype)[source]
__get__(obj: object, objtype: type) T

Return the field value for the owning instance.

If accessed on the class (obj is None) returns a FieldRef path proxy, enabling IDE-refactorable paths for use in Alias and Mirror declarations.

For static fields, always returns defaultval.

For non-static fields with no explicitly stored value, the lookup order is:

  • explicit assignment (stored on the instance)

  • environment variable, when env is set and the variable is present in os.environ

  • defaultval, called if callable, returned directly otherwise

Parameters:
objConfig or None

The owning instance, or None when accessed on the class.

objtypetype, optional

The owning class.

Returns:
valueobject

The field value, or a FieldRef path proxy when obj is None.

__set__(obj, value)[source]

Set the field value on the owning instance.

Full pipeline: normalize -> validate -> store.

Parameters:
objConfig

The owning instance.

valueobject

The new value. Passed through normalize then validate before being stored.

Raises:
AttributeError

If the field is declared static=True.

TypeError

If the value fails validate.

ValueError

If the value fails validate.