Skip to content

odys.optimization.constraints.constraints_group

Internal implementation detail. Most users do not need this page directly.

See Risk (CVaR) in the User Guide for the public API.

Constraint group base class with auto-registration of constraint methods.

ConstraintGroup

Base class for grouping related model constraints.

Subclasses decorate constraint-producing methods with @constraint. These are collected at class definition time via init_subclass and invoked automatically by collect_constraints() / add_to_model().

Source code in src/odys/optimization/constraints/constraints_group.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class ConstraintGroup:
    """Base class for grouping related model constraints.

    Subclasses decorate constraint-producing methods with @constraint.
    These are collected at class definition time via __init_subclass__
    and invoked automatically by collect_constraints() / add_to_model().
    """

    _constraint_methods: ClassVar[tuple[str, ...]] = ()

    def __init_subclass__(cls, **kwargs: Any) -> None:  # noqa: ANN401
        """Register @constraint-decorated methods defined on this subclass."""
        super().__init_subclass__(**kwargs)
        cls._constraint_methods = tuple(
            name for name, attr in cls.__dict__.items() if isinstance(attr, Hashable) and attr in _constraint_registry
        )

    def collect_constraints(self) -> list[ModelConstraint]:
        """Collect all @constraint-decorated methods. Preserves definition order."""
        results: list[ModelConstraint] = []
        for name in self._constraint_methods:
            result = getattr(self, name)()
            if isinstance(result, list):
                results.extend(result)
            else:
                results.append(result)
        return results

    def add_to_model(self, linopy_model: linopy.Model) -> None:
        """Collect all constraints and add them to the linopy model."""
        for c in self.collect_constraints():
            linopy_model.add_constraints(c.constraint, name=c.name)

__init_subclass__(**kwargs)

Register @constraint-decorated methods defined on this subclass.

Source code in src/odys/optimization/constraints/constraints_group.py
31
32
33
34
35
36
def __init_subclass__(cls, **kwargs: Any) -> None:  # noqa: ANN401
    """Register @constraint-decorated methods defined on this subclass."""
    super().__init_subclass__(**kwargs)
    cls._constraint_methods = tuple(
        name for name, attr in cls.__dict__.items() if isinstance(attr, Hashable) and attr in _constraint_registry
    )

add_to_model(linopy_model)

Collect all constraints and add them to the linopy model.

Source code in src/odys/optimization/constraints/constraints_group.py
49
50
51
52
def add_to_model(self, linopy_model: linopy.Model) -> None:
    """Collect all constraints and add them to the linopy model."""
    for c in self.collect_constraints():
        linopy_model.add_constraints(c.constraint, name=c.name)

collect_constraints()

Collect all @constraint-decorated methods. Preserves definition order.

Source code in src/odys/optimization/constraints/constraints_group.py
38
39
40
41
42
43
44
45
46
47
def collect_constraints(self) -> list[ModelConstraint]:
    """Collect all @constraint-decorated methods. Preserves definition order."""
    results: list[ModelConstraint] = []
    for name in self._constraint_methods:
        result = getattr(self, name)()
        if isinstance(result, list):
            results.extend(result)
        else:
            results.append(result)
    return results

constraint(fn)

Mark a method as a constraint producer. Discovered automatically by ConstraintGroup.

Source code in src/odys/optimization/constraints/constraints_group.py
13
14
15
16
17
18
def constraint(
    fn: Callable[..., ModelConstraint | list[ModelConstraint]],
) -> Callable[..., ModelConstraint | list[ModelConstraint]]:
    """Mark a method as a constraint producer. Discovered automatically by ConstraintGroup."""
    _constraint_registry[fn] = True
    return fn