We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Line-ends (unnecessary blank lines) problem in CSV export on Windows 
CSV export on Windows create unnecessary blank lines after each line.

You can fix the problem just by adding 
newline='' 
as parameter to io.TextIOWrapper in the __init__ method of the CsvItemExporter class in scrapy.exporters

Details are over here:
https://stackoverflow.com/questions/39477662/scrapy-csv-file-has-uniform-empty-rows/43394566#43394566

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scrapy/exporters.py`
Content:
```
1 """
2 Item Exporters are used to export/serialize items into different formats.
3 """
4 
5 import csv
6 import io
7 import sys
8 import pprint
9 import marshal
10 import six
11 from six.moves import cPickle as pickle
12 from xml.sax.saxutils import XMLGenerator
13 
14 from scrapy.utils.serialize import ScrapyJSONEncoder
15 from scrapy.utils.python import to_bytes, to_unicode, to_native_str, is_listlike
16 from scrapy.item import BaseItem
17 from scrapy.exceptions import ScrapyDeprecationWarning
18 import warnings
19 
20 
21 __all__ = ['BaseItemExporter', 'PprintItemExporter', 'PickleItemExporter',
22            'CsvItemExporter', 'XmlItemExporter', 'JsonLinesItemExporter',
23            'JsonItemExporter', 'MarshalItemExporter']
24 
25 
26 class BaseItemExporter(object):
27 
28     def __init__(self, **kwargs):
29         self._configure(kwargs)
30 
31     def _configure(self, options, dont_fail=False):
32         """Configure the exporter by poping options from the ``options`` dict.
33         If dont_fail is set, it won't raise an exception on unexpected options
34         (useful for using with keyword arguments in subclasses constructors)
35         """
36         self.encoding = options.pop('encoding', None)
37         self.fields_to_export = options.pop('fields_to_export', None)
38         self.export_empty_fields = options.pop('export_empty_fields', False)
39         self.indent = options.pop('indent', None)
40         if not dont_fail and options:
41             raise TypeError("Unexpected options: %s" % ', '.join(options.keys()))
42 
43     def export_item(self, item):
44         raise NotImplementedError
45 
46     def serialize_field(self, field, name, value):
47         serializer = field.get('serializer', lambda x: x)
48         return serializer(value)
49 
50     def start_exporting(self):
51         pass
52 
53     def finish_exporting(self):
54         pass
55 
56     def _get_serialized_fields(self, item, default_value=None, include_empty=None):
57         """Return the fields to export as an iterable of tuples
58         (name, serialized_value)
59         """
60         if include_empty is None:
61             include_empty = self.export_empty_fields
62         if self.fields_to_export is None:
63             if include_empty and not isinstance(item, dict):
64                 field_iter = six.iterkeys(item.fields)
65             else:
66                 field_iter = six.iterkeys(item)
67         else:
68             if include_empty:
69                 field_iter = self.fields_to_export
70             else:
71                 field_iter = (x for x in self.fields_to_export if x in item)
72 
73         for field_name in field_iter:
74             if field_name in item:
75                 field = {} if isinstance(item, dict) else item.fields[field_name]
76                 value = self.serialize_field(field, field_name, item[field_name])
77             else:
78                 value = default_value
79 
80             yield field_name, value
81 
82 
83 class JsonLinesItemExporter(BaseItemExporter):
84 
85     def __init__(self, file, **kwargs):
86         self._configure(kwargs, dont_fail=True)
87         self.file = file
88         kwargs.setdefault('ensure_ascii', not self.encoding)
89         self.encoder = ScrapyJSONEncoder(**kwargs)
90 
91     def export_item(self, item):
92         itemdict = dict(self._get_serialized_fields(item))
93         data = self.encoder.encode(itemdict) + '\n'
94         self.file.write(to_bytes(data, self.encoding))
95 
96 
97 class JsonItemExporter(BaseItemExporter):
98 
99     def __init__(self, file, **kwargs):
100         self._configure(kwargs, dont_fail=True)
101         self.file = file
102         # there is a small difference between the behaviour or JsonItemExporter.indent
103         # and ScrapyJSONEncoder.indent. ScrapyJSONEncoder.indent=None is needed to prevent
104         # the addition of newlines everywhere
105         json_indent = self.indent if self.indent is not None and self.indent > 0 else None
106         kwargs.setdefault('indent', json_indent)
107         kwargs.setdefault('ensure_ascii', not self.encoding)
108         self.encoder = ScrapyJSONEncoder(**kwargs)
109         self.first_item = True
110 
111     def _beautify_newline(self):
112         if self.indent is not None:
113             self.file.write(b'\n')
114 
115     def start_exporting(self):
116         self.file.write(b"[")
117         self._beautify_newline()
118 
119     def finish_exporting(self):
120         self._beautify_newline()
121         self.file.write(b"]")
122 
123     def export_item(self, item):
124         if self.first_item:
125             self.first_item = False
126         else:
127             self.file.write(b',')
128             self._beautify_newline()
129         itemdict = dict(self._get_serialized_fields(item))
130         data = self.encoder.encode(itemdict)
131         self.file.write(to_bytes(data, self.encoding))
132 
133 
134 class XmlItemExporter(BaseItemExporter):
135 
136     def __init__(self, file, **kwargs):
137         self.item_element = kwargs.pop('item_element', 'item')
138         self.root_element = kwargs.pop('root_element', 'items')
139         self._configure(kwargs)
140         if not self.encoding:
141             self.encoding = 'utf-8'
142         self.xg = XMLGenerator(file, encoding=self.encoding)
143 
144     def _beautify_newline(self, new_item=False):
145         if self.indent is not None and (self.indent > 0 or new_item):
146             self._xg_characters('\n')
147 
148     def _beautify_indent(self, depth=1):
149         if self.indent:
150             self._xg_characters(' ' * self.indent * depth)
151 
152     def start_exporting(self):
153         self.xg.startDocument()
154         self.xg.startElement(self.root_element, {})
155         self._beautify_newline(new_item=True)
156 
157     def export_item(self, item):
158         self._beautify_indent(depth=1)
159         self.xg.startElement(self.item_element, {})
160         self._beautify_newline()
161         for name, value in self._get_serialized_fields(item, default_value=''):
162             self._export_xml_field(name, value, depth=2)
163         self._beautify_indent(depth=1)
164         self.xg.endElement(self.item_element)
165         self._beautify_newline(new_item=True)
166 
167     def finish_exporting(self):
168         self.xg.endElement(self.root_element)
169         self.xg.endDocument()
170 
171     def _export_xml_field(self, name, serialized_value, depth):
172         self._beautify_indent(depth=depth)
173         self.xg.startElement(name, {})
174         if hasattr(serialized_value, 'items'):
175             self._beautify_newline()
176             for subname, value in serialized_value.items():
177                 self._export_xml_field(subname, value, depth=depth+1)
178             self._beautify_indent(depth=depth)
179         elif is_listlike(serialized_value):
180             self._beautify_newline()
181             for value in serialized_value:
182                 self._export_xml_field('value', value, depth=depth+1)
183             self._beautify_indent(depth=depth)
184         elif isinstance(serialized_value, six.text_type):
185             self._xg_characters(serialized_value)
186         else:
187             self._xg_characters(str(serialized_value))
188         self.xg.endElement(name)
189         self._beautify_newline()
190 
191     # Workaround for https://bugs.python.org/issue17606
192     # Before Python 2.7.4 xml.sax.saxutils required bytes;
193     # since 2.7.4 it requires unicode. The bug is likely to be
194     # fixed in 2.7.6, but 2.7.6 will still support unicode,
195     # and Python 3.x will require unicode, so ">= 2.7.4" should be fine.
196     if sys.version_info[:3] >= (2, 7, 4):
197         def _xg_characters(self, serialized_value):
198             if not isinstance(serialized_value, six.text_type):
199                 serialized_value = serialized_value.decode(self.encoding)
200             return self.xg.characters(serialized_value)
201     else:  # pragma: no cover
202         def _xg_characters(self, serialized_value):
203             return self.xg.characters(serialized_value)
204 
205 
206 class CsvItemExporter(BaseItemExporter):
207 
208     def __init__(self, file, include_headers_line=True, join_multivalued=',', **kwargs):
209         self._configure(kwargs, dont_fail=True)
210         if not self.encoding:
211             self.encoding = 'utf-8'
212         self.include_headers_line = include_headers_line
213         self.stream = io.TextIOWrapper(
214             file,
215             line_buffering=False,
216             write_through=True,
217             encoding=self.encoding
218         ) if six.PY3 else file
219         self.csv_writer = csv.writer(self.stream, **kwargs)
220         self._headers_not_written = True
221         self._join_multivalued = join_multivalued
222 
223     def serialize_field(self, field, name, value):
224         serializer = field.get('serializer', self._join_if_needed)
225         return serializer(value)
226 
227     def _join_if_needed(self, value):
228         if isinstance(value, (list, tuple)):
229             try:
230                 return self._join_multivalued.join(value)
231             except TypeError:  # list in value may not contain strings
232                 pass
233         return value
234 
235     def export_item(self, item):
236         if self._headers_not_written:
237             self._headers_not_written = False
238             self._write_headers_and_set_fields_to_export(item)
239 
240         fields = self._get_serialized_fields(item, default_value='',
241                                              include_empty=True)
242         values = list(self._build_row(x for _, x in fields))
243         self.csv_writer.writerow(values)
244 
245     def _build_row(self, values):
246         for s in values:
247             try:
248                 yield to_native_str(s, self.encoding)
249             except TypeError:
250                 yield s
251 
252     def _write_headers_and_set_fields_to_export(self, item):
253         if self.include_headers_line:
254             if not self.fields_to_export:
255                 if isinstance(item, dict):
256                     # for dicts try using fields of the first item
257                     self.fields_to_export = list(item.keys())
258                 else:
259                     # use fields declared in Item
260                     self.fields_to_export = list(item.fields.keys())
261             row = list(self._build_row(self.fields_to_export))
262             self.csv_writer.writerow(row)
263 
264 
265 class PickleItemExporter(BaseItemExporter):
266 
267     def __init__(self, file, protocol=2, **kwargs):
268         self._configure(kwargs)
269         self.file = file
270         self.protocol = protocol
271 
272     def export_item(self, item):
273         d = dict(self._get_serialized_fields(item))
274         pickle.dump(d, self.file, self.protocol)
275 
276 
277 class MarshalItemExporter(BaseItemExporter):
278 
279     def __init__(self, file, **kwargs):
280         self._configure(kwargs)
281         self.file = file
282 
283     def export_item(self, item):
284         marshal.dump(dict(self._get_serialized_fields(item)), self.file)
285 
286 
287 class PprintItemExporter(BaseItemExporter):
288 
289     def __init__(self, file, **kwargs):
290         self._configure(kwargs)
291         self.file = file
292 
293     def export_item(self, item):
294         itemdict = dict(self._get_serialized_fields(item))
295         self.file.write(to_bytes(pprint.pformat(itemdict) + '\n'))
296 
297 
298 class PythonItemExporter(BaseItemExporter):
299     """The idea behind this exporter is to have a mechanism to serialize items
300     to built-in python types so any serialization library (like
301     json, msgpack, binc, etc) can be used on top of it. Its main goal is to
302     seamless support what BaseItemExporter does plus nested items.
303     """
304     def _configure(self, options, dont_fail=False):
305         self.binary = options.pop('binary', True)
306         super(PythonItemExporter, self)._configure(options, dont_fail)
307         if self.binary:
308             warnings.warn(
309                 "PythonItemExporter will drop support for binary export in the future",
310                 ScrapyDeprecationWarning)
311         if not self.encoding:
312             self.encoding = 'utf-8'
313 
314     def serialize_field(self, field, name, value):
315         serializer = field.get('serializer', self._serialize_value)
316         return serializer(value)
317 
318     def _serialize_value(self, value):
319         if isinstance(value, BaseItem):
320             return self.export_item(value)
321         if isinstance(value, dict):
322             return dict(self._serialize_dict(value))
323         if is_listlike(value):
324             return [self._serialize_value(v) for v in value]
325         encode_func = to_bytes if self.binary else to_unicode
326         if isinstance(value, (six.text_type, bytes)):
327             return encode_func(value, encoding=self.encoding)
328         return value
329 
330     def _serialize_dict(self, value):
331         for key, val in six.iteritems(value):
332             key = to_bytes(key) if self.binary else key
333             yield key, self._serialize_value(val)
334 
335     def export_item(self, item):
336         result = dict(self._get_serialized_fields(item))
337         if self.binary:
338             result = dict(self._serialize_dict(result))
339         return result
340
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/scrapy/exporters.py b/scrapy/exporters.py
--- a/scrapy/exporters.py
+++ b/scrapy/exporters.py
@@ -214,7 +214,8 @@
             file,
             line_buffering=False,
             write_through=True,
