mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-02-20 20:09:11 +00:00
Types: Adds ParameterDict Type
Acts like a regular dictionary however will automatically url encode/decode the data along with relevant type information.
This commit is contained in:
parent
e884c3bcca
commit
85218a10d2
@ -32,6 +32,7 @@ import numbers
|
||||
import shlex
|
||||
import string
|
||||
from bisect import insort
|
||||
from urllib import quote, unquote
|
||||
from collections import defaultdict, MutableMapping
|
||||
from copy import copy
|
||||
|
||||
@ -327,7 +328,7 @@ class prioritylist(object):
|
||||
raise ValueError('Invalid index {}'.format(index))
|
||||
current_global_offset = 0
|
||||
priority_counts = {priority: count for (priority, count) in
|
||||
zip(self.priorities, [len(self.elements[p])
|
||||
zip(self.priorities, [len(self.elements[p])
|
||||
for p in self.priorities])}
|
||||
for priority in self.priorities:
|
||||
if not index_range:
|
||||
@ -586,3 +587,118 @@ def enum(args, start=0, step=1):
|
||||
|
||||
return Enum
|
||||
|
||||
|
||||
class ParameterDict(dict):
|
||||
"""
|
||||
A dict-like object that automatically encodes various types into a url safe string,
|
||||
and enforces a single type for the contents in a list.
|
||||
Each value is first prefixed with 2 letters to preserve type when encoding to a string.
|
||||
The format used is "value_type, value_dimension" e.g a 'list of floats' would become 'fl'.
|
||||
"""
|
||||
|
||||
# Function to determine the appropriate prefix based on the parameters type
|
||||
@staticmethod
|
||||
def _get_prefix(obj):
|
||||
if isinstance(obj, basestring):
|
||||
prefix = 's'
|
||||
elif isinstance(obj, float):
|
||||
prefix = 'f'
|
||||
elif isinstance(obj, long):
|
||||
prefix = 'd'
|
||||
elif isinstance(obj, bool):
|
||||
prefix = 'b'
|
||||
elif isinstance(obj, int):
|
||||
prefix = 'i'
|
||||
elif obj is None:
|
||||
prefix = 'n'
|
||||
else:
|
||||
raise ValueError('Unable to encode {} {}'.format(obj, type(obj)))
|
||||
return prefix
|
||||
|
||||
# Function to add prefix and urlencode a provided parameter.
|
||||
@staticmethod
|
||||
def _encode(obj):
|
||||
if isinstance(obj, list):
|
||||
t = type(obj[0])
|
||||
prefix = ParameterDict._get_prefix(obj[0]) + 'l'
|
||||
for item in obj:
|
||||
if not isinstance(item, t):
|
||||
msg = 'Lists must only contain a single type, contains {} and {}'
|
||||
raise ValueError(msg.format(t, type(item)))
|
||||
obj = '0newelement0'.join(str(x) for x in obj)
|
||||
else:
|
||||
prefix = ParameterDict._get_prefix(obj) + 's'
|
||||
return quote(prefix + str(obj))
|
||||
|
||||
# Function to decode a string and return a value of the original parameter type.
|
||||
# pylint: disable=too-many-return-statements
|
||||
@staticmethod
|
||||
def _decode(string):
|
||||
value_type = string[:1]
|
||||
value_dimension = string[1:2]
|
||||
value = unquote(string[2:])
|
||||
if value_dimension == 's':
|
||||
if value_type == 's':
|
||||
return str(value)
|
||||
elif value_type == 'b':
|
||||
return boolean(value)
|
||||
elif value_type == 'd':
|
||||
return long(value)
|
||||
elif value_type == 'f':
|
||||
return float(value)
|
||||
elif value_type == 'i':
|
||||
return int(value)
|
||||
elif value_type == 'n':
|
||||
return None
|
||||
elif value_dimension == 'l':
|
||||
return [ParameterDict._decode(value_type + 's' + x)
|
||||
for x in value.split('0newelement0')]
|
||||
else:
|
||||
raise ValueError('Unknown {} {}'.format(type(string), string))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
for k, v in kwargs.iteritems():
|
||||
self.__setitem__(k, v)
|
||||
dict.__init__(self, *args)
|
||||
|
||||
def __setitem__(self, name, value):
|
||||
dict.__setitem__(self, name, self._encode(value))
|
||||
|
||||
def __getitem__(self, name):
|
||||
return self._decode(dict.__getitem__(self, name))
|
||||
|
||||
def __contains__(self, item):
|
||||
return dict.__contains__(self, self._encode(item))
|
||||
|
||||
def __iter__(self):
|
||||
return iter((k, self._decode(v)) for (k, v) in self.items())
|
||||
|
||||
def iteritems(self):
|
||||
return self.__iter__()
|
||||
|
||||
def get(self, name):
|
||||
return self._decode(dict.get(self, name))
|
||||
|
||||
def pop(self, key):
|
||||
return self._decode(dict.pop(self, key))
|
||||
|
||||
def popitem(self):
|
||||
key, value = dict.popitem(self)
|
||||
return (key, self._decode(value))
|
||||
|
||||
def iter_encoded_items(self):
|
||||
return dict.iteritems(self)
|
||||
|
||||
def get_encoded_value(self, name):
|
||||
return dict.__getitem__(self, name)
|
||||
|
||||
def values(self):
|
||||
return [self[k] for k in dict.keys(self)]
|
||||
|
||||
def update(self, *args, **kwargs):
|
||||
for d in list(args) + [kwargs]:
|
||||
if isinstance(d, ParameterDict):
|
||||
dict.update(self, d)
|
||||
else:
|
||||
for k, v in d.iteritems():
|
||||
self[k] = v
|
||||
|
Loading…
x
Reference in New Issue
Block a user