mirror of
https://github.com/python/cpython.git
synced 2025-08-09 19:38:42 +00:00
[3.12] gh-67044: Always quote or escape \r and \n in csv.writer() (GH-115741) (GH-115866)
(cherry picked from commit c688c0f130
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
10907bdad3
commit
4ac657a62f
3 changed files with 43 additions and 15 deletions
|
@ -240,9 +240,11 @@ class Test_Csv(unittest.TestCase):
|
|||
writer = csv.writer(sio, lineterminator=lineterminator)
|
||||
writer.writerow(['a', 'b'])
|
||||
writer.writerow([1, 2])
|
||||
writer.writerow(['\r', '\n'])
|
||||
self.assertEqual(sio.getvalue(),
|
||||
f'a,b{lineterminator}'
|
||||
f'1,2{lineterminator}')
|
||||
f'1,2{lineterminator}'
|
||||
f'"\r","\n"{lineterminator}')
|
||||
|
||||
def test_write_iterable(self):
|
||||
self._write_test(iter(['a', 1, 'p,q']), 'a,1,"p,q"')
|
||||
|
@ -469,22 +471,44 @@ class Test_Csv(unittest.TestCase):
|
|||
self.assertEqual(r.line_num, 3)
|
||||
|
||||
def test_roundtrip_quoteed_newlines(self):
|
||||
with TemporaryFile("w+", encoding="utf-8", newline='') as fileobj:
|
||||
writer = csv.writer(fileobj)
|
||||
rows = [['a\nb','b'],['c','x\r\nd']]
|
||||
writer.writerows(rows)
|
||||
fileobj.seek(0)
|
||||
for i, row in enumerate(csv.reader(fileobj)):
|
||||
self.assertEqual(row, rows[i])
|
||||
rows = [
|
||||
['\na', 'b\nc', 'd\n'],
|
||||
['\re', 'f\rg', 'h\r'],
|
||||
['\r\ni', 'j\r\nk', 'l\r\n'],
|
||||
['\n\rm', 'n\n\ro', 'p\n\r'],
|
||||
['\r\rq', 'r\r\rs', 't\r\r'],
|
||||
['\n\nu', 'v\n\nw', 'x\n\n'],
|
||||
]
|
||||
for lineterminator in '\r\n', '\n', '\r':
|
||||
with self.subTest(lineterminator=lineterminator):
|
||||
with TemporaryFile("w+", encoding="utf-8", newline='') as fileobj:
|
||||
writer = csv.writer(fileobj, lineterminator=lineterminator)
|
||||
writer.writerows(rows)
|
||||
fileobj.seek(0)
|
||||
for i, row in enumerate(csv.reader(fileobj)):
|
||||
self.assertEqual(row, rows[i])
|
||||
|
||||
def test_roundtrip_escaped_unquoted_newlines(self):
|
||||
with TemporaryFile("w+", encoding="utf-8", newline='') as fileobj:
|
||||
writer = csv.writer(fileobj,quoting=csv.QUOTE_NONE,escapechar="\\")
|
||||
rows = [['a\nb','b'],['c','x\r\nd']]
|
||||
writer.writerows(rows)
|
||||
fileobj.seek(0)
|
||||
for i, row in enumerate(csv.reader(fileobj,quoting=csv.QUOTE_NONE,escapechar="\\")):
|
||||
self.assertEqual(row,rows[i])
|
||||
rows = [
|
||||
['\na', 'b\nc', 'd\n'],
|
||||
['\re', 'f\rg', 'h\r'],
|
||||
['\r\ni', 'j\r\nk', 'l\r\n'],
|
||||
['\n\rm', 'n\n\ro', 'p\n\r'],
|
||||
['\r\rq', 'r\r\rs', 't\r\r'],
|
||||
['\n\nu', 'v\n\nw', 'x\n\n'],
|
||||
]
|
||||
for lineterminator in '\r\n', '\n', '\r':
|
||||
with self.subTest(lineterminator=lineterminator):
|
||||
with TemporaryFile("w+", encoding="utf-8", newline='') as fileobj:
|
||||
writer = csv.writer(fileobj, lineterminator=lineterminator,
|
||||
quoting=csv.QUOTE_NONE, escapechar="\\")
|
||||
writer.writerows(rows)
|
||||
fileobj.seek(0)
|
||||
for i, row in enumerate(csv.reader(fileobj,
|
||||
quoting=csv.QUOTE_NONE,
|
||||
escapechar="\\")):
|
||||
self.assertEqual(row, rows[i])
|
||||
|
||||
|
||||
class TestDialectRegistry(unittest.TestCase):
|
||||
def test_registry_badargs(self):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue