Concepts bodies are now evaluated on demand

This commit is contained in:
2020-02-27 10:48:45 +01:00
parent 7cd94e888f
commit ef31a4807d
25 changed files with 468 additions and 172 deletions
+2
View File
@@ -34,6 +34,7 @@ def test_i_can_push():
concepts={"bar": Concept("bar")})
a.preprocess = set()
a.preprocess.add("preprocess")
a.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
b = a.push()
@@ -49,6 +50,7 @@ def test_i_can_push():
assert b.id == a.id + 1
assert b._tab == a._tab + " "
assert b.preprocess == a.preprocess
assert b.extra_info == [BuiltinConcepts.CONCEPT_EVAL_REQUESTED]
def test_children_i_created_when_i_push():
+42 -42
View File
@@ -21,8 +21,8 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
def test_i_can_evaluate_a_concept_with_simple_body(self, body, expected):
sheerka = self.get_sheerka()
concept = Concept("foo", body=body)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
concept = Concept("foo", body=body).init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == expected
@@ -53,7 +53,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka = self.get_sheerka()
concept = Concept("foo", pre=expr)
concept = Concept("foo", pre=expr).init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
assert evaluated.key == concept.key
@@ -63,7 +63,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
assert evaluated.metadata.where is None
assert evaluated.get_metadata_value(ConceptParts.PRE) == expected
assert evaluated.props == {}
assert evaluated.metadata.is_evaluated
assert not evaluated.metadata.is_evaluated
assert len(evaluated.values) == 0 if expr is None else 1
@pytest.mark.parametrize("expr, expected", [
@@ -80,7 +80,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka = self.get_sheerka()
concept = Concept("foo").def_prop("a", expr)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.metadata.pre is None
@@ -95,7 +95,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("foo")
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.body == "do not resolve"
assert evaluated.metadata.is_evaluated
@@ -105,7 +105,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("foo").def_prop("a")
concept.compiled["a"] = DoNotResolve("do not resolve")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.get_prop("a") == "do not resolve"
assert evaluated.metadata.is_evaluated
@@ -116,7 +116,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept.compiled["a"] = DoNotResolve("do not resolve")
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.body == "do not resolve"
assert evaluated.get_prop("a") == "do not resolve"
@@ -126,7 +126,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka = self.get_sheerka()
concept = Concept("foo", body="a+1").def_prop("a", "10").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == 11
@@ -137,7 +137,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(concept_a)
concept = Concept("foo", body="a").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated == simplec("foo", simplec("a", None))
assert id(evaluated.body) != id(concept_a)
@@ -150,7 +150,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(concept_a)
concept = Concept("foo", body="a")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == simplec("a", 1)
@@ -164,7 +164,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="c", body="b"))
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d, True)
assert evaluated.key == concept_d.key
expected = simplec("c", simplec("b", simplec("a", "a")))
@@ -179,7 +179,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="c", body="b"))
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d, True)
assert evaluated.key == concept_d.key
expected = simplec("c", simplec("b", simplec("a", None)))
@@ -192,7 +192,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept_a = sheerka.add_in_cache(Concept(name="a").init_key())
concept = Concept("foo", body="a").def_prop("a", "a").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
# first prop a is evaluated to concept_a
# then body is evaluated to prop a -> concept_a
@@ -209,7 +209,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept_a = sheerka.add_in_cache(Concept(name="a"))
concept = Concept("foo", body="concept_a").def_prop("concept_a", "a")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == concept_a
@@ -220,7 +220,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="b", body="2"))
concept = Concept("foo", body="propA + propB").def_prop("propA", "a").def_prop("propB", "b")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == 3
@@ -231,7 +231,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("foo").def_prop("a")
concept.compiled["a"] = concept_a
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.get_prop("a") == simplec("a", "a")
@@ -242,7 +242,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("to_eval").def_prop("prop")
concept.compiled["prop"] = [foo, DoNotResolve("1")]
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
props = evaluated.get_prop("prop")
assert len(props) == 2
@@ -257,20 +257,20 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("to_eval").def_prop("prop")
concept.compiled["prop"] = [ReturnValueConcept("who", True, parser_result)]
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.get_prop("prop") == 2
# also works when only one return value
concept = Concept("to_eval").def_prop("prop")
concept.compiled["prop"] = ReturnValueConcept("who", True, parser_result)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.get_prop("prop") == 2
def test_i_can_reference_sheerka(self):
sheerka = self.get_sheerka()
concept = Concept("foo", body="sheerka.test()").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == sheerka.test()
@@ -281,19 +281,19 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
concept = Concept("foo", body="a")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == simplec("a", "concept_a") # this test was already done
# so check this one.
concept = Concept("foo", body="a").def_prop("a", "'property_a'")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == 'property_a'
# or this one.
concept = Concept("foo", body="a").def_prop("a", "b")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == simplec(name="b", body="concept_b")
@@ -303,7 +303,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
concept = Concept("foo", body="a + b").def_prop("a", "'prop_a'").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == 'prop_aconcept_b'
@@ -312,21 +312,21 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="concept_a").def_prop("subProp", "'sub_a'"))
concept = Concept("foo", body="a.props['subProp'].value").def_prop("a", "concept_a")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated == simplec(concept.key, "sub_a")
def test_i_cannot_evaluate_concept_if_property_is_in_error(self):
sheerka = self.get_sheerka()
concept = Concept(name="concept_a").def_prop("subProp", "undef_concept")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
def test_key_is_initialized_by_evaluation(self):
sheerka = self.get_sheerka()
concept = Concept("foo")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.init_key().key
@@ -345,7 +345,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("foo", body="10", where=where_clause).def_prop("a", "20")
sheerka.add_in_cache(concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
if expected:
assert evaluated.key == concept.key
@@ -362,11 +362,11 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(foo_true)
concept = Concept("foo", where="foo_true").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
concept = Concept("foo", where="foo_false")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert sheerka.isinstance(evaluated, BuiltinConcepts.WHERE_CLAUSE_FAILED)
assert evaluated.body == concept
@@ -379,11 +379,11 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(one_str)
sheerka.add_in_cache(one_digit)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_digit)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_digit, True)
assert evaluated.key == one_digit.key
assert evaluated.body == InfiniteRecursionResolved(1)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_str)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_str, True)
assert evaluated.key == one_str.key
assert evaluated.body == InfiniteRecursionResolved(1)
@@ -396,11 +396,11 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(true_str)
sheerka.add_in_cache(true_bool)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_str)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_str, True)
assert evaluated.key == true_str.key
assert evaluated.body == InfiniteRecursionResolved(True)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_bool)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_bool, True)
assert evaluated.key == true_bool.key
assert evaluated.body == InfiniteRecursionResolved(True)
@@ -413,7 +413,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
c4 = sheerka.add_in_cache(Concept("3", body="one"))
for concept in (c1, c2, c3, c4):
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
assert evaluated.key == concept.key
assert evaluated.body == InfiniteRecursionResolved(3)
@@ -425,19 +425,19 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
baz = sheerka.add_in_cache(Concept("baz", body="qux"))
qux = sheerka.add_in_cache(Concept("qux", body="foo"))
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo, True)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
assert evaluated.body == {foo, bar, baz, qux}
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), bar)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), bar, True)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
assert evaluated.body == {foo, bar, baz, qux}
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), baz)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), baz, True)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
assert evaluated.body == {foo, bar, baz, qux}
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), qux)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), qux, True)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
assert evaluated.body == {foo, bar, baz, qux}
@@ -446,7 +446,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
foo = sheerka.add_in_cache(Concept("foo", body="foo"))
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo, True)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
assert evaluated.body == {foo}
@@ -454,7 +454,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka = self.get_sheerka()
one = Concept("1", body="1")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one, True)
assert evaluated.key == one.key
assert evaluated.body == 1
+3 -2
View File
@@ -107,7 +107,7 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
def test_i_can_define_a_group_from_another_group(self):
sheerka, context, foo, bar, group1, group2 = self.init_concepts(
Concept("foo"), Concept("bar"), Concept("group1"), Concept("group2", body="group1"))
"foo", "bar", "group1", Concept("group2", body="group1"))
sheerka.sets_handler.add_concepts_to_set(context, [foo, bar], group1)
@@ -122,7 +122,8 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
Concept("four", body="4"),
Concept("five", body="5"),
Concept("number"),
Concept("sub_number", body="number", where="number < 4")
Concept("sub_number", body="number", where="number < 4"),
create_new=True
)
sheerka.sets_handler.add_concepts_to_set(context, [one, two, three, four, five], number)
@@ -124,6 +124,26 @@ class EvaluatorOnePreEvaluation(OneReturnValueEvaluatorForTestingPurpose):
super().__init__("preEval", [BuiltinConcepts.BEFORE_EVALUATION], 10)
class EvaluatorOneInitializationOnce(OneReturnValueEvaluatorForTestingPurpose):
def __init__(self):
super().__init__("init_once", [BuiltinConcepts.EVALUATION], 10)
self.is_initialized = False
def init_evaluator(self, context, return_values):
self.out_all("init_evaluator", self.name, context, return_values)
self.is_initialized = True
class EvaluatorOneInitializationMultiple(OneReturnValueEvaluatorForTestingPurpose):
def __init__(self):
super().__init__("init_multiple", [BuiltinConcepts.EVALUATION], 10)
self.is_initialized = False
def init_evaluator(self, context, return_values):
self.out_all("init_evaluator", self.name, context, return_values)
# self.is_initialized = True
class EvaluatorOneMultiSteps(OneReturnValueEvaluatorForTestingPurpose):
def __init__(self):
super().__init__("multiStep", [BuiltinConcepts.EVALUATION, BuiltinConcepts.BEFORE_EVALUATION], 10)
@@ -373,3 +393,52 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
'__EVALUATION [1] modifyFoo - matches - target=bar',
'__EVALUATION [1] modifyFoo - matches - target=__EVALUATION'
]
def test_i_can_initialize_evaluator_if_initialize_evaluator_is_defined(self):
sheerka, context, foo, bar, baz = self.init_concepts("foo", "bar", "baz")
sheerka.evaluators = [EvaluatorOneInitializationOnce]
entries = [
self.tretval(sheerka, foo),
self.tretval(sheerka, bar),
self.tretval(sheerka, baz)
]
Out.debug_out = []
sheerka.execute(context, entries, [BuiltinConcepts.EVALUATION])
assert Out.debug_out == [
'__EVALUATION [0] init_once - matches - target=foo',
"__EVALUATION [0] init_once - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
'__EVALUATION [0] init_once - eval - target=foo',
'__EVALUATION [0] init_once - matches - target=bar',
'__EVALUATION [0] init_once - eval - target=bar',
'__EVALUATION [0] init_once - matches - target=baz',
'__EVALUATION [0] init_once - eval - target=baz',
'__EVALUATION [0] init_once - matches - target=__EVALUATION',
'__EVALUATION [0] init_once - eval - target=__EVALUATION'
]
def test_i_can_initialize_evaluators_multiple_times(self):
sheerka, context, foo, bar, baz = self.init_concepts("foo", "bar", "baz")
sheerka.evaluators = [EvaluatorOneInitializationMultiple]
entries = [
self.tretval(sheerka, foo),
self.tretval(sheerka, bar),
self.tretval(sheerka, baz)
]
Out.debug_out = []
sheerka.execute(context, entries, [BuiltinConcepts.EVALUATION])
assert Out.debug_out == [
'__EVALUATION [0] init_multiple - matches - target=foo',
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
'__EVALUATION [0] init_multiple - eval - target=foo',
'__EVALUATION [0] init_multiple - matches - target=bar',
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
'__EVALUATION [0] init_multiple - eval - target=bar',
'__EVALUATION [0] init_multiple - matches - target=baz',
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
'__EVALUATION [0] init_multiple - eval - target=baz',
'__EVALUATION [0] init_multiple - matches - target=__EVALUATION',
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
'__EVALUATION [0] init_multiple - eval - target=__EVALUATION'
]