From b0258314501d8df54bfaaf841be8c8326b018601 Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Fri, 19 Jan 2018 11:36:25 +0000 Subject: Replace "oslo_utils.importutils" with standard library "importlib" The current implementation of dynamic library importation is prone to failure [1]: - "sys.modules" is modified manually, which is something not recommended [2]. - When a module is imported is added to "sys.modules"; that means there is no need to manually create an entry in this object. - "importlib" library is part of the standard library and is now available in PY3 and PY2 (backported). This library contains a function called "import_module" to import a module in runtime. [1]https://github.com/opnfv/yardstick/blob/d2c7cc4e9768ed003257a95c92cdb278d516761b/yardstick/common/utils.py#L72-L93 [2]http://justus.science/blog/2015/04/19/sys.modules-is-dangerous.html JIRA: YARDSTICK-949 Change-Id: Ide3b74f98858d06fa275fb6c9b78ceeaa64feed5 Signed-off-by: Rodolfo Alonso Hernandez --- yardstick/common/utils.py | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'yardstick/common/utils.py') diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py index 82e20bec7..8604e900f 100644 --- a/yardstick/common/utils.py +++ b/yardstick/common/utils.py @@ -13,27 +13,22 @@ # License for the specific language governing permissions and limitations # under the License. -# yardstick comment: this is a modified copy of rally/rally/common/utils.py - -from __future__ import absolute_import -from __future__ import print_function - +import collections +from contextlib import closing import datetime import errno +import importlib +import ipaddress import logging import os +import random +import socket import subprocess import sys -import collections -import socket -import random -import ipaddress -from contextlib import closing import six from flask import jsonify from six.moves import configparser -from oslo_utils import importutils from oslo_serialization import jsonutils import yardstick @@ -70,27 +65,28 @@ def itersubclasses(cls, _seen=None): def import_modules_from_package(package): - """Import modules from package and append into sys.modules + """Import modules given a package name :param: package - Full package name. For example: rally.deploy.engines """ yardstick_root = os.path.dirname(os.path.dirname(yardstick.__file__)) - path = os.path.join(yardstick_root, *package.split(".")) + path = os.path.join(yardstick_root, *package.split('.')) for root, _, files in os.walk(path): - matches = (filename for filename in files if filename.endswith(".py") and - not filename.startswith("__")) - new_package = os.path.relpath(root, yardstick_root).replace(os.sep, ".") + matches = (filename for filename in files if filename.endswith('.py') + and not filename.startswith('__')) + new_package = os.path.relpath(root, yardstick_root).replace(os.sep, + '.') module_names = set( - ("{}.{}".format(new_package, filename.rsplit(".py", 1)[0]) for filename in matches)) - # find modules which haven't already been imported + '{}.{}'.format(new_package, filename.rsplit('.py', 1)[0]) + for filename in matches) + # Find modules which haven't already been imported missing_modules = module_names.difference(sys.modules) - logger.debug("importing %s", missing_modules) - # we have already checked for already imported modules, so we don't need to check again + logger.debug('Importing modules: %s', missing_modules) for module_name in missing_modules: try: - sys.modules[module_name] = importutils.import_module(module_name) + importlib.import_module(module_name) except (ImportError, SyntaxError): - logger.exception("unable to import %s", module_name) + logger.exception('Unable to import module %s', module_name) def makedirs(d): -- cgit 1.2.3-korg