Skip to content

Commit fc5b7ae

Browse files
committed
changes per craig
1 parent c980738 commit fc5b7ae

File tree

1 file changed

+24
-91
lines changed

1 file changed

+24
-91
lines changed

custom_components/pyscript/eval.py

Lines changed: 24 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@
4141
"print",
4242
}
4343

44+
TRIG_DECORATORS = {
45+
"time_trigger",
46+
"state_trigger",
47+
"event_trigger",
48+
"mqtt_trigger",
49+
"state_active",
50+
"time_active",
51+
"task_unique",
52+
}
53+
54+
ALL_DECORATORS = TRIG_DECORATORS.union({"service"})
4455

4556
def ast_eval_exec_factory(ast_ctx, mode):
4657
"""Generate a function that executes eval() or exec() with given ast_ctx."""
@@ -255,7 +266,6 @@ def __init__(self, func_def, code_list, code_str, global_ctx):
255266
self.trigger = None
256267
self.trigger_service = False
257268
self.has_closure = False
258-
self.perform_call = None
259269

260270
def get_name(self):
261271
"""Return the function name."""
@@ -281,15 +291,6 @@ async def trigger_init(self):
281291
"event_trigger",
282292
"mqtt_trigger",
283293
}
284-
trig_decorators = {
285-
"time_trigger",
286-
"state_trigger",
287-
"event_trigger",
288-
"mqtt_trigger",
289-
"state_active",
290-
"time_active",
291-
"task_unique",
292-
}
293294
decorator_used = set()
294295
for dec in self.decorators:
295296
dec_name, dec_args, dec_kwargs = dec[0], dec[1], dec[2]
@@ -304,7 +305,7 @@ async def trigger_init(self):
304305
decorator_used.add(dec_name)
305306
if dec_name in trig_decorators_reqd:
306307
got_reqd_dec = True
307-
if dec_name in trig_decorators:
308+
if dec_name in TRIG_DECORATORS:
308309
if dec_name not in trig_args:
309310
trig_args[dec_name] = {}
310311
trig_args[dec_name]["args"] = []
@@ -384,7 +385,7 @@ async def do_service_call(func, ast_ctx, data):
384385
dec_name,
385386
)
386387

387-
for dec_name in trig_decorators:
388+
for dec_name in TRIG_DECORATORS:
388389
if dec_name in trig_args and len(trig_args[dec_name]["args"]) == 0:
389390
trig_args[dec_name]["args"] = None
390391

@@ -520,85 +521,21 @@ async def eval_decorators(self, ast_ctx):
520521
code_str, code_list = ast_ctx.code_str, ast_ctx.code_list
521522
ast_ctx.code_str, ast_ctx.code_list = self.code_str, self.code_list
522523

523-
decorator_chain_funcs = []
524-
524+
dec_funcs = []
525525
for dec in self.func_def.decorator_list:
526-
# this should eventually handle:
527-
# SomeClass('a','b').some_method('x','y')
528-
if isinstance(dec, ast.Call) and isinstance(dec.func, ast.Attribute):
529-
_LOGGER.info(
530-
"Attribute as decorator (ignoring for now) %s %s %s",
531-
dec.func,
532-
dec.func.attr,
533-
dec.func.value
534-
)
535-
536-
elif isinstance(dec, ast.Call) and isinstance(dec.func, ast.Name):
537-
args = []
538-
kwargs = {}
539-
for arg in dec.args:
540-
args.append(await ast_ctx.aeval(arg))
541-
for keyw in dec.keywords:
542-
kwargs[keyw.arg] = await ast_ctx.aeval(keyw.value)
526+
if isinstance(dec, ast.Call) and isinstance(dec.func, ast.Name) and dec.func.id in ALL_DECORATORS:
527+
args = [await ast_ctx.aeval(arg) for arg in dec.args]
528+
kwargs = {keyw.arg: await ast_ctx.aeval(keyw.value) for keyw in dec.keywords}
543529
if len(kwargs) == 0:
544530
kwargs = None
545-
546-
if dec.func.id in ast_ctx.global_sym_table:
547-
_LOGGER.info(
548-
"added %s to decorator_chain_funcs",
549-
dec.func.id,
550-
)
551-
decorator_chain_funcs.append(dec)
552-
else:
553-
self.decorators.append([dec.func.id, args, kwargs])
554-
elif isinstance(dec, ast.Name):
555-
if dec.id in ast_ctx.global_sym_table:
556-
decorator_chain_funcs.append(dec)
557-
else:
558-
self.decorators.append([dec.id, None, None])
531+
self.decorators.append([dec.func.id, args, kwargs])
532+
elif isinstance(dec, ast.Name) and dec.id in ALL_DECORATORS:
533+
self.decorators.append([dec.id, None, None])
559534
else:
560-
_LOGGER.error("function %s has unexpected decorator type %s", self.name, dec)
561-
562-
actual_call = self.real_call
563-
564-
try:
565-
for dec in reversed(decorator_chain_funcs):
566-
if isinstance(dec, ast.Call) and isinstance(dec.func, ast.Name):
567-
args = []
568-
kwargs = {}
569-
for arg in dec.args:
570-
args.append(await ast_ctx.aeval(arg))
571-
for keyw in dec.keywords:
572-
kwargs[keyw.arg] = await ast_ctx.aeval(keyw.value)
573-
if len(kwargs) == 0:
574-
kwargs = {}
575-
func_def = ast_ctx.global_sym_table[dec.func.id]
576-
577-
wrapper = await func_def.call(ast_ctx, *args, **kwargs)
578-
def make_actual_call_inner(actual_call):
579-
async def actual_call_inner(*args_tuple, **kwargs):
580-
args = list(args_tuple)
581-
if len(args) > 0 and isinstance(args[0], AstEval):
582-
_LOGGER.info('AstEval seen')
583-
args.pop(0)
584-
_LOGGER.info(actual_call)
585-
return await actual_call(ast_ctx, *args, **kwargs)
586-
return actual_call_inner
587-
actual_call = await wrapper(make_actual_call_inner(actual_call))
588-
589-
elif isinstance(dec, ast.Name):
590-
func_def = ast_ctx.global_sym_table[dec.id]
591-
actual_call = await func_def.call(ast_ctx, actual_call)
535+
dec_funcs.append(await ast_ctx.aeval(dec))
592536

593-
else:
594-
_LOGGER.error("function %s has unexpected global_sym_table decorator type %s", self.name, dec)
595-
except Exception as e:
596-
_LOGGER.error(
597-
"Something went wrong %s",
598-
e
599-
)
600-
601-
self.perform_call = actual_call
537+
for func in reversed(dec_funcs):
538+
self.call = await ast_ctx.call_func(func, None, self.call)
602539

603540
ast_ctx.code_str, ast_ctx.code_list = code_str, code_list
604541

@@ -680,13 +617,9 @@ async def try_aeval(self, ast_ctx, arg):
680617
ast_ctx.exception_long = ast_ctx.format_exc(err, arg.lineno, arg.col_offset)
681618

682619
async def call(self, ast_ctx, *args, **kwargs):
683-
"""Call the function with decorators"""
684-
return await self.perform_call(ast_ctx, *args, **kwargs)
685-
686-
async def real_call(self, ast_ctx, *args, **kwargs):
687620
"""Call the function with the given context and arguments."""
688621
_LOGGER.info(
689-
'in real_call of %s',
622+
'in call of %s',
690623
self.name
691624
)
692625
sym_table = {}

0 commit comments

Comments
 (0)