From a88119aa8b841cf59010e8ad64ff58fff13bc350 Mon Sep 17 00:00:00 2001 From: Daniel Grana Date: Fri, 27 Feb 2009 18:44:40 +0000 Subject: [PATCH] newitem: redefine adaptor fields as staticmethods --HG-- extra : convert_revision : svn%3Ab85faa78-f9eb-468e-a121-7cced6da292c%40933 --- .../scrapy/contrib_exp/newitem/adaptors.py | 31 ++++++++++++------- scrapy/trunk/scrapy/tests/test_itemadaptor.py | 22 ++++++------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/scrapy/trunk/scrapy/contrib_exp/newitem/adaptors.py b/scrapy/trunk/scrapy/contrib_exp/newitem/adaptors.py index 07c1cda50..c79ea0e04 100644 --- a/scrapy/trunk/scrapy/contrib_exp/newitem/adaptors.py +++ b/scrapy/trunk/scrapy/contrib_exp/newitem/adaptors.py @@ -1,24 +1,33 @@ -from functools import wraps from scrapy.utils.python import get_func_args +def is_adaptor(func): + return callable(func) and 'adaptor_args' in get_func_args(func) + +class ItemAdaptorMetaClass(type): + def __new__(meta, name, bases, dct): + # defines adaptor fields as static methods + for key, func in dct.items(): + if not key.startswith('_') and is_adaptor(func): + dct[key] = staticmethod(func) + return type.__new__(meta, name, bases, dct) + class ItemAdaptor(object): - def __init__(self, response=None, item=None): - if item: - self.item_instance = item - else: - self.item_instance = self.item_class() + __metaclass__ = ItemAdaptorMetaClass + def __init__(self, response=None, item=None): + self.item_instance = item if item else self.item_class() self._response = response self._field_adaptors = self._get_field_adaptors() def _get_field_adaptors(self): def get_field_adaptor(field, cls): - if field in cls.__dict__: - return cls.__dict__[field] - else: - for class_ in cls.__bases__: - return get_field_adaptor(field, class_) + func = getattr(cls, field, None) + if func: + return func + + for class_ in cls.__bases__: + return get_field_adaptor(field, class_) fa = {} for field in self.item_instance._fields.keys(): diff --git a/scrapy/trunk/scrapy/tests/test_itemadaptor.py b/scrapy/trunk/scrapy/tests/test_itemadaptor.py index 5bc5fb4f2..5a86094bb 100644 --- a/scrapy/trunk/scrapy/tests/test_itemadaptor.py +++ b/scrapy/trunk/scrapy/tests/test_itemadaptor.py @@ -1,5 +1,6 @@ import unittest +import string from scrapy.contrib_exp.newitem.adaptors import adaptor, ItemAdaptor from scrapy.contrib_exp.newitem import Item, StringField @@ -53,17 +54,16 @@ class ItemAdaptorTest(unittest.TestCase): ia.name = 'marta' self.assertEqual(ia.name, 'Marta') - # FIXME: This test is fine but fails -# def test_inheritance_2(self): -# class ParentAdaptor(TestAdaptor): -# name = adaptor(lambda v, adaptor_args: v) -# -# class ChildAdaptor(ParentAdaptor): -# name = adaptor(lambda v: v.swapcase, ParentAdaptor.name) -# -# ia = ChildAdaptor() -# ia.name = 'marta' -# self.assertEqual(ia.name, 'mARTA') + def test_staticmethods(self): + class ParentAdaptor(TestAdaptor): + name = adaptor(lambda v, adaptor_args: v) + + class ChildAdaptor(ParentAdaptor): + name = adaptor(ParentAdaptor.name, string.swapcase) + + ia = ChildAdaptor() + ia.name = 'Marta' + self.assertEqual(ia.name, 'mARTA')