diff --git a/scrapy/contrib_exp/newitem/models.py b/scrapy/contrib_exp/newitem/models.py index b84de9b1a..867894612 100644 --- a/scrapy/contrib_exp/newitem/models.py +++ b/scrapy/contrib_exp/newitem/models.py @@ -10,6 +10,7 @@ class _ItemMeta(type): for n, v in attrs.iteritems(): if isinstance(v, BaseField): cls.fields[n] = v + delattr(cls, n) return cls @@ -38,17 +39,14 @@ class Item(ScrapedItem): else: raise AttributeError(name) - def __getattribute__(self, name): - if name.startswith('_') or name == 'fields': - return ScrapedItem.__getattribute__(self, name) - - if name in self.fields.keys(): + def __getattr__(self, name): + try: + return self._values[name] + except KeyError: try: - return self._values[name] - except KeyError: return self.fields[name].default - else: - raise AttributeError(name) + except KeyError: + raise AttributeError(name) def __repr__(self): """Generate a representation of this item that can be used to diff --git a/scrapy/tests/test_newitem.py b/scrapy/tests/test_newitem.py index 6a15f39f2..48e3254e1 100644 --- a/scrapy/tests/test_newitem.py +++ b/scrapy/tests/test_newitem.py @@ -85,6 +85,31 @@ class NewItemTest(unittest.TestCase): assert i2.name == 'John Doe' assert i2.number == 123 + def test_private_attr(self): + class TestItem(Item): + name = fields.StringField() + + i = TestItem() + i._private = 'test' + self.assertEqual(i._private, 'test') + + def test_custom_methods(self): + class TestItem(Item): + name = fields.StringField() + + def get_name(self): + return self.name + + def change_name(self, name): + self.name = name + + i = TestItem() + self.assertEqual(i.get_name(), None) + i.name = 'lala' + self.assertEqual(i.get_name(), 'lala') + i.change_name('other') + self.assertEqual(i.get_name(), 'other') + class NewItemFieldsTest(unittest.TestCase):