@@ -64,8 +64,7 @@ def _test_arg_valid(self, ctor, arg):
64
64
ctor (arg , delimiter = '\t ' , skipinitialspace = True )
65
65
ctor (arg , escapechar = '\t ' , skipinitialspace = True )
66
66
ctor (arg , quotechar = '\t ' , skipinitialspace = True )
67
- self .assertRaises (ValueError , ctor , arg ,
68
- delimiter = ' ' , skipinitialspace = True )
67
+ ctor (arg , delimiter = ' ' , skipinitialspace = True )
69
68
self .assertRaises (ValueError , ctor , arg ,
70
69
escapechar = ' ' , skipinitialspace = True )
71
70
self .assertRaises (ValueError , ctor , arg ,
@@ -192,9 +191,6 @@ def _write_error_test(self, exc, fields, **kwargs):
192
191
193
192
def test_write_arg_valid (self ):
194
193
self ._write_error_test (csv .Error , None )
195
- self ._write_test ((), '' )
196
- self ._write_test ([None ], '""' )
197
- self ._write_error_test (csv .Error , [None ], quoting = csv .QUOTE_NONE )
198
194
# Check that exceptions are passed up the chain
199
195
self ._write_error_test (OSError , BadIterable ())
200
196
class BadList :
@@ -208,7 +204,6 @@ class BadItem:
208
204
def __str__ (self ):
209
205
raise OSError
210
206
self ._write_error_test (OSError , [BadItem ()])
211
-
212
207
def test_write_bigfield (self ):
213
208
# This exercises the buffer realloc functionality
214
209
bigstring = 'X' * 50000
@@ -315,6 +310,49 @@ def test_writerows_with_none(self):
315
310
fileobj .seek (0 )
316
311
self .assertEqual (fileobj .read (), 'a\r \n ""\r \n ' )
317
312
313
+
314
+ def test_write_empty_fields (self ):
315
+ self ._write_test ((), '' )
316
+ self ._write_test (['' ], '""' )
317
+ self ._write_error_test (csv .Error , ['' ], quoting = csv .QUOTE_NONE )
318
+ self ._write_test (['' ], '""' , quoting = csv .QUOTE_STRINGS )
319
+ self ._write_test (['' ], '""' , quoting = csv .QUOTE_NOTNULL )
320
+ self ._write_test ([None ], '""' )
321
+ self ._write_error_test (csv .Error , [None ], quoting = csv .QUOTE_NONE )
322
+ self ._write_error_test (csv .Error , [None ], quoting = csv .QUOTE_STRINGS )
323
+ self ._write_error_test (csv .Error , [None ], quoting = csv .QUOTE_NOTNULL )
324
+ self ._write_test (['' , '' ], ',' )
325
+ self ._write_test ([None , None ], ',' )
326
+
327
+ def test_write_empty_fields_space_delimiter (self ):
328
+ self ._write_test (['' ], '""' , delimiter = ' ' , skipinitialspace = False )
329
+ self ._write_test (['' ], '""' , delimiter = ' ' , skipinitialspace = True )
330
+ self ._write_test ([None ], '""' , delimiter = ' ' , skipinitialspace = False )
331
+ self ._write_test ([None ], '""' , delimiter = ' ' , skipinitialspace = True )
332
+
333
+ self ._write_test (['' , '' ], ' ' , delimiter = ' ' , skipinitialspace = False )
334
+ self ._write_test (['' , '' ], '"" ""' , delimiter = ' ' , skipinitialspace = True )
335
+ self ._write_test ([None , None ], ' ' , delimiter = ' ' , skipinitialspace = False )
336
+ self ._write_test ([None , None ], '"" ""' , delimiter = ' ' , skipinitialspace = True )
337
+
338
+ self ._write_test (['' , '' ], ' ' , delimiter = ' ' , skipinitialspace = False ,
339
+ quoting = csv .QUOTE_NONE )
340
+ self ._write_error_test (csv .Error , ['' , '' ],
341
+ delimiter = ' ' , skipinitialspace = True ,
342
+ quoting = csv .QUOTE_NONE )
343
+ for quoting in csv .QUOTE_STRINGS , csv .QUOTE_NOTNULL :
344
+ self ._write_test (['' , '' ], '"" ""' , delimiter = ' ' , skipinitialspace = False ,
345
+ quoting = quoting )
346
+ self ._write_test (['' , '' ], '"" ""' , delimiter = ' ' , skipinitialspace = True ,
347
+ quoting = quoting )
348
+
349
+ for quoting in csv .QUOTE_NONE , csv .QUOTE_STRINGS , csv .QUOTE_NOTNULL :
350
+ self ._write_test ([None , None ], ' ' , delimiter = ' ' , skipinitialspace = False ,
351
+ quoting = quoting )
352
+ self ._write_error_test (csv .Error , [None , None ],
353
+ delimiter = ' ' , skipinitialspace = True ,
354
+ quoting = quoting )
355
+
318
356
def test_writerows_errors (self ):
319
357
with TemporaryFile ("w+" , encoding = "utf-8" , newline = '' ) as fileobj :
320
358
writer = csv .writer (fileobj )
@@ -429,6 +467,14 @@ def test_read_skipinitialspace(self):
429
467
[[None , None , None ]],
430
468
skipinitialspace = True , quoting = csv .QUOTE_STRINGS )
431
469
470
+ def test_read_space_delimiter (self ):
471
+ self ._read_test (['a b' , ' a ' , ' ' , '' ],
472
+ [['a' , '' , '' , 'b' ], ['' , '' , 'a' , '' , '' ], ['' , '' , '' ], []],
473
+ delimiter = ' ' , skipinitialspace = False )
474
+ self ._read_test (['a b' , ' a ' , ' ' , '' ],
475
+ [['a' , 'b' ], ['a' , '' ], ['' ], []],
476
+ delimiter = ' ' , skipinitialspace = True )
477
+
432
478
def test_read_bigfield (self ):
433
479
# This exercises the buffer realloc functionality and field size
434
480
# limits.
@@ -555,10 +601,10 @@ class space(csv.excel):
555
601
escapechar = "\\ "
556
602
557
603
with TemporaryFile ("w+" , encoding = "utf-8" ) as fileobj :
558
- fileobj .write ("abc def\n c1ccccc1 benzene\n " )
604
+ fileobj .write ("abc def\n c1ccccc1 benzene\n " )
559
605
fileobj .seek (0 )
560
606
reader = csv .reader (fileobj , dialect = space ())
561
- self .assertEqual (next (reader ), ["abc" , "def" ])
607
+ self .assertEqual (next (reader ), ["abc" , "" , "" , " def" ])
562
608
self .assertEqual (next (reader ), ["c1ccccc1" , "benzene" ])
563
609
564
610
def compare_dialect_123 (self , expected , * writeargs , ** kwwriteargs ):
@@ -1164,8 +1210,9 @@ class mydialect(csv.Dialect):
1164
1210
self .assertRaises (csv .Error , create_invalid , field_name , 5 )
1165
1211
self .assertRaises (ValueError , create_invalid , field_name , "\n " )
1166
1212
self .assertRaises (ValueError , create_invalid , field_name , "\r " )
1167
- self .assertRaises (ValueError , create_invalid , field_name , " " ,
1168
- skipinitialspace = True )
1213
+ if field_name != "delimiter" :
1214
+ self .assertRaises (ValueError , create_invalid , field_name , " " ,
1215
+ skipinitialspace = True )
1169
1216
1170
1217
1171
1218
class TestSniffer (unittest .TestCase ):
0 commit comments