diff --git a/setup.py b/setup.py index c438286..1bdd079 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ except ImportError: import versioneer -TEST_REQUIRES = ['pytest', 'coverage', 'pytest-cov', 'pymongo'] +TEST_REQUIRES = ['pytest', 'coverage', 'pytest-cov', 'pymongo', 'pandas'] README_RST = '' with open('README.rst') as f: diff --git a/tests/test_mongo_core.py b/tests/test_mongo_core.py index 88024ad..b6fd845 100644 --- a/tests/test_mongo_core.py +++ b/tests/test_mongo_core.py @@ -14,6 +14,8 @@ except ImportError: # python 2 import pytest import pymongo +import hashlib +import pandas as pd from pymongo.mongo_client import MongoClient from pymongo.errors import OperationFailure @@ -233,3 +235,35 @@ def test_stalled_mong_db_core(monkeypatch): res = _stalled_func_2() assert res == 2 + + +def test_callable_hash_param(): + + def _hash_params(args, kwargs): + def _hash(obj): + if isinstance(obj, pd.core.frame.DataFrame): + return hashlib.sha256(pd.util.hash_pandas_object(obj).values.tobytes()).hexdigest() + return obj + + k_args = tuple(map(_hash, args)) + k_kwargs = tuple(sorted({k: _hash(v) for k, v in kwargs.items()}.items())) + return k_args + k_kwargs + + @cachier(mongetter=_test_mongetter, hash_params=_hash_params) + def _params_with_dataframe(*args, **kwargs): + """Some function.""" + return random() + + _params_with_dataframe.clear_cache() + + df_a = pd.DataFrame.from_dict(dict(a=[0], b=[2], c=[3])) + df_b = pd.DataFrame.from_dict(dict(a=[0], b=[2], c=[3])) + value_a = _params_with_dataframe(df_a, 1) + value_b = _params_with_dataframe(df_b, 1) + + assert value_a == value_b # same content --> same key + + value_a = _params_with_dataframe(1, df=df_a) + value_b = _params_with_dataframe(1, df=df_b) + + assert value_a == value_b # same content --> same key diff --git a/tests/test_pickle_core.py b/tests/test_pickle_core.py index 0fef615..abf2591 100644 --- a/tests/test_pickle_core.py +++ b/tests/test_pickle_core.py @@ -24,6 +24,9 @@ try: except ImportError: # python 2 import Queue as queue +import hashlib +import pandas as pd + from cachier import cachier from cachier.pickle_core import DEF_CACHIER_DIR @@ -392,3 +395,35 @@ def test_pickle_core_custom_cache_dir(): assert end - start < 1 _takes_5_seconds_custom_dir.clear_cache() assert _takes_5_seconds_custom_dir.cache_dpath() == EXPANDED_CUSTOM_DIR + + +def test_callable_hash_param(): + + def _hash_params(args, kwargs): + def _hash(obj): + if isinstance(obj, pd.core.frame.DataFrame): + return hashlib.sha256(pd.util.hash_pandas_object(obj).values.tobytes()).hexdigest() + return obj + + k_args = tuple(map(_hash, args)) + k_kwargs = tuple(sorted({k: _hash(v) for k, v in kwargs.items()}.items())) + return k_args + k_kwargs + + @cachier(hash_params=_hash_params) + def _params_with_dataframe(*args, **kwargs): + """Some function.""" + return random() + + _params_with_dataframe.clear_cache() + + df_a = pd.DataFrame.from_dict(dict(a=[0], b=[2], c=[3])) + df_b = pd.DataFrame.from_dict(dict(a=[0], b=[2], c=[3])) + value_a = _params_with_dataframe(df_a, 1) + value_b = _params_with_dataframe(df_b, 1) + + assert value_a == value_b # same content --> same key + + value_a = _params_with_dataframe(1, df=df_a) + value_b = _params_with_dataframe(1, df=df_b) + + assert value_a == value_b # same content --> same key