On this page
Spellbook config defined๏
๐ก Intermediate ยท Lesson 31
SpellbookConfiguration DEFINED - the core settings you can set, what each one means, and the four laws that guard them. This is the book's policy object: it decides teardown and how hard the conjure pipeline works. Nothing here is exotic - explicit values, four rules.
THE CORE SETTINGS disposal (bool) Stored configuration metadata; matched method names drive disposal calls. disposal_method_names (list[str]) The teardown VOCABULARY - the method names that mean "clean yourself up" in this system. Cleanup calls whichever of them each object actually has (beginner 08 showed it firing). enforce_priority_disposal_methods (bool, default False) Place the matching book block last (False) or first (True). Shared names always keep the book's order; spell-only names keep their own order. Set this before binding. phase_scheduler_workers_per_spellbook (int) How many worker threads run the conjure pipeline. Conjure compiles and validates every spell in phases - more workers means more of that in parallel. phase_scheduler_barrier_timeout_milliseconds (int) How long a phase barrier waits for a straggler before refusing loudly. This is the anti-hang knob: a broken spell fails your startup with an error, never a frozen process.
THE FOUR LAWS 1) CLOSED REGISTRY - an unknown key refuses. No typo silently becomes a setting. 2) IDEMPOTENT PAIR - the two disposal items are set-ONCE. A world's teardown story must not change mid-flight. 3) FREEZE - conjure validates and freezes the whole object. Configuration is a pre-flight surface, period. 4) COMPLETION - hand a book YOUR configuration and you own completing it. with_defaults() is easy mode; a bare config refuses at conjure-time validation.
Before you run๏
Use the Intermediate guide for prerequisite concepts. Run from a checkout with Melder installed and Python 3.14 free-threading selected. The collection download includes the level's local helper modules.
Run the saved script๏
python UX_and_AIX_experiences/02_intermediate/31_spellbook_config_defined.py
py -3.14t UX_and_AIX_experiences/02_intermediate/31_spellbook_config_defined.py
Public surface๏
core configuration settings, the four refusal laws
Code๏
1"""
2TIER: intermediate (31)
3GOAL: SpellbookConfiguration DEFINED - the core settings you can set,
4 what each one means, and the four laws that guard them. This is
5 the book's policy object: it decides teardown and how hard the
6 conjure pipeline works. Nothing here is exotic - explicit values,
7 four rules.
8
9 THE CORE SETTINGS
10 disposal (bool)
11 Stored configuration metadata; matched method names drive disposal calls.
12 disposal_method_names (list[str])
13 The teardown VOCABULARY - the method names that mean "clean
14 yourself up" in this system. Cleanup calls whichever of them
15 each object actually has (beginner 08 showed it firing).
16 enforce_priority_disposal_methods (bool, default False)
17 Place the matching book block last (False) or first (True).
18 Shared names always keep the book's order; spell-only names
19 keep their own order. Set this before binding.
20 phase_scheduler_workers_per_spellbook (int)
21 How many worker threads run the conjure pipeline. Conjure
22 compiles and validates every spell in phases - more workers
23 means more of that in parallel.
24 phase_scheduler_barrier_timeout_milliseconds (int)
25 How long a phase barrier waits for a straggler before
26 refusing loudly. This is the anti-hang knob: a broken spell
27 fails your startup with an error, never a frozen process.
28
29 THE FOUR LAWS
30 1) CLOSED REGISTRY - an unknown key refuses. No typo silently
31 becomes a setting.
32 2) IDEMPOTENT PAIR - the two disposal items are set-ONCE. A
33 world's teardown story must not change mid-flight.
34 3) FREEZE - conjure validates and freezes the whole object.
35 Configuration is a pre-flight surface, period.
36 4) COMPLETION - hand a book YOUR configuration and you own
37 completing it. with_defaults() is easy mode; a bare config
38 refuses at conjure-time validation.
39SURFACE EXERCISED: core configuration settings, the four refusal laws
40"""
41import melder as md
42
43
44class Service:
45 pass
46
47
48class BareService:
49 """LAW 4's book's own spell - Service already belongs to the first book."""
50
51
52def main() -> None:
53 # NOTE the absent with_defaults() call. This configuration states every
54 # value it needs, so asking for the standard set first would only fight
55 # it: defaults are COMPLETE, and the disposal pair is set-once, so a
56 # default set leaves nothing for you to override. with_defaults() is for
57 # when you want the standard policy and nothing else.
58 configuration = md.SpellbookConfiguration()
59 configuration.set_property("disposal", True)
60 configuration.set_property("disposal_method_names", ["close"])
61 configuration.set_property("phase_scheduler_workers_per_spellbook", 1)
62 configuration.set_property(
63 "phase_scheduler_barrier_timeout_milliseconds", 30000)
64
65 # LAW 1 - closed registry: typos refuse.
66 try:
67 configuration.set_property("phase_sceduler_workers", 4)
68 except Exception as err:
69 print("unknown key refused:", type(err).__name__)
70
71 # LAW 2 - the disposal pair is set-once.
72 try:
73 configuration.set_property("disposal", False)
74 except Exception as err:
75 print("idempotent re-set refused:", type(err).__name__)
76
77 book = md.Spellbook(configuration=configuration)
78 book.bind(spell=Service, existence="unique")
79 conduit = book.conjure() # LAW 3 happens here: validate + freeze
80 assert isinstance(conduit.meld("Service"), Service)
81
82 try:
83 configuration.set_property(
84 "phase_scheduler_barrier_timeout_milliseconds", 1)
85 except Exception as err:
86 print("post-freeze set refused:", type(err).__name__)
87
88 # LAW 4 - completion: a bare config you never finished refuses at
89 # the conjure gate, naming what is missing.
90 # It binds its own class: one class registers once (a spell_id is the
91 # SHA256 of its code), and Service is the first book's.
92 bare_book = md.Spellbook(configuration=md.SpellbookConfiguration())
93 bare_book.bind(spell=BareService, existence="unique")
94 try:
95 bare_book.conjure()
96 print("bare configuration unexpectedly conjured")
97 except Exception as err:
98 print("incomplete configuration refused at conjure:",
99 type(err).__name__)
100
101
102if __name__ == "__main__":
103 main()
Check the outcome๏
The script contains its own assertions or demonstrated refusal paths. Run it to evaluate those checks against your installed version. The code above is taken directly from the saved file; no run output is invented here.