util, core: improve keyword definitions and handling

This commit is contained in:
Helmut Merz 2026-10-24 09:36:17 +02:00
parent 9ee4dd73aa
commit 334df9afbd
4 changed files with 27 additions and 24 deletions

View file

@ -13,14 +13,12 @@ from scopes.core.message import Message
from scopes import util
from scopes.util import keywords as k, Symbol, Symbols
# keywords (domains, actions, categories, stages):
k('csys', 'env',
'connect', 'create', 'created', 'data', 'default', 'value',
'c00', 'e00', 's00',
'initial', 'active', 'retired')
dom = util.Symbols('dom')('csys', 'env')
cat = util.Symbols('cat')('c00', 'e00', 's00')
# keywords (domains, actions, categories, stages, data keys):
k('csys env',
'connect create created data default value',
'c00 e00 s00',
'initial active retired',
'address pred succ')
type Mailbox = asyncio.Queue
type Categ = tuple[Symbol, Symbol]
@ -61,7 +59,7 @@ def notify() -> Handler:
def gen_proc(actions: Actions, default: Handlers = notify(),
prepare: Handlers = None, finalize: Handlers = None) -> Proc:
async def proc(msg: Message, scope: Scope) -> Scope:
acts = actions.get(msg.head.action, actions.get(k.default, default))
acts = actions.get(msg.action, actions.get(k.default, default))
acts = util.flatten(prepare, acts, finalize, ignore_none=True)
for act in acts:
msg = await act(msg, scope)
@ -87,7 +85,7 @@ def gen_program(spec: ProgramSpec, default: Proc = gen_proc({})) -> Program:
class Scope:
value: Any = 0
categ: Categ = (k.csys, cat.c00)
categ: Categ = (k.csys, k.c00)
stage: Symbol = k.initial
proc: Proc = field(init=False)
program: Program = gen_program({})
@ -101,7 +99,7 @@ class Scope:
self.proc = self.program(self)
return self
def create_scope(env: Mailbox, cat: Categ = (k.csys, cat.c00), **kw) -> Scope:
def create_scope(env: Mailbox, cat: Categ = (k.csys, k.c00), **kw) -> Scope:
return Scope(environ=env, categ=cat, **kw)
def clone_scope(scope: Scope, **kw) -> Scope:
@ -109,7 +107,7 @@ def clone_scope(scope: Scope, **kw) -> Scope:
categ = kw.get('categ', scope.categ)
stage = kw.get('stage', k.initial)
return Scope(environ=scope.environ, value=value, categ=categ, stage=stage,
program=scope.program, syns=[], **kw)
program=scope.program, syns=[])
async def create_zero(env: Mailbox) -> Mailbox:
scope = create_scope(env, program=gen_program({}, default=std_proc()))
@ -155,6 +153,6 @@ def std_proc(actions: Actions | None = None, finalize: Handler = forward(),
# helpers
async def notify_created(msg: Message, new: Mailbox, scope: Scope) -> None:
msg = Message(msg.head.domain, k.created, data=msg.data | {k.new: new})
msg = Message(msg.domain, k.created, data=msg.data | {k.new: new})
await scope.environ.put(msg)

View file

@ -15,14 +15,14 @@ class Symbol(str):
class Symbols:
def __init__(self, prefix=None):
self.__prefix = prefix
def __init__(self, ns=None):
self.__prefix = ns + '.' if ns else ''
def __call__(self, *ks):
prefix = self.__prefix + '.' if self.__prefix else ''
for k in ks:
if not hasattr(self, k):
setattr(self, k, Symbol(prefix + k))
def __call__(self, *keys):
for segment in keys:
for key in segment.split():
if not hasattr(self, key):
setattr(self, key, Symbol(self.__prefix + key))
return self
def __getattr__(self, k):

View file

@ -71,8 +71,8 @@ async def test_core(meta_env, collector):
zero = await core.create_zero(env)
await env.put(Message(k.env, k.hello))
await zero.put(Message(k.csys, k.hello))
await zero.put(Message(k.csys, k.create))
#data={k.connect: k.pred, k.address: (1, 1)}))
await zero.put(Message(k.csys, k.create,
data={k.connect: k.pred, k.address: (1, 1)}))
await asyncio.sleep(0.01)
assert len(collector) == 4
assert collector[0].action is k.created

View file

@ -4,8 +4,11 @@
import pytest
from scopes.util import keywords as k, flatten
k('dummy', 'other', 'cd', 'new')
from scopes.util import keywords as k, flatten, Symbols
k('dummy other', 'cd', 'new', 'erp')
dom = Symbols('dom')('crm erp sys')
def test_keywords():
assert k.dummy is k.dummy
@ -13,6 +16,8 @@ def test_keywords():
assert getattr(k, "abcd"[-2:]) is k.cd
assert k['dummy'] is k.dummy
assert k['new'] is k['new']
assert repr(dom.erp) == '<dom.erp>'
assert dom.erp != k.erp
def test_flatten():
lst = (1, (None, 2), (3, (4, 5)))