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
75from collections import Set , Sequence
86from collections import KeysView as AbstractKeysView
97from collections import ValuesView as AbstractValuesView
108from collections import ItemsView as AbstractItemsView
11-
12- from functools import wraps
139from 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+
6051class 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
410400class 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+
515509class 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+
620616class 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