Skip to content

Commit 43858b1

Browse files
committed
update sortedcontainers
1 parent 5645e3e commit 43858b1

File tree

4 files changed

+313
-233
lines changed

4 files changed

+313
-233
lines changed
Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
# -*- coding: utf-8 -*-
2-
3-
"""
4-
sortedcontainers Sorted Container Types Library
5-
===============================================
1+
"""Sorted Container Types: SortedList, SortedDict, SortedSet
62
73
SortedContainers is an Apache2 licensed containers library, written in
84
pure-Python, and fast as C-extensions.
95
10-
Python's standard library is great until you need a sorted container type. Many
11-
will attest that you can get really far without one, but the moment you
12-
**really need** a sorted list, dict, or set, you're faced with a dozen
6+
7+
Python's standard library is great until you need a sorted collections
8+
type. Many will attest that you can get really far without one, but the moment
9+
you **really need** a sorted list, dict, or set, you're faced with a dozen
1310
different implementations, most using C-extensions without great documentation
1411
and benchmarking.
1512
16-
Things shouldn't be this way. Not in Python.
13+
In Python, we can do better. And we can do it in pure-Python!
1714
1815
::
1916
@@ -35,20 +32,21 @@
3532
pre-build and distribute custom extensions. Performance is a feature and
3633
testing has 100% coverage with unit tests and hours of stress.
3734
38-
:copyright: (c) 2015 by Grant Jenks.
35+
:copyright: (c) 2016 by Grant Jenks.
3936
:license: Apache 2.0, see LICENSE for more details.
4037
4138
"""
4239

43-
__title__ = 'sortedcontainers'
44-
__version__ = '1.4.4'
45-
__build__ = 0x010404
46-
__author__ = 'Grant Jenks'
47-
__license__ = 'Apache 2.0'
48-
__copyright__ = 'Copyright 2015 Grant Jenks'
4940

5041
from .sortedlist import SortedList, SortedListWithKey
5142
from .sortedset import SortedSet
5243
from .sorteddict import SortedDict
5344

5445
__all__ = ['SortedList', 'SortedSet', 'SortedDict', 'SortedListWithKey']
46+
47+
__title__ = 'sortedcontainers'
48+
__version__ = '1.5.3'
49+
__build__ = 0x010503
50+
__author__ = 'Grant Jenks'
51+
__license__ = 'Apache 2.0'
52+
__copyright__ = 'Copyright 2016 Grant Jenks'

source_py3/python_toolbox/third_party/sortedcontainers/sorteddict.py

Lines changed: 65 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,22 @@
1-
# -*- coding: utf-8 -*-
2-
#
3-
# Sorted dict implementation.
1+
"""Sorted dictionary implementation.
2+
3+
"""
44

5-
from .sortedset import SortedSet
6-
from .sortedlist import SortedList, recursive_repr, SortedListWithKey
75
from collections import Set, Sequence
86
from collections import KeysView as AbstractKeysView
97
from collections import ValuesView as AbstractValuesView
108
from collections import ItemsView as AbstractItemsView
11-
12-
from functools import wraps
139
from sys import hexversion
1410

15-
_NotGiven = object()
16-
17-
def not26(func):
18-
"""Function decorator for methods not implemented in Python 2.6."""
11+
from .sortedlist import SortedList, recursive_repr, SortedListWithKey
12+
from .sortedset import SortedSet
1913

20-
@wraps(func)
21-
def errfunc(*args, **kwargs):
22-
raise NotImplementedError
14+
NONE = object()
2315

24-
if hexversion < 0x02070000:
25-
return errfunc
26-
else:
27-
return func
2816

29-
class _IlocWrapper:
17+
class _IlocWrapper(object):
18+
"Positional indexing support for sorted dictionary objects."
19+
# pylint: disable=protected-access, too-few-public-methods
3020
def __init__(self, _dict):
3121
self._dict = _dict
3222
def __len__(self):
@@ -43,9 +33,9 @@ def __delitem__(self, index):
4333
Remove the ``sdict[sdict.iloc[index]]`` from *sdict*. Supports negative
4434
indices and slice notation. Raises IndexError on invalid *index*.
4535
"""
46-
_temp = self._dict
47-
_list = _temp._list
48-
_delitem = _temp._delitem
36+
_dict = self._dict
37+
_list = _dict._list
38+
_delitem = _dict._delitem
4939

5040
if isinstance(index, slice):
5141
keys = _list[index]
@@ -57,19 +47,19 @@ def __delitem__(self, index):
5747
del _list[index]
5848
_delitem(key)
5949

