blob: 4704c16ea034af4b39046bbaa158c71f6617f90e [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 Wouters49fd7fa2006-04-21 10:40:58 +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#define Py_VISIT(op) \
53 do { \
54 if (op) { \
55 int vret = visit((PyObject *)(op), arg); \
56 if (vret) \
57 return vret; \
58 } \
59 } while (0)
60#endif
61
Skip Montanarob4a04172003-03-20 23:29:12 +000062/* end 2.2 compatibility macros */
63
Andrew McNamara37d2bdf2005-01-10 12:22:48 +000064#define IS_BASESTRING(o) \
65 PyObject_TypeCheck(o, &PyBaseString_Type)
66
Skip Montanarob4a04172003-03-20 23:29:12 +000067static PyObject *error_obj; /* CSV exception */
68static PyObject *dialects; /* Dialect registry */
Andrew McNamarae4d05c42005-01-11 07:32:02 +000069static long field_limit = 128 * 1024; /* max parsed field size */
Skip Montanarob4a04172003-03-20 23:29:12 +000070
71typedef enum {
72 START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD,
Andrew McNamaraf69d94f2005-01-13 11:30:54 +000073 IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD,
74 EAT_CRNL
Skip Montanarob4a04172003-03-20 23:29:12 +000075} ParserState;
76
77typedef enum {
78 QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE
79} QuoteStyle;
80
81typedef struct {
82 QuoteStyle style;
83 char *name;
84} StyleDesc;
85
86static StyleDesc quote_styles[] = {
87 { QUOTE_MINIMAL, "QUOTE_MINIMAL" },
88 { QUOTE_ALL, "QUOTE_ALL" },
89 { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" },
90 { QUOTE_NONE, "QUOTE_NONE" },
91 { 0 }
92};
93
94typedef struct {
95 PyObject_HEAD
96
97 int doublequote; /* is " represented by ""? */
98 char delimiter; /* field separator */
99 char quotechar; /* quote character */
100 char escapechar; /* escape character */
101 int skipinitialspace; /* ignore spaces following delimiter? */
102 PyObject *lineterminator; /* string to write between records */
Andrew McNamara1196cf12005-01-07 04:42:45 +0000103 int quoting; /* style of quoting to write */
Skip Montanarob4a04172003-03-20 23:29:12 +0000104
105 int strict; /* raise exception on bad CSV */
106} DialectObj;
107
Neal Norwitz227b5332006-03-22 09:28:35 +0000108static PyTypeObject Dialect_Type;
Skip Montanarob4a04172003-03-20 23:29:12 +0000109
110typedef struct {
111 PyObject_HEAD
112
113 PyObject *input_iter; /* iterate over this for input lines */
114
115 DialectObj *dialect; /* parsing dialect */
116
117 PyObject *fields; /* field list for current record */
118 ParserState state; /* current CSV parse state */
119 char *field; /* build current field in here */
120 int field_size; /* size of allocated buffer */
121 int field_len; /* length of current field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000122 int numeric_field; /* treat field as numeric */
Andrew McNamara7f2053e2005-01-12 11:17:16 +0000123 unsigned long line_num; /* Source-file line number */
Skip Montanarob4a04172003-03-20 23:29:12 +0000124} ReaderObj;
125
Neal Norwitz227b5332006-03-22 09:28:35 +0000126static PyTypeObject Reader_Type;
Skip Montanarob4a04172003-03-20 23:29:12 +0000127
128#define ReaderObject_Check(v) ((v)->ob_type == &Reader_Type)
129
130typedef struct {
131 PyObject_HEAD
132
133 PyObject *writeline; /* write output lines to this file */
134
135 DialectObj *dialect; /* parsing dialect */
136
137 char *rec; /* buffer for parser.join */
138 int rec_size; /* size of allocated record */
139 int rec_len; /* length of record */
140 int num_fields; /* number of fields in record */
141} WriterObj;
142
Neal Norwitz227b5332006-03-22 09:28:35 +0000143static PyTypeObject Writer_Type;
Skip Montanarob4a04172003-03-20 23:29:12 +0000144
145/*
146 * DIALECT class
147 */
148
149static PyObject *
150get_dialect_from_registry(PyObject * name_obj)
151{
152 PyObject *dialect_obj;
153
154 dialect_obj = PyDict_GetItem(dialects, name_obj);
Andrew McNamaradbce2612005-01-10 23:17:35 +0000155 if (dialect_obj == NULL) {
156 if (!PyErr_Occurred())
157 PyErr_Format(error_obj, "unknown dialect");
158 }
159 else
160 Py_INCREF(dialect_obj);
Skip Montanarob4a04172003-03-20 23:29:12 +0000161 return dialect_obj;
162}
163
Skip Montanarob4a04172003-03-20 23:29:12 +0000164static PyObject *
165get_string(PyObject *str)
166{
167 Py_XINCREF(str);
168 return str;
169}
170
Skip Montanarob4a04172003-03-20 23:29:12 +0000171static PyObject *
172get_nullchar_as_None(char c)
173{
174 if (c == '\0') {
175 Py_INCREF(Py_None);
176 return Py_None;
177 }
178 else
179 return PyString_FromStringAndSize((char*)&c, 1);
180}
181
Skip Montanarob4a04172003-03-20 23:29:12 +0000182static PyObject *
183Dialect_get_lineterminator(DialectObj *self)
184{
185 return get_string(self->lineterminator);
186}
187
Skip Montanarob4a04172003-03-20 23:29:12 +0000188static PyObject *
189Dialect_get_escapechar(DialectObj *self)
190{
191 return get_nullchar_as_None(self->escapechar);
192}
193
Andrew McNamara1196cf12005-01-07 04:42:45 +0000194static PyObject *
195Dialect_get_quotechar(DialectObj *self)
Skip Montanarob4a04172003-03-20 23:29:12 +0000196{
Andrew McNamara1196cf12005-01-07 04:42:45 +0000197 return get_nullchar_as_None(self->quotechar);
Skip Montanarob4a04172003-03-20 23:29:12 +0000198}
199
200static PyObject *
201Dialect_get_quoting(DialectObj *self)
202{
203 return PyInt_FromLong(self->quoting);
204}
205
206static int
Andrew McNamara1196cf12005-01-07 04:42:45 +0000207_set_bool(const char *name, int *target, PyObject *src, int dflt)
Skip Montanarob4a04172003-03-20 23:29:12 +0000208{
Andrew McNamara1196cf12005-01-07 04:42:45 +0000209 if (src == NULL)
210 *target = dflt;
211 else
212 *target = PyObject_IsTrue(src);
213 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000214}
215
Andrew McNamara1196cf12005-01-07 04:42:45 +0000216static int
217_set_int(const char *name, int *target, PyObject *src, int dflt)
218{
219 if (src == NULL)
220 *target = dflt;
221 else {
222 if (!PyInt_Check(src)) {
223 PyErr_Format(PyExc_TypeError,
224 "\"%s\" must be an integer", name);
225 return -1;
226 }
227 *target = PyInt_AsLong(src);
228 }
229 return 0;
230}
231
232static int
233_set_char(const char *name, char *target, PyObject *src, char dflt)
234{
235 if (src == NULL)
236 *target = dflt;
237 else {
Andrew McNamaraa8292632005-01-10 12:25:11 +0000238 if (src == Py_None || PyString_Size(src) == 0)
Andrew McNamara1196cf12005-01-07 04:42:45 +0000239 *target = '\0';
240 else if (!PyString_Check(src) || PyString_Size(src) != 1) {
241 PyErr_Format(PyExc_TypeError,
242 "\"%s\" must be an 1-character string",
243 name);
244 return -1;
245 }
246 else {
247 char *s = PyString_AsString(src);
248 if (s == NULL)
249 return -1;
250 *target = s[0];
251 }
252 }
253 return 0;
254}
255
256static int
257_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)
258{
259 if (src == NULL)
260 *target = PyString_FromString(dflt);
261 else {
262 if (src == Py_None)
263 *target = NULL;
Andrew McNamara37d2bdf2005-01-10 12:22:48 +0000264 else if (!IS_BASESTRING(src)) {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000265 PyErr_Format(PyExc_TypeError,
266 "\"%s\" must be an string", name);
267 return -1;
Andrew McNamaradd3e6cb2005-01-07 06:46:50 +0000268 }
269 else {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000270 Py_XDECREF(*target);
271 Py_INCREF(src);
272 *target = src;
273 }
274 }
275 return 0;
276}
277
278static int
279dialect_check_quoting(int quoting)
280{
281 StyleDesc *qs = quote_styles;
282
283 for (qs = quote_styles; qs->name; qs++) {
284 if (qs->style == quoting)
285 return 0;
286 }
287 PyErr_Format(PyExc_TypeError, "bad \"quoting\" value");
288 return -1;
289}
Skip Montanarob4a04172003-03-20 23:29:12 +0000290
291#define D_OFF(x) offsetof(DialectObj, x)
292
293static struct PyMemberDef Dialect_memberlist[] = {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000294 { "delimiter", T_CHAR, D_OFF(delimiter), READONLY },
295 { "skipinitialspace", T_INT, D_OFF(skipinitialspace), READONLY },
296 { "doublequote", T_INT, D_OFF(doublequote), READONLY },
297 { "strict", T_INT, D_OFF(strict), READONLY },
Skip Montanarob4a04172003-03-20 23:29:12 +0000298 { NULL }
299};
300
301static PyGetSetDef Dialect_getsetlist[] = {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000302 { "escapechar", (getter)Dialect_get_escapechar},
303 { "lineterminator", (getter)Dialect_get_lineterminator},
304 { "quotechar", (getter)Dialect_get_quotechar},
305 { "quoting", (getter)Dialect_get_quoting},
306 {NULL},
Skip Montanarob4a04172003-03-20 23:29:12 +0000307};
308
309static void
310Dialect_dealloc(DialectObj *self)
311{
312 Py_XDECREF(self->lineterminator);
Skip Montanarob4a04172003-03-20 23:29:12 +0000313 self->ob_type->tp_free((PyObject *)self);
314}
315
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +0000316static char *dialect_kws[] = {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000317 "dialect",
318 "delimiter",
319 "doublequote",
320 "escapechar",
321 "lineterminator",
322 "quotechar",
323 "quoting",
324 "skipinitialspace",
325 "strict",
326 NULL
327};
328
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000329static PyObject *
330dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
Skip Montanarob4a04172003-03-20 23:29:12 +0000331{
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000332 DialectObj *self;
333 PyObject *ret = NULL;
334 PyObject *dialect = NULL;
Andrew McNamara1196cf12005-01-07 04:42:45 +0000335 PyObject *delimiter = NULL;
336 PyObject *doublequote = NULL;
337 PyObject *escapechar = NULL;
338 PyObject *lineterminator = NULL;
339 PyObject *quotechar = NULL;
340 PyObject *quoting = NULL;
341 PyObject *skipinitialspace = NULL;
342 PyObject *strict = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000343
Andrew McNamara1196cf12005-01-07 04:42:45 +0000344 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
345 "|OOOOOOOOO", dialect_kws,
346 &dialect,
347 &delimiter,
348 &doublequote,
349 &escapechar,
350 &lineterminator,
351 &quotechar,
352 &quoting,
353 &skipinitialspace,
354 &strict))
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000355 return NULL;
356
357 if (dialect != NULL) {
358 if (IS_BASESTRING(dialect)) {
359 dialect = get_dialect_from_registry(dialect);
360 if (dialect == NULL)
361 return NULL;
362 }
363 else
364 Py_INCREF(dialect);
365 /* Can we reuse this instance? */
366 if (PyObject_TypeCheck(dialect, &Dialect_Type) &&
367 delimiter == 0 &&
368 doublequote == 0 &&
369 escapechar == 0 &&
370 lineterminator == 0 &&
371 quotechar == 0 &&
372 quoting == 0 &&
373 skipinitialspace == 0 &&
374 strict == 0)
375 return dialect;
376 }
377
378 self = (DialectObj *)type->tp_alloc(type, 0);
379 if (self == NULL) {
380 Py_XDECREF(dialect);
381 return NULL;
382 }
383 self->lineterminator = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000384
Andrew McNamara1196cf12005-01-07 04:42:45 +0000385 Py_XINCREF(delimiter);
386 Py_XINCREF(doublequote);
387 Py_XINCREF(escapechar);
388 Py_XINCREF(lineterminator);
389 Py_XINCREF(quotechar);
390 Py_XINCREF(quoting);
391 Py_XINCREF(skipinitialspace);
392 Py_XINCREF(strict);
393 if (dialect != NULL) {
Andrew McNamara1196cf12005-01-07 04:42:45 +0000394#define DIALECT_GETATTR(v, n) \
395 if (v == NULL) \
396 v = PyObject_GetAttrString(dialect, n)
Andrew McNamara1196cf12005-01-07 04:42:45 +0000397 DIALECT_GETATTR(delimiter, "delimiter");
398 DIALECT_GETATTR(doublequote, "doublequote");
399 DIALECT_GETATTR(escapechar, "escapechar");
400 DIALECT_GETATTR(lineterminator, "lineterminator");
401 DIALECT_GETATTR(quotechar, "quotechar");
402 DIALECT_GETATTR(quoting, "quoting");
403 DIALECT_GETATTR(skipinitialspace, "skipinitialspace");
404 DIALECT_GETATTR(strict, "strict");
405 PyErr_Clear();
Andrew McNamara1196cf12005-01-07 04:42:45 +0000406 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000407
Andrew McNamara1196cf12005-01-07 04:42:45 +0000408 /* check types and convert to C values */
409#define DIASET(meth, name, target, src, dflt) \
410 if (meth(name, target, src, dflt)) \
411 goto err
412 DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ',');
413 DIASET(_set_bool, "doublequote", &self->doublequote, doublequote, 1);
414 DIASET(_set_char, "escapechar", &self->escapechar, escapechar, 0);
415 DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n");
416 DIASET(_set_char, "quotechar", &self->quotechar, quotechar, '"');
417 DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL);
418 DIASET(_set_bool, "skipinitialspace", &self->skipinitialspace, skipinitialspace, 0);
419 DIASET(_set_bool, "strict", &self->strict, strict, 0);
Skip Montanarob4a04172003-03-20 23:29:12 +0000420
Andrew McNamara1196cf12005-01-07 04:42:45 +0000421 /* validate options */
422 if (dialect_check_quoting(self->quoting))
423 goto err;
424 if (self->delimiter == 0) {
425 PyErr_SetString(PyExc_TypeError, "delimiter must be set");
426 goto err;
427 }
Andrew McNamara5d45a8d2005-01-12 08:16:17 +0000428 if (quotechar == Py_None && quoting == NULL)
Andrew McNamara1196cf12005-01-07 04:42:45 +0000429 self->quoting = QUOTE_NONE;
430 if (self->quoting != QUOTE_NONE && self->quotechar == 0) {
431 PyErr_SetString(PyExc_TypeError,
432 "quotechar must be set if quoting enabled");
433 goto err;
434 }
435 if (self->lineterminator == 0) {
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000436 PyErr_SetString(PyExc_TypeError, "lineterminator must be set");
Andrew McNamara1196cf12005-01-07 04:42:45 +0000437 goto err;
438 }
439
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000440 ret = (PyObject *)self;
Skip Montanarod60fbd42005-06-15 01:33:30 +0000441 Py_INCREF(self);
Andrew McNamara1196cf12005-01-07 04:42:45 +0000442err:
Skip Montanarod60fbd42005-06-15 01:33:30 +0000443 Py_XDECREF(self);
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000444 Py_XDECREF(dialect);
Andrew McNamara1196cf12005-01-07 04:42:45 +0000445 Py_XDECREF(delimiter);
446 Py_XDECREF(doublequote);
447 Py_XDECREF(escapechar);
448 Py_XDECREF(lineterminator);
449 Py_XDECREF(quotechar);
450 Py_XDECREF(quoting);
451 Py_XDECREF(skipinitialspace);
452 Py_XDECREF(strict);
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000453 return ret;
Skip Montanarob4a04172003-03-20 23:29:12 +0000454}
455
456
457PyDoc_STRVAR(Dialect_Type_doc,
458"CSV dialect\n"
459"\n"
460"The Dialect type records CSV parsing and generation options.\n");
461
462static PyTypeObject Dialect_Type = {
463 PyObject_HEAD_INIT(NULL)
464 0, /* ob_size */
465 "_csv.Dialect", /* tp_name */
466 sizeof(DialectObj), /* tp_basicsize */
467 0, /* tp_itemsize */
468 /* methods */
469 (destructor)Dialect_dealloc, /* tp_dealloc */
470 (printfunc)0, /* tp_print */
471 (getattrfunc)0, /* tp_getattr */
472 (setattrfunc)0, /* tp_setattr */
473 (cmpfunc)0, /* tp_compare */
474 (reprfunc)0, /* tp_repr */
475 0, /* tp_as_number */
476 0, /* tp_as_sequence */
477 0, /* tp_as_mapping */
478 (hashfunc)0, /* tp_hash */
479 (ternaryfunc)0, /* tp_call */
480 (reprfunc)0, /* tp_str */
481 0, /* tp_getattro */
482 0, /* tp_setattro */
483 0, /* tp_as_buffer */
484 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
485 Dialect_Type_doc, /* tp_doc */
486 0, /* tp_traverse */
487 0, /* tp_clear */
488 0, /* tp_richcompare */
489 0, /* tp_weaklistoffset */
490 0, /* tp_iter */
491 0, /* tp_iternext */
Andrew McNamara1196cf12005-01-07 04:42:45 +0000492 0, /* tp_methods */
Skip Montanarob4a04172003-03-20 23:29:12 +0000493 Dialect_memberlist, /* tp_members */
494 Dialect_getsetlist, /* tp_getset */
495 0, /* tp_base */
496 0, /* tp_dict */
497 0, /* tp_descr_get */
498 0, /* tp_descr_set */
499 0, /* tp_dictoffset */
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000500 0, /* tp_init */
501 0, /* tp_alloc */
Skip Montanarob4a04172003-03-20 23:29:12 +0000502 dialect_new, /* tp_new */
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000503 0, /* tp_free */
Skip Montanarob4a04172003-03-20 23:29:12 +0000504};
505
Andrew McNamara91b97462005-01-11 01:07:23 +0000506/*
507 * Return an instance of the dialect type, given a Python instance or kwarg
508 * description of the dialect
509 */
510static PyObject *
511_call_dialect(PyObject *dialect_inst, PyObject *kwargs)
512{
513 PyObject *ctor_args;
514 PyObject *dialect;
515
516 ctor_args = Py_BuildValue(dialect_inst ? "(O)" : "()", dialect_inst);
517 if (ctor_args == NULL)
518 return NULL;
519 dialect = PyObject_Call((PyObject *)&Dialect_Type, ctor_args, kwargs);
520 Py_DECREF(ctor_args);
521 return dialect;
522}
523
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000524/*
525 * READER
526 */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000527static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000528parse_save_field(ReaderObj *self)
529{
530 PyObject *field;
531
532 field = PyString_FromStringAndSize(self->field, self->field_len);
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000533 if (field == NULL)
534 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000535 self->field_len = 0;
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000536 if (self->numeric_field) {
537 PyObject *tmp;
538
539 self->numeric_field = 0;
540 tmp = PyNumber_Float(field);
541 if (tmp == NULL) {
542 Py_DECREF(field);
543 return -1;
544 }
545 Py_DECREF(field);
546 field = tmp;
547 }
548 PyList_Append(self->fields, field);
549 Py_DECREF(field);
550 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000551}
552
553static int
554parse_grow_buff(ReaderObj *self)
555{
556 if (self->field_size == 0) {
557 self->field_size = 4096;
Andrew McNamaradcfb38c2003-06-09 05:59:23 +0000558 if (self->field != NULL)
559 PyMem_Free(self->field);
Skip Montanarob4a04172003-03-20 23:29:12 +0000560 self->field = PyMem_Malloc(self->field_size);
561 }
562 else {
563 self->field_size *= 2;
564 self->field = PyMem_Realloc(self->field, self->field_size);
565 }
566 if (self->field == NULL) {
567 PyErr_NoMemory();
568 return 0;
569 }
570 return 1;
571}
572
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000573static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000574parse_add_char(ReaderObj *self, char c)
575{
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000576 if (self->field_len >= field_limit) {
577 PyErr_Format(error_obj, "field larger than field limit (%ld)",
578 field_limit);
579 return -1;
580 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000581 if (self->field_len == self->field_size && !parse_grow_buff(self))
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000582 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000583 self->field[self->field_len++] = c;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000584 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000585}
586
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000587static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000588parse_process_char(ReaderObj *self, char c)
589{
590 DialectObj *dialect = self->dialect;
591
592 switch (self->state) {
593 case START_RECORD:
594 /* start of record */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000595 if (c == '\0')
Skip Montanarob4a04172003-03-20 23:29:12 +0000596 /* empty line - return [] */
597 break;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000598 else if (c == '\n' || c == '\r') {
599 self->state = EAT_CRNL;
600 break;
601 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000602 /* normal character - handle as START_FIELD */
603 self->state = START_FIELD;
604 /* fallthru */
605 case START_FIELD:
606 /* expecting field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000607 if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000608 /* save empty field - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000609 if (parse_save_field(self) < 0)
610 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000611 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000612 }
Andrew McNamara1196cf12005-01-07 04:42:45 +0000613 else if (c == dialect->quotechar &&
614 dialect->quoting != QUOTE_NONE) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000615 /* start quoted field */
616 self->state = IN_QUOTED_FIELD;
617 }
618 else if (c == dialect->escapechar) {
619 /* possible escaped character */
620 self->state = ESCAPED_CHAR;
621 }
622 else if (c == ' ' && dialect->skipinitialspace)
623 /* ignore space at start of field */
624 ;
625 else if (c == dialect->delimiter) {
626 /* save empty field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000627 if (parse_save_field(self) < 0)
628 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000629 }
630 else {
631 /* begin new unquoted field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000632 if (dialect->quoting == QUOTE_NONNUMERIC)
633 self->numeric_field = 1;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000634 if (parse_add_char(self, c) < 0)
635 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000636 self->state = IN_FIELD;
637 }
638 break;
639
640 case ESCAPED_CHAR:
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000641 if (c == '\0')
642 c = '\n';
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000643 if (parse_add_char(self, c) < 0)
644 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000645 self->state = IN_FIELD;
646 break;
647
648 case IN_FIELD:
649 /* in unquoted field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000650 if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000651 /* end of line - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000652 if (parse_save_field(self) < 0)
653 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000654 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000655 }
656 else if (c == dialect->escapechar) {
657 /* possible escaped character */
658 self->state = ESCAPED_CHAR;
659 }
660 else if (c == dialect->delimiter) {
661 /* save field - wait for new field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000662 if (parse_save_field(self) < 0)
663 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000664 self->state = START_FIELD;
665 }
666 else {
667 /* normal character - save in field */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000668 if (parse_add_char(self, c) < 0)
669 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000670 }
671 break;
672
673 case IN_QUOTED_FIELD:
674 /* in quoted field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000675 if (c == '\0')
676 ;
Skip Montanarob4a04172003-03-20 23:29:12 +0000677 else if (c == dialect->escapechar) {
678 /* Possible escape character */
679 self->state = ESCAPE_IN_QUOTED_FIELD;
680 }
Andrew McNamara1196cf12005-01-07 04:42:45 +0000681 else if (c == dialect->quotechar &&
682 dialect->quoting != QUOTE_NONE) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000683 if (dialect->doublequote) {
684 /* doublequote; " represented by "" */
685 self->state = QUOTE_IN_QUOTED_FIELD;
686 }
687 else {
688 /* end of quote part of field */
689 self->state = IN_FIELD;
690 }
691 }
692 else {
693 /* normal character - save in field */
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 }
697 break;
698
699 case ESCAPE_IN_QUOTED_FIELD:
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000700 if (c == '\0')
701 c = '\n';
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000702 if (parse_add_char(self, c) < 0)
703 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000704 self->state = IN_QUOTED_FIELD;
705 break;
706
707 case QUOTE_IN_QUOTED_FIELD:
708 /* doublequote - seen a quote in an quoted field */
709 if (dialect->quoting != QUOTE_NONE &&
710 c == dialect->quotechar) {
711 /* save "" as " */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000712 if (parse_add_char(self, c) < 0)
713 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000714 self->state = IN_QUOTED_FIELD;
715 }
716 else if (c == dialect->delimiter) {
717 /* save field - wait for new field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000718 if (parse_save_field(self) < 0)
719 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000720 self->state = START_FIELD;
721 }
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000722 else if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000723 /* end of line - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000724 if (parse_save_field(self) < 0)
725 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000726 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000727 }
728 else if (!dialect->strict) {
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000729 if (parse_add_char(self, c) < 0)
730 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000731 self->state = IN_FIELD;
732 }
733 else {
734 /* illegal */
Andrew McNamara5cfd8372005-01-12 11:39:50 +0000735 PyErr_Format(error_obj, "'%c' expected after '%c'",
Skip Montanarob4a04172003-03-20 23:29:12 +0000736 dialect->delimiter,
737 dialect->quotechar);
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000738 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000739 }
740 break;
741
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000742 case EAT_CRNL:
743 if (c == '\n' || c == '\r')
744 ;
745 else if (c == '\0')
746 self->state = START_RECORD;
747 else {
748 PyErr_Format(error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?");
749 return -1;
750 }
751 break;
752
Skip Montanarob4a04172003-03-20 23:29:12 +0000753 }
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000754 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000755}
756
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000757static int
758parse_reset(ReaderObj *self)
759{
760 Py_XDECREF(self->fields);
761 self->fields = PyList_New(0);
762 if (self->fields == NULL)
763 return -1;
764 self->field_len = 0;
765 self->state = START_RECORD;
766 self->numeric_field = 0;
767 return 0;
768}
Skip Montanarob4a04172003-03-20 23:29:12 +0000769
770static PyObject *
Skip Montanarob4a04172003-03-20 23:29:12 +0000771Reader_iternext(ReaderObj *self)
772{
773 PyObject *lineobj;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000774 PyObject *fields = NULL;
775 char *line, c;
776 int linelen;
Skip Montanarob4a04172003-03-20 23:29:12 +0000777
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000778 if (parse_reset(self) < 0)
779 return NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000780 do {
781 lineobj = PyIter_Next(self->input_iter);
782 if (lineobj == NULL) {
783 /* End of input OR exception */
784 if (!PyErr_Occurred() && self->field_len != 0)
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000785 PyErr_Format(error_obj,
786 "newline inside string");
Skip Montanarob4a04172003-03-20 23:29:12 +0000787 return NULL;
788 }
Andrew McNamara7f2053e2005-01-12 11:17:16 +0000789 ++self->line_num;
Skip Montanarob4a04172003-03-20 23:29:12 +0000790
Skip Montanarob4a04172003-03-20 23:29:12 +0000791 line = PyString_AsString(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000792 linelen = PyString_Size(lineobj);
Skip Montanarob4a04172003-03-20 23:29:12 +0000793
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000794 if (line == NULL || linelen < 0) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000795 Py_DECREF(lineobj);
796 return NULL;
797 }
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000798 while (linelen--) {
799 c = *line++;
800 if (c == '\0') {
801 Py_DECREF(lineobj);
802 PyErr_Format(error_obj,
803 "line contains NULL byte");
804 goto err;
805 }
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000806 if (parse_process_char(self, c) < 0) {
807 Py_DECREF(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000808 goto err;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000809 }
810 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000811 Py_DECREF(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000812 if (parse_process_char(self, 0) < 0)
813 goto err;
Skip Montanarob4a04172003-03-20 23:29:12 +0000814 } while (self->state != START_RECORD);
815
816 fields = self->fields;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000817 self->fields = NULL;
818err:
Skip Montanarob4a04172003-03-20 23:29:12 +0000819 return fields;
820}
821
822static void
823Reader_dealloc(ReaderObj *self)
824{
Andrew McNamara77ead872005-01-10 02:09:41 +0000825 PyObject_GC_UnTrack(self);
Skip Montanarob4a04172003-03-20 23:29:12 +0000826 Py_XDECREF(self->dialect);
827 Py_XDECREF(self->input_iter);
828 Py_XDECREF(self->fields);
Andrew McNamaradcfb38c2003-06-09 05:59:23 +0000829 if (self->field != NULL)
830 PyMem_Free(self->field);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000831 PyObject_GC_Del(self);
832}
833
834static int
835Reader_traverse(ReaderObj *self, visitproc visit, void *arg)
836{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000837 Py_VISIT(self->dialect);
838 Py_VISIT(self->input_iter);
839 Py_VISIT(self->fields);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000840 return 0;
841}
842
843static int
844Reader_clear(ReaderObj *self)
845{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000846 Py_CLEAR(self->dialect);
847 Py_CLEAR(self->input_iter);
848 Py_CLEAR(self->fields);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000849 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000850}
851
852PyDoc_STRVAR(Reader_Type_doc,
853"CSV reader\n"
854"\n"
855"Reader objects are responsible for reading and parsing tabular data\n"
856"in CSV format.\n"
857);
858
859static struct PyMethodDef Reader_methods[] = {
860 { NULL, NULL }
861};
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000862#define R_OFF(x) offsetof(ReaderObj, x)
863
864static struct PyMemberDef Reader_memberlist[] = {
865 { "dialect", T_OBJECT, R_OFF(dialect), RO },
866 { "line_num", T_ULONG, R_OFF(line_num), RO },
867 { NULL }
868};
869
Skip Montanarob4a04172003-03-20 23:29:12 +0000870
871static PyTypeObject Reader_Type = {
872 PyObject_HEAD_INIT(NULL)
873 0, /*ob_size*/
874 "_csv.reader", /*tp_name*/
875 sizeof(ReaderObj), /*tp_basicsize*/
876 0, /*tp_itemsize*/
877 /* methods */
878 (destructor)Reader_dealloc, /*tp_dealloc*/
879 (printfunc)0, /*tp_print*/
880 (getattrfunc)0, /*tp_getattr*/
881 (setattrfunc)0, /*tp_setattr*/
882 (cmpfunc)0, /*tp_compare*/
883 (reprfunc)0, /*tp_repr*/
884 0, /*tp_as_number*/
885 0, /*tp_as_sequence*/
886 0, /*tp_as_mapping*/
887 (hashfunc)0, /*tp_hash*/
888 (ternaryfunc)0, /*tp_call*/
889 (reprfunc)0, /*tp_str*/
890 0, /*tp_getattro*/
891 0, /*tp_setattro*/
892 0, /*tp_as_buffer*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000893 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
894 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000895 Reader_Type_doc, /*tp_doc*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000896 (traverseproc)Reader_traverse, /*tp_traverse*/
897 (inquiry)Reader_clear, /*tp_clear*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000898 0, /*tp_richcompare*/
899 0, /*tp_weaklistoffset*/
Andrew McNamara575a00b2005-01-06 02:25:41 +0000900 PyObject_SelfIter, /*tp_iter*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000901 (getiterfunc)Reader_iternext, /*tp_iternext*/
902 Reader_methods, /*tp_methods*/
903 Reader_memberlist, /*tp_members*/
904 0, /*tp_getset*/
905
906};
907
908static PyObject *
909csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
910{
Andrew McNamara91b97462005-01-11 01:07:23 +0000911 PyObject * iterator, * dialect = NULL;
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000912 ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +0000913
914 if (!self)
915 return NULL;
916
917 self->dialect = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000918 self->fields = NULL;
919 self->input_iter = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000920 self->field = NULL;
921 self->field_size = 0;
Andrew McNamara7f2053e2005-01-12 11:17:16 +0000922 self->line_num = 0;
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000923
924 if (parse_reset(self) < 0) {
925 Py_DECREF(self);
926 return NULL;
927 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000928
Raymond Hettinger1761a7c2004-06-20 04:23:19 +0000929 if (!PyArg_UnpackTuple(args, "", 1, 2, &iterator, &dialect)) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000930 Py_DECREF(self);
931 return NULL;
932 }
933 self->input_iter = PyObject_GetIter(iterator);
934 if (self->input_iter == NULL) {
935 PyErr_SetString(PyExc_TypeError,
936 "argument 1 must be an iterator");
937 Py_DECREF(self);
938 return NULL;
939 }
Andrew McNamara91b97462005-01-11 01:07:23 +0000940 self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
Skip Montanarob4a04172003-03-20 23:29:12 +0000941 if (self->dialect == NULL) {
942 Py_DECREF(self);
943 return NULL;
944 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000945
Andrew McNamara77ead872005-01-10 02:09:41 +0000946 PyObject_GC_Track(self);
Skip Montanarob4a04172003-03-20 23:29:12 +0000947 return (PyObject *)self;
948}
949
950/*
951 * WRITER
952 */
953/* ---------------------------------------------------------------- */
954static void
955join_reset(WriterObj *self)
956{
957 self->rec_len = 0;
958 self->num_fields = 0;
959}
960
961#define MEM_INCR 32768
962
963/* Calculate new record length or append field to record. Return new
964 * record length.
965 */
966static int
967join_append_data(WriterObj *self, char *field, int quote_empty,
968 int *quoted, int copy_phase)
969{
970 DialectObj *dialect = self->dialect;
971 int i, rec_len;
Andrew McNamarac89f2842005-01-12 07:44:42 +0000972 char *lineterm;
973
974#define ADDCH(c) \
975 do {\
976 if (copy_phase) \
977 self->rec[rec_len] = c;\
978 rec_len++;\
979 } while(0)
980
981 lineterm = PyString_AsString(dialect->lineterminator);
982 if (lineterm == NULL)
983 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000984
985 rec_len = self->rec_len;
986
Andrew McNamarac89f2842005-01-12 07:44:42 +0000987 /* If this is not the first field we need a field separator */
988 if (self->num_fields > 0)
989 ADDCH(dialect->delimiter);
990
991 /* Handle preceding quote */
992 if (copy_phase && *quoted)
993 ADDCH(dialect->quotechar);
994
995 /* Copy/count field data */
Skip Montanarob4a04172003-03-20 23:29:12 +0000996 for (i = 0;; i++) {
997 char c = field[i];
Andrew McNamarac89f2842005-01-12 07:44:42 +0000998 int want_escape = 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000999
1000 if (c == '\0')
1001 break;
Skip Montanarob4a04172003-03-20 23:29:12 +00001002
Andrew McNamarac89f2842005-01-12 07:44:42 +00001003 if (c == dialect->delimiter ||
1004 c == dialect->escapechar ||
1005 c == dialect->quotechar ||
1006 strchr(lineterm, c)) {
1007 if (dialect->quoting == QUOTE_NONE)
1008 want_escape = 1;
Skip Montanarob4a04172003-03-20 23:29:12 +00001009 else {
Andrew McNamarac89f2842005-01-12 07:44:42 +00001010 if (c == dialect->quotechar) {
1011 if (dialect->doublequote)
1012 ADDCH(dialect->quotechar);
1013 else
1014 want_escape = 1;
1015 }
1016 if (!want_escape)
1017 *quoted = 1;
1018 }
1019 if (want_escape) {
1020 if (!dialect->escapechar) {
1021 PyErr_Format(error_obj,
1022 "need to escape, but no escapechar set");
1023 return -1;
1024 }
1025 ADDCH(dialect->escapechar);
Skip Montanarob4a04172003-03-20 23:29:12 +00001026 }
1027 }
1028 /* Copy field character into record buffer.
1029 */
Andrew McNamarac89f2842005-01-12 07:44:42 +00001030 ADDCH(c);
Skip Montanarob4a04172003-03-20 23:29:12 +00001031 }
1032
1033 /* If field is empty check if it needs to be quoted.
1034 */
1035 if (i == 0 && quote_empty) {
1036 if (dialect->quoting == QUOTE_NONE) {
1037 PyErr_Format(error_obj,
1038 "single empty field record must be quoted");
1039 return -1;
Andrew McNamaradd3e6cb2005-01-07 06:46:50 +00001040 }
1041 else
Skip Montanarob4a04172003-03-20 23:29:12 +00001042 *quoted = 1;
1043 }
1044
Skip Montanarob4a04172003-03-20 23:29:12 +00001045 if (*quoted) {
1046 if (copy_phase)
Andrew McNamarac89f2842005-01-12 07:44:42 +00001047 ADDCH(dialect->quotechar);
Skip Montanarob4a04172003-03-20 23:29:12 +00001048 else
Andrew McNamarac89f2842005-01-12 07:44:42 +00001049 rec_len += 2;
Skip Montanarob4a04172003-03-20 23:29:12 +00001050 }
Skip Montanarob4a04172003-03-20 23:29:12 +00001051 return rec_len;
Andrew McNamarac89f2842005-01-12 07:44:42 +00001052#undef ADDCH
Skip Montanarob4a04172003-03-20 23:29:12 +00001053}
1054
1055static int
1056join_check_rec_size(WriterObj *self, int rec_len)
1057{
1058 if (rec_len > self->rec_size) {
1059 if (self->rec_size == 0) {
1060 self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
Andrew McNamaradcfb38c2003-06-09 05:59:23 +00001061 if (self->rec != NULL)
1062 PyMem_Free(self->rec);
Skip Montanarob4a04172003-03-20 23:29:12 +00001063 self->rec = PyMem_Malloc(self->rec_size);
1064 }
1065 else {
1066 char *old_rec = self->rec;
1067
1068 self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
1069 self->rec = PyMem_Realloc(self->rec, self->rec_size);
1070 if (self->rec == NULL)
1071 PyMem_Free(old_rec);
1072 }
1073 if (self->rec == NULL) {
1074 PyErr_NoMemory();
1075 return 0;
1076 }
1077 }
1078 return 1;
1079}
1080
1081static int
1082join_append(WriterObj *self, char *field, int *quoted, int quote_empty)
1083{
1084 int rec_len;
1085
1086 rec_len = join_append_data(self, field, quote_empty, quoted, 0);
1087 if (rec_len < 0)
1088 return 0;
1089
1090 /* grow record buffer if necessary */
1091 if (!join_check_rec_size(self, rec_len))
1092 return 0;
1093
1094 self->rec_len = join_append_data(self, field, quote_empty, quoted, 1);
1095 self->num_fields++;
1096
1097 return 1;
1098}
1099
1100static int
1101join_append_lineterminator(WriterObj *self)
1102{
1103 int terminator_len;
Andrew McNamaracf0fd5a2005-01-12 01:16:35 +00001104 char *terminator;
Skip Montanarob4a04172003-03-20 23:29:12 +00001105
1106 terminator_len = PyString_Size(self->dialect->lineterminator);
1107
1108 /* grow record buffer if necessary */
1109 if (!join_check_rec_size(self, self->rec_len + terminator_len))
1110 return 0;
1111
Andrew McNamaracf0fd5a2005-01-12 01:16:35 +00001112 terminator = PyString_AsString(self->dialect->lineterminator);
1113 if (terminator == NULL)
1114 return 0;
1115 memmove(self->rec + self->rec_len, terminator, terminator_len);
Skip Montanarob4a04172003-03-20 23:29:12 +00001116 self->rec_len += terminator_len;
1117
1118 return 1;
1119}
1120
1121PyDoc_STRVAR(csv_writerow_doc,
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001122"writerow(sequence)\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001123"\n"
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001124"Construct and write a CSV record from a sequence of fields. Non-string\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001125"elements will be converted to string.");
1126
1127static PyObject *
1128csv_writerow(WriterObj *self, PyObject *seq)
1129{
1130 DialectObj *dialect = self->dialect;
1131 int len, i;
1132
1133 if (!PySequence_Check(seq))
1134 return PyErr_Format(error_obj, "sequence expected");
1135
1136 len = PySequence_Length(seq);
1137 if (len < 0)
1138 return NULL;
1139
1140 /* Join all fields in internal buffer.
1141 */
1142 join_reset(self);
1143 for (i = 0; i < len; i++) {
1144 PyObject *field;
1145 int append_ok;
1146 int quoted;
1147
1148 field = PySequence_GetItem(seq, i);
1149 if (field == NULL)
1150 return NULL;
1151
Andrew McNamarac89f2842005-01-12 07:44:42 +00001152 switch (dialect->quoting) {
1153 case QUOTE_NONNUMERIC:
1154 quoted = !PyNumber_Check(field);
1155 break;
1156 case QUOTE_ALL:
1157 quoted = 1;
1158 break;
1159 default:
1160 quoted = 0;
1161 break;
Skip Montanarob4a04172003-03-20 23:29:12 +00001162 }
1163
1164 if (PyString_Check(field)) {
Skip Montanaro577c7a72003-04-12 19:17:14 +00001165 append_ok = join_append(self,
1166 PyString_AS_STRING(field),
Skip Montanarob4a04172003-03-20 23:29:12 +00001167 &quoted, len == 1);
1168 Py_DECREF(field);
1169 }
1170 else if (field == Py_None) {
1171 append_ok = join_append(self, "", &quoted, len == 1);
1172 Py_DECREF(field);
1173 }
1174 else {
1175 PyObject *str;
1176
1177 str = PyObject_Str(field);
1178 Py_DECREF(field);
1179 if (str == NULL)
1180 return NULL;
1181
Skip Montanaro577c7a72003-04-12 19:17:14 +00001182 append_ok = join_append(self, PyString_AS_STRING(str),
Skip Montanarob4a04172003-03-20 23:29:12 +00001183 &quoted, len == 1);
1184 Py_DECREF(str);
1185 }
1186 if (!append_ok)
1187 return NULL;
1188 }
1189
1190 /* Add line terminator.
1191 */
1192 if (!join_append_lineterminator(self))
1193 return 0;
1194
1195 return PyObject_CallFunction(self->writeline,
1196 "(s#)", self->rec, self->rec_len);
1197}
1198
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001199PyDoc_STRVAR(csv_writerows_doc,
1200"writerows(sequence of sequences)\n"
1201"\n"
1202"Construct and write a series of sequences to a csv file. Non-string\n"
1203"elements will be converted to string.");
1204
Skip Montanarob4a04172003-03-20 23:29:12 +00001205static PyObject *
1206csv_writerows(WriterObj *self, PyObject *seqseq)
1207{
1208 PyObject *row_iter, *row_obj, *result;
1209
1210 row_iter = PyObject_GetIter(seqseq);
1211 if (row_iter == NULL) {
1212 PyErr_SetString(PyExc_TypeError,
Skip Montanaro98f16e02003-04-11 23:10:13 +00001213 "writerows() argument must be iterable");
Skip Montanarob4a04172003-03-20 23:29:12 +00001214 return NULL;
1215 }
1216 while ((row_obj = PyIter_Next(row_iter))) {
1217 result = csv_writerow(self, row_obj);
1218 Py_DECREF(row_obj);
1219 if (!result) {
1220 Py_DECREF(row_iter);
1221 return NULL;
1222 }
1223 else
1224 Py_DECREF(result);
1225 }
1226 Py_DECREF(row_iter);
1227 if (PyErr_Occurred())
1228 return NULL;
1229 Py_INCREF(Py_None);
1230 return Py_None;
1231}
1232
1233static struct PyMethodDef Writer_methods[] = {
1234 { "writerow", (PyCFunction)csv_writerow, METH_O, csv_writerow_doc},
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001235 { "writerows", (PyCFunction)csv_writerows, METH_O, csv_writerows_doc},
Skip Montanarob4a04172003-03-20 23:29:12 +00001236 { NULL, NULL }
1237};
1238
1239#define W_OFF(x) offsetof(WriterObj, x)
1240
1241static struct PyMemberDef Writer_memberlist[] = {
1242 { "dialect", T_OBJECT, W_OFF(dialect), RO },
1243 { NULL }
1244};
1245
1246static void
1247Writer_dealloc(WriterObj *self)
1248{
Andrew McNamara77ead872005-01-10 02:09:41 +00001249 PyObject_GC_UnTrack(self);
Skip Montanarob4a04172003-03-20 23:29:12 +00001250 Py_XDECREF(self->dialect);
1251 Py_XDECREF(self->writeline);
Andrew McNamaradcfb38c2003-06-09 05:59:23 +00001252 if (self->rec != NULL)
1253 PyMem_Free(self->rec);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001254 PyObject_GC_Del(self);
1255}
1256
1257static int
1258Writer_traverse(WriterObj *self, visitproc visit, void *arg)
1259{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001260 Py_VISIT(self->dialect);
1261 Py_VISIT(self->writeline);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001262 return 0;
1263}
1264
1265static int
1266Writer_clear(WriterObj *self)
1267{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001268 Py_CLEAR(self->dialect);
1269 Py_CLEAR(self->writeline);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001270 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +00001271}
1272
1273PyDoc_STRVAR(Writer_Type_doc,
1274"CSV writer\n"
1275"\n"
1276"Writer objects are responsible for generating tabular data\n"
1277"in CSV format from sequence input.\n"
1278);
1279
1280static PyTypeObject Writer_Type = {
1281 PyObject_HEAD_INIT(NULL)
1282 0, /*ob_size*/
1283 "_csv.writer", /*tp_name*/
1284 sizeof(WriterObj), /*tp_basicsize*/
1285 0, /*tp_itemsize*/
1286 /* methods */
1287 (destructor)Writer_dealloc, /*tp_dealloc*/
1288 (printfunc)0, /*tp_print*/
1289 (getattrfunc)0, /*tp_getattr*/
1290 (setattrfunc)0, /*tp_setattr*/
1291 (cmpfunc)0, /*tp_compare*/
1292 (reprfunc)0, /*tp_repr*/
1293 0, /*tp_as_number*/
1294 0, /*tp_as_sequence*/
1295 0, /*tp_as_mapping*/
1296 (hashfunc)0, /*tp_hash*/
1297 (ternaryfunc)0, /*tp_call*/
1298 (reprfunc)0, /*tp_str*/
1299 0, /*tp_getattro*/
1300 0, /*tp_setattro*/
1301 0, /*tp_as_buffer*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001302 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1303 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Skip Montanarob4a04172003-03-20 23:29:12 +00001304 Writer_Type_doc,
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001305 (traverseproc)Writer_traverse, /*tp_traverse*/
1306 (inquiry)Writer_clear, /*tp_clear*/
Skip Montanarob4a04172003-03-20 23:29:12 +00001307 0, /*tp_richcompare*/
1308 0, /*tp_weaklistoffset*/
1309 (getiterfunc)0, /*tp_iter*/
1310 (getiterfunc)0, /*tp_iternext*/
1311 Writer_methods, /*tp_methods*/
1312 Writer_memberlist, /*tp_members*/
1313 0, /*tp_getset*/
1314};
1315
1316static PyObject *
1317csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)
1318{
Andrew McNamara91b97462005-01-11 01:07:23 +00001319 PyObject * output_file, * dialect = NULL;
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001320 WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +00001321
1322 if (!self)
1323 return NULL;
1324
1325 self->dialect = NULL;
1326 self->writeline = NULL;
1327
1328 self->rec = NULL;
1329 self->rec_size = 0;
1330 self->rec_len = 0;
1331 self->num_fields = 0;
1332
Raymond Hettinger1761a7c2004-06-20 04:23:19 +00001333 if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) {
Skip Montanarob4a04172003-03-20 23:29:12 +00001334 Py_DECREF(self);
1335 return NULL;
1336 }
1337 self->writeline = PyObject_GetAttrString(output_file, "write");
1338 if (self->writeline == NULL || !PyCallable_Check(self->writeline)) {
1339 PyErr_SetString(PyExc_TypeError,
Andrew McNamara5cfd8372005-01-12 11:39:50 +00001340 "argument 1 must have a \"write\" method");
Skip Montanarob4a04172003-03-20 23:29:12 +00001341 Py_DECREF(self);
1342 return NULL;
1343 }
Andrew McNamara91b97462005-01-11 01:07:23 +00001344 self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
Skip Montanarob4a04172003-03-20 23:29:12 +00001345 if (self->dialect == NULL) {
1346 Py_DECREF(self);
1347 return NULL;
1348 }
Andrew McNamara77ead872005-01-10 02:09:41 +00001349 PyObject_GC_Track(self);
Skip Montanarob4a04172003-03-20 23:29:12 +00001350 return (PyObject *)self;
1351}
1352
1353/*
1354 * DIALECT REGISTRY
1355 */
1356static PyObject *
1357csv_list_dialects(PyObject *module, PyObject *args)
1358{
1359 return PyDict_Keys(dialects);
1360}
1361
1362static PyObject *
Andrew McNamara86625972005-01-11 01:28:33 +00001363csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs)
Skip Montanarob4a04172003-03-20 23:29:12 +00001364{
Andrew McNamara86625972005-01-11 01:28:33 +00001365 PyObject *name_obj, *dialect_obj = NULL;
1366 PyObject *dialect;
Skip Montanarob4a04172003-03-20 23:29:12 +00001367
Andrew McNamara86625972005-01-11 01:28:33 +00001368 if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj))
Skip Montanarob4a04172003-03-20 23:29:12 +00001369 return NULL;
Andrew McNamara37d2bdf2005-01-10 12:22:48 +00001370 if (!IS_BASESTRING(name_obj)) {
Skip Montanarob4a04172003-03-20 23:29:12 +00001371 PyErr_SetString(PyExc_TypeError,
1372 "dialect name must be a string or unicode");
1373 return NULL;
1374 }
Andrew McNamara86625972005-01-11 01:28:33 +00001375 dialect = _call_dialect(dialect_obj, kwargs);
1376 if (dialect == NULL)
1377 return NULL;
1378 if (PyDict_SetItem(dialects, name_obj, dialect) < 0) {
1379 Py_DECREF(dialect);
Skip Montanarob4a04172003-03-20 23:29:12 +00001380 return NULL;
1381 }
Andrew McNamara86625972005-01-11 01:28:33 +00001382 Py_DECREF(dialect);
Skip Montanarob4a04172003-03-20 23:29:12 +00001383 Py_INCREF(Py_None);
1384 return Py_None;
1385}
1386
1387static PyObject *
Skip Montanaro577c7a72003-04-12 19:17:14 +00001388csv_unregister_dialect(PyObject *module, PyObject *name_obj)
Skip Montanarob4a04172003-03-20 23:29:12 +00001389{
Skip Montanarob4a04172003-03-20 23:29:12 +00001390 if (PyDict_DelItem(dialects, name_obj) < 0)
1391 return PyErr_Format(error_obj, "unknown dialect");
1392 Py_INCREF(Py_None);
1393 return Py_None;
1394}
1395
1396static PyObject *
Skip Montanaro577c7a72003-04-12 19:17:14 +00001397csv_get_dialect(PyObject *module, PyObject *name_obj)
Skip Montanarob4a04172003-03-20 23:29:12 +00001398{
Skip Montanarob4a04172003-03-20 23:29:12 +00001399 return get_dialect_from_registry(name_obj);
1400}
1401
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001402static PyObject *
Andrew McNamara31d88962005-01-12 03:45:10 +00001403csv_field_size_limit(PyObject *module, PyObject *args)
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001404{
1405 PyObject *new_limit = NULL;
1406 long old_limit = field_limit;
1407
Andrew McNamara31d88962005-01-12 03:45:10 +00001408 if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit))
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001409 return NULL;
1410 if (new_limit != NULL) {
1411 if (!PyInt_Check(new_limit)) {
1412 PyErr_Format(PyExc_TypeError,
1413 "limit must be an integer");
1414 return NULL;
1415 }
1416 field_limit = PyInt_AsLong(new_limit);
1417 }
1418 return PyInt_FromLong(old_limit);
1419}
1420
Skip Montanarob4a04172003-03-20 23:29:12 +00001421/*
1422 * MODULE
1423 */
1424
1425PyDoc_STRVAR(csv_module_doc,
1426"CSV parsing and writing.\n"
1427"\n"
1428"This module provides classes that assist in the reading and writing\n"
1429"of Comma Separated Value (CSV) files, and implements the interface\n"
1430"described by PEP 305. Although many CSV files are simple to parse,\n"
1431"the format is not formally defined by a stable specification and\n"
1432"is subtle enough that parsing lines of a CSV file with something\n"
1433"like line.split(\",\") is bound to fail. The module supports three\n"
1434"basic APIs: reading, writing, and registration of dialects.\n"
1435"\n"
1436"\n"
1437"DIALECT REGISTRATION:\n"
1438"\n"
1439"Readers and writers support a dialect argument, which is a convenient\n"
1440"handle on a group of settings. When the dialect argument is a string,\n"
1441"it identifies one of the dialects previously registered with the module.\n"
1442"If it is a class or instance, the attributes of the argument are used as\n"
1443"the settings for the reader or writer:\n"
1444"\n"
1445" class excel:\n"
1446" delimiter = ','\n"
1447" quotechar = '\"'\n"
1448" escapechar = None\n"
1449" doublequote = True\n"
1450" skipinitialspace = False\n"
Johannes Gijsbers8d3b9dd2004-08-15 12:23:10 +00001451" lineterminator = '\\r\\n'\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001452" quoting = QUOTE_MINIMAL\n"
1453"\n"
1454"SETTINGS:\n"
1455"\n"
1456" * quotechar - specifies a one-character string to use as the \n"
1457" quoting character. It defaults to '\"'.\n"
1458" * delimiter - specifies a one-character string to use as the \n"
1459" field separator. It defaults to ','.\n"
1460" * skipinitialspace - specifies how to interpret whitespace which\n"
1461" immediately follows a delimiter. It defaults to False, which\n"
1462" means that whitespace immediately following a delimiter is part\n"
1463" of the following field.\n"
1464" * lineterminator - specifies the character sequence which should \n"
1465" terminate rows.\n"
1466" * quoting - controls when quotes should be generated by the writer.\n"
1467" It can take on any of the following module constants:\n"
1468"\n"
1469" csv.QUOTE_MINIMAL means only when required, for example, when a\n"
1470" field contains either the quotechar or the delimiter\n"
1471" csv.QUOTE_ALL means that quotes are always placed around fields.\n"
1472" csv.QUOTE_NONNUMERIC means that quotes are always placed around\n"
Skip Montanaro148eb6a2003-12-02 18:57:47 +00001473" fields which do not parse as integers or floating point\n"
1474" numbers.\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001475" csv.QUOTE_NONE means that quotes are never placed around fields.\n"
1476" * escapechar - specifies a one-character string used to escape \n"
1477" the delimiter when quoting is set to QUOTE_NONE.\n"
1478" * doublequote - controls the handling of quotes inside fields. When\n"
1479" True, two consecutive quotes are interpreted as one during read,\n"
1480" and when writing, each quote character embedded in the data is\n"
1481" written as two quotes\n");
1482
1483PyDoc_STRVAR(csv_reader_doc,
1484" csv_reader = reader(iterable [, dialect='excel']\n"
1485" [optional keyword args])\n"
1486" for row in csv_reader:\n"
1487" process(row)\n"
1488"\n"
1489"The \"iterable\" argument can be any object that returns a line\n"
1490"of input for each iteration, such as a file object or a list. The\n"
1491"optional \"dialect\" parameter is discussed below. The function\n"
1492"also accepts optional keyword arguments which override settings\n"
1493"provided by the dialect.\n"
1494"\n"
1495"The returned object is an iterator. Each iteration returns a row\n"
Johannes Gijsbers8d3b9dd2004-08-15 12:23:10 +00001496"of the CSV file (which can span multiple input lines):\n");
Skip Montanarob4a04172003-03-20 23:29:12 +00001497
1498PyDoc_STRVAR(csv_writer_doc,
1499" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1500" [optional keyword args])\n"
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001501" for row in sequence:\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001502" csv_writer.writerow(row)\n"
1503"\n"
1504" [or]\n"
1505"\n"
1506" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1507" [optional keyword args])\n"
1508" csv_writer.writerows(rows)\n"
1509"\n"
1510"The \"fileobj\" argument can be any object that supports the file API.\n");
1511
1512PyDoc_STRVAR(csv_list_dialects_doc,
1513"Return a list of all know dialect names.\n"
1514" names = csv.list_dialects()");
1515
1516PyDoc_STRVAR(csv_get_dialect_doc,
1517"Return the dialect instance associated with name.\n"
1518" dialect = csv.get_dialect(name)");
1519
1520PyDoc_STRVAR(csv_register_dialect_doc,
1521"Create a mapping from a string name to a dialect class.\n"
1522" dialect = csv.register_dialect(name, dialect)");
1523
1524PyDoc_STRVAR(csv_unregister_dialect_doc,
1525"Delete the name/dialect mapping associated with a string name.\n"
1526" csv.unregister_dialect(name)");
1527
Andrew McNamara31d88962005-01-12 03:45:10 +00001528PyDoc_STRVAR(csv_field_size_limit_doc,
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001529"Sets an upper limit on parsed fields.\n"
Andrew McNamara31d88962005-01-12 03:45:10 +00001530" csv.field_size_limit([limit])\n"
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001531"\n"
1532"Returns old limit. If limit is not given, no new limit is set and\n"
1533"the old limit is returned");
1534
Skip Montanarob4a04172003-03-20 23:29:12 +00001535static struct PyMethodDef csv_methods[] = {
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001536 { "reader", (PyCFunction)csv_reader,
1537 METH_VARARGS | METH_KEYWORDS, csv_reader_doc},
1538 { "writer", (PyCFunction)csv_writer,
1539 METH_VARARGS | METH_KEYWORDS, csv_writer_doc},
1540 { "list_dialects", (PyCFunction)csv_list_dialects,
1541 METH_NOARGS, csv_list_dialects_doc},
1542 { "register_dialect", (PyCFunction)csv_register_dialect,
Andrew McNamara86625972005-01-11 01:28:33 +00001543 METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001544 { "unregister_dialect", (PyCFunction)csv_unregister_dialect,
1545 METH_O, csv_unregister_dialect_doc},
1546 { "get_dialect", (PyCFunction)csv_get_dialect,
1547 METH_O, csv_get_dialect_doc},
Andrew McNamara31d88962005-01-12 03:45:10 +00001548 { "field_size_limit", (PyCFunction)csv_field_size_limit,
1549 METH_VARARGS, csv_field_size_limit_doc},
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001550 { NULL, NULL }
Skip Montanarob4a04172003-03-20 23:29:12 +00001551};
1552
1553PyMODINIT_FUNC
1554init_csv(void)
1555{
1556 PyObject *module;
Skip Montanarob4a04172003-03-20 23:29:12 +00001557 StyleDesc *style;
1558
1559 if (PyType_Ready(&Dialect_Type) < 0)
1560 return;
1561
1562 if (PyType_Ready(&Reader_Type) < 0)
1563 return;
1564
1565 if (PyType_Ready(&Writer_Type) < 0)
1566 return;
1567
1568 /* Create the module and add the functions */
1569 module = Py_InitModule3("_csv", csv_methods, csv_module_doc);
1570 if (module == NULL)
1571 return;
1572
1573 /* Add version to the module. */
Skip Montanaro7b01a832003-04-12 19:23:46 +00001574 if (PyModule_AddStringConstant(module, "__version__",
1575 MODULE_VERSION) == -1)
Skip Montanarob4a04172003-03-20 23:29:12 +00001576 return;
1577
1578 /* Add _dialects dictionary */
1579 dialects = PyDict_New();
1580 if (dialects == NULL)
1581 return;
1582 if (PyModule_AddObject(module, "_dialects", dialects))
1583 return;
1584
1585 /* Add quote styles into dictionary */
1586 for (style = quote_styles; style->name; style++) {
Skip Montanaro7b01a832003-04-12 19:23:46 +00001587 if (PyModule_AddIntConstant(module, style->name,
1588 style->style) == -1)
Skip Montanarob4a04172003-03-20 23:29:12 +00001589 return;
1590 }
1591
1592 /* Add the Dialect type */
Skip Montanaro32c5d422005-06-15 13:35:08 +00001593 Py_INCREF(&Dialect_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +00001594 if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
1595 return;
1596
1597 /* Add the CSV exception object to the module. */
1598 error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
1599 if (error_obj == NULL)
1600 return;
1601 PyModule_AddObject(module, "Error", error_obj);
1602}