Fixed #72 : Exception when get_results(id=10)
Fixed #74 : Keyword parameters are no longer recognized when a concept that redefines equality is created Fixed #118 : RecursionError: maximum recursion depth exceeded Fixed #119 : PreventCircularReferenceEvaluator Fixed #121 : Plural are not updated when new elements are added Fixed #123 : BaseCache : Values in cache can be evicted before being committed Fixed #105 : TOO_MANY_ERROR is not the relevant error when results are filtered
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from typing import Set, List, Union
|
||||
from typing import List, Set, Union
|
||||
|
||||
import core.utils
|
||||
from cache.Cache import Cache
|
||||
@@ -9,14 +9,14 @@ from cache.DictionaryCache import DictionaryCache
|
||||
from cache.ListIfNeededCache import ListIfNeededCache
|
||||
from cache.SetCache import SetCache
|
||||
from core.builtin_concepts import ErrorConcept
|
||||
from core.builtin_concepts_ids import BuiltinConcepts, AllBuiltinConcepts, BuiltinUnique
|
||||
from core.builtin_helpers import ensure_concept, ensure_bnf
|
||||
from core.concept import Concept, DEFINITION_TYPE_DEF, DEFINITION_TYPE_BNF, freeze_concept_attrs, ConceptMetadata, \
|
||||
VARIABLE_PREFIX
|
||||
from core.global_symbols import EVENT_CONCEPT_CREATED, NotInit, NotFound, ErrorObj, EVENT_CONCEPT_DELETED, NoFirstToken, \
|
||||
EVENT_CONCEPT_MODIFIED, CONCEPT_COMPARISON_CONTEXT
|
||||
from core.builtin_concepts_ids import AllBuiltinConcepts, BuiltinConcepts, BuiltinUnique
|
||||
from core.builtin_helpers import ensure_bnf, ensure_concept
|
||||
from core.concept import Concept, ConceptMetadata, DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF, VARIABLE_PREFIX, \
|
||||
freeze_concept_attrs
|
||||
from core.global_symbols import CONCEPT_COMPARISON_CONTEXT, EVENT_CONCEPT_CREATED, EVENT_CONCEPT_DELETED, \
|
||||
EVENT_CONCEPT_MODIFIED, ErrorObj, NoFirstToken, NotFound, NotInit
|
||||
from core.sheerka.services.sheerka_service import BaseService
|
||||
from core.tokenizer import Tokenizer, TokenKind
|
||||
from core.tokenizer import TokenKind, Tokenizer
|
||||
from parsers.BnfNodeParser import RegExDef
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProviderDuplicateKeyError
|
||||
|
||||
@@ -133,6 +133,7 @@ class SheerkaConceptManager(BaseService):
|
||||
self.sheerka.bind_service_method(self.NAME, self.get_concepts_bnf_definitions, False, visible=False)
|
||||
self.sheerka.bind_service_method(self.NAME, self.clear_bnf_definition, True, visible=False)
|
||||
self.sheerka.bind_service_method(self.NAME, self.set_precedence, True)
|
||||
self.sheerka.bind_service_method(self.NAME, self.get_plural_concept_value, False)
|
||||
|
||||
register_concept_cache = self.sheerka.om.register_concept_cache
|
||||
|
||||
@@ -1294,3 +1295,11 @@ class SheerkaConceptManager(BaseService):
|
||||
for variable in [v for v in visitor.variables if isinstance(v, ParameterVariable)]:
|
||||
if variable.name not in concept.get_metadata().parameters:
|
||||
concept.get_metadata().parameters.append(variable.name)
|
||||
|
||||
@staticmethod
|
||||
def get_plural_concept_value(context, concept):
|
||||
underlying_concept = concept.get_prop(BuiltinConcepts.PLURAL)
|
||||
if context.sheerka.isaset(context, underlying_concept):
|
||||
return context.sheerka.get_set_elements(context, underlying_concept)
|
||||
|
||||
return None
|
||||
|
||||
@@ -600,7 +600,7 @@ class SheerkaDebugManager(BaseService):
|
||||
elif item_type == self.CONCEPTS_DEBUG_TYPE:
|
||||
self.registered_concepts.append((service, method, item))
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
raise NotImplementedError(f"register_debug {item_type=}")
|
||||
|
||||
def register_debug_vars(self, service, method, item):
|
||||
return self.register_debug(self.VARS_DEBUG_TYPE, service, method, item)
|
||||
@@ -643,7 +643,7 @@ class SheerkaDebugManager(BaseService):
|
||||
elif item_type == self.CONCEPTS_DEBUG_TYPE:
|
||||
lst = self.registered_concepts
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
raise NotImplementedError(f"filter_registered_debug {item_type=}")
|
||||
|
||||
for registered in lst:
|
||||
if service != "*" and service != registered[0]:
|
||||
|
||||
@@ -230,6 +230,12 @@ class SheerkaEvaluateConcept(BaseService):
|
||||
:param possible_variables: concepts that must be considered as variables
|
||||
:return:
|
||||
"""
|
||||
def get_filtered_by_prevent_circular_reference(return_values):
|
||||
for ret_val in return_values:
|
||||
from evaluators.PreventCircularReferenceEvaluator import PreventCircularReferenceEvaluator
|
||||
if ret_val.who == PreventCircularReferenceEvaluator.NAME:
|
||||
return ret_val.body.body
|
||||
return None
|
||||
|
||||
def parse_token_concept(s):
|
||||
"""
|
||||
@@ -252,6 +258,7 @@ class SheerkaEvaluateConcept(BaseService):
|
||||
"""
|
||||
parsers_to_use = INIT_AST_QUESTION_PARSERS if p in [ConceptParts.WHERE,
|
||||
ConceptParts.PRE] else INIT_AST_PARSERS
|
||||
recursion_detected = False
|
||||
while True:
|
||||
return_value = current_context.sheerka.parse_unrecognized(current_context,
|
||||
s,
|
||||
@@ -262,8 +269,24 @@ class SheerkaEvaluateConcept(BaseService):
|
||||
possible_variables=possible_variables)
|
||||
|
||||
if not return_value.status:
|
||||
if current_context.preprocess:
|
||||
raise ChickenAndEggException(context.sheerka.new(BuiltinConcepts.CHICKEN_AND_EGG, body={c}))
|
||||
# Dealing with circular reference is not easy.
|
||||
# Let's take for example 'def concept q from q ? as question(q)'
|
||||
# 'q' is the name of the concept, but also the name of the parameter
|
||||
# When chicken_and_egg_err is found with a concept parser (Exact, Sya, Bnf...) we must disable it
|
||||
# to let a chance to the Python parser (which can handle concepts parameters)
|
||||
sheerka = context.sheerka
|
||||
if sheerka.has_error(context, return_value, __type="ChickenAndEggException"):
|
||||
recursion_detected = True
|
||||
filtered = get_filtered_by_prevent_circular_reference(return_value.body.body)
|
||||
recursive_parsers = list(SheerkaEvaluateConcept.get_recursive_definitions(context, c, filtered))
|
||||
if len(recursive_parsers):
|
||||
desc = f"Removing parsers {recursive_parsers}"
|
||||
current_context = current_context.push(context.action, context.action_context, desc=desc)
|
||||
for recursive_parser in recursive_parsers:
|
||||
current_context.add_preprocess(recursive_parser.name, enabled=False)
|
||||
continue
|
||||
elif recursion_detected:
|
||||
raise ChickenAndEggException(sheerka.new(BuiltinConcepts.CHICKEN_AND_EGG, body={c}))
|
||||
else:
|
||||
raise FailedToCompileError([return_value.body])
|
||||
|
||||
@@ -529,7 +552,7 @@ class SheerkaEvaluateConcept(BaseService):
|
||||
return evaluated
|
||||
|
||||
elif isinstance(to_resolve, Rule):
|
||||
raise NotImplementedError() # how to resolve rules ?
|
||||
raise NotImplementedError(f"evaluate_concept.resolve() {to_resolve=}") # how to resolve rules ?
|
||||
|
||||
# otherwise, execute all return values to find out what is the value
|
||||
else:
|
||||
@@ -772,7 +795,7 @@ class SheerkaEvaluateConcept(BaseService):
|
||||
# TODO : Validate the POST condition
|
||||
#
|
||||
|
||||
if ConceptParts.BODY in all_metadata_to_eval and not failed_to_evaluate_body:
|
||||
if ConceptParts.BODY in all_metadata_to_eval and not failed_to_evaluate_body and not concept.is_dynamic():
|
||||
concept.get_hints().is_evaluated = True
|
||||
|
||||
# # update the cache for concepts with no variables
|
||||
|
||||
@@ -406,7 +406,7 @@ class SheerkaExecute(BaseService):
|
||||
if isinstance(text, ParserInput):
|
||||
return text.as_text()
|
||||
|
||||
raise NotImplementedError()
|
||||
raise NotImplementedError(f"get_input_as_text({text=})")
|
||||
|
||||
def get_parser_input(self, text, tokens=None):
|
||||
"""
|
||||
@@ -835,6 +835,15 @@ class SheerkaExecute(BaseService):
|
||||
:param possible_variables: concepts that must be considered as variables
|
||||
:return:
|
||||
"""
|
||||
|
||||
# def filter_for_circular_reference(return_values, concept):
|
||||
# for r in return_values:
|
||||
# if r.status and context.sheerka.isinstance(r.body, BuiltinConcepts.PARSER_RESULT):
|
||||
# body = r.body.body[0] if isinstance(r.body.body, list) and len(r.body.body) == 1 else r.body.body
|
||||
# if hasattr(body, "get_concept") and body.get_concept().id == concept.id:
|
||||
# continue
|
||||
# yield r
|
||||
|
||||
sheerka = context.sheerka
|
||||
|
||||
if prop:
|
||||
@@ -864,6 +873,14 @@ class SheerkaExecute(BaseService):
|
||||
sheerka.new(BuiltinConcepts.USER_INPUT, body=source))
|
||||
res = sheerka.execute(sub_context, to_parse, PARSE_STEPS)
|
||||
|
||||
# # before user defined filtering, remove the return values that may lead to circular reference
|
||||
# in_recursion = list(context.search(predicate=lambda c: c.action == BuiltinConcepts.EVALUATING_CONCEPT,
|
||||
# get_obj=lambda c: c.action_context,
|
||||
# only_first=True))
|
||||
#
|
||||
# if in_recursion:
|
||||
# res = list(filter_for_circular_reference(res, in_recursion[0]))
|
||||
|
||||
if filter_func:
|
||||
res = filter_func(sub_context, res)
|
||||
|
||||
|
||||
@@ -749,7 +749,7 @@ class ReteConditionExprVisitor(GetConditionExprVisitor):
|
||||
elif type(c) == NegatedCondition:
|
||||
res.append(Condition(c.identifier, c.attribute, c.value))
|
||||
else:
|
||||
raise NotImplementedError
|
||||
raise NotImplementedError("rete - negate_conditions")
|
||||
else:
|
||||
res.append(NegatedConjunctiveConditions(*conditions_))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user