50+
6051
class SortedDict(dict):
61-
"""
62-
A SortedDict provides the same methods as a dict. Additionally, a
63-
SortedDict efficiently maintains its keys in sorted order. Consequently, the
64-
keys method will return the keys in sorted order, the popitem method will
65-
remove the item with the highest key, etc.
52+
"""SortedDict provides the same methods as a dict. Additionally, SortedDict
53+
efficiently maintains its keys in sorted order. Consequently, the keys
54+
method will return the keys in sorted order, the popitem method will remove
55+
the item with the highest key, etc.
56+
6657
"""
6758
def __init__(self, *args, **kwargs):
68-
"""
69-
A SortedDict provides the same methods as a dict. Additionally, a
70-
SortedDict efficiently maintains its keys in sorted order. Consequently,
71-
the keys method will return the keys in sorted order, the popitem method
72-
will remove the item with the highest key, etc.
59+
"""SortedDict provides the same methods as a dict. Additionally, SortedDict
60+
efficiently maintains its keys in sorted order. Consequently, the keys
61+
method will return the keys in sorted order, the popitem method will
62+
remove the item with the highest key, etc.
7363
7464
An optional *key* argument defines a callable that, like the `key`
7565
argument to Python's `sorted` function, extracts a comparison key from
@@ -105,14 +95,16 @@ def __init__(self, *args, **kwargs):
10595
10696
The first example only works for keys that are valid Python
10797
identifiers; the others work with any valid keys.
98+
10899
"""
100+
# pylint: disable=super-init-not-called, redefined-variable-type
109101
if len(args) > 0 and (args[0] is None or callable(args[0])):
110102
self._key = args[0]
111103
args = args[1:]
112104
else:
113105
self._key = None
114106

115-
if len(args) > 0 and type(args[0]) == int:
107+
if len(args) > 0 and isinstance(args[0], int):
116108
self._load = args[0]
117109
args = args[1:]
118110
else:
@@ -282,7 +274,7 @@ def itervalues(self):
282274

283275
_itervalues = itervalues
284276

285-
def pop(self, key, default=_NotGiven):
277+
def pop(self, key, default=NONE):
286278
"""
287279
If *key* is in the dictionary, remove it and return its value,
288280
else return *default*. If *default* is not given and *key* is not in
@@ -292,7 +284,7 @@ def pop(self, key, default=_NotGiven):
292284
self._list_remove(key)
293285
return self._pop(key)
294286
else:
295-
if default is _NotGiven:
287+
if default is NONE:
296288
raise KeyError(key)
297289
else:
298290
return default
@@ -314,6 +306,19 @@ def popitem(self, last=True):
314306

315307
return (key, value)
316308

309+
def peekitem(self, index=-1):
310+
"""Return (key, value) item pair at index.
311+
312+
Unlike ``popitem``, the sorted dictionary is not modified. Index
313+
defaults to -1, the last/greatest key in the dictionary. Specify
314+
``index=0`` to lookup the first/least key in the dictiony.
315+
316+
If index is out of range, raise IndexError.
317+
318+
"""
319+
key = self._list[index]
320+
return key, self[key]
321+
317322
def setdefault(self, key, default=None):
318323
"""
319324
If *key* is in the dictionary, return its value. If not, insert *key*
@@ -342,7 +347,7 @@ def update(self, *args, **kwargs):
342347
self._list_update(self._iter())
343348
return
344349

345-
if (len(kwargs) == 0 and len(args) == 1 and isinstance(args[0], dict)):
350+
if len(kwargs) == 0 and len(args) == 1 and isinstance(args[0], dict):
346351
pairs = args[0]
347352
else:
348353
pairs = dict(*args, **kwargs)
@@ -357,35 +362,18 @@ def update(self, *args, **kwargs):
357362

358363
_update = update
359364

360-
@not26
361-
def viewkeys(self):
362-
"""
363-
In Python 2.7 and later, return a new `KeysView` of the dictionary's
364-
keys.
365-
366-
In Python 2.6, raise a NotImplementedError.
367-
"""
368-
return KeysView(self)
369-
370-
@not26
371-
def viewvalues(self):
372-
"""
373-
In Python 2.7 and later, return a new `ValuesView` of the dictionary's
374-
values.
375-
376-
In Python 2.6, raise a NotImplementedError.
377-
"""
378-
return ValuesView(self)
365+
if hexversion >= 0x02070000:
366+
def viewkeys(self):
367+
"Return ``KeysView`` of dictionary keys."
368+
return KeysView(self)
379369

380-
@not26
381-
def viewitems(self):
382-
"""
383-
In Python 2.7 and later, return a new `ItemsView` of the dictionary's
384-
items.
370+
def viewvalues(self):
371+
"Return ``ValuesView`` of dictionary values."
372+
return ValuesView(self)
385373

386-
In Python 2.6, raise a NotImplementedError.
387-
"""
388-
return ItemsView(self)
374+
def viewitems(self):
375+
"Return ``ItemsView`` of dictionary (key, value) item pairs."
376+
return ItemsView(self)
389377

