@@ -75,7 +75,7 @@ class Deque(Sequence):
75
75
76
76
"""
77
77
78
- def __init__ (self , iterable = (), directory = None ):
78
+ def __init__ (self , iterable = (), directory = None , maxlen = None ):
79
79
"""Initialize deque instance.
80
80
81
81
If directory is None then temporary directory created. The directory
@@ -86,10 +86,11 @@ def __init__(self, iterable=(), directory=None):
86
86
87
87
"""
88
88
self ._cache = Cache (directory , eviction_policy = 'none' )
89
- self .extend (iterable )
89
+ self ._maxlen = float ('inf' ) if maxlen is None else maxlen
90
+ self ._extend (iterable )
90
91
91
92
@classmethod
92
- def fromcache (cls , cache , iterable = ()):
93
+ def fromcache (cls , cache , iterable = (), maxlen = None ):
93
94
"""Initialize deque using `cache`.
94
95
95
96
>>> cache = Cache()
@@ -111,7 +112,8 @@ def fromcache(cls, cache, iterable=()):
111
112
# pylint: disable=no-member,protected-access
112
113
self = cls .__new__ (cls )
113
114
self ._cache = cache
114
- self .extend (iterable )
115
+ self ._maxlen = float ('inf' ) if maxlen is None else maxlen
116
+ self ._extend (iterable )
115
117
return self
116
118
117
119
@property
@@ -124,6 +126,31 @@ def directory(self):
124
126
"""Directory path where deque is stored."""
125
127
return self ._cache .directory
126
128
129
+ @property
130
+ def maxlen (self ):
131
+ """Max length of the deque."""
132
+ return self ._maxlen
133
+
134
+ @maxlen .setter
135
+ def maxlen (self , value ):
136
+ """Set max length of the deque.
137
+
138
+ Pops items from left while length greater than max.
139
+
140
+ >>> deque = Deque()
141
+ >>> deque.extendleft('abcde')
142
+ >>> deque.maxlen = 3
143
+ >>> list(deque)
144
+ ['c', 'd', 'e']
145
+
146
+ :param value: max length
147
+
148
+ """
149
+ self ._maxlen = value
150
+ with self ._cache .transact (retry = True ):
151
+ while len (self ._cache ) > self ._maxlen :
152
+ self ._popleft ()
153
+
127
154
def _index (self , index , func ):
128
155
len_self = len (self )
129
156
@@ -244,7 +271,7 @@ def __iadd__(self, iterable):
244
271
:return: deque with added items
245
272
246
273
"""
247
- self .extend (iterable )
274
+ self ._extend (iterable )
248
275
return self
249
276
250
277
def __iter__ (self ):
@@ -292,10 +319,11 @@ def __reversed__(self):
292
319
pass
293
320
294
321
def __getstate__ (self ):
295
- return self .directory
322
+ return self .directory , self . maxlen
296
323
297
324
def __setstate__ (self , state ):
298
- self .__init__ (directory = state )
325
+ directory , maxlen = state
326
+ self .__init__ (directory = directory , maxlen = maxlen )
299
327
300
328
def append (self , value ):
301
329
"""Add `value` to back of deque.
@@ -310,7 +338,12 @@ def append(self, value):
310
338
:param value: value to add to back of deque
311
339
312
340
"""
313
- self ._cache .push (value , retry = True )
341
+ with self ._cache .transact (retry = True ):
342
+ self ._cache .push (value , retry = True )
343
+ if len (self ._cache ) > self ._maxlen :
344
+ self ._popleft ()
345
+
346
+ _append = append
314
347
315
348
def appendleft (self , value ):
316
349
"""Add `value` to front of deque.
@@ -325,7 +358,12 @@ def appendleft(self, value):
325
358
:param value: value to add to front of deque
326
359
327
360
"""
328
- self ._cache .push (value , side = 'front' , retry = True )
361
+ with self ._cache .transact (retry = True ):
362
+ self ._cache .push (value , side = 'front' , retry = True )
363
+ if len (self ._cache ) > self ._maxlen :
364
+ self ._pop ()
365
+
366
+ _appendleft = appendleft
329
367
330
368
def clear (self ):
331
369
"""Remove all elements from deque.
@@ -340,6 +378,13 @@ def clear(self):
340
378
"""
341
379
self ._cache .clear (retry = True )
342
380
381
+ _clear = clear
382
+
383
+ def copy (self ):
384
+ """Copy deque with same directory and max length."""
385
+ TypeSelf = type (self )
386
+ return TypeSelf (directory = self .directory , maxlen = self .maxlen )
387
+
343
388
def count (self , value ):
344
389
"""Return number of occurrences of `value` in deque.
345
390
@@ -365,7 +410,9 @@ def extend(self, iterable):
365
410
366
411
"""
367
412
for value in iterable :
368
- self .append (value )
413
+ self ._append (value )
414
+
415
+ _extend = extend
369
416
370
417
def extendleft (self , iterable ):
371
418
"""Extend front side of deque with value from `iterable`.
@@ -379,7 +426,7 @@ def extendleft(self, iterable):
379
426
380
427
"""
381
428
for value in iterable :
382
- self .appendleft (value )
429
+ self ._appendleft (value )
383
430
384
431
def peek (self ):
385
432
"""Peek at value at back of deque.
@@ -459,6 +506,8 @@ def pop(self):
459
506
raise IndexError ('pop from an empty deque' )
460
507
return value
461
508
509
+ _pop = pop
510
+
462
511
def popleft (self ):
463
512
"""Remove and return value at front of deque.
464
513
@@ -483,6 +532,8 @@ def popleft(self):
483
532
raise IndexError ('pop from an empty deque' )
484
533
return value
485
534
535
+ _popleft = popleft
536
+
486
537
def remove (self , value ):
487
538
"""Remove first occurrence of `value` in deque.
488
539
@@ -537,8 +588,8 @@ def reverse(self):
537
588
# forward iterator and a reverse iterator, the reverse method could
538
589
# avoid making copies of the values.
539
590
temp = Deque (iterable = reversed (self ))
540
- self .clear ()
541
- self .extend (temp )
591
+ self ._clear ()
592
+ self ._extend (temp )
542
593
directory = temp .directory
543
594
temp ._cache .close ()
544
595
del temp
@@ -575,22 +626,22 @@ def rotate(self, steps=1):
575
626
576
627
for _ in range (steps ):
577
628
try :
578
- value = self .pop ()
629
+ value = self ._pop ()
579
630
except IndexError :
580
631
return
581
632
else :
582
- self .appendleft (value )
633
+ self ._appendleft (value )
583
634
else :
584
635
steps *= - 1
585
636
steps %= len_self
586
637
587
638
for _ in range (steps ):
588
639
try :
589
- value = self .popleft ()
640
+ value = self ._popleft ()
590
641
except IndexError :
591
642
return
592
643
else :
593
- self .append (value )
644
+ self ._append (value )
594
645
595
646
__hash__ = None # type: ignore
596
647
@@ -669,7 +720,9 @@ def __init__(self, *args, **kwargs):
669
720
args = args [1 :]
670
721
directory = None
671
722
self ._cache = Cache (directory , eviction_policy = 'none' )
672
- self .update (* args , ** kwargs )
723
+ self ._update (* args , ** kwargs )
724
+
725
+ _update = MutableMapping .update
673
726
674
727
@classmethod
675
728
def fromcache (cls , cache , * args , ** kwargs ):
@@ -695,7 +748,7 @@ def fromcache(cls, cache, *args, **kwargs):
695
748
# pylint: disable=no-member,protected-access
696
749
self = cls .__new__ (cls )
697
750
self ._cache = cache
698
- self .update (* args , ** kwargs )
751
+ self ._update (* args , ** kwargs )
699
752
return self
700
753
701
754
@property
0 commit comments