Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/future/backports/misc.py @ 0:d30785e31577 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author | guerler |
---|---|
date | Fri, 31 Jul 2020 00:18:57 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d30785e31577 |
---|---|
1 """ | |
2 Miscellaneous function (re)definitions from the Py3.4+ standard library | |
3 for Python 2.6/2.7. | |
4 | |
5 - math.ceil (for Python 2.7) | |
6 - collections.OrderedDict (for Python 2.6) | |
7 - collections.Counter (for Python 2.6) | |
8 - collections.ChainMap (for all versions prior to Python 3.3) | |
9 - itertools.count (for Python 2.6, with step parameter) | |
10 - subprocess.check_output (for Python 2.6) | |
11 - reprlib.recursive_repr (for Python 2.6+) | |
12 - functools.cmp_to_key (for Python 2.6) | |
13 """ | |
14 | |
15 from __future__ import absolute_import | |
16 | |
17 import subprocess | |
18 from math import ceil as oldceil | |
19 | |
20 from operator import itemgetter as _itemgetter, eq as _eq | |
21 import sys | |
22 import heapq as _heapq | |
23 from _weakref import proxy as _proxy | |
24 from itertools import repeat as _repeat, chain as _chain, starmap as _starmap | |
25 from socket import getaddrinfo, SOCK_STREAM, error, socket | |
26 | |
27 from future.utils import iteritems, itervalues, PY2, PY26, PY3 | |
28 | |
29 if PY2: | |
30 from collections import Mapping, MutableMapping | |
31 else: | |
32 from collections.abc import Mapping, MutableMapping | |
33 | |
34 | |
35 def ceil(x): | |
36 """ | |
37 Return the ceiling of x as an int. | |
38 This is the smallest integral value >= x. | |
39 """ | |
40 return int(oldceil(x)) | |
41 | |
42 | |
43 ######################################################################## | |
44 ### reprlib.recursive_repr decorator from Py3.4 | |
45 ######################################################################## | |
46 | |
47 from itertools import islice | |
48 | |
49 if PY3: | |
50 try: | |
51 from _thread import get_ident | |
52 except ImportError: | |
53 from _dummy_thread import get_ident | |
54 else: | |
55 try: | |
56 from thread import get_ident | |
57 except ImportError: | |
58 from dummy_thread import get_ident | |
59 | |
60 | |
61 def recursive_repr(fillvalue='...'): | |
62 'Decorator to make a repr function return fillvalue for a recursive call' | |
63 | |
64 def decorating_function(user_function): | |
65 repr_running = set() | |
66 | |
67 def wrapper(self): | |
68 key = id(self), get_ident() | |
69 if key in repr_running: | |
70 return fillvalue | |
71 repr_running.add(key) | |
72 try: | |
73 result = user_function(self) | |
74 finally: | |
75 repr_running.discard(key) | |
76 return result | |
77 | |
78 # Can't use functools.wraps() here because of bootstrap issues | |
79 wrapper.__module__ = getattr(user_function, '__module__') | |
80 wrapper.__doc__ = getattr(user_function, '__doc__') | |
81 wrapper.__name__ = getattr(user_function, '__name__') | |
82 wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) | |
83 return wrapper | |
84 | |
85 return decorating_function | |
86 | |
87 | |
88 ################################################################################ | |
89 ### OrderedDict | |
90 ################################################################################ | |
91 | |
92 class _Link(object): | |
93 __slots__ = 'prev', 'next', 'key', '__weakref__' | |
94 | |
95 class OrderedDict(dict): | |
96 'Dictionary that remembers insertion order' | |
97 # An inherited dict maps keys to values. | |
98 # The inherited dict provides __getitem__, __len__, __contains__, and get. | |
99 # The remaining methods are order-aware. | |
100 # Big-O running times for all methods are the same as regular dictionaries. | |
101 | |
102 # The internal self.__map dict maps keys to links in a doubly linked list. | |
103 # The circular doubly linked list starts and ends with a sentinel element. | |
104 # The sentinel element never gets deleted (this simplifies the algorithm). | |
105 # The sentinel is in self.__hardroot with a weakref proxy in self.__root. | |
106 # The prev links are weakref proxies (to prevent circular references). | |
107 # Individual links are kept alive by the hard reference in self.__map. | |
108 # Those hard references disappear when a key is deleted from an OrderedDict. | |
109 | |
110 def __init__(*args, **kwds): | |
111 '''Initialize an ordered dictionary. The signature is the same as | |
112 regular dictionaries, but keyword arguments are not recommended because | |
113 their insertion order is arbitrary. | |
114 | |
115 ''' | |
116 if not args: | |
117 raise TypeError("descriptor '__init__' of 'OrderedDict' object " | |
118 "needs an argument") | |
119 self = args[0] | |
120 args = args[1:] | |
121 if len(args) > 1: | |
122 raise TypeError('expected at most 1 arguments, got %d' % len(args)) | |
123 try: | |
124 self.__root | |
125 except AttributeError: | |
126 self.__hardroot = _Link() | |
127 self.__root = root = _proxy(self.__hardroot) | |
128 root.prev = root.next = root | |
129 self.__map = {} | |
130 self.__update(*args, **kwds) | |
131 | |
132 def __setitem__(self, key, value, | |
133 dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link): | |
134 'od.__setitem__(i, y) <==> od[i]=y' | |
135 # Setting a new item creates a new link at the end of the linked list, | |
136 # and the inherited dictionary is updated with the new key/value pair. | |
137 if key not in self: | |
138 self.__map[key] = link = Link() | |
139 root = self.__root | |
140 last = root.prev | |
141 link.prev, link.next, link.key = last, root, key | |
142 last.next = link | |
143 root.prev = proxy(link) | |
144 dict_setitem(self, key, value) | |
145 | |
146 def __delitem__(self, key, dict_delitem=dict.__delitem__): | |
147 'od.__delitem__(y) <==> del od[y]' | |
148 # Deleting an existing item uses self.__map to find the link which gets | |
149 # removed by updating the links in the predecessor and successor nodes. | |
150 dict_delitem(self, key) | |
151 link = self.__map.pop(key) | |
152 link_prev = link.prev | |
153 link_next = link.next | |
154 link_prev.next = link_next | |
155 link_next.prev = link_prev | |
156 | |
157 def __iter__(self): | |
158 'od.__iter__() <==> iter(od)' | |
159 # Traverse the linked list in order. | |
160 root = self.__root | |
161 curr = root.next | |
162 while curr is not root: | |
163 yield curr.key | |
164 curr = curr.next | |
165 | |
166 def __reversed__(self): | |
167 'od.__reversed__() <==> reversed(od)' | |
168 # Traverse the linked list in reverse order. | |
169 root = self.__root | |
170 curr = root.prev | |
171 while curr is not root: | |
172 yield curr.key | |
173 curr = curr.prev | |
174 | |
175 def clear(self): | |
176 'od.clear() -> None. Remove all items from od.' | |
177 root = self.__root | |
178 root.prev = root.next = root | |
179 self.__map.clear() | |
180 dict.clear(self) | |
181 | |
182 def popitem(self, last=True): | |
183 '''od.popitem() -> (k, v), return and remove a (key, value) pair. | |
184 Pairs are returned in LIFO order if last is true or FIFO order if false. | |
185 | |
186 ''' | |
187 if not self: | |
188 raise KeyError('dictionary is empty') | |
189 root = self.__root | |
190 if last: | |
191 link = root.prev | |
192 link_prev = link.prev | |
193 link_prev.next = root | |
194 root.prev = link_prev | |
195 else: | |
196 link = root.next | |
197 link_next = link.next | |
198 root.next = link_next | |
199 link_next.prev = root | |
200 key = link.key | |
201 del self.__map[key] | |
202 value = dict.pop(self, key) | |
203 return key, value | |
204 | |
205 def move_to_end(self, key, last=True): | |
206 '''Move an existing element to the end (or beginning if last==False). | |
207 | |
208 Raises KeyError if the element does not exist. | |
209 When last=True, acts like a fast version of self[key]=self.pop(key). | |
210 | |
211 ''' | |
212 link = self.__map[key] | |
213 link_prev = link.prev | |
214 link_next = link.next | |
215 link_prev.next = link_next | |
216 link_next.prev = link_prev | |
217 root = self.__root | |
218 if last: | |
219 last = root.prev | |
220 link.prev = last | |
221 link.next = root | |
222 last.next = root.prev = link | |
223 else: | |
224 first = root.next | |
225 link.prev = root | |
226 link.next = first | |
227 root.next = first.prev = link | |
228 | |
229 def __sizeof__(self): | |
230 sizeof = sys.getsizeof | |
231 n = len(self) + 1 # number of links including root | |
232 size = sizeof(self.__dict__) # instance dictionary | |
233 size += sizeof(self.__map) * 2 # internal dict and inherited dict | |
234 size += sizeof(self.__hardroot) * n # link objects | |
235 size += sizeof(self.__root) * n # proxy objects | |
236 return size | |
237 | |
238 update = __update = MutableMapping.update | |
239 keys = MutableMapping.keys | |
240 values = MutableMapping.values | |
241 items = MutableMapping.items | |
242 __ne__ = MutableMapping.__ne__ | |
243 | |
244 __marker = object() | |
245 | |
246 def pop(self, key, default=__marker): | |
247 '''od.pop(k[,d]) -> v, remove specified key and return the corresponding | |
248 value. If key is not found, d is returned if given, otherwise KeyError | |
249 is raised. | |
250 | |
251 ''' | |
252 if key in self: | |
253 result = self[key] | |
254 del self[key] | |
255 return result | |
256 if default is self.__marker: | |
257 raise KeyError(key) | |
258 return default | |
259 | |
260 def setdefault(self, key, default=None): | |
261 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' | |
262 if key in self: | |
263 return self[key] | |
264 self[key] = default | |
265 return default | |
266 | |
267 @recursive_repr() | |
268 def __repr__(self): | |
269 'od.__repr__() <==> repr(od)' | |
270 if not self: | |
271 return '%s()' % (self.__class__.__name__,) | |
272 return '%s(%r)' % (self.__class__.__name__, list(self.items())) | |
273 | |
274 def __reduce__(self): | |
275 'Return state information for pickling' | |
276 inst_dict = vars(self).copy() | |
277 for k in vars(OrderedDict()): | |
278 inst_dict.pop(k, None) | |
279 return self.__class__, (), inst_dict or None, None, iter(self.items()) | |
280 | |
281 def copy(self): | |
282 'od.copy() -> a shallow copy of od' | |
283 return self.__class__(self) | |
284 | |
285 @classmethod | |
286 def fromkeys(cls, iterable, value=None): | |
287 '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S. | |
288 If not specified, the value defaults to None. | |
289 | |
290 ''' | |
291 self = cls() | |
292 for key in iterable: | |
293 self[key] = value | |
294 return self | |
295 | |
296 def __eq__(self, other): | |
297 '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive | |
298 while comparison to a regular mapping is order-insensitive. | |
299 | |
300 ''' | |
301 if isinstance(other, OrderedDict): | |
302 return dict.__eq__(self, other) and all(map(_eq, self, other)) | |
303 return dict.__eq__(self, other) | |
304 | |
305 | |
306 # {{{ http://code.activestate.com/recipes/576611/ (r11) | |
307 | |
308 try: | |
309 from operator import itemgetter | |
310 from heapq import nlargest | |
311 except ImportError: | |
312 pass | |
313 | |
314 ######################################################################## | |
315 ### Counter | |
316 ######################################################################## | |
317 | |
318 def _count_elements(mapping, iterable): | |
319 'Tally elements from the iterable.' | |
320 mapping_get = mapping.get | |
321 for elem in iterable: | |
322 mapping[elem] = mapping_get(elem, 0) + 1 | |
323 | |
324 class Counter(dict): | |
325 '''Dict subclass for counting hashable items. Sometimes called a bag | |
326 or multiset. Elements are stored as dictionary keys and their counts | |
327 are stored as dictionary values. | |
328 | |
329 >>> c = Counter('abcdeabcdabcaba') # count elements from a string | |
330 | |
331 >>> c.most_common(3) # three most common elements | |
332 [('a', 5), ('b', 4), ('c', 3)] | |
333 >>> sorted(c) # list all unique elements | |
334 ['a', 'b', 'c', 'd', 'e'] | |
335 >>> ''.join(sorted(c.elements())) # list elements with repetitions | |
336 'aaaaabbbbcccdde' | |
337 >>> sum(c.values()) # total of all counts | |
338 15 | |
339 | |
340 >>> c['a'] # count of letter 'a' | |
341 5 | |
342 >>> for elem in 'shazam': # update counts from an iterable | |
343 ... c[elem] += 1 # by adding 1 to each element's count | |
344 >>> c['a'] # now there are seven 'a' | |
345 7 | |
346 >>> del c['b'] # remove all 'b' | |
347 >>> c['b'] # now there are zero 'b' | |
348 0 | |
349 | |
350 >>> d = Counter('simsalabim') # make another counter | |
351 >>> c.update(d) # add in the second counter | |
352 >>> c['a'] # now there are nine 'a' | |
353 9 | |
354 | |
355 >>> c.clear() # empty the counter | |
356 >>> c | |
357 Counter() | |
358 | |
359 Note: If a count is set to zero or reduced to zero, it will remain | |
360 in the counter until the entry is deleted or the counter is cleared: | |
361 | |
362 >>> c = Counter('aaabbc') | |
363 >>> c['b'] -= 2 # reduce the count of 'b' by two | |
364 >>> c.most_common() # 'b' is still in, but its count is zero | |
365 [('a', 3), ('c', 1), ('b', 0)] | |
366 | |
367 ''' | |
368 # References: | |
369 # http://en.wikipedia.org/wiki/Multiset | |
370 # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html | |
371 # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm | |
372 # http://code.activestate.com/recipes/259174/ | |
373 # Knuth, TAOCP Vol. II section 4.6.3 | |
374 | |
375 def __init__(*args, **kwds): | |
376 '''Create a new, empty Counter object. And if given, count elements | |
377 from an input iterable. Or, initialize the count from another mapping | |
378 of elements to their counts. | |
379 | |
380 >>> c = Counter() # a new, empty counter | |
381 >>> c = Counter('gallahad') # a new counter from an iterable | |
382 >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping | |
383 >>> c = Counter(a=4, b=2) # a new counter from keyword args | |
384 | |
385 ''' | |
386 if not args: | |
387 raise TypeError("descriptor '__init__' of 'Counter' object " | |
388 "needs an argument") | |
389 self = args[0] | |
390 args = args[1:] | |
391 if len(args) > 1: | |
392 raise TypeError('expected at most 1 arguments, got %d' % len(args)) | |
393 super(Counter, self).__init__() | |
394 self.update(*args, **kwds) | |
395 | |
396 def __missing__(self, key): | |
397 'The count of elements not in the Counter is zero.' | |
398 # Needed so that self[missing_item] does not raise KeyError | |
399 return 0 | |
400 | |
401 def most_common(self, n=None): | |
402 '''List the n most common elements and their counts from the most | |
403 common to the least. If n is None, then list all element counts. | |
404 | |
405 >>> Counter('abcdeabcdabcaba').most_common(3) | |
406 [('a', 5), ('b', 4), ('c', 3)] | |
407 | |
408 ''' | |
409 # Emulate Bag.sortedByCount from Smalltalk | |
410 if n is None: | |
411 return sorted(self.items(), key=_itemgetter(1), reverse=True) | |
412 return _heapq.nlargest(n, self.items(), key=_itemgetter(1)) | |
413 | |
414 def elements(self): | |
415 '''Iterator over elements repeating each as many times as its count. | |
416 | |
417 >>> c = Counter('ABCABC') | |
418 >>> sorted(c.elements()) | |
419 ['A', 'A', 'B', 'B', 'C', 'C'] | |
420 | |
421 # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1 | |
422 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) | |
423 >>> product = 1 | |
424 >>> for factor in prime_factors.elements(): # loop over factors | |
425 ... product *= factor # and multiply them | |
426 >>> product | |
427 1836 | |
428 | |
429 Note, if an element's count has been set to zero or is a negative | |
430 number, elements() will ignore it. | |
431 | |
432 ''' | |
433 # Emulate Bag.do from Smalltalk and Multiset.begin from C++. | |
434 return _chain.from_iterable(_starmap(_repeat, self.items())) | |
435 | |
436 # Override dict methods where necessary | |
437 | |
438 @classmethod | |
439 def fromkeys(cls, iterable, v=None): | |
440 # There is no equivalent method for counters because setting v=1 | |
441 # means that no element can have a count greater than one. | |
442 raise NotImplementedError( | |
443 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') | |
444 | |
445 def update(*args, **kwds): | |
446 '''Like dict.update() but add counts instead of replacing them. | |
447 | |
448 Source can be an iterable, a dictionary, or another Counter instance. | |
449 | |
450 >>> c = Counter('which') | |
451 >>> c.update('witch') # add elements from another iterable | |
452 >>> d = Counter('watch') | |
453 >>> c.update(d) # add elements from another counter | |
454 >>> c['h'] # four 'h' in which, witch, and watch | |
455 4 | |
456 | |
457 ''' | |
458 # The regular dict.update() operation makes no sense here because the | |
459 # replace behavior results in the some of original untouched counts | |
460 # being mixed-in with all of the other counts for a mismash that | |
461 # doesn't have a straight-forward interpretation in most counting | |
462 # contexts. Instead, we implement straight-addition. Both the inputs | |
463 # and outputs are allowed to contain zero and negative counts. | |
464 | |
465 if not args: | |
466 raise TypeError("descriptor 'update' of 'Counter' object " | |
467 "needs an argument") | |
468 self = args[0] | |
469 args = args[1:] | |
470 if len(args) > 1: | |
471 raise TypeError('expected at most 1 arguments, got %d' % len(args)) | |
472 iterable = args[0] if args else None | |
473 if iterable is not None: | |
474 if isinstance(iterable, Mapping): | |
475 if self: | |
476 self_get = self.get | |
477 for elem, count in iterable.items(): | |
478 self[elem] = count + self_get(elem, 0) | |
479 else: | |
480 super(Counter, self).update(iterable) # fast path when counter is empty | |
481 else: | |
482 _count_elements(self, iterable) | |
483 if kwds: | |
484 self.update(kwds) | |
485 | |
486 def subtract(*args, **kwds): | |
487 '''Like dict.update() but subtracts counts instead of replacing them. | |
488 Counts can be reduced below zero. Both the inputs and outputs are | |
489 allowed to contain zero and negative counts. | |
490 | |
491 Source can be an iterable, a dictionary, or another Counter instance. | |
492 | |
493 >>> c = Counter('which') | |
494 >>> c.subtract('witch') # subtract elements from another iterable | |
495 >>> c.subtract(Counter('watch')) # subtract elements from another counter | |
496 >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch | |
497 0 | |
498 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch | |
499 -1 | |
500 | |
501 ''' | |
502 if not args: | |
503 raise TypeError("descriptor 'subtract' of 'Counter' object " | |
504 "needs an argument") | |
505 self = args[0] | |
506 args = args[1:] | |
507 if len(args) > 1: | |
508 raise TypeError('expected at most 1 arguments, got %d' % len(args)) | |
509 iterable = args[0] if args else None | |
510 if iterable is not None: | |
511 self_get = self.get | |
512 if isinstance(iterable, Mapping): | |
513 for elem, count in iterable.items(): | |
514 self[elem] = self_get(elem, 0) - count | |
515 else: | |
516 for elem in iterable: | |
517 self[elem] = self_get(elem, 0) - 1 | |
518 if kwds: | |
519 self.subtract(kwds) | |
520 | |
521 def copy(self): | |
522 'Return a shallow copy.' | |
523 return self.__class__(self) | |
524 | |
525 def __reduce__(self): | |
526 return self.__class__, (dict(self),) | |
527 | |
528 def __delitem__(self, elem): | |
529 'Like dict.__delitem__() but does not raise KeyError for missing values.' | |
530 if elem in self: | |
531 super(Counter, self).__delitem__(elem) | |
532 | |
533 def __repr__(self): | |
534 if not self: | |
535 return '%s()' % self.__class__.__name__ | |
536 try: | |
537 items = ', '.join(map('%r: %r'.__mod__, self.most_common())) | |
538 return '%s({%s})' % (self.__class__.__name__, items) | |
539 except TypeError: | |
540 # handle case where values are not orderable | |
541 return '{0}({1!r})'.format(self.__class__.__name__, dict(self)) | |
542 | |
543 # Multiset-style mathematical operations discussed in: | |
544 # Knuth TAOCP Volume II section 4.6.3 exercise 19 | |
545 # and at http://en.wikipedia.org/wiki/Multiset | |
546 # | |
547 # Outputs guaranteed to only include positive counts. | |
548 # | |
549 # To strip negative and zero counts, add-in an empty counter: | |
550 # c += Counter() | |
551 | |
552 def __add__(self, other): | |
553 '''Add counts from two counters. | |
554 | |
555 >>> Counter('abbb') + Counter('bcc') | |
556 Counter({'b': 4, 'c': 2, 'a': 1}) | |
557 | |
558 ''' | |
559 if not isinstance(other, Counter): | |
560 return NotImplemented | |
561 result = Counter() | |
562 for elem, count in self.items(): | |
563 newcount = count + other[elem] | |
564 if newcount > 0: | |
565 result[elem] = newcount | |
566 for elem, count in other.items(): | |
567 if elem not in self and count > 0: | |
568 result[elem] = count | |
569 return result | |
570 | |
571 def __sub__(self, other): | |
572 ''' Subtract count, but keep only results with positive counts. | |
573 | |
574 >>> Counter('abbbc') - Counter('bccd') | |
575 Counter({'b': 2, 'a': 1}) | |
576 | |
577 ''' | |
578 if not isinstance(other, Counter): | |
579 return NotImplemented | |
580 result = Counter() | |
581 for elem, count in self.items(): | |
582 newcount = count - other[elem] | |
583 if newcount > 0: | |
584 result[elem] = newcount | |
585 for elem, count in other.items(): | |
586 if elem not in self and count < 0: | |
587 result[elem] = 0 - count | |
588 return result | |
589 | |
590 def __or__(self, other): | |
591 '''Union is the maximum of value in either of the input counters. | |
592 | |
593 >>> Counter('abbb') | Counter('bcc') | |
594 Counter({'b': 3, 'c': 2, 'a': 1}) | |
595 | |
596 ''' | |
597 if not isinstance(other, Counter): | |
598 return NotImplemented | |
599 result = Counter() | |
600 for elem, count in self.items(): | |
601 other_count = other[elem] | |
602 newcount = other_count if count < other_count else count | |
603 if newcount > 0: | |
604 result[elem] = newcount | |
605 for elem, count in other.items(): | |
606 if elem not in self and count > 0: | |
607 result[elem] = count | |
608 return result | |
609 | |
610 def __and__(self, other): | |
611 ''' Intersection is the minimum of corresponding counts. | |
612 | |
613 >>> Counter('abbb') & Counter('bcc') | |
614 Counter({'b': 1}) | |
615 | |
616 ''' | |
617 if not isinstance(other, Counter): | |
618 return NotImplemented | |
619 result = Counter() | |
620 for elem, count in self.items(): | |
621 other_count = other[elem] | |
622 newcount = count if count < other_count else other_count | |
623 if newcount > 0: | |
624 result[elem] = newcount | |
625 return result | |
626 | |
627 def __pos__(self): | |
628 'Adds an empty counter, effectively stripping negative and zero counts' | |
629 return self + Counter() | |
630 | |
631 def __neg__(self): | |
632 '''Subtracts from an empty counter. Strips positive and zero counts, | |
633 and flips the sign on negative counts. | |
634 | |
635 ''' | |
636 return Counter() - self | |
637 | |
638 def _keep_positive(self): | |
639 '''Internal method to strip elements with a negative or zero count''' | |
640 nonpositive = [elem for elem, count in self.items() if not count > 0] | |
641 for elem in nonpositive: | |
642 del self[elem] | |
643 return self | |
644 | |
645 def __iadd__(self, other): | |
646 '''Inplace add from another counter, keeping only positive counts. | |
647 | |
648 >>> c = Counter('abbb') | |
649 >>> c += Counter('bcc') | |
650 >>> c | |
651 Counter({'b': 4, 'c': 2, 'a': 1}) | |
652 | |
653 ''' | |
654 for elem, count in other.items(): | |
655 self[elem] += count | |
656 return self._keep_positive() | |
657 | |
658 def __isub__(self, other): | |
659 '''Inplace subtract counter, but keep only results with positive counts. | |
660 | |
661 >>> c = Counter('abbbc') | |
662 >>> c -= Counter('bccd') | |
663 >>> c | |
664 Counter({'b': 2, 'a': 1}) | |
665 | |
666 ''' | |
667 for elem, count in other.items(): | |
668 self[elem] -= count | |
669 return self._keep_positive() | |
670 | |
671 def __ior__(self, other): | |
672 '''Inplace union is the maximum of value from either counter. | |
673 | |
674 >>> c = Counter('abbb') | |
675 >>> c |= Counter('bcc') | |
676 >>> c | |
677 Counter({'b': 3, 'c': 2, 'a': 1}) | |
678 | |
679 ''' | |
680 for elem, other_count in other.items(): | |
681 count = self[elem] | |
682 if other_count > count: | |
683 self[elem] = other_count | |
684 return self._keep_positive() | |
685 | |
686 def __iand__(self, other): | |
687 '''Inplace intersection is the minimum of corresponding counts. | |
688 | |
689 >>> c = Counter('abbb') | |
690 >>> c &= Counter('bcc') | |
691 >>> c | |
692 Counter({'b': 1}) | |
693 | |
694 ''' | |
695 for elem, count in self.items(): | |
696 other_count = other[elem] | |
697 if other_count < count: | |
698 self[elem] = other_count | |
699 return self._keep_positive() | |
700 | |
701 | |
702 def check_output(*popenargs, **kwargs): | |
703 """ | |
704 For Python 2.6 compatibility: see | |
705 http://stackoverflow.com/questions/4814970/ | |
706 """ | |
707 | |
708 if 'stdout' in kwargs: | |
709 raise ValueError('stdout argument not allowed, it will be overridden.') | |
710 process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) | |
711 output, unused_err = process.communicate() | |
712 retcode = process.poll() | |
713 if retcode: | |
714 cmd = kwargs.get("args") | |
715 if cmd is None: | |
716 cmd = popenargs[0] | |
717 raise subprocess.CalledProcessError(retcode, cmd) | |
718 return output | |
719 | |
720 | |
721 def count(start=0, step=1): | |
722 """ | |
723 ``itertools.count`` in Py 2.6 doesn't accept a step | |
724 parameter. This is an enhanced version of ``itertools.count`` | |
725 for Py2.6 equivalent to ``itertools.count`` in Python 2.7+. | |
726 """ | |
727 while True: | |
728 yield start | |
729 start += step | |
730 | |
731 | |
732 ######################################################################## | |
733 ### ChainMap (helper for configparser and string.Template) | |
734 ### From the Py3.4 source code. See also: | |
735 ### https://github.com/kkxue/Py2ChainMap/blob/master/py2chainmap.py | |
736 ######################################################################## | |
737 | |
738 class ChainMap(MutableMapping): | |
739 ''' A ChainMap groups multiple dicts (or other mappings) together | |
740 to create a single, updateable view. | |
741 | |
742 The underlying mappings are stored in a list. That list is public and can | |
743 accessed or updated using the *maps* attribute. There is no other state. | |
744 | |
745 Lookups search the underlying mappings successively until a key is found. | |
746 In contrast, writes, updates, and deletions only operate on the first | |
747 mapping. | |
748 | |
749 ''' | |
750 | |
751 def __init__(self, *maps): | |
752 '''Initialize a ChainMap by setting *maps* to the given mappings. | |
753 If no mappings are provided, a single empty dictionary is used. | |
754 | |
755 ''' | |
756 self.maps = list(maps) or [{}] # always at least one map | |
757 | |
758 def __missing__(self, key): | |
759 raise KeyError(key) | |
760 | |
761 def __getitem__(self, key): | |
762 for mapping in self.maps: | |
763 try: | |
764 return mapping[key] # can't use 'key in mapping' with defaultdict | |
765 except KeyError: | |
766 pass | |
767 return self.__missing__(key) # support subclasses that define __missing__ | |
768 | |
769 def get(self, key, default=None): | |
770 return self[key] if key in self else default | |
771 | |
772 def __len__(self): | |
773 return len(set().union(*self.maps)) # reuses stored hash values if possible | |
774 | |
775 def __iter__(self): | |
776 return iter(set().union(*self.maps)) | |
777 | |
778 def __contains__(self, key): | |
779 return any(key in m for m in self.maps) | |
780 | |
781 def __bool__(self): | |
782 return any(self.maps) | |
783 | |
784 # Py2 compatibility: | |
785 __nonzero__ = __bool__ | |
786 | |
787 @recursive_repr() | |
788 def __repr__(self): | |
789 return '{0.__class__.__name__}({1})'.format( | |
790 self, ', '.join(map(repr, self.maps))) | |
791 | |
792 @classmethod | |
793 def fromkeys(cls, iterable, *args): | |
794 'Create a ChainMap with a single dict created from the iterable.' | |
795 return cls(dict.fromkeys(iterable, *args)) | |
796 | |
797 def copy(self): | |
798 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' | |
799 return self.__class__(self.maps[0].copy(), *self.maps[1:]) | |
800 | |
801 __copy__ = copy | |
802 | |
803 def new_child(self, m=None): # like Django's Context.push() | |
804 ''' | |
805 New ChainMap with a new map followed by all previous maps. If no | |
806 map is provided, an empty dict is used. | |
807 ''' | |
808 if m is None: | |
809 m = {} | |
810 return self.__class__(m, *self.maps) | |
811 | |
812 @property | |
813 def parents(self): # like Django's Context.pop() | |
814 'New ChainMap from maps[1:].' | |
815 return self.__class__(*self.maps[1:]) | |
816 | |
817 def __setitem__(self, key, value): | |
818 self.maps[0][key] = value | |
819 | |
820 def __delitem__(self, key): | |
821 try: | |
822 del self.maps[0][key] | |
823 except KeyError: | |
824 raise KeyError('Key not found in the first mapping: {0!r}'.format(key)) | |
825 | |
826 def popitem(self): | |
827 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' | |
828 try: | |
829 return self.maps[0].popitem() | |
830 except KeyError: | |
831 raise KeyError('No keys found in the first mapping.') | |
832 | |
833 def pop(self, key, *args): | |
834 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' | |
835 try: | |
836 return self.maps[0].pop(key, *args) | |
837 except KeyError: | |
838 raise KeyError('Key not found in the first mapping: {0!r}'.format(key)) | |
839 | |
840 def clear(self): | |
841 'Clear maps[0], leaving maps[1:] intact.' | |
842 self.maps[0].clear() | |
843 | |
844 | |
845 # Re-use the same sentinel as in the Python stdlib socket module: | |
846 from socket import _GLOBAL_DEFAULT_TIMEOUT | |
847 # Was: _GLOBAL_DEFAULT_TIMEOUT = object() | |
848 | |
849 | |
850 def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, | |
851 source_address=None): | |
852 """Backport of 3-argument create_connection() for Py2.6. | |
853 | |
854 Connect to *address* and return the socket object. | |
855 | |
856 Convenience function. Connect to *address* (a 2-tuple ``(host, | |
857 port)``) and return the socket object. Passing the optional | |
858 *timeout* parameter will set the timeout on the socket instance | |
859 before attempting to connect. If no *timeout* is supplied, the | |
860 global default timeout setting returned by :func:`getdefaulttimeout` | |
861 is used. If *source_address* is set it must be a tuple of (host, port) | |
862 for the socket to bind as a source address before making the connection. | |
863 An host of '' or port 0 tells the OS to use the default. | |
864 """ | |
865 | |
866 host, port = address | |
867 err = None | |
868 for res in getaddrinfo(host, port, 0, SOCK_STREAM): | |
869 af, socktype, proto, canonname, sa = res | |
870 sock = None | |
871 try: | |
872 sock = socket(af, socktype, proto) | |
873 if timeout is not _GLOBAL_DEFAULT_TIMEOUT: | |
874 sock.settimeout(timeout) | |
875 if source_address: | |
876 sock.bind(source_address) | |
877 sock.connect(sa) | |
878 return sock | |
879 | |
880 except error as _: | |
881 err = _ | |
882 if sock is not None: | |
883 sock.close() | |
884 | |
885 if err is not None: | |
886 raise err | |
887 else: | |
888 raise error("getaddrinfo returns an empty list") | |
889 | |
890 # Backport from Py2.7 for Py2.6: | |
891 def cmp_to_key(mycmp): | |
892 """Convert a cmp= function into a key= function""" | |
893 class K(object): | |
894 __slots__ = ['obj'] | |
895 def __init__(self, obj, *args): | |
896 self.obj = obj | |
897 def __lt__(self, other): | |
898 return mycmp(self.obj, other.obj) < 0 | |
899 def __gt__(self, other): | |
900 return mycmp(self.obj, other.obj) > 0 | |
901 def __eq__(self, other): | |
902 return mycmp(self.obj, other.obj) == 0 | |
903 def __le__(self, other): | |
904 return mycmp(self.obj, other.obj) <= 0 | |
905 def __ge__(self, other): | |
906 return mycmp(self.obj, other.obj) >= 0 | |
907 def __ne__(self, other): | |
908 return mycmp(self.obj, other.obj) != 0 | |
909 def __hash__(self): | |
910 raise TypeError('hash not implemented') | |
911 return K | |
912 | |
913 # Back up our definitions above in case they're useful | |
914 _OrderedDict = OrderedDict | |
915 _Counter = Counter | |
916 _check_output = check_output | |
917 _count = count | |
918 _ceil = ceil | |
919 __count_elements = _count_elements | |
920 _recursive_repr = recursive_repr | |
921 _ChainMap = ChainMap | |
922 _create_connection = create_connection | |
923 _cmp_to_key = cmp_to_key | |
924 | |
925 # Overwrite the definitions above with the usual ones | |
926 # from the standard library: | |
927 if sys.version_info >= (2, 7): | |
928 from collections import OrderedDict, Counter | |
929 from itertools import count | |
930 from functools import cmp_to_key | |
931 try: | |
932 from subprocess import check_output | |
933 except ImportError: | |
934 # Not available. This happens with Google App Engine: see issue #231 | |
935 pass | |
936 from socket import create_connection | |
937 | |
938 if sys.version_info >= (3, 0): | |
939 from math import ceil | |
940 from collections import _count_elements | |
941 | |
942 if sys.version_info >= (3, 3): | |
943 from reprlib import recursive_repr | |
944 from collections import ChainMap |