Files
Sheerka-Old/core/concept.py
T

112 lines
3.4 KiB
Python

import hashlib
from enum import Enum
import logging
log = logging.getLogger(__name__)
class ConceptParts(Enum):
WHERE = "where"
PRE = "pre"
POST = "post"
BODY = "body"
class Concept:
"""
Default concept object
A concept is a the base object of our universe
Everything is a concept
"""
props_to_serialize = ("id", "is_builtin", "name", "where", "pre", "post", "body", "desc")
def __init__(self, name=None, is_builtin=False, where=None, pre=None, post=None, body=None, desc=None, key=None):
self.name = name
self.is_builtin = is_builtin
self.where = where # condition to recognize variables in name
self.pre = pre # list of pre conditions before calling the main function
self.post = post # list of post conditions after calling the main function
self.body = body # main method, can also be the value of the concept
self.desc = desc
self.id = None
self.key = key
self.props = [] # list of Property for this concept
self.functions = {} # list of helper functions
self.codes = {} # cached ast for the where, pre, post and body parts
def __repr__(self):
return f"({self.id}){self.name}"
def __eq__(self, other):
if not isinstance(other, Concept):
return False
return self.name == other.name and \
self.where == other.where and \
self.pre == other.pre and \
self.post == other.post and \
self.body == other.body
def __hash__(self):
return hash(self.name)
def get_key(self):
return self.key
def add_codes(self, codes):
"""
From a dict of <ConceptParts, AST>
fill the codes
:param codes:
:return:
"""
possibles_codes = set(item.value for item in ConceptParts)
if codes is None:
return
for key in codes:
if key in possibles_codes:
self.codes[ConceptParts(key)] = codes[key]
def get_digest(self):
"""
Returns the digest of the event
:return: hexa form of the sha256
"""
return hashlib.sha256(f"Concept:{self.name}{self.pre}{self.post}{self.body}".encode("utf-8")).hexdigest()
def to_dict(self):
props_as_dict = dict((prop, getattr(self, prop)) for prop in self.props_to_serialize)
props_as_dict["props"] = [(p.name, p.value) for p in self.props]
return props_as_dict
def from_dict(self, as_dict):
for prop in self.props_to_serialize:
if prop in as_dict:
setattr(self, prop, as_dict[prop])
if "props" in as_dict:
for n, v in as_dict["props"]:
self.props.append(Property(n, v))
return self
def update_from(self, other):
for prop in self.props_to_serialize:
setattr(self, prop, getattr(other, prop))
class ErrorConcept(Concept):
def __init__(self, where=None, pre=None, post=None, body=None, desc=None):
Concept.__init__(self, "error", is_builtin=True, where=where, pre=pre, post=post, body=body, desc=desc)
def __repr__(self):
return f"({self.id}){self.name} : {self.body}"
class Property:
"""
Defines a behaviour of Concept
"""
def __init__(self, name, value):
self.name = name
self.value = value