On this page

Spell spaces, lineage, and scopes that end๏ƒ

Prerequisite: Beginner scopes. Keep the scope boundary explicit: a child conduit, a conduit lineage, and a spell space answer different questions about where instances are shared.

Lifetime

Scope demonstrated by the lessons

unique_per_conduit

A root and its child resolve different instances

unique_per_conduit_lineage

Root, child, and grandchild share one family instance

unique_per_spell_space

Reuse inside one spell space; separate instances across spaces

A job owns its child scope๏ƒ

Create a lesser conduit for a job, resolve the job's objects through it, and call the child's cleanup() when the job ends. The scoped-cleanup lesson compares the root and job sessions, ends the child, and resolves through the root again. The root has a longer lifetime and is cleaned up separately when the application ends.

The runtime retains the objects it manages. Dropping your last local variable does not end that ownership; cleanup and memory ownership explains why the explicit end of the scope matters.

A lesser conduit can grow into a named root๏ƒ

In a dynamic world, upgrade_to_normal(name=...) promotes the existing child. The promotion lesson asserts that a previously created per-conduit workbench is the same object afterward, then finds the promoted conduit through cloud lookup. Read dynamic mode before using this operation.

Clusters add a group-wide lifetime. The original cluster lesson remains in its saved Intermediate collection and is linked from that guide.

The workflow in code๏ƒ

These are the core steps from the saved example. Use its complete linked script for all class definitions and setup.

 1def main() -> None:
 2    book = md.Spellbook()
 3    book.bind(spell=JobSession, existence="unique_per_conduit",
 4              disposal_method_names=["close"])
 5    root = book.conjure()
 6
 7    # The long-lived scope holds its own session...
 8    root_session = root.meld(spell=JobSession)
 9
10    # ...and each job gets a THROWAWAY scope with its own.
11    job = root.create_lesser_conduit()
12    job_session = job.meld(spell=JobSession)
13    assert job_session is not root_session  # per-conduit = per-scope
14
15    # Job done: end the SCOPE, not the world.
16    job.cleanup()
17    print("job scope closed its session:", job_session.closed)
18    print("root session untouched:", root_session.closed is False)
19
20    # The root never noticed - it keeps resolving.
21    assert root.meld(spell=JobSession) is root_session
22    print("root still resolves after the child scope ended")
23
24    # And when the whole world is done, the same verb one level up.
25    root.cleanup()
26    print("root cleanup closed its session too:", root_session.closed)

Runnable examples๏ƒ

All intermediate examples ยท Level contents ยท Full contents

Canonical page source