Added first version of DebugManager. Implemented draft of the rule engine

This commit is contained in:
2020-11-20 13:41:45 +01:00
parent cd066881b4
commit 315f8ea09b
156 changed files with 8388 additions and 2852 deletions
+82 -48
View File
@@ -2,19 +2,20 @@ import ast
import pytest
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
from core.concept import Concept, CB, NotInit
from core.concept import Concept, CB
from core.sheerka.services.SheerkaExecute import ParserInput
from core.tokenizer import Tokenizer
from evaluators.PythonEvaluator import PythonEvaluator, PythonEvalError
from evaluators.PythonEvaluator import PythonEvaluator, PythonEvalError, NamesWithAttributesVisitor
from parsers.BaseNodeParser import SourceCodeNode, SourceCodeWithConceptNode
from parsers.FunctionParser import FunctionParser
from parsers.PythonParser import PythonNode, PythonParser
from parsers.PythonWithConceptsParser import PythonWithConceptsParser
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
def get_concept_name(concept):
return concept.name
def get_obj_name(obj):
return obj.name
def get_source_code_node(source_code, concepts=None):
@@ -36,7 +37,7 @@ def get_source_code_node(source_code, concepts=None):
tokens = list(Tokenizer(source_code, yield_eof=False))
return SourceCodeNode(0, len(tokens), tokens, python_node=python_node)
else:
python_node.concepts = concepts
python_node.objects = concepts
scwcn = SourceCodeWithConceptNode(None, None)
scwcn.python_node = python_node
return scwcn
@@ -62,10 +63,13 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
assert PythonEvaluator().matches(context, ret_val) == expected
@pytest.mark.parametrize("text, expected", [
("1 + 1", 2),
("test()", "I have access to Sheerka !"),
# ("1 + 1", 2),
# ("test()", "I have access to Sheerka !"),
("sheerka.test()", "I have access to Sheerka !"),
("a=10\na", 10),
("Concept('foo')", Concept('foo')),
("BuiltinConcepts.NOP", BuiltinConcepts.NOP),
("in_context(BuiltinConcepts.EVAL_QUESTION_REQUESTED)", False),
])
def test_i_can_eval(self, text, expected):
context = self.get_context()
@@ -76,6 +80,29 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
assert evaluated.status
assert evaluated.value == expected
def test_i_can_eval_isinstance(self):
sheerka, context, foo = self.init_concepts("foo")
parsed = PythonParser().parse(context, ParserInput("isinstance('foo', str)"))
evaluated = PythonEvaluator().eval(context, parsed)
assert evaluated.status
assert evaluated.value
parsed = PythonParser().parse(context, ParserInput("isinstance(foo, 'foo')"))
evaluated = PythonEvaluator().eval(context, parsed)
assert evaluated.status
assert evaluated.value
def test_i_can_eval_context_obj_properties(self):
sheerka, context, foo = self.init_concepts(Concept("foo").def_var("a", "hello world!").auto_init())
context = self.get_context()
parsed = PythonParser().parse(context, ParserInput("a"))
context.obj = foo
evaluated = PythonEvaluator().eval(context, parsed)
assert evaluated.status
assert evaluated.value == "hello world!"
@pytest.mark.parametrize("source_code_node, expected", [
(get_source_code_node("1 + 1"), 2),
(get_source_code_node("one + one", {"one": Concept("one", body="1")}), 2)
@@ -89,14 +116,14 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
assert evaluated.status
assert evaluated.value == expected
def test_i_can_eval_using_context(self):
def test_i_can_eval_a_method_that_requires_the_context(self):
context = self.get_context()
parsed = PythonParser().parse(context, ParserInput("test_using_context('value for param1', 10)"))
parsed = PythonParser().parse(context, ParserInput("test_using_context('value for param')"))
evaluated = PythonEvaluator().eval(context, parsed)
assert evaluated.status
assert evaluated.value.startswith("I have access to Sheerka ! param1='value for param1', param2=10, event=")
assert evaluated.value == "I have access to Sheerka ! param='value for param', event='xxx'."
def test_i_can_eval_using_context_when_self_is_not_sheerka(self):
sheerka, context = self.init_concepts()
@@ -107,21 +134,6 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
assert evaluated.status
assert sheerka.has_key("foo")
@pytest.mark.parametrize("concept", [
Concept("foo"),
Concept("foo", body="2"),
Concept("foo").def_var("prop", "'a'"),
Concept("foo", body="bar")
])
def test_simple_concepts_are_not_for_me(self, concept):
context = self.get_context()
context.sheerka.add_in_cache(Concept("foo"))
parsed = PythonParser().parse(context, ParserInput("foo"))
evaluated = PythonEvaluator().eval(context, parsed)
assert not evaluated.status
assert context.sheerka.isinstance(evaluated.value, BuiltinConcepts.NOT_FOR_ME)
def test_i_can_eval_ast_expression_that_references_concepts(self):
"""
@@ -167,10 +179,10 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
def test_i_can_eval_concept_token(self):
context = self.get_context()
context.sheerka.add_in_cache(Concept("foo", body="2"))
context.add_to_short_term_memory("get_obj_name", get_obj_name)
parsed = PythonParser().parse(context, ParserInput("get_concept_name(c:foo:)"))
parsed = PythonParser().parse(context, ParserInput("get_obj_name(c:foo:)"))
python_evaluator = PythonEvaluator()
python_evaluator.globals["get_concept_name"] = get_concept_name
evaluated = python_evaluator.eval(context, parsed)
assert evaluated.status
@@ -210,7 +222,8 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
evaluated = python_evaluator.eval(context, parsed)
assert evaluated.status
assert sheerka.get_concepts_weights(BuiltinConcepts.PRECEDENCE) == {'1001': 1, '1002': 2}
assert sheerka.get_concepts_weights(BuiltinConcepts.PRECEDENCE) == {'c:__var__0 plus __var__1|1001:': 1,
'c:__var__0 mult __var__1|1002:': 2}
def test_i_can_define_variables(self):
sheerka, context = self.init_concepts()
@@ -261,7 +274,7 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
evaluated = PythonEvaluator().eval(context, parsed)
assert not evaluated.status
assert context.sheerka.isinstance(evaluated.value, BuiltinConcepts.TOO_MANY_ERRORS)
assert context.sheerka.isinstance(evaluated.value, BuiltinConcepts.ERROR)
error0 = evaluated.body.body[0]
assert isinstance(error0, PythonEvalError)
@@ -275,21 +288,6 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
assert error1.error.args[0] == 'can only concatenate str (not "int") to str'
assert error1.concepts == {'foo': 'string'}
def test_i_do_not_include_not_initialized_variables_when_evaluating(self):
sheerka, context, foo = self.init_concepts(
Concept("foo a", pre="a == 'True'").def_var("a", "'True'").def_var("b"))
foo.set_value("b", "'Initialized!'")
context.obj = foo
assert foo.get_value("a") == NotInit
assert foo.get_value("b") == "'Initialized!'"
my_globals = {}
PythonEvaluator().update_globals_with_context(my_globals, context)
assert my_globals == {"self": foo, "b": "'Initialized!'"}
def test_i_can_use_sheerka_locals(self):
sheerka, context = self.init_concepts()
@@ -307,11 +305,47 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
def test_i_can_eval_concept_with_ret(self):
sheerka, context, one, the = self.init_concepts("one", Concept("the a", ret="a").def_var("a"))
ret_val = get_ret_val_from_source_code(context, "test_using_context(one, the one)", {
"the one": self.get_concept_instance(sheerka, the, a="one"),
"one": self.get_concept_instance(sheerka, "one")
ret_val = get_ret_val_from_source_code(context, "test_using_context(the one)", {
"the one": self.get_concept_instance(sheerka, the, a="one")
})
evaluated = PythonEvaluator().eval(context, ret_val)
assert evaluated.status
assert evaluated.value.startswith("I have access to Sheerka ! param1=(1001)one, param2=(1001)one, event=")
assert evaluated.value == "I have access to Sheerka ! param=(1001)one, event='xxx'."
def test_i_can_eval_rules_from_python_parser(self):
sheerka, context = self.init_concepts()
parsed_ret_val = PythonParser().parse(context, ParserInput("r:|1:.id"))
assert parsed_ret_val.status
evaluated = PythonEvaluator().eval(context, parsed_ret_val)
assert evaluated.status
assert evaluated.value == "1"
def test_i_can_eval_rules_from_function_parser(self):
context = self.get_context()
context.add_to_short_term_memory("get_obj_name", get_obj_name)
parsed = FunctionParser().parse(context, ParserInput("get_obj_name(r:|1:)"))
python_evaluator = PythonEvaluator()
evaluated = python_evaluator.eval(context, parsed)
assert evaluated.status
assert evaluated.value == "Print return values"
@pytest.mark.parametrize("text, expected", [
("foo.bar.baz", [["foo", "bar", "baz"]]),
("foo.bar.baz; one.two.three", [["foo", "bar", "baz"]]),
("foo.bar.baz; one.two.three; foo.bar", [["foo", "bar", "baz"], ["foo", "bar"]]),
("one.two.three", []),
("foo", [["foo"]]),
("foo.bar[1].baz", [["foo", "bar", "baz"]]),
("foo[1].bar.baz", [["foo", "bar", "baz"]]),
])
def test_names_with_attributes_visitor(self, text, expected):
ast_ = ast.parse(text, "<src>", mode="exec")
visitor = NamesWithAttributesVisitor()
sequence = visitor.get_sequences(ast_, "foo")
assert sequence == expected