Added parsers and Evaluators auto discovery

This commit is contained in:
2019-11-15 16:36:38 +01:00
parent 9e10e77737
commit 2fbda533f1
3 changed files with 109 additions and 14 deletions
+40 -13
View File
@@ -65,17 +65,8 @@ class Sheerka(Concept):
self.sdp.set_key(self.USER_CONCEPTS_KEYS, 1000)
self.initialize_builtin_concepts()
self.parsers.append(core.utils.get_class("parsers.DefaultParser.DefaultParser"))
self.parsers.append(core.utils.get_class("parsers.PythonParser.PythonParser"))
self.parsers.append(core.utils.get_class("parsers.ExactConceptParser.ExactConceptParser"))
self.evaluators.append(core.utils.new_object("evaluators.ParsersEvaluator.ParsersEvaluator"))
self.evaluators.append(core.utils.new_object("evaluators.AddConceptEvaluator.AddConceptEvaluator"))
self.evaluators.append(core.utils.new_object("evaluators.PythonEvaluator.PythonEvaluator"))
self.evaluators.append(core.utils.new_object("evaluators.ConceptEvaluator.ConceptEvaluator"))
self.evaluators.append(
core.utils.new_object("evaluators.DuplicateConceptEvaluator.DuplicateConceptEvaluator"))
self.initialize_builtin_parsers()
self.initialize_builtin_evaluators()
except IOError as e:
return ReturnValueConcept(self, False, self.get(BuiltinConcepts.ERROR), e)
@@ -123,6 +114,28 @@ class Sheerka(Concept):
self.add_in_cache(concept)
def initialize_builtin_parsers(self):
"""
Init the parsers
:return:
"""
for parser in core.utils.get_sub_classes("parsers", "parsers.BaseParser.BaseParser"):
log.debug(f"Adding builtin parser '{parser.__name__}'")
self.parsers.append(parser)
def initialize_builtin_evaluators(self):
"""
Init the evaluators
:return:
"""
for evaluator in core.utils.get_sub_classes("evaluators", "evaluators.BaseEvaluator.OneReturnValueEvaluator"):
log.debug(f"Adding builtin evaluator '{evaluator.__name__}'")
self.evaluators.append(evaluator)
for evaluator in core.utils.get_sub_classes("evaluators", "evaluators.BaseEvaluator.AllReturnValuesEvaluator"):
log.debug(f"Adding builtin evaluator '{evaluator.__name__}'")
self.evaluators.append(evaluator)
def init_logging(self):
if self.debug:
log_format = "%(asctime)s %(name)s [%(levelname)s] %(message)s"
@@ -197,17 +210,18 @@ class Sheerka(Concept):
def process(self, context, return_values, contextual_concepts=None):
log.debug("Evaluating parsing result.")
# init
# return_values must be a list
if not isinstance(return_values, list):
return_values = [return_values]
# adds contextual concepts
if contextual_concepts:
return_values.extend(contextual_concepts)
# group the evaluators by priority and sort them
# The first one to be applied will be the one with the highest priority
grouped_evaluators = {}
for item in self.evaluators:
for item in [e() for e in self.evaluators]:
grouped_evaluators.setdefault(item.priority, []).append(item)
sorted_priorities = sorted(grouped_evaluators.keys(), reverse=True)
@@ -428,6 +442,19 @@ class Sheerka(Concept):
return res
@staticmethod
def get_builtin_parsers():
res = []
# modules = core.utils.get_module("parsers")
# for m in modules:
base_class = core.utils.get_class("parsers.BaseParser.BaseParser")
for c in core.utils.get_classes_recursive("parsers"):
#if issubclass(c, base_class) and c != base_class:
res.append(c)
return res
@staticmethod
def test():
return "I have access to Sheerka !"
+32
View File
@@ -1,4 +1,6 @@
import importlib
import inspect
import pkgutil
import sys
@@ -38,6 +40,7 @@ def get_class(qname):
m = getattr(m, comp)
return m
def get_module(qname):
"""
Loads a module from its full qualified name
@@ -77,6 +80,11 @@ def get_full_qualified_name(obj):
def get_classes(module_name):
"""
Gets all classes, for a given module_name
:param module_name: name of the module
:return:
"""
mod = get_module(module_name)
for name in dir(mod):
obj = getattr(mod, name)
@@ -84,6 +92,30 @@ def get_classes(module_name):
yield obj
def get_classes_from_package(package_name):
"""
Gets all classes, for a given package
:param package_name: name of the package
:return:
"""
pkg = __import__(package_name)
prefix = pkg.__name__ + "."
for importer, modname, ispkg in pkgutil.iter_modules(pkg.__path__, prefix):
for c in get_classes(modname):
yield c
def get_sub_classes(package_name, base_class_name):
pkg = __import__(package_name)
prefix = pkg.__name__ + "."
for (module_loader, name, ispkg) in pkgutil.iter_modules(pkg.__path__, prefix):
importlib.import_module(name)
base_class = get_class(base_class_name)
return base_class.__subclasses__()
def remove_from_list(lst, to_remove):
"""
Removes elements from a list if they exist