Except popitem, the constructor also goes different code path. There seems to be some difference behaviours between C version and pure Python version when it comes to subclass. Calling PyObject_DelItem() directly on the node should work fine I believe. Revising the behaviour of popitem() to avoid calling _odict_popkey_hash() seems like it may provide a marginal performance benefit as well as fix the problem. It seems to me that calling _contains_() (PySequence_Contains()) isn't necessary, as the first and last elements of the list are already known, and therefore known to be in the list. Even if it passes _contains_, it will call _getitem_. In _contains_ it deletes the item since it expires, and finally emit a KeyError. I want to correct my last message that popitem does not fail in this case because it calls _getitem_ but instead it calls _contains_. Raymond, In single threaded case popitem may still fail. I don't think this is a locking-related issue as the expiringdict test case itself fails which is also single-threaded. This might explain why you've observed, '''Replacing use of popitem() with "del self" removes the KeyErrors and the structure otherwise works fine.'''Īt least in my case, the application is single-threaded. If the first thread runs between the two steps in the second, the race condition would cause a KeyError. Otherwise, there is a risk that one thread is deleting a key with no lock held, while another thread is running expiringdict.popitem() which holds a lock while calling both _getitem_ and del. I'm wondering if the expiringdict(1) needs to have locked wrappers for the inherited methods: I haven't checked that.ĭ = ExpiringDict(max_len=3, max_age_seconds=0.01) I think the new OrderedDict may call your _getitem_ even in iteration which leads to the 'RuntimeError: OrderedDict mutated during iteration'. The C version's OrderedDict.popitem may call your _getitem_ which then does deletion and emit KeyError when expires. I think your expiringdict seems not work with the C version OrderedDict, you may need to change your implementation or clarify that :(. Replacing use of popitem() with "del self" removes the KeyErrors and the structure otherwise works fine. :(Īuthor: Serhiy Storchaka (serhiy.storchaka) *Ī frequent reproducer is to run the expiringdict tests on Python 3.5.1, unfortunately I cannot come up with a testcase. The C-based optimised version of collections.OrderedDict occasionally throws KeyErrors when deleting items.īackporting 3.6's patches to 3.5.1 does not resolve the issue. These were the 6 different ways to remove a Key from a dictionary in python.KeyError thrown by optimised ()ĭennis Sweeney, eric.snow, josh.r, kaniini, lukasz.langa, methane, python-dev, rhettinger, serhiy.storchaka, xiang.zhang, zach.wareĬreated on 04:33 by kaniini, last changed 14:58 by admin. Output: Key where is not in the dictionary Updated Dictionary : is not in the dictionary') Print("Updated Dictionary :", word_freq_dict) Result = word_freq_dict.pop(key_to_be_deleted, None) # As 'this' key is present in dict, so pop() will delete Python : 6 Different ways to create Dictionaries.Python: Pretty print nested dictionaries – dict of dicts.Convert dictionary values to a list in Python.Create CSV file from List of Dictionaries in Python. Python - Access Nth item in List Of Tuples Python - Check if a value is in Dictionary Python - Returning Multiple Values in Function
0 Comments
Leave a Reply. |