blob: 6aa13a2f9a646a586799eb7d43160c8804d15780 [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',
14 'singledispatch']
Georg Brandl2e7346a2010-07-31 18:09:23 +000015
Antoine Pitroub5b37142012-11-13 21:35:40 +010016try:
17 from _functools import reduce
Brett Cannoncd171c82013-07-04 17:43:24 -040018except ImportError:
Antoine Pitroub5b37142012-11-13 21:35:40 +010019 pass
Łukasz Langa6f692512013-06-05 12:20:24 +020020from abc import get_cache_token
Raymond Hettingerec0e9102012-03-16 01:16:31 -070021from collections import namedtuple
Łukasz Langa6f692512013-06-05 12:20:24 +020022from types import MappingProxyType
23from weakref import WeakKeyDictionary
Raymond Hettingercbe88132010-08-14 22:22:10 +000024try:
Raymond Hettingerfd541172013-03-01 03:47:57 -080025 from _thread import RLock
Raymond Hettingercbe88132010-08-14 22:22:10 +000026except:
Raymond Hettinger409f6632013-03-01 23:20:13 -080027 class RLock:
Raymond Hettingerf96b2b02013-03-08 21:11:55 -070028 'Dummy reentrant lock for builds without threads'
Raymond Hettinger409f6632013-03-01 23:20:13 -080029 def __enter__(self): pass
30 def __exit__(self, exctype, excinst, exctb): pass
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000031
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -070032
33################################################################################
34### update_wrapper() and wraps() decorator
35################################################################################
36
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000037# update_wrapper() and wraps() are tools to help write
38# wrapper functions that can handle naive introspection
39
Meador Ingeff7f64c2011-12-11 22:37:31 -060040WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
41 '__annotations__')
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000042WRAPPER_UPDATES = ('__dict__',)
43def update_wrapper(wrapper,
44 wrapped,
45 assigned = WRAPPER_ASSIGNMENTS,
46 updated = WRAPPER_UPDATES):
47 """Update a wrapper function to look like the wrapped function
48
49 wrapper is the function to be updated
50 wrapped is the original function
51 assigned is a tuple naming the attributes assigned directly
52 from the wrapped function to the wrapper function (defaults to
53 functools.WRAPPER_ASSIGNMENTS)
Thomas Wouters89f507f2006-12-13 04:49:30 +000054 updated is a tuple naming the attributes of the wrapper that
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000055 are updated with the corresponding attribute from the wrapped
56 function (defaults to functools.WRAPPER_UPDATES)
57 """
Nick Coghlan98876832010-08-17 06:17:18 +000058 wrapper.__wrapped__ = wrapped
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000059 for attr in assigned:
Nick Coghlan98876832010-08-17 06:17:18 +000060 try:
61 value = getattr(wrapped, attr)
62 except AttributeError:
63 pass
64 else:
65 setattr(wrapper, attr, value)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000066 for attr in updated:
Thomas Wouters89f507f2006-12-13 04:49:30 +000067 getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000068 # Return the wrapper so this can be used as a decorator via partial()
69 return wrapper
70
71def wraps(wrapped,
72 assigned = WRAPPER_ASSIGNMENTS,
73 updated = WRAPPER_UPDATES):
74 """Decorator factory to apply update_wrapper() to a wrapper function
75
76 Returns a decorator that invokes update_wrapper() with the decorated
77 function as the wrapper argument and the arguments to wraps() as the
78 remaining arguments. Default arguments are as for update_wrapper().
79 This is a convenience function to simplify applying partial() to
80 update_wrapper().
81 """
82 return partial(update_wrapper, wrapped=wrapped,
83 assigned=assigned, updated=updated)
Raymond Hettingerc50846a2010-04-05 18:56:31 +000084
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -070085
86################################################################################
87### total_ordering class decorator
88################################################################################
89
Raymond Hettingerc50846a2010-04-05 18:56:31 +000090def total_ordering(cls):
Georg Brandle5a26732010-05-19 21:06:36 +000091 """Class decorator that fills in missing ordering methods"""
Raymond Hettingerc50846a2010-04-05 18:56:31 +000092 convert = {
Raymond Hettinger23f9fc32011-01-08 07:01:56 +000093 '__lt__': [('__gt__', lambda self, other: not (self < other or self == other)),
94 ('__le__', lambda self, other: self < other or self == other),
Raymond Hettingerc50846a2010-04-05 18:56:31 +000095 ('__ge__', lambda self, other: not self < other)],
Raymond Hettinger23f9fc32011-01-08 07:01:56 +000096 '__le__': [('__ge__', lambda self, other: not self <= other or self == other),
97 ('__lt__', lambda self, other: self <= other and not self == other),
Raymond Hettingerc50846a2010-04-05 18:56:31 +000098 ('__gt__', lambda self, other: not self <= other)],
Raymond Hettinger23f9fc32011-01-08 07:01:56 +000099 '__gt__': [('__lt__', lambda self, other: not (self > other or self == other)),
100 ('__ge__', lambda self, other: self > other or self == other),
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000101 ('__le__', lambda self, other: not self > other)],
Raymond Hettinger23f9fc32011-01-08 07:01:56 +0000102 '__ge__': [('__le__', lambda self, other: (not self >= other) or self == other),
103 ('__gt__', lambda self, other: self >= other and not self == other),
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000104 ('__lt__', lambda self, other: not self >= other)]
105 }
Raymond Hettinger3255c632010-09-16 00:31:21 +0000106 # Find user-defined comparisons (not those inherited from object).
Raymond Hettinger1006bd42010-09-14 22:55:13 +0000107 roots = [op for op in convert if getattr(cls, op, None) is not getattr(object, op, None)]
Raymond Hettinger56de7e22010-04-10 16:59:03 +0000108 if not roots:
109 raise ValueError('must define at least one ordering operation: < > <= >=')
110 root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000111 for opname, opfunc in convert[root]:
112 if opname not in roots:
113 opfunc.__name__ = opname
114 opfunc.__doc__ = getattr(int, opname).__doc__
115 setattr(cls, opname, opfunc)
116 return cls
117
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700118
119################################################################################
120### cmp_to_key() function converter
121################################################################################
122
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000123def cmp_to_key(mycmp):
Georg Brandle5a26732010-05-19 21:06:36 +0000124 """Convert a cmp= function into a key= function"""
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000125 class K(object):
Raymond Hettingera0d1d962011-03-21 17:50:28 -0700126 __slots__ = ['obj']
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700127 def __init__(self, obj):
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000128 self.obj = obj
129 def __lt__(self, other):
130 return mycmp(self.obj, other.obj) < 0
131 def __gt__(self, other):
132 return mycmp(self.obj, other.obj) > 0
133 def __eq__(self, other):
134 return mycmp(self.obj, other.obj) == 0
135 def __le__(self, other):
136 return mycmp(self.obj, other.obj) <= 0
137 def __ge__(self, other):
138 return mycmp(self.obj, other.obj) >= 0
139 def __ne__(self, other):
140 return mycmp(self.obj, other.obj) != 0
Raymond Hettinger003be522011-05-03 11:01:32 -0700141 __hash__ = None
Raymond Hettingerc50846a2010-04-05 18:56:31 +0000142 return K
Georg Brandl2e7346a2010-07-31 18:09:23 +0000143
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700144try:
145 from _functools import cmp_to_key
Brett Cannoncd171c82013-07-04 17:43:24 -0400146except ImportError:
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700147 pass
148
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700149
150################################################################################
Antoine Pitroub5b37142012-11-13 21:35:40 +0100151### partial() argument application
152################################################################################
153
154def partial(func, *args, **keywords):
155 """new function with partial application of the given arguments
156 and keywords.
157 """
158 def newfunc(*fargs, **fkeywords):
159 newkeywords = keywords.copy()
160 newkeywords.update(fkeywords)
161 return func(*(args + fargs), **newkeywords)
162 newfunc.func = func
163 newfunc.args = args
164 newfunc.keywords = keywords
165 return newfunc
166
167try:
168 from _functools import partial
Brett Cannoncd171c82013-07-04 17:43:24 -0400169except ImportError:
Antoine Pitroub5b37142012-11-13 21:35:40 +0100170 pass
171
172
173################################################################################
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700174### LRU Cache function decorator
175################################################################################
176
Raymond Hettingerdce583e2012-03-16 22:12:20 -0700177_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])
Nick Coghlan234515a2010-11-30 06:19:46 +0000178
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700179class _HashedSeq(list):
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700180 """ This class guarantees that hash() will be called no more than once
181 per element. This is important because the lru_cache() will hash
182 the key multiple times on a cache miss.
183
184 """
185
Raymond Hettinger9acbb602012-04-30 22:32:16 -0700186 __slots__ = 'hashvalue'
187
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700188 def __init__(self, tup, hash=hash):
189 self[:] = tup
190 self.hashvalue = hash(tup)
Raymond Hettinger9acbb602012-04-30 22:32:16 -0700191
192 def __hash__(self):
193 return self.hashvalue
194
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700195def _make_key(args, kwds, typed,
196 kwd_mark = (object(),),
197 fasttypes = {int, str, frozenset, type(None)},
198 sorted=sorted, tuple=tuple, type=type, len=len):
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700199 """Make a cache key from optionally typed positional and keyword arguments
200
201 The key is constructed in a way that is flat as possible rather than
202 as a nested structure that would take more memory.
203
204 If there is only a single argument and its data type is known to cache
205 its hash value, then that argument is returned without a wrapper. This
206 saves space and improves lookup speed.
207
208 """
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700209 key = args
210 if kwds:
211 sorted_items = sorted(kwds.items())
212 key += kwd_mark
213 for item in sorted_items:
214 key += item
215 if typed:
216 key += tuple(type(v) for v in args)
217 if kwds:
218 key += tuple(type(v) for k, v in sorted_items)
219 elif len(key) == 1 and type(key[0]) in fasttypes:
220 return key[0]
221 return _HashedSeq(key)
222
Raymond Hettinger010ce322012-05-19 21:20:48 -0700223def lru_cache(maxsize=128, typed=False):
Benjamin Peterson1f594ad2010-08-08 13:17:07 +0000224 """Least-recently-used cache decorator.
Georg Brandl2e7346a2010-07-31 18:09:23 +0000225
Raymond Hettingerc79fb0e2010-12-01 03:45:41 +0000226 If *maxsize* is set to None, the LRU features are disabled and the cache
227 can grow without bound.
228
Raymond Hettingercd9fdfd2011-10-20 08:57:45 -0700229 If *typed* is True, arguments of different types will be cached separately.
230 For example, f(3.0) and f(3) will be treated as distinct calls with
231 distinct results.
232
Georg Brandl2e7346a2010-07-31 18:09:23 +0000233 Arguments to the cached function must be hashable.
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000234
Raymond Hettinger7f7a5a72012-03-30 21:50:40 -0700235 View the cache statistics named tuple (hits, misses, maxsize, currsize)
236 with f.cache_info(). Clear the cache and statistics with f.cache_clear().
Raymond Hettinger00f2f972010-12-01 00:47:56 +0000237 Access the underlying function with f.__wrapped__.
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000238
239 See: http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used
Georg Brandl2e7346a2010-07-31 18:09:23 +0000240
Benjamin Peterson1f594ad2010-08-08 13:17:07 +0000241 """
Raymond Hettinger1ff50df2012-03-30 13:15:48 -0700242
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000243 # Users should only access the lru_cache through its public API:
Raymond Hettinger5e20bab2010-11-30 07:13:04 +0000244 # cache_info, cache_clear, and f.__wrapped__
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000245 # The internals of the lru_cache are encapsulated for thread safety and
246 # to allow the implementation to change (including a possible C version).
247
Raymond Hettinger9f0ab9f2012-04-29 14:55:27 -0700248 # Constants shared by all lru cache instances:
Raymond Hettingerb6b98c02012-04-29 18:09:02 -0700249 sentinel = object() # unique object used to signal cache misses
Raymond Hettinger0c9050c2012-06-04 00:21:14 -0700250 make_key = _make_key # build a key from the function arguments
Raymond Hettinger9f0ab9f2012-04-29 14:55:27 -0700251 PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields
252
Raymond Hettinger6e8c8172012-03-16 16:53:05 -0700253 def decorating_function(user_function):
Raymond Hettinger7f7a5a72012-03-30 21:50:40 -0700254 cache = {}
Raymond Hettinger832edde2013-02-17 00:08:45 -0800255 hits = misses = 0
Raymond Hettinger018b4fb2012-04-30 20:48:55 -0700256 full = False
Raymond Hettingerc6897852012-03-31 02:19:06 -0700257 cache_get = cache.get # bound method to lookup a key or return None
Raymond Hettingerfd541172013-03-01 03:47:57 -0800258 lock = RLock() # because linkedlist updates aren't threadsafe
Raymond Hettinger7f7a5a72012-03-30 21:50:40 -0700259 root = [] # root of the circular doubly linked list
260 root[:] = [root, root, None, None] # initialize by pointing to self
Raymond Hettinger6e8c8172012-03-16 16:53:05 -0700261
Raymond Hettinger7e0c5812012-03-17 15:10:24 -0700262 if maxsize == 0:
263
Raymond Hettinger7e0c5812012-03-17 15:10:24 -0700264 def wrapper(*args, **kwds):
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700265 # No caching -- just a statistics update after a successful call
Raymond Hettinger7e0c5812012-03-17 15:10:24 -0700266 nonlocal misses
Raymond Hettinger7dabfed2012-03-17 15:11:09 -0700267 result = user_function(*args, **kwds)
Raymond Hettinger7e0c5812012-03-17 15:10:24 -0700268 misses += 1
269 return result
270
271 elif maxsize is None:
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700272
Raymond Hettingerc79fb0e2010-12-01 03:45:41 +0000273 def wrapper(*args, **kwds):
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700274 # Simple caching without ordering or size limit
Raymond Hettinger832edde2013-02-17 00:08:45 -0800275 nonlocal hits, misses
Raymond Hettinger9acbb602012-04-30 22:32:16 -0700276 key = make_key(args, kwds, typed)
Raymond Hettinger7f7a5a72012-03-30 21:50:40 -0700277 result = cache_get(key, sentinel)
278 if result is not sentinel:
Nick Coghlan234515a2010-11-30 06:19:46 +0000279 hits += 1
Raymond Hettinger4b779b32011-10-15 23:50:42 -0700280 return result
Raymond Hettinger4b779b32011-10-15 23:50:42 -0700281 result = user_function(*args, **kwds)
282 cache[key] = result
283 misses += 1
Raymond Hettingerc79fb0e2010-12-01 03:45:41 +0000284 return result
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700285
Raymond Hettingerc79fb0e2010-12-01 03:45:41 +0000286 else:
Raymond Hettingerbc8e81d2012-03-17 00:24:09 -0700287
Raymond Hettingerc79fb0e2010-12-01 03:45:41 +0000288 def wrapper(*args, **kwds):
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700289 # Size limited caching that tracks accesses by recency
Raymond Hettinger832edde2013-02-17 00:08:45 -0800290 nonlocal root, hits, misses, full
Raymond Hettinger9acbb602012-04-30 22:32:16 -0700291 key = make_key(args, kwds, typed)
Raymond Hettinger4b779b32011-10-15 23:50:42 -0700292 with lock:
Raymond Hettingerec0e9102012-03-16 01:16:31 -0700293 link = cache_get(key)
294 if link is not None:
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700295 # Move the link to the front of the circular queue
296 link_prev, link_next, _key, result = link
Raymond Hettingerec0e9102012-03-16 01:16:31 -0700297 link_prev[NEXT] = link_next
298 link_next[PREV] = link_prev
299 last = root[PREV]
300 last[NEXT] = root[PREV] = link
301 link[PREV] = last
302 link[NEXT] = root
Raymond Hettingerc79fb0e2010-12-01 03:45:41 +0000303 hits += 1
Raymond Hettinger4b779b32011-10-15 23:50:42 -0700304 return result
Raymond Hettinger4b779b32011-10-15 23:50:42 -0700305 result = user_function(*args, **kwds)
306 with lock:
Raymond Hettinger34d94a22012-04-30 14:14:28 -0700307 if key in cache:
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700308 # Getting here means that this same key was added to the
309 # cache while the lock was released. Since the link
Raymond Hettinger34d94a22012-04-30 14:14:28 -0700310 # update is already done, we need only return the
311 # computed result and update the count of misses.
312 pass
Raymond Hettinger018b4fb2012-04-30 20:48:55 -0700313 elif full:
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700314 # Use the old root to store the new key and result.
Raymond Hettingerf2c17a92013-03-04 03:34:09 -0500315 oldroot = root
316 oldroot[KEY] = key
317 oldroot[RESULT] = result
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700318 # Empty the oldest link and make it the new root.
319 # Keep a reference to the old key and old result to
320 # prevent their ref counts from going to zero during the
321 # update. That will prevent potentially arbitrary object
322 # clean-up code (i.e. __del__) from running while we're
323 # still adjusting the links.
Raymond Hettingerf2c17a92013-03-04 03:34:09 -0500324 root = oldroot[NEXT]
325 oldkey = root[KEY]
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700326 oldresult = root[RESULT]
Raymond Hettingerc6897852012-03-31 02:19:06 -0700327 root[KEY] = root[RESULT] = None
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700328 # Now update the cache dictionary.
Raymond Hettingerf2c17a92013-03-04 03:34:09 -0500329 del cache[oldkey]
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700330 # Save the potentially reentrant cache[key] assignment
331 # for last, after the root and links have been put in
332 # a consistent state.
Raymond Hettingerf2c17a92013-03-04 03:34:09 -0500333 cache[key] = oldroot
Raymond Hettinger018b4fb2012-04-30 20:48:55 -0700334 else:
Raymond Hettingerf96b2b02013-03-08 21:11:55 -0700335 # Put result in a new link at the front of the queue.
Raymond Hettinger018b4fb2012-04-30 20:48:55 -0700336 last = root[PREV]
337 link = [last, root, key, result]
Raymond Hettingerf2c17a92013-03-04 03:34:09 -0500338 last[NEXT] = root[PREV] = cache[key] = link
Raymond Hettingerbb5f4802013-03-04 04:20:46 -0500339 full = (len(cache) >= maxsize)
Raymond Hettingerec0e9102012-03-16 01:16:31 -0700340 misses += 1
Raymond Hettingerc79fb0e2010-12-01 03:45:41 +0000341 return result
Georg Brandl2e7346a2010-07-31 18:09:23 +0000342
Nick Coghlan234515a2010-11-30 06:19:46 +0000343 def cache_info():
Raymond Hettinger5e20bab2010-11-30 07:13:04 +0000344 """Report cache statistics"""
Nick Coghlan234515a2010-11-30 06:19:46 +0000345 with lock:
Raymond Hettinger832edde2013-02-17 00:08:45 -0800346 return _CacheInfo(hits, misses, maxsize, len(cache))
Nick Coghlan234515a2010-11-30 06:19:46 +0000347
Raymond Hettinger02566ec2010-09-04 22:46:06 +0000348 def cache_clear():
Benjamin Peterson1f594ad2010-08-08 13:17:07 +0000349 """Clear the cache and cache statistics"""
Raymond Hettinger832edde2013-02-17 00:08:45 -0800350 nonlocal hits, misses, full
Raymond Hettingercbe88132010-08-14 22:22:10 +0000351 with lock:
352 cache.clear()
Benjamin Peterson954cf572012-03-16 18:22:26 -0500353 root[:] = [root, root, None, None]
Raymond Hettinger832edde2013-02-17 00:08:45 -0800354 hits = misses = 0
Raymond Hettinger018b4fb2012-04-30 20:48:55 -0700355 full = False
Georg Brandl2e7346a2010-07-31 18:09:23 +0000356
Nick Coghlan234515a2010-11-30 06:19:46 +0000357 wrapper.cache_info = cache_info
Raymond Hettinger02566ec2010-09-04 22:46:06 +0000358 wrapper.cache_clear = cache_clear
Raymond Hettinger1ff50df2012-03-30 13:15:48 -0700359 return update_wrapper(wrapper, user_function)
Raymond Hettinger5fa40c02010-11-25 08:11:57 +0000360
Georg Brandl2e7346a2010-07-31 18:09:23 +0000361 return decorating_function
Łukasz Langa6f692512013-06-05 12:20:24 +0200362
363
364################################################################################
365### singledispatch() - single-dispatch generic function decorator
366################################################################################
367
Łukasz Langa3720c772013-07-01 16:00:38 +0200368def _c3_merge(sequences):
369 """Merges MROs in *sequences* to a single MRO using the C3 algorithm.
370
371 Adapted from http://www.python.org/download/releases/2.3/mro/.
372
373 """
374 result = []
375 while True:
376 sequences = [s for s in sequences if s] # purge empty sequences
377 if not sequences:
378 return result
379 for s1 in sequences: # find merge candidates among seq heads
380 candidate = s1[0]
381 for s2 in sequences:
382 if candidate in s2[1:]:
383 candidate = None
384 break # reject the current head, it appears later
385 else:
386 break
387 if not candidate:
388 raise RuntimeError("Inconsistent hierarchy")
389 result.append(candidate)
390 # remove the chosen candidate
391 for seq in sequences:
392 if seq[0] == candidate:
393 del seq[0]
394
395def _c3_mro(cls, abcs=None):
396 """Computes the method resolution order using extended C3 linearization.
397
398 If no *abcs* are given, the algorithm works exactly like the built-in C3
399 linearization used for method resolution.
400
401 If given, *abcs* is a list of abstract base classes that should be inserted
402 into the resulting MRO. Unrelated ABCs are ignored and don't end up in the
403 result. The algorithm inserts ABCs where their functionality is introduced,
404 i.e. issubclass(cls, abc) returns True for the class itself but returns
405 False for all its direct base classes. Implicit ABCs for a given class
406 (either registered or inferred from the presence of a special method like
407 __len__) are inserted directly after the last ABC explicitly listed in the
408 MRO of said class. If two implicit ABCs end up next to each other in the
409 resulting MRO, their ordering depends on the order of types in *abcs*.
410
411 """
412 for i, base in enumerate(reversed(cls.__bases__)):
413 if hasattr(base, '__abstractmethods__'):
414 boundary = len(cls.__bases__) - i
415 break # Bases up to the last explicit ABC are considered first.
416 else:
417 boundary = 0
418 abcs = list(abcs) if abcs else []
419 explicit_bases = list(cls.__bases__[:boundary])
420 abstract_bases = []
421 other_bases = list(cls.__bases__[boundary:])
422 for base in abcs:
423 if issubclass(cls, base) and not any(
424 issubclass(b, base) for b in cls.__bases__
425 ):
426 # If *cls* is the class that introduces behaviour described by
427 # an ABC *base*, insert said ABC to its MRO.
428 abstract_bases.append(base)
429 for base in abstract_bases:
430 abcs.remove(base)
431 explicit_c3_mros = [_c3_mro(base, abcs=abcs) for base in explicit_bases]
432 abstract_c3_mros = [_c3_mro(base, abcs=abcs) for base in abstract_bases]
433 other_c3_mros = [_c3_mro(base, abcs=abcs) for base in other_bases]
434 return _c3_merge(
435 [[cls]] +
436 explicit_c3_mros + abstract_c3_mros + other_c3_mros +
437 [explicit_bases] + [abstract_bases] + [other_bases]
438 )
439
440def _compose_mro(cls, types):
441 """Calculates the method resolution order for a given class *cls*.
442
443 Includes relevant abstract base classes (with their respective bases) from
444 the *types* iterable. Uses a modified C3 linearization algorithm.
Łukasz Langa6f692512013-06-05 12:20:24 +0200445
446 """
447 bases = set(cls.__mro__)
Łukasz Langa3720c772013-07-01 16:00:38 +0200448 # Remove entries which are already present in the __mro__ or unrelated.
449 def is_related(typ):
450 return (typ not in bases and hasattr(typ, '__mro__')
451 and issubclass(cls, typ))
452 types = [n for n in types if is_related(n)]
453 # Remove entries which are strict bases of other entries (they will end up
454 # in the MRO anyway.
455 def is_strict_base(typ):
456 for other in types:
457 if typ != other and typ in other.__mro__:
458 return True
459 return False
460 types = [n for n in types if not is_strict_base(n)]
461 # Subclasses of the ABCs in *types* which are also implemented by
462 # *cls* can be used to stabilize ABC ordering.
463 type_set = set(types)
464 mro = []
465 for typ in types:
466 found = []
467 for sub in typ.__subclasses__():
468 if sub not in bases and issubclass(cls, sub):
469 found.append([s for s in sub.__mro__ if s in type_set])
470 if not found:
471 mro.append(typ)
472 continue
473 # Favor subclasses with the biggest number of useful bases
474 found.sort(key=len, reverse=True)
475 for sub in found:
476 for subcls in sub:
477 if subcls not in mro:
478 mro.append(subcls)
479 return _c3_mro(cls, abcs=mro)
Łukasz Langa6f692512013-06-05 12:20:24 +0200480
481def _find_impl(cls, registry):
Łukasz Langa3720c772013-07-01 16:00:38 +0200482 """Returns the best matching implementation from *registry* for type *cls*.
Łukasz Langa6f692512013-06-05 12:20:24 +0200483
Łukasz Langa3720c772013-07-01 16:00:38 +0200484 Where there is no registered implementation for a specific type, its method
485 resolution order is used to find a more generic implementation.
486
487 Note: if *registry* does not contain an implementation for the base
488 *object* type, this function may return None.
Łukasz Langa6f692512013-06-05 12:20:24 +0200489
490 """
491 mro = _compose_mro(cls, registry.keys())
492 match = None
493 for t in mro:
494 if match is not None:
Łukasz Langa3720c772013-07-01 16:00:38 +0200495 # If *match* is an implicit ABC but there is another unrelated,
496 # equally matching implicit ABC, refuse the temptation to guess.
497 if (t in registry and t not in cls.__mro__
498 and match not in cls.__mro__
499 and not issubclass(match, t)):
Łukasz Langa6f692512013-06-05 12:20:24 +0200500 raise RuntimeError("Ambiguous dispatch: {} or {}".format(
501 match, t))
502 break
503 if t in registry:
504 match = t
505 return registry.get(match)
506
507def singledispatch(func):
508 """Single-dispatch generic function decorator.
509
510 Transforms a function into a generic function, which can have different
511 behaviours depending upon the type of its first argument. The decorated
512 function acts as the default implementation, and additional
Łukasz Langa3720c772013-07-01 16:00:38 +0200513 implementations can be registered using the register() attribute of the
514 generic function.
Łukasz Langa6f692512013-06-05 12:20:24 +0200515
516 """
517 registry = {}
518 dispatch_cache = WeakKeyDictionary()
519 cache_token = None
520
Łukasz Langa3720c772013-07-01 16:00:38 +0200521 def dispatch(cls):
522 """generic_func.dispatch(cls) -> <function implementation>
Łukasz Langa6f692512013-06-05 12:20:24 +0200523
524 Runs the dispatch algorithm to return the best available implementation
Łukasz Langa3720c772013-07-01 16:00:38 +0200525 for the given *cls* registered on *generic_func*.
Łukasz Langa6f692512013-06-05 12:20:24 +0200526
527 """
528 nonlocal cache_token
529 if cache_token is not None:
530 current_token = get_cache_token()
531 if cache_token != current_token:
532 dispatch_cache.clear()
533 cache_token = current_token
534 try:
Łukasz Langa3720c772013-07-01 16:00:38 +0200535 impl = dispatch_cache[cls]
Łukasz Langa6f692512013-06-05 12:20:24 +0200536 except KeyError:
537 try:
Łukasz Langa3720c772013-07-01 16:00:38 +0200538 impl = registry[cls]
Łukasz Langa6f692512013-06-05 12:20:24 +0200539 except KeyError:
Łukasz Langa3720c772013-07-01 16:00:38 +0200540 impl = _find_impl(cls, registry)
541 dispatch_cache[cls] = impl
Łukasz Langa6f692512013-06-05 12:20:24 +0200542 return impl
543
Łukasz Langa3720c772013-07-01 16:00:38 +0200544 def register(cls, func=None):
545 """generic_func.register(cls, func) -> func
Łukasz Langa6f692512013-06-05 12:20:24 +0200546
Łukasz Langa3720c772013-07-01 16:00:38 +0200547 Registers a new implementation for the given *cls* on a *generic_func*.
Łukasz Langa6f692512013-06-05 12:20:24 +0200548
549 """
550 nonlocal cache_token
551 if func is None:
Łukasz Langa3720c772013-07-01 16:00:38 +0200552 return lambda f: register(cls, f)
553 registry[cls] = func
554 if cache_token is None and hasattr(cls, '__abstractmethods__'):
Łukasz Langa6f692512013-06-05 12:20:24 +0200555 cache_token = get_cache_token()
556 dispatch_cache.clear()
557 return func
558
559 def wrapper(*args, **kw):
560 return dispatch(args[0].__class__)(*args, **kw)
561
562 registry[object] = func
563 wrapper.register = register
564 wrapper.dispatch = dispatch
565 wrapper.registry = MappingProxyType(registry)
566 wrapper._clear_cache = dispatch_cache.clear
567 update_wrapper(wrapper, func)
568 return wrapper