390378
def __reduce__(self):
391379
return (self.__class__, (self._key, self._load, list(self._iteritems())))
@@ -403,9 +391,11 @@ def __repr__(self):
403391
)
404392

405393
def _check(self):
394+
# pylint: disable=protected-access
406395
self._list._check()
407396
assert len(self) == len(self._list)
408-
assert all(val in self for val in self._list)
397+
assert all(key in self for key in self._list)
398+
409399

410400
class KeysView(AbstractKeysView, Set, Sequence):
411401
"""
@@ -420,13 +410,15 @@ def __init__(self, sorted_dict):
420410
"""
421411
Initialize a KeysView from a SortedDict container as *sorted_dict*.
422412
"""
413+
# pylint: disable=super-init-not-called, protected-access
423414
self._list = sorted_dict._list
424415
self._view = sorted_dict._dict.viewkeys()
425416
else:
426417
def __init__(self, sorted_dict):
427418
"""
428419
Initialize a KeysView from a SortedDict container as *sorted_dict*.
429420
"""
421+
# pylint: disable=super-init-not-called, protected-access
430422
self._list = sorted_dict._list
431423
self._view = sorted_dict._dict.keys()
432424
def __len__(self):
@@ -466,6 +458,7 @@ def index(self, value, start=None, stop=None):
466458
to the end of the set. *start* defaults to the beginning. Negative
467459
indexes are supported, as for slice indices.
468460
"""
461+
# pylint: disable=arguments-differ
469462
return self._list.index(value, start, stop)
470463
def count(self, value):
471464
"""Return the number of occurrences of *value* in the set."""
@@ -512,6 +505,7 @@ def isdisjoint(self, that):
512505
def __repr__(self):
513506
return 'SortedDict_keys({0})'.format(repr(list(self)))
514507

508+
515509
class ValuesView(AbstractValuesView, Sequence):
516510
"""
517511
A ValuesView object is a dynamic view of the dictionary's values, which
@@ -526,6 +520,7 @@ def __init__(self, sorted_dict):
526520
Initialize a ValuesView from a SortedDict container as
527521
*sorted_dict*.
528522
"""
523+
# pylint: disable=super-init-not-called, protected-access
529524
self._dict = sorted_dict
530525
self._list = sorted_dict._list
531526
self._view = sorted_dict._dict.viewvalues()
@@ -535,6 +530,7 @@ def __init__(self, sorted_dict):
535530
Initialize a ValuesView from a SortedDict container as
536531
*sorted_dict*.
537532
"""
533+
# pylint: disable=super-init-not-called, protected-access
538534
self._dict = sorted_dict
539535
self._list = sorted_dict._list
540536
self._view = sorted_dict._dict.values()
@@ -587,8 +583,7 @@ def index(self, value):
587583
for idx, val in enumerate(self):
588584
if value == val:
589585
return idx
590-
else:
591-
raise ValueError('{0} is not in dict'.format(repr(value)))
586+
raise ValueError('{0} is not in dict'.format(repr(value)))
592587
if hexversion < 0x03000000:
593588
def count(self, value):
594589
"""Return the number of occurrences of *value* in self."""
@@ -617,6 +612,7 @@ def __xor__(self, that):
617612
def __repr__(self):
618613
return 'SortedDict_values({0})'.format(repr(list(self)))
619614

615+
620616
class ItemsView(AbstractItemsView, Set, Sequence):
621617
"""
622618
An ItemsView object is a dynamic view of the dictionary's ``(key,
@@ -633,6 +629,7 @@ def __init__(self, sorted_dict):
633629
Initialize an ItemsView from a SortedDict container as
634630
*sorted_dict*.
635631
"""
632+
# pylint: disable=super-init-not-called, protected-access
636633
self._dict = sorted_dict
637634
self._list = sorted_dict._list
638635
self._view = sorted_dict._dict.viewitems()
@@ -642,6 +639,7 @@ def __init__(self, sorted_dict):
642639
Initialize an ItemsView from a SortedDict container as
643640
*sorted_dict*.
644641
"""
642+
# pylint: disable=super-init-not-called, protected-access
645643
self._dict = sorted_dict
646644
self._list = sorted_dict._list
647645
self._view = sorted_dict._dict.items()
@@ -689,6 +687,7 @@ def index(self, key, start=None, stop=None):
689687
to the end of the set. *start* defaults to the beginning. Negative
690688
indexes are supported, as for slice indices.
691689
"""
690+
# pylint: disable=arguments-differ
692691
temp, value = key
693692
pos = self._list.index(temp, start, stop)
694693
if value == self._dict[temp]:

0 commit comments

Comments
 (0)