Added first implementation of concepts ambiguity resolution + Jenkins file test
This commit is contained in:
+45
-11
@@ -1,5 +1,6 @@
|
||||
import inspect
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
|
||||
import core.builtin_helpers
|
||||
import core.utils
|
||||
@@ -22,6 +23,15 @@ BASE_NODE_PARSER_CLASS = "parsers.BaseNodeParser.BaseNodeParser"
|
||||
EXIT_COMMANDS = ("quit", "exit", "bye")
|
||||
|
||||
|
||||
@dataclass
|
||||
class SheerkaMethod:
|
||||
"""
|
||||
Wrapper to sheerka method, to indicate if it's safe to call
|
||||
"""
|
||||
method: object
|
||||
has_side_effect: bool
|
||||
|
||||
|
||||
class Sheerka(Concept):
|
||||
"""
|
||||
Main controller for the project
|
||||
@@ -55,6 +65,7 @@ class Sheerka(Concept):
|
||||
self.log.debug("Starting Sheerka.")
|
||||
|
||||
self.bnp = None # reference to the BaseNodeParser class (to compute first keyword token)
|
||||
self.return_value_concept_id = None
|
||||
|
||||
# a concept can be instantiated
|
||||
# ex: File is a concept, but File('foo.txt') is an instance
|
||||
@@ -84,10 +95,10 @@ class Sheerka(Concept):
|
||||
|
||||
self.save_execution_context = True
|
||||
|
||||
self.methods_with_context = {"test_using_context"}
|
||||
self.methods_with_context = {"test_using_context"} # only the names, the method is defined in sheerka_methods
|
||||
self.sheerka_methods = {
|
||||
"test": self.test,
|
||||
"test_using_context": self.test_using_context
|
||||
"test": SheerkaMethod(self.test, False),
|
||||
"test_using_context": SheerkaMethod(self.test_using_context, False)
|
||||
}
|
||||
self.sheerka_pipeables = {}
|
||||
|
||||
@@ -119,10 +130,11 @@ class Sheerka(Concept):
|
||||
def chicken_and_eggs(self):
|
||||
return self.cache_manager.caches[self.CONCEPTS_GRAMMARS_ENTRY].cache
|
||||
|
||||
def bind_service_method(self, bound_method, as_name=None):
|
||||
def bind_service_method(self, bound_method, has_side_effect, as_name=None):
|
||||
"""
|
||||
Bind service method to sheerka instance for ease of use ?
|
||||
:param bound_method:
|
||||
:param has_side_effect: False if the method is safe
|
||||
:param as_name:
|
||||
:return:
|
||||
"""
|
||||
@@ -132,18 +144,19 @@ class Sheerka(Concept):
|
||||
signature = inspect.signature(bound_method)
|
||||
if len(signature.parameters) > 0 and list(signature.parameters.keys())[0] == "context":
|
||||
self.methods_with_context.add(as_name)
|
||||
self.sheerka_methods[as_name] = bound_method
|
||||
self.sheerka_methods[as_name] = SheerkaMethod(bound_method, has_side_effect)
|
||||
|
||||
setattr(self, as_name, bound_method)
|
||||
|
||||
def add_pipeable(self, func_name, function):
|
||||
def add_pipeable(self, func_name, function, has_side_effect):
|
||||
"""
|
||||
Adds a function that can bu used with pipe '|'
|
||||
:param func_name:
|
||||
:param function:
|
||||
:param has_side_effect:
|
||||
:return:
|
||||
"""
|
||||
self.sheerka_pipeables[func_name] = function
|
||||
self.sheerka_pipeables[func_name] = SheerkaMethod(function, has_side_effect)
|
||||
|
||||
def initialize(self, root_folder: str = None, save_execution_context=True):
|
||||
"""
|
||||
@@ -292,6 +305,10 @@ class Sheerka(Concept):
|
||||
self.init_log.debug(f"'{concept.name}' concept is not found in db. Adding.")
|
||||
self.set_id_if_needed(concept, True)
|
||||
self.cache_manager.add_concept(concept)
|
||||
|
||||
if key == BuiltinConcepts.RETURN_VALUE:
|
||||
self.return_value_concept_id = concept.id
|
||||
|
||||
else:
|
||||
self.init_log.debug(f"Found concept '{from_db}' in db. Updating.")
|
||||
concept.update_from(from_db)
|
||||
@@ -595,6 +612,8 @@ class Sheerka(Concept):
|
||||
:param concept_id:
|
||||
:return:
|
||||
"""
|
||||
if concept_id is None:
|
||||
return False
|
||||
return self.cache_manager.has(self.CONCEPTS_BY_ID_ENTRY, concept_id)
|
||||
|
||||
def has_key(self, concept_key):
|
||||
@@ -652,6 +671,7 @@ class Sheerka(Concept):
|
||||
return self.new_from_template(template, concept_key, **kwargs)
|
||||
|
||||
def new_from_template(self, template, key, **kwargs):
|
||||
# core.utils.my_debug(f"Created {template}, {key=}, {kwargs=}")
|
||||
# manage singleton
|
||||
if template.metadata.is_unique:
|
||||
return template
|
||||
@@ -677,7 +697,7 @@ class Sheerka(Concept):
|
||||
return self.new(BuiltinConcepts.UNKNOWN_PROPERTY, body=k, concept=concept)
|
||||
|
||||
# TODO : add the concept to the list of known concepts (self.instances)
|
||||
concept.metadata.is_evaluated = True # because we have manually set the variables
|
||||
concept.metadata.is_evaluated = True # because we have manually set the variables
|
||||
return concept
|
||||
|
||||
def ret(self, who: str, status: bool, value, message=None, parents=None):
|
||||
@@ -690,13 +710,23 @@ class Sheerka(Concept):
|
||||
:param parents:
|
||||
:return:
|
||||
"""
|
||||
return self.new(
|
||||
BuiltinConcepts.RETURN_VALUE,
|
||||
|
||||
# 1 second saved every twenty seconds in unit tests
|
||||
return ReturnValueConcept(
|
||||
who=who,
|
||||
status=status,
|
||||
value=value,
|
||||
message=message,
|
||||
parents=parents)
|
||||
parents=parents,
|
||||
concept_id=self.return_value_concept_id
|
||||
)
|
||||
# return self.new(
|
||||
# BuiltinConcepts.RETURN_VALUE,
|
||||
# who=who,
|
||||
# status=status,
|
||||
# value=value,
|
||||
# message=message,
|
||||
# parents=parents)
|
||||
|
||||
def objvalue(self, obj, reduce_simple_list=False):
|
||||
if obj is None:
|
||||
@@ -812,6 +842,10 @@ class Sheerka(Concept):
|
||||
if isinstance(obj, ReturnValueConcept):
|
||||
return obj.status
|
||||
|
||||
# other cases ?
|
||||
# ...
|
||||
|
||||
# manage internal errors
|
||||
if isinstance(obj, Concept) and obj.metadata.is_builtin and obj.key in BuiltinErrors:
|
||||
return False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user