PY3: use MutableMapping instead of DictMixin

This commit is contained in:
Felix Yan 2014-07-25 00:32:52 +08:00
parent 1cd9c4d653
commit dbc9b37365
2 changed files with 33 additions and 14 deletions

View File

@ -5,7 +5,8 @@ See documentation in docs/topics/item.rst
"""
from pprint import pformat
from UserDict import DictMixin
from collections import MutableMapping
from abc import ABCMeta
import six
from scrapy.utils.trackref import object_ref
@ -20,7 +21,7 @@ class Field(dict):
"""Container of field metadata"""
class ItemMeta(type):
class ItemMeta(ABCMeta):
def __new__(mcs, class_name, bases, attrs):
fields = {}
@ -37,7 +38,7 @@ class ItemMeta(type):
return cls
class DictItem(DictMixin, BaseItem):
class DictItem(MutableMapping, BaseItem):
fields = {}
@ -71,6 +72,19 @@ class DictItem(DictMixin, BaseItem):
(name, value))
super(DictItem, self).__setattr__(name, value)
def __len__(self):
return len(self._values)
def __iter__(self):
for i in getattr(self, "_values", ()):
yield i
def __hash__(self):
if hasattr(self, "_values"):
return hash(frozenset(self._values.items()))
else:
return 1
def keys(self):
return self._values.keys()
@ -81,6 +95,5 @@ class DictItem(DictMixin, BaseItem):
return self.__class__(self)
class Item(DictItem):
__metaclass__ = ItemMeta
class Item(six.with_metaclass(ItemMeta, DictItem)):
pass

View File

@ -1,6 +1,7 @@
import unittest
from scrapy.item import Item, Field
import six
class ItemTest(unittest.TestCase):
@ -52,8 +53,13 @@ class ItemTest(unittest.TestCase):
i['name'] = u'John Doe'
i['number'] = 123
itemrepr = repr(i)
self.assertEqual(itemrepr,
"{'name': u'John Doe', 'number': 123}")
if six.PY2:
self.assertEqual(itemrepr,
"{'name': u'John Doe', 'number': 123}")
else:
self.assertEqual(itemrepr,
"{'name': 'John Doe', 'number': 123}")
i2 = eval(itemrepr)
self.assertEqual(i2['name'], 'John Doe')
@ -106,13 +112,13 @@ class ItemTest(unittest.TestCase):
i = TestItem()
i['name'] = u'John'
self.assertEqual(i.keys(), ['name'])
self.assertEqual(i.values(), ['John'])
self.assertEqual(list(i.keys()), ['name'])
self.assertEqual(list(i.values()), ['John'])
i['keys'] = u'Keys'
i['values'] = u'Values'
self.assertSortedEqual(i.keys(), ['keys', 'values', 'name'])
self.assertSortedEqual(i.values(), [u'Keys', u'Values', u'John'])
self.assertSortedEqual(list(i.keys()), ['keys', 'values', 'name'])
self.assertSortedEqual(list(i.values()), [u'Keys', u'Values', u'John'])
def test_metaclass_inheritance(self):
class BaseItem(Item):
@ -125,8 +131,8 @@ class ItemTest(unittest.TestCase):
i = TestItem()
i['keys'] = 3
self.assertEqual(i.keys(), ['keys'])
self.assertEqual(i.values(), [3])
self.assertEqual(list(i.keys()), ['keys'])
self.assertEqual(list(i.values()), [3])
def test_to_dict(self):
class TestItem(Item):