1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2024-10-05 10:21:16 +01:00

wa: Remove dependency on "imp" module

Python 3.12 removed the "imp" module, so use importlib instead.
This commit is contained in:
Douglas Raillard 2023-10-05 12:10:41 +01:00 committed by Marc Bonnici
parent 41f7984243
commit 77ebefba08
3 changed files with 47 additions and 28 deletions

View File

@ -79,6 +79,7 @@ params = dict(
license='Apache v2',
maintainer='ARM Architecture & Technology Device Lab',
maintainer_email='workload-automation@arm.com',
python_requires='>= 3.7',
setup_requires=[
'numpy<=1.16.4; python_version<"3"',
'numpy; python_version>="3"',

View File

@ -18,8 +18,6 @@
import os
import sys
import inspect
import imp
import string
import logging
from collections import OrderedDict, defaultdict
from itertools import chain
@ -32,16 +30,10 @@ from wa.framework.exception import (NotFoundError, PluginLoaderError, TargetErro
ValidationError, ConfigError, HostError)
from wa.utils import log
from wa.utils.misc import (ensure_directory_exists as _d, walk_modules, load_class,
merge_dicts_simple, get_article)
merge_dicts_simple, get_article, import_path)
from wa.utils.types import identifier
if sys.version_info[0] == 3:
MODNAME_TRANS = str.maketrans(':/\\.', '____')
else:
MODNAME_TRANS = string.maketrans(':/\\.', '____')
class AttributeCollection(object):
"""
Accumulator for plugin attribute objects (such as Parameters or Artifacts).
@ -645,8 +637,7 @@ class PluginLoader(object):
def _discover_from_file(self, filepath):
try:
modname = os.path.splitext(filepath[1:])[0].translate(MODNAME_TRANS)
module = imp.load_source(modname, filepath)
module = import_path(filepath)
self._discover_in_module(module)
except (SystemExit, ImportError) as e:
if self.keep_going:

View File

@ -21,10 +21,12 @@ Miscellaneous functions that don't fit anywhere else.
import errno
import hashlib
import imp
import importlib
import inspect
import logging
import math
import os
import pathlib
import random
import re
import shutil
@ -308,32 +310,57 @@ class LoadSyntaxError(Exception):
RAND_MOD_NAME_LEN = 30
def load_struct_from_python(filepath=None, text=None):
def import_path(filepath, module_name=None):
"""
Programmatically import the given Python source file under the name
``module_name``. If ``module_name`` is not provided, a stable name based on
``filepath`` will be created. Note that this module name cannot be relied
on, so don't make write import statements assuming this will be stable in
the future.
"""
if not module_name:
path = pathlib.Path(filepath).resolve()
id_ = to_identifier(str(path))
module_name = f'wa._user_import.{id_}'
try:
return sys.modules[module_name]
except KeyError:
spec = importlib.util.spec_from_file_location(module_name, filepath)
module = importlib.util.module_from_spec(spec)
try:
sys.modules[module_name] = module
spec.loader.exec_module(module)
except BaseException:
sys.modules.pop(module_name, None)
raise
else:
# We could return the "module" object, but that would not take into
# account any manipulation the module did on sys.modules when
# executing. To be consistent with the import statement, re-lookup
# the module name.
return sys.modules[module_name]
def load_struct_from_python(filepath):
"""Parses a config structure from a .py file. The structure should be composed
of basic Python types (strings, ints, lists, dicts, etc.)."""
if not (filepath or text) or (filepath and text):
raise ValueError('Exactly one of filepath or text must be specified.')
try:
if filepath:
modname = to_identifier(filepath)
mod = imp.load_source(modname, filepath)
else:
modname = get_random_string(RAND_MOD_NAME_LEN)
while modname in sys.modules: # highly unlikely, but...
modname = get_random_string(RAND_MOD_NAME_LEN)
mod = imp.new_module(modname)
exec(text, mod.__dict__) # pylint: disable=exec-used
return dict((k, v)
for k, v in mod.__dict__.items()
if not k.startswith('_'))
mod = import_path(filepath)
except SyntaxError as e:
raise LoadSyntaxError(e.message, filepath, e.lineno)
else:
return {
k: v
for k, v in inspect.getmembers(mod)
if not k.startswith('_')
}
def load_struct_from_yaml(filepath=None, text=None):
"""Parses a config structure from a .yaml file. The structure should be composed
of basic Python types (strings, ints, lists, dicts, etc.)."""
# Import here to avoid circular imports
# pylint: disable=wrong-import-position,cyclic-import, import-outside-toplevel
from wa.utils.serializer import yaml