1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2025-09-03 03:42:35 +01:00

New target description + moving target stuff under "framework"

Changing the way target descriptions work from a static mapping to
something that is dynamically generated and is extensible via plugins.
Also moving core target implementation stuff under "framework".
This commit is contained in:
Sergei Trofimov
2017-03-06 11:10:25 +00:00
parent 18d001fd76
commit 42539bbe0d
43 changed files with 6229 additions and 2586 deletions

View File

@@ -1,13 +1,13 @@
"""
This module contains wrappers for Python serialization modules for
common formats that make it easier to serialize/deserialize WA
Plain Old Data structures (serilizable WA classes implement
``to_pod()``/``from_pod()`` methods for converting between POD
Plain Old Data structures (serilizable WA classes implement
``to_pod()``/``from_pod()`` methods for converting between POD
structures and Python class instances).
The modifications to standard serilization procedures are:
- mappings are deserialized as ``OrderedDict``\ 's are than standard
- mappings are deserialized as ``OrderedDict``\ 's rather than standard
Python ``dict``\ 's. This allows for cleaner syntax in certain parts
of WA configuration (e.g. values to be written to files can be specified
as a dict, and they will be written in the order specified in the config).
@@ -16,7 +16,7 @@ The modifications to standard serilization procedures are:
in the POD config.
This module exports the "wrapped" versions of serialization libraries,
and this should be imported and used instead of importing the libraries
and this should be imported and used instead of importing the libraries
directly. i.e. ::
from wa.utils.serializer import yaml
@@ -27,7 +27,7 @@ instead of ::
import yaml
pod = yaml.load(fh)
It's also possible to suse the serializer directly::
It's also possible to use the serializer directly::
from wa.utils import serializer
pod = serializer.load(fh)
@@ -35,13 +35,14 @@ It's also possible to suse the serializer directly::
This can also be used to ``dump()`` POD structures. By default,
``dump()`` will produce JSON, but ``fmt`` parameter may be used to
specify an alternative format (``yaml`` or ``python``). ``load()`` will
use the file extension to guess the format, but ``fmt`` may also be used
use the file plugin to guess the format, but ``fmt`` may also be used
to specify it explicitly.
"""
# pylint: disable=unused-argument
import os
import re
import sys
import json as _json
from collections import OrderedDict
from datetime import datetime
@@ -50,8 +51,8 @@ import yaml as _yaml
import dateutil.parser
from wa.framework.exception import SerializerSyntaxError
from wa.utils.types import regex_type
from wa.utils.misc import isiterable
from wa.utils.types import regex_type, none_type
__all__ = [
@@ -60,16 +61,29 @@ __all__ = [
'read_pod',
'dump',
'load',
'is_pod',
'POD_TYPES',
]
POD_TYPES = [
list,
tuple,
dict,
set,
str,
unicode,
int,
float,
bool,
datetime,
regex_type,
none_type,
]
class WAJSONEncoder(_json.JSONEncoder):
def default(self, obj):
if hasattr(obj, 'to_pod'):
return obj.to_pod()
elif isinstance(obj, regex_type):
def default(self, obj): # pylint: disable=method-hidden
if isinstance(obj, regex_type):
return 'REGEX:{}:{}'.format(obj.flags, obj.pattern)
elif isinstance(obj, datetime):
return 'DATET:{}'.format(obj.isoformat())
@@ -79,8 +93,8 @@ class WAJSONEncoder(_json.JSONEncoder):
class WAJSONDecoder(_json.JSONDecoder):
def decode(self, s):
d = _json.JSONDecoder.decode(self, s)
def decode(self, s, **kwargs):
d = _json.JSONDecoder.decode(self, s, **kwargs)
def try_parse_object(v):
if isinstance(v, basestring) and v.startswith('REGEX:'):
@@ -112,7 +126,6 @@ class json(object):
def dump(o, wfh, indent=4, *args, **kwargs):
return _json.dump(o, wfh, cls=WAJSONEncoder, indent=indent, *args, **kwargs)
@staticmethod
def load(fh, *args, **kwargs):
try:
@@ -176,7 +189,7 @@ class yaml(object):
except _yaml.YAMLError as e:
lineno = None
if hasattr(e, 'problem_mark'):
lineno = e.problem_mark.line
lineno = e.problem_mark.line # pylint: disable=no-member
raise SerializerSyntaxError(e.message, lineno)
loads = load
@@ -196,7 +209,7 @@ class python(object):
def loads(s, *args, **kwargs):
pod = {}
try:
exec s in pod
exec s in pod # pylint: disable=exec-used
except SyntaxError as e:
raise SerializerSyntaxError(e.message, e.lineno)
for k in pod.keys():
@@ -209,20 +222,29 @@ def read_pod(source, fmt=None):
if isinstance(source, basestring):
with open(source) as fh:
return _read_pod(fh, fmt)
elif hasattr(source, 'read') and (hasattr(sourc, 'name') or fmt):
elif hasattr(source, 'read') and (hasattr(source, 'name') or fmt):
return _read_pod(source, fmt)
else:
message = 'source must be a path or an open file handle; got {}'
raise ValueError(message.format(type(source)))
def write_pod(pod, dest, fmt=None):
if isinstance(dest, basestring):
with open(dest, 'w') as wfh:
return _write_pod(pod, wfh, fmt)
elif hasattr(dest, 'write') and (hasattr(dest, 'name') or fmt):
return _write_pod(pod, dest, fmt)
else:
message = 'dest must be a path or an open file handle; got {}'
raise ValueError(message.format(type(dest)))
def dump(o, wfh, fmt='json', *args, **kwargs):
serializer = {
'yaml': yaml,
'json': json,
'python': python,
'py': python,
}.get(fmt)
serializer = {'yaml': yaml,
'json': json,
'python': python,
'py': python,
}.get(fmt)
if serializer is None:
raise ValueError('Unknown serialization format: "{}"'.format(fmt))
serializer.dump(o, wfh, *args, **kwargs)
@@ -242,4 +264,20 @@ def _read_pod(fh, fmt=None):
elif fmt == 'py':
return python.load(fh)
else:
raise ValueError('Unknown format "{}": {}'.format(fmt, path))
raise ValueError('Unknown format "{}": {}'.format(fmt, getattr(fh, 'name', '<none>')))
def _write_pod(pod, wfh, fmt=None):
if fmt is None:
fmt = os.path.splitext(wfh.name)[1].lower().strip('.')
if fmt == 'yaml':
return yaml.dump(pod, wfh)
elif fmt == 'json':
return json.dump(pod, wfh)
elif fmt == 'py':
raise ValueError('Serializing to Python is not supported')
else:
raise ValueError('Unknown format "{}": {}'.format(fmt, getattr(wfh, 'name', '<none>')))
def is_pod(obj):
return type(obj) in POD_TYPES