Skip to content

Commit

Permalink
FIX #7: Default arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
mtik00 committed Apr 11, 2018
1 parent abfc365 commit 6b60289
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
34 changes: 34 additions & 0 deletions tests/test_default_args.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from __future__ import print_function
from pprint import pprint as pp
from yamicache import Cache


c = Cache(hashing=False)


@c.cached()
def function1(argument, power=4, addition=0, division=2):
return argument ** power + addition / division


def test_main():
'''use default args'''

# `function1` uses default arguments. These calls are all equivalent, so
# there should only be 1 item in cache.
function1(1)
function1(1, 4)
function1(1, 4, 0)
function1(1, 4, addition=0, division=2)

assert len(c) == 1

pp(c._data_store)


def main():
test_main()


if __name__ == '__main__':
main()
22 changes: 21 additions & 1 deletion yamicache/yamicache.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from __future__ import print_function
import json
import time
import inspect
import contextlib
import collections
from hashlib import sha224
Expand Down Expand Up @@ -227,9 +228,28 @@ def _calculate_key(self, func, cached_key=None, *args, **kwargs):

key = cached_key
if not key:
key = dict(kwargs)
key = {}
# We need to grab the default arguments. `inspect.getargspec()`
# returns the function argument names, and any defaults. The
# defaults are always the last args. For example:
# `args=['arg1', 'arg2'], defaults=(4,)` means that `arg2` has a
# default of 4.
fargs, _, _, defaults = inspect.getargspec(func)

# Load the defaults first, since they may not be in the calling
# spec.
if defaults:
key = dict(zip(fargs[-len(defaults):], defaults))

# Now load in the arguments.
key.update(kwargs)
key.update(dict(zip(func.__code__.co_varnames, args)))

# This next issue is that Python may re-order the keys when we go
# to repr them. This will cause invalid cache misses. We can fix
# this by recreating a dictionary with a 'known' algorithm.
key = repr(dict(sorted(key.items())))

return "{prefix}{name}{join}{formatted_key}".format(
join=self._key_join,
prefix=(self._prefix + self._key_join) if self._prefix else '',
Expand Down

0 comments on commit 6b60289

Please sign in to comment.