On this page

Protocols as shapes๏ƒ

๐ŸŸข Beginner ยท Lesson 17

Protocols describe a SHAPE; bindings fill it - two implementations of one Protocol, chosen by binding name, called through the shared shape. Static duck typing meets dependency injection, gently.

Before you run๏ƒ

Use the Beginner 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/01_beginner/17_protocols_as_shapes.py
py -3.14t UX_and_AIX_experiences/01_beginner/17_protocols_as_shapes.py

Download this collection ยท Source on GitHub

Public surface๏ƒ

typing.Protocol + named bindings

Code๏ƒ

 1"""
 2TIER: beginner (17)
 3GOAL: Protocols describe a SHAPE; bindings fill it - two implementations
 4      of one Protocol, chosen by binding name, called through the shared
 5      shape. Static duck typing meets dependency injection, gently.
 6SURFACE EXERCISED: typing.Protocol + named bindings
 7"""
 8from typing import Protocol
 9
10import melder as md
11
12
13class Notifier(Protocol):
14    def send(self, message: str) -> str: ...
15
16
17class ConsoleNotifier:
18    def send(self, message: str) -> str:
19        return "console: " + message
20
21
22class QuietNotifier:
23    def send(self, message: str) -> str:
24        return "(logged silently: " + message + ")"
25
26
27def notify(notifier: Notifier, message: str) -> str:
28    return notifier.send(message)  # any object with the right SHAPE works
29
30
31def main() -> None:
32    book = md.Spellbook()
33    book.bind(spell=ConsoleNotifier, existence="unique",
34              spellframe="notifiers", binding_name="loud")
35    book.bind(spell=QuietNotifier, existence="unique",
36              spellframe="notifiers", binding_name="quiet")
37    conduit = book.conjure()
38
39    loud: Notifier = conduit.meld(spellframe="notifiers", binding_name="loud")
40    quiet: Notifier = conduit.meld(spellframe="notifiers", binding_name="quiet")
41    print(notify(loud, "deploy finished"))
42    print(notify(quiet, "cache warmed"))
43    assert notify(loud, "x").startswith("console")
44    print("one Protocol shape, two swappable spells")
45
46
47if __name__ == "__main__":
48    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.

More beginner examples ยท Level guide