@@ -235,6 +235,97 @@ If installed, we now require:
235
235
| scipy | 0.18.1 | |
236
236
+-----------------+-----------------+----------+
237
237
238
+ .. _whatsnew_0240.api_breaking.csv_line_terminator:
239
+
240
+ `os.linesep` is used for ``line_terminator`` of ``DataFrame.to_csv``
241
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
242
+
243
+ :func:`DataFrame.to_csv` now uses :func:`os.linesep` rather than ``'\n'``
244
+ for the default line terminator (:issue:`20353`).
245
+ This change only affects when running on Windows, where ``'\r\n'`` was used for line terminator
246
+ even when ``'\n'`` was passed in ``line_terminator``.
247
+
248
+ Previous Behavior on Windows:
249
+
250
+ .. code-block:: ipython
251
+
252
+ In [1]: data = pd.DataFrame({
253
+ ...: "string_with_lf": ["a\nbc"],
254
+ ...: "string_with_crlf": ["a\r\nbc"]
255
+ ...: })
256
+
257
+ In [2]: # When passing file PATH to to_csv, line_terminator does not work, and csv is saved with '\r\n'.
258
+ ...: # Also, this converts all '\n's in the data to '\r\n'.
259
+ ...: data.to_csv("test.csv", index=False, line_terminator='\n')
260
+
261
+ In [3]: with open("test.csv", mode='rb') as f:
262
+ ...: print(f.read())
263
+ b'string_with_lf,string_with_crlf\r\n"a\r\nbc","a\r\r\nbc"\r\n'
264
+
265
+ In [4]: # When passing file OBJECT with newline option to to_csv, line_terminator works.
266
+ ...: with open("test2.csv", mode='w', newline='\n') as f:
267
+ ...: data.to_csv(f, index=False, line_terminator='\n')
268
+
269
+ In [5]: with open("test2.csv", mode='rb') as f:
270
+ ...: print(f.read())
271
+ b'string_with_lf,string_with_crlf\n"a\nbc","a\r\nbc"\n'
272
+
273
+
274
+ New Behavior on Windows:
275
+
276
+ - By passing ``line_terminator`` explicitly, line terminator is set to that character.
277
+ - The value of ``line_terminator`` only affects the line terminator of CSV,
278
+ so it does not change the value inside the data.
279
+
280
+ .. code-block:: ipython
281
+
282
+ In [1]: data = pd.DataFrame({
283
+ ...: "string_with_lf": ["a\nbc"],
284
+ ...: "string_with_crlf": ["a\r\nbc"]
285
+ ...: })
286
+
287
+ In [2]: data.to_csv("test.csv", index=False, line_terminator='\n')
288
+
289
+ In [3]: with open("test.csv", mode='rb') as f:
290
+ ...: print(f.read())
291
+ b'string_with_lf,string_with_crlf\n"a\nbc","a\r\nbc"\n'
292
+
293
+
294
+ - On Windows, the value of ``os.linesep`` is ``'\r\n'``,
295
+ so if ``line_terminator`` is not set, ``'\r\n'`` is used for line terminator.
296
+ - Again, it does not affect the value inside the data.
297
+
298
+ .. code-block:: ipython
299
+
300
+ In [1]: data = pd.DataFrame({
301
+ ...: "string_with_lf": ["a\nbc"],
302
+ ...: "string_with_crlf": ["a\r\nbc"]
303
+ ...: })
304
+
305
+ In [2]: data.to_csv("test.csv", index=False)
306
+
307
+ In [3]: with open("test.csv", mode='rb') as f:
308
+ ...: print(f.read())
309
+ b'string_with_lf,string_with_crlf\r\n"a\nbc","a\r\nbc"\r\n'
310
+
311
+
312
+ - For files objects, specifying ``newline`` is not sufficient to set the line terminator.
313
+ You must pass in the ``line_terminator`` explicitly, even in this case.
314
+
315
+ .. code-block:: ipython
316
+
317
+ In [1]: data = pd.DataFrame({
318
+ ...: "string_with_lf": ["a\nbc"],
319
+ ...: "string_with_crlf": ["a\r\nbc"]
320
+ ...: })
321
+
322
+ In [2]: with open("test2.csv", mode='w', newline='\n') as f:
323
+ ...: data.to_csv(f, index=False)
324
+
325
+ In [3]: with open("test2.csv", mode='rb') as f:
326
+ ...: print(f.read())
327
+ b'string_with_lf,string_with_crlf\r\n"a\nbc","a\r\nbc"\r\n'
328
+
238
329
.. _whatsnew_0240.api_breaking.interval_values:
239
330
240
331
``IntervalIndex.values`` is now an ``IntervalArray``
0 commit comments