designspace.Constraint#

class designspace.Constraint(expr: BoolExpr, hard: bool, origin: str, tags: frozenset[str], meta: MappingProxyType, params: frozenset[str])#

Bases: object

A restriction on which configurations are valid, as resolved IR.

All four constraint verbs and the bound sugar produce one of these; read kind to tell them apart, and feasible_when_satisfied rather than reasoning about hard and origin yourself.

expr#

The stored predicate. Note that this is the predicate as written: for a forbid it names the bad state, so satisfying it is not the same as being feasible. feasible_when_satisfied resolves it.

Type:

BoolExpr

hard#

Whether violating it makes a configuration infeasible. False for encourage and discourage, which annotate without restricting.

Type:

bool

origin#

Provenance: “user”, “bound”, “require”, or “discourage”. An implementation detail of how the constraint was spelled, and deliberately excluded from the fingerprint, so prefer kind.

Type:

str

tags#

Labels, used by Space.without_constraints().

Type:

frozenset[str]

meta#

Metadata. Never interpreted.

Type:

MappingProxyType[str, Any]

params#

Every parameter path expr reads. This is what Space.param_constraints() matches on, and what puts the constraint in the dependency graph.

Type:

frozenset[str]

property kind: str#

The builder verb that created this constraint, for display and dispatch: "forbid" | "require" | "encourage" | "discourage" | "bound" (the last is the implicit constraint an expression bound desugars to). Derived from (origin, hard) so consumers never re-derive polarity by hand.

property feasible_when_satisfied: bool#

Whether the stored expr is the desired predicate (satisfied is the good outcome) rather than a forbidden one (satisfied is the bad outcome). False only for forbid/discourage, the two verbs that name a bad state. This is the single source of truth for “is this constraint supposed to hold?”; ConstraintEval.violated reads it, so forbid/require/encourage/discourage all report consistently.