Source code for dhtmlparser.specialdict

#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# Interpreter version: python 2.7
#
# Imports =====================================================================
from collections import OrderedDict


# Functions & objects =========================================================
def _lower_if_str(item):
    """
    Try to convert item to lowercase, if it is string.

    Args:
        item (obj): Str, unicode or any other object.

    Returns:
        obj: ``item.lower()`` if `item` is ``str`` or ``unicode``, else just \
             `item` itself.
    """
    # python 2 / 3 shill
    try:
        string_type = basestring
    except NameError:
        string_type = str

    if isinstance(item, string_type):
        return item.lower()

    return item


[docs]class SpecialDict(OrderedDict): """ This dictionary stores items case sensitive, but compare them case INsensitive. """ def __init__(self, *args, **kwargs): # lower_key -> key mapping self._case = OrderedDict() self._super.__init__(*args, **kwargs) @property def _super(self): return super(SpecialDict, self) def __setitem__(self, key, value): lower_key = _lower_if_str(key) # remove the old key with (possibly) different case if lower_key in self._case: original_key = self._case[lower_key] self._super.__delitem__(original_key) self._case[lower_key] = key self._super.__setitem__(key, value) def __getitem__(self, key): lower_key = _lower_if_str(key) if lower_key not in self._case: raise KeyError(repr(key)) return self._super.__getitem__(self._case[lower_key]) def __delitem__(self, key): lower_key = _lower_if_str(key) key = self._case[lower_key] del self._case[lower_key] return self._super.__delitem__(key)
[docs] def clear(self): self._case.clear() return self._super.clear()
[docs] def get(self, k, d=None): lower_key = _lower_if_str(k) if lower_key not in self._case: return d return self._super.get(self._case[lower_key], d)
def __contains__(self, key): lower_key = _lower_if_str(key) right_key = self._case.get(lower_key, None) return right_key and right_key in set(self.keys())
[docs] def has_key(self, key): return key in self
def __eq__(self, obj): if self is obj: return True if not hasattr(obj, "__getitem__"): return False keys = None if hasattr(obj, "keys"): keys = obj.keys() elif hasattr(obj, "iterkeys"): keys = list(obj.keys()) else: keys = list(obj) if len(self.keys()) != len(keys): return False for key in keys: if not self.__contains__(key): return False if obj[key] != self.__getitem__(key): return False return True def __ne__(self, obj): return not self.__eq__(obj) # python 2 / 3 compatibility def _is_py2(self): return hasattr(self._super, "iteritems")
[docs] def iteritems(self, *args, **kwargs): if self._is_py2(): return self._super.iteritems(*args, **kwargs) return self.items()
[docs] def iterkeys(self, *args, **kwargs): if self._is_py2(): return self._super.iterkeys(*args, **kwargs) return self.keys()
[docs] def itervalues(self, *args, **kwargs): if self._is_py2(): return self._super.itervalues(*args, **kwargs) return self.values()
[docs] def keys(self, *args, **kwargs): if not self._is_py2(): return list(self._super.keys(*args, **kwargs)) return self._super.keys(*args, **kwargs)
[docs] def items(self, *args, **kwargs): if not self._is_py2(): return list(self._super.items(*args, **kwargs)) return self._super.items(*args, **kwargs)
[docs] def values(self, *args, **kwargs): if not self._is_py2(): return list(self._super.values(*args, **kwargs)) return self._super.values(*args, **kwargs)