mirror of
				https://github.com/ARM-software/workload-automation.git
				synced 2025-11-04 00:52:08 +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:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user