blob: 30964a6fe3d83a00d420259f9f43b77a432c9804 [file] [log] [blame]
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001"""functools.py - Tools for working with functions and callable objects
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002"""
3# Python module wrapper for _functools C module
4# to allow utilities written in Python to be added
5# to the functools module.
Łukasz Langa6f692512013-06-05 12:20:24 +02006# Written by Nick Coghlan <ncoghlan at gmail.com>,
7# Raymond Hettinger <python at rcn.com>,
8# and Łukasz Langa <lukasz at langa.pl>.
9# Copyright (C) 2006-2013 Python Software Foundation.
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000010# See C source code for _functools credits/copyright
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000011
Georg Brandl2e7346a2010-07-31 18:09:23 +000012__all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES',
Łukasz Langa6f692512013-06-05 12:20:24 +020013 'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial',
Ethan Smithc6512752018-05-26 16:38:33 -040014 'partialmethod', 'singledispatch', 'singledispatchmethod']
Georg Brandl2e7346a2010-07-31 18:09:23 +000015
Łukasz Langa6f692512013-06-05 12:20:24 +020016from abc import get_cache_token
Raymond Hettingerec0e9102012-03-16 01:16:31 -070017from collections import namedtuple
INADA Naoki9811e802017-09-30 16:13:02 +090018# import types, weakref # Deferred to single_dispatch()
Nick Coghlan457fc9a2016-09-10 20:00:02 +100019from reprlib import recursive_repr
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020020from _thread import RLock
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000021
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -070022
23################################################################################
24### update_wrapper() and wraps() decorator
25################################################################################
26
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000027# update_wrapper() and wraps() are tools to help write
28# wrapper functions that can handle naive introspection
29
Meador Ingeff7f64c2011-12-11 22:37:31 -060030WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
31 '__annotations__')
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000032WRAPPER_UPDATES = ('__dict__',)
33def update_wrapper(wrapper,
34 wrapped,
35 assigned = WRAPPER_ASSIGNMENTS,
36 updated = WRAPPER_UPDATES):
37 """Update a wrapper function to look like the wrapped function
38
39 wrapper is the function to be updated
40 wrapped is the original function
41 assigned is a tuple naming the attributes assigned directly
42 from the wrapped function to the wrapper function (defaults to
43 functools.WRAPPER_ASSIGNMENTS)
Thomas Wouters89f507f2006-12-13 04:49:30 +000044 updated is a tuple naming the attributes of the wrapper that
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000045 are updated with the corresponding attribute from the wrapped
46 function (defaults to functools.WRAPPER_UPDATES)
47 """
48 for attr in assigned:
Nick Coghlan98876832010-08-17 06:17:18 +000049 try:
50 value = getattr(wrapped, attr)
51 except AttributeError:
52 pass
53 else:
54 setattr(wrapper, attr, value)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000055 for attr in updated:
Thomas Wouters89f507f2006-12-13 04:49:30 +000056 getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
Nick Coghlan24c05bc2013-07-15 21:13:08 +100057 # Issue #17482: set __wrapped__ last so we don't inadvertently copy it
58 # from the wrapped function when updating __dict__
59 wrapper.__wrapped__ = wrapped
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000060 # Return the wrapper so this can be used as a decorator via partial()
61 return wrapper
62
63def wraps(wrapped,
64 assigned = WRAPPER_ASSIGNMENTS,
65 updated = WRAPPER_UPDATES):
66 """Decorator factory to apply update_wrapper() to a wrapper function
67
68 Returns a decorator that invokes update_wrapper() with the decorated
69 function as the wrapper argument and the arguments to wraps() as the
70 remaining arguments. Default arguments are as for update_wrapper().
71 This is a convenience function to simplify applying partial() to
72 update_wrapper().
73 """
74 return partial(update_wrapper, wrapped=wrapped,
75 assigned=assigned, updated=updated)
Raymond Hettingerc50846a2010-04-05 18:56:31 +000076
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -070077
78################################################################################
79### total_ordering class decorator
80################################################################################
81
Raymond Hettinger0603d302015-01-05 21:52:10 -080082# The total ordering functions all invoke the root magic method directly
83# rather than using the corresponding operator. This avoids possible
84# infinite recursion that could occur when the operator dispatch logic
85# detects a NotImplemented result and then calls a reflected method.
Nick Coghlanf05d9812013-10-02 00:02:03 +100086
Raymond Hettingerffcd8492015-05-12 21:26:37 -070087def _gt_from_lt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -080088 'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).'
89 op_result = self.__lt__(other)
Nick Coghlanf05d9812013-10-02 00:02:03 +100090 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -080091 return op_result
Nick Coghlanf05d9812013-10-02 00:02:03 +100092 return not op_result and self != other
93
Raymond Hettingerffcd8492015-05-12 21:26:37 -070094def _le_from_lt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -080095 'Return a <= b. Computed by @total_ordering from (a < b) or (a == b).'
96 op_result = self.__lt__(other)
97 return op_result or self == other
98
Raymond Hettingerffcd8492015-05-12 21:26:37 -070099def _ge_from_lt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800100 'Return a >= b. Computed by @total_ordering from (not a < b).'
101 op_result = self.__lt__(other)
102 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800103 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800104 return not op_result
105
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700106def _ge_from_le(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800107 'Return a >= b. Computed by @total_ordering from (not a <= b) or (a == b).'
108 op_result = self.__le__(other)
Nick Coghlanf05d9812013-10-02 00:02:03 +1000109 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800110 return op_result
Nick Coghlanf05d9812013-10-02 00:02:03 +1000111 return not op_result or self == other
112
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700113def _lt_from_le(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800114 'Return a < b. Computed by @total_ordering from (a <= b) and (a != b).'
115 op_result = self.__le__(other)
Nick Coghlanf05d9812013-10-02 00:02:03 +1000116 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800117 return op_result
Nick Coghlanf05d9812013-10-02 00:02:03 +1000118 return op_result and self != other
119
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700120def _gt_from_le(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800121 'Return a > b. Computed by @total_ordering from (not a <= b).'
122 op_result = self.__le__(other)
123 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800124 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800125 return not op_result
126
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700127def _lt_from_gt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800128 'Return a < b. Computed by @total_ordering from (not a > b) and (a != b).'
129 op_result = self.__gt__(other)
130 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800131 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800132 return not op_result and self != other
133
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700134def _ge_from_gt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800135 'Return a >= b. Computed by @total_ordering from (a > b) or (a == b).'
136 op_result = self.__gt__(other)
137 return op_result or self == other
138
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700139def _le_from_gt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800140 'Return a <= b. Computed by @total_ordering from (not a > b).'
141 op_result = self.__gt__(other)
142 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800143 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800144 return not op_result
145
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700146def _le_from_ge(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800147 'Return a <= b. Computed by @total_ordering from (not a >= b) or (a == b).'
148 op_result = self.__ge__(other)
149 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800150 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800151 return not op_result or self == other
152
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700153def _gt_from_ge(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800154 'Return a > b. Computed by @total_ordering from (a >= b) and (a != b).'
155 op_result = self.__ge__(other)
156 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800157 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800158 return op_result and self != other
159
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700160def _lt_from_ge(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800161 'Return a < b. Computed by @total_ordering from (not a >= b).'
162 op_result = self.__ge__(other)
163 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800164 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800165 return not op_result
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000166
Raymond Hettinger1a8ada82015-01-13 22:57:35 -0800167_convert = {
168 '__lt__': [('__gt__', _gt_from_lt),
169 ('__le__', _le_from_lt),
170 ('__ge__', _ge_from_lt)],
171 '__le__': [('__ge__', _ge_from_le),
172 ('__lt__', _lt_from_le),
173 ('__gt__', _gt_from_le)],
174 '__gt__': [('__lt__', _lt_from_gt),
175 ('__ge__', _ge_from_gt),
176 ('__le__', _le_from_gt)],
177 '__ge__': [('__le__', _le_from_ge),
178 ('__gt__', _gt_from_ge),
179 ('__lt__', _lt_from_ge)]
180}
181
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000182def total_ordering(cls):
Georg Brandle5a26732010-05-19 21:06:36 +0000183 """Class decorator that fills in missing ordering methods"""
Raymond Hettinger3255c632010-09-16 00:31:21 +0000184 # Find user-defined comparisons (not those inherited from object).
Raymond Hettinger15ce0be2017-09-05 09:40:44 -0700185 roots = {op for op in _convert if getattr(cls, op, None) is not getattr(object, op, None)}
Raymond Hettinger56de7e22010-04-10 16:59:03 +0000186 if not roots:
187 raise ValueError('must define at least one ordering operation: < > <= >=')
188 root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
Raymond Hettinger1a8ada82015-01-13 22:57:35 -0800189 for opname, opfunc in _convert[root]:
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000190 if opname not in roots:
191 opfunc.__name__ = opname
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000192 setattr(cls, opname, opfunc)
193 return cls
194
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700195
196################################################################################
197### cmp_to_key() function converter
198################################################################################
199
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000200def cmp_to_key(mycmp):
Georg Brandle5a26732010-05-19 21:06:36 +0000201 """Convert a cmp= function into a key= function"""
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000202 class K(object):
Raymond Hettingera0d1d962011-03-21 17:50:28 -0700203 __slots__ = ['obj']
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700204 def __init__(self, obj):
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000205 self.obj = obj
206 def __lt__(self, other):
207 return mycmp(self.obj, other.obj) < 0
208 def __gt__(self, other):
209 return mycmp(self.obj, other.obj) > 0
210 def __eq__(self, other):
211 return mycmp(self.obj, other.obj) == 0
212 def __le__(self, other):
213 return mycmp(self.obj, other.obj) <= 0
214 def __ge__(self, other):
215 return mycmp(self.obj, other.obj) >= 0
Raymond Hettinger003be522011-05-03 11:01:32 -0700216 __hash__ = None
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000217 return K
Georg Brandl2e7346a2010-07-31 18:09:23 +0000218
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700219try:
220 from _functools import cmp_to_key
Brett Cannoncd171c82013-07-04 17:43:24 -0400221except ImportError:
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700222 pass
223
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700224
225################################################################################
madman-bobe25d5fc2018-10-25 15:02:10 +0100226### reduce() sequence to a single item
227################################################################################
228
229_initial_missing = object()
230
231def reduce(function, sequence, initial=_initial_missing):
232 """
233 reduce(function, sequence[, initial]) -> value
234
235 Apply a function of two arguments cumulatively to the items of a sequence,
236 from left to right, so as to reduce the sequence to a single value.
237 For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
238 ((((1+2)+3)+4)+5). If initial is present, it is placed before the items
239 of the sequence in the calculation, and serves as a default when the
240 sequence is empty.
241 """
242
243 it = iter(sequence)
244
245 if initial is _initial_missing:
246 try:
247 value = next(it)
248 except StopIteration:
249 raise TypeError("reduce() of empty sequence with no initial value") from None
250 else:
251 value = initial
252
253 for element in it:
254 value = function(value, element)
255
256 return value
257
258try:
259 from _functools import reduce
260except ImportError:
261 pass
262
263
264################################################################################
Antoine Pitroub5b37142012-11-13 21:35:40 +0100265### partial() argument application
266################################################################################
267
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000268# Purely functional, no descriptor behaviour
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000269class partial:
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000270 """New function with partial application of the given arguments
Antoine Pitroub5b37142012-11-13 21:35:40 +0100271 and keywords.
272 """
Alexander Belopolskye49af342015-03-01 15:08:17 -0500273
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000274 __slots__ = "func", "args", "keywords", "__dict__", "__weakref__"
275
276 def __new__(*args, **keywords):
277 if not args:
278 raise TypeError("descriptor '__new__' of partial needs an argument")
279 if len(args) < 2:
280 raise TypeError("type 'partial' takes at least one argument")
281 cls, func, *args = args
282 if not callable(func):
283 raise TypeError("the first argument must be callable")
284 args = tuple(args)
285
286 if hasattr(func, "func"):
287 args = func.args + args
Serhiy Storchakada084702019-03-27 08:02:28 +0200288 keywords = {**func.keywords, **keywords}
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000289 func = func.func
290
291 self = super(partial, cls).__new__(cls)
292
293 self.func = func
294 self.args = args
295 self.keywords = keywords
296 return self
297
298 def __call__(*args, **keywords):
299 if not args:
300 raise TypeError("descriptor '__call__' of partial needs an argument")
301 self, *args = args
Serhiy Storchakada084702019-03-27 08:02:28 +0200302 keywords = {**self.keywords, **keywords}
303 return self.func(*self.args, *args, **keywords)
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000304
305 @recursive_repr()
306 def __repr__(self):
307 qualname = type(self).__qualname__
308 args = [repr(self.func)]
309 args.extend(repr(x) for x in self.args)
310 args.extend(f"{k}={v!r}" for (k, v) in self.keywords.items())
311 if type(self).__module__ == "functools":
312 return f"functools.{qualname}({', '.join(args)})"
313 return f"{qualname}({', '.join(args)})"
314
315 def __reduce__(self):
316 return type(self), (self.func,), (self.func, self.args,
317 self.keywords or None, self.__dict__ or None)
318
319 def __setstate__(self, state):
320 if not isinstance(state, tuple):
321 raise TypeError("argument to __setstate__ must be a tuple")
322 if len(state) != 4:
323 raise TypeError(f"expected 4 items in state, got {len(state)}")
324 func, args, kwds, namespace = state
325 if (not callable(func) or not isinstance(args, tuple) or
326 (kwds is not None and not isinstance(kwds, dict)) or
327 (namespace is not None and not isinstance(namespace, dict))):
328 raise TypeError("invalid partial state")
329
330 args = tuple(args) # just in case it's a subclass
331 if kwds is None:
332 kwds = {}
333 elif type(kwds) is not dict: # XXX does it need to be *exactly* dict?
334 kwds = dict(kwds)
335 if namespace is None:
336 namespace = {}
337
338 self.__dict__ = namespace
339 self.func = func
340 self.args = args
341 self.keywords = kwds
Antoine Pitroub5b37142012-11-13 21:35:40 +0100342
343try:
344 from _functools import partial
Brett Cannoncd171c82013-07-04 17:43:24 -0400345except ImportError:
Antoine Pitroub5b37142012-11-13 21:35:40 +0100346 pass
347
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000348# Descriptor version
349class partialmethod(object):
350 """Method descriptor with partial application of the given arguments
351 and keywords.
352
353 Supports wrapping existing descriptors and handles non-descriptor
354 callables as instance methods.
355 """
356
Serhiy Storchaka42a139e2019-04-01 09:16:35 +0300357 def __init__(*args, **keywords):
358 if len(args) >= 2:
359 self, func, *args = args
360 elif not args:
361 raise TypeError("descriptor '__init__' of partialmethod "
362 "needs an argument")
363 elif 'func' in keywords:
364 func = keywords.pop('func')
365 self, *args = args
366 import warnings
367 warnings.warn("Passing 'func' as keyword argument is deprecated",
368 DeprecationWarning, stacklevel=2)
369 else:
370 raise TypeError("type 'partialmethod' takes at least one argument, "
371 "got %d" % (len(args)-1))
372 args = tuple(args)
373
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000374 if not callable(func) and not hasattr(func, "__get__"):
375 raise TypeError("{!r} is not callable or a descriptor"
376 .format(func))
377
378 # func could be a descriptor like classmethod which isn't callable,
379 # so we can't inherit from partial (it verifies func is callable)
380 if isinstance(func, partialmethod):
381 # flattening is mandatory in order to place cls/self before all
382 # other arguments
383 # it's also more efficient since only one function will be called
384 self.func = func.func
385 self.args = func.args + args
Serhiy Storchakada084702019-03-27 08:02:28 +0200386 self.keywords = {**func.keywords, **keywords}
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000387 else:
388 self.func = func
389 self.args = args
390 self.keywords = keywords
Serhiy Storchakad53cf992019-05-06 22:40:27 +0300391 __init__.__text_signature__ = '($self, func, /, *args, **keywords)'
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000392
393 def __repr__(self):
394 args = ", ".join(map(repr, self.args))
395 keywords = ", ".join("{}={!r}".format(k, v)
396 for k, v in self.keywords.items())
397 format_string = "{module}.{cls}({func}, {args}, {keywords})"
398 return format_string.format(module=self.__class__.__module__,
Serhiy Storchaka521e5862014-07-22 15:00:37 +0300399 cls=self.__class__.__qualname__,
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000400 func=self.func,
401 args=args,
402 keywords=keywords)
403
404 def _make_unbound_method(self):
405 def _method(*args, **keywords):
Serhiy Storchakada084702019-03-27 08:02:28 +0200406 cls_or_self, *args = args
407 keywords = {**self.keywords, **keywords}
408 return self.func(cls_or_self, *self.args, *args, **keywords)
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000409 _method.__isabstractmethod__ = self.__isabstractmethod__
Yury Selivanovda5fe4f2014-01-27 17:28:37 -0500410 _method._partialmethod = self
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000411 return _method
412
413 def __get__(self, obj, cls):
414 get = getattr(self.func, "__get__", None)
415 result = None
416 if get is not None:
417 new_func = get(obj, cls)
418 if new_func is not self.func:
419 # Assume __get__ returning something new indicates the
420 # creation of an appropriate callable
421 result = partial(new_func, *self.args, **self.keywords)
422 try:
423 result.__self__ = new_func.__self__
424 except AttributeError:
425 pass
426 if result is None:
427 # If the underlying descriptor didn't do anything, treat this
428 # like an instance method
429 result = self._make_unbound_method().__get__(obj, cls)
430 return result
431
432 @property
433 def __isabstractmethod__(self):
434 return getattr(self.func, "__isabstractmethod__", False)
435
Pablo Galindo7cd25432018-10-26 12:19:14 +0100436# Helper functions
437
438def _unwrap_partial(func):
439 while isinstance(func, partial):
440 func = func.func
441 return func
Antoine Pitroub5b37142012-11-13 21:35:40 +0100442
443################################################################################
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700444### LRU Cache function decorator
445################################################################################
446
Raymond Hettingerdce583e2012-03-16 22:12:20 -0700447_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])
Nick Coghlan234515a2010-11-30 06:19:46 +0000448
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700449class _HashedSeq(list):
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700450 """ This class guarantees that hash() will be called no more than once
451 per element. This is important because the lru_cache() will hash
452 the key multiple times on a cache miss.
453
454 """
455
Raymond Hettinger9acbb602012-04-30 22:32:16 -0700456 __slots__ = 'hashvalue'
457
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700458 def __init__(self, tup, hash=hash):
459 self[:] = tup
460 self.hashvalue = hash(tup)
Raymond Hettinger9acbb602012-04-30 22:32:16 -0700461
462 def __hash__(self):
463 return self.hashvalue
464
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700465def _make_key(args, kwds, typed,
466 kwd_mark = (object(),),
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500467 fasttypes = {int, str},
Raymond Hettinger4ee39142017-01-08 17:28:20 -0800468 tuple=tuple, type=type, len=len):
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700469 """Make a cache key from optionally typed positional and keyword arguments
470
471 The key is constructed in a way that is flat as possible rather than
472 as a nested structure that would take more memory.
473
474 If there is only a single argument and its data type is known to cache
475 its hash value, then that argument is returned without a wrapper. This
476 saves space and improves lookup speed.
477
478 """
Raymond Hettinger55037092017-09-04 17:47:53 -0700479 # All of code below relies on kwds preserving the order input by the user.
480 # Formerly, we sorted() the kwds before looping. The new way is *much*
481 # faster; however, it means that f(x=1, y=2) will now be treated as a
482 # distinct call from f(y=2, x=1) which will be cached separately.
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700483 key = args
484 if kwds:
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700485 key += kwd_mark
Raymond Hettinger4ee39142017-01-08 17:28:20 -0800486 for item in kwds.items():
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700487 key += item
488 if typed:
489 key += tuple(type(v) for v in args)
490 if kwds:
Raymond Hettinger4ee39142017-01-08 17:28:20 -0800491 key += tuple(type(v) for v in kwds.values())
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700492 elif len(key) == 1 and type(key[0]) in fasttypes:
493 return key[0]
494 return _HashedSeq(key)
495
Raymond Hettinger010ce322012-05-19 21:20:48 -0700496def lru_cache(maxsize=128, typed=False):
Benjamin Peterson1f594ad2010-08-08 13:17:07 +0000497 """Least-recently-used cache decorator.
Georg Brandl2e7346a2010-07-31 18:09:23 +0000498
Raymond Hettingerc79fb0e2010-12-01 03:45:41 +0000499 If *maxsize* is set to None, the LRU features are disabled and the cache
500 can grow without bound.
501
Raymond Hettingercd9fdfd2011-10-20 08:57:45 -0700502 If *typed* is True, arguments of different types will be cached separately.
503 For example, f(3.0) and f(3) will be treated as distinct calls with
504 distinct results.
505
Georg Brandl2e7346a2010-07-31 18:09:23 +0000506 Arguments to the cached function must be hashable.
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000507
Raymond Hettinger7f7a5a72012-03-30 21:50:40 -0700508 View the cache statistics named tuple (hits, misses, maxsize, currsize)
509 with f.cache_info(). Clear the cache and statistics with f.cache_clear().
Raymond Hettinger00f2f972010-12-01 00:47:56 +0000510 Access the underlying function with f.__wrapped__.
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000511
512 See: http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used
Georg Brandl2e7346a2010-07-31 18:09:23 +0000513
Benjamin Peterson1f594ad2010-08-08 13:17:07 +0000514 """
Raymond Hettinger1ff50df2012-03-30 13:15:48 -0700515
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000516 # Users should only access the lru_cache through its public API:
Raymond Hettinger5e20bab2010-11-30 07:13:04 +0000517 # cache_info, cache_clear, and f.__wrapped__
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000518 # The internals of the lru_cache are encapsulated for thread safety and
519 # to allow the implementation to change (including a possible C version).
520
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500521 if isinstance(maxsize, int):
Raymond Hettingerb8218682019-05-26 11:27:35 -0700522 # Negative maxsize is treated as 0
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500523 if maxsize < 0:
524 maxsize = 0
Raymond Hettingerb8218682019-05-26 11:27:35 -0700525 elif callable(maxsize) and isinstance(typed, bool):
526 # The user_function was passed in directly via the maxsize argument
527 user_function, maxsize = maxsize, 128
528 wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
529 return update_wrapper(wrapper, user_function)
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500530 elif maxsize is not None:
Raymond Hettingerb8218682019-05-26 11:27:35 -0700531 raise TypeError(
532 'Expected first argument to be an integer, a callable, or None')
Raymond Hettinger4d588972014-08-12 12:44:52 -0700533
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300534 def decorating_function(user_function):
535 wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
536 return update_wrapper(wrapper, user_function)
537
538 return decorating_function
539
540def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
Raymond Hettinger9f0ab9f2012-04-29 14:55:27 -0700541 # Constants shared by all lru cache instances:
Raymond Hettingerb6b98c02012-04-29 18:09:02 -0700542 sentinel = object() # unique object used to signal cache misses
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700543 make_key = _make_key # build a key from the function arguments
Raymond Hettinger9f0ab9f2012-04-29 14:55:27 -0700544 PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields
545
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300546 cache = {}
547 hits = misses = 0
548 full = False
549 cache_get = cache.get # bound method to lookup a key or return None
Raymond Hettingerb2d4b3d2016-12-16 14:59:37 -0800550 cache_len = cache.__len__ # get cache size without calling len()
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300551 lock = RLock() # because linkedlist updates aren't threadsafe
552 root = [] # root of the circular doubly linked list
553 root[:] = [root, root, None, None] # initialize by pointing to self
Raymond Hettinger6e8c8172012-03-16 16:53:05 -0700554
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300555 if maxsize == 0:
Raymond Hettinger7e0c5812012-03-17 15:10:24 -0700556
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300557 def wrapper(*args, **kwds):
Raymond Hettingerffdf1c32019-01-31 15:03:38 -0800558 # No caching -- just a statistics update
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300559 nonlocal misses
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300560 misses += 1
Raymond Hettingerffdf1c32019-01-31 15:03:38 -0800561 result = user_function(*args, **kwds)
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300562 return result
563
564 elif maxsize is None:
565
566 def wrapper(*args, **kwds):
567 # Simple caching without ordering or size limit
568 nonlocal hits, misses
569 key = make_key(args, kwds, typed)
570 result = cache_get(key, sentinel)
571 if result is not sentinel:
572 hits += 1
Raymond Hettinger7e0c5812012-03-17 15:10:24 -0700573 return result
Raymond Hettingerffdf1c32019-01-31 15:03:38 -0800574 misses += 1
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300575 result = user_function(*args, **kwds)
576 cache[key] = result
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300577 return result
Raymond Hettinger7e0c5812012-03-17 15:10:24 -0700578
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300579 else:
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700580
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300581 def wrapper(*args, **kwds):
582 # Size limited caching that tracks accesses by recency
583 nonlocal root, hits, misses, full
584 key = make_key(args, kwds, typed)
585 with lock:
586 link = cache_get(key)
587 if link is not None:
588 # Move the link to the front of the circular queue
589 link_prev, link_next, _key, result = link
590 link_prev[NEXT] = link_next
591 link_next[PREV] = link_prev
592 last = root[PREV]
593 last[NEXT] = root[PREV] = link
594 link[PREV] = last
595 link[NEXT] = root
Nick Coghlan234515a2010-11-30 06:19:46 +0000596 hits += 1
Raymond Hettinger4b779b32011-10-15 23:50:42 -0700597 return result
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500598 misses += 1
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300599 result = user_function(*args, **kwds)
600 with lock:
601 if key in cache:
602 # Getting here means that this same key was added to the
603 # cache while the lock was released. Since the link
604 # update is already done, we need only return the
605 # computed result and update the count of misses.
606 pass
607 elif full:
608 # Use the old root to store the new key and result.
609 oldroot = root
610 oldroot[KEY] = key
611 oldroot[RESULT] = result
612 # Empty the oldest link and make it the new root.
613 # Keep a reference to the old key and old result to
614 # prevent their ref counts from going to zero during the
615 # update. That will prevent potentially arbitrary object
616 # clean-up code (i.e. __del__) from running while we're
617 # still adjusting the links.
618 root = oldroot[NEXT]
619 oldkey = root[KEY]
620 oldresult = root[RESULT]
621 root[KEY] = root[RESULT] = None
622 # Now update the cache dictionary.
623 del cache[oldkey]
624 # Save the potentially reentrant cache[key] assignment
625 # for last, after the root and links have been put in
626 # a consistent state.
627 cache[key] = oldroot
628 else:
629 # Put result in a new link at the front of the queue.
630 last = root[PREV]
631 link = [last, root, key, result]
632 last[NEXT] = root[PREV] = cache[key] = link
Raymond Hettingerb2d4b3d2016-12-16 14:59:37 -0800633 # Use the cache_len bound method instead of the len() function
Raymond Hettingeraf56e0e2016-12-16 13:57:40 -0800634 # which could potentially be wrapped in an lru_cache itself.
Raymond Hettingerb2d4b3d2016-12-16 14:59:37 -0800635 full = (cache_len() >= maxsize)
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300636 return result
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700637
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300638 def cache_info():
639 """Report cache statistics"""
640 with lock:
Raymond Hettingerb2d4b3d2016-12-16 14:59:37 -0800641 return _CacheInfo(hits, misses, maxsize, cache_len())
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700642
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300643 def cache_clear():
644 """Clear the cache and cache statistics"""
645 nonlocal hits, misses, full
646 with lock:
647 cache.clear()
648 root[:] = [root, root, None, None]
649 hits = misses = 0
650 full = False
Georg Brandl2e7346a2010-07-31 18:09:23 +0000651
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300652 wrapper.cache_info = cache_info
653 wrapper.cache_clear = cache_clear
Serhiy Storchakace2295d2015-10-24 09:51:53 +0300654 return wrapper
Nick Coghlan234515a2010-11-30 06:19:46 +0000655
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300656try:
657 from _functools import _lru_cache_wrapper
658except ImportError:
659 pass
Łukasz Langa6f692512013-06-05 12:20:24 +0200660
661
662################################################################################
663### singledispatch() - single-dispatch generic function decorator
664################################################################################
665
Łukasz Langa3720c772013-07-01 16:00:38 +0200666def _c3_merge(sequences):
667 """Merges MROs in *sequences* to a single MRO using the C3 algorithm.
668
669 Adapted from http://www.python.org/download/releases/2.3/mro/.
670
671 """
672 result = []
673 while True:
674 sequences = [s for s in sequences if s] # purge empty sequences
675 if not sequences:
676 return result
677 for s1 in sequences: # find merge candidates among seq heads
678 candidate = s1[0]
679 for s2 in sequences:
680 if candidate in s2[1:]:
681 candidate = None
682 break # reject the current head, it appears later
683 else:
684 break
Yury Selivanov77a8cd62015-08-18 14:20:00 -0400685 if candidate is None:
Łukasz Langa3720c772013-07-01 16:00:38 +0200686 raise RuntimeError("Inconsistent hierarchy")
687 result.append(candidate)
688 # remove the chosen candidate
689 for seq in sequences:
690 if seq[0] == candidate:
691 del seq[0]
692
693def _c3_mro(cls, abcs=None):
694 """Computes the method resolution order using extended C3 linearization.
695
696 If no *abcs* are given, the algorithm works exactly like the built-in C3
697 linearization used for method resolution.
698
699 If given, *abcs* is a list of abstract base classes that should be inserted
700 into the resulting MRO. Unrelated ABCs are ignored and don't end up in the
701 result. The algorithm inserts ABCs where their functionality is introduced,
702 i.e. issubclass(cls, abc) returns True for the class itself but returns
703 False for all its direct base classes. Implicit ABCs for a given class
704 (either registered or inferred from the presence of a special method like
705 __len__) are inserted directly after the last ABC explicitly listed in the
706 MRO of said class. If two implicit ABCs end up next to each other in the
707 resulting MRO, their ordering depends on the order of types in *abcs*.
708
709 """
710 for i, base in enumerate(reversed(cls.__bases__)):
711 if hasattr(base, '__abstractmethods__'):
712 boundary = len(cls.__bases__) - i
713 break # Bases up to the last explicit ABC are considered first.
714 else:
715 boundary = 0
716 abcs = list(abcs) if abcs else []
717 explicit_bases = list(cls.__bases__[:boundary])
718 abstract_bases = []
719 other_bases = list(cls.__bases__[boundary:])
720 for base in abcs:
721 if issubclass(cls, base) and not any(
722 issubclass(b, base) for b in cls.__bases__
723 ):
724 # If *cls* is the class that introduces behaviour described by
725 # an ABC *base*, insert said ABC to its MRO.
726 abstract_bases.append(base)
727 for base in abstract_bases:
728 abcs.remove(base)
729 explicit_c3_mros = [_c3_mro(base, abcs=abcs) for base in explicit_bases]
730 abstract_c3_mros = [_c3_mro(base, abcs=abcs) for base in abstract_bases]
731 other_c3_mros = [_c3_mro(base, abcs=abcs) for base in other_bases]
732 return _c3_merge(
733 [[cls]] +
734 explicit_c3_mros + abstract_c3_mros + other_c3_mros +
735 [explicit_bases] + [abstract_bases] + [other_bases]
736 )
737
738def _compose_mro(cls, types):
739 """Calculates the method resolution order for a given class *cls*.
740
741 Includes relevant abstract base classes (with their respective bases) from
742 the *types* iterable. Uses a modified C3 linearization algorithm.
Łukasz Langa6f692512013-06-05 12:20:24 +0200743
744 """
745 bases = set(cls.__mro__)
Łukasz Langa3720c772013-07-01 16:00:38 +0200746 # Remove entries which are already present in the __mro__ or unrelated.
747 def is_related(typ):
748 return (typ not in bases and hasattr(typ, '__mro__')
749 and issubclass(cls, typ))
750 types = [n for n in types if is_related(n)]
751 # Remove entries which are strict bases of other entries (they will end up
752 # in the MRO anyway.
753 def is_strict_base(typ):
754 for other in types:
755 if typ != other and typ in other.__mro__:
756 return True
757 return False
758 types = [n for n in types if not is_strict_base(n)]
759 # Subclasses of the ABCs in *types* which are also implemented by
760 # *cls* can be used to stabilize ABC ordering.
761 type_set = set(types)
762 mro = []
763 for typ in types:
764 found = []
765 for sub in typ.__subclasses__():
766 if sub not in bases and issubclass(cls, sub):
767 found.append([s for s in sub.__mro__ if s in type_set])
768 if not found:
769 mro.append(typ)
770 continue
771 # Favor subclasses with the biggest number of useful bases
772 found.sort(key=len, reverse=True)
773 for sub in found:
774 for subcls in sub:
775 if subcls not in mro:
776 mro.append(subcls)
777 return _c3_mro(cls, abcs=mro)
Łukasz Langa6f692512013-06-05 12:20:24 +0200778
779def _find_impl(cls, registry):
Łukasz Langa3720c772013-07-01 16:00:38 +0200780 """Returns the best matching implementation from *registry* for type *cls*.
Łukasz Langa6f692512013-06-05 12:20:24 +0200781
Łukasz Langa3720c772013-07-01 16:00:38 +0200782 Where there is no registered implementation for a specific type, its method
783 resolution order is used to find a more generic implementation.
784
785 Note: if *registry* does not contain an implementation for the base
786 *object* type, this function may return None.
Łukasz Langa6f692512013-06-05 12:20:24 +0200787
788 """
789 mro = _compose_mro(cls, registry.keys())
790 match = None
791 for t in mro:
792 if match is not None:
Łukasz Langa3720c772013-07-01 16:00:38 +0200793 # If *match* is an implicit ABC but there is another unrelated,
794 # equally matching implicit ABC, refuse the temptation to guess.
795 if (t in registry and t not in cls.__mro__
796 and match not in cls.__mro__
797 and not issubclass(match, t)):
Łukasz Langa6f692512013-06-05 12:20:24 +0200798 raise RuntimeError("Ambiguous dispatch: {} or {}".format(
799 match, t))
800 break
801 if t in registry:
802 match = t
803 return registry.get(match)
804
805def singledispatch(func):
806 """Single-dispatch generic function decorator.
807
808 Transforms a function into a generic function, which can have different
809 behaviours depending upon the type of its first argument. The decorated
810 function acts as the default implementation, and additional
Łukasz Langa3720c772013-07-01 16:00:38 +0200811 implementations can be registered using the register() attribute of the
812 generic function.
Łukasz Langa6f692512013-06-05 12:20:24 +0200813 """
INADA Naoki9811e802017-09-30 16:13:02 +0900814 # There are many programs that use functools without singledispatch, so we
815 # trade-off making singledispatch marginally slower for the benefit of
816 # making start-up of such applications slightly faster.
817 import types, weakref
818
Łukasz Langa6f692512013-06-05 12:20:24 +0200819 registry = {}
INADA Naoki9811e802017-09-30 16:13:02 +0900820 dispatch_cache = weakref.WeakKeyDictionary()
Łukasz Langa6f692512013-06-05 12:20:24 +0200821 cache_token = None
822
Łukasz Langa3720c772013-07-01 16:00:38 +0200823 def dispatch(cls):
824 """generic_func.dispatch(cls) -> <function implementation>
Łukasz Langa6f692512013-06-05 12:20:24 +0200825
826 Runs the dispatch algorithm to return the best available implementation
Łukasz Langa3720c772013-07-01 16:00:38 +0200827 for the given *cls* registered on *generic_func*.
Łukasz Langa6f692512013-06-05 12:20:24 +0200828
829 """
830 nonlocal cache_token
831 if cache_token is not None:
832 current_token = get_cache_token()
833 if cache_token != current_token:
834 dispatch_cache.clear()
835 cache_token = current_token
836 try:
Łukasz Langa3720c772013-07-01 16:00:38 +0200837 impl = dispatch_cache[cls]
Łukasz Langa6f692512013-06-05 12:20:24 +0200838 except KeyError:
839 try:
Łukasz Langa3720c772013-07-01 16:00:38 +0200840 impl = registry[cls]
Łukasz Langa6f692512013-06-05 12:20:24 +0200841 except KeyError:
Łukasz Langa3720c772013-07-01 16:00:38 +0200842 impl = _find_impl(cls, registry)
843 dispatch_cache[cls] = impl
Łukasz Langa6f692512013-06-05 12:20:24 +0200844 return impl
845
Łukasz Langa3720c772013-07-01 16:00:38 +0200846 def register(cls, func=None):
847 """generic_func.register(cls, func) -> func
Łukasz Langa6f692512013-06-05 12:20:24 +0200848
Łukasz Langa3720c772013-07-01 16:00:38 +0200849 Registers a new implementation for the given *cls* on a *generic_func*.
Łukasz Langa6f692512013-06-05 12:20:24 +0200850
851 """
852 nonlocal cache_token
853 if func is None:
Łukasz Langae5697532017-12-11 13:56:31 -0800854 if isinstance(cls, type):
855 return lambda f: register(cls, f)
856 ann = getattr(cls, '__annotations__', {})
857 if not ann:
858 raise TypeError(
859 f"Invalid first argument to `register()`: {cls!r}. "
860 f"Use either `@register(some_class)` or plain `@register` "
861 f"on an annotated function."
862 )
863 func = cls
864
865 # only import typing if annotation parsing is necessary
866 from typing import get_type_hints
867 argname, cls = next(iter(get_type_hints(func).items()))
Lysandros Nikolaoud6738102019-05-20 00:11:21 +0200868 if not isinstance(cls, type):
869 raise TypeError(
870 f"Invalid annotation for {argname!r}. "
871 f"{cls!r} is not a class."
872 )
Łukasz Langa3720c772013-07-01 16:00:38 +0200873 registry[cls] = func
874 if cache_token is None and hasattr(cls, '__abstractmethods__'):
Łukasz Langa6f692512013-06-05 12:20:24 +0200875 cache_token = get_cache_token()
876 dispatch_cache.clear()
877 return func
878
879 def wrapper(*args, **kw):
Dong-hee Na445f1b32018-07-10 16:26:36 +0900880 if not args:
881 raise TypeError(f'{funcname} requires at least '
882 '1 positional argument')
883
Łukasz Langa6f692512013-06-05 12:20:24 +0200884 return dispatch(args[0].__class__)(*args, **kw)
885
Dong-hee Na445f1b32018-07-10 16:26:36 +0900886 funcname = getattr(func, '__name__', 'singledispatch function')
Łukasz Langa6f692512013-06-05 12:20:24 +0200887 registry[object] = func
888 wrapper.register = register
889 wrapper.dispatch = dispatch
INADA Naoki9811e802017-09-30 16:13:02 +0900890 wrapper.registry = types.MappingProxyType(registry)
Łukasz Langa6f692512013-06-05 12:20:24 +0200891 wrapper._clear_cache = dispatch_cache.clear
892 update_wrapper(wrapper, func)
893 return wrapper
Ethan Smithc6512752018-05-26 16:38:33 -0400894
895
896# Descriptor version
897class singledispatchmethod:
898 """Single-dispatch generic method descriptor.
899
900 Supports wrapping existing descriptors and handles non-descriptor
901 callables as instance methods.
902 """
903
904 def __init__(self, func):
905 if not callable(func) and not hasattr(func, "__get__"):
906 raise TypeError(f"{func!r} is not callable or a descriptor")
907
908 self.dispatcher = singledispatch(func)
909 self.func = func
910
911 def register(self, cls, method=None):
912 """generic_method.register(cls, func) -> func
913
914 Registers a new implementation for the given *cls* on a *generic_method*.
915 """
916 return self.dispatcher.register(cls, func=method)
917
918 def __get__(self, obj, cls):
919 def _method(*args, **kwargs):
920 method = self.dispatcher.dispatch(args[0].__class__)
921 return method.__get__(obj, cls)(*args, **kwargs)
922
923 _method.__isabstractmethod__ = self.__isabstractmethod__
924 _method.register = self.register
925 update_wrapper(_method, self.func)
926 return _method
927
928 @property
929 def __isabstractmethod__(self):
930 return getattr(self.func, '__isabstractmethod__', False)
Carl Meyerd658dea2018-08-28 01:11:56 -0600931
932
933################################################################################
934### cached_property() - computed once per instance, cached as attribute
935################################################################################
936
937_NOT_FOUND = object()
938
939
940class cached_property:
941 def __init__(self, func):
942 self.func = func
943 self.attrname = None
944 self.__doc__ = func.__doc__
945 self.lock = RLock()
946
947 def __set_name__(self, owner, name):
948 if self.attrname is None:
949 self.attrname = name
950 elif name != self.attrname:
951 raise TypeError(
952 "Cannot assign the same cached_property to two different names "
953 f"({self.attrname!r} and {name!r})."
954 )
955
956 def __get__(self, instance, owner):
957 if instance is None:
958 return self
959 if self.attrname is None:
960 raise TypeError(
961 "Cannot use cached_property instance without calling __set_name__ on it.")
962 try:
963 cache = instance.__dict__
964 except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
965 msg = (
966 f"No '__dict__' attribute on {type(instance).__name__!r} "
967 f"instance to cache {self.attrname!r} property."
968 )
969 raise TypeError(msg) from None
970 val = cache.get(self.attrname, _NOT_FOUND)
971 if val is _NOT_FOUND:
972 with self.lock:
973 # check if another thread filled cache while we awaited lock
974 val = cache.get(self.attrname, _NOT_FOUND)
975 if val is _NOT_FOUND:
976 val = self.func(instance)
977 try:
978 cache[self.attrname] = val
979 except TypeError:
980 msg = (
981 f"The '__dict__' attribute on {type(instance).__name__!r} instance "
982 f"does not support item assignment for caching {self.attrname!r} property."
983 )
984 raise TypeError(msg) from None
985 return val