From 21da87393f1c4d4485a6077a8cac184ed07388fb Mon Sep 17 00:00:00 2001 From: Kodjo Sossouvi Date: Fri, 27 Dec 2019 11:33:16 +0100 Subject: [PATCH] Enhanced sheerka.update_concept() logs --- core/builtin_concepts.py | 3 +++ core/sheerka.py | 40 +++++++++++++++++++++------------- core/sheerka_logger.py | 5 ++++- evaluators/ConceptEvaluator.py | 5 ++++- parsers/ExactConceptParser.py | 16 +++++++++++--- 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/core/builtin_concepts.py b/core/builtin_concepts.py index e0ae2d6..f144889 100644 --- a/core/builtin_concepts.py +++ b/core/builtin_concepts.py @@ -92,6 +92,9 @@ class UserInputConcept(Concept): def user_name(self): return self.props["user_name"].value + def __repr__(self): + return f"({self.id}){self.name}: '{self.body}'" + class SuccessConcept(Concept): def __init__(self): diff --git a/core/sheerka.py b/core/sheerka.py index 30ff343..d1597e8 100644 --- a/core/sheerka.py +++ b/core/sheerka.py @@ -367,7 +367,7 @@ class Sheerka(Concept): sub_context = execution_context.push(step=step) sub_context.log(logger or self.log, f"{step=}, context='{sub_context}'") - copy = return_values[:] if hasattr(return_values, "__iter__") else return_values + copy = return_values[:] if hasattr(return_values, "__iter__") else [return_values] if step == BuiltinConcepts.PARSING: return_values = self._call_parsers(sub_context, return_values, logger) @@ -428,6 +428,7 @@ class Sheerka(Concept): concept_lexer_parser = self.parsers[CONCEPT_LEXER_PARSER_CLASS]() sub_context = context.push(self.name, desc=f"Initializing concept definition for {concept}") sub_context.concepts[concept.key] = concept # the concept is not in the real cache yet + sub_context.log_new(logger) init_ret_value = concept_lexer_parser.initialize(sub_context, concepts_definitions) if not init_ret_value.status: return self.ret(self.create_new_concept.__name__, False, ErrorConcept(init_ret_value.value)) @@ -494,7 +495,6 @@ class Sheerka(Concept): :param logger: :return: """ - # steps = [BuiltinConcepts.BEFORE_PARSING, BuiltinConcepts.PARSING, BuiltinConcepts.AFTER_PARSING] steps = [BuiltinConcepts.BEFORE_PARSING, BuiltinConcepts.PARSING, BuiltinConcepts.AFTER_PARSING] for part_key in ConceptParts: source = getattr(concept.metadata, part_key.value) @@ -503,8 +503,10 @@ class Sheerka(Concept): # I refuse empty strings for performance matters, I don't want to handle useless NOPConcepts continue else: + sub_context = context.push(desc=f"Initializing AST for {part_key}") + sub_context.log_new(logger) to_parse = self.ret(context.who, True, self.new(BuiltinConcepts.USER_INPUT, body=source)) - concept.cached_asts[part_key] = self.execute(context, to_parse, steps, logger) + concept.cached_asts[part_key] = self.execute(sub_context, to_parse, steps, logger) for prop in concept.props: if concept.props[prop].value: @@ -512,6 +514,8 @@ class Sheerka(Concept): context.who, True, self.new(BuiltinConcepts.USER_INPUT, body=concept.props[prop].value)) + sub_context = context.push(desc=f"Initializing AST for property {prop}") + sub_context.log_new(logger) concept.cached_asts[prop] = self.execute(context, to_parse, steps) # Updates the cache of concepts when possible @@ -533,11 +537,17 @@ class Sheerka(Concept): :return: value of the evaluation or error """ + logger = logger or self.log + if concept.metadata.is_evaluated: return concept - def _resolve(resolve_context, return_value): - r = self.execute(resolve_context, return_value, CONCEPT_EVALUATION_STEPS, logger or self.log) + def _resolve(return_value, desc, obj): + context.log(logger, desc, self.evaluate_concept.__name__) + sub_context = context.push(desc=desc, obj=obj) + sub_context.add_preprocess(self.get_evaluator_name("Concept"), return_body=True) + sub_context.log_new(logger) + r = self.execute(sub_context, return_value, CONCEPT_EVALUATION_STEPS, logger) return core.builtin_helpers.expect_one(context, r) # WHERE condition should already be validated by the parser. @@ -548,6 +558,7 @@ class Sheerka(Concept): # if len(concept.cached_asts) == 0: + context.log(logger, "concept asts are not initialized. Initializing.", self.evaluate_concept.__name__) self.initialize_concept_asts(context, concept, logger) # to make sure of the order, it don't use ConceptParts.get_parts() @@ -557,9 +568,7 @@ class Sheerka(Concept): for metadata_to_eval in all_metadata_to_eval: if metadata_to_eval == "props": for prop_name in (p for p in concept.props if p in concept.cached_asts): - sub_context = context.push(desc=f"Evaluating property '{prop_name}'") - sub_context.add_preprocess(self.get_evaluator_name("Concept"), return_body=True) - res = _resolve(sub_context, concept.cached_asts[prop_name]) + res = _resolve(concept.cached_asts[prop_name], f"Evaluating property '{prop_name}'", None) if res.status: concept.set_prop(prop_name, res.value) else: @@ -571,9 +580,7 @@ class Sheerka(Concept): part_key = ConceptParts(metadata_to_eval) if part_key in concept.cached_asts and concept.cached_asts[part_key] is not None: - sub_context = context.push(desc=f"Evaluating '{part_key}'", obj=concept) - sub_context.add_preprocess(self.get_evaluator_name("Concept"), return_body=True) - res = _resolve(sub_context, concept.cached_asts[part_key]) + res = _resolve(concept.cached_asts[part_key], f"Evaluating '{part_key}'", concept) if res.status: setattr(concept.metadata, metadata_to_eval, res.value) else: @@ -833,10 +840,13 @@ class Sheerka(Concept): self.log.info(defs) def dump_desc(self, concept_name): - c = self.get(concept_name) - if self.isinstance(c, BuiltinConcepts.UNKNOWN_CONCEPT): - self.log.error("Concept unknown") - return False + if isinstance(concept_name, Concept): + c = concept_name + else: + c = self.get(concept_name) + if self.isinstance(c, BuiltinConcepts.UNKNOWN_CONCEPT): + self.log.error("Concept unknown") + return False self.log.info(f"name : {c.name}") self.log.info(f"bnf : {c.metadata.definition}") diff --git a/core/sheerka_logger.py b/core/sheerka_logger.py index 64dcbb0..9f87a99 100644 --- a/core/sheerka_logger.py +++ b/core/sheerka_logger.py @@ -20,7 +20,10 @@ def set_enabled(to_enable): def to_discard(logger_class): - if logger_class in enabled: + if logger_class is None: + return False + + if logger_class in enabled or logger_class.strip(".") in enabled: return False if logger_class not in disabled: diff --git a/evaluators/ConceptEvaluator.py b/evaluators/ConceptEvaluator.py index f9cbbb4..9f4355b 100644 --- a/evaluators/ConceptEvaluator.py +++ b/evaluators/ConceptEvaluator.py @@ -36,7 +36,10 @@ class ConceptEvaluator(OneReturnValueEvaluator): # If we evaluate Concept("foo", body="a").set_prop("a", "'property_a'") # The body should be 'property_a', and not a concept called a in our universe if context.obj and concept.name in context.obj.props: - return sheerka.ret(self.name, True, context.obj.props[concept.name].value, parents=[return_value]) + value = context.obj.props[concept.name].value + context.log(self.verbose_log, f"{concept.name} is a property. Returning value '{value}'.", self.name) + + return sheerka.ret(self.name, True, value, parents=[return_value]) evaluated = sheerka.evaluate_concept(context, concept, self.verbose_log) diff --git a/parsers/ExactConceptParser.py b/parsers/ExactConceptParser.py index 89ef856..427d01d 100644 --- a/parsers/ExactConceptParser.py +++ b/parsers/ExactConceptParser.py @@ -1,10 +1,9 @@ +import logging + from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts from parsers.BaseParser import BaseParser from core.tokenizer import Tokenizer, Keywords, TokenKind from core.concept import VARIABLE_PREFIX -import logging - -log = logging.getLogger(__name__) class ExactConceptParser(BaseParser): @@ -24,10 +23,13 @@ class ExactConceptParser(BaseParser): :param text: :return: """ + + context.log(self.verbose_log, f"Parsing '{text}'", self.name) res = [] sheerka = context.sheerka words = self.get_words(text) if len(words) > self.MAX_WORDS_SIZE: + context.log(self.verbose_log, f"Max words reached. Stopping.", self.name) return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.CONCEPT_TOO_LONG, body=text)) recognized = False @@ -42,11 +44,19 @@ class ExactConceptParser(BaseParser): concepts = result.body if sheerka.isinstance(result, BuiltinConcepts.ENUMERATION) else [result] for concept in concepts: + context.log(self.verbose_log, f"Recognized concept {concept}.", self.name) # update the properties if needed for i, token in enumerate(combination): if token.startswith(VARIABLE_PREFIX): index = int(token[len(VARIABLE_PREFIX):]) concept.set_prop_by_index(index, words[i]) + if self.verbose_log.isEnabledFor(logging.DEBUG): + prop_name = list(concept.props.keys())[index] + context.log( + self.verbose_log, + f"Added property {index}: {prop_name}='{words[i]}'.", + self.name) + res.append(ReturnValueConcept( self.name, True,