mirror of https://github.com/scrapy/scrapy.git
PY3: use MutableMapping instead of DictMixin
This commit is contained in:
parent
1cd9c4d653
commit
dbc9b37365
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Reference in New Issue