Used in practice: qualified consumer excerpts¶
Optional reading after the standalone tutorial. These larger applications show how the same mechanisms are used in practice. You do not need to install or build these packages to complete the tutorial; use the example catalog for examples you can run in YIDL itself.
For using the current standalone libraries, start with Lifecycle installation and transactions or Cache installation and its consumer example. Those guides describe their own package boundaries; the excerpts below remain historical, revision-pinned evidence.
These are fixed-revision excerpts of consumer-authored resources, facts and canonical generated output. They are attributed to their owning repositories; this documentation does not select or change a license. The snapshots include source/excerpt hashes and links. Building this site needs no consumer checkout. They explain generic mechanisms alongside the runnable standalone tutorial.
Qualification boundary: Dataclass 202b01c and Undoable ca68b82 have accepted
local functional/package checkpoints and original SDK-wheel evidence. Separately
recorded Mac Python functional reruns passed 259 tests/3 skips and 350 tests,
respectively. Those source/workspace runs are not a new installed-package
qualification by this documentation task. Lifecycle ee5ba63 is the pre-annotation-
fix baseline; native core behavior passed in the separate operational run, while
Python had a known owned-field source-hygiene golden mismatch. This page does not
claim all consumer tests pass or live-type annotations work. Source links below
identify exact authority rather than mutable working-tree bytes.
Dataclass: facts to constructor parameters¶
Requirement: generate a direct-slot constructor with a required count and
captured defaults, keeping parameter order separate from field processing order.
The consumer harvester creates DataclassField facts containing FieldName,
AnnotationName, default/factory flags and ParamOrder:
Source: yidl-dataclass, 202b01c879eb, src/yidl_dataclass/dataclass.py:179
builder.add(
generated.FieldsCollection,
generated.DataclassField(
field_id=f"Model.{item.name}",
field_owner="Model",
field_name=item.name,
field_order=index,
annotation_name=item.annotation_name,
default_name=item.default_name,
factory_name=item.factory_name,
has_default=metadata.default is not std.MISSING,
has_factory=metadata.default_factory is not std.MISSING,
include_param=metadata.init,
param_order=item.parameter_order,
kw_only=metadata.kw_only,
install_default=install_default,
install_factory=install_factory,
),
)
A required field has IncludeParam true, KwOnly/HasDefault/HasFactory false, so
ParamContributions.required selects RequiredParamContribution. A defaulted field
selects the distinct defaulted rule. Annotation/default values are identifier
names of captures, not serialized live Python objects:
Source: yidl-dataclass, 202b01c879eb, src/yidl_dataclass/yidl/dataclass_core.yidl:260
matcher ParamContributions(field: Fields, cls: Classes) -> contribution {
rule required when IncludeParam == True and KwOnly == False and HasDefault == False and HasFactory == False -> RequiredParamContribution
rule defaulted when IncludeParam == True and KwOnly == False and HasDefault == True -> DefaultParamContribution
rule factory when IncludeParam == True and KwOnly == False and HasFactory == True -> FactoryParamContribution
rule required_kw when IncludeParam == True and KwOnly == True and HasDefault == False and HasFactory == False -> RequiredKwParamContribution
rule defaulted_kw when IncludeParam == True and KwOnly == True and HasDefault == True -> DefaultKwParamContribution
rule factory_kw when IncludeParam == True and KwOnly == True and HasFactory == True -> FactoryKwParamContribution
}
Source: yidl-dataclass, 202b01c879eb, src/yidl_dataclass/yidl/dataclass_core.yidl:88
resource EmptyParams = template $[
def astichi_params():
pass
]$
resource RequiredParam = template $[
def astichi_params(param_name__astichi_arg__: annotation_name__astichi_arg__):
pass
]$
resource DefaultParam = template $[
def astichi_params(param_name__astichi_arg__: annotation_name__astichi_arg__ = default_name__astichi_arg__):
pass
]$
resource InputStore = template $[
astichi_pass(self, outer_bind=True).astichi_ref(external=slot_name)._ = astichi_pass(param_name__astichi_arg__, outer_bind=True)
]$
Source: yidl-dataclass, 202b01c879eb, src/yidl_dataclass/yidl/dataclass_core.yidl:146
contribution RequiredParamContribution = RequiredParam {
as Parameter
index ParamOrder
order ParamOrder
target params { build /InitMethod }
ident param_name = FieldName
ident annotation_name = AnnotationName
}
contribution DefaultParamContribution = DefaultParam {
as Parameter
index ParamOrder
order ParamOrder
target params { build /InitMethod }
ident param_name = FieldName
ident annotation_name = AnnotationName
ident default_name = DefaultName
}
contribution InputStoreContribution = InputStore {
as Store
index FieldOrder
order FieldOrder
target stores { build /InitMethod }
ident param_name = FieldName
external slot_name = FieldName
}
The target is the nested /InitMethod parameter hole. ParamOrder sets parameter
order; FieldOrder independently sets store order. Here is actual CPython 3.12
canonical output and the author's behavior assertions:
class Inventory(*_y_dc_bases, metaclass=_y_dc_metaclass):
locals().update(_y_dc_namespace)
__slots__ = ("count", "label", "reserve")
def __init__(
self,
count: _y_dc_annotation_0,
label: _y_dc_annotation_1 = _y_dc_default_1,
reserve: _y_dc_annotation_2 = _y_dc_default_2,
) -> None:
pass
self.count = count
self.label = label
self.reserve = reserve
Source: yidl-dataclass, 202b01c879eb, tests/data/goldens/materialized/dataclass_plain/bindings.py:1
"""Canonical direct-storage and constructor contrast; no comparison/repr yet."""
from inspect import signature
from yidl_dataclass import dataclass, generated_source
def render_case():
@dataclass(eq=False, repr=False)
class Inventory:
count: int
label: str = "stock"
reserve: int = 2
assert Inventory.__slots__ == ("count", "label", "reserve")
first = Inventory(3)
second = Inventory(8, "custom", 5)
third = Inventory(count=0, reserve=9)
assert not hasattr(first, "__dict__")
first.count = 4
assert (first.count, first.label, first.reserve) == (4, "stock", 2)
assert (second.count, second.label, second.reserve) == (8, "custom", 5)
assert (third.count, third.label, third.reserve) == (0, "stock", 9)
class SharedSlot:
The same generic flow is explained without consumer metadata by the
two-owner tutorial. Dataclass's richer
factory/provider/policy semantics remain consumer-owned. Its fixed-revision
dataclass_field_removal fixture
contains before/after removal and retained-reference checks; its
comparison_neutral fixture
illustrates read specialization without Dataclass field metadata.
Undoable: select transactional access resources¶
Requirement: a managed field uses Undoable's history-aware read/write protocol. The normalized schema supplies a concrete field variant; build facts preserve FieldName and FieldOrder. A computed ManagedFields view filters FieldKind, then the default matcher selects the accessor contribution:
Source: yidl_undoable, ca68b8271841, src/yidl_undoable/undoable.py:25
def build_composable(schema, *, generation_module=generated):
generated = generation_module
builder = generated.new_builder()
aliases = capture_ids(schema.name)
builder.add(
generated.ClassesCollection,
generated.UndoableClass(
class_id=aliases[0],
class_name=schema.name,
current_class_name=schema.name + "_Current",
working_class_name=schema.name + "_Working",
restore_identity=schema.restore_identity,
restore_order=schema.restore_order,
),
)
for fact in schema.fields:
record = getattr(generated, RECORDS[fact["field_kind"]])
kwargs = {name: fact[name] for name in record.__slots__ if name in fact}
kwargs["is_lazy"] = fact["field_kind"] == "static"
builder.add(generated.FieldsCollection, record(**kwargs))
Source: yidl_undoable, ca68b8271841, src/yidl_undoable/yidl/undoable_managed.yidl:1
module undoable.managed
import "undoable_const_static.yidl" as previous
export concept UndoableManaged
concept UndoableManaged extends previous.UndoableConstStatic {
family previous.UndoableField {
variant ManagedField {}
}
computed collection ManagedFields: UndoableField from Fields where FieldKind == "managed"
resource ManagedFieldProperty = template $[
@property
def getter__astichi_arg__(self):
return self._u_read_managed(astichi_bind_external(field_name))
@setter_target__astichi_arg__.setter
def setter__astichi_arg__(self, value):
self._u_write_managed(astichi_bind_external(field_name), value)
]$
contribution ManagedFieldAccessor = ManagedFieldProperty {
index FieldOrder order FieldOrder target properties { build /ClassDef }
ident getter = FieldName ident setter_target = FieldName ident setter = FieldName
external field_name = FieldName
}
matcher ManagedFieldAccessors(field: ManagedFields) -> contribution { default -> ManagedFieldAccessor }
extend production ClassProduction {
phase properties_managed after properties_plain from field: ManagedFields { apply ManagedField_properties using ManagedFieldAccessors }
}
}
The contribution binds three public identifier spellings (getter, setter target, setter) and a literal field-name argument, orders by FieldOrder and targets the class properties surface. Actual generated output calls the consumer's protocol:
Source: yidl_undoable, ca68b8271841, tests/data/golden/02_transactions.generated.py:25
@property
def value(self):
return self._u_read_managed('value')
@value.setter
def value(self, value):
self._u_write_managed('value', value)
Source: yidl_undoable, ca68b8271841, tests/data/gold_src/02_transactions.py:1
import pytest
from yidl_undoable import *
@undoable
class Item:
value: int = managed(default=1)
sequence: tuple = managed(default=(1,), thaw=list, freeze=tuple)
plain: int = field(default=0)
h = UndoRedoManager()
a = Item(transaction_manager=h)
h.initialize(a)
with pytest.raises(TransactionRequiredError):
a.value = 2
with h.begin() as token:
assert h.active_transaction_for() is token
a.value = 2
a.plain = 7
assert a.value == a.working.value == 2 and a.current.value == 1
assert a.sequence == (1,)
working = a.working.sequence
assert working is a.working.sequence
working.append(2)
The generic mechanism is resource selection/binding/insertion. Undo history, transaction requirements and thaw/freeze policy belong to Undoable. This is a related object-model consumer, not independent evidence of unrelated-domain applicability.
Lifecycle: property paths from produced facts¶
Requirement: a default facade reads working storage when present and otherwise current storage. A generated analysis operation produces IndexedTransactionalField records with CurrentSlotName, WorkingSlotName and TxIndex. The selected matcher uses those records; the contribution binds identifier names and storage paths:
Source: yidl-lifecycle, ee5ba633efde, src/yidl_lifecycle/yidl/lifecycle_managed.yidl:1268
matcher ManagedDefaultFacadePropertyContributions(field: IndexedTransactionalFields) -> contribution {
default -> ManagedDefaultFacadeProperty
}
Source: yidl-lifecycle, ee5ba633efde, src/yidl_lifecycle/yidl/lifecycle_managed.yidl:761
}
contribution ManagedDefaultFacadeProperty = ManagedDefaultProperty {
as ManagedDefaultFacadeProperty
index FieldOrder
order FieldOrder
target default_facade_properties {
build /ClassDef
}
ident property_getter_name = FieldName
ident property_setter_target_name = FieldName
ident property_setter_name = FieldName
external current_slot = CurrentSlotName
external working_slot = WorkingSlotName
external tx_index = TxIndex
Source: yidl-lifecycle, ee5ba633efde, src/yidl_lifecycle/yidl/lifecycle_managed.yidl:241
resource ManagedDefaultProperty = template $[
@property
def property_getter_name__astichi_arg__(self):
state = self._y_state
if state.astichi_ref(external=working_slot) is not VOID:
return state.astichi_ref(external=working_slot)
return state.astichi_ref(external=current_slot)
@property_setter_target_name__astichi_arg__.setter
def property_setter_name__astichi_arg__(self, value):
state = self._y_state
state._y_require_active_transaction(astichi_bind_external(tx_index))
if state.astichi_ref(external=working_slot) is not VOID:
current = state.astichi_ref(external=working_slot)
else:
current = state.astichi_ref(external=current_slot)
next_value = value
with astichi_hole(compare_guard) as astichi_fallback:
if current == next_value:
return
state._y_ensure_working_transaction(astichi_bind_external(tx_index))
state.astichi_ref(external=working_slot)._ = next_value
]$ {
keep VOID
}
This is compiler resource source, including consumer-owned internal naming. Its actual output specializes the paths and transaction index:
def count(self):
state = self._y_state
if state._y_count_working is not VOID:
return state._y_count_working
return state._y_count_current
@count.setter
def count(self, value):
state = self._y_state
state._y_require_active_transaction(0)
if state._y_count_working is not VOID:
current = state._y_count_working
else:
current = state._y_count_current
next_value = value
if current == next_value:
return
state._y_ensure_working_transaction(0)
state._y_count_working = next_value
The full fixed-revision
phase_f_hooks canonical fixture
and
callable-fact resource
record the surrounding facts, captures, generated library and output. These
snippets are read-only explanatory evidence; the annotation fix in another task
is not incorporated. Generic DDS does not know what a transaction slot means.