Fixed #29: Parsers: Implement parsing memoization

Fixed #77 : Parser: ShortTermMemoryParser should be called separately
Fixed #78 : Remove VariableNode usage
Fixed #79 : ConceptManager: Implement compile caching
Fixed #80 : SheerkaExecute : parsers_key is not correctly computed
Fixed #81 : ValidateConceptEvaluator : Validate concept's where and pre clauses right after the parsing
Fixed #82 : SheerkaIsAManager: isa() failed when the set as a body
Fixed #83 : ValidateConceptEvaluator : Support BNF and SYA Concepts
Fixed #84 : ExpressionParser: Implement the parser as a standard parser
Fixed #85 : Services: Give order to services
Fixed #86 : cannot manage smart_get_attr(the short, color)
This commit is contained in:
2021-06-07 21:14:03 +02:00
parent 1059ce25c5
commit 7dcaa9c111
92 changed files with 4263 additions and 1890 deletions
+443 -21
View File
@@ -1,14 +1,38 @@
from core.builtin_concepts import ReturnValueConcept, UserInputConcept, BuiltinConcepts, ParserResultConcept
from core.sheerka.services.SheerkaExecute import ParserInput, SheerkaExecute
from parsers.BaseParser import BaseParser
import pytest
from core.builtin_concepts import ReturnValueConcept, UserInputConcept, BuiltinConcepts, ParserResultConcept
from core.concept import Concept
from core.sheerka.services.SheerkaExecute import ParserInput, SheerkaExecute, DEFAULT, PARSE_STEPS
from parsers.BaseExpressionParser import ExprNode
from parsers.BaseParser import BaseParser
from parsers.BnfNodeParser import BnfNodeParser
from parsers.SequenceNodeParser import SequenceNodeParser
from parsers.SyaNodeParser import SyaNodeParser
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
def get_ret_val(text, who="who"):
def get_user_input(text, who="who"):
return ReturnValueConcept(who, True, UserInputConcept(text, "user_name"))
def check_same_results(result1, result2, user_input):
assert len(result1) == len(result2)
for previous, current in zip(result1, result2):
assert current.parents == user_input
assert current.who == previous.who
assert current.status == previous.status
assert id(current.body) == id(previous.body)
def check_same_values(sheerka, context, ret_val1, ret_val2):
previous = sheerka.execute(context, ret_val1, [BuiltinConcepts.EVALUATION])
current = sheerka.execute(context, ret_val2, [BuiltinConcepts.EVALUATION])
assert len(previous) == len(current)
for p, c in zip(previous, current):
assert p == c
class BaseTestParser(BaseParser):
debug_out = []
@@ -136,12 +160,23 @@ class ListOfNoneParser(BaseTestParser):
class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
default_parsers = None
@classmethod
def setup_class(cls):
cls.default_parsers = cls().get_sheerka().parsers
@classmethod
def teardown_class(cls):
# At the end of the tests, sheerka singleton instance will be corrupted
# Ask for a new one
TestUsingMemoryBasedSheerka.sheerka = None
def reset_parsers(self, sheerka):
sheerka.parsers = self.default_parsers
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
def test_i_can_get_parser_when_context_is_not_altered(self):
sheerka, context = self.init_concepts()
sheerka.parsers = {
@@ -152,7 +187,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service.reset_registered_parsers()
parsers_key, groups, sorted_priorities = service.get_parsers(context)
assert parsers_key == "__default"
assert parsers_key == ("__default", "__default")
assert groups == {80: [Enabled80FalseParser()], 90: [Enabled90FalseParser()]}
assert sorted_priorities == [90, 80]
@@ -171,13 +206,13 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
context.preprocess_parsers = parsers_names
parsers_key, groups, sorted_priorities = service.get_parsers(context)
assert parsers_key == "Enabled50True|Enabled70False|Disabled"
assert parsers_key == (DEFAULT, "Enabled50True|Enabled70False|Disabled")
assert groups == {50: [Enabled50TrueParser()], 70: [Enabled70FalseParser()]}
assert sorted_priorities == [70, 50] # Disabled parser does not appear
key = "|".join(parsers_names)
assert key in service.grouped_parsers_cache
groups, sorted_priorities = service.grouped_parsers_cache[key]
assert (DEFAULT, key) in service.grouped_parsers_cache
groups, sorted_priorities = service.grouped_parsers_cache[(DEFAULT, key)]
assert groups == {50: [Enabled50TrueParser], 70: [Enabled70FalseParser]}
assert sorted_priorities == [70, 50]
@@ -202,8 +237,8 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
assert groups == {80: [Enabled50TrueParser()], 70: [Enabled70FalseParser()]}
assert sorted_priorities == [80, 70] # Disabled parsers does not appear
key = "|".join(parsers_names)
assert key not in service.grouped_parsers_cache # not saved in cache
key = (DEFAULT, "|".join(parsers_names))
assert key not in service.grouped_parsers_cache # not saved in cache
def test_disabled_parsers_are_not_executed(self):
sheerka = self.get_sheerka()
@@ -214,7 +249,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
user_input = [get_ret_val("hello world")]
user_input = [get_user_input("hello world")]
BaseTestParser.debug_out = []
sheerka.execute(self.get_context(sheerka), user_input, [BuiltinConcepts.PARSING])
@@ -230,7 +265,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
user_input = [get_ret_val("hello world")]
user_input = [get_user_input("hello world")]
BaseTestParser.debug_out = []
sheerka.execute(self.get_context(sheerka), user_input, [BuiltinConcepts.PARSING])
@@ -254,7 +289,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
user_input = [get_ret_val("hello world")]
user_input = [get_user_input("hello world")]
BaseTestParser.debug_out = []
sheerka.execute(self.get_context(sheerka), user_input, [BuiltinConcepts.PARSING])
@@ -279,7 +314,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
user_input = [get_ret_val("hello world")]
user_input = [get_user_input("hello world")]
BaseTestParser.debug_out = []
sheerka.execute(self.get_context(sheerka), user_input, [BuiltinConcepts.PARSING])
@@ -310,7 +345,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
user_input = [get_ret_val("hello world")]
user_input = [get_user_input("hello world")]
BaseTestParser.debug_out = []
sheerka.execute(self.get_context(sheerka), user_input, [BuiltinConcepts.PARSING])
@@ -342,7 +377,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
user_input = [get_ret_val("hello world")]
user_input = [get_user_input("hello world")]
res = sheerka.execute(self.get_context(sheerka), user_input, [BuiltinConcepts.PARSING])
res_as_tuple = [(str(r.who)[8:], r.status, r.body.body) for r in res]
@@ -365,7 +400,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
user_input = [get_ret_val("hello world")]
user_input = [get_user_input("hello world")]
BaseTestParser.debug_out = []
res = sheerka.execute(self.get_context(sheerka), user_input, [BuiltinConcepts.PARSING])
@@ -391,7 +426,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
user_input = [get_ret_val("hello world")]
user_input = [get_user_input("hello world")]
BaseTestParser.debug_out = []
sheerka.execute(self.get_context(sheerka), user_input, [BuiltinConcepts.PARSING])
@@ -412,7 +447,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
user_input = [get_ret_val("hello world")]
user_input = [get_user_input("hello world")]
BaseTestParser.debug_out = []
res = sheerka.execute(self.get_context(sheerka), user_input, [BuiltinConcepts.PARSING])
@@ -432,7 +467,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
('Enabled50True', False, 'Enabled50True:Enabled80MultipleFalse:hello world_2'),
]
def test_i_can_manage_parser_with_multiple_results_and_a_sucess(self):
def test_i_can_manage_parser_with_multiple_results_and_a_success(self):
sheerka = self.get_sheerka()
sheerka.parsers = {
"Enabled80MultipleTrue": Enabled80MultipleTrueParser,
@@ -441,7 +476,7 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
service = sheerka.services[SheerkaExecute.NAME]
service.reset_registered_parsers()
user_input = [get_ret_val("hello world")]
user_input = [get_user_input("hello world")]
BaseTestParser.debug_out = []
res = sheerka.execute(self.get_context(sheerka), user_input, [BuiltinConcepts.PARSING])
@@ -454,3 +489,390 @@ class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
('Enabled80MultipleTrue', True, 'Enabled80MultipleTrue:hello world_1'),
('Enabled80MultipleTrue', False, 'Enabled80MultipleTrue:hello world_2'),
]
def test_parser_calls_are_put_in_cache(self):
sheerka, context = self.init_test().unpack()
service = sheerka.services[SheerkaExecute.NAME]
self.reset_parsers(sheerka)
user_input = [get_user_input("1")]
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
assert len(res) > 0
assert len(service.parsers_cache.cache) == 1
assert (('__default', '__default'), '1') in service.parsers_cache
def test_parser_calls_are_put_in_cache_when_question(self):
sheerka, context = self.init_test().unpack()
service = sheerka.services[SheerkaExecute.NAME]
self.reset_parsers(sheerka)
context.add_to_protected_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
user_input = [get_user_input("1")]
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
assert len(res) > 0
assert len(service.parsers_cache.cache) == 2 # one for EVAL_QUESTION, one to compile the Python
assert ((BuiltinConcepts.EVAL_QUESTION_REQUESTED, DEFAULT), '1') in service.parsers_cache
def test_parser_calls_are_not_put_in_cache_when_preprocess_parsers(self):
sheerka, context = self.init_test().unpack()
service = sheerka.services[SheerkaExecute.NAME]
self.reset_parsers(sheerka)
context.preprocess_parsers = [SequenceNodeParser.NAME, BnfNodeParser.NAME, SyaNodeParser.NAME]
user_input = [get_user_input("1")]
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
expected_key = (DEFAULT, "|".join([SequenceNodeParser.NAME, BnfNodeParser.NAME, SyaNodeParser.NAME]))
assert len(res) == 3
assert len(service.parsers_cache.cache) == 1
assert (expected_key, '1') in service.parsers_cache
def test_parser_calls_are_not_put_in_cache_when_preprocess(self):
sheerka, context = self.init_test().unpack()
service = sheerka.services[SheerkaExecute.NAME]
self.reset_parsers(sheerka)
context.add_preprocess(BaseParser.PREFIX + "parser_name", some_attribute='some_value')
user_input = [get_user_input("1")]
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
assert len(res) > 0
assert len(service.parsers_cache.cache) == 0
def test_i_can_use_parser_memoization_on_python(self):
sheerka, context = self.init_test().unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("1 + 1")]
first_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
user_input_2 = [get_user_input("1 + 1")]
second_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
check_same_results(first_request, second_request, user_input_2)
check_same_values(sheerka, context, first_request, second_request)
@pytest.mark.parametrize("concept", {
Concept("foo"),
Concept("foo", body="1"),
})
def test_i_can_use_parser_memoization_when_exact_concept(self, concept):
sheerka, context, foo = self.init_test(eval_body=True, eval_where=True).with_concepts(concept).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("foo")]
first_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r.who for r in first_request if r.status]
assert successful == ['parsers.ExactConcept']
user_input_2 = [get_user_input("foo")]
second_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
check_same_results(first_request, second_request, user_input_2)
check_same_values(sheerka, context, first_request, second_request)
def test_i_can_use_parser_memoization_when_multiple_results(self):
sheerka, context, *foo = self.init_test(eval_body=True, eval_where=True).with_concepts(
Concept("foo", body="1"),
Concept("foo", body="2")).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("foo")]
first_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r.who for r in first_request if r.status]
assert successful == ['parsers.ExactConcept', 'parsers.ExactConcept']
user_input_2 = [get_user_input("foo")]
second_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
check_same_results(first_request, second_request, user_input_2)
check_same_values(sheerka, context, first_request, second_request)
def test_i_can_use_parser_memoization_when_bnf_node(self):
sheerka, context, *concepts = self.init_test(eval_body=True, eval_where=True).with_concepts(
Concept("one", body="1"),
Concept("two", body="2"),
Concept("twenties", definition="'twenty' (one|two)=unit", body="20 + unit").def_var("unit"),
create_new=True).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("twenty one")]
first_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r.who for r in first_request if r.status]
assert successful == ['parsers.Bnf']
user_input_2 = [get_user_input("twenty one")]
second_request = sheerka.execute(context, user_input_2, [BuiltinConcepts.PARSING])
check_same_results(first_request, second_request, user_input_2)
check_same_values(sheerka, context, first_request, second_request)
def test_i_can_use_parser_memoization_when_sequence_node(self):
sheerka, context, *concepts = self.init_test(eval_body=True, eval_where=True).with_concepts(
Concept("one", body="1"),
Concept("two", body="2"),
create_new=True).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("one two")]
first_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r.who for r in first_request if r.status]
assert successful == ['parsers.Sequence']
user_input_2 = [get_user_input("one two")]
second_request = sheerka.execute(context, user_input_2, [BuiltinConcepts.PARSING])
check_same_results(first_request, second_request, user_input_2)
check_same_values(sheerka, context, first_request, second_request)
def test_i_can_use_parser_memoization_when_sya_node(self):
sheerka, context, *concepts = self.init_test(eval_body=True, eval_where=True).with_concepts(
Concept("one", body="1"),
Concept("twenty two", body="22"),
Concept("a plus b", body="a + b").def_var("a").def_var("b"),
create_new=True).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("one plus twenty two")]
first_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r.who for r in first_request if r.status]
assert successful == ['parsers.Sya']
user_input_2 = [get_user_input("one plus twenty two")]
second_request = sheerka.execute(context, user_input_2, [BuiltinConcepts.PARSING])
check_same_results(first_request, second_request, user_input_2)
check_same_values(sheerka, context, first_request, second_request)
def test_i_can_use_parser_memoization_when_not_parser_input_from_sequence_node(self):
# In the test, 'one two' will be partially parsed by the SequenceNodeParser
# We test that the results of the UnrecognizedNodeParser and the PythonWithConceptParser
# which both do not used ParsingInput as an input (but a ParserResult)
# are added to the list of results
sheerka, context, *concepts = self.init_test(eval_body=True, eval_where=True).with_concepts(
Concept("one", body="1")).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("one two")]
first_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r.who for r in first_request if r.status]
assert successful == []
user_input_2 = [get_user_input("one two")]
second_request = sheerka.execute(context, user_input_2, [BuiltinConcepts.PARSING])
check_same_results(first_request, second_request, user_input_2)
check_same_values(sheerka, context, first_request, second_request)
def test_i_can_use_parser_memoization_when_not_parser_input_from_bnf_node(self):
# check the comment from test_i_can_use_parser_memoization_when_not_parser_input_from_sequence_node
# for more information on this test
sheerka, context, *concepts = self.init_test(eval_body=True, eval_where=True).with_concepts(
Concept("one", body="1"),
Concept("two", body="2"),
Concept("twenties", definition="'twenty' (one|two)=unit", body="20 + unit"),
create_new=True).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("twenty two foo")]
first_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r.who for r in first_request if r.status]
assert successful == []
user_input_2 = [get_user_input("twenty two foo")]
second_request = sheerka.execute(context, user_input_2, [BuiltinConcepts.PARSING])
check_same_results(first_request, second_request, user_input_2)
check_same_values(sheerka, context, first_request, second_request)
def test_i_can_use_parser_memoization_when_not_parser_input_from_sy_node(self):
# check the comment from test_i_can_use_parser_memoization_when_not_parser_input_from_sequence_node
# for more information on this test
sheerka, context, *concepts = self.init_test(eval_body=True, eval_where=True).with_concepts(
Concept("one", body="1"),
Concept("twenty two", body="22"),
Concept("a plus b", body="a + b").def_var("a").def_var("b"),
create_new=True).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("twenty two plus one foo")]
first_request = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r.who for r in first_request if r.status]
assert successful == []
user_input_2 = [get_user_input("twenty two plus one foo")]
second_request = sheerka.execute(context, user_input_2, [BuiltinConcepts.PARSING])
check_same_results(first_request, second_request, user_input_2)
check_same_values(sheerka, context, first_request, second_request)
def test_cache_is_reset_on_concept_creation(self):
sheerka, context, *concepts = self.init_test().with_concepts(
Concept("foo", body="1"), create_new=True).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("foo")]
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r for r in res if r.status]
assert len(successful) == 1
sheerka.create_new_concept(context, Concept("foo", body="2"))
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r for r in res if r.status]
assert len(successful) == 2
def test_cache_is_reset_on_concept_deletion(self):
sheerka, context, foo1, foo2 = self.init_test().with_concepts(
Concept("foo", body="1"),
Concept("foo", body="2"),
create_new=True).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("foo")]
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r for r in res if r.status]
assert len(successful) == 2
sheerka.remove_concept(context, foo2)
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r for r in res if r.status]
assert len(successful) == 1
def test_cache_is_reset_on_concept_modification(self):
sheerka, context, foo1, foo2 = self.init_test().with_concepts(
Concept("foo", body="1"),
Concept("foo", body="2"),
create_new=True).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("foo")]
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r for r in res if r.status]
assert len(successful) == 2
sheerka.modify_concept(context, foo2, to_add={'meta': {"name": "bar"}})
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
successful = [r for r in res if r.status]
assert len(successful) == 1
def test_i_do_not_use_short_term_memory_when_not_requested(self):
sheerka, context, foo = self.init_test().with_concepts(
Concept("foo"),
create_new=True).unpack()
self.reset_parsers(sheerka)
user_input = [get_user_input("foo")]
# put something is STM
context.add_to_short_term_memory("foo", "value")
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
assert len(res) == 1
assert res[0].body == "value"
# specify the parsers to use
context.preprocess_parsers = ["ExactConcept"]
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
assert len(res) == 1
assert res[0].body.body == foo
# I can force STM
context.preprocess_parsers = ["ExactConcept", "ShortTermMemory"] # order in not relevant for STM parser
res = sheerka.execute(context, user_input, [BuiltinConcepts.PARSING])
assert len(res) == 1
assert res[0].body == "value"
def test_i_can_compute_parsers_key(self):
sheerka = self.get_sheerka()
context = self.get_context(sheerka)
key = SheerkaExecute.get_parsers_key(context)
assert key == (DEFAULT, DEFAULT)
context = self.get_context(sheerka)
context.add_to_private_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
key = SheerkaExecute.get_parsers_key(context)
assert key == (BuiltinConcepts.EVAL_QUESTION_REQUESTED, DEFAULT)
context = self.get_context(sheerka)
context.preprocess_parsers = ["foo", "bar", "baz"]
key = SheerkaExecute.get_parsers_key(context)
assert key == (DEFAULT, 'foo|bar|baz')
context = self.get_context(sheerka)
context.preprocess_parsers = ["foo", "bar", "baz"]
context.add_to_private_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
key = SheerkaExecute.get_parsers_key(context)
assert key == (BuiltinConcepts.EVAL_QUESTION_REQUESTED, 'foo|bar|baz')
context = self.get_context(sheerka)
context.add_preprocess(BaseParser.PREFIX + "foo", key="some_value")
key = SheerkaExecute.get_parsers_key(context)
assert key is None
context = self.get_context(sheerka)
context.add_preprocess(BaseParser.PREFIX + "foo", key="some_value")
context.add_to_private_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
key = SheerkaExecute.get_parsers_key(context)
assert key is None
context = self.get_context(sheerka)
context.add_preprocess("foo", key="some_value")
key = SheerkaExecute.get_parsers_key(context)
assert key == (DEFAULT, DEFAULT)
context = self.get_context(sheerka)
context.add_preprocess("foo", key="some_value")
context.add_to_private_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
key = SheerkaExecute.get_parsers_key(context)
assert key == (BuiltinConcepts.EVAL_QUESTION_REQUESTED, DEFAULT)
context = self.get_context(sheerka)
context.preprocess_parsers = ["foo", "bar", "baz"]
context.add_preprocess("foo", key="some_value")
key = SheerkaExecute.get_parsers_key(context)
assert key == (DEFAULT, 'foo|bar|baz')
context = self.get_context(sheerka)
context.preprocess_parsers = ["foo", "bar", "baz"]
context.add_preprocess("foo", key="some_value")
context.add_to_private_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
key = SheerkaExecute.get_parsers_key(context)
assert key == (BuiltinConcepts.EVAL_QUESTION_REQUESTED, 'foo|bar|baz')
def test_i_use_expression_parser_when_needed(self):
sheerka, context, one, number, isa_q, isa = self.init_concepts(
"one",
"number",
Concept("x is a y ", pre="is_question()").def_var("x").def_var("y"),
Concept("x is a y ").def_var("x").def_var("y"),
)
user_input = get_user_input("one is a number")
res = sheerka.execute(context, [user_input], PARSE_STEPS)
res = self.successful_return_values(res)
assert len(res) == 1
assert res[0].status
assert isinstance(res[0].body.body, Concept)
context = self.get_context(sheerka)
context.add_to_protected_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
res = sheerka.execute(context, [user_input], PARSE_STEPS)
assert len(res) == 1
assert res[0].status
assert isinstance(res[0].body.body, ExprNode)