Source code for powersimdata.utility.helpers

import copy
import importlib
import os
import sys


[docs]class MemoryCache: """Wrapper around a dict object that exposes a cache interface. Users should create a separate instance for each distinct use case. """ def __init__(self): """Constructor""" self._cache = {}
[docs] def put(self, key, obj): """Add or set the value for the given key. :param tuple key: a tuple used to lookup the cached value :param Any obj: the object to cache """ self._cache[key] = copy.deepcopy(obj)
[docs] def get(self, key): """Retrieve the value associated with key if it exists. :param tuple key: the cache key :return: (*Any* or *NoneType*) -- the cached value if found, or None """ if key in self._cache.keys(): return copy.deepcopy(self._cache[key])
[docs] def list_keys(self): """Return and print the current cache keys. :return: (*list*) -- the list of cache keys """ keys = list(self._cache.keys()) print(keys) return keys
[docs]def cache_key(*args, **kwargs): """Creates a cache key from the given args. The user should ensure that the range of inputs will not result in key collisions. :param args: variable length argument list :return: (*tuple*) -- a tuple containing the input in heirarchical structure """ kb = CacheKeyBuilder(*args, **kwargs) return kb.build()
[docs]class CacheKeyBuilder: """Helper class to generate cache keys :param args: variable length arguments from which to build a key """ def __init__(self, *args, **kwargs): """Constructor""" self.args = list(args) self.args.extend((k, v) for k, v in kwargs.items())
[docs] def build(self): """Combine args into a tuple, preserving the structure of each element. :return: (*tuple*) -- container which can be used as a cache key """ return self._build(self.args)
def _build(self, arg): if arg is None: return "null" if isinstance(arg, (str, int, bool)): return arg if isinstance(arg, (list, set, tuple)): return tuple(self._build(a) for a in arg) print(f"cache key of type = {type(arg)} may result in unexpected behavior") return f"obj:{type(arg)}:{id(arg)}"
[docs]class PrintManager: """Manages print messages.""" def __init__(self): """Constructor""" self.stdout = sys.stdout def __enter__(self): self.block_print() def __exit__(self, exc_type, exc_value, traceback): self.enable_print()
[docs] @staticmethod def block_print(): """Suppresses print""" sys.stdout = open(os.devnull, "w")
[docs] def enable_print(self): """Enables print""" sys.stdout = self.stdout
def _check_import(package_name): """Import a package, or give a useful error message if it's not there.""" try: return importlib.import_module(package_name) except ImportError: err_msg = ( f"{package_name} is not installed. " "It may be an optional powersimdata requirement." ) raise ImportError(err_msg)