Skip to content

Commit f373864

Browse files
committed
Merge pull request #4752 from jtratner/fix-to_csv_QUOTE_NONE-GH4328
BUG: Fix crash using to_csv with QUOTE_NONE
2 parents dbb3a3d + 5e73865 commit f373864

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

doc/source/release.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ See :ref:`Internal Refactoring<whatsnew_0130.refactoring>`
315315
- Fix some inconsistencies with ``Index.rename`` and ``MultiIndex.rename``,
316316
etc. (:issue:`4718`, :issue:`4628`)
317317
- Bug in using ``iloc/loc`` with a cross-sectional and duplicate indicies (:issue:`4726`)
318+
- Bug with using ``QUOTE_NONE`` with ``to_csv`` causing ``Exception``. (:issue:`4328`)
318319

319320
pandas 0.12
320321
===========

pandas/core/format.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ def __init__(self, obj, path_or_buf, sep=",", na_rep='', float_format=None,
787787
cols=None, header=True, index=True, index_label=None,
788788
mode='w', nanRep=None, encoding=None, quoting=None,
789789
line_terminator='\n', chunksize=None, engine=None,
790-
tupleize_cols=True):
790+
tupleize_cols=True, quotechar='"'):
791791

792792
self.engine = engine # remove for 0.13
793793
self.obj = obj
@@ -807,6 +807,11 @@ def __init__(self, obj, path_or_buf, sep=",", na_rep='', float_format=None,
807807
quoting = csv.QUOTE_MINIMAL
808808
self.quoting = quoting
809809

810+
if quoting == csv.QUOTE_NONE:
811+
# prevents crash in _csv
812+
quotechar = None
813+
self.quotechar = quotechar
814+
810815
self.line_terminator = line_terminator
811816

812817
#GH3457
@@ -950,13 +955,14 @@ def save(self):
950955
close = True
951956

952957
try:
958+
writer_kwargs = dict(lineterminator=self.line_terminator,
959+
delimiter=self.sep, quoting=self.quoting,
960+
quotechar=self.quotechar)
953961
if self.encoding is not None:
954-
self.writer = com.UnicodeWriter(f, lineterminator=self.line_terminator,
955-
delimiter=self.sep, encoding=self.encoding,
956-
quoting=self.quoting)
962+
writer_kwargs['encoding'] = self.encoding
963+
self.writer = com.UnicodeWriter(f, **writer_kwargs)
957964
else:
958-
self.writer = csv.writer(f, lineterminator=self.line_terminator,
959-
delimiter=self.sep, quoting=self.quoting)
965+
self.writer = csv.writer(f, **writer_kwargs)
960966

961967
if self.engine == 'python':
962968
# to be removed in 0.13

pandas/tests/test_frame.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from datetime import datetime, timedelta, time
77
import operator
88
import re
9+
import csv
910
import unittest
1011
import nose
1112

@@ -5465,8 +5466,6 @@ def test_to_csv_float_format(self):
54655466
assert_frame_equal(rs, xp)
54665467

54675468
def test_to_csv_quoting(self):
5468-
import csv
5469-
54705469
df = DataFrame({'A': [1, 2, 3], 'B': ['foo', 'bar', 'baz']})
54715470

54725471
buf = StringIO()
@@ -5489,8 +5488,6 @@ def test_to_csv_quoting(self):
54895488
self.assertEqual(buf.getvalue(), text)
54905489

54915490
def test_to_csv_unicodewriter_quoting(self):
5492-
import csv
5493-
54945491
df = DataFrame({'A': [1, 2, 3], 'B': ['foo', 'bar', 'baz']})
54955492

54965493
buf = StringIO()
@@ -5505,6 +5502,17 @@ def test_to_csv_unicodewriter_quoting(self):
55055502

55065503
self.assertEqual(result, expected)
55075504

5505+
def test_to_csv_quote_none(self):
5506+
# GH4328
5507+
df = DataFrame({'A': ['hello', '{"hello"}']})
5508+
for encoding in (None, 'utf-8'):
5509+
buf = StringIO()
5510+
df.to_csv(buf, quoting=csv.QUOTE_NONE,
5511+
encoding=encoding, index=False)
5512+
result = buf.getvalue()
5513+
expected = 'A\nhello\n{"hello"}\n'
5514+
self.assertEqual(result, expected)
5515+
55085516
def test_to_csv_index_no_leading_comma(self):
55095517
df = DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]},
55105518
index=['one', 'two', 'three'])

0 commit comments

Comments
 (0)