[issue28014] Strange interaction between methods in subclass of C OrderedDict

2016-10-25 Thread Josh Rosenberg

Josh Rosenberg added the comment:

Note: This class doesn't actually work on 3.4 in other ways (because 
__getitem__ is not idempotent, while OrderedDict assumes it is):

>>> s = SimpleLRUCache(2)
>>> s['t1'] = 1
>>> s
SimpleLRUCache([('t1', 1)])
>>> s['t2'] = 2
>>> s
SimpleLRUCache([('t1', 1)])
>>> s
SimpleLRUCache([('t2', 2)])  # <-- No changes, repr different

If your __getitem__ isn't idempotent, you've broken a basic assumption built 
into the logic of the other methods you inherited, and you're going to need to 
override other methods to avoid misbehavior.

--
nosy: +josh.r

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28014] Strange interaction between methods in subclass of C OrderedDict

2016-09-07 Thread Zachary Ware

Changes by Zachary Ware :


--
resolution:  -> duplicate
stage:  -> resolved
status: open -> closed
superseder:  -> KeyError thrown by optimised collections.OrderedDict.popitem()

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28014] Strange interaction between methods in subclass of C OrderedDict

2016-09-07 Thread Xiang Zhang

Xiang Zhang added the comment:

Please see issue27275. Someone has already complained about this. And I think 
the cause is the gap between Pure Python implementation and C implementation 
when it comes to subclasses.

--
nosy: +xiang.zhang

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28014] Strange interaction between methods in subclass of C OrderedDict

2016-09-07 Thread Zachary Ware

New submission from Zachary Ware:

I'm not certain that the implementation of this subclass of OrderedDict is 
actually sane, but it works in 3.4 and fails in 3.5+.

The buggy implementation:

class SimpleLRUCache(OrderedDict):

def __init__(self, size):
super().__init__()
self.size = size

def __getitem__(self, item):
value = super().__getitem__(item)
self.move_to_end(item)
return value

def __setitem__(self, key, value):
while key not in self and len(self) >= self.size:
self.popitem(last=False)
super().__setitem__(key, value)
self.move_to_end(key)


When trying to add a new item after `size` items are already in the cache, it 
will throw a KeyError with the key of the item in the oldest position.  
Something like:

>>> s = SimpleLRUCache(2)
>>> s['t1'] = 1
>>> s['t2'] = 2
>>> s['t2'] # gives 2, properly moves 2 to the end
>>> s['t3'] = 3

Traceback (most recent call last):
  File "", line 1, in 
  File "simple_lru.py", line 14, in __setitem__
self.popitem(last=False)
  File "simple_lru.py", line 9, in __getitem__
self.move_to_end(item)
KeyError: 't3'


I can work around the failure by implementing __getitem__ as follows:

def __getitem__(self, item):
value = super().__getitem__(item)
del self[item]
self[item] = value
return value

Attached is a script with a couple of tests that pass with 3.4 and fail with 
3.5+.

--
files: simple_lru.py
messages: 274959
nosy: eric.snow, zach.ware
priority: normal
severity: normal
status: open
title: Strange interaction between methods in subclass of C OrderedDict
type: behavior
versions: Python 3.5, Python 3.6
Added file: http://bugs.python.org/file44458/simple_lru.py

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com