blob: 9ce53bdade75c941da1c56ae133c799e0381f6a2 [file] [log] [blame]
Skip Montanaroa16b21f2003-03-23 14:32:54 +00001/* csv module */
2
3/*
4
5This module provides the low-level underpinnings of a CSV reading/writing
6module. Users should not use this module directly, but import the csv.py
7module instead.
8
9**** For people modifying this code, please note that as of this writing
Skip Montanarodfa35fa2003-04-11 21:40:01 +000010**** (2003-03-23), it is intended that this code should work with Python
Skip Montanaroa16b21f2003-03-23 14:32:54 +000011**** 2.2.
12
Skip Montanarob4a04172003-03-20 23:29:12 +000013*/
14
Skip Montanaro7b01a832003-04-12 19:23:46 +000015#define MODULE_VERSION "1.0"
16
Skip Montanarob4a04172003-03-20 23:29:12 +000017#include "Python.h"
18#include "structmember.h"
19
Skip Montanaroa16b21f2003-03-23 14:32:54 +000020
Skip Montanarob4a04172003-03-20 23:29:12 +000021/* begin 2.2 compatibility macros */
22#ifndef PyDoc_STRVAR
23/* Define macros for inline documentation. */
24#define PyDoc_VAR(name) static char name[]
25#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
26#ifdef WITH_DOC_STRINGS
27#define PyDoc_STR(str) str
28#else
29#define PyDoc_STR(str) ""
30#endif
31#endif /* ifndef PyDoc_STRVAR */
32
33#ifndef PyMODINIT_FUNC
34# if defined(__cplusplus)
35# define PyMODINIT_FUNC extern "C" void
36# else /* __cplusplus */
37# define PyMODINIT_FUNC void
38# endif /* __cplusplus */
39#endif
Thomas Wouters2742c5e2006-04-15 17:33:14 +000040
41#ifndef Py_CLEAR
42#define Py_CLEAR(op) \
43 do { \
44 if (op) { \
45 PyObject *tmp = (PyObject *)(op); \
46 (op) = NULL; \
47 Py_DECREF(tmp); \
48 } \
49 } while (0)
50#endif
51#ifndef Py_VISIT
52
53
Skip Montanarob4a04172003-03-20 23:29:12 +000054/* end 2.2 compatibility macros */
55
Andrew McNamara37d2bdf2005-01-10 12:22:48 +000056#define IS_BASESTRING(o) \
57 PyObject_TypeCheck(o, &PyBaseString_Type)
58
Skip Montanarob4a04172003-03-20 23:29:12 +000059static PyObject *error_obj; /* CSV exception */
60static PyObject *dialects; /* Dialect registry */
Andrew McNamarae4d05c42005-01-11 07:32:02 +000061static long field_limit = 128 * 1024; /* max parsed field size */
Skip Montanarob4a04172003-03-20 23:29:12 +000062
63typedef enum {
64 START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD,
Andrew McNamaraf69d94f2005-01-13 11:30:54 +000065 IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD,
66 EAT_CRNL
Skip Montanarob4a04172003-03-20 23:29:12 +000067} ParserState;
68
69typedef enum {
70 QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE
71} QuoteStyle;
72
73typedef struct {
74 QuoteStyle style;
75 char *name;
76} StyleDesc;
77
78static StyleDesc quote_styles[] = {
79 { QUOTE_MINIMAL, "QUOTE_MINIMAL" },
80 { QUOTE_ALL, "QUOTE_ALL" },
81 { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" },
82 { QUOTE_NONE, "QUOTE_NONE" },
83 { 0 }
84};
85
86typedef struct {
87 PyObject_HEAD
88
89 int doublequote; /* is " represented by ""? */
90 char delimiter; /* field separator */
91 char quotechar; /* quote character */
92 char escapechar; /* escape character */
93 int skipinitialspace; /* ignore spaces following delimiter? */
94 PyObject *lineterminator; /* string to write between records */
Andrew McNamara1196cf12005-01-07 04:42:45 +000095 int quoting; /* style of quoting to write */
Skip Montanarob4a04172003-03-20 23:29:12 +000096
97 int strict; /* raise exception on bad CSV */
98} DialectObj;
99
100staticforward PyTypeObject Dialect_Type;
101
102typedef struct {
103 PyObject_HEAD
104
105 PyObject *input_iter; /* iterate over this for input lines */
106
107 DialectObj *dialect; /* parsing dialect */
108
109 PyObject *fields; /* field list for current record */
110 ParserState state; /* current CSV parse state */
111 char *field; /* build current field in here */
112 int field_size; /* size of allocated buffer */
113 int field_len; /* length of current field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000114 int numeric_field; /* treat field as numeric */
Andrew McNamara7f2053e2005-01-12 11:17:16 +0000115 unsigned long line_num; /* Source-file line number */
Skip Montanarob4a04172003-03-20 23:29:12 +0000116} ReaderObj;
117
118staticforward PyTypeObject Reader_Type;
119
120#define ReaderObject_Check(v) ((v)->ob_type == &Reader_Type)
121
122typedef struct {
123 PyObject_HEAD
124
125 PyObject *writeline; /* write output lines to this file */
126
127 DialectObj *dialect; /* parsing dialect */
128
129 char *rec; /* buffer for parser.join */
130 int rec_size; /* size of allocated record */
131 int rec_len; /* length of record */
132 int num_fields; /* number of fields in record */
133} WriterObj;
134
135staticforward PyTypeObject Writer_Type;
136
137/*
138 * DIALECT class
139 */
140
141static PyObject *
142get_dialect_from_registry(PyObject * name_obj)
143{
144 PyObject *dialect_obj;
145
146 dialect_obj = PyDict_GetItem(dialects, name_obj);
Andrew McNamaradbce2612005-01-10 23:17:35 +0000147 if (dialect_obj == NULL) {
148 if (!PyErr_Occurred())
149 PyErr_Format(error_obj, "unknown dialect");
150 }
151 else
152 Py_INCREF(dialect_obj);
Skip Montanarob4a04172003-03-20 23:29:12 +0000153 return dialect_obj;
154}
155
Skip Montanarob4a04172003-03-20 23:29:12 +0000156static PyObject *
157get_string(PyObject *str)
158{
159 Py_XINCREF(str);
160 return str;
161}
162
Skip Montanarob4a04172003-03-20 23:29:12 +0000163static PyObject *
164get_nullchar_as_None(char c)
165{
166 if (c == '\0') {
167 Py_INCREF(Py_None);
168 return Py_None;
169 }
170 else
171 return PyString_FromStringAndSize((char*)&c, 1);
172}
173
Skip Montanarob4a04172003-03-20 23:29:12 +0000174static PyObject *
175Dialect_get_lineterminator(DialectObj *self)
176{
177 return get_string(self->lineterminator);
178}
179
Skip Montanarob4a04172003-03-20 23:29:12 +0000180static PyObject *
181Dialect_get_escapechar(DialectObj *self)
182{
183 return get_nullchar_as_None(self->escapechar);
184}
185
Andrew McNamara1196cf12005-01-07 04:42:45 +0000186static PyObject *
187Dialect_get_quotechar(DialectObj *self)
Skip Montanarob4a04172003-03-20 23:29:12 +0000188{
Andrew McNamara1196cf12005-01-07 04:42:45 +0000189 return get_nullchar_as_None(self->quotechar);
Skip Montanarob4a04172003-03-20 23:29:12 +0000190}
191
192static PyObject *
193Dialect_get_quoting(DialectObj *self)
194{
195 return PyInt_FromLong(self->quoting);
196}
197
198static int
Andrew McNamara1196cf12005-01-07 04:42:45 +0000199_set_bool(const char *name, int *target, PyObject *src, int dflt)
Skip Montanarob4a04172003-03-20 23:29:12 +0000200{
Andrew McNamara1196cf12005-01-07 04:42:45 +0000201 if (src == NULL)
202 *target = dflt;
203 else
204 *target = PyObject_IsTrue(src);
205 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000206}
207
Andrew McNamara1196cf12005-01-07 04:42:45 +0000208static int
209_set_int(const char *name, int *target, PyObject *src, int dflt)
210{
211 if (src == NULL)
212 *target = dflt;
213 else {
214 if (!PyInt_Check(src)) {
215 PyErr_Format(PyExc_TypeError,
216 "\"%s\" must be an integer", name);
217 return -1;
218 }
219 *target = PyInt_AsLong(src);
220 }
221 return 0;
222}
223
224static int
225_set_char(const char *name, char *target, PyObject *src, char dflt)
226{
227 if (src == NULL)
228 *target = dflt;
229 else {
Andrew McNamaraa8292632005-01-10 12:25:11 +0000230 if (src == Py_None || PyString_Size(src) == 0)
Andrew McNamara1196cf12005-01-07 04:42:45 +0000231 *target = '\0';
232 else if (!PyString_Check(src) || PyString_Size(src) != 1) {
233 PyErr_Format(PyExc_TypeError,
234 "\"%s\" must be an 1-character string",
235 name);
236 return -1;
237 }
238 else {
239 char *s = PyString_AsString(src);
240 if (s == NULL)
241 return -1;
242 *target = s[0];
243 }
244 }
245 return 0;
246}
247
248static int
249_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)
250{
251 if (src == NULL)
252 *target = PyString_FromString(dflt);
253 else {
254 if (src == Py_None)
255 *target = NULL;
Andrew McNamara37d2bdf2005-01-10 12:22:48 +0000256 else if (!IS_BASESTRING(src)) {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000257 PyErr_Format(PyExc_TypeError,
258 "\"%s\" must be an string", name);
259 return -1;
Andrew McNamaradd3e6cb2005-01-07 06:46:50 +0000260 }
261 else {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000262 Py_XDECREF(*target);
263 Py_INCREF(src);
264 *target = src;
265 }
266 }
267 return 0;
268}
269
270static int
271dialect_check_quoting(int quoting)
272{
273 StyleDesc *qs = quote_styles;
274
275 for (qs = quote_styles; qs->name; qs++) {
276 if (qs->style == quoting)
277 return 0;
278 }
279 PyErr_Format(PyExc_TypeError, "bad \"quoting\" value");
280 return -1;
281}
Skip Montanarob4a04172003-03-20 23:29:12 +0000282
283#define D_OFF(x) offsetof(DialectObj, x)
284
285static struct PyMemberDef Dialect_memberlist[] = {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000286 { "delimiter", T_CHAR, D_OFF(delimiter), READONLY },
287 { "skipinitialspace", T_INT, D_OFF(skipinitialspace), READONLY },
288 { "doublequote", T_INT, D_OFF(doublequote), READONLY },
289 { "strict", T_INT, D_OFF(strict), READONLY },
Skip Montanarob4a04172003-03-20 23:29:12 +0000290 { NULL }
291};
292
293static PyGetSetDef Dialect_getsetlist[] = {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000294 { "escapechar", (getter)Dialect_get_escapechar},
295 { "lineterminator", (getter)Dialect_get_lineterminator},
296 { "quotechar", (getter)Dialect_get_quotechar},
297 { "quoting", (getter)Dialect_get_quoting},
298 {NULL},
Skip Montanarob4a04172003-03-20 23:29:12 +0000299};
300
301static void
302Dialect_dealloc(DialectObj *self)
303{
304 Py_XDECREF(self->lineterminator);
Skip Montanarob4a04172003-03-20 23:29:12 +0000305 self->ob_type->tp_free((PyObject *)self);
306}
307
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +0000308static char *dialect_kws[] = {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000309 "dialect",
310 "delimiter",
311 "doublequote",
312 "escapechar",
313 "lineterminator",
314 "quotechar",
315 "quoting",
316 "skipinitialspace",
317 "strict",
318 NULL
319};
320
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000321static PyObject *
322dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
Skip Montanarob4a04172003-03-20 23:29:12 +0000323{
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000324 DialectObj *self;
325 PyObject *ret = NULL;
326 PyObject *dialect = NULL;
Andrew McNamara1196cf12005-01-07 04:42:45 +0000327 PyObject *delimiter = NULL;
328 PyObject *doublequote = NULL;
329 PyObject *escapechar = NULL;
330 PyObject *lineterminator = NULL;
331 PyObject *quotechar = NULL;
332 PyObject *quoting = NULL;
333 PyObject *skipinitialspace = NULL;
334 PyObject *strict = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000335
Andrew McNamara1196cf12005-01-07 04:42:45 +0000336 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
337 "|OOOOOOOOO", dialect_kws,
338 &dialect,
339 &delimiter,
340 &doublequote,
341 &escapechar,
342 &lineterminator,
343 &quotechar,
344 &quoting,
345 &skipinitialspace,
346 &strict))
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000347 return NULL;
348
349 if (dialect != NULL) {
350 if (IS_BASESTRING(dialect)) {
351 dialect = get_dialect_from_registry(dialect);
352 if (dialect == NULL)
353 return NULL;
354 }
355 else
356 Py_INCREF(dialect);
357 /* Can we reuse this instance? */
358 if (PyObject_TypeCheck(dialect, &Dialect_Type) &&
359 delimiter == 0 &&
360 doublequote == 0 &&
361 escapechar == 0 &&
362 lineterminator == 0 &&
363 quotechar == 0 &&
364 quoting == 0 &&
365 skipinitialspace == 0 &&
366 strict == 0)
367 return dialect;
368 }
369
370 self = (DialectObj *)type->tp_alloc(type, 0);
371 if (self == NULL) {
372 Py_XDECREF(dialect);
373 return NULL;
374 }
375 self->lineterminator = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000376
Andrew McNamara1196cf12005-01-07 04:42:45 +0000377 Py_XINCREF(delimiter);
378 Py_XINCREF(doublequote);
379 Py_XINCREF(escapechar);
380 Py_XINCREF(lineterminator);
381 Py_XINCREF(quotechar);
382 Py_XINCREF(quoting);
383 Py_XINCREF(skipinitialspace);
384 Py_XINCREF(strict);
385 if (dialect != NULL) {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000386#define DIALECT_GETATTR(v, n) \
387 if (v == NULL) \
388 v = PyObject_GetAttrString(dialect, n)
Andrew McNamara1196cf12005-01-07 04:42:45 +0000389 DIALECT_GETATTR(delimiter, "delimiter");
390 DIALECT_GETATTR(doublequote, "doublequote");
391 DIALECT_GETATTR(escapechar, "escapechar");
392 DIALECT_GETATTR(lineterminator, "lineterminator");
393 DIALECT_GETATTR(quotechar, "quotechar");
394 DIALECT_GETATTR(quoting, "quoting");
395 DIALECT_GETATTR(skipinitialspace, "skipinitialspace");
396 DIALECT_GETATTR(strict, "strict");
397 PyErr_Clear();
Andrew McNamara1196cf12005-01-07 04:42:45 +0000398 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000399
Andrew McNamara1196cf12005-01-07 04:42:45 +0000400 /* check types and convert to C values */
401#define DIASET(meth, name, target, src, dflt) \
402 if (meth(name, target, src, dflt)) \
403 goto err
404 DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ',');
405 DIASET(_set_bool, "doublequote", &self->doublequote, doublequote, 1);
406 DIASET(_set_char, "escapechar", &self->escapechar, escapechar, 0);
407 DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n");
408 DIASET(_set_char, "quotechar", &self->quotechar, quotechar, '"');
409 DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL);
410 DIASET(_set_bool, "skipinitialspace", &self->skipinitialspace, skipinitialspace, 0);
411 DIASET(_set_bool, "strict", &self->strict, strict, 0);
Skip Montanarob4a04172003-03-20 23:29:12 +0000412
Andrew McNamara1196cf12005-01-07 04:42:45 +0000413 /* validate options */
414 if (dialect_check_quoting(self->quoting))
415 goto err;
416 if (self->delimiter == 0) {
417 PyErr_SetString(PyExc_TypeError, "delimiter must be set");
418 goto err;
419 }
Andrew McNamara5d45a8d2005-01-12 08:16:17 +0000420 if (quotechar == Py_None && quoting == NULL)
Andrew McNamara1196cf12005-01-07 04:42:45 +0000421 self->quoting = QUOTE_NONE;
422 if (self->quoting != QUOTE_NONE && self->quotechar == 0) {
423 PyErr_SetString(PyExc_TypeError,
424 "quotechar must be set if quoting enabled");
425 goto err;
426 }
427 if (self->lineterminator == 0) {
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000428 PyErr_SetString(PyExc_TypeError, "lineterminator must be set");
Andrew McNamara1196cf12005-01-07 04:42:45 +0000429 goto err;
430 }
431
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000432 ret = (PyObject *)self;
Skip Montanarod60fbd42005-06-15 01:33:30 +0000433 Py_INCREF(self);
Andrew McNamara1196cf12005-01-07 04:42:45 +0000434err:
Skip Montanarod60fbd42005-06-15 01:33:30 +0000435 Py_XDECREF(self);
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000436 Py_XDECREF(dialect);
Andrew McNamara1196cf12005-01-07 04:42:45 +0000437 Py_XDECREF(delimiter);
438 Py_XDECREF(doublequote);
439 Py_XDECREF(escapechar);
440 Py_XDECREF(lineterminator);
441 Py_XDECREF(quotechar);
442 Py_XDECREF(quoting);
443 Py_XDECREF(skipinitialspace);
444 Py_XDECREF(strict);
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000445 return ret;
Skip Montanarob4a04172003-03-20 23:29:12 +0000446}
447
448
449PyDoc_STRVAR(Dialect_Type_doc,
450"CSV dialect\n"
451"\n"
452"The Dialect type records CSV parsing and generation options.\n");
453
454static PyTypeObject Dialect_Type = {
455 PyObject_HEAD_INIT(NULL)
456 0, /* ob_size */
457 "_csv.Dialect", /* tp_name */
458 sizeof(DialectObj), /* tp_basicsize */
459 0, /* tp_itemsize */
460 /* methods */
461 (destructor)Dialect_dealloc, /* tp_dealloc */
462 (printfunc)0, /* tp_print */
463 (getattrfunc)0, /* tp_getattr */
464 (setattrfunc)0, /* tp_setattr */
465 (cmpfunc)0, /* tp_compare */
466 (reprfunc)0, /* tp_repr */
467 0, /* tp_as_number */
468 0, /* tp_as_sequence */
469 0, /* tp_as_mapping */
470 (hashfunc)0, /* tp_hash */
471 (ternaryfunc)0, /* tp_call */
472 (reprfunc)0, /* tp_str */
473 0, /* tp_getattro */
474 0, /* tp_setattro */
475 0, /* tp_as_buffer */
476 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
477 Dialect_Type_doc, /* tp_doc */
478 0, /* tp_traverse */
479 0, /* tp_clear */
480 0, /* tp_richcompare */
481 0, /* tp_weaklistoffset */
482 0, /* tp_iter */
483 0, /* tp_iternext */
Andrew McNamara1196cf12005-01-07 04:42:45 +0000484 0, /* tp_methods */
Skip Montanarob4a04172003-03-20 23:29:12 +0000485 Dialect_memberlist, /* tp_members */
486 Dialect_getsetlist, /* tp_getset */
487 0, /* tp_base */
488 0, /* tp_dict */
489 0, /* tp_descr_get */
490 0, /* tp_descr_set */
491 0, /* tp_dictoffset */
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000492 0, /* tp_init */
493 0, /* tp_alloc */
Skip Montanarob4a04172003-03-20 23:29:12 +0000494 dialect_new, /* tp_new */
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000495 0, /* tp_free */
Skip Montanarob4a04172003-03-20 23:29:12 +0000496};
497
Andrew McNamara91b97462005-01-11 01:07:23 +0000498/*
499 * Return an instance of the dialect type, given a Python instance or kwarg
500 * description of the dialect
501 */
502static PyObject *
503_call_dialect(PyObject *dialect_inst, PyObject *kwargs)
504{
505 PyObject *ctor_args;
506 PyObject *dialect;
507
508 ctor_args = Py_BuildValue(dialect_inst ? "(O)" : "()", dialect_inst);
509 if (ctor_args == NULL)
510 return NULL;
511 dialect = PyObject_Call((PyObject *)&Dialect_Type, ctor_args, kwargs);
512 Py_DECREF(ctor_args);
513 return dialect;
514}
515
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000516/*
517 * READER
518 */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000519static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000520parse_save_field(ReaderObj *self)
521{
522 PyObject *field;
523
524 field = PyString_FromStringAndSize(self->field, self->field_len);
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000525 if (field == NULL)
526 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000527 self->field_len = 0;
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000528 if (self->numeric_field) {
529 PyObject *tmp;
530
531 self->numeric_field = 0;
532 tmp = PyNumber_Float(field);
533 if (tmp == NULL) {
534 Py_DECREF(field);
535 return -1;
536 }
537 Py_DECREF(field);
538 field = tmp;
539 }
540 PyList_Append(self->fields, field);
541 Py_DECREF(field);
542 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000543}
544
545static int
546parse_grow_buff(ReaderObj *self)
547{
548 if (self->field_size == 0) {
549 self->field_size = 4096;
Andrew McNamaradcfb38c2003-06-09 05:59:23 +0000550 if (self->field != NULL)
551 PyMem_Free(self->field);
Skip Montanarob4a04172003-03-20 23:29:12 +0000552 self->field = PyMem_Malloc(self->field_size);
553 }
554 else {
555 self->field_size *= 2;
556 self->field = PyMem_Realloc(self->field, self->field_size);
557 }
558 if (self->field == NULL) {
559 PyErr_NoMemory();
560 return 0;
561 }
562 return 1;
563}
564
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000565static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000566parse_add_char(ReaderObj *self, char c)
567{
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000568 if (self->field_len >= field_limit) {
569 PyErr_Format(error_obj, "field larger than field limit (%ld)",
570 field_limit);
571 return -1;
572 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000573 if (self->field_len == self->field_size && !parse_grow_buff(self))
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000574 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000575 self->field[self->field_len++] = c;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000576 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000577}
578
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000579static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000580parse_process_char(ReaderObj *self, char c)
581{
582 DialectObj *dialect = self->dialect;
583
584 switch (self->state) {
585 case START_RECORD:
586 /* start of record */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000587 if (c == '\0')
Skip Montanarob4a04172003-03-20 23:29:12 +0000588 /* empty line - return [] */
589 break;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000590 else if (c == '\n' || c == '\r') {
591 self->state = EAT_CRNL;
592 break;
593 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000594 /* normal character - handle as START_FIELD */
595 self->state = START_FIELD;
596 /* fallthru */
597 case START_FIELD:
598 /* expecting field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000599 if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000600 /* save empty field - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000601 if (parse_save_field(self) < 0)
602 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000603 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000604 }
Andrew McNamara1196cf12005-01-07 04:42:45 +0000605 else if (c == dialect->quotechar &&
606 dialect->quoting != QUOTE_NONE) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000607 /* start quoted field */
608 self->state = IN_QUOTED_FIELD;
609 }
610 else if (c == dialect->escapechar) {
611 /* possible escaped character */
612 self->state = ESCAPED_CHAR;
613 }
614 else if (c == ' ' && dialect->skipinitialspace)
615 /* ignore space at start of field */
616 ;
617 else if (c == dialect->delimiter) {
618 /* save empty field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000619 if (parse_save_field(self) < 0)
620 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000621 }
622 else {
623 /* begin new unquoted field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000624 if (dialect->quoting == QUOTE_NONNUMERIC)
625 self->numeric_field = 1;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000626 if (parse_add_char(self, c) < 0)
627 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000628 self->state = IN_FIELD;
629 }
630 break;
631
632 case ESCAPED_CHAR:
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000633 if (c == '\0')
634 c = '\n';
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000635 if (parse_add_char(self, c) < 0)
636 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000637 self->state = IN_FIELD;
638 break;
639
640 case IN_FIELD:
641 /* in unquoted field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000642 if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000643 /* end of line - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000644 if (parse_save_field(self) < 0)
645 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000646 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000647 }
648 else if (c == dialect->escapechar) {
649 /* possible escaped character */
650 self->state = ESCAPED_CHAR;
651 }
652 else if (c == dialect->delimiter) {
653 /* save field - wait for new field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000654 if (parse_save_field(self) < 0)
655 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000656 self->state = START_FIELD;
657 }
658 else {
659 /* normal character - save in field */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000660 if (parse_add_char(self, c) < 0)
661 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000662 }
663 break;
664
665 case IN_QUOTED_FIELD:
666 /* in quoted field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000667 if (c == '\0')
668 ;
Skip Montanarob4a04172003-03-20 23:29:12 +0000669 else if (c == dialect->escapechar) {
670 /* Possible escape character */
671 self->state = ESCAPE_IN_QUOTED_FIELD;
672 }
Andrew McNamara1196cf12005-01-07 04:42:45 +0000673 else if (c == dialect->quotechar &&
674 dialect->quoting != QUOTE_NONE) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000675 if (dialect->doublequote) {
676 /* doublequote; " represented by "" */
677 self->state = QUOTE_IN_QUOTED_FIELD;
678 }
679 else {
680 /* end of quote part of field */
681 self->state = IN_FIELD;
682 }
683 }
684 else {
685 /* normal character - save in field */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000686 if (parse_add_char(self, c) < 0)
687 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000688 }
689 break;
690
691 case ESCAPE_IN_QUOTED_FIELD:
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000692 if (c == '\0')
693 c = '\n';
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000694 if (parse_add_char(self, c) < 0)
695 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000696 self->state = IN_QUOTED_FIELD;
697 break;
698
699 case QUOTE_IN_QUOTED_FIELD:
700 /* doublequote - seen a quote in an quoted field */
701 if (dialect->quoting != QUOTE_NONE &&
702 c == dialect->quotechar) {
703 /* save "" as " */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000704 if (parse_add_char(self, c) < 0)
705 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000706 self->state = IN_QUOTED_FIELD;
707 }
708 else if (c == dialect->delimiter) {
709 /* save field - wait for new field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000710 if (parse_save_field(self) < 0)
711 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000712 self->state = START_FIELD;
713 }
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000714 else if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000715 /* end of line - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000716 if (parse_save_field(self) < 0)
717 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000718 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000719 }
720 else if (!dialect->strict) {
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000721 if (parse_add_char(self, c) < 0)
722 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000723 self->state = IN_FIELD;
724 }
725 else {
726 /* illegal */
Andrew McNamara5cfd8372005-01-12 11:39:50 +0000727 PyErr_Format(error_obj, "'%c' expected after '%c'",
Skip Montanarob4a04172003-03-20 23:29:12 +0000728 dialect->delimiter,
729 dialect->quotechar);
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000730 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000731 }
732 break;
733
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000734 case EAT_CRNL:
735 if (c == '\n' || c == '\r')
736 ;
737 else if (c == '\0')
738 self->state = START_RECORD;
739 else {
740 PyErr_Format(error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?");
741 return -1;
742 }
743 break;
744
Skip Montanarob4a04172003-03-20 23:29:12 +0000745 }
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000746 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000747}
748
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000749static int
750parse_reset(ReaderObj *self)
751{
752 Py_XDECREF(self->fields);
753 self->fields = PyList_New(0);
754 if (self->fields == NULL)
755 return -1;
756 self->field_len = 0;
757 self->state = START_RECORD;
758 self->numeric_field = 0;
759 return 0;
760}
Skip Montanarob4a04172003-03-20 23:29:12 +0000761
762static PyObject *
Skip Montanarob4a04172003-03-20 23:29:12 +0000763Reader_iternext(ReaderObj *self)
764{
765 PyObject *lineobj;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000766 PyObject *fields = NULL;
767 char *line, c;
768 int linelen;
Skip Montanarob4a04172003-03-20 23:29:12 +0000769
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000770 if (parse_reset(self) < 0)
771 return NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000772 do {
773 lineobj = PyIter_Next(self->input_iter);
774 if (lineobj == NULL) {
775 /* End of input OR exception */
776 if (!PyErr_Occurred() && self->field_len != 0)
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000777 PyErr_Format(error_obj,
778 "newline inside string");
Skip Montanarob4a04172003-03-20 23:29:12 +0000779 return NULL;
780 }
Andrew McNamara7f2053e2005-01-12 11:17:16 +0000781 ++self->line_num;
Skip Montanarob4a04172003-03-20 23:29:12 +0000782
Skip Montanarob4a04172003-03-20 23:29:12 +0000783 line = PyString_AsString(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000784 linelen = PyString_Size(lineobj);
Skip Montanarob4a04172003-03-20 23:29:12 +0000785
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000786 if (line == NULL || linelen < 0) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000787 Py_DECREF(lineobj);
788 return NULL;
789 }
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000790 while (linelen--) {
791 c = *line++;
792 if (c == '\0') {
793 Py_DECREF(lineobj);
794 PyErr_Format(error_obj,
795 "line contains NULL byte");
796 goto err;
797 }
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000798 if (parse_process_char(self, c) < 0) {
799 Py_DECREF(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000800 goto err;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000801 }
802 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000803 Py_DECREF(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000804 if (parse_process_char(self, 0) < 0)
805 goto err;
Skip Montanarob4a04172003-03-20 23:29:12 +0000806 } while (self->state != START_RECORD);
807
808 fields = self->fields;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000809 self->fields = NULL;
810err:
Skip Montanarob4a04172003-03-20 23:29:12 +0000811 return fields;
812}
813
814static void
815Reader_dealloc(ReaderObj *self)
816{
Andrew McNamara77ead872005-01-10 02:09:41 +0000817 PyObject_GC_UnTrack(self);
Skip Montanarob4a04172003-03-20 23:29:12 +0000818 Py_XDECREF(self->dialect);
819 Py_XDECREF(self->input_iter);
820 Py_XDECREF(self->fields);
Andrew McNamaradcfb38c2003-06-09 05:59:23 +0000821 if (self->field != NULL)
822 PyMem_Free(self->field);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000823 PyObject_GC_Del(self);
824}
825
826static int
827Reader_traverse(ReaderObj *self, visitproc visit, void *arg)
828{
829 int err;
830#define VISIT(SLOT) \
831 if (SLOT) { \
832 err = visit((PyObject *)(SLOT), arg); \
833 if (err) \
834 return err; \
835 }
836 VISIT(self->dialect);
837 VISIT(self->input_iter);
838 VISIT(self->fields);
839 return 0;
840}
841
842static int
843Reader_clear(ReaderObj *self)
844{
Thomas Woutersedf17d82006-04-15 17:28:34 +0000845 Py_CLEAR(self->dialect);
846 Py_CLEAR(self->input_iter);
847 Py_CLEAR(self->fields);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000848 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000849}
850
851PyDoc_STRVAR(Reader_Type_doc,
852"CSV reader\n"
853"\n"
854"Reader objects are responsible for reading and parsing tabular data\n"
855"in CSV format.\n"
856);
857
858static struct PyMethodDef Reader_methods[] = {
859 { NULL, NULL }
860};
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000861#define R_OFF(x) offsetof(ReaderObj, x)
862
863static struct PyMemberDef Reader_memberlist[] = {
864 { "dialect", T_OBJECT, R_OFF(dialect), RO },
865 { "line_num", T_ULONG, R_OFF(line_num), RO },
866 { NULL }
867};
868
Skip Montanarob4a04172003-03-20 23:29:12 +0000869
870static PyTypeObject Reader_Type = {
871 PyObject_HEAD_INIT(NULL)
872 0, /*ob_size*/
873 "_csv.reader", /*tp_name*/
874 sizeof(ReaderObj), /*tp_basicsize*/
875 0, /*tp_itemsize*/
876 /* methods */
877 (destructor)Reader_dealloc, /*tp_dealloc*/
878 (printfunc)0, /*tp_print*/
879 (getattrfunc)0, /*tp_getattr*/
880 (setattrfunc)0, /*tp_setattr*/
881 (cmpfunc)0, /*tp_compare*/
882 (reprfunc)0, /*tp_repr*/
883 0, /*tp_as_number*/
884 0, /*tp_as_sequence*/
885 0, /*tp_as_mapping*/
886 (hashfunc)0, /*tp_hash*/
887 (ternaryfunc)0, /*tp_call*/
888 (reprfunc)0, /*tp_str*/
889 0, /*tp_getattro*/
890 0, /*tp_setattro*/
891 0, /*tp_as_buffer*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000892 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
893 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000894 Reader_Type_doc, /*tp_doc*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000895 (traverseproc)Reader_traverse, /*tp_traverse*/
896 (inquiry)Reader_clear, /*tp_clear*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000897 0, /*tp_richcompare*/
898 0, /*tp_weaklistoffset*/
Andrew McNamara575a00b2005-01-06 02:25:41 +0000899 PyObject_SelfIter, /*tp_iter*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000900 (getiterfunc)Reader_iternext, /*tp_iternext*/
901 Reader_methods, /*tp_methods*/
902 Reader_memberlist, /*tp_members*/
903 0, /*tp_getset*/
904
905};
906
907static PyObject *
908csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
909{
Andrew McNamara91b97462005-01-11 01:07:23 +0000910 PyObject * iterator, * dialect = NULL;
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000911 ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +0000912
913 if (!self)
914 return NULL;
915
916 self->dialect = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000917 self->fields = NULL;
918 self->input_iter = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000919 self->field = NULL;
920 self->field_size = 0;
Andrew McNamara7f2053e2005-01-12 11:17:16 +0000921 self->line_num = 0;
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000922
923 if (parse_reset(self) < 0) {
924 Py_DECREF(self);
925 return NULL;
926 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000927
Raymond Hettinger1761a7c2004-06-20 04:23:19 +0000928 if (!PyArg_UnpackTuple(args, "", 1, 2, &iterator, &dialect)) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000929 Py_DECREF(self);
930 return NULL;
931 }
932 self->input_iter = PyObject_GetIter(iterator);
933 if (self->input_iter == NULL) {
934 PyErr_SetString(PyExc_TypeError,
935 "argument 1 must be an iterator");
936 Py_DECREF(self);
937 return NULL;
938 }
Andrew McNamara91b97462005-01-11 01:07:23 +0000939 self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
Skip Montanarob4a04172003-03-20 23:29:12 +0000940 if (self->dialect == NULL) {
941 Py_DECREF(self);
942 return NULL;
943 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000944
Andrew McNamara77ead872005-01-10 02:09:41 +0000945 PyObject_GC_Track(self);
Skip Montanarob4a04172003-03-20 23:29:12 +0000946 return (PyObject *)self;
947}
948
949/*
950 * WRITER
951 */
952/* ---------------------------------------------------------------- */
953static void
954join_reset(WriterObj *self)
955{
956 self->rec_len = 0;
957 self->num_fields = 0;
958}
959
960#define MEM_INCR 32768
961
962/* Calculate new record length or append field to record. Return new
963 * record length.
964 */
965static int
966join_append_data(WriterObj *self, char *field, int quote_empty,
967 int *quoted, int copy_phase)
968{
969 DialectObj *dialect = self->dialect;
970 int i, rec_len;
Andrew McNamarac89f2842005-01-12 07:44:42 +0000971 char *lineterm;
972
973#define ADDCH(c) \
974 do {\
975 if (copy_phase) \
976 self->rec[rec_len] = c;\
977 rec_len++;\
978 } while(0)
979
980 lineterm = PyString_AsString(dialect->lineterminator);
981 if (lineterm == NULL)
982 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000983
984 rec_len = self->rec_len;
985
Andrew McNamarac89f2842005-01-12 07:44:42 +0000986 /* If this is not the first field we need a field separator */
987 if (self->num_fields > 0)
988 ADDCH(dialect->delimiter);
989
990 /* Handle preceding quote */
991 if (copy_phase && *quoted)
992 ADDCH(dialect->quotechar);
993
994 /* Copy/count field data */
Skip Montanarob4a04172003-03-20 23:29:12 +0000995 for (i = 0;; i++) {
996 char c = field[i];
Andrew McNamarac89f2842005-01-12 07:44:42 +0000997 int want_escape = 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000998
999 if (c == '\0')
1000 break;
Skip Montanarob4a04172003-03-20 23:29:12 +00001001
Andrew McNamarac89f2842005-01-12 07:44:42 +00001002 if (c == dialect->delimiter ||
1003 c == dialect->escapechar ||
1004 c == dialect->quotechar ||
1005 strchr(lineterm, c)) {
1006 if (dialect->quoting == QUOTE_NONE)
1007 want_escape = 1;
Skip Montanarob4a04172003-03-20 23:29:12 +00001008 else {
Andrew McNamarac89f2842005-01-12 07:44:42 +00001009 if (c == dialect->quotechar) {
1010 if (dialect->doublequote)
1011 ADDCH(dialect->quotechar);
1012 else
1013 want_escape = 1;
1014 }
1015 if (!want_escape)
1016 *quoted = 1;
1017 }
1018 if (want_escape) {
1019 if (!dialect->escapechar) {
1020 PyErr_Format(error_obj,
1021 "need to escape, but no escapechar set");
1022 return -1;
1023 }
1024 ADDCH(dialect->escapechar);
Skip Montanarob4a04172003-03-20 23:29:12 +00001025 }
1026 }
1027 /* Copy field character into record buffer.
1028 */
Andrew McNamarac89f2842005-01-12 07:44:42 +00001029 ADDCH(c);
Skip Montanarob4a04172003-03-20 23:29:12 +00001030 }
1031
1032 /* If field is empty check if it needs to be quoted.
1033 */
1034 if (i == 0 && quote_empty) {
1035 if (dialect->quoting == QUOTE_NONE) {
1036 PyErr_Format(error_obj,
1037 "single empty field record must be quoted");
1038 return -1;
Andrew McNamaradd3e6cb2005-01-07 06:46:50 +00001039 }
1040 else
Skip Montanarob4a04172003-03-20 23:29:12 +00001041 *quoted = 1;
1042 }
1043
Skip Montanarob4a04172003-03-20 23:29:12 +00001044 if (*quoted) {
1045 if (copy_phase)
Andrew McNamarac89f2842005-01-12 07:44:42 +00001046 ADDCH(dialect->quotechar);
Skip Montanarob4a04172003-03-20 23:29:12 +00001047 else
Andrew McNamarac89f2842005-01-12 07:44:42 +00001048 rec_len += 2;
Skip Montanarob4a04172003-03-20 23:29:12 +00001049 }
Skip Montanarob4a04172003-03-20 23:29:12 +00001050 return rec_len;
Andrew McNamarac89f2842005-01-12 07:44:42 +00001051#undef ADDCH
Skip Montanarob4a04172003-03-20 23:29:12 +00001052}
1053
1054static int
1055join_check_rec_size(WriterObj *self, int rec_len)
1056{
1057 if (rec_len > self->rec_size) {
1058 if (self->rec_size == 0) {
1059 self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
Andrew McNamaradcfb38c2003-06-09 05:59:23 +00001060 if (self->rec != NULL)
1061 PyMem_Free(self->rec);
Skip Montanarob4a04172003-03-20 23:29:12 +00001062 self->rec = PyMem_Malloc(self->rec_size);
1063 }
1064 else {
1065 char *old_rec = self->rec;
1066
1067 self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
1068 self->rec = PyMem_Realloc(self->rec, self->rec_size);
1069 if (self->rec == NULL)
1070 PyMem_Free(old_rec);
1071 }
1072 if (self->rec == NULL) {
1073 PyErr_NoMemory();
1074 return 0;
1075 }
1076 }
1077 return 1;
1078}
1079
1080static int
1081join_append(WriterObj *self, char *field, int *quoted, int quote_empty)
1082{
1083 int rec_len;
1084
1085 rec_len = join_append_data(self, field, quote_empty, quoted, 0);
1086 if (rec_len < 0)
1087 return 0;
1088
1089 /* grow record buffer if necessary */
1090 if (!join_check_rec_size(self, rec_len))
1091 return 0;
1092
1093 self->rec_len = join_append_data(self, field, quote_empty, quoted, 1);
1094 self->num_fields++;
1095
1096 return 1;
1097}
1098
1099static int
1100join_append_lineterminator(WriterObj *self)
1101{
1102 int terminator_len;
Andrew McNamaracf0fd5a2005-01-12 01:16:35 +00001103 char *terminator;
Skip Montanarob4a04172003-03-20 23:29:12 +00001104
1105 terminator_len = PyString_Size(self->dialect->lineterminator);
1106
1107 /* grow record buffer if necessary */
1108 if (!join_check_rec_size(self, self->rec_len + terminator_len))
1109 return 0;
1110
Andrew McNamaracf0fd5a2005-01-12 01:16:35 +00001111 terminator = PyString_AsString(self->dialect->lineterminator);
1112 if (terminator == NULL)
1113 return 0;
1114 memmove(self->rec + self->rec_len, terminator, terminator_len);
Skip Montanarob4a04172003-03-20 23:29:12 +00001115 self->rec_len += terminator_len;
1116
1117 return 1;
1118}
1119
1120PyDoc_STRVAR(csv_writerow_doc,
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001121"writerow(sequence)\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001122"\n"
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001123"Construct and write a CSV record from a sequence of fields. Non-string\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001124"elements will be converted to string.");
1125
1126static PyObject *
1127csv_writerow(WriterObj *self, PyObject *seq)
1128{
1129 DialectObj *dialect = self->dialect;
1130 int len, i;
1131
1132 if (!PySequence_Check(seq))
1133 return PyErr_Format(error_obj, "sequence expected");
1134
1135 len = PySequence_Length(seq);
1136 if (len < 0)
1137 return NULL;
1138
1139 /* Join all fields in internal buffer.
1140 */
1141 join_reset(self);
1142 for (i = 0; i < len; i++) {
1143 PyObject *field;
1144 int append_ok;
1145 int quoted;
1146
1147 field = PySequence_GetItem(seq, i);
1148 if (field == NULL)
1149 return NULL;
1150
Andrew McNamarac89f2842005-01-12 07:44:42 +00001151 switch (dialect->quoting) {
1152 case QUOTE_NONNUMERIC:
1153 quoted = !PyNumber_Check(field);
1154 break;
1155 case QUOTE_ALL:
1156 quoted = 1;
1157 break;
1158 default:
1159 quoted = 0;
1160 break;
Skip Montanarob4a04172003-03-20 23:29:12 +00001161 }
1162
1163 if (PyString_Check(field)) {
Skip Montanaro577c7a72003-04-12 19:17:14 +00001164 append_ok = join_append(self,
1165 PyString_AS_STRING(field),
Skip Montanarob4a04172003-03-20 23:29:12 +00001166 &quoted, len == 1);
1167 Py_DECREF(field);
1168 }
1169 else if (field == Py_None) {
1170 append_ok = join_append(self, "", &quoted, len == 1);
1171 Py_DECREF(field);
1172 }
1173 else {
1174 PyObject *str;
1175
1176 str = PyObject_Str(field);
1177 Py_DECREF(field);
1178 if (str == NULL)
1179 return NULL;
1180
Skip Montanaro577c7a72003-04-12 19:17:14 +00001181 append_ok = join_append(self, PyString_AS_STRING(str),
Skip Montanarob4a04172003-03-20 23:29:12 +00001182 &quoted, len == 1);
1183 Py_DECREF(str);
1184 }
1185 if (!append_ok)
1186 return NULL;
1187 }
1188
1189 /* Add line terminator.
1190 */
1191 if (!join_append_lineterminator(self))
1192 return 0;
1193
1194 return PyObject_CallFunction(self->writeline,
1195 "(s#)", self->rec, self->rec_len);
1196}
1197
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001198PyDoc_STRVAR(csv_writerows_doc,
1199"writerows(sequence of sequences)\n"
1200"\n"
1201"Construct and write a series of sequences to a csv file. Non-string\n"
1202"elements will be converted to string.");
1203
Skip Montanarob4a04172003-03-20 23:29:12 +00001204static PyObject *
1205csv_writerows(WriterObj *self, PyObject *seqseq)
1206{
1207 PyObject *row_iter, *row_obj, *result;
1208
1209 row_iter = PyObject_GetIter(seqseq);
1210 if (row_iter == NULL) {
1211 PyErr_SetString(PyExc_TypeError,
Skip Montanaro98f16e02003-04-11 23:10:13 +00001212 "writerows() argument must be iterable");
Skip Montanarob4a04172003-03-20 23:29:12 +00001213 return NULL;
1214 }
1215 while ((row_obj = PyIter_Next(row_iter))) {
1216 result = csv_writerow(self, row_obj);
1217 Py_DECREF(row_obj);
1218 if (!result) {
1219 Py_DECREF(row_iter);
1220 return NULL;
1221 }
1222 else
1223 Py_DECREF(result);
1224 }
1225 Py_DECREF(row_iter);
1226 if (PyErr_Occurred())
1227 return NULL;
1228 Py_INCREF(Py_None);
1229 return Py_None;
1230}
1231
1232static struct PyMethodDef Writer_methods[] = {
1233 { "writerow", (PyCFunction)csv_writerow, METH_O, csv_writerow_doc},
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001234 { "writerows", (PyCFunction)csv_writerows, METH_O, csv_writerows_doc},
Skip Montanarob4a04172003-03-20 23:29:12 +00001235 { NULL, NULL }
1236};
1237
1238#define W_OFF(x) offsetof(WriterObj, x)
1239
1240static struct PyMemberDef Writer_memberlist[] = {
1241 { "dialect", T_OBJECT, W_OFF(dialect), RO },
1242 { NULL }
1243};
1244
1245static void
1246Writer_dealloc(WriterObj *self)
1247{
Andrew McNamara77ead872005-01-10 02:09:41 +00001248 PyObject_GC_UnTrack(self);
Skip Montanarob4a04172003-03-20 23:29:12 +00001249 Py_XDECREF(self->dialect);
1250 Py_XDECREF(self->writeline);
Andrew McNamaradcfb38c2003-06-09 05:59:23 +00001251 if (self->rec != NULL)
1252 PyMem_Free(self->rec);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001253 PyObject_GC_Del(self);
1254}
1255
1256static int
1257Writer_traverse(WriterObj *self, visitproc visit, void *arg)
1258{
1259 int err;
1260#define VISIT(SLOT) \
1261 if (SLOT) { \
1262 err = visit((PyObject *)(SLOT), arg); \
1263 if (err) \
1264 return err; \
1265 }
1266 VISIT(self->dialect);
1267 VISIT(self->writeline);
1268 return 0;
1269}
1270
1271static int
1272Writer_clear(WriterObj *self)
1273{
Thomas Woutersedf17d82006-04-15 17:28:34 +00001274 Py_CLEAR(self->dialect);
1275 Py_CLEAR(self->writeline);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001276 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +00001277}
1278
1279PyDoc_STRVAR(Writer_Type_doc,
1280"CSV writer\n"
1281"\n"
1282"Writer objects are responsible for generating tabular data\n"
1283"in CSV format from sequence input.\n"
1284);
1285
1286static PyTypeObject Writer_Type = {
1287 PyObject_HEAD_INIT(NULL)
1288 0, /*ob_size*/
1289 "_csv.writer", /*tp_name*/
1290 sizeof(WriterObj), /*tp_basicsize*/
1291 0, /*tp_itemsize*/
1292 /* methods */
1293 (destructor)Writer_dealloc, /*tp_dealloc*/
1294 (printfunc)0, /*tp_print*/
1295 (getattrfunc)0, /*tp_getattr*/
1296 (setattrfunc)0, /*tp_setattr*/
1297 (cmpfunc)0, /*tp_compare*/
1298 (reprfunc)0, /*tp_repr*/
1299 0, /*tp_as_number*/
1300 0, /*tp_as_sequence*/
1301 0, /*tp_as_mapping*/
1302 (hashfunc)0, /*tp_hash*/
1303 (ternaryfunc)0, /*tp_call*/
1304 (reprfunc)0, /*tp_str*/
1305 0, /*tp_getattro*/
1306 0, /*tp_setattro*/
1307 0, /*tp_as_buffer*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001308 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1309 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Skip Montanarob4a04172003-03-20 23:29:12 +00001310 Writer_Type_doc,
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001311 (traverseproc)Writer_traverse, /*tp_traverse*/
1312 (inquiry)Writer_clear, /*tp_clear*/
Skip Montanarob4a04172003-03-20 23:29:12 +00001313 0, /*tp_richcompare*/
1314 0, /*tp_weaklistoffset*/
1315 (getiterfunc)0, /*tp_iter*/
1316 (getiterfunc)0, /*tp_iternext*/
1317 Writer_methods, /*tp_methods*/
1318 Writer_memberlist, /*tp_members*/
1319 0, /*tp_getset*/
1320};
1321
1322static PyObject *
1323csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)
1324{
Andrew McNamara91b97462005-01-11 01:07:23 +00001325 PyObject * output_file, * dialect = NULL;
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001326 WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +00001327
1328 if (!self)
1329 return NULL;
1330
1331 self->dialect = NULL;
1332 self->writeline = NULL;
1333
1334 self->rec = NULL;
1335 self->rec_size = 0;
1336 self->rec_len = 0;
1337 self->num_fields = 0;
1338
Raymond Hettinger1761a7c2004-06-20 04:23:19 +00001339 if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) {
Skip Montanarob4a04172003-03-20 23:29:12 +00001340 Py_DECREF(self);
1341 return NULL;
1342 }
1343 self->writeline = PyObject_GetAttrString(output_file, "write");
1344 if (self->writeline == NULL || !PyCallable_Check(self->writeline)) {
1345 PyErr_SetString(PyExc_TypeError,
Andrew McNamara5cfd8372005-01-12 11:39:50 +00001346 "argument 1 must have a \"write\" method");
Skip Montanarob4a04172003-03-20 23:29:12 +00001347 Py_DECREF(self);
1348 return NULL;
1349 }
Andrew McNamara91b97462005-01-11 01:07:23 +00001350 self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
Skip Montanarob4a04172003-03-20 23:29:12 +00001351 if (self->dialect == NULL) {
1352 Py_DECREF(self);
1353 return NULL;
1354 }
Andrew McNamara77ead872005-01-10 02:09:41 +00001355 PyObject_GC_Track(self);
Skip Montanarob4a04172003-03-20 23:29:12 +00001356 return (PyObject *)self;
1357}
1358
1359/*
1360 * DIALECT REGISTRY
1361 */
1362static PyObject *
1363csv_list_dialects(PyObject *module, PyObject *args)
1364{
1365 return PyDict_Keys(dialects);
1366}
1367
1368static PyObject *
Andrew McNamara86625972005-01-11 01:28:33 +00001369csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs)
Skip Montanarob4a04172003-03-20 23:29:12 +00001370{
Andrew McNamara86625972005-01-11 01:28:33 +00001371 PyObject *name_obj, *dialect_obj = NULL;
1372 PyObject *dialect;
Skip Montanarob4a04172003-03-20 23:29:12 +00001373
Andrew McNamara86625972005-01-11 01:28:33 +00001374 if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj))
Skip Montanarob4a04172003-03-20 23:29:12 +00001375 return NULL;
Andrew McNamara37d2bdf2005-01-10 12:22:48 +00001376 if (!IS_BASESTRING(name_obj)) {
Skip Montanarob4a04172003-03-20 23:29:12 +00001377 PyErr_SetString(PyExc_TypeError,
1378 "dialect name must be a string or unicode");
1379 return NULL;
1380 }
Andrew McNamara86625972005-01-11 01:28:33 +00001381 dialect = _call_dialect(dialect_obj, kwargs);
1382 if (dialect == NULL)
1383 return NULL;
1384 if (PyDict_SetItem(dialects, name_obj, dialect) < 0) {
1385 Py_DECREF(dialect);
Skip Montanarob4a04172003-03-20 23:29:12 +00001386 return NULL;
1387 }
Andrew McNamara86625972005-01-11 01:28:33 +00001388 Py_DECREF(dialect);
Skip Montanarob4a04172003-03-20 23:29:12 +00001389 Py_INCREF(Py_None);
1390 return Py_None;
1391}
1392
1393static PyObject *
Skip Montanaro577c7a72003-04-12 19:17:14 +00001394csv_unregister_dialect(PyObject *module, PyObject *name_obj)
Skip Montanarob4a04172003-03-20 23:29:12 +00001395{
Skip Montanarob4a04172003-03-20 23:29:12 +00001396 if (PyDict_DelItem(dialects, name_obj) < 0)
1397 return PyErr_Format(error_obj, "unknown dialect");
1398 Py_INCREF(Py_None);
1399 return Py_None;
1400}
1401
1402static PyObject *
Skip Montanaro577c7a72003-04-12 19:17:14 +00001403csv_get_dialect(PyObject *module, PyObject *name_obj)
Skip Montanarob4a04172003-03-20 23:29:12 +00001404{
Skip Montanarob4a04172003-03-20 23:29:12 +00001405 return get_dialect_from_registry(name_obj);
1406}
1407
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001408static PyObject *
Andrew McNamara31d88962005-01-12 03:45:10 +00001409csv_field_size_limit(PyObject *module, PyObject *args)
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001410{
1411 PyObject *new_limit = NULL;
1412 long old_limit = field_limit;
1413
Andrew McNamara31d88962005-01-12 03:45:10 +00001414 if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit))
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001415 return NULL;
1416 if (new_limit != NULL) {
1417 if (!PyInt_Check(new_limit)) {
1418 PyErr_Format(PyExc_TypeError,
1419 "limit must be an integer");
1420 return NULL;
1421 }
1422 field_limit = PyInt_AsLong(new_limit);
1423 }
1424 return PyInt_FromLong(old_limit);
1425}
1426
Skip Montanarob4a04172003-03-20 23:29:12 +00001427/*
1428 * MODULE
1429 */
1430
1431PyDoc_STRVAR(csv_module_doc,
1432"CSV parsing and writing.\n"
1433"\n"
1434"This module provides classes that assist in the reading and writing\n"
1435"of Comma Separated Value (CSV) files, and implements the interface\n"
1436"described by PEP 305. Although many CSV files are simple to parse,\n"
1437"the format is not formally defined by a stable specification and\n"
1438"is subtle enough that parsing lines of a CSV file with something\n"
1439"like line.split(\",\") is bound to fail. The module supports three\n"
1440"basic APIs: reading, writing, and registration of dialects.\n"
1441"\n"
1442"\n"
1443"DIALECT REGISTRATION:\n"
1444"\n"
1445"Readers and writers support a dialect argument, which is a convenient\n"
1446"handle on a group of settings. When the dialect argument is a string,\n"
1447"it identifies one of the dialects previously registered with the module.\n"
1448"If it is a class or instance, the attributes of the argument are used as\n"
1449"the settings for the reader or writer:\n"
1450"\n"
1451" class excel:\n"
1452" delimiter = ','\n"
1453" quotechar = '\"'\n"
1454" escapechar = None\n"
1455" doublequote = True\n"
1456" skipinitialspace = False\n"
Johannes Gijsbers8d3b9dd2004-08-15 12:23:10 +00001457" lineterminator = '\\r\\n'\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001458" quoting = QUOTE_MINIMAL\n"
1459"\n"
1460"SETTINGS:\n"
1461"\n"
1462" * quotechar - specifies a one-character string to use as the \n"
1463" quoting character. It defaults to '\"'.\n"
1464" * delimiter - specifies a one-character string to use as the \n"
1465" field separator. It defaults to ','.\n"
1466" * skipinitialspace - specifies how to interpret whitespace which\n"
1467" immediately follows a delimiter. It defaults to False, which\n"
1468" means that whitespace immediately following a delimiter is part\n"
1469" of the following field.\n"
1470" * lineterminator - specifies the character sequence which should \n"
1471" terminate rows.\n"
1472" * quoting - controls when quotes should be generated by the writer.\n"
1473" It can take on any of the following module constants:\n"
1474"\n"
1475" csv.QUOTE_MINIMAL means only when required, for example, when a\n"
1476" field contains either the quotechar or the delimiter\n"
1477" csv.QUOTE_ALL means that quotes are always placed around fields.\n"
1478" csv.QUOTE_NONNUMERIC means that quotes are always placed around\n"
Skip Montanaro148eb6a2003-12-02 18:57:47 +00001479" fields which do not parse as integers or floating point\n"
1480" numbers.\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001481" csv.QUOTE_NONE means that quotes are never placed around fields.\n"
1482" * escapechar - specifies a one-character string used to escape \n"
1483" the delimiter when quoting is set to QUOTE_NONE.\n"
1484" * doublequote - controls the handling of quotes inside fields. When\n"
1485" True, two consecutive quotes are interpreted as one during read,\n"
1486" and when writing, each quote character embedded in the data is\n"
1487" written as two quotes\n");
1488
1489PyDoc_STRVAR(csv_reader_doc,
1490" csv_reader = reader(iterable [, dialect='excel']\n"
1491" [optional keyword args])\n"
1492" for row in csv_reader:\n"
1493" process(row)\n"
1494"\n"
1495"The \"iterable\" argument can be any object that returns a line\n"
1496"of input for each iteration, such as a file object or a list. The\n"
1497"optional \"dialect\" parameter is discussed below. The function\n"
1498"also accepts optional keyword arguments which override settings\n"
1499"provided by the dialect.\n"
1500"\n"
1501"The returned object is an iterator. Each iteration returns a row\n"
Johannes Gijsbers8d3b9dd2004-08-15 12:23:10 +00001502"of the CSV file (which can span multiple input lines):\n");
Skip Montanarob4a04172003-03-20 23:29:12 +00001503
1504PyDoc_STRVAR(csv_writer_doc,
1505" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1506" [optional keyword args])\n"
Fredrik Lundh4aaaa492006-04-04 16:51:13 +00001507" for row in sequence:\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001508" csv_writer.writerow(row)\n"
1509"\n"
1510" [or]\n"
1511"\n"
1512" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1513" [optional keyword args])\n"
1514" csv_writer.writerows(rows)\n"
1515"\n"
1516"The \"fileobj\" argument can be any object that supports the file API.\n");
1517
1518PyDoc_STRVAR(csv_list_dialects_doc,
1519"Return a list of all know dialect names.\n"
1520" names = csv.list_dialects()");
1521
1522PyDoc_STRVAR(csv_get_dialect_doc,
1523"Return the dialect instance associated with name.\n"
1524" dialect = csv.get_dialect(name)");
1525
1526PyDoc_STRVAR(csv_register_dialect_doc,
1527"Create a mapping from a string name to a dialect class.\n"
1528" dialect = csv.register_dialect(name, dialect)");
1529
1530PyDoc_STRVAR(csv_unregister_dialect_doc,
1531"Delete the name/dialect mapping associated with a string name.\n"
1532" csv.unregister_dialect(name)");
1533
Andrew McNamara31d88962005-01-12 03:45:10 +00001534PyDoc_STRVAR(csv_field_size_limit_doc,
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001535"Sets an upper limit on parsed fields.\n"
Andrew McNamara31d88962005-01-12 03:45:10 +00001536" csv.field_size_limit([limit])\n"
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001537"\n"
1538"Returns old limit. If limit is not given, no new limit is set and\n"
1539"the old limit is returned");
1540
Skip Montanarob4a04172003-03-20 23:29:12 +00001541static struct PyMethodDef csv_methods[] = {
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001542 { "reader", (PyCFunction)csv_reader,
1543 METH_VARARGS | METH_KEYWORDS, csv_reader_doc},
1544 { "writer", (PyCFunction)csv_writer,
1545 METH_VARARGS | METH_KEYWORDS, csv_writer_doc},
1546 { "list_dialects", (PyCFunction)csv_list_dialects,
1547 METH_NOARGS, csv_list_dialects_doc},
1548 { "register_dialect", (PyCFunction)csv_register_dialect,
Andrew McNamara86625972005-01-11 01:28:33 +00001549 METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001550 { "unregister_dialect", (PyCFunction)csv_unregister_dialect,
1551 METH_O, csv_unregister_dialect_doc},
1552 { "get_dialect", (PyCFunction)csv_get_dialect,
1553 METH_O, csv_get_dialect_doc},
Andrew McNamara31d88962005-01-12 03:45:10 +00001554 { "field_size_limit", (PyCFunction)csv_field_size_limit,
1555 METH_VARARGS, csv_field_size_limit_doc},
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001556 { NULL, NULL }
Skip Montanarob4a04172003-03-20 23:29:12 +00001557};
1558
1559PyMODINIT_FUNC
1560init_csv(void)
1561{
1562 PyObject *module;
Skip Montanarob4a04172003-03-20 23:29:12 +00001563 StyleDesc *style;
1564
1565 if (PyType_Ready(&Dialect_Type) < 0)
1566 return;
1567
1568 if (PyType_Ready(&Reader_Type) < 0)
1569 return;
1570
1571 if (PyType_Ready(&Writer_Type) < 0)
1572 return;
1573
1574 /* Create the module and add the functions */
1575 module = Py_InitModule3("_csv", csv_methods, csv_module_doc);
1576 if (module == NULL)
1577 return;
1578
1579 /* Add version to the module. */
Skip Montanaro7b01a832003-04-12 19:23:46 +00001580 if (PyModule_AddStringConstant(module, "__version__",
1581 MODULE_VERSION) == -1)
Skip Montanarob4a04172003-03-20 23:29:12 +00001582 return;
1583
1584 /* Add _dialects dictionary */
1585 dialects = PyDict_New();
1586 if (dialects == NULL)
1587 return;
1588 if (PyModule_AddObject(module, "_dialects", dialects))
1589 return;
1590
1591 /* Add quote styles into dictionary */
1592 for (style = quote_styles; style->name; style++) {
Skip Montanaro7b01a832003-04-12 19:23:46 +00001593 if (PyModule_AddIntConstant(module, style->name,
1594 style->style) == -1)
Skip Montanarob4a04172003-03-20 23:29:12 +00001595 return;
1596 }
1597
1598 /* Add the Dialect type */
Skip Montanaro32c5d422005-06-15 13:35:08 +00001599 Py_INCREF(&Dialect_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +00001600 if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
1601 return;
1602
1603 /* Add the CSV exception object to the module. */
1604 error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
1605 if (error_obj == NULL)
1606 return;
1607 PyModule_AddObject(module, "Error", error_obj);
1608}