New GitHub issue #101016 from tewalds:<br>

<hr>

<pre>
Say you have a function:
```
def expensive_func(arr: np.ndarray, value: int) -> np.ndarray:
  ...
```
that is expensive but called with the same values repeatedly. Ideally you'd wrap it in the `functools.cache` (or `lru_cache`) decorator and call it done, but `np.ndarray` is not hashable, so instead you get an exception.

Currently you'd have to have to create your own cache dict.
```
_CACHE = {}
def expensive_func(arr: np.ndarray, value: int) -> np.ndarray:
  key = (tuple(arr), value)
  if key not in _CACHE:
    _CACHE[key] = ...
  return _CACHE[key]
```
or maybe wrap your function in such a way that the args are hashable, which adds a lot of boilerplate.

Instead I'd like to see something like:
```
@functools.cache(key=lambda args, value: (tuple(arr), value))
def expensive_func(arr: np.ndarray, value: int) -> np.ndarray:
   ...
```
Looking at the implementation of `lru_cache` there's already a `_make_key` function: https://github.com/python/cpython/blob/3.11/Lib/functools.py#L448 . I'm mainly proposing letting you supply that function yourself. The default would remain as is, requiring hashable args.
</pre>

<hr>

<a href="https://github.com/python/cpython/issues/101016">View on GitHub</a>
<p>Labels: type-feature</p>
<p>Assignee: </p>