blob: 794eb8213a28a23298454c010a4f6826c52c39a2 [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
40/* end 2.2 compatibility macros */
41
42static PyObject *error_obj; /* CSV exception */
43static PyObject *dialects; /* Dialect registry */
44
45typedef enum {
46 START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD,
47 IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD
48} ParserState;
49
50typedef enum {
51 QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE
52} QuoteStyle;
53
54typedef struct {
55 QuoteStyle style;
56 char *name;
57} StyleDesc;
58
59static StyleDesc quote_styles[] = {
60 { QUOTE_MINIMAL, "QUOTE_MINIMAL" },
61 { QUOTE_ALL, "QUOTE_ALL" },
62 { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" },
63 { QUOTE_NONE, "QUOTE_NONE" },
64 { 0 }
65};
66
67typedef struct {
68 PyObject_HEAD
69
70 int doublequote; /* is " represented by ""? */
71 char delimiter; /* field separator */
72 char quotechar; /* quote character */
73 char escapechar; /* escape character */
74 int skipinitialspace; /* ignore spaces following delimiter? */
75 PyObject *lineterminator; /* string to write between records */
76 QuoteStyle quoting; /* style of quoting to write */
77
78 int strict; /* raise exception on bad CSV */
79} DialectObj;
80
81staticforward PyTypeObject Dialect_Type;
82
83typedef struct {
84 PyObject_HEAD
85
86 PyObject *input_iter; /* iterate over this for input lines */
87
88 DialectObj *dialect; /* parsing dialect */
89
90 PyObject *fields; /* field list for current record */
91 ParserState state; /* current CSV parse state */
92 char *field; /* build current field in here */
93 int field_size; /* size of allocated buffer */
94 int field_len; /* length of current field */
95 int had_parse_error; /* did we have a parse error? */
96} ReaderObj;
97
98staticforward PyTypeObject Reader_Type;
99
100#define ReaderObject_Check(v) ((v)->ob_type == &Reader_Type)
101
102typedef struct {
103 PyObject_HEAD
104
105 PyObject *writeline; /* write output lines to this file */
106
107 DialectObj *dialect; /* parsing dialect */
108
109 char *rec; /* buffer for parser.join */
110 int rec_size; /* size of allocated record */
111 int rec_len; /* length of record */
112 int num_fields; /* number of fields in record */
113} WriterObj;
114
115staticforward PyTypeObject Writer_Type;
116
117/*
118 * DIALECT class
119 */
120
121static PyObject *
122get_dialect_from_registry(PyObject * name_obj)
123{
124 PyObject *dialect_obj;
125
126 dialect_obj = PyDict_GetItem(dialects, name_obj);
127 if (dialect_obj == NULL)
128 return PyErr_Format(error_obj, "unknown dialect");
129 Py_INCREF(dialect_obj);
130 return dialect_obj;
131}
132
133static int
134check_delattr(PyObject *v)
135{
136 if (v == NULL) {
137 PyErr_SetString(PyExc_TypeError,
138 "Cannot delete attribute");
139 return -1;
140 }
141 return 0;
142}
143
144static PyObject *
145get_string(PyObject *str)
146{
147 Py_XINCREF(str);
148 return str;
149}
150
151static int
152set_string(PyObject **str, PyObject *v)
153{
154 if (check_delattr(v) < 0)
155 return -1;
Skip Montanaro860fc0b2003-04-12 18:57:52 +0000156 if (!PyString_Check(v)
157#ifdef Py_USING_UNICODE
158&& !PyUnicode_Check(v)
159#endif
160) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000161 PyErr_BadArgument();
162 return -1;
163 }
164 Py_XDECREF(*str);
165 Py_INCREF(v);
166 *str = v;
167 return 0;
168}
169
170static PyObject *
171get_nullchar_as_None(char c)
172{
173 if (c == '\0') {
174 Py_INCREF(Py_None);
175 return Py_None;
176 }
177 else
178 return PyString_FromStringAndSize((char*)&c, 1);
179}
180
181static int
182set_None_as_nullchar(char * addr, PyObject *v)
183{
184 if (check_delattr(v) < 0)
185 return -1;
186 if (v == Py_None)
187 *addr = '\0';
188 else if (!PyString_Check(v) || PyString_Size(v) != 1) {
189 PyErr_BadArgument();
190 return -1;
191 }
Skip Montanaro577c7a72003-04-12 19:17:14 +0000192 else {
193 char *s = PyString_AsString(v);
194 if (s == NULL)
195 return -1;
196 *addr = s[0];
197 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000198 return 0;
199}
200
201static PyObject *
202Dialect_get_lineterminator(DialectObj *self)
203{
204 return get_string(self->lineterminator);
205}
206
207static int
208Dialect_set_lineterminator(DialectObj *self, PyObject *value)
209{
210 return set_string(&self->lineterminator, value);
211}
212
213static PyObject *
214Dialect_get_escapechar(DialectObj *self)
215{
216 return get_nullchar_as_None(self->escapechar);
217}
218
219static int
220Dialect_set_escapechar(DialectObj *self, PyObject *value)
221{
222 return set_None_as_nullchar(&self->escapechar, value);
223}
224
225static PyObject *
226Dialect_get_quoting(DialectObj *self)
227{
228 return PyInt_FromLong(self->quoting);
229}
230
231static int
232Dialect_set_quoting(DialectObj *self, PyObject *v)
233{
234 int quoting;
235 StyleDesc *qs = quote_styles;
236
237 if (check_delattr(v) < 0)
238 return -1;
239 if (!PyInt_Check(v)) {
240 PyErr_BadArgument();
241 return -1;
242 }
243 quoting = PyInt_AsLong(v);
244 for (qs = quote_styles; qs->name; qs++) {
245 if (qs->style == quoting) {
246 self->quoting = quoting;
247 return 0;
248 }
249 }
250 PyErr_BadArgument();
251 return -1;
252}
253
254static struct PyMethodDef Dialect_methods[] = {
255 { NULL, NULL }
256};
257
258#define D_OFF(x) offsetof(DialectObj, x)
259
260static struct PyMemberDef Dialect_memberlist[] = {
261 { "quotechar", T_CHAR, D_OFF(quotechar) },
262 { "delimiter", T_CHAR, D_OFF(delimiter) },
263 { "skipinitialspace", T_INT, D_OFF(skipinitialspace) },
264 { "doublequote", T_INT, D_OFF(doublequote) },
265 { "strict", T_INT, D_OFF(strict) },
266 { NULL }
267};
268
269static PyGetSetDef Dialect_getsetlist[] = {
270 { "escapechar", (getter)Dialect_get_escapechar,
271 (setter)Dialect_set_escapechar },
272 { "lineterminator", (getter)Dialect_get_lineterminator,
273 (setter)Dialect_set_lineterminator },
274 { "quoting", (getter)Dialect_get_quoting,
275 (setter)Dialect_set_quoting },
276 {NULL},
277};
278
279static void
280Dialect_dealloc(DialectObj *self)
281{
282 Py_XDECREF(self->lineterminator);
Skip Montanarob4a04172003-03-20 23:29:12 +0000283 self->ob_type->tp_free((PyObject *)self);
284}
285
286static int
287dialect_init(DialectObj * self, PyObject * args, PyObject * kwargs)
288{
289 PyObject *dialect = NULL, *name_obj, *value_obj;
290
291 self->quotechar = '"';
292 self->delimiter = ',';
293 self->escapechar = '\0';
294 self->skipinitialspace = 0;
295 Py_XDECREF(self->lineterminator);
296 self->lineterminator = PyString_FromString("\r\n");
297 if (self->lineterminator == NULL)
298 return -1;
299 self->quoting = QUOTE_MINIMAL;
300 self->doublequote = 1;
301 self->strict = 0;
302
303 if (!PyArg_ParseTuple(args, "|O", &dialect))
304 return -1;
305 Py_XINCREF(dialect);
306 if (kwargs != NULL) {
307 PyObject * key = PyString_FromString("dialect");
308 PyObject * d;
309
310 d = PyDict_GetItem(kwargs, key);
311 if (d) {
312 Py_INCREF(d);
313 Py_XDECREF(dialect);
314 PyDict_DelItem(kwargs, key);
315 dialect = d;
316 }
317 Py_DECREF(key);
318 }
319 if (dialect != NULL) {
320 int i;
321 PyObject * dir_list;
322
323 /* If dialect is a string, look it up in our registry */
Skip Montanaro860fc0b2003-04-12 18:57:52 +0000324 if (PyString_Check(dialect)
325#ifdef Py_USING_UNICODE
326|| PyUnicode_Check(dialect)
327#endif
328) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000329 PyObject * new_dia;
330 new_dia = get_dialect_from_registry(dialect);
331 Py_DECREF(dialect);
332 if (new_dia == NULL)
333 return -1;
334 dialect = new_dia;
335 }
336 /* A class rather than an instance? Instanciate */
337 if (PyObject_TypeCheck(dialect, &PyClass_Type)) {
338 PyObject * new_dia;
339 new_dia = PyObject_CallFunction(dialect, "");
340 Py_DECREF(dialect);
341 if (new_dia == NULL)
342 return -1;
343 dialect = new_dia;
344 }
345 /* Make sure we finally have an instance */
346 if (!PyInstance_Check(dialect) ||
347 (dir_list = PyObject_Dir(dialect)) == NULL) {
348 PyErr_SetString(PyExc_TypeError,
349 "dialect must be an instance");
350 Py_DECREF(dialect);
351 return -1;
352 }
353 /* And extract the attributes */
354 for (i = 0; i < PyList_GET_SIZE(dir_list); ++i) {
Tim Peters38fc8372003-04-13 03:25:15 +0000355 char *s;
Skip Montanarob4a04172003-03-20 23:29:12 +0000356 name_obj = PyList_GET_ITEM(dir_list, i);
Tim Peters38fc8372003-04-13 03:25:15 +0000357 s = PyString_AsString(name_obj);
Skip Montanaro577c7a72003-04-12 19:17:14 +0000358 if (s == NULL)
359 return -1;
360 if (s[0] == '_')
Skip Montanarob4a04172003-03-20 23:29:12 +0000361 continue;
362 value_obj = PyObject_GetAttr(dialect, name_obj);
363 if (value_obj) {
364 if (PyObject_SetAttr((PyObject *)self,
365 name_obj, value_obj)) {
366 Py_DECREF(dir_list);
367 return -1;
368 }
369 Py_DECREF(value_obj);
370 }
371 }
372 Py_DECREF(dir_list);
373 Py_DECREF(dialect);
374 }
375 if (kwargs != NULL) {
376 int pos = 0;
377
378 while (PyDict_Next(kwargs, &pos, &name_obj, &value_obj)) {
379 if (PyObject_SetAttr((PyObject *)self,
380 name_obj, value_obj))
381 return -1;
382 }
383 }
384 return 0;
385}
386
387static PyObject *
388dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
389{
390 DialectObj *self;
391 self = (DialectObj *)type->tp_alloc(type, 0);
392 if (self != NULL) {
393 self->lineterminator = NULL;
394 }
395 return (PyObject *)self;
396}
397
398
399PyDoc_STRVAR(Dialect_Type_doc,
400"CSV dialect\n"
401"\n"
402"The Dialect type records CSV parsing and generation options.\n");
403
404static PyTypeObject Dialect_Type = {
405 PyObject_HEAD_INIT(NULL)
406 0, /* ob_size */
407 "_csv.Dialect", /* tp_name */
408 sizeof(DialectObj), /* tp_basicsize */
409 0, /* tp_itemsize */
410 /* methods */
411 (destructor)Dialect_dealloc, /* tp_dealloc */
412 (printfunc)0, /* tp_print */
413 (getattrfunc)0, /* tp_getattr */
414 (setattrfunc)0, /* tp_setattr */
415 (cmpfunc)0, /* tp_compare */
416 (reprfunc)0, /* tp_repr */
417 0, /* tp_as_number */
418 0, /* tp_as_sequence */
419 0, /* tp_as_mapping */
420 (hashfunc)0, /* tp_hash */
421 (ternaryfunc)0, /* tp_call */
422 (reprfunc)0, /* tp_str */
423 0, /* tp_getattro */
424 0, /* tp_setattro */
425 0, /* tp_as_buffer */
426 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
427 Dialect_Type_doc, /* tp_doc */
428 0, /* tp_traverse */
429 0, /* tp_clear */
430 0, /* tp_richcompare */
431 0, /* tp_weaklistoffset */
432 0, /* tp_iter */
433 0, /* tp_iternext */
434 Dialect_methods, /* tp_methods */
435 Dialect_memberlist, /* tp_members */
436 Dialect_getsetlist, /* tp_getset */
437 0, /* tp_base */
438 0, /* tp_dict */
439 0, /* tp_descr_get */
440 0, /* tp_descr_set */
441 0, /* tp_dictoffset */
442 (initproc)dialect_init, /* tp_init */
443 PyType_GenericAlloc, /* tp_alloc */
444 dialect_new, /* tp_new */
445 0, /* tp_free */
446};
447
448static void
449parse_save_field(ReaderObj *self)
450{
451 PyObject *field;
452
453 field = PyString_FromStringAndSize(self->field, self->field_len);
454 if (field != NULL) {
455 PyList_Append(self->fields, field);
456 Py_XDECREF(field);
457 }
458 self->field_len = 0;
459}
460
461static int
462parse_grow_buff(ReaderObj *self)
463{
464 if (self->field_size == 0) {
465 self->field_size = 4096;
466 self->field = PyMem_Malloc(self->field_size);
467 }
468 else {
469 self->field_size *= 2;
470 self->field = PyMem_Realloc(self->field, self->field_size);
471 }
472 if (self->field == NULL) {
473 PyErr_NoMemory();
474 return 0;
475 }
476 return 1;
477}
478
479static void
480parse_add_char(ReaderObj *self, char c)
481{
482 if (self->field_len == self->field_size && !parse_grow_buff(self))
483 return;
484 self->field[self->field_len++] = c;
485}
486
487static void
488parse_process_char(ReaderObj *self, char c)
489{
490 DialectObj *dialect = self->dialect;
491
492 switch (self->state) {
493 case START_RECORD:
494 /* start of record */
495 if (c == '\n')
496 /* empty line - return [] */
497 break;
498 /* normal character - handle as START_FIELD */
499 self->state = START_FIELD;
500 /* fallthru */
501 case START_FIELD:
502 /* expecting field */
503 if (c == '\n') {
504 /* save empty field - return [fields] */
505 parse_save_field(self);
506 self->state = START_RECORD;
507 }
508 else if (c == dialect->quotechar) {
509 /* start quoted field */
510 self->state = IN_QUOTED_FIELD;
511 }
512 else if (c == dialect->escapechar) {
513 /* possible escaped character */
514 self->state = ESCAPED_CHAR;
515 }
516 else if (c == ' ' && dialect->skipinitialspace)
517 /* ignore space at start of field */
518 ;
519 else if (c == dialect->delimiter) {
520 /* save empty field */
521 parse_save_field(self);
522 }
523 else {
524 /* begin new unquoted field */
525 parse_add_char(self, c);
526 self->state = IN_FIELD;
527 }
528 break;
529
530 case ESCAPED_CHAR:
531 if (c != dialect->escapechar &&
532 c != dialect->delimiter &&
533 c != dialect->quotechar)
534 parse_add_char(self, dialect->escapechar);
535 parse_add_char(self, c);
536 self->state = IN_FIELD;
537 break;
538
539 case IN_FIELD:
540 /* in unquoted field */
541 if (c == '\n') {
542 /* end of line - return [fields] */
543 parse_save_field(self);
544 self->state = START_RECORD;
545 }
546 else if (c == dialect->escapechar) {
547 /* possible escaped character */
548 self->state = ESCAPED_CHAR;
549 }
550 else if (c == dialect->delimiter) {
551 /* save field - wait for new field */
552 parse_save_field(self);
553 self->state = START_FIELD;
554 }
555 else {
556 /* normal character - save in field */
557 parse_add_char(self, c);
558 }
559 break;
560
561 case IN_QUOTED_FIELD:
562 /* in quoted field */
563 if (c == '\n') {
564 /* end of line - save '\n' in field */
565 parse_add_char(self, '\n');
566 }
567 else if (c == dialect->escapechar) {
568 /* Possible escape character */
569 self->state = ESCAPE_IN_QUOTED_FIELD;
570 }
571 else if (c == dialect->quotechar) {
572 if (dialect->doublequote) {
573 /* doublequote; " represented by "" */
574 self->state = QUOTE_IN_QUOTED_FIELD;
575 }
576 else {
577 /* end of quote part of field */
578 self->state = IN_FIELD;
579 }
580 }
581 else {
582 /* normal character - save in field */
583 parse_add_char(self, c);
584 }
585 break;
586
587 case ESCAPE_IN_QUOTED_FIELD:
588 if (c != dialect->escapechar &&
589 c != dialect->delimiter &&
590 c != dialect->quotechar)
591 parse_add_char(self, dialect->escapechar);
592 parse_add_char(self, c);
593 self->state = IN_QUOTED_FIELD;
594 break;
595
596 case QUOTE_IN_QUOTED_FIELD:
597 /* doublequote - seen a quote in an quoted field */
598 if (dialect->quoting != QUOTE_NONE &&
599 c == dialect->quotechar) {
600 /* save "" as " */
601 parse_add_char(self, c);
602 self->state = IN_QUOTED_FIELD;
603 }
604 else if (c == dialect->delimiter) {
605 /* save field - wait for new field */
606 parse_save_field(self);
607 self->state = START_FIELD;
608 }
609 else if (c == '\n') {
610 /* end of line - return [fields] */
611 parse_save_field(self);
612 self->state = START_RECORD;
613 }
614 else if (!dialect->strict) {
615 parse_add_char(self, c);
616 self->state = IN_FIELD;
617 }
618 else {
619 /* illegal */
620 self->had_parse_error = 1;
621 PyErr_Format(error_obj, "%c expected after %c",
622 dialect->delimiter,
623 dialect->quotechar);
624 }
625 break;
626
627 }
628}
629
630/*
631 * READER
632 */
633#define R_OFF(x) offsetof(ReaderObj, x)
634
635static struct PyMemberDef Reader_memberlist[] = {
636 { "dialect", T_OBJECT, R_OFF(dialect), RO },
637 { NULL }
638};
639
640static PyObject *
641Reader_getiter(ReaderObj *self)
642{
643 Py_INCREF(self);
644 return (PyObject *)self;
645}
646
647static PyObject *
648Reader_iternext(ReaderObj *self)
649{
650 PyObject *lineobj;
651 PyObject *fields;
652 char *line;
653
654 do {
655 lineobj = PyIter_Next(self->input_iter);
656 if (lineobj == NULL) {
657 /* End of input OR exception */
658 if (!PyErr_Occurred() && self->field_len != 0)
659 return PyErr_Format(error_obj,
660 "newline inside string");
661 return NULL;
662 }
663
664 if (self->had_parse_error) {
665 if (self->fields) {
666 Py_XDECREF(self->fields);
667 }
668 self->fields = PyList_New(0);
669 self->field_len = 0;
670 self->state = START_RECORD;
671 self->had_parse_error = 0;
672 }
673 line = PyString_AsString(lineobj);
674
675 if (line == NULL) {
676 Py_DECREF(lineobj);
677 return NULL;
678 }
Tim Petersef4b7ed2003-03-21 01:35:28 +0000679 if (strlen(line) < (size_t)PyString_GET_SIZE(lineobj)) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000680 self->had_parse_error = 1;
681 Py_DECREF(lineobj);
682 return PyErr_Format(error_obj,
683 "string with NUL bytes");
684 }
685
686 /* Process line of text - send '\n' to processing code to
687 represent end of line. End of line which is not at end of
688 string is an error. */
689 while (*line) {
690 char c;
691
692 c = *line++;
693 if (c == '\r') {
694 c = *line++;
695 if (c == '\0')
696 /* macintosh end of line */
697 break;
698 if (c == '\n') {
699 c = *line++;
700 if (c == '\0')
701 /* DOS end of line */
702 break;
703 }
704 self->had_parse_error = 1;
705 Py_DECREF(lineobj);
706 return PyErr_Format(error_obj,
707 "newline inside string");
708 }
709 if (c == '\n') {
710 c = *line++;
711 if (c == '\0')
712 /* unix end of line */
713 break;
714 self->had_parse_error = 1;
715 Py_DECREF(lineobj);
716 return PyErr_Format(error_obj,
717 "newline inside string");
718 }
719 parse_process_char(self, c);
720 if (PyErr_Occurred()) {
721 Py_DECREF(lineobj);
722 return NULL;
723 }
724 }
725 parse_process_char(self, '\n');
726 Py_DECREF(lineobj);
727 } while (self->state != START_RECORD);
728
729 fields = self->fields;
730 self->fields = PyList_New(0);
731 return fields;
732}
733
734static void
735Reader_dealloc(ReaderObj *self)
736{
737 Py_XDECREF(self->dialect);
738 Py_XDECREF(self->input_iter);
739 Py_XDECREF(self->fields);
740 PyMem_DEL(self);
741}
742
743PyDoc_STRVAR(Reader_Type_doc,
744"CSV reader\n"
745"\n"
746"Reader objects are responsible for reading and parsing tabular data\n"
747"in CSV format.\n"
748);
749
750static struct PyMethodDef Reader_methods[] = {
751 { NULL, NULL }
752};
753
754static PyTypeObject Reader_Type = {
755 PyObject_HEAD_INIT(NULL)
756 0, /*ob_size*/
757 "_csv.reader", /*tp_name*/
758 sizeof(ReaderObj), /*tp_basicsize*/
759 0, /*tp_itemsize*/
760 /* methods */
761 (destructor)Reader_dealloc, /*tp_dealloc*/
762 (printfunc)0, /*tp_print*/
763 (getattrfunc)0, /*tp_getattr*/
764 (setattrfunc)0, /*tp_setattr*/
765 (cmpfunc)0, /*tp_compare*/
766 (reprfunc)0, /*tp_repr*/
767 0, /*tp_as_number*/
768 0, /*tp_as_sequence*/
769 0, /*tp_as_mapping*/
770 (hashfunc)0, /*tp_hash*/
771 (ternaryfunc)0, /*tp_call*/
772 (reprfunc)0, /*tp_str*/
773 0, /*tp_getattro*/
774 0, /*tp_setattro*/
775 0, /*tp_as_buffer*/
776 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
777 Reader_Type_doc, /*tp_doc*/
778 0, /*tp_traverse*/
779 0, /*tp_clear*/
780 0, /*tp_richcompare*/
781 0, /*tp_weaklistoffset*/
782 (getiterfunc)Reader_getiter, /*tp_iter*/
783 (getiterfunc)Reader_iternext, /*tp_iternext*/
784 Reader_methods, /*tp_methods*/
785 Reader_memberlist, /*tp_members*/
786 0, /*tp_getset*/
787
788};
789
790static PyObject *
791csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
792{
793 PyObject * iterator, * dialect = NULL, *ctor_args;
794 ReaderObj * self = PyObject_NEW(ReaderObj, &Reader_Type);
795
796 if (!self)
797 return NULL;
798
799 self->dialect = NULL;
800 self->input_iter = self->fields = NULL;
801
802 self->fields = NULL;
803 self->input_iter = NULL;
804 self->had_parse_error = 0;
805 self->field = NULL;
806 self->field_size = 0;
807 self->field_len = 0;
808 self->state = START_RECORD;
809
810 if (!PyArg_ParseTuple(args, "O|O", &iterator, &dialect)) {
811 Py_DECREF(self);
812 return NULL;
813 }
814 self->input_iter = PyObject_GetIter(iterator);
815 if (self->input_iter == NULL) {
816 PyErr_SetString(PyExc_TypeError,
817 "argument 1 must be an iterator");
818 Py_DECREF(self);
819 return NULL;
820 }
821 ctor_args = Py_BuildValue(dialect ? "(O)" : "()", dialect);
822 if (ctor_args == NULL) {
823 Py_DECREF(self);
824 return NULL;
825 }
826 self->dialect = (DialectObj *)PyObject_Call((PyObject *)&Dialect_Type,
827 ctor_args, keyword_args);
828 Py_DECREF(ctor_args);
829 if (self->dialect == NULL) {
830 Py_DECREF(self);
831 return NULL;
832 }
833 self->fields = PyList_New(0);
834 if (self->fields == NULL) {
835 Py_DECREF(self);
836 return NULL;
837 }
838
839 return (PyObject *)self;
840}
841
842/*
843 * WRITER
844 */
845/* ---------------------------------------------------------------- */
846static void
847join_reset(WriterObj *self)
848{
849 self->rec_len = 0;
850 self->num_fields = 0;
851}
852
853#define MEM_INCR 32768
854
855/* Calculate new record length or append field to record. Return new
856 * record length.
857 */
858static int
859join_append_data(WriterObj *self, char *field, int quote_empty,
860 int *quoted, int copy_phase)
861{
862 DialectObj *dialect = self->dialect;
863 int i, rec_len;
864
865 rec_len = self->rec_len;
866
867 /* If this is not the first field we need a field separator.
868 */
869 if (self->num_fields > 0) {
870 if (copy_phase)
871 self->rec[rec_len] = dialect->delimiter;
872 rec_len++;
873 }
874 /* Handle preceding quote.
875 */
876 switch (dialect->quoting) {
877 case QUOTE_ALL:
878 *quoted = 1;
879 if (copy_phase)
880 self->rec[rec_len] = dialect->quotechar;
881 rec_len++;
882 break;
883 case QUOTE_MINIMAL:
884 case QUOTE_NONNUMERIC:
885 /* We only know about quoted in the copy phase.
886 */
887 if (copy_phase && *quoted) {
888 self->rec[rec_len] = dialect->quotechar;
889 rec_len++;
890 }
891 break;
892 case QUOTE_NONE:
893 break;
894 }
895 /* Copy/count field data.
896 */
897 for (i = 0;; i++) {
898 char c = field[i];
899
900 if (c == '\0')
901 break;
902 /* If in doublequote mode we escape quote chars with a
903 * quote.
904 */
905 if (dialect->quoting != QUOTE_NONE &&
906 c == dialect->quotechar && dialect->doublequote) {
907 if (copy_phase)
908 self->rec[rec_len] = dialect->quotechar;
909 *quoted = 1;
910 rec_len++;
911 }
912
913 /* Some special characters need to be escaped. If we have a
914 * quote character switch to quoted field instead of escaping
915 * individual characters.
916 */
917 if (!*quoted
918 && (c == dialect->delimiter ||
919 c == dialect->escapechar ||
920 c == '\n' || c == '\r')) {
921 if (dialect->quoting != QUOTE_NONE)
922 *quoted = 1;
923 else if (dialect->escapechar) {
924 if (copy_phase)
925 self->rec[rec_len] = dialect->escapechar;
926 rec_len++;
927 }
928 else {
929 PyErr_Format(error_obj,
930 "delimiter must be quoted or escaped");
931 return -1;
932 }
933 }
934 /* Copy field character into record buffer.
935 */
936 if (copy_phase)
937 self->rec[rec_len] = c;
938 rec_len++;
939 }
940
941 /* If field is empty check if it needs to be quoted.
942 */
943 if (i == 0 && quote_empty) {
944 if (dialect->quoting == QUOTE_NONE) {
945 PyErr_Format(error_obj,
946 "single empty field record must be quoted");
947 return -1;
948 } else
949 *quoted = 1;
950 }
951
952 /* Handle final quote character on field.
953 */
954 if (*quoted) {
955 if (copy_phase)
956 self->rec[rec_len] = dialect->quotechar;
957 else
958 /* Didn't know about leading quote until we found it
959 * necessary in field data - compensate for it now.
960 */
961 rec_len++;
962 rec_len++;
963 }
964
965 return rec_len;
966}
967
968static int
969join_check_rec_size(WriterObj *self, int rec_len)
970{
971 if (rec_len > self->rec_size) {
972 if (self->rec_size == 0) {
973 self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
974 self->rec = PyMem_Malloc(self->rec_size);
975 }
976 else {
977 char *old_rec = self->rec;
978
979 self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
980 self->rec = PyMem_Realloc(self->rec, self->rec_size);
981 if (self->rec == NULL)
982 PyMem_Free(old_rec);
983 }
984 if (self->rec == NULL) {
985 PyErr_NoMemory();
986 return 0;
987 }
988 }
989 return 1;
990}
991
992static int
993join_append(WriterObj *self, char *field, int *quoted, int quote_empty)
994{
995 int rec_len;
996
997 rec_len = join_append_data(self, field, quote_empty, quoted, 0);
998 if (rec_len < 0)
999 return 0;
1000
1001 /* grow record buffer if necessary */
1002 if (!join_check_rec_size(self, rec_len))
1003 return 0;
1004
1005 self->rec_len = join_append_data(self, field, quote_empty, quoted, 1);
1006 self->num_fields++;
1007
1008 return 1;
1009}
1010
1011static int
1012join_append_lineterminator(WriterObj *self)
1013{
1014 int terminator_len;
1015
1016 terminator_len = PyString_Size(self->dialect->lineterminator);
1017
1018 /* grow record buffer if necessary */
1019 if (!join_check_rec_size(self, self->rec_len + terminator_len))
1020 return 0;
1021
1022 memmove(self->rec + self->rec_len,
Skip Montanaro577c7a72003-04-12 19:17:14 +00001023 /* should not be NULL */
Skip Montanarob4a04172003-03-20 23:29:12 +00001024 PyString_AsString(self->dialect->lineterminator),
1025 terminator_len);
1026 self->rec_len += terminator_len;
1027
1028 return 1;
1029}
1030
1031PyDoc_STRVAR(csv_writerow_doc,
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001032"writerow(sequence)\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001033"\n"
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001034"Construct and write a CSV record from a sequence of fields. Non-string\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001035"elements will be converted to string.");
1036
1037static PyObject *
1038csv_writerow(WriterObj *self, PyObject *seq)
1039{
1040 DialectObj *dialect = self->dialect;
1041 int len, i;
1042
1043 if (!PySequence_Check(seq))
1044 return PyErr_Format(error_obj, "sequence expected");
1045
1046 len = PySequence_Length(seq);
1047 if (len < 0)
1048 return NULL;
1049
1050 /* Join all fields in internal buffer.
1051 */
1052 join_reset(self);
1053 for (i = 0; i < len; i++) {
1054 PyObject *field;
1055 int append_ok;
1056 int quoted;
1057
1058 field = PySequence_GetItem(seq, i);
1059 if (field == NULL)
1060 return NULL;
1061
1062 quoted = 0;
1063 if (dialect->quoting == QUOTE_NONNUMERIC) {
1064 PyObject *num;
1065
1066 num = PyNumber_Float(field);
1067 if (num == NULL) {
1068 quoted = 1;
1069 PyErr_Clear();
1070 }
1071 else {
1072 Py_DECREF(num);
1073 }
1074 }
1075
1076 if (PyString_Check(field)) {
Skip Montanaro577c7a72003-04-12 19:17:14 +00001077 append_ok = join_append(self,
1078 PyString_AS_STRING(field),
Skip Montanarob4a04172003-03-20 23:29:12 +00001079 &quoted, len == 1);
1080 Py_DECREF(field);
1081 }
1082 else if (field == Py_None) {
1083 append_ok = join_append(self, "", &quoted, len == 1);
1084 Py_DECREF(field);
1085 }
1086 else {
1087 PyObject *str;
1088
1089 str = PyObject_Str(field);
1090 Py_DECREF(field);
1091 if (str == NULL)
1092 return NULL;
1093
Skip Montanaro577c7a72003-04-12 19:17:14 +00001094 append_ok = join_append(self, PyString_AS_STRING(str),
Skip Montanarob4a04172003-03-20 23:29:12 +00001095 &quoted, len == 1);
1096 Py_DECREF(str);
1097 }
1098 if (!append_ok)
1099 return NULL;
1100 }
1101
1102 /* Add line terminator.
1103 */
1104 if (!join_append_lineterminator(self))
1105 return 0;
1106
1107 return PyObject_CallFunction(self->writeline,
1108 "(s#)", self->rec, self->rec_len);
1109}
1110
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001111PyDoc_STRVAR(csv_writerows_doc,
1112"writerows(sequence of sequences)\n"
1113"\n"
1114"Construct and write a series of sequences to a csv file. Non-string\n"
1115"elements will be converted to string.");
1116
Skip Montanarob4a04172003-03-20 23:29:12 +00001117static PyObject *
1118csv_writerows(WriterObj *self, PyObject *seqseq)
1119{
1120 PyObject *row_iter, *row_obj, *result;
1121
1122 row_iter = PyObject_GetIter(seqseq);
1123 if (row_iter == NULL) {
1124 PyErr_SetString(PyExc_TypeError,
Skip Montanaro98f16e02003-04-11 23:10:13 +00001125 "writerows() argument must be iterable");
Skip Montanarob4a04172003-03-20 23:29:12 +00001126 return NULL;
1127 }
1128 while ((row_obj = PyIter_Next(row_iter))) {
1129 result = csv_writerow(self, row_obj);
1130 Py_DECREF(row_obj);
1131 if (!result) {
1132 Py_DECREF(row_iter);
1133 return NULL;
1134 }
1135 else
1136 Py_DECREF(result);
1137 }
1138 Py_DECREF(row_iter);
1139 if (PyErr_Occurred())
1140 return NULL;
1141 Py_INCREF(Py_None);
1142 return Py_None;
1143}
1144
1145static struct PyMethodDef Writer_methods[] = {
1146 { "writerow", (PyCFunction)csv_writerow, METH_O, csv_writerow_doc},
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001147 { "writerows", (PyCFunction)csv_writerows, METH_O, csv_writerows_doc},
Skip Montanarob4a04172003-03-20 23:29:12 +00001148 { NULL, NULL }
1149};
1150
1151#define W_OFF(x) offsetof(WriterObj, x)
1152
1153static struct PyMemberDef Writer_memberlist[] = {
1154 { "dialect", T_OBJECT, W_OFF(dialect), RO },
1155 { NULL }
1156};
1157
1158static void
1159Writer_dealloc(WriterObj *self)
1160{
1161 Py_XDECREF(self->dialect);
1162 Py_XDECREF(self->writeline);
1163 PyMem_DEL(self);
1164}
1165
1166PyDoc_STRVAR(Writer_Type_doc,
1167"CSV writer\n"
1168"\n"
1169"Writer objects are responsible for generating tabular data\n"
1170"in CSV format from sequence input.\n"
1171);
1172
1173static PyTypeObject Writer_Type = {
1174 PyObject_HEAD_INIT(NULL)
1175 0, /*ob_size*/
1176 "_csv.writer", /*tp_name*/
1177 sizeof(WriterObj), /*tp_basicsize*/
1178 0, /*tp_itemsize*/
1179 /* methods */
1180 (destructor)Writer_dealloc, /*tp_dealloc*/
1181 (printfunc)0, /*tp_print*/
1182 (getattrfunc)0, /*tp_getattr*/
1183 (setattrfunc)0, /*tp_setattr*/
1184 (cmpfunc)0, /*tp_compare*/
1185 (reprfunc)0, /*tp_repr*/
1186 0, /*tp_as_number*/
1187 0, /*tp_as_sequence*/
1188 0, /*tp_as_mapping*/
1189 (hashfunc)0, /*tp_hash*/
1190 (ternaryfunc)0, /*tp_call*/
1191 (reprfunc)0, /*tp_str*/
1192 0, /*tp_getattro*/
1193 0, /*tp_setattro*/
1194 0, /*tp_as_buffer*/
1195 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1196 Writer_Type_doc,
1197 0, /*tp_traverse*/
1198 0, /*tp_clear*/
1199 0, /*tp_richcompare*/
1200 0, /*tp_weaklistoffset*/
1201 (getiterfunc)0, /*tp_iter*/
1202 (getiterfunc)0, /*tp_iternext*/
1203 Writer_methods, /*tp_methods*/
1204 Writer_memberlist, /*tp_members*/
1205 0, /*tp_getset*/
1206};
1207
1208static PyObject *
1209csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)
1210{
1211 PyObject * output_file, * dialect = NULL, *ctor_args;
1212 WriterObj * self = PyObject_NEW(WriterObj, &Writer_Type);
1213
1214 if (!self)
1215 return NULL;
1216
1217 self->dialect = NULL;
1218 self->writeline = NULL;
1219
1220 self->rec = NULL;
1221 self->rec_size = 0;
1222 self->rec_len = 0;
1223 self->num_fields = 0;
1224
1225 if (!PyArg_ParseTuple(args, "O|O", &output_file, &dialect)) {
1226 Py_DECREF(self);
1227 return NULL;
1228 }
1229 self->writeline = PyObject_GetAttrString(output_file, "write");
1230 if (self->writeline == NULL || !PyCallable_Check(self->writeline)) {
1231 PyErr_SetString(PyExc_TypeError,
1232 "argument 1 must be an instance with a write method");
1233 Py_DECREF(self);
1234 return NULL;
1235 }
1236 ctor_args = Py_BuildValue(dialect ? "(O)" : "()", dialect);
1237 if (ctor_args == NULL) {
1238 Py_DECREF(self);
1239 return NULL;
1240 }
1241 self->dialect = (DialectObj *)PyObject_Call((PyObject *)&Dialect_Type,
1242 ctor_args, keyword_args);
1243 Py_DECREF(ctor_args);
1244 if (self->dialect == NULL) {
1245 Py_DECREF(self);
1246 return NULL;
1247 }
1248 return (PyObject *)self;
1249}
1250
1251/*
1252 * DIALECT REGISTRY
1253 */
1254static PyObject *
1255csv_list_dialects(PyObject *module, PyObject *args)
1256{
1257 return PyDict_Keys(dialects);
1258}
1259
1260static PyObject *
1261csv_register_dialect(PyObject *module, PyObject *args)
1262{
1263 PyObject *name_obj, *dialect_obj;
1264
1265 if (!PyArg_ParseTuple(args, "OO", &name_obj, &dialect_obj))
1266 return NULL;
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001267 if (!PyString_Check(name_obj)
1268#ifdef Py_USING_UNICODE
1269&& !PyUnicode_Check(name_obj)
1270#endif
1271) {
Skip Montanarob4a04172003-03-20 23:29:12 +00001272 PyErr_SetString(PyExc_TypeError,
1273 "dialect name must be a string or unicode");
1274 return NULL;
1275 }
1276 Py_INCREF(dialect_obj);
1277 /* A class rather than an instance? Instanciate */
1278 if (PyObject_TypeCheck(dialect_obj, &PyClass_Type)) {
1279 PyObject * new_dia;
1280 new_dia = PyObject_CallFunction(dialect_obj, "");
1281 Py_DECREF(dialect_obj);
1282 if (new_dia == NULL)
1283 return NULL;
1284 dialect_obj = new_dia;
1285 }
1286 /* Make sure we finally have an instance */
1287 if (!PyInstance_Check(dialect_obj)) {
1288 PyErr_SetString(PyExc_TypeError, "dialect must be an instance");
1289 Py_DECREF(dialect_obj);
1290 return NULL;
1291 }
1292 if (PyObject_SetAttrString(dialect_obj, "_name", name_obj) < 0) {
1293 Py_DECREF(dialect_obj);
1294 return NULL;
1295 }
1296 if (PyDict_SetItem(dialects, name_obj, dialect_obj) < 0) {
1297 Py_DECREF(dialect_obj);
1298 return NULL;
1299 }
1300 Py_DECREF(dialect_obj);
1301 Py_INCREF(Py_None);
1302 return Py_None;
1303}
1304
1305static PyObject *
Skip Montanaro577c7a72003-04-12 19:17:14 +00001306csv_unregister_dialect(PyObject *module, PyObject *name_obj)
Skip Montanarob4a04172003-03-20 23:29:12 +00001307{
Skip Montanarob4a04172003-03-20 23:29:12 +00001308 if (PyDict_DelItem(dialects, name_obj) < 0)
1309 return PyErr_Format(error_obj, "unknown dialect");
1310 Py_INCREF(Py_None);
1311 return Py_None;
1312}
1313
1314static PyObject *
Skip Montanaro577c7a72003-04-12 19:17:14 +00001315csv_get_dialect(PyObject *module, PyObject *name_obj)
Skip Montanarob4a04172003-03-20 23:29:12 +00001316{
Skip Montanarob4a04172003-03-20 23:29:12 +00001317 return get_dialect_from_registry(name_obj);
1318}
1319
1320/*
1321 * MODULE
1322 */
1323
1324PyDoc_STRVAR(csv_module_doc,
1325"CSV parsing and writing.\n"
1326"\n"
1327"This module provides classes that assist in the reading and writing\n"
1328"of Comma Separated Value (CSV) files, and implements the interface\n"
1329"described by PEP 305. Although many CSV files are simple to parse,\n"
1330"the format is not formally defined by a stable specification and\n"
1331"is subtle enough that parsing lines of a CSV file with something\n"
1332"like line.split(\",\") is bound to fail. The module supports three\n"
1333"basic APIs: reading, writing, and registration of dialects.\n"
1334"\n"
1335"\n"
1336"DIALECT REGISTRATION:\n"
1337"\n"
1338"Readers and writers support a dialect argument, which is a convenient\n"
1339"handle on a group of settings. When the dialect argument is a string,\n"
1340"it identifies one of the dialects previously registered with the module.\n"
1341"If it is a class or instance, the attributes of the argument are used as\n"
1342"the settings for the reader or writer:\n"
1343"\n"
1344" class excel:\n"
1345" delimiter = ','\n"
1346" quotechar = '\"'\n"
1347" escapechar = None\n"
1348" doublequote = True\n"
1349" skipinitialspace = False\n"
1350" lineterminator = '\r\n'\n"
1351" quoting = QUOTE_MINIMAL\n"
1352"\n"
1353"SETTINGS:\n"
1354"\n"
1355" * quotechar - specifies a one-character string to use as the \n"
1356" quoting character. It defaults to '\"'.\n"
1357" * delimiter - specifies a one-character string to use as the \n"
1358" field separator. It defaults to ','.\n"
1359" * skipinitialspace - specifies how to interpret whitespace which\n"
1360" immediately follows a delimiter. It defaults to False, which\n"
1361" means that whitespace immediately following a delimiter is part\n"
1362" of the following field.\n"
1363" * lineterminator - specifies the character sequence which should \n"
1364" terminate rows.\n"
1365" * quoting - controls when quotes should be generated by the writer.\n"
1366" It can take on any of the following module constants:\n"
1367"\n"
1368" csv.QUOTE_MINIMAL means only when required, for example, when a\n"
1369" field contains either the quotechar or the delimiter\n"
1370" csv.QUOTE_ALL means that quotes are always placed around fields.\n"
1371" csv.QUOTE_NONNUMERIC means that quotes are always placed around\n"
1372" fields which contain characters other than [+-0-9.].\n"
1373" csv.QUOTE_NONE means that quotes are never placed around fields.\n"
1374" * escapechar - specifies a one-character string used to escape \n"
1375" the delimiter when quoting is set to QUOTE_NONE.\n"
1376" * doublequote - controls the handling of quotes inside fields. When\n"
1377" True, two consecutive quotes are interpreted as one during read,\n"
1378" and when writing, each quote character embedded in the data is\n"
1379" written as two quotes\n");
1380
1381PyDoc_STRVAR(csv_reader_doc,
1382" csv_reader = reader(iterable [, dialect='excel']\n"
1383" [optional keyword args])\n"
1384" for row in csv_reader:\n"
1385" process(row)\n"
1386"\n"
1387"The \"iterable\" argument can be any object that returns a line\n"
1388"of input for each iteration, such as a file object or a list. The\n"
1389"optional \"dialect\" parameter is discussed below. The function\n"
1390"also accepts optional keyword arguments which override settings\n"
1391"provided by the dialect.\n"
1392"\n"
1393"The returned object is an iterator. Each iteration returns a row\n"
1394 "of the CSV file (which can span multiple input lines):\n");
1395
1396PyDoc_STRVAR(csv_writer_doc,
1397" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1398" [optional keyword args])\n"
1399" for row in csv_writer:\n"
1400" csv_writer.writerow(row)\n"
1401"\n"
1402" [or]\n"
1403"\n"
1404" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1405" [optional keyword args])\n"
1406" csv_writer.writerows(rows)\n"
1407"\n"
1408"The \"fileobj\" argument can be any object that supports the file API.\n");
1409
1410PyDoc_STRVAR(csv_list_dialects_doc,
1411"Return a list of all know dialect names.\n"
1412" names = csv.list_dialects()");
1413
1414PyDoc_STRVAR(csv_get_dialect_doc,
1415"Return the dialect instance associated with name.\n"
1416" dialect = csv.get_dialect(name)");
1417
1418PyDoc_STRVAR(csv_register_dialect_doc,
1419"Create a mapping from a string name to a dialect class.\n"
1420" dialect = csv.register_dialect(name, dialect)");
1421
1422PyDoc_STRVAR(csv_unregister_dialect_doc,
1423"Delete the name/dialect mapping associated with a string name.\n"
1424" csv.unregister_dialect(name)");
1425
1426static struct PyMethodDef csv_methods[] = {
1427 { "reader", (PyCFunction)csv_reader,
1428 METH_VARARGS | METH_KEYWORDS, csv_reader_doc},
1429 { "writer", (PyCFunction)csv_writer,
1430 METH_VARARGS | METH_KEYWORDS, csv_writer_doc},
1431 { "list_dialects", (PyCFunction)csv_list_dialects,
1432 METH_NOARGS, csv_list_dialects_doc},
1433 { "register_dialect", (PyCFunction)csv_register_dialect,
1434 METH_VARARGS, csv_register_dialect_doc},
1435 { "unregister_dialect", (PyCFunction)csv_unregister_dialect,
Skip Montanaro577c7a72003-04-12 19:17:14 +00001436 METH_O, csv_unregister_dialect_doc},
Skip Montanarob4a04172003-03-20 23:29:12 +00001437 { "get_dialect", (PyCFunction)csv_get_dialect,
Skip Montanaro577c7a72003-04-12 19:17:14 +00001438 METH_O, csv_get_dialect_doc},
Skip Montanarob4a04172003-03-20 23:29:12 +00001439 { NULL, NULL }
1440};
1441
1442PyMODINIT_FUNC
1443init_csv(void)
1444{
1445 PyObject *module;
Skip Montanarob4a04172003-03-20 23:29:12 +00001446 StyleDesc *style;
1447
1448 if (PyType_Ready(&Dialect_Type) < 0)
1449 return;
1450
1451 if (PyType_Ready(&Reader_Type) < 0)
1452 return;
1453
1454 if (PyType_Ready(&Writer_Type) < 0)
1455 return;
1456
1457 /* Create the module and add the functions */
1458 module = Py_InitModule3("_csv", csv_methods, csv_module_doc);
1459 if (module == NULL)
1460 return;
1461
1462 /* Add version to the module. */
Skip Montanaro7b01a832003-04-12 19:23:46 +00001463 if (PyModule_AddStringConstant(module, "__version__",
1464 MODULE_VERSION) == -1)
Skip Montanarob4a04172003-03-20 23:29:12 +00001465 return;
1466
1467 /* Add _dialects dictionary */
1468 dialects = PyDict_New();
1469 if (dialects == NULL)
1470 return;
1471 if (PyModule_AddObject(module, "_dialects", dialects))
1472 return;
1473
1474 /* Add quote styles into dictionary */
1475 for (style = quote_styles; style->name; style++) {
Skip Montanaro7b01a832003-04-12 19:23:46 +00001476 if (PyModule_AddIntConstant(module, style->name,
1477 style->style) == -1)
Skip Montanarob4a04172003-03-20 23:29:12 +00001478 return;
1479 }
1480
1481 /* Add the Dialect type */
1482 if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
1483 return;
1484
1485 /* Add the CSV exception object to the module. */
1486 error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
1487 if (error_obj == NULL)
1488 return;
1489 PyModule_AddObject(module, "Error", error_obj);
1490}