Python spec builder API reference
The public API of the spec builder gecode_iris.build, imported in the guide as ib. pdoc 16.0.0 generates it during each site build from the builder's type stubs and docstrings, and shows each typed overload of a statement. The guide shows the builder in use, and the package reference covers the specs and data it builds.
Build reader specs from Python code, with typed handles.
A SpecBuilder is the root scope of a spec. Each statement is a method
call, a block is a with statement, and every definition returns a handle
that later statements use in expressions and that data[handle] reads from
the data with the type it promises.
A handle's type parameter is the value data[handle] gives: int for an
integer, list[int] for an array or for an integer read in a repeat, and
int | None for an entry that may be absent. Scopes carry their depth in
their class, Scope0 to Scope3, and their presence in their parameter:
Required when their statements always execute and None when they may
not. Inside more than three repeats, ScopeN gives DynField handles.
Python operators build Iris expressions, except for division, remainder and
power, which are div(), rem() and pow(), and the logical
operators, which are &, | and ~. Line patterns are t-strings on
Python 3.14 and later, and tuples of text and parts on every version.
A mistake that a builder can find raises BuildError at the call that
made it, or from build(), and names the caller's file and line. Errors
while reading a built spec name the call site of their statement in
gecode_iris.Error.call_site.
Alphabet
alphabet "symbols": reads each symbol as its index. blank,
strip and base add options in call order.
Alphabet.blank
blank "characters".
Alphabet.strip
strip "characters".
Alphabet.base
base value.
ArmGuard
The guard of an arm: with gives the arm's block.
Arms
The block of a sections statement, which holds only arms: _R_co
is the scope of a required arm and _O_co of an optional one.
Arms.arm
An arm with this pattern; with gives it a block. What an optional
arm defines may be absent, and sections end after a last arm.
Block
The guard of a block statement: with gives the block's scope. A
guard that is never entered writes an empty block.
BuildError
Why a reader spec could not be built.
kind names the builder check that failed, or is "spec" when the
emitted text failed to parse; then error is the language error, which
is also the __cause__. str(error) shows the language code and
message, the line of emitted text, and the call site.
BuildError.kind
The check that failed: scope, provenance, redefinition,
unprintable, binding, or spec for a language error.
BuildError.message
The message of a builder check, without the call site. For a spec
error it is the language diagnostic, with its location and excerpt, less
the call site line.
BuildError.call_site
The host code of the statement that failed.
BuildError.text
The emitted text, when the language rejected it.
BuildError.error
The language error, when the emitted text was rejected.
BuildError.from_error
The error for emitted text that the language rejected.
BuildError.emitted_line
The line of emitted text that the language error points at.
BuildErrorKind
The value of BuildError.kind: the builder check that failed, or
spec when the language rejected the emitted text.
CallSite
A place in the host program: where a builder statement was called.
str(site) is file:line.
CallSite.filename
Alias for field number 0
CallSite.line
Alias for field number 1
CallSite.function
Alias for field number 2
Discard
The discard _: a target that reads without storing, and {_} in
a pattern.
DynExpr
An expression with no static type, which every operator accepts.
DynExpr.field
self.name, the field handle of the record this selects.
DynField
A handle whose value type or depth is open.
DynField.field
self.name, the field handle of the record this selects.
Eol
The end-of-line marker of a list.
Expr
An Iris expression. Operators build larger expressions; bool() is an
error, so that a comparison is never taken for a Python condition.
Expr.dynamic
This expression with no static type, accepted anywhere.
Field
A typed handle: the name of an entry. data[handle] reads its value,
of type _T_co.
In the builder a handle is an expression; after reading it is a key.
Field.name
The entry name.
FloatExpr
A float expression.
FloatField
A handle of a float entry.
FloatField.field
self.name, the field handle of the record this selects.
FloatLookup
A float lookup, which may be an array.
FloatLookup.field
self.name, the field handle of the record this selects.
FloatType
A type that reads floats.
FloatType.dim
Add a dimension: x[size]: type.
FloatType.dims
Add several dimensions, as many as known only at run time.
FloatType.layout
layout expression: a matrix layout name such as "LOWER_COL".
FloatType.offset
offset expression.
FloatType.until
A list of this type ending at end: a sentinel, or ib.eol.
IntExpr
An integer expression.
IntField
A handle of an integer entry.
IntField.field
self.name, the field handle of the record this selects.
IntLookup
An integer lookup, such as an index or a field: it may be an array.
IntLookup.field
self.name, the field handle of the record this selects.
IntType
A type that reads integers.
IntType.dim
Add a dimension: x[size]: type.
IntType.dims
Add several dimensions, as many as known only at run time.
IntType.layout
layout expression: a matrix layout name such as "LOWER_COL".
IntType.offset
offset expression.
IntType.until
A list of this type ending at end: a sentinel, or ib.eol.
ListReading
The type and end of a list statement; the parameter is the type.
ListReading.offset
offset expression, after the list's end.
Maybe
The presence of a scope whose statements may not execute.
NumExpr
A num expression: an int or a float, decided by the data.
NumField
A handle of a num entry.
NumField.field
self.name, the field handle of the record this selects.
NumLookup
A num lookup, which may be an array.
NumLookup.field
self.name, the field handle of the record this selects.
NumType
A type that reads ints or floats, decided by the data.
NumType.dim
Add a dimension: x[size]: type.
NumType.dims
Add several dimensions, as many as known only at run time.
NumType.layout
layout expression: a matrix layout name such as "LOWER_COL".
NumType.offset
offset expression.
NumType.until
A list of this type ending at end: a sentinel, or ib.eol.
Part
A part of a pattern other than text or a capture handle.
Record
The records of a repeat. record[field] is the field of the current
record, record.list all the records, and a comprehension over a record
gives its body one record at a time.
Record.list
All the records of this repeat, printed as its as name.
Record.records
The records of the nested repeat inner in the current record.
RecordExpr
One record: selected by index, or a comprehension's variable.
record[field] looks up one of its fields.
RecordExpr.at
self[index], for a record that is itself a list.
RecordExpr.records
The records of the nested repeat inner in this record.
RecordList
A list of records: all the records of a repeat, or a nested list.
records[i] selects one.
Required
The presence of a scope whose statements always execute: T | Required
is T.
Scope
An open block, with the statements whose types do not depend on its depth. A scope accepts statements only while it is the innermost open block.
Scope.set
let x = value through a handle, keeping its type.
The value must have the handle's value type and, where both are known,
its depth. To change either, use let with the handle as the target,
which returns a DynField.
Scope.check
check condition, with an optional message for when it fails.
Scope.expect
expect "text"....
Scope.line
line "pattern".
Scope.find
find "pattern".
Scope.skip_line
skip line.
Scope.skip_lines
skip count lines.
Scope.index
index position.
Scope.define_type
type name = type, usable wherever a type is. The type it returns
belongs to this declaration: build() reports a use where another
declaration of the name is visible.
Scope.forward
A handle for a name that a later statement defines, of the handle
type kind, such as ib.IntField[list[int]] or ib.DynField.
Scope.undefined
A handle for a name deliberately left undefined.
Scope.forward_record
The record of a repeat that comes later in the text, printed with
the names given here. Bind it with record_as.
Scope0
A scope outside every repeat. _N is Required when its
statements always execute and None when they may not.
Scope0.read
x: type, reading a value into target: a new name, a handle to
bind or redefine, or ib.discard().
Scope0.else_read_if
else if:type: the else branch is a declaration of the name if,
which the target must have.
Scope0.list
list x: type until end.
Scope0.let
let x = value.
Scope0.param
param p, whose type the caller decides, or param p = default.
Scope0.capture
A handle for a pattern to bind, at this scope's depth and presence.
Without a type the capture is {x}, which reads a word.
Scope0.optional_capture
capture for an optional arm or a conditional block.
Scope0.repeat
repeat count { ... }, whose block is the next depth.
Scope0.repeat_until_eof
repeat until eof { ... }.
Scope0.repeat_until
repeat until "text"... { ... }. store keeps the terminator
that ended it in a name; to read it, pass a handle from forward.
Scope0.sections
sections: entering it gives the block of arms. until and
skip_other add clauses in that order; chain .until() and
.skip_other() for any other order.
Scope0.if_
if condition { ... }. What its block defines may be absent.
Scope0.else_if
else if condition { ... }, directly after an if_ block.
Scope0.else_
Scope1
A scope inside one repeat: its definitions are lists.
Scope1.read
x: type, reading a value into target: a new name, a handle to
bind or redefine, or ib.discard().
Scope1.else_read_if
else if:type: the else branch is a declaration of the name if,
which the target must have.
Scope1.list
list x: type until end.
Scope1.let
let x = value.
Scope1.param
param p, whose type the caller decides, or param p = default.
Scope1.capture
A handle for a pattern to bind, at this scope's depth and presence.
Without a type the capture is {x}, which reads a word.
Scope1.optional_capture
capture for an optional arm or a conditional block.
Scope1.repeat
repeat count { ... }, whose block is the next depth.
Scope1.repeat_until_eof
repeat until eof { ... }.
Scope1.repeat_until
repeat until "text"... { ... }. store keeps the terminator
that ended it in a name; to read it, pass a handle from forward.
Scope1.sections
sections: entering it gives the block of arms. until and
skip_other add clauses in that order; chain .until() and
.skip_other() for any other order.
Scope1.if_
if condition { ... }. What its block defines may be absent.
Scope1.else_if
else if condition { ... }, directly after an if_ block.
Scope1.else_
Scope1.record
The record of the nearest repeat.
Scope1.each_name
Print this repeat's each name as name, which may be _.
Scope1.as_name
Print this repeat's as name as name, which may be _.
Scope1.record_as
Bind this repeat to a record from forward_record.
Scope2
A scope inside two repeats.
Scope2.read
x: type, reading a value into target: a new name, a handle to
bind or redefine, or ib.discard().
Scope2.else_read_if
else if:type: the else branch is a declaration of the name if,
which the target must have.
Scope2.list
list x: type until end.
Scope2.let
let x = value.
Scope2.param
param p, whose type the caller decides, or param p = default.
Scope2.capture
A handle for a pattern to bind, at this scope's depth and presence.
Without a type the capture is {x}, which reads a word.
Scope2.optional_capture
capture for an optional arm or a conditional block.
Scope2.repeat
repeat count { ... }, whose block is the next depth.
Scope2.repeat_until_eof
repeat until eof { ... }.
Scope2.repeat_until
repeat until "text"... { ... }. store keeps the terminator
that ended it in a name; to read it, pass a handle from forward.
Scope2.sections
sections: entering it gives the block of arms. until and
skip_other add clauses in that order; chain .until() and
.skip_other() for any other order.
Scope2.if_
if condition { ... }. What its block defines may be absent.
Scope2.else_if
else if condition { ... }, directly after an if_ block.
Scope2.else_
Scope2.record
The record of the nearest repeat.
Scope2.each_name
Print this repeat's each name as name, which may be _.
Scope2.as_name
Print this repeat's as name as name, which may be _.
Scope2.record_as
Bind this repeat to a record from forward_record.
Scope3
A scope inside three repeats, the deepest with typed handles.
Scope3.read
x: type, reading a value into target: a new name, a handle to
bind or redefine, or ib.discard().
Scope3.else_read_if
else if:type: the else branch is a declaration of the name if,
which the target must have.
Scope3.list
list x: type until end.
Scope3.let
let x = value.
Scope3.param
param p, whose type the caller decides, or param p = default.
Scope3.capture
A handle for a pattern to bind, at this scope's depth and presence.
Without a type the capture is {x}, which reads a word.
Scope3.optional_capture
capture for an optional arm or a conditional block.
Scope3.repeat
repeat count { ... }, whose block is the next depth.
Scope3.repeat_until_eof
repeat until eof { ... }.
Scope3.repeat_until
repeat until "text"... { ... }. store keeps the terminator
that ended it in a name; to read it, pass a handle from forward.
Scope3.sections
sections: entering it gives the block of arms. until and
skip_other add clauses in that order; chain .until() and
.skip_other() for any other order.
Scope3.if_
if condition { ... }. What its block defines may be absent.
Scope3.else_if
else if condition { ... }, directly after an if_ block.
Scope3.else_
Scope3.record
The record of the nearest repeat.
Scope3.each_name
Print this repeat's each name as name, which may be _.
Scope3.as_name
Print this repeat's as name as name, which may be _.
Scope3.record_as
Bind this repeat to a record from forward_record.
ScopeN
A scope inside more repeats than handles can type: its definitions
give DynField, and dimensions still nest.
ScopeN.read
x: type, reading a value into target: a new name, a handle to
bind or redefine, or ib.discard().
ScopeN.else_read_if
else if:type: the else branch is a declaration of the name if,
which the target must have.
ScopeN.list
list x: type until end.
ScopeN.let
let x = value.
ScopeN.param
param p, whose type the caller decides, or param p = default.
ScopeN.capture
A handle for a pattern to bind, at this scope's depth and presence.
Without a type the capture is {x}, which reads a word.
ScopeN.optional_capture
capture for an optional arm or a conditional block.
ScopeN.repeat
repeat count { ... }, whose block is the next depth.
ScopeN.repeat_until_eof
repeat until eof { ... }.
ScopeN.repeat_until
repeat until "text"... { ... }. store keeps the terminator
that ended it in a name; to read it, pass a handle from forward.
ScopeN.sections
sections: entering it gives the block of arms. until and
skip_other add clauses in that order; chain .until() and
.skip_other() for any other order.
ScopeN.if_
if condition { ... }. What its block defines may be absent.
ScopeN.else_if
else if condition { ... }, directly after an if_ block.
ScopeN.else_
ScopeN.record
The record of the nearest repeat.
ScopeN.each_name
Print this repeat's each name as name, which may be _.
ScopeN.as_name
Print this repeat's as name as name, which may be _.
ScopeN.record_as
Bind this repeat to a record from forward_record.
SectionsGuard
The guard of sections: clauses chain, and with gives the arms.
SectionsGuard.until
until "text"..., with store x keeping the terminator; to read
it, pass a handle from forward.
SectionsGuard.skip_other
skip other.
SpecBuilder
Builds a reader spec. It is the root scope, with the settings and statements that only the top level allows.
SpecBuilder.format
format name, a name of this format.
SpecBuilder.comment
comment "text"....
SpecBuilder.stop
stop "text"....
SpecBuilder.tokens
tokens "characters".
SpecBuilder.separators
separators "characters".
SpecBuilder.ignore_trailing
ignore trailing.
SpecBuilder.instances
instances { ... }.
SpecBuilder.source
The text this builder emits, without parsing it.
SpecBuilder.build
Print the text and parse it. The spec is an ordinary one, whose errors while reading name the call site of their statement.
StrExpr
A string expression.
StrField
A handle of a string entry.
StrField.field
self.name, the field handle of the record this selects.
StrLookup
A string lookup, which may be an array.
StrLookup.field
self.name, the field handle of the record this selects.
StrType
A type that reads strings.
StrType.dim
Add a dimension: x[size]: type.
StrType.dims
Add several dimensions, as many as known only at run time.
StrType.layout
layout expression: a matrix layout name such as "LOWER_COL".
StrType.offset
offset expression.
StrType.until
A list of this type ending at end: a sentinel, or ib.eol.
Type
A reading type, whose parameter is the value it reads, with a list for each dimension.
all
all(x in domain: body).
alphabet
alphabet "symbols", with the options given, in this order.
any
any(x in domain: body).
at_least
lo.., the integers from lo up.
bind
{x:type}, binding a forward or redefined handle; without a type,
{x}, which reads a word.
blank
{}, which matches a word without storing it.
count
count(domain), or count(x in domain: body) given a function.
declared
A handle for the entry name of a text spec, of the handle type
kind, such as ib.IntField[list[int]] or ib.DynField.
iris gen --lang python SPEC prints one per entry. The handle reads data
as a builder's handle does, but no builder accepts it, since it comes from
none.
defined
defined(name): a handle, record, record list or comprehension
variable. defined(record) tests the record list.
discard
_: read a value without storing it, or {_} in a pattern.
discard_as
{_:type}, a discarded capture with a type.
distinct
distinct(a, b, ...).
div
left / right, Iris integer division.
eol
until eol: a list that ends with its line.
float_
float.
int_
int.
int_range
lo..hi, both included, or lo..<below. Either end may be left
out, but not both.
lit
An Iris literal: an int in the 64-bit range, a float or a str.
max
max(a, b, ...).
min
min(a, b, ...).
num
num: an int or a float, decided by the data.
over
domain, with its comprehension variable printed as name.
pow
base ^ exponent.
ref
{$x}, matching the current value of x.
rem
left % right, the Iris remainder.
rest
rest: the rest of the line.
rest_of_line
The trailing ... of a pattern.
size
size(domain).
sum
sum(a, b, ...), or sum(x in domain: body) given a domain and a
function of its variable.
track_caller
Make a helper function report its caller's line as the call site of the statements it writes, as builder methods do.
validate
{:type}, which checks the text without storing it.
word
word: one token.
gecode
Gecode's host constants, for ranges and checks.
gecode.INT_MAX
gecode.int_max, 2147483646.
gecode.INT_MIN
gecode.int_min, -2147483646.