mirror of https://github.com/scrapy/scrapy.git
item fields defined on fields class attribute fix
This commit is contained in:
parent
e521740b39
commit
773ea5a5ef
|
|
@ -6,6 +6,7 @@ See documentation in docs/topics/item.rst
|
|||
|
||||
from pprint import pformat
|
||||
from collections import MutableMapping
|
||||
|
||||
from abc import ABCMeta
|
||||
import six
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ class ItemMeta(ABCMeta):
|
|||
new_bases = tuple(base._class for base in bases if hasattr(base, '_class'))
|
||||
_class = super(ItemMeta, mcs).__new__(mcs, 'x_' + class_name, new_bases, attrs)
|
||||
|
||||
fields = {}
|
||||
fields = getattr(_class, 'fields', {})
|
||||
new_attrs = {}
|
||||
for n in dir(_class):
|
||||
v = getattr(_class, n)
|
||||
|
|
|
|||
|
|
@ -120,6 +120,14 @@ class ItemTest(unittest.TestCase):
|
|||
self.assertSortedEqual(list(i.keys()), ['keys', 'values', 'name'])
|
||||
self.assertSortedEqual(list(i.values()), [u'Keys', u'Values', u'John'])
|
||||
|
||||
def test_metaclass_with_fields_attribute(self):
|
||||
class TestItem(Item):
|
||||
fields = {'new': Field(default='X')}
|
||||
|
||||
item = TestItem(new=u'New')
|
||||
self.assertSortedEqual(list(item.keys()), ['new'])
|
||||
self.assertSortedEqual(list(item.values()), [u'New'])
|
||||
|
||||
def test_metaclass_inheritance(self):
|
||||
class BaseItem(Item):
|
||||
name = Field()
|
||||
|
|
@ -136,41 +144,51 @@ class ItemTest(unittest.TestCase):
|
|||
|
||||
def test_metaclass_multiple_inheritance_simple(self):
|
||||
class A(Item):
|
||||
fields = {'load': Field(default='A')}
|
||||
save = Field(default='A')
|
||||
|
||||
class B(A): pass
|
||||
|
||||
class C(Item):
|
||||
fields = {'load': Field(default='C')}
|
||||
save = Field(default='C')
|
||||
|
||||
class D(B, C): pass
|
||||
|
||||
self.assertEqual(D(save='X')['save'], 'X')
|
||||
self.assertEqual(D.fields, {'save': {'default': 'A'}})
|
||||
item = D(save='X', load='Y')
|
||||
self.assertEqual(item['save'], 'X')
|
||||
self.assertEqual(item['load'], 'Y')
|
||||
self.assertEqual(D.fields, {'load': {'default': 'A'},
|
||||
'save': {'default': 'A'}})
|
||||
|
||||
# D class inverted
|
||||
class E(C, B): pass
|
||||
|
||||
self.assertEqual(E(save='X')['save'], 'X')
|
||||
self.assertEqual(E.fields, {'save': {'default': 'C'}})
|
||||
self.assertEqual(E(load='X')['load'], 'X')
|
||||
self.assertEqual(E.fields, {'load': {'default': 'C'},
|
||||
'save': {'default': 'C'}})
|
||||
|
||||
def test_metaclass_multiple_inheritance_diamond(self):
|
||||
class A(Item):
|
||||
fields = {'update': Field(default='A')}
|
||||
save = Field(default='A')
|
||||
load = Field(default='A')
|
||||
|
||||
class B(A): pass
|
||||
|
||||
class C(A):
|
||||
fields = {'update': Field(default='C')}
|
||||
save = Field(default='C')
|
||||
|
||||
class D(B, C):
|
||||
fields = {'update': Field(default='D')}
|
||||
load = Field(default='D')
|
||||
|
||||
self.assertEqual(D(save='X')['save'], 'X')
|
||||
self.assertEqual(D(load='X')['load'], 'X')
|
||||
self.assertEqual(D.fields, {'save': {'default': 'C'},
|
||||
'load': {'default': 'D'}})
|
||||
'load': {'default': 'D'}, 'update': {'default': 'D'}})
|
||||
|
||||
# D class inverted
|
||||
class E(C, B):
|
||||
|
|
@ -179,15 +197,17 @@ class ItemTest(unittest.TestCase):
|
|||
self.assertEqual(E(save='X')['save'], 'X')
|
||||
self.assertEqual(E(load='X')['load'], 'X')
|
||||
self.assertEqual(E.fields, {'save': {'default': 'C'},
|
||||
'load': {'default': 'E'}})
|
||||
'load': {'default': 'E'}, 'update': {'default': 'C'}})
|
||||
|
||||
def test_metaclass_multiple_inheritance_without_metaclass(self):
|
||||
class A(Item):
|
||||
fields = {'load': Field(default='A')}
|
||||
save = Field(default='A')
|
||||
|
||||
class B(A): pass
|
||||
|
||||
class C(object):
|
||||
fields = {'load': Field(default='C')}
|
||||
not_allowed = Field(default='not_allowed')
|
||||
save = Field(default='C')
|
||||
|
||||
|
|
@ -195,14 +215,16 @@ class ItemTest(unittest.TestCase):
|
|||
|
||||
self.assertRaises(KeyError, D, not_allowed='value')
|
||||
self.assertEqual(D(save='X')['save'], 'X')
|
||||
self.assertEqual(D.fields, {'save': {'default': 'A'}})
|
||||
self.assertEqual(D.fields, {'save': {'default': 'A'},
|
||||
'load': {'default': 'A'}})
|
||||
|
||||
# D class inverted
|
||||
class E(C, B): pass
|
||||
|
||||
self.assertRaises(KeyError, E, not_allowed='value')
|
||||
self.assertEqual(E(save='X')['save'], 'X')
|
||||
self.assertEqual(E.fields, {'save': {'default': 'A'}})
|
||||
self.assertEqual(E.fields, {'save': {'default': 'A'},
|
||||
'load': {'default': 'A'}})
|
||||
|
||||
def test_to_dict(self):
|
||||
class TestItem(Item):
|
||||
|
|
|
|||
Loading…
Reference in New Issue