Decorator to wrap a function with a memoizing callable that saves
    up to `maxsize` results based on a Least Recently Used (LRU)
    algorithm.
977017
def lru_cache(maxsize=128, typed=False):
    
    if maxsize is None:
        return _cache(_UnboundCache(), typed)
    else:
        return _cache(LRUCache(maxsize), typed)
125706
def memoize(method):
    

    cache = method.cache = collections.OrderedDict()

    # Put these two methods in the local space (faster)
    _get = cache.get
    _popitem = cache.popitem

    @functools.wraps(method)
    def memoizer(instance, x, *args, **kwargs):

        if not _WITH_MEMOIZATION or isinstance(x, u.Quantity):

            # Memoization is not active or using units, do not use memoization

            return method(instance, x, *args, **kwargs)

        # Create a tuple because a tuple is hashable

        unique_id = tuple(float(yy.value) for yy in instance.parameters.values()) + (x.size, x.min(), x.max())

        # Create a unique identifier for this combination of inputs

        key = hash(unique_id)

        # Let's do it this way so we only look into the dictionary once

        result = _get(key)

        if result is not None:

            return result

        else:

            result = method(instance, x, *args, **kwargs)

            cache[key] = result

            if len(cache) > _CACHE_SIZE:
                # Remove half of the element (but at least 1, even if _CACHE_SIZE=1, which would be pretty idiotic ;-) )
                [_popitem(False) for i in range(max(_CACHE_SIZE // 2, 1))]

            return result

    # Add the function as a "attribute" so we can access it
    memoizer.input_object = method

    return memoizer
1031869
def memoize(func, cache, num_args):
    

    @wraps(func)
    def wrapper(*args):
        mem_args = args[:num_args]
        if mem_args in cache:
            return cache[mem_args]
        result = func(*args)
        cache[mem_args] = result
        return result

    return wrapper
487963
def cache(*depends_on):
    
    def cache_decorator(fn):
        @memoize
        @wraps(fn)
        def wrapper(*args, **kwargs):
            if cache.disabled:
                return fn(*args, **kwargs)
            else:
                return _cache.get_value(fn, depends_on, args, kwargs)

        return wrapper

    return cache_decorator
968235
def memoize_nonzero(func):
    
    class _memorizer(dict):
        def __init__(self, func):
            self.func = func
        def __call__(self, *args):
            return self[args]
        def __missing__(self, key):
            ret = self[key] = self.func(*key)
            return ret
    return _memorizer(func)
1038814
def lfu_cache(max_size=128):
    

    def actual_decorator(func):
        return _cached_func(func, caches.LFUCache, max_size)

    return actual_decorator
897110
def cache(cls, key_attrs, expires=None):
        

        def decorator(func):

            @functools.wraps(func)
            def wrapper(self, *args, **kwargs):
                module = type(self).__module__
                classname = type(self).__name__
                method_name = func.__name__

                data = {}
                if isinstance(key_attrs, basestring):
                    _key_attrs = key_attrs.split()
                else:
                    _key_attrs = key_attrs
                for key_attr in _key_attrs:
                    key_value = getattr(self, key_attr)
                    if isinstance(key_value, dict):
                        key_value = ('dict', sorted(key_value.items()))
                    elif isinstance(key_value, set):
                        key_value = ('set', sorted(key_value))
                    else:
                        key_value = (type(key_value).__name__, key_value)
                    data[key_attr] = key_value
                data = sorted(data.items())

                result_cache, new = cls.get_or_create(
                    module=module,
                    classname=classname,
                    method_name=method_name,
                    data=data,
                    args=args,
                    kwargs=sorted(kwargs.items()),
                )

                if new:
                    result_cache.result = func(self, *args, **kwargs)
                    result_cache.save(expires)

                return result_cache.result

            return wrapper

        return decorator
1319093
def _memoize(f):
  """"""
  nothing = object()  # Unique "no value" sentinel object.
  cache = {}
  # Use a reentrant lock so that if f references the resulting wrapper we die
  # with recursion depth exceeded instead of deadlocking.
  lock = threading.RLock()
  @functools.wraps(f)
  def wrapper(arg):
    if cache.get(arg, nothing) is nothing:
      with lock:
        if cache.get(arg, nothing) is nothing:
          cache[arg] = f(arg)
    return cache[arg]
  return wrapper
917401
def wrap_function(self, func):
        
        def f(*args, **kwds):
            # Start time
            timestamps = [_get_memory(os.getpid(), timestamps=True)]
            self.functions[func].append(timestamps)
            try:
                result = func(*args, **kwds)
            finally:
                # end time
                timestamps.append(_get_memory(os.getpid(), timestamps=True))
            return result
        return f
219981
def memoize(function):
    
    cache = {}
    @functools.wraps(function)
    def _memoize(*args):
        if args in cache:
            return cache[args]
        result = function(*args)
        cache[args] = result
        return result
    return function
52686
def memoize(fn):
    
    memoized_values = {}

    @wraps(fn)
    def wrapped_fn(*args, **kwargs):
        key = (args, tuple(sorted(kwargs.items())))
        try:
            return memoized_values[key]
        except KeyError:
            memoized_values[key] = fn(*args, **kwargs)
            return memoized_values[key]

    return wrapped_fn
479537
def cache(ignore=None):
    
    def decorator(func):
        # Initialize both cached versions
        joblib_cached = constants.joblib_memory.cache(func, ignore=ignore)
        db_cached = DbMemoizedFunc(func, ignore)

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            """Dynamically choose the cache at call-time, not at import."""
            if func.__name__ == '_sia' and not config.CACHE_SIAS:
                f = func
            elif config.CACHING_BACKEND == 'fs':
                f = joblib_cached
            elif config.CACHING_BACKEND == 'db':
                f = db_cached
            return f(*args, **kwargs)

        return wrapper
    return decorator
1222903
def cached(func):
    
    @wraps(func)
    def wrapper(*args, **kwargs):
        global cache
        key = json.dumps((func, args, kwargs), sort_keys=True, default=str)
        try:
            return cache[key]
        except KeyError:
            pass  # Drop out of the exception handler scope.
        res = func(*args, **kwargs)
        cache[key] = res
        return res
    wrapper._wrapped = func
    return wrapper
224902
def lazyfunc(func):
    
    closuremem_ = [{}]
    def wrapper(*args, **kwargs):
        mem = closuremem_[0]
        key = (repr(args), repr(kwargs))
        try:
            return mem[key]
        except KeyError:
            mem[key] = func(*args, **kwargs)
        return mem[key]
    return wrapper
656469
def storage_method(func):
    ''''''
    def wrap(self, *args, **kwargs):
        return func(self._root_storage, *args, **kwargs)
    return wrap
1309357
def cache_return(func):
    """"""

    _cache = []

    def wrap():
        if not _cache:
            _cache.append(func())
        return _cache[0]
    return wrap
447092
def wraps(
    wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES
):
    """"""
    if not is_cython_function(wrapped):
        return functools.wraps(wrapped, assigned, updated)
    else:
        return lambda wrapper: wrapper