Skip to content

add the default parameter to get_output_value #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions itemloaders/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ def load_item(self):

return adapter.item

def get_output_value(self, field_name):
def get_output_value(self, field_name, default=None):
"""
Return the collected values parsed using the output processor, for the
given field. This method doesn't populate or modify the item at all.
Expand All @@ -275,10 +275,13 @@ def get_output_value(self, field_name):
proc = wrap_loader_context(proc, self.context)
value = self._values.get(field_name, [])
try:
return proc(value)
result = proc(value)
except Exception as e:
raise ValueError("Error with output processor: field=%r value=%r error='%s: %s'" %
(field_name, value, type(e).__name__, str(e)))
if not result and default is not None:
return default
return result

def get_collected_values(self, field_name):
"""Return the collected values for the given field."""
Expand Down
2 changes: 1 addition & 1 deletion tests/test_base_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class MyLoader(ItemLoader):
url_out = TakeFirst()

def img_url_out(self, values):
return (self.get_output_value('url') or '') + values[0]
return self.get_output_value('url', '') + values[0]

il = MyLoader(item={})
il.add_value('url', 'http://example.com/')
Expand Down
50 changes: 50 additions & 0 deletions tests/test_loader_initialization.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import unittest

from itemloaders import ItemLoader
from itemloaders.processors import TakeFirst


class InitializationTestMixin:
Expand Down Expand Up @@ -77,6 +78,55 @@ def test_get_output_value_list(self):
self.assertIsInstance(loaded_item, self.item_class)
self.assertEqual(loaded_item, dict({'name': ['foo', 'bar']}))

def test_get_output_value_default_singlevalue(self):
"""
The default value should be used only when the returned value is
empty (None, '', etc.) and there is a default value defined
"""
input_item = self.item_class()
il = ItemLoader(item=input_item)
il.default_output_processor = TakeFirst() # make "name" field single

self.assertEqual(il.get_output_value('name'), None)
self.assertEqual(il.get_output_value('name', ''), '')
self.assertEqual(il.get_output_value('name', []), [])
self.assertEqual(il.get_output_value('name', 'foo'), 'foo')

il.add_value('name', '')
self.assertEqual(il.get_output_value('name'), None)
self.assertEqual(il.get_output_value('name', ''), '')
self.assertEqual(il.get_output_value('name', []), [])
self.assertEqual(il.get_output_value('name', 'foo'), 'foo')
self.assertEqual(il.load_item(), {})

input_item2 = self.item_class()
il2 = ItemLoader(item=input_item2)
il2.default_output_processor = TakeFirst()
il2.add_value('name', 'foo')
self.assertEqual(il2.get_output_value('name'), 'foo')
self.assertEqual(il2.get_output_value('name', 'bar'), 'foo')
self.assertEqual(il2.load_item(), dict({'name': 'foo'}))

def test_get_output_value_default_list(self):
"""
The default value should be used only when the returned value is
empty ([], etc.) and there is a default value defined
"""
input_item = self.item_class()
il = ItemLoader(item=input_item)
il.add_value('name', [])
self.assertEqual(il.get_output_value('name'), [])
self.assertEqual(il.get_output_value('name', ['foo']), ['foo'])
self.assertEqual(il.get_output_value('name', 'foo'), 'foo')
self.assertEqual(il.load_item(), {})

input_item2 = self.item_class()
il2 = ItemLoader(item=input_item2)
il2.add_value('name', ['foo', 'bar'])
self.assertEqual(il2.get_output_value('name'), ['foo', 'bar'])
self.assertEqual(il2.get_output_value('name', ['spam']), ['foo', 'bar'])
self.assertEqual(il2.load_item(), dict({'name': ['foo', 'bar']}))

def test_values_single(self):
"""Values from initial item must be added to loader._values"""
input_item = self.item_class(name='foo')
Expand Down