Robot Framework Integrated Development Environment (RIDE)
pluginloader.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import importlib
17 import importlib.util
18 import inspect
19 import os
20 
21 from ..context import LOG
22 from ..pluginapi import Plugin
23 from .pluginconnector import PluginFactory
24 
25 
26 class PluginLoader():
27 
28  def __init__(self, application, load_dirs, standard_classes):
29  self._load_errors_load_errors = []
30  self.pluginsplugins = [PluginFactory(application, cls) for cls in standard_classes + self._find_classes_find_classes(load_dirs)]
31  if self._load_errors_load_errors:
32  LOG.error('\n\n'.join(self._load_errors_load_errors))
33 
34  def enable_plugins(self):
35  for p in self.pluginsplugins:
36  p.enable_on_startup()
37 
38  def _find_classes(self, load_dirs):
39  classes = []
40  for path in self._find_python_files_find_python_files(load_dirs):
41  for cls in self._import_classes_import_classes(path):
42  if self._is_plugin_class_is_plugin_class(path, cls):
43  classes.append(cls)
44  return classes
45 
46  def _is_plugin_class(self, path, cls):
47  try:
48  return issubclass(cls, Plugin) and cls is not Plugin
49  except Exception as err:
50  msg = "Finding classes from module '%s' failed: %s"
51  self._load_errors_load_errors.append(msg % (path, err))
52 
53  def _find_python_files(self, load_dirs):
54  files = []
55  for path in load_dirs:
56  if not os.path.exists(path):
57  continue
58  for filename in os.listdir(path):
59  full_path = os.path.join(path, filename)
60  if filename[0].isalpha() and \
61  os.path.splitext(filename)[1].lower() == ".py":
62  files.append(full_path)
63  elif os.path.isdir(full_path):
64  files.extend(self._find_python_files_find_python_files([full_path]))
65  return files
66 
67  def _import_classes(self, path):
68  dirpath, filename = os.path.split(path)
69  modulename = os.path.splitext(filename)[0]
70  spec = importlib.util.spec_from_file_location(modulename, path)
71  if spec is None:
72  return []
73  try:
74  m_module = importlib.util.module_from_spec(spec)
75  spec.loader.exec_module(m_module)
76  except Exception as err:
77  self._load_errors_load_errors.append("Importing plugin module '%s' failed:\n%s"
78  % (path, err))
79  return []
80  return [cls for _, cls in
81  inspect.getmembers(m_module, predicate=inspect.isclass)]
def __init__(self, application, load_dirs, standard_classes)
Definition: pluginloader.py:28
def PluginFactory(application, plugin_class)