How can you port this code from 2.5 to 3.4 version?
from __future__ import with_statement
from ..globals import addonPath
import os, time
import collections
class TailDeque(collections.deque):
'''Implementation of deque with limited maxlen support for Python 2.5.'''
def __init__(self, iterable=None, maxlen=20):
super(TailDeque, self).__init__([])
self.maxlen = maxlen
if iterable is not None:
self.extend(iterable)
def extend(self, iterable):
for item in iterable:
self.append(item)
def extendleft(self, iterable):
for item in iterable:
self.appendleft(item)
def appendleft(self, item):
if len(self) == self.maxlen:
self.pop()
super(TailDeque, self).appendleft(item)
def append(self, item):
if len(self) == self.maxlen:
self.popleft()
super(TailDeque, self).append(item)
logPath = os.path.join( addonPath, "log.txt" )
logQueue = TailDeque()
def log(text):
return
logQueue.append(time.strftime("%H:%M:%S") + " - " + text)
with open(logPath, "w") as fs:
fs.write('\n'.join(logQueue))
Line 10: self.maxlen = maxlen
AttributeError: attribute 'maxlen' of 'collections.deque' objects is not writable
I think you need to replace these two lines:
super(TailDeque, self).__init__([])
self.maxlen = maxlen
with:
if sys.version_info <= (2, 5):
super(TailDeque, self).__init__([])
self.maxlen = maxlen
else:
super(TailDeque, self).__init__([], maxlen=maxlen)
If you don’t need to maintain compatibility with Python 2.5, you can be a bit simpler:
super(TailDeque, self).__init__([], maxlen=maxlen)
In Python 2.5, the constructor for collections.deque
only took a single argument, iterable:
deque([iterable])
so you had to set the maxlen after initialising the object.
In Python 2.6, you were able to supply maxlen as an optional argument:
collections.deque([iterable[, maxlen]])
This has stayed the same into Python 3.4. I think that setting it as a constructor argument was the preferred approach from 2.6 onwards. They couldn’t take away your approach – setting the attribute directly – in the 2.x series, because they didn’t want to break backwards compatibility.
With Python 3, there were no such concerns, and so using constructor arguments became the only approach you could use.
Rather than initialising with an empty list and then extending with the user-supplied utterable, why not pass that iterable to collections.deque
directly? i.e.
super(TailDeque, self).__init__(iterable, maxlen=maxlen)