1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# 5# Copyright 2017, Data61 6# Commonwealth Scientific and Industrial Research Organisation (CSIRO) 7# ABN 41 687 119 230. 8# 9# This software may be distributed and modified according to the terms of 10# the BSD 2-Clause license. Note that NO WARRANTY is provided. 11# See "LICENSE_BSD2.txt" for details. 12# 13# @TAG(DATA61_BSD) 14# 15 16'''Caching infrastructure for function calls. Nothing in here is CAmkES- 17specific. Note that this memoization implementation is not complete. If you are 18using it, you are expected to understand its limitations. 19''' 20 21from __future__ import absolute_import, division, print_function, \ 22 unicode_literals 23from camkes.internal.seven import cmp, filter, map, zip 24import functools, six 25 26if six.PY3: 27 # Python 3 has memoization support in functools. 28 assert hasattr(functools, 'lru_cache'), '`functools.lru_cache` ' \ 29 'unexpectedly missing (unsupported Python 3 minor version?)' 30 memoize = functools.lru_cache # pylint: disable=E1101 31 32else: 33 # Python 2 has no built-in memoization support, so we need to roll our own. 34 # See also https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize. 35 class memoized(object): 36 '''Decorator. Cache a function's return value each time it is called. If 37 called later with the same arguments, the cached value is returned (not 38 reevaluated).''' 39 40 def __init__(self, func): 41 self.func = func 42 self.cache = {} 43 44 def __call__(self, *args, **kwargs): 45 key = str(args) + str(kwargs) 46 if key not in self.cache: 47 self.cache[key] = self.func(*args, **kwargs) 48 return self.cache[key] 49 50 def __repr__(self): 51 '''Return the function's docstring.''' 52 return self.func.__doc__ 53 54 def memoize(): 55 return memoized 56