mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-01-18 03:56:04 +00:00
wa: Remove dependency on "imp" module
Python 3.12 removed the "imp" module, so use importlib instead.
This commit is contained in:
parent
41f7984243
commit
77ebefba08
1
setup.py
1
setup.py
@ -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"',
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user