from core.builtin_concepts import BuiltinConcepts from core.concept import Concept from core.global_symbols import NotInit from evaluators.BaseEvaluator import OneReturnValueEvaluator class PostExecutionEvaluator(OneReturnValueEvaluator): """ Last chance to alter the return_value This evaluator is supposed to be a generic evaluator for all rules that must be executed just before the aggregations As of now, the AUTO_EVAL rule implementation is simply hardcoded """ NAME = "PostExecution" def __init__(self): super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 90) def matches(self, context, return_value): evaluation_parents = context.get_parents(lambda c: c.action == BuiltinConcepts.PROCESSING) if len(evaluation_parents) > 1: return False # It must be executed only when the top level context value = return_value.body return isinstance(value, Concept) and context.sheerka.isa(value, context.sheerka.new(BuiltinConcepts.AUTO_EVAL)) def eval(self, context, return_value): # only support the rule for the AUTO_EVAL return context.sheerka.ret( self.name, True, self.custom_obj_value(context, return_value.body), parents=[return_value]) @staticmethod def custom_obj_value(context, obj): """ get concept inner value. You cannot use sheerka.objvalue() as it does not handle container And... Do not try to make it manage it, it won't work ;-) :param context: :param obj: :return: """ if context.sheerka.is_container(obj): return obj if isinstance(obj, Concept): if isinstance(obj.body, Concept): return PostExecutionEvaluator.custom_obj_value(context, obj.body) else: return obj.body if obj.body != NotInit else obj return obj