blob: 050bec86051179448ad120df49a85cac94a9b4e0 [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',
Pablo Galindo99e6c262020-01-23 15:29:52 +000013 'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce',
14 'TopologicalSorter', 'CycleError',
15 'partial', 'partialmethod', 'singledispatch', 'singledispatchmethod']
Georg Brandl2e7346a2010-07-31 18:09:23 +000016
Łukasz Langa6f692512013-06-05 12:20:24 +020017from abc import get_cache_token
Raymond Hettingerec0e9102012-03-16 01:16:31 -070018from collections import namedtuple
INADA Naoki9811e802017-09-30 16:13:02 +090019# import types, weakref # Deferred to single_dispatch()
Nick Coghlan457fc9a2016-09-10 20:00:02 +100020from reprlib import recursive_repr
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020021from _thread import RLock
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000022
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -070023
24################################################################################
25### update_wrapper() and wraps() decorator
26################################################################################
27
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000028# update_wrapper() and wraps() are tools to help write
29# wrapper functions that can handle naive introspection
30
Meador Ingeff7f64c2011-12-11 22:37:31 -060031WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
32 '__annotations__')
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000033WRAPPER_UPDATES = ('__dict__',)
34def update_wrapper(wrapper,
35 wrapped,
36 assigned = WRAPPER_ASSIGNMENTS,
37 updated = WRAPPER_UPDATES):
38 """Update a wrapper function to look like the wrapped function
39
40 wrapper is the function to be updated
41 wrapped is the original function
42 assigned is a tuple naming the attributes assigned directly
43 from the wrapped function to the wrapper function (defaults to
44 functools.WRAPPER_ASSIGNMENTS)
Thomas Wouters89f507f2006-12-13 04:49:30 +000045 updated is a tuple naming the attributes of the wrapper that
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000046 are updated with the corresponding attribute from the wrapped
47 function (defaults to functools.WRAPPER_UPDATES)
48 """
49 for attr in assigned:
Nick Coghlan98876832010-08-17 06:17:18 +000050 try:
51 value = getattr(wrapped, attr)
52 except AttributeError:
53 pass
54 else:
55 setattr(wrapper, attr, value)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000056 for attr in updated:
Thomas Wouters89f507f2006-12-13 04:49:30 +000057 getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
Nick Coghlan24c05bc2013-07-15 21:13:08 +100058 # Issue #17482: set __wrapped__ last so we don't inadvertently copy it
59 # from the wrapped function when updating __dict__
60 wrapper.__wrapped__ = wrapped
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000061 # Return the wrapper so this can be used as a decorator via partial()
62 return wrapper
63
64def wraps(wrapped,
65 assigned = WRAPPER_ASSIGNMENTS,
66 updated = WRAPPER_UPDATES):
67 """Decorator factory to apply update_wrapper() to a wrapper function
68
69 Returns a decorator that invokes update_wrapper() with the decorated
70 function as the wrapper argument and the arguments to wraps() as the
71 remaining arguments. Default arguments are as for update_wrapper().
72 This is a convenience function to simplify applying partial() to
73 update_wrapper().
74 """
75 return partial(update_wrapper, wrapped=wrapped,
76 assigned=assigned, updated=updated)
Raymond Hettingerc50846a2010-04-05 18:56:31 +000077
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -070078
79################################################################################
80### total_ordering class decorator
81################################################################################
82
Raymond Hettinger0603d302015-01-05 21:52:10 -080083# The total ordering functions all invoke the root magic method directly
84# rather than using the corresponding operator. This avoids possible
85# infinite recursion that could occur when the operator dispatch logic
86# detects a NotImplemented result and then calls a reflected method.
Nick Coghlanf05d9812013-10-02 00:02:03 +100087
Raymond Hettingerffcd8492015-05-12 21:26:37 -070088def _gt_from_lt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -080089 'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).'
90 op_result = self.__lt__(other)
Nick Coghlanf05d9812013-10-02 00:02:03 +100091 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -080092 return op_result
Nick Coghlanf05d9812013-10-02 00:02:03 +100093 return not op_result and self != other
94
Raymond Hettingerffcd8492015-05-12 21:26:37 -070095def _le_from_lt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -080096 'Return a <= b. Computed by @total_ordering from (a < b) or (a == b).'
97 op_result = self.__lt__(other)
98 return op_result or self == other
99
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700100def _ge_from_lt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800101 'Return a >= b. Computed by @total_ordering from (not a < b).'
102 op_result = self.__lt__(other)
103 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800104 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800105 return not op_result
106
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700107def _ge_from_le(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800108 'Return a >= b. Computed by @total_ordering from (not a <= b) or (a == b).'
109 op_result = self.__le__(other)
Nick Coghlanf05d9812013-10-02 00:02:03 +1000110 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800111 return op_result
Nick Coghlanf05d9812013-10-02 00:02:03 +1000112 return not op_result or self == other
113
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700114def _lt_from_le(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800115 'Return a < b. Computed by @total_ordering from (a <= b) and (a != b).'
116 op_result = self.__le__(other)
Nick Coghlanf05d9812013-10-02 00:02:03 +1000117 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800118 return op_result
Nick Coghlanf05d9812013-10-02 00:02:03 +1000119 return op_result and self != other
120
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700121def _gt_from_le(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800122 'Return a > b. Computed by @total_ordering from (not a <= b).'
123 op_result = self.__le__(other)
124 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800125 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800126 return not op_result
127
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700128def _lt_from_gt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800129 'Return a < b. Computed by @total_ordering from (not a > b) and (a != b).'
130 op_result = self.__gt__(other)
131 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800132 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800133 return not op_result and self != other
134
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700135def _ge_from_gt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800136 'Return a >= b. Computed by @total_ordering from (a > b) or (a == b).'
137 op_result = self.__gt__(other)
138 return op_result or self == other
139
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700140def _le_from_gt(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800141 'Return a <= b. Computed by @total_ordering from (not a > b).'
142 op_result = self.__gt__(other)
143 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800144 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800145 return not op_result
146
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700147def _le_from_ge(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800148 'Return a <= b. Computed by @total_ordering from (not a >= b) or (a == b).'
149 op_result = self.__ge__(other)
150 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800151 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800152 return not op_result or self == other
153
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700154def _gt_from_ge(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800155 'Return a > b. Computed by @total_ordering from (a >= b) and (a != b).'
156 op_result = self.__ge__(other)
157 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800158 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800159 return op_result and self != other
160
Raymond Hettingerffcd8492015-05-12 21:26:37 -0700161def _lt_from_ge(self, other, NotImplemented=NotImplemented):
Raymond Hettinger0603d302015-01-05 21:52:10 -0800162 'Return a < b. Computed by @total_ordering from (not a >= b).'
163 op_result = self.__ge__(other)
164 if op_result is NotImplemented:
Raymond Hettingere5db8632015-01-06 22:16:10 -0800165 return op_result
Raymond Hettinger0603d302015-01-05 21:52:10 -0800166 return not op_result
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000167
Raymond Hettinger1a8ada82015-01-13 22:57:35 -0800168_convert = {
169 '__lt__': [('__gt__', _gt_from_lt),
170 ('__le__', _le_from_lt),
171 ('__ge__', _ge_from_lt)],
172 '__le__': [('__ge__', _ge_from_le),
173 ('__lt__', _lt_from_le),
174 ('__gt__', _gt_from_le)],
175 '__gt__': [('__lt__', _lt_from_gt),
176 ('__ge__', _ge_from_gt),
177 ('__le__', _le_from_gt)],
178 '__ge__': [('__le__', _le_from_ge),
179 ('__gt__', _gt_from_ge),
180 ('__lt__', _lt_from_ge)]
181}
182
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000183def total_ordering(cls):
Georg Brandle5a26732010-05-19 21:06:36 +0000184 """Class decorator that fills in missing ordering methods"""
Raymond Hettinger3255c632010-09-16 00:31:21 +0000185 # Find user-defined comparisons (not those inherited from object).
Raymond Hettinger15ce0be2017-09-05 09:40:44 -0700186 roots = {op for op in _convert if getattr(cls, op, None) is not getattr(object, op, None)}
Raymond Hettinger56de7e22010-04-10 16:59:03 +0000187 if not roots:
188 raise ValueError('must define at least one ordering operation: < > <= >=')
189 root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
Raymond Hettinger1a8ada82015-01-13 22:57:35 -0800190 for opname, opfunc in _convert[root]:
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000191 if opname not in roots:
192 opfunc.__name__ = opname
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000193 setattr(cls, opname, opfunc)
194 return cls
195
Pablo Galindo99e6c262020-01-23 15:29:52 +0000196################################################################################
197### topological sort
198################################################################################
199
200_NODE_OUT = -1
201_NODE_DONE = -2
202
203
204class _NodeInfo:
205 __slots__ = 'node', 'npredecessors', 'successors'
206
207 def __init__(self, node):
208 # The node this class is augmenting.
209 self.node = node
210
211 # Number of predecessors, generally >= 0. When this value falls to 0,
212 # and is returned by get_ready(), this is set to _NODE_OUT and when the
213 # node is marked done by a call to done(), set to _NODE_DONE.
214 self.npredecessors = 0
215
216 # List of successor nodes. The list can contain duplicated elements as
217 # long as they're all reflected in the successor's npredecessors attribute).
218 self.successors = []
219
220
221class CycleError(ValueError):
222 """Subclass of ValueError raised by TopologicalSorterif cycles exist in the graph
223
224 If multiple cycles exist, only one undefined choice among them will be reported
225 and included in the exception. The detected cycle can be accessed via the second
226 element in the *args* attribute of the exception instance and consists in a list
227 of nodes, such that each node is, in the graph, an immediate predecessor of the
228 next node in the list. In the reported list, the first and the last node will be
229 the same, to make it clear that it is cyclic.
230 """
231 pass
232
233
234class TopologicalSorter:
235 """Provides functionality to topologically sort a graph of hashable nodes"""
236
237 def __init__(self, graph=None):
238 self._node2info = {}
239 self._ready_nodes = None
240 self._npassedout = 0
241 self._nfinished = 0
242
243 if graph is not None:
244 for node, predecessors in graph.items():
245 self.add(node, *predecessors)
246
247 def _get_nodeinfo(self, node):
248 if (result := self._node2info.get(node)) is None:
249 self._node2info[node] = result = _NodeInfo(node)
250 return result
251
252 def add(self, node, *predecessors):
253 """Add a new node and its predecessors to the graph.
254
255 Both the *node* and all elements in *predecessors* must be hashable.
256
257 If called multiple times with the same node argument, the set of dependencies
258 will be the union of all dependencies passed in.
259
260 It is possible to add a node with no dependencies (*predecessors* is not provided)
261 as well as provide a dependency twice. If a node that has not been provided before
262 is included among *predecessors* it will be automatically added to the graph with
263 no predecessors of its own.
264
265 Raises ValueError if called after "prepare".
266 """
267 if self._ready_nodes is not None:
268 raise ValueError("Nodes cannot be added after a call to prepare()")
269
270 # Create the node -> predecessor edges
271 nodeinfo = self._get_nodeinfo(node)
272 nodeinfo.npredecessors += len(predecessors)
273
274 # Create the predecessor -> node edges
275 for pred in predecessors:
276 pred_info = self._get_nodeinfo(pred)
277 pred_info.successors.append(node)
278
279 def prepare(self):
280 """Mark the graph as finished and check for cycles in the graph.
281
282 If any cycle is detected, "CycleError" will be raised, but "get_ready" can
283 still be used to obtain as many nodes as possible until cycles block more
284 progress. After a call to this function, the graph cannot be modified and
285 therefore no more nodes can be added using "add".
286 """
287 if self._ready_nodes is not None:
288 raise ValueError("cannot prepare() more than once")
289
290 self._ready_nodes = [i.node for i in self._node2info.values()
291 if i.npredecessors == 0]
292 # ready_nodes is set before we look for cycles on purpose:
293 # if the user wants to catch the CycleError, that's fine,
294 # they can continue using the instance to grab as many
295 # nodes as possible before cycles block more progress
296 cycle = self._find_cycle()
297 if cycle:
298 raise CycleError(f"nodes are in a cycle", cycle)
299
300 def get_ready(self):
301 """Return a tuple of all the nodes that are ready.
302
303 Initially it returns all nodes with no predecessors; once those are marked
304 as processed by calling "done", further calls will return all new nodes that
305 have all their predecessors already processed. Once no more progress can be made,
306 empty tuples are returned.
307
308 Raises ValueError if called without calling "prepare" previously.
309 """
310 if self._ready_nodes is None:
311 raise ValueError("prepare() must be called first")
312
313 # Get the nodes that are ready and mark them
314 result = tuple(self._ready_nodes)
315 n2i = self._node2info
316 for node in result:
317 n2i[node].npredecessors = _NODE_OUT
318
319 # Clean the list of nodes that are ready and update
320 # the counter of nodes that we have returned.
321 self._ready_nodes.clear()
322 self._npassedout += len(result)
323
324 return result
325
326 def is_active(self):
327 """Return True if more progress can be made and ``False`` otherwise.
328
329 Progress can be made if cycles do not block the resolution and either there
330 are still nodes ready that haven't yet been returned by "get_ready" or the
331 number of nodes marked "done" is less than the number that have been returned
332 by "get_ready".
333
334 Raises ValueError if called without calling "prepare" previously.
335 """
336 if self._ready_nodes is None:
337 raise ValueError("prepare() must be called first")
338 return self._nfinished < self._npassedout or bool(self._ready_nodes)
339
340 def __bool__(self):
341 return self.is_active()
342
343 def done(self, *nodes):
344 """Marks a set of nodes returned by "get_ready" as processed.
345
346 This method unblocks any successor of each node in *nodes* for being returned
347 in the future by a a call to "get_ready"
348
349 Raises :exec:`ValueError` if any node in *nodes* has already been marked as
350 processed by a previous call to this method, if a node was not added to the
351 graph by using "add" or if called without calling "prepare" previously or if
352 node has not yet been returned by "get_ready".
353 """
354
355 if self._ready_nodes is None:
356 raise ValueError("prepare() must be called first")
357
358 n2i = self._node2info
359
360 for node in nodes:
361
362 # Check if we know about this node (it was added previously using add()
363 if (nodeinfo := n2i.get(node)) is None:
364 raise ValueError(f"node {node!r} was not added using add()")
365
366 # If the node has not being returned (marked as ready) previously, inform the user.
367 stat = nodeinfo.npredecessors
368 if stat != _NODE_OUT:
369 if stat >= 0:
370 raise ValueError(f"node {node!r} was not passed out (still not ready)")
371 elif stat == _NODE_DONE:
372 raise ValueError(f"node {node!r} was already marked done")
373 else:
374 assert False, f"node {node!r}: unknown status {stat}"
375
376 # Mark the node as processed
377 nodeinfo.npredecessors = _NODE_DONE
378
379 # Go to all the successors and reduce the number of predecessors, collecting all the ones
380 # that are ready to be returned in the next get_ready() call.
381 for successor in nodeinfo.successors:
382 successor_info = n2i[successor]
383 successor_info.npredecessors -= 1
384 if successor_info.npredecessors == 0:
385 self._ready_nodes.append(successor)
386 self._nfinished += 1
387
388 def _find_cycle(self):
389 n2i = self._node2info
390 stack = []
391 itstack = []
392 seen = set()
393 node2stacki = {}
394
395 for node in n2i:
396 if node in seen:
397 continue
398
399 while True:
400 if node in seen:
401 # If we have seen already the node and is in the
402 # current stack we have found a cycle.
403 if node in node2stacki:
404 return stack[node2stacki[node]:] + [node]
405 # else go on to get next successor
406 else:
407 seen.add(node)
408 itstack.append(iter(n2i[node].successors).__next__)
409 node2stacki[node] = len(stack)
410 stack.append(node)
411
412 # Backtrack to the topmost stack entry with
413 # at least another successor.
414 while stack:
415 try:
416 node = itstack[-1]()
417 break
418 except StopIteration:
419 del node2stacki[stack.pop()]
420 itstack.pop()
421 else:
422 break
423 return None
424
425 def static_order(self):
426 """Returns an iterable of nodes in a topological order.
427
428 The particular order that is returned may depend on the specific
429 order in which the items were inserted in the graph.
430
431 Using this method does not require to call "prepare" or "done". If any
432 cycle is detected, :exc:`CycleError` will be raised.
433 """
434 self.prepare()
435 while self.is_active():
436 node_group = self.get_ready()
437 yield from node_group
438 self.done(*node_group)
439
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700440
441################################################################################
442### cmp_to_key() function converter
443################################################################################
444
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000445def cmp_to_key(mycmp):
Georg Brandle5a26732010-05-19 21:06:36 +0000446 """Convert a cmp= function into a key= function"""
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000447 class K(object):
Raymond Hettingera0d1d962011-03-21 17:50:28 -0700448 __slots__ = ['obj']
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700449 def __init__(self, obj):
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000450 self.obj = obj
451 def __lt__(self, other):
452 return mycmp(self.obj, other.obj) < 0
453 def __gt__(self, other):
454 return mycmp(self.obj, other.obj) > 0
455 def __eq__(self, other):
456 return mycmp(self.obj, other.obj) == 0
457 def __le__(self, other):
458 return mycmp(self.obj, other.obj) <= 0
459 def __ge__(self, other):
460 return mycmp(self.obj, other.obj) >= 0
Raymond Hettinger003be522011-05-03 11:01:32 -0700461 __hash__ = None
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000462 return K
Georg Brandl2e7346a2010-07-31 18:09:23 +0000463
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700464try:
465 from _functools import cmp_to_key
Brett Cannoncd171c82013-07-04 17:43:24 -0400466except ImportError:
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700467 pass
468
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700469
470################################################################################
madman-bobe25d5fc2018-10-25 15:02:10 +0100471### reduce() sequence to a single item
472################################################################################
473
474_initial_missing = object()
475
476def reduce(function, sequence, initial=_initial_missing):
477 """
478 reduce(function, sequence[, initial]) -> value
479
480 Apply a function of two arguments cumulatively to the items of a sequence,
481 from left to right, so as to reduce the sequence to a single value.
482 For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
483 ((((1+2)+3)+4)+5). If initial is present, it is placed before the items
484 of the sequence in the calculation, and serves as a default when the
485 sequence is empty.
486 """
487
488 it = iter(sequence)
489
490 if initial is _initial_missing:
491 try:
492 value = next(it)
493 except StopIteration:
494 raise TypeError("reduce() of empty sequence with no initial value") from None
495 else:
496 value = initial
497
498 for element in it:
499 value = function(value, element)
500
501 return value
502
503try:
504 from _functools import reduce
505except ImportError:
506 pass
507
508
509################################################################################
Antoine Pitroub5b37142012-11-13 21:35:40 +0100510### partial() argument application
511################################################################################
512
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000513# Purely functional, no descriptor behaviour
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000514class partial:
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000515 """New function with partial application of the given arguments
Antoine Pitroub5b37142012-11-13 21:35:40 +0100516 and keywords.
517 """
Alexander Belopolskye49af342015-03-01 15:08:17 -0500518
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000519 __slots__ = "func", "args", "keywords", "__dict__", "__weakref__"
520
Serhiy Storchaka2085bd02019-06-01 11:00:15 +0300521 def __new__(cls, func, /, *args, **keywords):
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000522 if not callable(func):
523 raise TypeError("the first argument must be callable")
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000524
525 if hasattr(func, "func"):
526 args = func.args + args
Serhiy Storchakada084702019-03-27 08:02:28 +0200527 keywords = {**func.keywords, **keywords}
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000528 func = func.func
529
530 self = super(partial, cls).__new__(cls)
531
532 self.func = func
533 self.args = args
534 self.keywords = keywords
535 return self
536
Serhiy Storchaka2085bd02019-06-01 11:00:15 +0300537 def __call__(self, /, *args, **keywords):
Serhiy Storchakada084702019-03-27 08:02:28 +0200538 keywords = {**self.keywords, **keywords}
539 return self.func(*self.args, *args, **keywords)
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000540
541 @recursive_repr()
542 def __repr__(self):
543 qualname = type(self).__qualname__
544 args = [repr(self.func)]
545 args.extend(repr(x) for x in self.args)
546 args.extend(f"{k}={v!r}" for (k, v) in self.keywords.items())
547 if type(self).__module__ == "functools":
548 return f"functools.{qualname}({', '.join(args)})"
549 return f"{qualname}({', '.join(args)})"
550
551 def __reduce__(self):
552 return type(self), (self.func,), (self.func, self.args,
553 self.keywords or None, self.__dict__ or None)
554
555 def __setstate__(self, state):
556 if not isinstance(state, tuple):
557 raise TypeError("argument to __setstate__ must be a tuple")
558 if len(state) != 4:
559 raise TypeError(f"expected 4 items in state, got {len(state)}")
560 func, args, kwds, namespace = state
561 if (not callable(func) or not isinstance(args, tuple) or
562 (kwds is not None and not isinstance(kwds, dict)) or
563 (namespace is not None and not isinstance(namespace, dict))):
564 raise TypeError("invalid partial state")
565
566 args = tuple(args) # just in case it's a subclass
567 if kwds is None:
568 kwds = {}
569 elif type(kwds) is not dict: # XXX does it need to be *exactly* dict?
570 kwds = dict(kwds)
571 if namespace is None:
572 namespace = {}
573
574 self.__dict__ = namespace
575 self.func = func
576 self.args = args
577 self.keywords = kwds
Antoine Pitroub5b37142012-11-13 21:35:40 +0100578
579try:
580 from _functools import partial
Brett Cannoncd171c82013-07-04 17:43:24 -0400581except ImportError:
Antoine Pitroub5b37142012-11-13 21:35:40 +0100582 pass
583
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000584# Descriptor version
585class partialmethod(object):
586 """Method descriptor with partial application of the given arguments
587 and keywords.
588
589 Supports wrapping existing descriptors and handles non-descriptor
590 callables as instance methods.
591 """
592
Serhiy Storchaka142566c2019-06-05 18:22:31 +0300593 def __init__(self, func, /, *args, **keywords):
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000594 if not callable(func) and not hasattr(func, "__get__"):
595 raise TypeError("{!r} is not callable or a descriptor"
596 .format(func))
597
598 # func could be a descriptor like classmethod which isn't callable,
599 # so we can't inherit from partial (it verifies func is callable)
600 if isinstance(func, partialmethod):
601 # flattening is mandatory in order to place cls/self before all
602 # other arguments
603 # it's also more efficient since only one function will be called
604 self.func = func.func
605 self.args = func.args + args
Serhiy Storchakada084702019-03-27 08:02:28 +0200606 self.keywords = {**func.keywords, **keywords}
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000607 else:
608 self.func = func
609 self.args = args
610 self.keywords = keywords
611
612 def __repr__(self):
613 args = ", ".join(map(repr, self.args))
614 keywords = ", ".join("{}={!r}".format(k, v)
615 for k, v in self.keywords.items())
616 format_string = "{module}.{cls}({func}, {args}, {keywords})"
617 return format_string.format(module=self.__class__.__module__,
Serhiy Storchaka521e5862014-07-22 15:00:37 +0300618 cls=self.__class__.__qualname__,
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000619 func=self.func,
620 args=args,
621 keywords=keywords)
622
623 def _make_unbound_method(self):
Serhiy Storchaka2085bd02019-06-01 11:00:15 +0300624 def _method(cls_or_self, /, *args, **keywords):
Serhiy Storchakada084702019-03-27 08:02:28 +0200625 keywords = {**self.keywords, **keywords}
626 return self.func(cls_or_self, *self.args, *args, **keywords)
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000627 _method.__isabstractmethod__ = self.__isabstractmethod__
Yury Selivanovda5fe4f2014-01-27 17:28:37 -0500628 _method._partialmethod = self
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000629 return _method
630
Raymond Hettinger0dac68f2019-08-29 01:27:42 -0700631 def __get__(self, obj, cls=None):
Nick Coghlanf4cb48a2013-11-03 16:41:46 +1000632 get = getattr(self.func, "__get__", None)
633 result = None
634 if get is not None:
635 new_func = get(obj, cls)
636 if new_func is not self.func:
637 # Assume __get__ returning something new indicates the
638 # creation of an appropriate callable
639 result = partial(new_func, *self.args, **self.keywords)
640 try:
641 result.__self__ = new_func.__self__
642 except AttributeError:
643 pass
644 if result is None:
645 # If the underlying descriptor didn't do anything, treat this
646 # like an instance method
647 result = self._make_unbound_method().__get__(obj, cls)
648 return result
649
650 @property
651 def __isabstractmethod__(self):
652 return getattr(self.func, "__isabstractmethod__", False)
653
Pablo Galindo7cd25432018-10-26 12:19:14 +0100654# Helper functions
655
656def _unwrap_partial(func):
657 while isinstance(func, partial):
658 func = func.func
659 return func
Antoine Pitroub5b37142012-11-13 21:35:40 +0100660
661################################################################################
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700662### LRU Cache function decorator
663################################################################################
664
Raymond Hettingerdce583e2012-03-16 22:12:20 -0700665_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])
Nick Coghlan234515a2010-11-30 06:19:46 +0000666
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700667class _HashedSeq(list):
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700668 """ This class guarantees that hash() will be called no more than once
669 per element. This is important because the lru_cache() will hash
670 the key multiple times on a cache miss.
671
672 """
673
Raymond Hettinger9acbb602012-04-30 22:32:16 -0700674 __slots__ = 'hashvalue'
675
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700676 def __init__(self, tup, hash=hash):
677 self[:] = tup
678 self.hashvalue = hash(tup)
Raymond Hettinger9acbb602012-04-30 22:32:16 -0700679
680 def __hash__(self):
681 return self.hashvalue
682
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700683def _make_key(args, kwds, typed,
684 kwd_mark = (object(),),
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500685 fasttypes = {int, str},
Raymond Hettinger4ee39142017-01-08 17:28:20 -0800686 tuple=tuple, type=type, len=len):
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700687 """Make a cache key from optionally typed positional and keyword arguments
688
689 The key is constructed in a way that is flat as possible rather than
690 as a nested structure that would take more memory.
691
692 If there is only a single argument and its data type is known to cache
693 its hash value, then that argument is returned without a wrapper. This
694 saves space and improves lookup speed.
695
696 """
Raymond Hettinger55037092017-09-04 17:47:53 -0700697 # All of code below relies on kwds preserving the order input by the user.
698 # Formerly, we sorted() the kwds before looping. The new way is *much*
699 # faster; however, it means that f(x=1, y=2) will now be treated as a
700 # distinct call from f(y=2, x=1) which will be cached separately.
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700701 key = args
702 if kwds:
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700703 key += kwd_mark
Raymond Hettinger4ee39142017-01-08 17:28:20 -0800704 for item in kwds.items():
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700705 key += item
706 if typed:
707 key += tuple(type(v) for v in args)
708 if kwds:
Raymond Hettinger4ee39142017-01-08 17:28:20 -0800709 key += tuple(type(v) for v in kwds.values())
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700710 elif len(key) == 1 and type(key[0]) in fasttypes:
711 return key[0]
712 return _HashedSeq(key)
713
Raymond Hettinger010ce322012-05-19 21:20:48 -0700714def lru_cache(maxsize=128, typed=False):
Benjamin Peterson1f594ad2010-08-08 13:17:07 +0000715 """Least-recently-used cache decorator.
Georg Brandl2e7346a2010-07-31 18:09:23 +0000716
Raymond Hettingerc79fb0e2010-12-01 03:45:41 +0000717 If *maxsize* is set to None, the LRU features are disabled and the cache
718 can grow without bound.
719
Raymond Hettingercd9fdfd2011-10-20 08:57:45 -0700720 If *typed* is True, arguments of different types will be cached separately.
721 For example, f(3.0) and f(3) will be treated as distinct calls with
722 distinct results.
723
Georg Brandl2e7346a2010-07-31 18:09:23 +0000724 Arguments to the cached function must be hashable.
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000725
Raymond Hettinger7f7a5a72012-03-30 21:50:40 -0700726 View the cache statistics named tuple (hits, misses, maxsize, currsize)
727 with f.cache_info(). Clear the cache and statistics with f.cache_clear().
Raymond Hettinger00f2f972010-12-01 00:47:56 +0000728 Access the underlying function with f.__wrapped__.
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000729
amist336b3062019-09-16 21:36:14 +0300730 See: http://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)
Georg Brandl2e7346a2010-07-31 18:09:23 +0000731
Benjamin Peterson1f594ad2010-08-08 13:17:07 +0000732 """
Raymond Hettinger1ff50df2012-03-30 13:15:48 -0700733
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000734 # Users should only access the lru_cache through its public API:
Raymond Hettinger5e20bab2010-11-30 07:13:04 +0000735 # cache_info, cache_clear, and f.__wrapped__
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000736 # The internals of the lru_cache are encapsulated for thread safety and
737 # to allow the implementation to change (including a possible C version).
738
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500739 if isinstance(maxsize, int):
Raymond Hettingerb8218682019-05-26 11:27:35 -0700740 # Negative maxsize is treated as 0
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500741 if maxsize < 0:
742 maxsize = 0
Raymond Hettingerb8218682019-05-26 11:27:35 -0700743 elif callable(maxsize) and isinstance(typed, bool):
744 # The user_function was passed in directly via the maxsize argument
745 user_function, maxsize = maxsize, 128
746 wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
Manjusaka051ff522019-11-12 15:30:18 +0800747 wrapper.cache_parameters = lambda : {'maxsize': maxsize, 'typed': typed}
Raymond Hettingerb8218682019-05-26 11:27:35 -0700748 return update_wrapper(wrapper, user_function)
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500749 elif maxsize is not None:
Raymond Hettingerb8218682019-05-26 11:27:35 -0700750 raise TypeError(
751 'Expected first argument to be an integer, a callable, or None')
Raymond Hettinger4d588972014-08-12 12:44:52 -0700752
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300753 def decorating_function(user_function):
754 wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
Manjusaka051ff522019-11-12 15:30:18 +0800755 wrapper.cache_parameters = lambda : {'maxsize': maxsize, 'typed': typed}
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300756 return update_wrapper(wrapper, user_function)
757
758 return decorating_function
759
760def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
Raymond Hettinger9f0ab9f2012-04-29 14:55:27 -0700761 # Constants shared by all lru cache instances:
Raymond Hettingerb6b98c02012-04-29 18:09:02 -0700762 sentinel = object() # unique object used to signal cache misses
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700763 make_key = _make_key # build a key from the function arguments
Raymond Hettinger9f0ab9f2012-04-29 14:55:27 -0700764 PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields
765
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300766 cache = {}
767 hits = misses = 0
768 full = False
769 cache_get = cache.get # bound method to lookup a key or return None
Raymond Hettingerb2d4b3d2016-12-16 14:59:37 -0800770 cache_len = cache.__len__ # get cache size without calling len()
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300771 lock = RLock() # because linkedlist updates aren't threadsafe
772 root = [] # root of the circular doubly linked list
773 root[:] = [root, root, None, None] # initialize by pointing to self
Raymond Hettinger6e8c8172012-03-16 16:53:05 -0700774
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300775 if maxsize == 0:
Raymond Hettinger7e0c5812012-03-17 15:10:24 -0700776
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300777 def wrapper(*args, **kwds):
Raymond Hettingerffdf1c32019-01-31 15:03:38 -0800778 # No caching -- just a statistics update
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300779 nonlocal misses
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300780 misses += 1
Raymond Hettingerffdf1c32019-01-31 15:03:38 -0800781 result = user_function(*args, **kwds)
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300782 return result
783
784 elif maxsize is None:
785
786 def wrapper(*args, **kwds):
787 # Simple caching without ordering or size limit
788 nonlocal hits, misses
789 key = make_key(args, kwds, typed)
790 result = cache_get(key, sentinel)
791 if result is not sentinel:
792 hits += 1
Raymond Hettinger7e0c5812012-03-17 15:10:24 -0700793 return result
Raymond Hettingerffdf1c32019-01-31 15:03:38 -0800794 misses += 1
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300795 result = user_function(*args, **kwds)
796 cache[key] = result
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300797 return result
Raymond Hettinger7e0c5812012-03-17 15:10:24 -0700798
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300799 else:
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700800
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300801 def wrapper(*args, **kwds):
802 # Size limited caching that tracks accesses by recency
803 nonlocal root, hits, misses, full
804 key = make_key(args, kwds, typed)
805 with lock:
806 link = cache_get(key)
807 if link is not None:
808 # Move the link to the front of the circular queue
809 link_prev, link_next, _key, result = link
810 link_prev[NEXT] = link_next
811 link_next[PREV] = link_prev
812 last = root[PREV]
813 last[NEXT] = root[PREV] = link
814 link[PREV] = last
815 link[NEXT] = root
Nick Coghlan234515a2010-11-30 06:19:46 +0000816 hits += 1
Raymond Hettinger4b779b32011-10-15 23:50:42 -0700817 return result
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500818 misses += 1
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300819 result = user_function(*args, **kwds)
820 with lock:
821 if key in cache:
822 # Getting here means that this same key was added to the
823 # cache while the lock was released. Since the link
824 # update is already done, we need only return the
825 # computed result and update the count of misses.
826 pass
827 elif full:
828 # Use the old root to store the new key and result.
829 oldroot = root
830 oldroot[KEY] = key
831 oldroot[RESULT] = result
832 # Empty the oldest link and make it the new root.
833 # Keep a reference to the old key and old result to
834 # prevent their ref counts from going to zero during the
835 # update. That will prevent potentially arbitrary object
836 # clean-up code (i.e. __del__) from running while we're
837 # still adjusting the links.
838 root = oldroot[NEXT]
839 oldkey = root[KEY]
840 oldresult = root[RESULT]
841 root[KEY] = root[RESULT] = None
842 # Now update the cache dictionary.
843 del cache[oldkey]
844 # Save the potentially reentrant cache[key] assignment
845 # for last, after the root and links have been put in
846 # a consistent state.
847 cache[key] = oldroot
848 else:
849 # Put result in a new link at the front of the queue.
850 last = root[PREV]
851 link = [last, root, key, result]
852 last[NEXT] = root[PREV] = cache[key] = link
Raymond Hettingerb2d4b3d2016-12-16 14:59:37 -0800853 # Use the cache_len bound method instead of the len() function
Raymond Hettingeraf56e0e2016-12-16 13:57:40 -0800854 # which could potentially be wrapped in an lru_cache itself.
Raymond Hettingerb2d4b3d2016-12-16 14:59:37 -0800855 full = (cache_len() >= maxsize)
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300856 return result
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700857
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300858 def cache_info():
859 """Report cache statistics"""
860 with lock:
Raymond Hettingerb2d4b3d2016-12-16 14:59:37 -0800861 return _CacheInfo(hits, misses, maxsize, cache_len())
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700862
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300863 def cache_clear():
864 """Clear the cache and cache statistics"""
865 nonlocal hits, misses, full
866 with lock:
867 cache.clear()
868 root[:] = [root, root, None, None]
869 hits = misses = 0
870 full = False
Georg Brandl2e7346a2010-07-31 18:09:23 +0000871
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300872 wrapper.cache_info = cache_info
873 wrapper.cache_clear = cache_clear
Serhiy Storchakace2295d2015-10-24 09:51:53 +0300874 return wrapper
Nick Coghlan234515a2010-11-30 06:19:46 +0000875
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300876try:
877 from _functools import _lru_cache_wrapper
878except ImportError:
879 pass
Łukasz Langa6f692512013-06-05 12:20:24 +0200880
881
882################################################################################
883### singledispatch() - single-dispatch generic function decorator
884################################################################################
885
Łukasz Langa3720c772013-07-01 16:00:38 +0200886def _c3_merge(sequences):
887 """Merges MROs in *sequences* to a single MRO using the C3 algorithm.
888
889 Adapted from http://www.python.org/download/releases/2.3/mro/.
890
891 """
892 result = []
893 while True:
894 sequences = [s for s in sequences if s] # purge empty sequences
895 if not sequences:
896 return result
897 for s1 in sequences: # find merge candidates among seq heads
898 candidate = s1[0]
899 for s2 in sequences:
900 if candidate in s2[1:]:
901 candidate = None
902 break # reject the current head, it appears later
903 else:
904 break
Yury Selivanov77a8cd62015-08-18 14:20:00 -0400905 if candidate is None:
Łukasz Langa3720c772013-07-01 16:00:38 +0200906 raise RuntimeError("Inconsistent hierarchy")
907 result.append(candidate)
908 # remove the chosen candidate
909 for seq in sequences:
910 if seq[0] == candidate:
911 del seq[0]
912
913def _c3_mro(cls, abcs=None):
914 """Computes the method resolution order using extended C3 linearization.
915
916 If no *abcs* are given, the algorithm works exactly like the built-in C3
917 linearization used for method resolution.
918
919 If given, *abcs* is a list of abstract base classes that should be inserted
920 into the resulting MRO. Unrelated ABCs are ignored and don't end up in the
921 result. The algorithm inserts ABCs where their functionality is introduced,
922 i.e. issubclass(cls, abc) returns True for the class itself but returns
923 False for all its direct base classes. Implicit ABCs for a given class
924 (either registered or inferred from the presence of a special method like
925 __len__) are inserted directly after the last ABC explicitly listed in the
926 MRO of said class. If two implicit ABCs end up next to each other in the
927 resulting MRO, their ordering depends on the order of types in *abcs*.
928
929 """
930 for i, base in enumerate(reversed(cls.__bases__)):
931 if hasattr(base, '__abstractmethods__'):
932 boundary = len(cls.__bases__) - i
933 break # Bases up to the last explicit ABC are considered first.
934 else:
935 boundary = 0
936 abcs = list(abcs) if abcs else []
937 explicit_bases = list(cls.__bases__[:boundary])
938 abstract_bases = []
939 other_bases = list(cls.__bases__[boundary:])
940 for base in abcs:
941 if issubclass(cls, base) and not any(
942 issubclass(b, base) for b in cls.__bases__
943 ):
944 # If *cls* is the class that introduces behaviour described by
945 # an ABC *base*, insert said ABC to its MRO.
946 abstract_bases.append(base)
947 for base in abstract_bases:
948 abcs.remove(base)
949 explicit_c3_mros = [_c3_mro(base, abcs=abcs) for base in explicit_bases]
950 abstract_c3_mros = [_c3_mro(base, abcs=abcs) for base in abstract_bases]
951 other_c3_mros = [_c3_mro(base, abcs=abcs) for base in other_bases]
952 return _c3_merge(
953 [[cls]] +
954 explicit_c3_mros + abstract_c3_mros + other_c3_mros +
955 [explicit_bases] + [abstract_bases] + [other_bases]
956 )
957
958def _compose_mro(cls, types):
959 """Calculates the method resolution order for a given class *cls*.
960
961 Includes relevant abstract base classes (with their respective bases) from
962 the *types* iterable. Uses a modified C3 linearization algorithm.
Łukasz Langa6f692512013-06-05 12:20:24 +0200963
964 """
965 bases = set(cls.__mro__)
Łukasz Langa3720c772013-07-01 16:00:38 +0200966 # Remove entries which are already present in the __mro__ or unrelated.
967 def is_related(typ):
968 return (typ not in bases and hasattr(typ, '__mro__')
969 and issubclass(cls, typ))
970 types = [n for n in types if is_related(n)]
971 # Remove entries which are strict bases of other entries (they will end up
972 # in the MRO anyway.
973 def is_strict_base(typ):
974 for other in types:
975 if typ != other and typ in other.__mro__:
976 return True
977 return False
978 types = [n for n in types if not is_strict_base(n)]
979 # Subclasses of the ABCs in *types* which are also implemented by
980 # *cls* can be used to stabilize ABC ordering.
981 type_set = set(types)
982 mro = []
983 for typ in types:
984 found = []
985 for sub in typ.__subclasses__():
986 if sub not in bases and issubclass(cls, sub):
987 found.append([s for s in sub.__mro__ if s in type_set])
988 if not found:
989 mro.append(typ)
990 continue
991 # Favor subclasses with the biggest number of useful bases
992 found.sort(key=len, reverse=True)
993 for sub in found:
994 for subcls in sub:
995 if subcls not in mro:
996 mro.append(subcls)
997 return _c3_mro(cls, abcs=mro)
Łukasz Langa6f692512013-06-05 12:20:24 +0200998
999def _find_impl(cls, registry):
Łukasz Langa3720c772013-07-01 16:00:38 +02001000 """Returns the best matching implementation from *registry* for type *cls*.
Łukasz Langa6f692512013-06-05 12:20:24 +02001001
Łukasz Langa3720c772013-07-01 16:00:38 +02001002 Where there is no registered implementation for a specific type, its method
1003 resolution order is used to find a more generic implementation.
1004
1005 Note: if *registry* does not contain an implementation for the base
1006 *object* type, this function may return None.
Łukasz Langa6f692512013-06-05 12:20:24 +02001007
1008 """
1009 mro = _compose_mro(cls, registry.keys())
1010 match = None
1011 for t in mro:
1012 if match is not None:
Łukasz Langa3720c772013-07-01 16:00:38 +02001013 # If *match* is an implicit ABC but there is another unrelated,
1014 # equally matching implicit ABC, refuse the temptation to guess.
1015 if (t in registry and t not in cls.__mro__
1016 and match not in cls.__mro__
1017 and not issubclass(match, t)):
Łukasz Langa6f692512013-06-05 12:20:24 +02001018 raise RuntimeError("Ambiguous dispatch: {} or {}".format(
1019 match, t))
1020 break
1021 if t in registry:
1022 match = t
1023 return registry.get(match)
1024
1025def singledispatch(func):
1026 """Single-dispatch generic function decorator.
1027
1028 Transforms a function into a generic function, which can have different
1029 behaviours depending upon the type of its first argument. The decorated
1030 function acts as the default implementation, and additional
Łukasz Langa3720c772013-07-01 16:00:38 +02001031 implementations can be registered using the register() attribute of the
1032 generic function.
Łukasz Langa6f692512013-06-05 12:20:24 +02001033 """
INADA Naoki9811e802017-09-30 16:13:02 +09001034 # There are many programs that use functools without singledispatch, so we
1035 # trade-off making singledispatch marginally slower for the benefit of
1036 # making start-up of such applications slightly faster.
1037 import types, weakref
1038
Łukasz Langa6f692512013-06-05 12:20:24 +02001039 registry = {}
INADA Naoki9811e802017-09-30 16:13:02 +09001040 dispatch_cache = weakref.WeakKeyDictionary()
Łukasz Langa6f692512013-06-05 12:20:24 +02001041 cache_token = None
1042
Łukasz Langa3720c772013-07-01 16:00:38 +02001043 def dispatch(cls):
1044 """generic_func.dispatch(cls) -> <function implementation>
Łukasz Langa6f692512013-06-05 12:20:24 +02001045
1046 Runs the dispatch algorithm to return the best available implementation
Łukasz Langa3720c772013-07-01 16:00:38 +02001047 for the given *cls* registered on *generic_func*.
Łukasz Langa6f692512013-06-05 12:20:24 +02001048
1049 """
1050 nonlocal cache_token
1051 if cache_token is not None:
1052 current_token = get_cache_token()
1053 if cache_token != current_token:
1054 dispatch_cache.clear()
1055 cache_token = current_token
1056 try:
Łukasz Langa3720c772013-07-01 16:00:38 +02001057 impl = dispatch_cache[cls]
Łukasz Langa6f692512013-06-05 12:20:24 +02001058 except KeyError:
1059 try:
Łukasz Langa3720c772013-07-01 16:00:38 +02001060 impl = registry[cls]
Łukasz Langa6f692512013-06-05 12:20:24 +02001061 except KeyError:
Łukasz Langa3720c772013-07-01 16:00:38 +02001062 impl = _find_impl(cls, registry)
1063 dispatch_cache[cls] = impl
Łukasz Langa6f692512013-06-05 12:20:24 +02001064 return impl
1065
Łukasz Langa3720c772013-07-01 16:00:38 +02001066 def register(cls, func=None):
1067 """generic_func.register(cls, func) -> func
Łukasz Langa6f692512013-06-05 12:20:24 +02001068
Łukasz Langa3720c772013-07-01 16:00:38 +02001069 Registers a new implementation for the given *cls* on a *generic_func*.
Łukasz Langa6f692512013-06-05 12:20:24 +02001070
1071 """
1072 nonlocal cache_token
1073 if func is None:
Łukasz Langae5697532017-12-11 13:56:31 -08001074 if isinstance(cls, type):
1075 return lambda f: register(cls, f)
1076 ann = getattr(cls, '__annotations__', {})
1077 if not ann:
1078 raise TypeError(
1079 f"Invalid first argument to `register()`: {cls!r}. "
1080 f"Use either `@register(some_class)` or plain `@register` "
1081 f"on an annotated function."
1082 )
1083 func = cls
1084
1085 # only import typing if annotation parsing is necessary
1086 from typing import get_type_hints
1087 argname, cls = next(iter(get_type_hints(func).items()))
Lysandros Nikolaoud6738102019-05-20 00:11:21 +02001088 if not isinstance(cls, type):
1089 raise TypeError(
1090 f"Invalid annotation for {argname!r}. "
1091 f"{cls!r} is not a class."
1092 )
Łukasz Langa3720c772013-07-01 16:00:38 +02001093 registry[cls] = func
1094 if cache_token is None and hasattr(cls, '__abstractmethods__'):
Łukasz Langa6f692512013-06-05 12:20:24 +02001095 cache_token = get_cache_token()
1096 dispatch_cache.clear()
1097 return func
1098
1099 def wrapper(*args, **kw):
Dong-hee Na445f1b32018-07-10 16:26:36 +09001100 if not args:
1101 raise TypeError(f'{funcname} requires at least '
1102 '1 positional argument')
1103
Łukasz Langa6f692512013-06-05 12:20:24 +02001104 return dispatch(args[0].__class__)(*args, **kw)
1105
Dong-hee Na445f1b32018-07-10 16:26:36 +09001106 funcname = getattr(func, '__name__', 'singledispatch function')
Łukasz Langa6f692512013-06-05 12:20:24 +02001107 registry[object] = func
1108 wrapper.register = register
1109 wrapper.dispatch = dispatch
INADA Naoki9811e802017-09-30 16:13:02 +09001110 wrapper.registry = types.MappingProxyType(registry)
Łukasz Langa6f692512013-06-05 12:20:24 +02001111 wrapper._clear_cache = dispatch_cache.clear
1112 update_wrapper(wrapper, func)
1113 return wrapper
Ethan Smithc6512752018-05-26 16:38:33 -04001114
1115
1116# Descriptor version
1117class singledispatchmethod:
1118 """Single-dispatch generic method descriptor.
1119
1120 Supports wrapping existing descriptors and handles non-descriptor
1121 callables as instance methods.
1122 """
1123
1124 def __init__(self, func):
1125 if not callable(func) and not hasattr(func, "__get__"):
1126 raise TypeError(f"{func!r} is not callable or a descriptor")
1127
1128 self.dispatcher = singledispatch(func)
1129 self.func = func
1130
1131 def register(self, cls, method=None):
1132 """generic_method.register(cls, func) -> func
1133
1134 Registers a new implementation for the given *cls* on a *generic_method*.
1135 """
1136 return self.dispatcher.register(cls, func=method)
1137
Raymond Hettinger0dac68f2019-08-29 01:27:42 -07001138 def __get__(self, obj, cls=None):
Ethan Smithc6512752018-05-26 16:38:33 -04001139 def _method(*args, **kwargs):
1140 method = self.dispatcher.dispatch(args[0].__class__)
1141 return method.__get__(obj, cls)(*args, **kwargs)
1142
1143 _method.__isabstractmethod__ = self.__isabstractmethod__
1144 _method.register = self.register
1145 update_wrapper(_method, self.func)
1146 return _method
1147
1148 @property
1149 def __isabstractmethod__(self):
1150 return getattr(self.func, '__isabstractmethod__', False)
Carl Meyerd658dea2018-08-28 01:11:56 -06001151
1152
1153################################################################################
1154### cached_property() - computed once per instance, cached as attribute
1155################################################################################
1156
1157_NOT_FOUND = object()
1158
1159
1160class cached_property:
1161 def __init__(self, func):
1162 self.func = func
1163 self.attrname = None
1164 self.__doc__ = func.__doc__
1165 self.lock = RLock()
1166
1167 def __set_name__(self, owner, name):
1168 if self.attrname is None:
1169 self.attrname = name
1170 elif name != self.attrname:
1171 raise TypeError(
1172 "Cannot assign the same cached_property to two different names "
1173 f"({self.attrname!r} and {name!r})."
1174 )
1175
Raymond Hettinger0dac68f2019-08-29 01:27:42 -07001176 def __get__(self, instance, owner=None):
Carl Meyerd658dea2018-08-28 01:11:56 -06001177 if instance is None:
1178 return self
1179 if self.attrname is None:
1180 raise TypeError(
1181 "Cannot use cached_property instance without calling __set_name__ on it.")
1182 try:
1183 cache = instance.__dict__
1184 except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
1185 msg = (
1186 f"No '__dict__' attribute on {type(instance).__name__!r} "
1187 f"instance to cache {self.attrname!r} property."
1188 )
1189 raise TypeError(msg) from None
1190 val = cache.get(self.attrname, _NOT_FOUND)
1191 if val is _NOT_FOUND:
1192 with self.lock:
1193 # check if another thread filled cache while we awaited lock
1194 val = cache.get(self.attrname, _NOT_FOUND)
1195 if val is _NOT_FOUND:
1196 val = self.func(instance)
1197 try:
1198 cache[self.attrname] = val
1199 except TypeError:
1200 msg = (
1201 f"The '__dict__' attribute on {type(instance).__name__!r} instance "
1202 f"does not support item assignment for caching {self.attrname!r} property."
1203 )
1204 raise TypeError(msg) from None
1205 return val