However, in practice it's not used that way. This specific LWN article concerns the following code from functools.py:
_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])
It is used like this: def decorating_function(user_function):
wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
...
def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
...
def cache_info():
"""Report cache statistics"""
with lock:
return _CacheInfo(hits, misses, maxsize, cache_len())
The _lru_cache_wrapper is then replaced by a C extension in _functoolsmodule.c which only uses the cache_info_type as: static PyObject *
lru_cache_cache_info(lru_cache_object *self, PyObject *unused)
{
return PyObject_CallFunction(self->cache_info_type, "nnOn",
self->hits, self->misses, self->maxsize_O,
PyDict_GET_SIZE(self->cache));
}
This is basically the same code, just in C.There is no reason for this to expose a tuple API. And yet it does.
>>> @functools.lru_cache(maxsize=None)
... def fib(i):
... if i <= 1: return 1
... return fib(i-1)+fib(i-2)
...
>>> for i in range(10):
... print(i, fib(i))
...
0 1
1 1
2 2
3 3
4 5
5 8
6 13
7 21
8 34
9 55
>>> fib.cache_info()
CacheInfo(hits=17, misses=10, maxsize=None, currsize=10)
>>> for x in fib.cache_info():
... print(x)
...
17
10
None
10
A spot check shows no uses of namedtuple in the Python standard library which are used to keep backwards compatibility with tuples, though I only looked at a few.So while I agree with you, it appears that the core developers do not agree with us.