From ca7936eae11e0125981fffed4f09e3200dcedbe9 Mon Sep 17 00:00:00 2001 From: Zahari Date: Tue, 2 May 2017 08:49:32 +0200 Subject: [PATCH] WORK --- src/reportengine/configparser.py | 46 +++++++++++++++++++++++ src/reportengine/inputcache.py | 56 ++++++++++++++++++++++++++++ src/reportengine/rb2.py | 45 ++++++++++++++++++++++ src/reportengine/tests/test_cache.py | 21 +++++++++++ 4 files changed, 168 insertions(+) create mode 100644 src/reportengine/inputcache.py create mode 100644 src/reportengine/rb2.py create mode 100644 src/reportengine/tests/test_cache.py diff --git a/src/reportengine/configparser.py b/src/reportengine/configparser.py index c80c4e7..f805e9d 100644 --- a/src/reportengine/configparser.py +++ b/src/reportengine/configparser.py @@ -180,6 +180,52 @@ def __new__(cls, name, bases, namespace, **kwds): class ConfigMetaClass(ElementOfResolver, AutoTypeCheck, OrderedClass): pass +class Config2(metaclass=ConfigMetaClass): + _traps = ['from_'] + + @classmethod + def get_all_parse_functions(cls): + """Return all defined parse functions, as a dictionary: + {parsed_element:function}""" + return collections.OrderedDict((trim_token(k),getattr(cls,k)) + for k in cls.members + if k.startswith(_config_token)) + + + + def get_parse_func(self, param): + """Return the function that is defined to parse `param` if it exists. + Otherwise, return None.""" + func_name = _config_token + param + try: + return getattr(self, func_name) + except AttributeError: + return None + + + def get_produce_func(self, param): + """Return the function that is defined to produce `param` + from other inputs. + Otherwise, return None.""" + func_name = _produce_token + param + try: + return getattr(self, func_name) + except AttributeError: + return None + + + def get_trap_func(self, input_val): + """If the value has a special meaning that is trapped, return the + function that handles it. Otherwise, return None""" + if isinstance(input_val, dict) and len(input_val) == 1: + k = next(iter(input_val)) + if k in self._traps: + f = self.get_parse_func(k) + return functools.partial(f, input_val[k]) + return None + + + class Config(metaclass=ConfigMetaClass): _traps = ['from_'] diff --git a/src/reportengine/inputcache.py b/src/reportengine/inputcache.py new file mode 100644 index 0000000..263b4e4 --- /dev/null +++ b/src/reportengine/inputcache.py @@ -0,0 +1,56 @@ +""" +inputcache.py + +Saves and retrieves parsed data for providers. +""" + +import pickle + +from attr import attributes, attr + +@attributes(hash=False) +class Frozen: + value = attr() + def __hash__(self): + return hash(pickle.dumps(self.value)) + +def freeze(ele): + try: + hash(ele) + except TypeError: + return Frozen(ele) + else: + return ele + +def unfreeze(ele): + if isinstance(ele, Frozen): + return ele.value + return ele + +class Cache: + def __init__(self): + self._d = {} + + def _freezeargs(self, args): + return tuple((k,freeze(v)) for k,v in args.items()) + + def _unfreeze_args(self, args): + return {k : unfreeze(v) for k,v in args.items()} + + def register(self, key, args, value): + self._d[(key, self._freezeargs(args))] = value + + def retrieve(self, key, args): + return self._d[(key, self._freezeargs(args))] + + def __contains__(self, item): + key, args = item + return (key, self._freezeargs(args)) in self._d + + def __getitem__(self, item): + key,args = item + return self.retrieve(key,args) + + def __setitem__(self, item, value): + key,args = item + self.register(key,args,value) diff --git a/src/reportengine/rb2.py b/src/reportengine/rb2.py new file mode 100644 index 0000000..a8437c0 --- /dev/null +++ b/src/reportengine/rb2.py @@ -0,0 +1,45 @@ +""" +resourcebuilder.py + +Generate an execute a call graph based on Python function signatures. +""" + +from collections import namedtuple +import logging + +log = logging.getLogger(__name__) + +#These represent the final actions we are interested in executiong. +Target = namedtuple('Target', ('name', 'nsspec')) +FuzzyTarget = namedtuple('FuzzyTarget', ('name', 'fuzzyspec', 'rootspec')) + + + +def compiletime(f): + f.compiletime = True + return f + +class CompileTime(): + pass + +class Function(): + pass + +class Collect(): + pass + +def get_processor(obj, key): + if hasattr(obj, 'get_processor'): + return obj.get_processor(key) + if hasattr(obj, key): + res = getattr(obj, key) + if callable(res): + if hasattr(res, 'compiletime'): + return CompileTime(res) + return Function(res) + raise InputNotFound(key) + +class ResourceBuilder: + def __init__(self, providers): + self.providers = providers + diff --git a/src/reportengine/tests/test_cache.py b/src/reportengine/tests/test_cache.py new file mode 100644 index 0000000..cdf7057 --- /dev/null +++ b/src/reportengine/tests/test_cache.py @@ -0,0 +1,21 @@ +from string import printable, ascii_letters + +from hypothesis import given +from hypothesis.strategies import (recursive, none, booleans, floats, text, + lists, dictionaries) + +from reportengine import inputcache + + +json = recursive(none() | booleans() | floats() | text(printable), + lambda children: lists(children) | dictionaries(text(printable), children)) + +args = dictionaries(text(printable), json) + +c = inputcache.Cache() + +@given(text(ascii_letters), args, floats(allow_nan=False)) +def test_register(key, args, value): + c[key, args] = value + assert (key, args) in c + assert c[key, args] == value