@@ -1275,6 +1275,30 @@ def open_csv(input_file, read_options=None, parse_options=None,
12751275 return reader
12761276
12771277
1278+ def _raise_invalid_function_option (value , description , *,
1279+ exception_class = ValueError ):
1280+ raise exception_class(f" \" {value}\" is not a valid {description}" )
1281+
1282+
1283+ cdef CQuotingStyle unwrap_quoting_style(quoting_style) except * :
1284+ if quoting_style == " needed" :
1285+ return CQuotingStyle_Needed
1286+ elif quoting_style == " all_valid" :
1287+ return CQuotingStyle_AllValid
1288+ elif quoting_style == " none" :
1289+ return CQuotingStyle_None
1290+ _raise_invalid_function_option(quoting_style, " quoting style" )
1291+
1292+
1293+ cdef wrap_quoting_style(quoting_style):
1294+ if quoting_style == CQuotingStyle_Needed:
1295+ return ' needed'
1296+ elif quoting_style == CQuotingStyle_AllValid:
1297+ return ' all_valid'
1298+ elif quoting_style == CQuotingStyle_None:
1299+ return ' none'
1300+
1301+
12781302cdef class WriteOptions(_Weakrefable):
12791303 """
12801304 Options for writing CSV files.
@@ -1288,20 +1312,31 @@ cdef class WriteOptions(_Weakrefable):
12881312 CSV data
12891313 delimiter : 1-character string, optional (default ",")
12901314 The character delimiting individual cells in the CSV data.
1315+ quoting_style : str, optional (default "needed")
1316+ Whether to quote values, and if so, which quoting style to use.
1317+ The following values are accepted:
1318+
1319+ - "needed" (default): only enclose values in quotes when needed.
1320+ - "all_valid": enclose all valid values in quotes; nulls are not quoted.
1321+ - "none": do not enclose any values in quotes; values containing
1322+ special characters (such as quotes, cell delimiters or line endings)
1323+ will raise an error.
12911324 """
12921325
12931326 # Avoid mistakingly creating attributes
12941327 __slots__ = ()
12951328
12961329 def __init__ (self , *, include_header = None , batch_size = None ,
1297- delimiter = None ):
1330+ delimiter = None , quoting_style = None ):
12981331 self .options.reset(new CCSVWriteOptions(CCSVWriteOptions.Defaults()))
12991332 if include_header is not None :
13001333 self .include_header = include_header
13011334 if batch_size is not None :
13021335 self .batch_size = batch_size
13031336 if delimiter is not None :
13041337 self .delimiter = delimiter
1338+ if quoting_style is not None :
1339+ self .quoting_style = quoting_style
13051340
13061341 @property
13071342 def include_header (self ):
@@ -1337,6 +1372,24 @@ cdef class WriteOptions(_Weakrefable):
13371372 def delimiter (self , value ):
13381373 deref(self .options).delimiter = _single_char(value)
13391374
1375+ @property
1376+ def quoting_style (self ):
1377+ """
1378+ Whether to quote values, and if so, which quoting style to use.
1379+ The following values are accepted:
1380+
1381+ - "needed" (default): only enclose values in quotes when needed.
1382+ - "all_valid": enclose all valid values in quotes; nulls are not quoted.
1383+ - "none": do not enclose any values in quotes; values containing
1384+ special characters (such as quotes, cell delimiters or line endings)
1385+ will raise an error.
1386+ """
1387+ return wrap_quoting_style(deref(self .options).quoting_style)
1388+
1389+ @quoting_style.setter
1390+ def quoting_style (self , value ):
1391+ deref(self .options).quoting_style = unwrap_quoting_style(value)
1392+
13401393 @staticmethod
13411394 cdef WriteOptions wrap(CCSVWriteOptions options):
13421395 out = WriteOptions()
0 commit comments