Skip to content

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:

Source: yidl-dataclass, 202b01c879eb, tests/data/goldens/materialized/dataclass_plain/generated_output_prettier_py312.py:1

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:

Source: yidl-lifecycle, ee5ba633efde, tests/data/goldens/materialized/yidl_transactional_phase_f_hooks/generated_output_prettier.py:482

        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.