cardinal_pythonlib.dogpile_cache


Original code copyright (C) 2009-2022 Rudolf Cardinal (rudolf@pobox.com).

This file is part of cardinal_pythonlib.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.


Extensions to dogpile.cache.

  1. The basic cache objects.

  2. FIX FOR DOGPILE.CACHE FOR DECORATED FUNCTIONS, 2017-07-28 (PLUS SOME OTHER IMPROVEMENTS). SEE

    This fixes a crash using type-hinted functions under Python 3.5 with dogpile.cache==0.6.4:

    Traceback (most recent call last):
      File "/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main
        "__main__", mod_spec)
      File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
        exec(code, run_globals)
      File "/home/rudolf/Documents/code/camcops/server/camcops_server/cc_modules/cc_cache.py", line 64, in <module>
        unit_test_cache()
      File "/home/rudolf/Documents/code/camcops/server/camcops_server/cc_modules/cc_cache.py", line 50, in unit_test_cache
        def testfunc() -> str:
      File "/home/rudolf/dev/venvs/camcops/lib/python3.5/site-packages/dogpile/cache/region.py", line 1215, in decorator
        key_generator = function_key_generator(namespace, fn)
      File "/home/rudolf/dev/venvs/camcops/lib/python3.5/site-packages/dogpile/cache/util.py", line 31, in function_key_generator
        args = inspect.getargspec(fn)
      File "/usr/lib/python3.5/inspect.py", line 1045, in getargspec
        raise ValueError("Function has keyword-only arguments or annotations"
    ValueError: Function has keyword-only arguments or annotations, use getfullargspec() API which can support them
    
  3. Other improvements include:

    • the cache decorators operate as:
      • PER-INSTANCE caches for class instances, provided the first parameter is named “self”;

      • PER-CLASS caches for classmethods, provided the first parameter is named “cls”;

      • PER-FUNCTION caches for staticmethods and plain functions

    • keyword arguments are supported

    • properties are supported (the @property decorator must be ABOVE the cache decorator)

    • Note that this sort of cache relies on the generation of a STRING KEY from the function arguments. It uses the hex(id()) function for self/cls arguments, and the to_str() function, passed as a parameter, for others (for which the default is "repr"; see discussion below as to why "repr" is suitable while "str" is not).

cardinal_pythonlib.dogpile_cache.fkg(namespace: str | None, fn: ~typing.Callable, to_str: ~typing.Callable[[~typing.Any], str] = <built-in function repr>) Callable[[Any], str]

As for fkg_allowing_type_hints(), but allowing keyword arguments.

For kwargs passed in, we will build a dict of all argname (key) to argvalue (values) pairs, including default args from the argspec, and then alphabetize the list before generating the key.

NOTE ALSO that once we have keyword arguments, we should be using repr(), because we need to distinguish

kwargs = {'p': 'another', 'q': 'thing'}
# ... which compat.string_type will make into
#         p=another q=thing
# ... from
kwargs = {'p': 'another q=thing'}

Also modified to make the cached function unique per INSTANCE for normal methods of a class.

cardinal_pythonlib.dogpile_cache.fkg_allowing_type_hints(namespace: str | None, fn: ~typing.Callable, to_str: ~typing.Callable[[~typing.Any], str] = <built-in function repr>) Callable[[Any], str][source]

Replacement for dogpile.cache.util.function_key_generator() that handles type-hinted functions like

def testfunc(param: str) -> str:
    return param + "hello"

… at which inspect.getargspec() balks; plus inspect.getargspec() is deprecated in Python 3.

Used as an argument to e.g. @cache_region_static.cache_on_arguments().

Also modified to make the cached function unique per INSTANCE for normal methods of a class.

Parameters:
  • namespace – optional namespace, as per get_namespace()

  • fn – function to generate a key for (usually the function being decorated)

  • to_str – function to apply to map arguments to a string (to make a unique key for a particular call to the function); by default it is repr()

Returns:

a function that generates a string key, based on a given function as well as arguments to the returned function itself.

cardinal_pythonlib.dogpile_cache.get_namespace(fn: Callable, namespace: str | None) str[source]

Returns a representation of a function’s name (perhaps within a namespace), like

mymodule:MyClass.myclassfunc  # with no namespace
mymodule:MyClass.myclassfunc|somenamespace  # with a namespace
Parameters:
cardinal_pythonlib.dogpile_cache.kw_fkg_allowing_type_hints(namespace: str | None, fn: ~typing.Callable, to_str: ~typing.Callable[[~typing.Any], str] = <built-in function repr>) Callable[[Any], str][source]

As for fkg_allowing_type_hints(), but allowing keyword arguments.

For kwargs passed in, we will build a dict of all argname (key) to argvalue (values) pairs, including default args from the argspec, and then alphabetize the list before generating the key.

NOTE ALSO that once we have keyword arguments, we should be using repr(), because we need to distinguish

kwargs = {'p': 'another', 'q': 'thing'}
# ... which compat.string_type will make into
#         p=another q=thing
# ... from
kwargs = {'p': 'another q=thing'}

Also modified to make the cached function unique per INSTANCE for normal methods of a class.

cardinal_pythonlib.dogpile_cache.multikey_fkg_allowing_type_hints(namespace: str | None, fn: ~typing.Callable, to_str: ~typing.Callable[[~typing.Any], str] = <built-in function repr>) Callable[[Any], List[str]][source]

Equivalent of dogpile.cache.util.function_multi_key_generator(), but using inspect.signature() instead.

Also modified to make the cached function unique per INSTANCE for normal methods of a class.

cardinal_pythonlib.dogpile_cache.repr_parameter(param: Parameter) str[source]

Provides a repr-style representation of a function parameter.