diff --git a/cachier/core.py b/cachier/core.py index 79becf7c..0f363f85 100644 --- a/cachier/core.py +++ b/cachier/core.py @@ -15,6 +15,7 @@ import hashlib import os import pickle +from collections import OrderedDict from concurrent.futures import ThreadPoolExecutor from functools import wraps from typing import TYPE_CHECKING, Callable, Literal, Optional, TypedDict, Union @@ -257,10 +258,11 @@ def func_wrapper(*args, **kwds): # pylint: disable=C0111,R0911 _print = print if ignore_cache or not _default_params['caching_enabled']: return func(*args, **kwds) + kwds_ordered = OrderedDict(sorted(kwds.items())) if core.func_is_method: - key, entry = core.get_entry(args[1:], kwds) + key, entry = core.get_entry(args[1:], kwds_ordered) else: - key, entry = core.get_entry(args, kwds) + key, entry = core.get_entry(args, kwds_ordered) if overwrite_cache: return _calc_entry(core, key, func, args, kwds) if entry is not None: # pylint: disable=R0101 diff --git a/tests/test_general.py b/tests/test_general.py index f1aa6888..aafd7a11 100644 --- a/tests/test_general.py +++ b/tests/test_general.py @@ -275,3 +275,21 @@ def do_operation(): do_operation() do_operation() assert count == 1 + + +def test_order_independent_kwargs_handling(): + count = 0 + + @cachier.cachier() + def func(a=None, b=None): + nonlocal count + count += 1 + return 0 + + func.clear_cache() + assert count == 0 + func(a=1, b=2) + func(a=1, b=2) + assert count == 1 + func(b=2, a=1) + assert count == 1