diff --git a/docs/topics/feed-exports.rst b/docs/topics/feed-exports.rst index f4fb07761..d9444e34a 100644 --- a/docs/topics/feed-exports.rst +++ b/docs/topics/feed-exports.rst @@ -243,13 +243,13 @@ Example: ``FEED_EXPORT_FIELDS = ["foo", "bar", "baz"]``. Use FEED_EXPORT_FIELDS option to define fields to export and their order. -When FEED_EXPORT_FIELDS is None (default), Scrapy uses fields -defined in :class:`~.Item` subclasses a spider is yielding. -If FEED_EXPORT_FIELDS is None, raw dicts are used as items and -an exporter requires a fixed set of fields (this is the case for -:ref:`CSV ` export format), then -Scrapy tries to infer field names from the exported data - currently it -uses field names from the first item. +When FEED_EXPORT_FIELDS is empty or None (default), Scrapy uses fields +defined in dicts or :class:`~.Item` subclasses a spider is yielding. + +If an exporter requires a fixed set of fields (this is the case for +:ref:`CSV ` export format) and FEED_EXPORT_FIELDS +is empty or None, then Scrapy tries to infer field names from the +exported data - currently it uses field names from the first item. .. setting:: FEED_STORE_EMPTY diff --git a/scrapy/extensions/feedexport.py b/scrapy/extensions/feedexport.py index 08e868c9f..7a1a02be1 100644 --- a/scrapy/extensions/feedexport.py +++ b/scrapy/extensions/feedexport.py @@ -151,12 +151,7 @@ class FeedExporter(object): if not self._exporter_supported(self.format): raise NotConfigured self.store_empty = settings.getbool('FEED_STORE_EMPTY') - - if settings.get('FEED_EXPORT_FIELDS') is None: - self.export_fields = None # don't promote None to [] - else: - self.export_fields = settings.getlist('FEED_EXPORT_FIELDS') - + self.export_fields = settings.getlist('FEED_EXPORT_FIELDS') or None uripar = settings['FEED_URI_PARAMS'] self._uripar = load_object(uripar) if uripar else lambda x, y: None diff --git a/tests/test_feedexport.py b/tests/test_feedexport.py index c3d8b64ef..d6c96ca74 100644 --- a/tests/test_feedexport.py +++ b/tests/test_feedexport.py @@ -234,7 +234,12 @@ class FeedExportTest(unittest.TestCase): yield self.assertExportedCsv(items, header, rows_csv, ordered=False) yield self.assertExportedJsonLines(items, rows_jl) - # but it is possible to override fields using FEED_EXPORT_FIELDS + # edge case: FEED_EXPORT_FIELDS==[] means the same as default None + settings = {'FEED_EXPORT_FIELDS': []} + yield self.assertExportedCsv(items, header, rows_csv, ordered=False) + yield self.assertExportedJsonLines(items, rows_jl, settings) + + # it is possible to override fields using FEED_EXPORT_FIELDS header = ["foo", "baz", "hello"] settings = {'FEED_EXPORT_FIELDS': header} rows = [ @@ -246,10 +251,6 @@ class FeedExportTest(unittest.TestCase): yield self.assertExported(items, header, rows, settings=settings, ordered=True) - # edge case: FEED_EXPORT_FIELDS==[] means nothing is exported - settings = {'FEED_EXPORT_FIELDS': []} - yield self.assertExportedJsonLines(items, [{},{},{},{}], settings) - @defer.inlineCallbacks def test_export_dicts(self): # When dicts are used, only keys from the first row are used as