If you provide a __copy__ method (renaming your clone method would do fine) then you will be ok. You might want to consider providing an __deepcopy__ method as well.
On 15/02/2013, at 1:13 PM, Brian May <[email protected]> wrote: > Hello, > > I have the following class, for case insensitive dictionary operations, while > preserving the case for times this is required. Unfortunately, it doesn't > work well with the Python copy module. I get random intermittent errors like > "AttributeError: 'CaseInsensitiveDict' object has no attribute 'lc'" in > __setitem__ which is weird, because lc is initialized in the constructor. > > I can only assume that the copy module does not call the constructor, but > does expect the __setitem__ method to work regardless. This seems wrong to me. > > Just to make things even more difficult, this generally is more likely to > work on my development system (python 2.7.3) then my production systems > (python 2.6.6) - so maybe the later version of Python is better? > > I created the clone method to try and solve this, the challenge is to catch > all instances of code that try to use the copy module. > > Anyway, just curious if anybody here has any thoughts on this issue. > > Thanks > > > class CaseInsensitiveDict(dict): > """ Case insensitve dictionary for searches however preserves the case > for retrieval. """ > > def __init__(self, d={}): > self.lc = {} > for k,v in d.iteritems(): > self.lc[k.lower()] = k > super(CaseInsensitiveDict, self).__init__(d) > > def __setitem__(self, key, value): > try: > old_key = self.lc[key.lower()] > except KeyError: > pass > else: > if key != old_key: > super(CaseInsensitiveDict, self).__delitem__(old_key) > self.lc[key.lower()] = key > super(CaseInsensitiveDict, self).__setitem__(key, value) > > def __delitem__(self, key): > key = self.lc[key.lower()] > del self.lc[key.lower()] > super(CaseInsensitiveDict, self).__delitem__(key) > > def __getitem__(self, key): > key = self.lc[key.lower()] > return super(CaseInsensitiveDict, self).__getitem__(key) > > def __contains__(self, key): > try: > key = self.lc[key.lower()] > except KeyError: > return False > else: > return super(CaseInsensitiveDict, self).__contains__(key) > > def get(self, key, default=None): > try: > key = self.lc[key.lower()] > except KeyError: > return default > else: > return super(CaseInsensitiveDict, self).get(key, default) > > def has_key(self, key): > try: > key = self.lc[key.lower()] > except KeyError: > return False > else: > return super(CaseInsensitiveDict, self).has_key(key) > > def get_correct_key(self, key): > return self.lc[key.lower()] > > def clone(self): > return self.__class__(self) > > > > -- > Brian May <[email protected]> > _______________________________________________ > melbourne-pug mailing list > [email protected] > http://mail.python.org/mailman/listinfo/melbourne-pug _______________________________________________ melbourne-pug mailing list [email protected] http://mail.python.org/mailman/listinfo/melbourne-pug