-            encoding=self.encoding
+            encoding=self.encoding,
+            newline='' # Windows needs this https://github.com/scrapy/scrapy/issues/3034
         ) if six.PY3 else file
         self.csv_writer = csv.writer(self.stream, **kwargs)
         self._headers_not_written = True

{"golden_diff": "diff --git a/scrapy/exporters.py b/scrapy/exporters.py\n--- a/scrapy/exporters.py\n+++ b/scrapy/exporters.py\n@@ -214,7 +214,8 @@\n             file,\n             line_buffering=False,\n             write_through=True,\n-            encoding=self.encoding\n+            encoding=self.encoding,\n+            newline='' # Windows needs this https://github.com/scrapy/scrapy/issues/3034\n         ) if six.PY3 else file\n         self.csv_writer = csv.writer(self.stream, **kwargs)\n         self._headers_not_written = True\n", "issue": "Line-ends (unnecessary blank lines) problem in CSV export on Windows \nCSV export on Windows create unnecessary blank lines after each line.\r\n\r\nYou can fix the problem just by adding \r\nnewline='' \r\nas parameter to io.TextIOWrapper in the __init__ method of the CsvItemExporter class in scrapy.exporters\r\n\r\nDetails are over here:\r\nhttps://stackoverflow.com/questions/39477662/scrapy-csv-file-has-uniform-empty-rows/43394566#43394566\n", "before_files": [{"content": "\"\"\"\nItem Exporters are used to export/serialize items into different formats.\n\"\"\"\n\nimport csv\nimport io\nimport sys\nimport pprint\nimport marshal\nimport six\nfrom six.moves import cPickle as pickle\nfrom xml.sax.saxutils import XMLGenerator\n\nfrom scrapy.utils.serialize import ScrapyJSONEncoder\nfrom scrapy.utils.python import to_bytes, to_unicode, to_native_str, is_listlike\nfrom scrapy.item import BaseItem\nfrom scrapy.exceptions import ScrapyDeprecationWarning\nimport warnings\n\n\n__all__ = ['BaseItemExporter', 'PprintItemExporter', 'PickleItemExporter',\n           'CsvItemExporter', 'XmlItemExporter', 'JsonLinesItemExporter',\n           'JsonItemExporter', 'MarshalItemExporter']\n\n\nclass BaseItemExporter(object):\n\n    def __init__(self, **kwargs):\n        self._configure(kwargs)\n\n    def _configure(self, options, dont_fail=False):\n        \"\"\"Configure the exporter by poping options from the ``options`` dict.\n        If dont_fail is set, it won't raise an exception on unexpected options\n        (useful for using with keyword arguments in subclasses constructors)\n        \"\"\"\n        self.encoding = options.pop('encoding', None)\n        self.fields_to_export = options.pop('fields_to_export', None)\n        self.export_empty_fields = options.pop('export_empty_fields', False)\n        self.indent = options.pop('indent', None)\n        if not dont_fail and options:\n            raise TypeError(\"Unexpected options: %s\" % ', '.join(options.keys()))\n\n    def export_item(self, item):\n        raise NotImplementedError\n\n    def serialize_field(self, field, name, value):\n        serializer = field.get('serializer', lambda x: x)\n        return serializer(value)\n\n    def start_exporting(self):\n        pass\n\n    def finish_exporting(self):\n        pass\n\n    def _get_serialized_fields(self, item, default_value=None, include_empty=None):\n        \"\"\"Return the fields to export as an iterable of tuples\n        (name, serialized_value)\n        \"\"\"\n        if include_empty is None:\n            include_empty = self.export_empty_fields\n        if self.fields_to_export is None:\n            if include_empty and not isinstance(item, dict):\n                field_iter = six.iterkeys(item.fields)\n            else:\n                field_iter = six.iterkeys(item)\n        else:\n            if include_empty:\n                field_iter = self.fields_to_export\n            else:\n                field_iter = (x for x in self.fields_to_export if x in item)\n\n        for field_name in field_iter:\n            if field_name in item:\n                field = {} if isinstance(item, dict) else item.fields[field_name]\n                value = self.serialize_field(field, field_name, item[field_name])\n            else:\n                value = default_value\n\n            yield field_name, value\n\n\nclass JsonLinesItemExporter(BaseItemExporter):\n\n    def __init__(self, file, **kwargs):\n        self._configure(kwargs, dont_fail=True)\n        self.file = file\n        kwargs.setdefault('ensure_ascii', not self.encoding)\n        self.encoder = ScrapyJSONEncoder(**kwargs)\n\n    def export_item(self, item):\n        itemdict = dict(self._get_serialized_fields(item))\n        data = self.encoder.encode(itemdict) + '\\n'\n        self.file.write(to_bytes(data, self.encoding))\n\n\nclass JsonItemExporter(BaseItemExporter):\n\n    def __init__(self, file, **kwargs):\n        self._configure(kwargs, dont_fail=True)\n        self.file = file\n        # there is a small difference between the behaviour or JsonItemExporter.indent\n        # and ScrapyJSONEncoder.indent. ScrapyJSONEncoder.indent=None is needed to prevent\n        # the addition of newlines everywhere\n        json_indent = self.indent if self.indent is not None and self.indent > 0 else None\n        kwargs.setdefault('indent', json_indent)\n        kwargs.setdefault('ensure_ascii', not self.encoding)\n        self.encoder = ScrapyJSONEncoder(**kwargs)\n        self.first_item = True\n\n    def _beautify_newline(self):\n        if self.indent is not None:\n            self.file.write(b'\\n')\n\n    def start_exporting(self):\n        self.file.write(b\"[\")\n        self._beautify_newline()\n\n    def finish_exporting(self):\n        self._beautify_newline()\n        self.file.write(b\"]\")\n\n    def export_item(self, item):\n        if self.first_item:\n            self.first_item = False\n        else:\n            self.file.write(b',')\n            self._beautify_newline()\n        itemdict = dict(self._get_serialized_fields(item))\n        data = self.encoder.encode(itemdict)\n        self.file.write(to_bytes(data, self.encoding))\n\n\nclass XmlItemExporter(BaseItemExporter):\n\n    def __init__(self, file, **kwargs):\n        self.item_element = kwargs.pop('item_element', 'item')\n        self.root_element = kwargs.pop('root_element', 'items')\n        self._configure(kwargs)\n        if not self.encoding:\n            self.encoding = 'utf-8'\n        self.xg = XMLGenerator(file, encoding=self.encoding)\n\n    def _beautify_newline(self, new_item=False):\n        if self.indent is not None and (self.indent > 0 or new_item):\n            self._xg_characters('\\n')\n\n    def _beautify_indent(self, depth=1):\n        if self.indent:\n            self._xg_characters(' ' * self.indent * depth)\n\n    def start_exporting(self):\n        self.xg.startDocument()\n        self.xg.startElement(self.root_element, {})\n        self._beautify_newline(new_item=True)\n\n    def export_item(self, item):\n        self._beautify_indent(depth=1)\n        self.xg.startElement(self.item_element, {})\n        self._beautify_newline()\n        for name, value in self._get_serialized_fields(item, default_value=''):\n            self._export_xml_field(name, value, depth=2)\n        self._beautify_indent(depth=1)\n        self.xg.endElement(self.item_element)\n        self._beautify_newline(new_item=True)\n\n    def finish_exporting(self):\n        self.xg.endElement(self.root_element)\n        self.xg.endDocument()\n\n    def _export_xml_field(self, name, serialized_value, depth):\n        self._beautify_indent(depth=depth)\n        self.xg.startElement(name, {})\n        if hasattr(serialized_value, 'items'):\n            self._beautify_newline()\n            for subname, value in serialized_value.items():\n                self._export_xml_field(subname, value, depth=depth+1)\n            self._beautify_indent(depth=depth)\n        elif is_listlike(serialized_value):\n            self._beautify_newline()\n            for value in serialized_value:\n                self._export_xml_field('value', value, depth=depth+1)\n            self._beautify_indent(depth=depth)\n        elif isinstance(serialized_value, six.text_type):\n            self._xg_characters(serialized_value)\n        else:\n            self._xg_characters(str(serialized_value))\n        self.xg.endElement(name)\n        self._beautify_newline()\n\n    # Workaround for https://bugs.python.org/issue17606\n    # Before Python 2.7.4 xml.sax.saxutils required bytes;\n    # since 2.7.4 it requires unicode. The bug is likely to be\n    # fixed in 2.7.6, but 2.7.6 will still support unicode,\n    # and Python 3.x will require unicode, so \">= 2.7.4\" should be fine.\n    if sys.version_info[:3] >= (2, 7, 4):\n        def _xg_characters(self, serialized_value):\n            if not isinstance(serialized_value, six.text_type):\n                serialized_value = serialized_value.decode(self.encoding)\n            return self.xg.characters(serialized_value)\n    else:  # pragma: no cover\n        def _xg_characters(self, serialized_value):\n            return self.xg.characters(serialized_value)\n\n\nclass CsvItemExporter(BaseItemExporter):\n\n    def __init__(self, file, include_headers_line=True, join_multivalued=',', **kwargs):\n        self._configure(kwargs, dont_fail=True)\n        if not self.encoding:\n            self.encoding = 'utf-8'\n        self.include_headers_line = include_headers_line\n        self.stream = io.TextIOWrapper(\n            file,\n            line_buffering=False,\n            write_through=True,\n            encoding=self.encoding\n        ) if six.PY3 else file\n        self.csv_writer = csv.writer(self.stream, **kwargs)\n        self._headers_not_written = True\n        self._join_multivalued = join_multivalued\n\n    def serialize_field(self, field, name, value):\n        serializer = field.get('serializer', self._join_if_needed)\n        return serializer(value)\n\n    def _join_if_needed(self, value):\n        if isinstance(value, (list, tuple)):\n            try:\n                return self._join_multivalued.join(value)\n            except TypeError:  # list in value may not contain strings\n                pass\n        return value\n\n    def export_item(self, item):\n        if self._headers_not_written:\n            self._headers_not_written = False\n            self._write_headers_and_set_fields_to_export(item)\n\n        fields = self._get_serialized_fields(item, default_value='',\n                                             include_empty=True)\n        values = list(self._build_row(x for _, x in fields))\n        self.csv_writer.writerow(values)\n\n    def _build_row(self, values):\n        for s in values:\n            try:\n                yield to_native_str(s, self.encoding)\n            except TypeError:\n                yield s\n\n    def _write_headers_and_set_fields_to_export(self, item):\n        if self.include_headers_line:\n            if not self.fields_to_export:\n                if isinstance(item, dict):\n                    # for dicts try using fields of the first item\n                    self.fields_to_export = list(item.keys())\n                else:\n                    # use fields declared in Item\n                    self.fields_to_export = list(item.fields.keys())\n            row = list(self._build_row(self.fields_to_export))\n            self.csv_writer.writerow(row)\n\n\nclass PickleItemExporter(BaseItemExporter):\n\n    def __init__(self, file, protocol=2, **kwargs):\n        self._configure(kwargs)\n        self.file = file\n        self.protocol = protocol\n\n    def export_item(self, item):\n        d = dict(self._get_serialized_fields(item))\n        pickle.dump(d, self.file, self.protocol)\n\n\nclass MarshalItemExporter(BaseItemExporter):\n\n    def __init__(self, file, **kwargs):\n        self._configure(kwargs)\n        self.file = file\n\n    def export_item(self, item):\n        marshal.dump(dict(self._get_serialized_fields(item)), self.file)\n\n\nclass PprintItemExporter(BaseItemExporter):\n\n    def __init__(self, file, **kwargs):\n        self._configure(kwargs)\n        self.file = file\n\n    def export_item(self, item):\n        itemdict = dict(self._get_serialized_fields(item))\n        self.file.write(to_bytes(pprint.pformat(itemdict) + '\\n'))\n\n\nclass PythonItemExporter(BaseItemExporter):\n    \"\"\"The idea behind this exporter is to have a mechanism to serialize items\n    to built-in python types so any serialization library (like\n    json, msgpack, binc, etc) can be used on top of it. Its main goal is to\n    seamless support what BaseItemExporter does plus nested items.\n    \"\"\"\n    def _configure(self, options, dont_fail=False):\n        self.binary = options.pop('binary', True)\n        super(PythonItemExporter, self)._configure(options, dont_fail)\n        if self.binary:\n            warnings.warn(\n                \"PythonItemExporter will drop support for binary export in the future\",\n                ScrapyDeprecationWarning)\n        if not self.encoding:\n            self.encoding = 'utf-8'\n\n    def serialize_field(self, field, name, value):\n        serializer = field.get('serializer', self._serialize_value)\n        return serializer(value)\n\n    def _serialize_value(self, value):\n        if isinstance(value, BaseItem):\n            return self.export_item(value)\n        if isinstance(value, dict):\n            return dict(self._serialize_dict(value))\n        if is_listlike(value):\n            return [self._serialize_value(v) for v in value]\n        encode_func = to_bytes if self.binary else to_unicode\n        if isinstance(value, (six.text_type, bytes)):\n            return encode_func(value, encoding=self.encoding)\n        return value\n\n    def _serialize_dict(self, value):\n        for key, val in six.iteritems(value):\n            key = to_bytes(key) if self.binary else key\n            yield key, self._serialize_value(val)\n\n    def export_item(self, item):\n        result = dict(self._get_serialized_fields(item))\n        if self.binary:\n            result = dict(self._serialize_dict(result))\n        return result\n", "path": "scrapy/exporters.py"}], "after_files": [{"content": "\"\"\"\nItem Exporters are used to export/serialize items into different formats.\n\"\"\"\n\nimport csv\nimport io\nimport sys\nimport pprint\nimport marshal\nimport six\nfrom six.moves import cPickle as pickle\nfrom xml.sax.saxutils import XMLGenerator\n\nfrom scrapy.utils.serialize import ScrapyJSONEncoder\nfrom scrapy.utils.python import to_bytes, to_unicode, to_native_str, is_listlike\nfrom scrapy.item import BaseItem\nfrom scrapy.exceptions import ScrapyDeprecationWarning\nimport warnings\n\n\n__all__ = ['BaseItemExporter', 'PprintItemExporter', 'PickleItemExporter',\n           'CsvItemExporter', 'XmlItemExporter', 'JsonLinesItemExporter',\n           'JsonItemExporter', 'MarshalItemExporter']\n\n\nclass BaseItemExporter(object):\n\n    def __init__(self, **kwargs):\n        self._configure(kwargs)\n\n    def _configure(self, options, dont_fail=False):\n        \"\"\"Configure the exporter by poping options from the ``options`` dict.\n        If dont_fail is set, it won't raise an exception on unexpected options\n        (useful for using with keyword arguments in subclasses constructors)\n        \"\"\"\n        self.encoding = options.pop('encoding', None)\n        self.fields_to_export = options.pop('fields_to_export', None)\n        self.export_empty_fields = options.pop('export_empty_fields', False)\n        self.indent = options.pop('indent', None)\n        if not dont_fail and options:\n            raise TypeError(\"Unexpected options: %s\" % ', '.join(options.keys()))\n\n    def export_item(self, item):\n        raise NotImplementedError\n\n    def serialize_field(self, field, name, value):\n        serializer = field.get('serializer', lambda x: x)\n        return serializer(value)\n\n    def start_exporting(self):\n        pass\n\n    def finish_exporting(self):\n        pass\n\n    def _get_serialized_fields(self, item, default_value=None, include_empty=None):\n        \"\"\"Return the fields to export as an iterable of tuples\n        (name, serialized_value)\n        \"\"\"\n        if include_empty is None:\n            include_empty = self.export_empty_fields\n        if self.fields_to_export is None:\n            if include_empty and not isinstance(item, dict):\n                field_iter = six.iterkeys(item.fields)\n            else:\n                field_iter = six.iterkeys(item)\n        else:\n            if include_empty:\n                field_iter = self.fields_to_export\n            else:\n                field_iter = (x for x in self.fields_to_export if x in item)\n\n        for field_name in field_iter:\n            if field_name in item:\n                field = {} if isinstance(item, dict) else item.fields[field_name]\n                value = self.serialize_field(field, field_name, item[field_name])\n            else:\n                value = default_value\n\n            yield field_name, value\n\n\nclass JsonLinesItemExporter(BaseItemExporter):\n\n    def __init__(self, file, **kwargs):\n        self._configure(kwargs, dont_fail=True)\n        self.file = file\n        kwargs.setdefault('ensure_ascii', not self.encoding)\n        self.encoder = ScrapyJSONEncoder(**kwargs)\n\n    def export_item(self, item):\n        itemdict = dict(self._get_serialized_fields(item))\n        data = self.encoder.encode(itemdict) + '\\n'\n        self.file.write(to_bytes(data, self.encoding))\n\n\nclass JsonItemExporter(BaseItemExporter):\n\n    def __init__(self, file, **kwargs):\n        self._configure(kwargs, dont_fail=True)\n        self.file = file\n        # there is a small difference between the behaviour or JsonItemExporter.indent\n        # and ScrapyJSONEncoder.indent. ScrapyJSONEncoder.indent=None is needed to prevent\n        # the addition of newlines everywhere\n        json_indent = self.indent if self.indent is not None and self.indent > 0 else None\n        kwargs.setdefault('indent', json_indent)\n        kwargs.setdefault('ensure_ascii', not self.encoding)\n        self.encoder = ScrapyJSONEncoder(**kwargs)\n        self.first_item = True\n\n    def _beautify_newline(self):\n        if self.indent is not None:\n            self.file.write(b'\\n')\n\n    def start_exporting(self):\n        self.file.write(b\"[\")\n        self._beautify_newline()\n\n    def finish_exporting(self):\n        self._beautify_newline()\n        self.file.write(b\"]\")\n\n    def export_item(self, item):\n        if self.first_item:\n            self.first_item = False\n        else:\n            self.file.write(b',')\n            self._beautify_newline()\n        itemdict = dict(self._get_serialized_fields(item))\n        data = self.encoder.encode(itemdict)\n        self.file.write(to_bytes(data, self.encoding))\n\n\nclass XmlItemExporter(BaseItemExporter):\n\n    def __init__(self, file, **kwargs):\n        self.item_element = kwargs.pop('item_element', 'item')\n        self.root_element = kwargs.pop('root_element', 'items')\n        self._configure(kwargs)\n        if not self.encoding:\n            self.encoding = 'utf-8'\n        self.xg = XMLGenerator(file, encoding=self.encoding)\n\n    def _beautify_newline(self, new_item=False):\n        if self.indent is not None and (self.indent > 0 or new_item):\n            self._xg_characters('\\n')\n\n    def _beautify_indent(self, depth=1):\n        if self.indent:\n            self._xg_characters(' ' * self.indent * depth)\n\n    def start_exporting(self):\n        self.xg.startDocument()\n        self.xg.startElement(self.root_element, {})\n        self._beautify_newline(new_item=True)\n\n    def export_item(self, item):\n        self._beautify_indent(depth=1)\n        self.xg.startElement(self.item_element, {})\n        self._beautify_newline()\n        for name, value in self._get_serialized_fields(item, default_value=''):\n            self._export_xml_field(name, value, depth=2)\n        self._beautify_indent(depth=1)\n        self.xg.endElement(self.item_element)\n        self._beautify_newline(new_item=True)\n\n    def finish_exporting(self):\n        self.xg.endElement(self.root_element)\n        self.xg.endDocument()\n\n    def _export_xml_field(self, name, serialized_value, depth):\n        self._beautify_indent(depth=depth)\n        self.xg.startElement(name, {})\n        if hasattr(serialized_value, 'items'):\n            self._beautify_newline()\n            for subname, value in serialized_value.items():\n                self._export_xml_field(subname, value, depth=depth+1)\n            self._beautify_indent(depth=depth)\n        elif is_listlike(serialized_value):\n            self._beautify_newline()\n            for value in serialized_value:\n                self._export_xml_field('value', value, depth=depth+1)\n            self._beautify_indent(depth=depth)\n        elif isinstance(serialized_value, six.text_type):\n            self._xg_characters(serialized_value)\n        else:\n            self._xg_characters(str(serialized_value))\n        self.xg.endElement(name)\n        self._beautify_newline()\n\n    # Workaround for https://bugs.python.org/issue17606\n    # Before Python 2.7.4 xml.sax.saxutils required bytes;\n    # since 2.7.4 it requires unicode. The bug is likely to be\n    # fixed in 2.7.6, but 2.7.6 will still support unicode,\n    # and Python 3.x will require unicode, so \">= 2.7.4\" should be fine.\n    if sys.version_info[:3] >= (2, 7, 4):\n        def _xg_characters(self, serialized_value):\n            if not isinstance(serialized_value, six.text_type):\n                serialized_value = serialized_value.decode(self.encoding)\n            return self.xg.characters(serialized_value)\n    else:  # pragma: no cover\n        def _xg_characters(self, serialized_value):\n            return self.xg.characters(serialized_value)\n\n\nclass CsvItemExporter(BaseItemExporter):\n\n    def __init__(self, file, include_headers_line=True, join_multivalued=',', **kwargs):\n        self._configure(kwargs, dont_fail=True)\n        if not self.encoding:\n            self.encoding = 'utf-8'\n        self.include_headers_line = include_headers_line\n        self.stream = io.TextIOWrapper(\n            file,\n            line_buffering=False,\n            write_through=True,\n            encoding=self.encoding,\n            newline='' # Windows needs this https://github.com/scrapy/scrapy/issues/3034\n        ) if six.PY3 else file\n        self.csv_writer = csv.writer(self.stream, **kwargs)\n        self._headers_not_written = True\n        self._join_multivalued = join_multivalued\n\n    def serialize_field(self, field, name, value):\n        serializer = field.get('serializer', self._join_if_needed)\n        return serializer(value)\n\n    def _join_if_needed(self, value):\n        if isinstance(value, (list, tuple)):\n            try:\n                return self._join_multivalued.join(value)\n            except TypeError:  # list in value may not contain strings\n                pass\n        return value\n\n    def export_item(self, item):\n        if self._headers_not_written:\n            self._headers_not_written = False\n            self._write_headers_and_set_fields_to_export(item)\n\n        fields = self._get_serialized_fields(item, default_value='',\n                                             include_empty=True)\n        values = list(self._build_row(x for _, x in fields))\n        self.csv_writer.writerow(values)\n\n    def _build_row(self, values):\n        for s in values:\n            try:\n                yield to_native_str(s, self.encoding)\n            except TypeError:\n                yield s\n\n    def _write_headers_and_set_fields_to_export(self, item):\n        if self.include_headers_line:\n            if not self.fields_to_export:\n                if isinstance(item, dict):\n                    # for dicts try using fields of the first item\n                    self.fields_to_export = list(item.keys())\n                else:\n                    # use fields declared in Item\n                    self.fields_to_export = list(item.fields.keys())\n            row = list(self._build_row(self.fields_to_export))\n            self.csv_writer.writerow(row)\n\n\nclass PickleItemExporter(BaseItemExporter):\n\n    def __init__(self, file, protocol=2, **kwargs):\n        self._configure(kwargs)\n        self.file = file\n        self.protocol = protocol\n\n    def export_item(self, item):\n        d = dict(self._get_serialized_fields(item))\n        pickle.dump(d, self.file, self.protocol)\n\n\nclass MarshalItemExporter(BaseItemExporter):\n\n    def __init__(self, file, **kwargs):\n        self._configure(kwargs)\n        self.file = file\n\n    def export_item(self, item):\n        marshal.dump(dict(self._get_serialized_fields(item)), self.file)\n\n\nclass PprintItemExporter(BaseItemExporter):\n\n    def __init__(self, file, **kwargs):\n        self._configure(kwargs)\n        self.file = file\n\n    def export_item(self, item):\n        itemdict = dict(self._get_serialized_fields(item))\n        self.file.write(to_bytes(pprint.pformat(itemdict) + '\\n'))\n\n\nclass PythonItemExporter(BaseItemExporter):\n    \"\"\"The idea behind this exporter is to have a mechanism to serialize items\n    to built-in python types so any serialization library (like\n    json, msgpack, binc, etc) can be used on top of it. Its main goal is to\n    seamless support what BaseItemExporter does plus nested items.\n    \"\"\"\n    def _configure(self, options, dont_fail=False):\n        self.binary = options.pop('binary', True)\n        super(PythonItemExporter, self)._configure(options, dont_fail)\n        if self.binary:\n            warnings.warn(\n                \"PythonItemExporter will drop support for binary export in the future\",\n                ScrapyDeprecationWarning)\n        if not self.encoding:\n            self.encoding = 'utf-8'\n\n    def serialize_field(self, field, name, value):\n        serializer = field.get('serializer', self._serialize_value)\n        return serializer(value)\n\n    def _serialize_value(self, value):\n        if isinstance(value, BaseItem):\n            return self.export_item(value)\n        if isinstance(value, dict):\n            return dict(self._serialize_dict(value))\n        if is_listlike(value):\n            return [self._serialize_value(v) for v in value]\n        encode_func = to_bytes if self.binary else to_unicode\n        if isinstance(value, (six.text_type, bytes)):\n            return encode_func(value, encoding=self.encoding)\n        return value\n\n    def _serialize_dict(self, value):\n        for key, val in six.iteritems(value):\n            key = to_bytes(key) if self.binary else key\n            yield key, self._serialize_value(val)\n\n    def export_item(self, item):\n        result = dict(self._get_serialized_fields(item))\n        if self.binary:\n            result = dict(self._serialize_dict(result))\n        return result\n", "path": "scrapy/exporters.py"}]}