/usr/lib/python2.7/dist-packages/stuf/collects.py is in python-stuf 0.9.16-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | # -*- coding: utf-8 -*-
'''stuf collections.'''
import sys
from .deep import getcls
from .base import second, first
from .six import OrderedDict, items
try:
from reprlib import recursive_repr # @UnusedImport
except ImportError:
from .six import get_ident, getdoc, getmod, docit
def recursive_repr(fillvalue='...'):
def decorating_function(user_function):
repr_running = set()
def wrapper(self): # @IgnorePep8
key = id(self), get_ident()
if key in repr_running:
return fillvalue
repr_running.add(key)
try:
result = user_function(self)
finally:
repr_running.discard(key)
return result
wrapper.__module__ = getmod(user_function)
docit(wrapper, getdoc(user_function))
return wrapper
return decorating_function
version = sys.version_info
if version[0] == 3 and version[1] > 1:
from collections import Counter
else:
from heapq import nlargest
from itertools import chain, starmap, repeat
from .deep import clsname
from .base import ismapping
class Counter(dict):
'''dict subclass for counting hashable items'''
def __init__(self, iterable=None, **kw):
'''
If given, count elements from an input iterable. Or, initialize
count from another mapping of elements to their counts.
'''
super(Counter, self).__init__()
self.update(iterable, **kw)
def __missing__(self, key):
'''The count of elements not in the Counter is zero.'''
return 0
def __reduce__(self):
return getcls(self), (dict(self),)
def __delitem__(self, elem):
'''
Like dict.__delitem__() but does not raise KeyError for missing'
values.
'''
if elem in self:
super(Counter, self).__delitem__(elem)
def __repr__(self): # pragma: no coverage
if not self:
return '%s()' % clsname(self)
try:
items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
return '%s({%s})' % (clsname(self), items)
except TypeError:
# handle case where values are not orderable
return '{0}({1!r})'.format(clsname(self), dict(self))
def __add__(self, other):
'''Add counts from two counters.'''
if not isinstance(other, getcls(self)):
return NotImplemented()
result = getcls(self)()
for elem, count in items(self):
newcount = count + other[elem]
if newcount > 0:
result[elem] = newcount
for elem, count in items(other):
if elem not in self and count > 0:
result[elem] = count
return result
def __sub__(self, other):
'''Subtract count, but keep only results with positive counts.'''
if not isinstance(other, getcls(self)):
return NotImplemented()
result = getcls(self)()
for elem, count in items(self):
newcount = count - other[elem]
if newcount > 0:
result[elem] = newcount
for elem, count in items(other):
if elem not in self and count < 0:
result[elem] = 0 - count
return result
def __or__(self, other):
'''Union is the maximum of value in either of the input counters.'''
if not isinstance(other, getcls(self)):
return NotImplemented()
result = getcls(self)()
for elem, count in items(self):
other_count = other[elem]
newcount = other_count if count < other_count else count
if newcount > 0:
result[elem] = newcount
for elem, count in items(other):
if elem not in self and count > 0:
result[elem] = count
return result
def __and__(self, other):
'''Intersection is the minimum of corresponding counts.'''
if not isinstance(other, getcls(self)):
return NotImplemented()
result = getcls(self)()
for elem, count in items(self):
other_count = other[elem]
newcount = count if count < other_count else other_count
if newcount > 0:
result[elem] = newcount
return result
def __pos__(self):
'''
Adds an empty counter, effectively stripping negative and zero
counts.
'''
return self + getcls(self)()
def __neg__(self):
'''
Subtracts from an empty counter. Strips positive and zero counts,
and flips the sign on negative counts.
'''
return getcls(self)() - self
def most_common(self, n=None, nl=nlargest, i=items, g=second):
'''
List the n most common elements and their counts from the most
common to the least. If n is None, then list all element counts.
'''
if n is None:
return sorted(i(self), key=g, reverse=True)
return nl(n, i(self), key=g)
def elements(self):
'''
Iterator over elements repeating each as many times as its count.
'''
return chain.from_iterable(starmap(repeat, items(self)))
@classmethod
def fromkeys(cls, iterable, v=None):
raise NotImplementedError(
'Counter.fromkeys() undefined. Use Counter(iterable) instead.'
)
def update(self, iterable=None, **kwds):
'''Like dict.update() but add counts instead of replacing them.'''
if iterable is not None:
if ismapping(iterable):
if self:
self_get = self.get
for elem, count in items(iterable):
self[elem] = count + self_get(elem, 0)
else:
super(Counter, self).update(iterable)
else:
mapping_get = self.get
for elem in iterable:
self[elem] = mapping_get(elem, 0) + 1
if kwds:
self.update(kwds)
def subtract(self, iterable=None, **kwds):
'''
Like dict.update() but subtracts counts instead of replacing them.
Counts can be reduced below zero. Both the inputs and outputs are
allowed to contain zero and negative counts.
Source can be an iterable, a dictionary, or another Counter
instance.
'''
if iterable is not None:
self_get = self.get
if ismapping(iterable):
for elem, count in items(iterable):
self[elem] = self_get(elem, 0) - count
else:
for elem in iterable:
self[elem] = self_get(elem, 0) - 1
if kwds:
self.subtract(kwds)
def copy(self):
'Return a shallow copy.'
return getcls(self)(self)
try:
from collections import ChainMap # @UnusedImport
except ImportError:
# not until Python >= 3.3
from collections import MutableMapping
class ChainMap(MutableMapping):
'''
`ChainMap` groups multiple dicts (or other mappings) together to create
a single, updateable view.
'''
def __init__(self, *maps):
'''
Initialize `ChainMap` by setting *maps* to the given mappings. If no
mappings are provided, a single empty dictionary is used.
'''
# always at least one map
self.maps = list(maps) or [OrderedDict()]
def __missing__(self, key):
raise KeyError(key)
def __getitem__(self, key):
for mapping in self.maps:
try:
# can't use 'key in mapping' with defaultdict
return mapping[key]
except KeyError:
pass
# support subclasses that define __missing__
return self.__missing__(key)
def get(self, key, default=None):
return self[key] if key in self else default
def __len__(self):
# reuses stored hash values if possible
return len(set().union(*self.maps))
def __iter__(self, set=set):
return set().union(*self.maps).__iter__()
def __contains__(self, key, any=any):
return any(key in m for m in self.maps)
def __bool__(self, any=any):
return any(self.maps)
@classmethod
def fromkeys(cls, iterable, *args):
'''
Create a ChainMap with a single dict created from the iterable.
'''
return cls(dict.fromkeys(iterable, *args))
def copy(self):
'''
New ChainMap or subclass with a new copy of maps[0] and refs to
maps[1:]
'''
return getcls(self)(first(self.maps).copy(), *self.maps[1:])
__copy__ = copy
def new_child(self):
'''New ChainMap with a new dict followed by all previous maps.'''
# like Django's Context.push()
return getcls(self)({}, *self.maps)
@property
def parents(self):
'''New ChainMap from maps[1:].'''
# like Django's Context.pop()
return getcls(self)(*self.maps[1:])
def __setitem__(self, key, value):
first(self.maps)[key] = value
def __delitem__(self, key):
try:
del first(self.maps)[key]
except KeyError:
raise KeyError(
'Key not found in the first mapping: {r}'.format(key)
)
def popitem(self):
'''
Remove and return an item pair from maps[0]. Raise `KeyError` is
maps[0] is empty.
'''
try:
return first(self.maps).popitem()
except KeyError:
raise KeyError('No keys found in the first mapping.')
def pop(self, key, *args):
'''
Remove *key* from maps[0] and return its value. Raise KeyError if
*key* not in maps[0].
'''
try:
return first(self.maps).pop(key, *args)
except KeyError:
raise KeyError(
'Key not found in the first mapping: {r}'.format(key)
)
def clear(self):
'''Clear maps[0], leaving maps[1:] intact.'''
first(self.maps).clear()
|