@@ -17,44 +17,112 @@ class Test_Csv(unittest.TestCase):
1717 from the high level interface. Further tests of this nature are done
1818 in TestDialectRegistry.
1919 """
20- def test_reader_arg_valid (self ):
21- self .assertRaises (TypeError , csv .reader )
22- self .assertRaises (TypeError , csv .reader , None )
23- self .assertRaises (AttributeError , csv .reader , [], bad_attr = 0 )
24- self .assertRaises (csv .Error , csv .reader , [], 'foo' )
20+ def _test_arg_valid (self , ctor , arg ):
21+ self .assertRaises (TypeError , ctor )
22+ self .assertRaises (TypeError , ctor , None )
23+ self .assertRaises (TypeError , ctor , arg , bad_attr = 0 )
24+ self .assertRaises (TypeError , ctor , arg , delimiter = 0 )
25+ self .assertRaises (TypeError , ctor , arg , delimiter = 'XX' )
26+ self .assertRaises (csv .Error , ctor , arg , 'foo' )
27+ self .assertRaises (TypeError , ctor , arg , None )
28+ self .assertRaises (TypeError , ctor , arg , delimiter = None )
29+ self .assertRaises (TypeError , ctor , arg , delimiter = 1 )
30+ self .assertRaises (TypeError , ctor , arg , quotechar = 1 )
31+ self .assertRaises (TypeError , ctor , arg , lineterminator = None )
32+ self .assertRaises (TypeError , ctor , arg , lineterminator = 1 )
33+ self .assertRaises (TypeError , ctor , arg , quoting = None )
34+ # We now allow this, only raising an exception if quoting is needed.
35+ # self.assertRaises(TypeError, ctor, arg, quotechar=None)
36+ # self.assertRaises(TypeError, ctor, arg,
37+ # quoting=csv.QUOTE_NONE, escapechar=None)
38+ # No longer complains about dialects with invalid attributes [AM]
39+ # class BadDialect:
40+ # bad_attr = 0
41+ # self.assertRaises(AttributeError, csv.reader, [], BadDialect)
2542 class BadClass :
2643 def __init__ (self ):
2744 raise IOError
2845 self .assertRaises (IOError , csv .reader , [], BadClass )
29- self .assertRaises (TypeError , csv .reader , [], None )
30- class BadDialect :
31- bad_attr = 0
32- self .assertRaises (AttributeError , csv .reader , [], BadDialect )
46+
47+ def test_reader_arg_valid (self ):
48+ self ._test_arg_valid (csv .reader , [])
3349
3450 def test_writer_arg_valid (self ):
35- self .assertRaises (TypeError , csv .writer )
36- self .assertRaises (TypeError , csv .writer , None )
37- self .assertRaises (AttributeError , csv .writer , StringIO (), bad_attr = 0 )
51+ self ._test_arg_valid (csv .writer , StringIO ())
3852
39- def _test_attrs (self , obj ):
53+ def _test_default_attrs (self , ctor , * args ):
54+ obj = ctor (* args )
55+ # Check defaults
4056 self .assertEqual (obj .dialect .delimiter , ',' )
41- obj .dialect .delimiter = '\t '
42- self .assertEqual (obj .dialect .delimiter , '\t ' )
43- self .assertRaises (TypeError , delattr , obj .dialect , 'delimiter' )
44- self .assertRaises (TypeError , setattr , obj .dialect ,
45- 'lineterminator' , None )
46- obj .dialect .escapechar = None
57+ self .assertEqual (obj .dialect .doublequote , True )
4758 self .assertEqual (obj .dialect .escapechar , None )
59+ self .assertEqual (obj .dialect .lineterminator , "\r \n " )
60+ self .assertEqual (obj .dialect .quotechar , '"' )
61+ self .assertEqual (obj .dialect .quoting , csv .QUOTE_MINIMAL )
62+ self .assertEqual (obj .dialect .skipinitialspace , False )
63+ self .assertEqual (obj .dialect .strict , False )
64+ # Try deleting or changing attributes (they are read-only)
65+ self .assertRaises (TypeError , delattr , obj .dialect , 'delimiter' )
66+ self .assertRaises (TypeError , setattr , obj .dialect , 'delimiter' , ':' )
4867 self .assertRaises (TypeError , delattr , obj .dialect , 'quoting' )
4968 self .assertRaises (TypeError , setattr , obj .dialect , 'quoting' , None )
50- obj .dialect .quoting = csv .QUOTE_MINIMAL
51- self .assertEqual (obj .dialect .quoting , csv .QUOTE_MINIMAL )
5269
5370 def test_reader_attrs (self ):
54- self ._test_attrs (csv .reader ([]) )
71+ self ._test_default_attrs (csv .reader , [] )
5572
5673 def test_writer_attrs (self ):
57- self ._test_attrs (csv .writer (StringIO ()))
74+ self ._test_default_attrs (csv .writer , StringIO ())
75+
76+ def _test_kw_attrs (self , ctor , * args ):
77+ # Now try with alternate options
78+ kwargs = dict (delimiter = ':' , doublequote = False , escapechar = '\\ ' ,
79+ lineterminator = '\r ' , quotechar = '*' ,
80+ quoting = csv .QUOTE_NONE , skipinitialspace = True ,
81+ strict = True )
82+ obj = ctor (* args , ** kwargs )
83+ self .assertEqual (obj .dialect .delimiter , ':' )
84+ self .assertEqual (obj .dialect .doublequote , False )
85+ self .assertEqual (obj .dialect .escapechar , '\\ ' )
86+ self .assertEqual (obj .dialect .lineterminator , "\r " )
87+ self .assertEqual (obj .dialect .quotechar , '*' )
88+ self .assertEqual (obj .dialect .quoting , csv .QUOTE_NONE )
89+ self .assertEqual (obj .dialect .skipinitialspace , True )
90+ self .assertEqual (obj .dialect .strict , True )
91+
92+ def test_reader_kw_attrs (self ):
93+ self ._test_kw_attrs (csv .reader , [])
94+
95+ def test_writer_kw_attrs (self ):
96+ self ._test_kw_attrs (csv .writer , StringIO ())
97+
98+ def _test_dialect_attrs (self , ctor , * args ):
99+ # Now try with dialect-derived options
100+ class dialect :
101+ delimiter = '-'
102+ doublequote = False
103+ escapechar = '^'
104+ lineterminator = '$'
105+ quotechar = '#'
106+ quoting = csv .QUOTE_ALL
107+ skipinitialspace = True
108+ strict = False
109+ args = args + (dialect ,)
110+ obj = ctor (* args )
111+ self .assertEqual (obj .dialect .delimiter , '-' )
112+ self .assertEqual (obj .dialect .doublequote , False )
113+ self .assertEqual (obj .dialect .escapechar , '^' )
114+ self .assertEqual (obj .dialect .lineterminator , "$" )
115+ self .assertEqual (obj .dialect .quotechar , '#' )
116+ self .assertEqual (obj .dialect .quoting , csv .QUOTE_ALL )
117+ self .assertEqual (obj .dialect .skipinitialspace , True )
118+ self .assertEqual (obj .dialect .strict , False )
119+
120+ def test_reader_dialect_attrs (self ):
121+ self ._test_dialect_attrs (csv .reader , [])
122+
123+ def test_writer_dialect_attrs (self ):
124+ self ._test_dialect_attrs (csv .writer , StringIO ())
125+
58126
59127 def _write_test (self , fields , expect , ** kwargs ):
60128 fd , name = tempfile .mkstemp ()
@@ -166,6 +234,13 @@ def test_read_escape(self):
166234 self ._read_test (['a,"b,c\\ ""' ], [['a' , 'b,c"' ]], escapechar = '\\ ' )
167235 self ._read_test (['a,"b,c"\\ ' ], [['a' , 'b,c\\ ' ]], escapechar = '\\ ' )
168236
237+ def test_read_quoting (self ):
238+ self ._read_test (['1,",3,",5' ], [['1' , ',3,' , '5' ]])
239+ self ._read_test (['1,",3,",5' ], [['1' , '"' , '3' , '"' , '5' ]],
240+ quotechar = None , escapechar = '\\ ' )
241+ self ._read_test (['1,",3,",5' ], [['1' , '"' , '3' , '"' , '5' ]],
242+ quoting = csv .QUOTE_NONE , escapechar = '\\ ' )
243+
169244 def test_read_bigfield (self ):
170245 # This exercises the buffer realloc functionality
171246 bigstring = 'X' * 50000
@@ -297,7 +372,7 @@ class testC(csv.excel):
297372
298373 def test_bad_dialect (self ):
299374 # Unknown parameter
300- self .assertRaises (AttributeError , csv .reader , [], bad_attr = 0 )
375+ self .assertRaises (TypeError , csv .reader , [], bad_attr = 0 )
301376 # Bad values
302377 self .assertRaises (TypeError , csv .reader , [], delimiter = None )
303378 self .assertRaises (TypeError , csv .reader , [], quoting = - 1 )
0 commit comments