From f4b55bfd203b22db2f101f804ddfbdb015ad90e4 Mon Sep 17 00:00:00 2001 From: Daniel Grana Date: Tue, 24 Feb 2009 06:57:28 +0000 Subject: [PATCH] datatypes: add CaselessDict test and cleanup --HG-- extra : convert_revision : svn%3Ab85faa78-f9eb-468e-a121-7cced6da292c%40911 --- scrapy/trunk/scrapy/tests/test_datatypes.py | 83 +++++++++++++++++++++ scrapy/trunk/scrapy/utils/datatypes.py | 35 ++++----- 2 files changed, 96 insertions(+), 22 deletions(-) create mode 100644 scrapy/trunk/scrapy/tests/test_datatypes.py diff --git a/scrapy/trunk/scrapy/tests/test_datatypes.py b/scrapy/trunk/scrapy/tests/test_datatypes.py new file mode 100644 index 000000000..a99c564a6 --- /dev/null +++ b/scrapy/trunk/scrapy/tests/test_datatypes.py @@ -0,0 +1,83 @@ +import unittest + +from scrapy.utils.datatypes import CaselessDict + + +class CaselessDictTest(unittest.TestCase): + + def test_init(self): + seq = {'red': 1, 'black': 3} + d = CaselessDict(seq) + self.assertEqual(d['red'], 1) + self.assertEqual(d['black'], 3) + + seq = (('red', 1), ('black', 3)) + d = CaselessDict(seq) + self.assertEqual(d['red'], 1) + self.assertEqual(d['black'], 3) + + def test_caseless(self): + d = CaselessDict() + d['key_Lower'] = 1 + self.assertEqual(d['KEy_loWer'], 1) + self.assertEqual(d.get('KEy_loWer'), 1) + + d['KEY_LOWER'] = 3 + self.assertEqual(d['key_Lower'], 3) + self.assertEqual(d.get('key_Lower'), 3) + + def test_delete(self): + d = CaselessDict({'key_lower': 1}) + del d['key_LOWER'] + self.assertRaises(KeyError, d.__getitem__, 'key_LOWER') + self.assertRaises(KeyError, d.__getitem__, 'key_lower') + + def test_getdefault(self): + d = CaselessDict() + self.assertEqual(d.get('c', 5), 5) + d['c'] = 10 + self.assertEqual(d.get('c', 5), 10) + + def test_setdefault(self): + d = CaselessDict({'a': 1, 'b': 2}) + + r = d.setdefault('A', 5) + self.assertEqual(r, 1) + self.assertEqual(d['A'], 1) + + r = d.setdefault('c', 5) + self.assertEqual(r, 5) + self.assertEqual(d['C'], 5) + + def test_fromkeys(self): + keys = ('a', 'b') + + d = CaselessDict.fromkeys(keys) + self.assertEqual(d['A'], None) + self.assertEqual(d['B'], None) + + d = CaselessDict.fromkeys(keys, 1) + self.assertEqual(d['A'], 1) + self.assertEqual(d['B'], 1) + + instance = CaselessDict() + d = instance.fromkeys(keys) + self.assertEqual(d['A'], None) + self.assertEqual(d['B'], None) + + d = instance.fromkeys(keys, 1) + self.assertEqual(d['A'], 1) + self.assertEqual(d['B'], 1) + + def test_contains(self): + d = CaselessDict() + d['a'] = 1 + assert 'a' in d + assert d.has_key('a') + + def test_pop(self): + d = CaselessDict() + d['a'] = 1 + self.assertEqual(d.pop('A'), 1) + self.assertRaises(KeyError, d.pop, 'A') + diff --git a/scrapy/trunk/scrapy/utils/datatypes.py b/scrapy/trunk/scrapy/utils/datatypes.py index 6e2d38a34..3eae2d3dd 100644 --- a/scrapy/trunk/scrapy/utils/datatypes.py +++ b/scrapy/trunk/scrapy/utils/datatypes.py @@ -184,15 +184,10 @@ class SiteNode(object): return s class CaselessDict(dict): - def __init__(self, other=None): - if other: - # Doesn't do keyword args - if isinstance(other, dict): - for k, v in other.items(): - dict.__setitem__(self, self.normkey(k), v) - else: - for k, v in other: - dict.__setitem__(self, self.normkey(k), v) + def __init__(self, seq=None): + dict.__init__(self) + if seq: + self.update(seq) def __getitem__(self, key): return dict.__getitem__(self, self.normkey(key)) @@ -205,31 +200,27 @@ class CaselessDict(dict): def __contains__(self, key): return dict.__contains__(self, self.normkey(key)) + has_key = __contains__ def normkey(self, key): return key.lower() - def has_key(self, key): - return dict.has_key(self, self.normkey(key)) - def get(self, key, def_val=None): return dict.get(self, self.normkey(key), def_val) def setdefault(self, key, def_val=None): return dict.setdefault(self, self.normkey(key), def_val) - def update(self, other): - for k, v in other.items(): - dict.__setitem__(self, self.normkey(k), v) + def update(self, seq): + items = seq.iteritems() if isinstance(seq, dict) else seq + dict.update(self, ((self.normkey(k), v) for k, v in items)) - def fromkeys(self, iterable, value=None): - d = CaselessDict() - for k in iterable: - dict.__setitem__(d, self.normkey(k), value) - return d + @classmethod + def fromkeys(cls, keys, value=None): + return cls((k, value) for k in keys) - def pop(self, key, def_val=None): - return dict.pop(self, self.normkey(key), def_val) + def pop(self, key, *args): + return dict.pop(self, self.normkey(key), *args) class PriorityQueue(object): """A simple priority queue"""