Added first version of DebugManager. Implemented draft of the rule engine
This commit is contained in:
+289
-303
@@ -1,9 +1,8 @@
|
||||
from enum import Enum
|
||||
|
||||
from core.concept import Concept, ConceptParts
|
||||
from core.error import ErrorObj
|
||||
|
||||
|
||||
class BuiltinConcepts(Enum):
|
||||
class BuiltinConcepts:
|
||||
"""
|
||||
List of builtin concepts that do no need any specific implementation
|
||||
Please note that the value of the enum is informal. It is not used in the system
|
||||
@@ -13,116 +12,102 @@ class BuiltinConcepts(Enum):
|
||||
|
||||
The values of the enum is not used the code
|
||||
"""
|
||||
SHEERKA = "sheerka"
|
||||
SHEERKA = "__SHEERKA"
|
||||
|
||||
# processing instructions during sheerka.execute() or sheerka.evaluate_concept()
|
||||
# The instruction may alter how the actions work
|
||||
DEBUG = "debug" # activate all debug information
|
||||
EVAL_BODY_REQUESTED = "eval body" # to evaluate the body
|
||||
EVAL_WHERE_REQUESTED = "eval where" # to evaluate the where clause
|
||||
RETURN_BODY_REQUESTED = "return body" # returns the body of the concept instead of the concept itself
|
||||
REDUCE_REQUESTED = "reduce" # remove meaningless error when possible
|
||||
EVAL_UNTIL_SUCCESS_REQUESTED = "eval until success" # PythonEvaluator tries combination until True is found
|
||||
EVAL_QUESTION_REQUESTED = "question" # the user input must be treated as question
|
||||
# The instructions may alter how the actions work
|
||||
DEBUG = "__DEBUG" # activate all debug information
|
||||
EVAL_BODY_REQUESTED = "__EVAL_BODY_REQUESTED" # to evaluate the body
|
||||
EVAL_WHERE_REQUESTED = "__EVAL_WHERE_REQUESTED" # to evaluate the where clause
|
||||
RETURN_BODY_REQUESTED = "__RETURN_BODY_REQUESTED" # returns the body of the concept instead of the concept itself
|
||||
REDUCE_REQUESTED = "__REDUCE_REQUESTED" # remove meaningless error when possible
|
||||
EVAL_UNTIL_SUCCESS_REQUESTED = "__EVAL_UNTIL_SUCCESS_REQUESTED" # PythonEvaluator tries combination until True is found
|
||||
EVAL_QUESTION_REQUESTED = "__EVAL_QUESTION_REQUESTED" # the user input must be treated as question
|
||||
|
||||
# possible actions during sheerka.execute()
|
||||
INIT_SHEERKA = "init sheerka" #
|
||||
PROCESS_INPUT = "process input" # Processing user input or other input
|
||||
PROCESSING = "processing input" # Processing user input or other input
|
||||
BEFORE_PARSING = "before parsing" # activated before evaluation by the parsers
|
||||
PARSING = "parsing" # activated during the parsing. It contains the text to parse
|
||||
AFTER_PARSING = "after parsing" # after parsing
|
||||
BEFORE_EVALUATION = "before evaluation" # before evaluation
|
||||
EVALUATION = "evaluation" # activated when the parsing process seems to be finished
|
||||
AFTER_EVALUATION = "after evaluation" # activated when the parsing process seems to be finished
|
||||
BEFORE_RENDERING = "before rendering" # activate before the output is rendered
|
||||
RENDERING = "rendering" # rendering the response from sheerka
|
||||
AFTER_RENDERING = "after rendering" # rendering the response from sheerka
|
||||
EVALUATE_SOURCE = "evaluate source" #
|
||||
EVALUATE_CONCEPT = "evaluate concept" # a concept will be evaluated
|
||||
EVALUATING_CONCEPT = "evaluating concept" # a concept will be evaluated
|
||||
EVALUATING_ATTRIBUTE = "evaluating concept attribute" #
|
||||
VALIDATE_CONCEPT = "validate concept"
|
||||
VALIDATING_CONCEPT = "validating concept"
|
||||
INIT_COMPILED = "initializing concept compiled"
|
||||
INIT_BNF = "initialize bnf"
|
||||
MANAGE_INFINITE_RECURSION = "manage infinite recursion"
|
||||
PARSE_CODE = "execute source code"
|
||||
EXEC_CODE = "execute source code" # to use when executing Python or other language compiled code
|
||||
TESTING = "testing"
|
||||
# possible actions during sheerka.execute() or sheerka.evaluate_rules()
|
||||
INIT_SHEERKA = "__INIT_SHEERKA" #
|
||||
PROCESS_INPUT = "__PROCESS_INPUT" # Processing user input or other input
|
||||
PROCESSING = "__PROCESSING" # Processing user input or other input
|
||||
BEFORE_PARSING = "__BEFORE_PARSING" # activated before evaluation by the parsers
|
||||
PARSING = "__PARSING" # activated during the parsing. It contains the text to parse
|
||||
AFTER_PARSING = "__AFTER_PARSING" # after parsing
|
||||
BEFORE_EVALUATION = "__BEFORE_EVALUATION" # before evaluation
|
||||
EVALUATION = "__EVALUATION" # activated when the parsing process seems to be finished
|
||||
AFTER_EVALUATION = "__AFTER_EVALUATION" # activated when the parsing process seems to be finished
|
||||
BEFORE_RENDERING = "__BEFORE_RENDERING" # activate before the output is rendered
|
||||
RENDERING = "__RENDERING" # rendering the response from sheerka
|
||||
AFTER_RENDERING = "__AFTER_RENDERING" # rendering the response from sheerka
|
||||
EVALUATE_SOURCE = "__EVALUATE_SOURCE" #
|
||||
EVALUATE_CONCEPT = "__EVALUATE_CONCEPT" # a concept will be evaluated
|
||||
EVALUATING_CONCEPT = "__EVALUATING_CONCEPT" # a concept will be evaluated
|
||||
EVALUATING_ATTRIBUTE = "__EVALUATING_ATTRIBUTE" #
|
||||
VALIDATE_CONCEPT = "__VALIDATE_CONCEPT"
|
||||
VALIDATING_CONCEPT = "__VALIDATING_CONCEPT"
|
||||
INIT_COMPILED = "__INIT_COMPILED"
|
||||
INIT_BNF = "__INIT_BNF"
|
||||
MANAGE_INFINITE_RECURSION = "__MANAGE_INFINITE_RECURSION"
|
||||
PARSE_CODE = "__PARSE_CODE"
|
||||
EXEC_CODE = "__EXEC_CODE" # to use when executing Python or other language compiled code
|
||||
TESTING = "__TESTING"
|
||||
EVALUATOR_PRE_PROCESS = "__EVALUATOR_PRE_PROCESS" # used modify / tweak behaviour of evaluators
|
||||
EVALUATING_RULES = "__EVALUATING_RULES"
|
||||
|
||||
# builtin attributes
|
||||
ISA = "is a" # when a concept is an instance of another one
|
||||
HASA = "has a" # when a concept has/owns another concept
|
||||
AUTO_EVAL = "auto eval" # when the concept must be auto evaluated
|
||||
ISA = "__ISA" # when a concept is an instance of another one
|
||||
HASA = "__HASA" # when a concept has/owns another concept
|
||||
AUTO_EVAL = "__AUTO_EVAL" # when the concept must be auto evaluated
|
||||
|
||||
# object
|
||||
USER_INPUT = "user input concept" # represent an input from an user
|
||||
SUCCESS = "success concept"
|
||||
ERROR = "error concept"
|
||||
UNKNOWN_CONCEPT = "unknown concept" # the request concept is not recognized
|
||||
CANNOT_RESOLVE_CONCEPT = "cannot resolve concept" # when too many concepts with the same name
|
||||
RETURN_VALUE = "return value concept" # a value is returned
|
||||
CONCEPT_TOO_LONG = "concept too long concept" # concept cannot be processed by exactConcept parser
|
||||
NEW_CONCEPT = "new concept" # when a new concept is added
|
||||
UNKNOWN_PROPERTY = "unknown property" # when requesting for a unknown property
|
||||
PARSER_RESULT = "parser result"
|
||||
TOO_MANY_SUCCESS = "too many success" # when expecting a limited number of successful return value
|
||||
TOO_MANY_ERRORS = "too many errors" # when expecting a limited number of successful return value
|
||||
ONLY_SUCCESSFUL = "only successful" # filter the result, only keep successful ones
|
||||
MULTIPLE_ERRORS = "multiple errors" # filter the result, only keep evaluator in error
|
||||
NOT_FOR_ME = "not for me" # a parser recognize that the entry is not meant for it
|
||||
IS_EMPTY = "is empty" # when a set is empty
|
||||
NO_RESULT = "no result" # no return value returned
|
||||
INVALID_RETURN_VALUE = "invalid return value" # the return value of an evaluator is not correct
|
||||
CONCEPT_ALREADY_DEFINED = "concept already defined" # when you try to add the same object twice (a concept or whatever)
|
||||
PROPERTY_ALREADY_DEFINED = "property already defined" # When you try to add the same element in a property
|
||||
NOP = "no operation" # no operation concept. Does nothing
|
||||
CONCEPT_EVAL_ERROR = "concept evaluation error" # cannot evaluate a property or metadata of a concept
|
||||
ENUMERATION = "enum" # represents a list or a set
|
||||
LIST = "list" # represents a list
|
||||
FILTERED = "filtered" # represents the result of a filtering
|
||||
CONCEPT_ALREADY_IN_SET = "concept already in set"
|
||||
EVALUATOR_PRE_PROCESS = "evaluator pre process" # used modify / tweak behaviour of evaluators
|
||||
NOT_A_SET = "not a set" # the concept has no entry in sets
|
||||
CONDITION_FAILED = "where clause failed" # failed to validate where clause during evaluation
|
||||
CHICKEN_AND_EGG = "chicken and egg" # infinite recursion when declaring concept
|
||||
EXPLANATION = "explanation"
|
||||
PRECEDENCE = "precedence" # use to set priority among concepts when parsing
|
||||
ASSOCIATIVITY = "associativity" # use to set priority among concepts when parsing
|
||||
NOT_INITIALIZED = "not initialized"
|
||||
NOT_FOUND = "not found" # when the wanted resource is not found
|
||||
FORMAT_INSTRUCTIONS = "format instructions" # to express how to print the concept
|
||||
NOT_IMPLEMENTED = "not implemented" # instead of raise an error
|
||||
PYTHON_SECURITY_ERROR = "security error" # when trying to execute statement when only expression is allowed
|
||||
INVALID_LESSER_OPERATION = "Invalid lesser operation"
|
||||
INVALID_GREATEST_OPERATION = "Invalid greatest operation"
|
||||
USER_INPUT = "__USER_INPUT" # represent an input from an user
|
||||
SUCCESS = "__SUCCESS"
|
||||
ERROR = "__ERROR"
|
||||
UNKNOWN_CONCEPT = "__UNKNOWN_CONCEPT" # the request concept is not recognized
|
||||
CANNOT_RESOLVE_CONCEPT = "__CANNOT_RESOLVE_CONCEPT" # when too many concepts with the same name
|
||||
RETURN_VALUE = "__RETURN_VALUE" # a value is returned
|
||||
CONCEPT_TOO_LONG = "__CONCEPT_TOO_LONG" # concept cannot be processed by exactConcept parser
|
||||
NEW_CONCEPT = "__NEW_CONCEPT" # when a new concept is added
|
||||
UNKNOWN_PROPERTY = "__UNKNOWN_PROPERTY" # when requesting for a unknown property
|
||||
PARSER_RESULT = "__PARSER_RESULT"
|
||||
TOO_MANY_SUCCESS = "__TOO_MANY_SUCCESS" # when expecting a limited number of successful return value
|
||||
TOO_MANY_ERRORS = "__TOO_MANY_ERRORS" # when expecting a limited number of successful return value
|
||||
ONLY_SUCCESSFUL = "__ONLY_SUCCESSFUL" # filter the result, only keep successful ones
|
||||
MULTIPLE_ERRORS = "__MULTIPLE_ERRORS" # filter the result, only keep evaluator in error
|
||||
NOT_FOR_ME = "__NOT_FOR_ME" # a parser recognize that the entry is not meant for it
|
||||
IS_EMPTY = "__IS_EMPTY" # when a set is empty
|
||||
NO_RESULT = "__NO_RESULT" # no return value returned
|
||||
INVALID_RETURN_VALUE = "__INVALID_RETURN_VALUE" # the return value of an evaluator is not correct
|
||||
CONCEPT_ALREADY_DEFINED = "__CONCEPT_ALREADY_DEFINED" # when you try to add the same object twice (a concept or whatever)
|
||||
PROPERTY_ALREADY_DEFINED = "__PROPERTY_ALREADY_DEFINED" # When you try to add the same element in a property
|
||||
NOP = "__NOP" # no operation concept. Does nothing
|
||||
CONCEPT_EVAL_ERROR = "__CONCEPT_EVAL_ERROR" # cannot evaluate a property or metadata of a concept
|
||||
ENUMERATION = "__ENUMERATION" # represents a list or a set
|
||||
LIST = "__LIST" # represents a list
|
||||
FILTERED = "__FILTERED" # represents the result of a filtering
|
||||
CONCEPT_ALREADY_IN_SET = "__CONCEPT_ALREADY_IN_SET"
|
||||
NOT_A_SET = "__NOT_A_SET" # the concept has no entry in sets
|
||||
CONDITION_FAILED = "__CONDITION_FAILED" # failed to validate where clause during evaluation
|
||||
CHICKEN_AND_EGG = "__CHICKEN_AND_EGG" # infinite recursion when declaring concept
|
||||
EXPLANATION = "__EXPLANATION"
|
||||
PRECEDENCE = "__PRECEDENCE" # use to set priority among concepts when parsing
|
||||
ASSOCIATIVITY = "__ASSOCIATIVITY" # use to set priority among concepts when parsing
|
||||
NOT_FOUND = "__NOT_FOUND" # when the wanted resource is not found
|
||||
FORMAT_INSTRUCTIONS = "__FORMAT_INSTRUCTIONS" # to express how to print the concept
|
||||
NOT_IMPLEMENTED = "__NOT_IMPLEMENTED" # instead of raise an error
|
||||
PYTHON_SECURITY_ERROR = "__PYTHON_SECURITY_ERROR" # when trying to execute statement when only expression is allowed
|
||||
INVALID_LESSER_OPERATION = "__INVALID_LESSER_OPERATION"
|
||||
INVALID_GREATEST_OPERATION = "__INVALID_GREATEST_OPERATION"
|
||||
NEW_RULE = "__NEW_RULE"
|
||||
UNKNOWN_RULE = "__UNKNOWN_RULE"
|
||||
|
||||
NODE = "node"
|
||||
GENERIC_NODE = "generic node"
|
||||
IDENTIFIER_NODE = "identifier node"
|
||||
NODE = "__NODE"
|
||||
GENERIC_NODE = "__GENERIC_NODE"
|
||||
IDENTIFIER_NODE = "__IDENTIFIER_NODE"
|
||||
|
||||
def __repr__(self):
|
||||
return "__" + self.name
|
||||
# formatting
|
||||
TO_LIST = "__TO_LIST"
|
||||
|
||||
def __str__(self):
|
||||
return "__" + self.name
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if isinstance(other, str):
|
||||
return str(self) == other
|
||||
|
||||
if not isinstance(other, BuiltinConcepts):
|
||||
return False
|
||||
|
||||
return self.value == other.value
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.value)
|
||||
|
||||
AllBuiltinConcepts = [v for n, v in BuiltinConcepts.__dict__.items() if not n.startswith("__")]
|
||||
|
||||
BuiltinUnique = [
|
||||
BuiltinConcepts.EVAL_BODY_REQUESTED,
|
||||
@@ -163,7 +148,7 @@ BuiltinUnique = [
|
||||
BuiltinConcepts.INVALID_GREATEST_OPERATION,
|
||||
]
|
||||
|
||||
BuiltinErrors = [str(e) for e in {
|
||||
BuiltinErrors = [
|
||||
BuiltinConcepts.ERROR,
|
||||
BuiltinConcepts.UNKNOWN_CONCEPT,
|
||||
BuiltinConcepts.CANNOT_RESOLVE_CONCEPT,
|
||||
@@ -180,12 +165,18 @@ BuiltinErrors = [str(e) for e in {
|
||||
BuiltinConcepts.NOT_A_SET,
|
||||
BuiltinConcepts.CONDITION_FAILED,
|
||||
BuiltinConcepts.CHICKEN_AND_EGG,
|
||||
BuiltinConcepts.NOT_INITIALIZED,
|
||||
BuiltinConcepts.NOT_FOUND,
|
||||
BuiltinConcepts.INVALID_LESSER_OPERATION,
|
||||
BuiltinConcepts.INVALID_GREATEST_OPERATION,
|
||||
# DO NOT PUT NOT_INITIALIZED. It's not an error
|
||||
}]
|
||||
]
|
||||
|
||||
BuiltinContainers = [
|
||||
BuiltinConcepts.PARSER_RESULT,
|
||||
BuiltinConcepts.ONLY_SUCCESSFUL,
|
||||
BuiltinConcepts.FILTERED,
|
||||
BuiltinConcepts.EXPLANATION,
|
||||
BuiltinConcepts.TO_LIST,
|
||||
]
|
||||
|
||||
"""
|
||||
Some concepts have a specific implementation
|
||||
@@ -194,39 +185,51 @@ It's mainly to ease the usage
|
||||
|
||||
|
||||
class UserInputConcept(Concept):
|
||||
ALL_ATTRIBUTES = ["text", "user_name"]
|
||||
|
||||
def __init__(self, text=None, user_name=None):
|
||||
super().__init__(BuiltinConcepts.USER_INPUT, True, False, BuiltinConcepts.USER_INPUT)
|
||||
self.set_value(ConceptParts.BODY, text)
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.USER_INPUT,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.USER_INPUT, bound_body="text")
|
||||
self.set_value("text", text)
|
||||
self.set_value("user_name", user_name)
|
||||
self.metadata.is_evaluated = True
|
||||
|
||||
@property
|
||||
def text(self):
|
||||
return self.body
|
||||
|
||||
@property
|
||||
def user_name(self):
|
||||
return self.get_value("user_name")
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
return f"({self.id}){self.name}: '{self.body}'"
|
||||
|
||||
|
||||
class ErrorConcept(Concept):
|
||||
def __init__(self, error=None):
|
||||
super().__init__(BuiltinConcepts.ERROR, True, False, BuiltinConcepts.ERROR)
|
||||
self.set_value(ConceptParts.BODY, error)
|
||||
self.metadata.is_evaluated = True
|
||||
class ErrorConcept(Concept, ErrorObj):
|
||||
ALL_ATTRIBUTES = ["error"]
|
||||
|
||||
def __init__(self, error=None, concept_id=None):
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.ERROR,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.ERROR,
|
||||
id=concept_id,
|
||||
bound_body="error")
|
||||
self.set_value("error", error)
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
return f"({self.id}){self.name}: {self.body}"
|
||||
|
||||
|
||||
class UnknownConcept(Concept):
|
||||
def __init__(self, metadata=None):
|
||||
super().__init__(BuiltinConcepts.UNKNOWN_CONCEPT, True, False, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
self.set_value(ConceptParts.BODY, metadata)
|
||||
self.metadata.is_evaluated = True
|
||||
class UnknownConcept(Concept, ErrorObj):
|
||||
ALL_ATTRIBUTES = ["concept_ref"]
|
||||
|
||||
def __init__(self, concept_ref=None):
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.UNKNOWN_CONCEPT,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.UNKNOWN_CONCEPT, bound_body="concept_ref")
|
||||
self.set_value("concept_ref", concept_ref)
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
return f"({self.id}){self.name}: {self.body}"
|
||||
@@ -238,67 +241,36 @@ class ReturnValueConcept(Concept):
|
||||
It's the main input for the evaluators
|
||||
"""
|
||||
|
||||
def __init__(self, who=None, status=None, value=None, message=None, parents=None, concept_id=None):
|
||||
super().__init__(BuiltinConcepts.RETURN_VALUE, True, False, BuiltinConcepts.RETURN_VALUE)
|
||||
self.set_value(ConceptParts.BODY, value)
|
||||
ALL_ATTRIBUTES = ["who", "status", "value", "parents", "message"]
|
||||
|
||||
def __init__(self, who=None, status=None, value=None, parents=None, message=None, concept_id=None):
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.RETURN_VALUE,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.RETURN_VALUE,
|
||||
id=concept_id,
|
||||
bound_body="value")
|
||||
self.set_value("who", who)
|
||||
self.set_value("status", status)
|
||||
self.set_value("message", message)
|
||||
self.set_value("value", value)
|
||||
self.set_value("parents", parents)
|
||||
self.metadata.is_evaluated = True
|
||||
self.metadata.id = concept_id
|
||||
|
||||
@property
|
||||
def who(self):
|
||||
return self.get_value("who")
|
||||
|
||||
@who.setter
|
||||
def who(self, value):
|
||||
self.set_value("who", value)
|
||||
|
||||
@property
|
||||
def status(self):
|
||||
return self.get_value("status")
|
||||
|
||||
@status.setter
|
||||
def status(self, value):
|
||||
self.set_value("status", value)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self.body
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
self.set_value(ConceptParts.BODY, value)
|
||||
|
||||
@property
|
||||
def message(self):
|
||||
return self.get_value("message")
|
||||
|
||||
@message.setter
|
||||
def message(self, value):
|
||||
self.set_value("message", value)
|
||||
|
||||
@property
|
||||
def parents(self):
|
||||
return self.get_value("parents")
|
||||
|
||||
@parents.setter
|
||||
def parents(self, value):
|
||||
self.set_value("parents", value)
|
||||
self.set_value("message", message)
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
return f"ReturnValue(who={self.who}, status={self.status}, value={self.value}, message={self.message})"
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if not isinstance(other, ReturnValueConcept):
|
||||
return False
|
||||
|
||||
return self.who == other.who and \
|
||||
self.status == other.status and \
|
||||
self.value == other.value and \
|
||||
self.message == other.message
|
||||
self.value == other.value
|
||||
|
||||
def __hash__(self):
|
||||
if hasattr(self.value, "__iter__") and not isinstance(self.value, str):
|
||||
@@ -309,47 +281,52 @@ class ReturnValueConcept(Concept):
|
||||
return hash((self.who, self.status, value_hash))
|
||||
|
||||
|
||||
class UnknownPropertyConcept(Concept):
|
||||
class UnknownPropertyConcept(Concept, ErrorObj):
|
||||
"""
|
||||
This error is raised when, during sheerka.new(), an unknown property is asked
|
||||
"""
|
||||
ALL_ATTRIBUTES = ["property_name", "concept"]
|
||||
|
||||
def __init__(self, property_name=None, concept=None):
|
||||
super().__init__(BuiltinConcepts.UNKNOWN_PROPERTY, True, False, BuiltinConcepts.UNKNOWN_PROPERTY)
|
||||
self.set_value(ConceptParts.BODY, property_name)
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.UNKNOWN_PROPERTY,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.UNKNOWN_PROPERTY,
|
||||
bound_body="property_name")
|
||||
self.set_value("property_name", property_name)
|
||||
self.set_value("concept", concept)
|
||||
self.metadata.is_evaluated = True
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
return f"UnknownProperty(property={self.property_name}, concept={self.concept})"
|
||||
|
||||
@property
|
||||
def concept(self):
|
||||
return self.get_value("concept")
|
||||
|
||||
@property
|
||||
def property_name(self):
|
||||
return self.body
|
||||
|
||||
|
||||
class ParserResultConcept(Concept):
|
||||
"""
|
||||
Result of a parsing
|
||||
"""
|
||||
|
||||
def __init__(self, parser=None, source=None, tokens=None, value=None, try_parsed=None):
|
||||
super().__init__(BuiltinConcepts.PARSER_RESULT, True, False, BuiltinConcepts.PARSER_RESULT)
|
||||
self.set_value(ConceptParts.BODY, value)
|
||||
ALL_ATTRIBUTES = ["parser", "source", "tokens", "value", "try_parsed"]
|
||||
|
||||
def __init__(self, parser=None, source=None, tokens=None, value=None, try_parsed=None, concept_id=None):
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.PARSER_RESULT,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.PARSER_RESULT,
|
||||
id=concept_id,
|
||||
bound_body="value")
|
||||
self.set_value("parser", parser)
|
||||
self.set_value("source", source)
|
||||
self.set_value("tokens", tokens)
|
||||
self.set_value("try_parsed", try_parsed) # in case of error, what was found before the error
|
||||
self.metadata.is_evaluated = True
|
||||
self.set_value("value", value)
|
||||
self.set_value("try_parsed", try_parsed)
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
text = f"ParserResult(parser={self.get_value('parser')}"
|
||||
source = self.get_value('source')
|
||||
text += f", source='{source}')" if source else f", body='{self.body}')"
|
||||
text = f"ParserResult(parser={self.parser}"
|
||||
text += f", source='{self.source}')" if self.source else f", body='{self.value}')"
|
||||
return text
|
||||
|
||||
def __eq__(self, other):
|
||||
@@ -361,27 +338,10 @@ class ParserResultConcept(Concept):
|
||||
|
||||
return self.source == other.source and \
|
||||
self_parser_name == other_parser_name and \
|
||||
self.body == other.body and \
|
||||
self.try_parsed == other.try_parsed
|
||||
self.value == other.value
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.metadata.name)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self.body
|
||||
|
||||
@property
|
||||
def try_parsed(self):
|
||||
return self.get_value("try_parsed")
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
return self.get_value("source")
|
||||
|
||||
@property
|
||||
def parser(self):
|
||||
return self.get_value("parser")
|
||||
return hash(self._metadata.name)
|
||||
|
||||
@staticmethod
|
||||
def get_parser_name(parser):
|
||||
@@ -389,191 +349,217 @@ class ParserResultConcept(Concept):
|
||||
return parser.name if isinstance(parser, BaseParser) else str(parser)
|
||||
|
||||
|
||||
class InvalidReturnValueConcept(Concept):
|
||||
class InvalidReturnValueConcept(Concept, ErrorObj):
|
||||
"""
|
||||
Error returned when an evaluator is not correctly coded
|
||||
The accepted return value are
|
||||
ReturnValueConcept, list of ReturnValueConcept or None
|
||||
"""
|
||||
|
||||
ALL_ATTRIBUTES = ["return_value", "evaluator"]
|
||||
|
||||
def __init__(self, return_value=None, evaluator=None):
|
||||
super().__init__(
|
||||
BuiltinConcepts.INVALID_RETURN_VALUE,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.INVALID_RETURN_VALUE)
|
||||
self.set_value(ConceptParts.BODY, return_value)
|
||||
BuiltinConcepts.INVALID_RETURN_VALUE,
|
||||
bound_body="return_value")
|
||||
self.set_value("return_value", return_value)
|
||||
self.set_value("evaluator", evaluator)
|
||||
self.metadata.is_evaluated = True
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
|
||||
class ConceptEvalError(Concept):
|
||||
class ConceptEvalError(Concept, ErrorObj):
|
||||
ALL_ATTRIBUTES = ["error", "concept", "property_name"]
|
||||
|
||||
def __init__(self, error=None, concept=None, property_name=None):
|
||||
super().__init__(BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
self.set_value(ConceptParts.BODY, error)
|
||||
BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
||||
bound_body="error")
|
||||
self.set_value("error", error)
|
||||
self.set_value("concept", concept)
|
||||
self.set_value("property_name", property_name)
|
||||
self.metadata.is_evaluated = True
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
return f"ConceptEvalError(error={self.error}, concept={self.concept}, property={self.property_name})"
|
||||
|
||||
@property
|
||||
def error(self):
|
||||
return self.body
|
||||
|
||||
@property
|
||||
def concept(self):
|
||||
return self.get_value("concept")
|
||||
|
||||
@property
|
||||
def property_name(self):
|
||||
return self.get_value("property_name")
|
||||
|
||||
|
||||
class EnumerationConcept(Concept):
|
||||
def __init__(self, iteration=None):
|
||||
super().__init__(BuiltinConcepts.ENUMERATION, True, False, BuiltinConcepts.ENUMERATION)
|
||||
self.set_value(ConceptParts.BODY, iteration)
|
||||
self.metadata.is_evaluated = True
|
||||
|
||||
|
||||
class ListConcept(Concept):
|
||||
ALL_ATTRIBUTES = ["items"]
|
||||
|
||||
def __init__(self, items=None):
|
||||
super().__init__(BuiltinConcepts.LIST, True, False, BuiltinConcepts.LIST)
|
||||
self.set_value(ConceptParts.BODY, items or [])
|
||||
self.metadata.is_evaluated = True
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.LIST,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.LIST,
|
||||
bound_body="items")
|
||||
self.set_value("items", items or [])
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def append(self, obj):
|
||||
self.body.append(obj)
|
||||
|
||||
|
||||
class FilteredConcept(Concept):
|
||||
ALL_ATTRIBUTES = ["filtered", "iterable", "predicate"]
|
||||
|
||||
def __init__(self, filtered=None, iterable=None, predicate=None):
|
||||
super().__init__(BuiltinConcepts.FILTERED, True, False, BuiltinConcepts.FILTERED)
|
||||
self.set_value(ConceptParts.BODY, filtered)
|
||||
self.set_value("iterable", iterable)
|
||||
self.set_value("predicate", predicate)
|
||||
self.metadata.is_evaluated = True
|
||||
|
||||
|
||||
class ConceptAlreadyInSet(Concept):
|
||||
def __init__(self, concept=None, concept_set=None):
|
||||
super().__init__(BuiltinConcepts.CONCEPT_ALREADY_IN_SET,
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.FILTERED,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.CONCEPT_ALREADY_IN_SET)
|
||||
self.set_value(ConceptParts.BODY, concept)
|
||||
BuiltinConcepts.FILTERED,
|
||||
bound_body="filtered")
|
||||
self.set_value("filtered", filtered)
|
||||
self.set_value("iterable", iterable)
|
||||
self.set_value("predicate", predicate)
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
|
||||
class ConceptAlreadyInSet(Concept, ErrorObj):
|
||||
ALL_ATTRIBUTES = ["concept", "concept_set"]
|
||||
|
||||
def __init__(self, concept=None, concept_set=None):
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.CONCEPT_ALREADY_IN_SET,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.CONCEPT_ALREADY_IN_SET,
|
||||
bound_body="concept")
|
||||
self.set_value("concept", concept)
|
||||
self.set_value("concept_set", concept_set)
|
||||
self.metadata.is_evaluated = True
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
return f"ConceptAlreadyInSet(concept={self.concept}, concept_set={self.concept_set})"
|
||||
|
||||
@property
|
||||
def concept(self):
|
||||
return self.body
|
||||
|
||||
@property
|
||||
def concept_set(self):
|
||||
return self.get_value("concept_set")
|
||||
class PropertyAlreadyDefined(Concept, ErrorObj):
|
||||
ALL_ATTRIBUTES = ["property_name", "property_value", "concept"]
|
||||
|
||||
|
||||
class PropertyAlreadyDefined(Concept):
|
||||
def __init__(self, property_name=None, property_value=None, concept=None):
|
||||
super().__init__(BuiltinConcepts.PROPERTY_ALREADY_DEFINED,
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.PROPERTY_ALREADY_DEFINED,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.PROPERTY_ALREADY_DEFINED)
|
||||
self.set_value(ConceptParts.BODY, property_name)
|
||||
BuiltinConcepts.PROPERTY_ALREADY_DEFINED,
|
||||
bound_body="property_name")
|
||||
self.set_value("property_name", property_name)
|
||||
self.set_value("property_value", property_value)
|
||||
self.set_value("concept", concept)
|
||||
self.metadata.is_evaluated = True
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
return f"PropertyAlreadyDefined(property={self.property_name}, value={self.property_value}, concept={self.concept})"
|
||||
|
||||
@property
|
||||
def property_name(self):
|
||||
return self.body
|
||||
|
||||
@property
|
||||
def property_value(self):
|
||||
return self.get_value("property_value")
|
||||
class ConditionFailed(Concept, ErrorObj):
|
||||
ALL_ATTRIBUTES = ["condition", "concept", "prop", "reason"]
|
||||
|
||||
@property
|
||||
def concept(self):
|
||||
return self.get_value("concept")
|
||||
|
||||
|
||||
class ConditionFailed(Concept):
|
||||
def __init__(self, condition=None, concept=None, prop=None):
|
||||
super().__init__(BuiltinConcepts.CONDITION_FAILED,
|
||||
def __init__(self, condition=None, concept=None, prop=None, reason=None):
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.CONDITION_FAILED,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.CONDITION_FAILED)
|
||||
self.set_value(ConceptParts.BODY, condition)
|
||||
BuiltinConcepts.CONDITION_FAILED,
|
||||
bound_body="condition")
|
||||
self.set_value("condition", condition)
|
||||
self.set_value("concept", concept)
|
||||
self.set_value("prop", prop)
|
||||
self.metadata.is_evaluated = True
|
||||
self.set_value("reason", reason)
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
return f"ConditionFailed(condition='{self.body}', concept='{self.concept}', prop='{self.prop}')"
|
||||
|
||||
|
||||
class NotForMeConcept(Concept):
|
||||
class NotForMeConcept(Concept): # Not considered as an error ?
|
||||
ALL_ATTRIBUTES = ["source", "reason"]
|
||||
|
||||
def __init__(self, source=None, reason=None):
|
||||
super().__init__(BuiltinConcepts.NOT_FOR_ME,
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.NOT_FOR_ME,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.NOT_FOR_ME)
|
||||
self.set_value(ConceptParts.BODY, source)
|
||||
BuiltinConcepts.NOT_FOR_ME,
|
||||
bound_body="source")
|
||||
self.set_value("source", source)
|
||||
self.set_value("reason", reason)
|
||||
self.metadata.is_evaluated = True
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
def __repr__(self):
|
||||
return f"NotForMeConcept(source={self.body}, reason={self.get_value('reason')})"
|
||||
|
||||
|
||||
class ExplanationConcept(Concept):
|
||||
ALL_ATTRIBUTES = ["digest", "command", "title", "instructions", "execution_result"]
|
||||
|
||||
def __init__(self, digest=None, command=None, title=None, instructions=None, execution_result=None):
|
||||
super().__init__(BuiltinConcepts.EXPLANATION,
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.EXPLANATION,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.EXPLANATION)
|
||||
BuiltinConcepts.EXPLANATION,
|
||||
bound_body="execution_result")
|
||||
self.set_value("digest", digest) # event digest
|
||||
self.set_value("command", command) # explain command parameters
|
||||
self.set_value("title", title) # a title to the explanation
|
||||
self.set_value("instructions", instructions) # instructions for SheerkaPrint
|
||||
self.set_value(ConceptParts.BODY, execution_result) # list of results
|
||||
self.metadata.is_evaluated = True
|
||||
self.set_value("execution_result", execution_result) # list of results
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
|
||||
class PythonSecurityError(Concept):
|
||||
class PythonSecurityError(Concept, ErrorObj):
|
||||
ALL_ATTRIBUTES = ["prop", "source_code", "source", "line", "column"]
|
||||
|
||||
def __init__(self, prop=None, source_code=None, source=None, line=None, column=None):
|
||||
super().__init__(BuiltinConcepts.PYTHON_SECURITY_ERROR,
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.PYTHON_SECURITY_ERROR,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.PYTHON_SECURITY_ERROR)
|
||||
BuiltinConcepts.PYTHON_SECURITY_ERROR,
|
||||
bound_body="source_code")
|
||||
|
||||
self.set_value("prop", prop) # property or variable that was evaluated
|
||||
self.set_value("source", source) # origin of the source code (eg. file name)
|
||||
self.set_value("line", line) # line number
|
||||
self.set_value("column", column) # column number
|
||||
self.set_value(ConceptParts.BODY, source_code) # code being executed
|
||||
self.metadata.is_evaluated = True
|
||||
self.set_value("source_code", source_code) # code being executed
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
|
||||
class NotFound(Concept):
|
||||
class NotFound(Concept, ErrorObj):
|
||||
ALL_ATTRIBUTES = []
|
||||
|
||||
def __init__(self, body=None):
|
||||
super().__init__(BuiltinConcepts.NOT_FOUND,
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.NOT_FOUND,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.NOT_FOUND)
|
||||
self.set_value(ConceptParts.BODY, body)
|
||||
|
||||
def __repr__(self):
|
||||
return f"({self.metadata.id}){self.metadata.name}, body={self.get_value(ConceptParts.BODY)}"
|
||||
return f"({self._metadata.id}){self._metadata.name}, body={self.get_value(ConceptParts.BODY)}"
|
||||
|
||||
|
||||
class ToListConcept(Concept):
|
||||
ALL_ATTRIBUTES = ["items", "recursion_depth", "recurse_on", "tab"]
|
||||
|
||||
def __init__(self, items=None, recursion_depth=None, recurse_on=None, tab=None):
|
||||
Concept.__init__(self,
|
||||
BuiltinConcepts.TO_LIST,
|
||||
True,
|
||||
False,
|
||||
BuiltinConcepts.TO_LIST,
|
||||
bound_body="items")
|
||||
self.set_value("items", items) # items to display
|
||||
self.set_value("recursion_depth", recursion_depth) # recursion depth when showing children
|
||||
self.set_value("recurse_on", recurse_on) # which sub items should we display
|
||||
self.set_value("tab", tab) # customise tab (content and length)
|
||||
self._metadata.is_evaluated = True
|
||||
|
||||
Reference in New Issue
Block a user