blob: 2cd91998e1384a80da6c315dd90a605682b5fd6c [file] [log] [blame]
Skip Montanaroa16b21f2003-03-23 14:32:54 +00001/* csv module */
2
3/*
4
5This module provides the low-level underpinnings of a CSV reading/writing
6module. Users should not use this module directly, but import the csv.py
7module instead.
8
9**** For people modifying this code, please note that as of this writing
Skip Montanarodfa35fa2003-04-11 21:40:01 +000010**** (2003-03-23), it is intended that this code should work with Python
Skip Montanaroa16b21f2003-03-23 14:32:54 +000011**** 2.2.
12
Skip Montanarob4a04172003-03-20 23:29:12 +000013*/
14
Skip Montanaro7b01a832003-04-12 19:23:46 +000015#define MODULE_VERSION "1.0"
16
Skip Montanarob4a04172003-03-20 23:29:12 +000017#include "Python.h"
18#include "structmember.h"
19
Skip Montanaroa16b21f2003-03-23 14:32:54 +000020
Skip Montanarob4a04172003-03-20 23:29:12 +000021/* begin 2.2 compatibility macros */
22#ifndef PyDoc_STRVAR
23/* Define macros for inline documentation. */
24#define PyDoc_VAR(name) static char name[]
25#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
26#ifdef WITH_DOC_STRINGS
27#define PyDoc_STR(str) str
28#else
29#define PyDoc_STR(str) ""
30#endif
31#endif /* ifndef PyDoc_STRVAR */
32
33#ifndef PyMODINIT_FUNC
34# if defined(__cplusplus)
35# define PyMODINIT_FUNC extern "C" void
36# else /* __cplusplus */
37# define PyMODINIT_FUNC void
38# endif /* __cplusplus */
39#endif
Thomas Wouters2742c5e2006-04-15 17:33:14 +000040
41#ifndef Py_CLEAR
42#define Py_CLEAR(op) \
43 do { \
44 if (op) { \
45 PyObject *tmp = (PyObject *)(op); \
46 (op) = NULL; \
47 Py_DECREF(tmp); \
48 } \
49 } while (0)
50#endif
Thomas Woutersc6e55062006-04-15 21:47:09 +000051#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
Thomas Wouters2742c5e2006-04-15 17:33:14 +000061
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
108staticforward PyTypeObject Dialect_Type;
109
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
126staticforward PyTypeObject Reader_Type;
127
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
143staticforward PyTypeObject Writer_Type;
144
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 {
Martin v. Löwis73c01d42008-02-14 11:26:18 +0000563 if (self->field_size > INT_MAX / 2) {
564 PyErr_NoMemory();
565 return 0;
566 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000567 self->field_size *= 2;
568 self->field = PyMem_Realloc(self->field, self->field_size);
569 }
570 if (self->field == NULL) {
571 PyErr_NoMemory();
572 return 0;
573 }
574 return 1;
575}
576
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000577static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000578parse_add_char(ReaderObj *self, char c)
579{
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000580 if (self->field_len >= field_limit) {
581 PyErr_Format(error_obj, "field larger than field limit (%ld)",
582 field_limit);
583 return -1;
584 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000585 if (self->field_len == self->field_size && !parse_grow_buff(self))
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000586 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000587 self->field[self->field_len++] = c;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000588 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000589}
590
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000591static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000592parse_process_char(ReaderObj *self, char c)
593{
594 DialectObj *dialect = self->dialect;
595
596 switch (self->state) {
597 case START_RECORD:
598 /* start of record */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000599 if (c == '\0')
Skip Montanarob4a04172003-03-20 23:29:12 +0000600 /* empty line - return [] */
601 break;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000602 else if (c == '\n' || c == '\r') {
603 self->state = EAT_CRNL;
604 break;
605 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000606 /* normal character - handle as START_FIELD */
607 self->state = START_FIELD;
608 /* fallthru */
609 case START_FIELD:
610 /* expecting field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000611 if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000612 /* save empty field - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000613 if (parse_save_field(self) < 0)
614 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000615 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000616 }
Andrew McNamara1196cf12005-01-07 04:42:45 +0000617 else if (c == dialect->quotechar &&
618 dialect->quoting != QUOTE_NONE) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000619 /* start quoted field */
620 self->state = IN_QUOTED_FIELD;
621 }
622 else if (c == dialect->escapechar) {
623 /* possible escaped character */
624 self->state = ESCAPED_CHAR;
625 }
626 else if (c == ' ' && dialect->skipinitialspace)
627 /* ignore space at start of field */
628 ;
629 else if (c == dialect->delimiter) {
630 /* save empty field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000631 if (parse_save_field(self) < 0)
632 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000633 }
634 else {
635 /* begin new unquoted field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000636 if (dialect->quoting == QUOTE_NONNUMERIC)
637 self->numeric_field = 1;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000638 if (parse_add_char(self, c) < 0)
639 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000640 self->state = IN_FIELD;
641 }
642 break;
643
644 case ESCAPED_CHAR:
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000645 if (c == '\0')
646 c = '\n';
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000647 if (parse_add_char(self, c) < 0)
648 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000649 self->state = IN_FIELD;
650 break;
651
652 case IN_FIELD:
653 /* in unquoted field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000654 if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000655 /* end of line - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000656 if (parse_save_field(self) < 0)
657 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000658 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000659 }
660 else if (c == dialect->escapechar) {
661 /* possible escaped character */
662 self->state = ESCAPED_CHAR;
663 }
664 else if (c == dialect->delimiter) {
665 /* save field - wait for new field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000666 if (parse_save_field(self) < 0)
667 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000668 self->state = START_FIELD;
669 }
670 else {
671 /* normal character - save in field */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000672 if (parse_add_char(self, c) < 0)
673 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000674 }
675 break;
676
677 case IN_QUOTED_FIELD:
678 /* in quoted field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000679 if (c == '\0')
680 ;
Skip Montanarob4a04172003-03-20 23:29:12 +0000681 else if (c == dialect->escapechar) {
682 /* Possible escape character */
683 self->state = ESCAPE_IN_QUOTED_FIELD;
684 }
Andrew McNamara1196cf12005-01-07 04:42:45 +0000685 else if (c == dialect->quotechar &&
686 dialect->quoting != QUOTE_NONE) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000687 if (dialect->doublequote) {
688 /* doublequote; " represented by "" */
689 self->state = QUOTE_IN_QUOTED_FIELD;
690 }
691 else {
692 /* end of quote part of field */
693 self->state = IN_FIELD;
694 }
695 }
696 else {
697 /* normal character - save in field */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000698 if (parse_add_char(self, c) < 0)
699 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000700 }
701 break;
702
703 case ESCAPE_IN_QUOTED_FIELD:
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000704 if (c == '\0')
705 c = '\n';
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000706 if (parse_add_char(self, c) < 0)
707 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000708 self->state = IN_QUOTED_FIELD;
709 break;
710
711 case QUOTE_IN_QUOTED_FIELD:
712 /* doublequote - seen a quote in an quoted field */
713 if (dialect->quoting != QUOTE_NONE &&
714 c == dialect->quotechar) {
715 /* save "" as " */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000716 if (parse_add_char(self, c) < 0)
717 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000718 self->state = IN_QUOTED_FIELD;
719 }
720 else if (c == dialect->delimiter) {
721 /* save field - wait for new field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000722 if (parse_save_field(self) < 0)
723 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000724 self->state = START_FIELD;
725 }
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000726 else if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000727 /* end of line - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000728 if (parse_save_field(self) < 0)
729 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000730 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000731 }
732 else if (!dialect->strict) {
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000733 if (parse_add_char(self, c) < 0)
734 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000735 self->state = IN_FIELD;
736 }
737 else {
738 /* illegal */
Andrew McNamara5cfd8372005-01-12 11:39:50 +0000739 PyErr_Format(error_obj, "'%c' expected after '%c'",
Skip Montanarob4a04172003-03-20 23:29:12 +0000740 dialect->delimiter,
741 dialect->quotechar);
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000742 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000743 }
744 break;
745
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000746 case EAT_CRNL:
747 if (c == '\n' || c == '\r')
748 ;
749 else if (c == '\0')
750 self->state = START_RECORD;
751 else {
752 PyErr_Format(error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?");
753 return -1;
754 }
755 break;
756
Skip Montanarob4a04172003-03-20 23:29:12 +0000757 }
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000758 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000759}
760
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000761static int
762parse_reset(ReaderObj *self)
763{
764 Py_XDECREF(self->fields);
765 self->fields = PyList_New(0);
766 if (self->fields == NULL)
767 return -1;
768 self->field_len = 0;
769 self->state = START_RECORD;
770 self->numeric_field = 0;
771 return 0;
772}
Skip Montanarob4a04172003-03-20 23:29:12 +0000773
774static PyObject *
Skip Montanarob4a04172003-03-20 23:29:12 +0000775Reader_iternext(ReaderObj *self)
776{
777 PyObject *lineobj;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000778 PyObject *fields = NULL;
779 char *line, c;
780 int linelen;
Skip Montanarob4a04172003-03-20 23:29:12 +0000781
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000782 if (parse_reset(self) < 0)
783 return NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000784 do {
785 lineobj = PyIter_Next(self->input_iter);
786 if (lineobj == NULL) {
787 /* End of input OR exception */
788 if (!PyErr_Occurred() && self->field_len != 0)
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000789 PyErr_Format(error_obj,
790 "newline inside string");
Skip Montanarob4a04172003-03-20 23:29:12 +0000791 return NULL;
792 }
Andrew McNamara7f2053e2005-01-12 11:17:16 +0000793 ++self->line_num;
Skip Montanarob4a04172003-03-20 23:29:12 +0000794
Skip Montanarob4a04172003-03-20 23:29:12 +0000795 line = PyString_AsString(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000796 linelen = PyString_Size(lineobj);
Skip Montanarob4a04172003-03-20 23:29:12 +0000797
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000798 if (line == NULL || linelen < 0) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000799 Py_DECREF(lineobj);
800 return NULL;
801 }
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000802 while (linelen--) {
803 c = *line++;
804 if (c == '\0') {
805 Py_DECREF(lineobj);
806 PyErr_Format(error_obj,
807 "line contains NULL byte");
808 goto err;
809 }
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000810 if (parse_process_char(self, c) < 0) {
811 Py_DECREF(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000812 goto err;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000813 }
814 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000815 Py_DECREF(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000816 if (parse_process_char(self, 0) < 0)
817 goto err;
Skip Montanarob4a04172003-03-20 23:29:12 +0000818 } while (self->state != START_RECORD);
819
820 fields = self->fields;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000821 self->fields = NULL;
822err:
Skip Montanarob4a04172003-03-20 23:29:12 +0000823 return fields;
824}
825
826static void
827Reader_dealloc(ReaderObj *self)
828{
Andrew McNamara77ead872005-01-10 02:09:41 +0000829 PyObject_GC_UnTrack(self);
Skip Montanarob4a04172003-03-20 23:29:12 +0000830 Py_XDECREF(self->dialect);
831 Py_XDECREF(self->input_iter);
832 Py_XDECREF(self->fields);
Andrew McNamaradcfb38c2003-06-09 05:59:23 +0000833 if (self->field != NULL)
834 PyMem_Free(self->field);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000835 PyObject_GC_Del(self);
836}
837
838static int
839Reader_traverse(ReaderObj *self, visitproc visit, void *arg)
840{
Thomas Woutersc6e55062006-04-15 21:47:09 +0000841 Py_VISIT(self->dialect);
842 Py_VISIT(self->input_iter);
843 Py_VISIT(self->fields);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000844 return 0;
845}
846
847static int
848Reader_clear(ReaderObj *self)
849{
Thomas Woutersedf17d82006-04-15 17:28:34 +0000850 Py_CLEAR(self->dialect);
851 Py_CLEAR(self->input_iter);
852 Py_CLEAR(self->fields);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000853 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000854}
855
856PyDoc_STRVAR(Reader_Type_doc,
857"CSV reader\n"
858"\n"
859"Reader objects are responsible for reading and parsing tabular data\n"
860"in CSV format.\n"
861);
862
863static struct PyMethodDef Reader_methods[] = {
864 { NULL, NULL }
865};
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000866#define R_OFF(x) offsetof(ReaderObj, x)
867
868static struct PyMemberDef Reader_memberlist[] = {
869 { "dialect", T_OBJECT, R_OFF(dialect), RO },
870 { "line_num", T_ULONG, R_OFF(line_num), RO },
871 { NULL }
872};
873
Skip Montanarob4a04172003-03-20 23:29:12 +0000874
875static PyTypeObject Reader_Type = {
876 PyObject_HEAD_INIT(NULL)
877 0, /*ob_size*/
878 "_csv.reader", /*tp_name*/
879 sizeof(ReaderObj), /*tp_basicsize*/
880 0, /*tp_itemsize*/
881 /* methods */
882 (destructor)Reader_dealloc, /*tp_dealloc*/
883 (printfunc)0, /*tp_print*/
884 (getattrfunc)0, /*tp_getattr*/
885 (setattrfunc)0, /*tp_setattr*/
886 (cmpfunc)0, /*tp_compare*/
887 (reprfunc)0, /*tp_repr*/
888 0, /*tp_as_number*/
889 0, /*tp_as_sequence*/
890 0, /*tp_as_mapping*/
891 (hashfunc)0, /*tp_hash*/
892 (ternaryfunc)0, /*tp_call*/
893 (reprfunc)0, /*tp_str*/
894 0, /*tp_getattro*/
895 0, /*tp_setattro*/
896 0, /*tp_as_buffer*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000897 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
898 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000899 Reader_Type_doc, /*tp_doc*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000900 (traverseproc)Reader_traverse, /*tp_traverse*/
901 (inquiry)Reader_clear, /*tp_clear*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000902 0, /*tp_richcompare*/
903 0, /*tp_weaklistoffset*/
Andrew McNamara575a00b2005-01-06 02:25:41 +0000904 PyObject_SelfIter, /*tp_iter*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000905 (getiterfunc)Reader_iternext, /*tp_iternext*/
906 Reader_methods, /*tp_methods*/
907 Reader_memberlist, /*tp_members*/
908 0, /*tp_getset*/
909
910};
911
912static PyObject *
913csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
914{
Andrew McNamara91b97462005-01-11 01:07:23 +0000915 PyObject * iterator, * dialect = NULL;
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000916 ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +0000917
918 if (!self)
919 return NULL;
920
921 self->dialect = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000922 self->fields = NULL;
923 self->input_iter = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000924 self->field = NULL;
925 self->field_size = 0;
Andrew McNamara7f2053e2005-01-12 11:17:16 +0000926 self->line_num = 0;
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000927
928 if (parse_reset(self) < 0) {
929 Py_DECREF(self);
930 return NULL;
931 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000932
Raymond Hettinger1761a7c2004-06-20 04:23:19 +0000933 if (!PyArg_UnpackTuple(args, "", 1, 2, &iterator, &dialect)) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000934 Py_DECREF(self);
935 return NULL;
936 }
937 self->input_iter = PyObject_GetIter(iterator);
938 if (self->input_iter == NULL) {
939 PyErr_SetString(PyExc_TypeError,
940 "argument 1 must be an iterator");
941 Py_DECREF(self);
942 return NULL;
943 }
Andrew McNamara91b97462005-01-11 01:07:23 +0000944 self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
Skip Montanarob4a04172003-03-20 23:29:12 +0000945 if (self->dialect == NULL) {
946 Py_DECREF(self);
947 return NULL;
948 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000949
Andrew McNamara77ead872005-01-10 02:09:41 +0000950 PyObject_GC_Track(self);
Skip Montanarob4a04172003-03-20 23:29:12 +0000951 return (PyObject *)self;
952}
953
954/*
955 * WRITER
956 */
957/* ---------------------------------------------------------------- */
958static void
959join_reset(WriterObj *self)
960{
961 self->rec_len = 0;
962 self->num_fields = 0;
963}
964
965#define MEM_INCR 32768
966
967/* Calculate new record length or append field to record. Return new
968 * record length.
969 */
970static int
971join_append_data(WriterObj *self, char *field, int quote_empty,
972 int *quoted, int copy_phase)
973{
974 DialectObj *dialect = self->dialect;
975 int i, rec_len;
Andrew McNamarac89f2842005-01-12 07:44:42 +0000976 char *lineterm;
977
978#define ADDCH(c) \
979 do {\
980 if (copy_phase) \
981 self->rec[rec_len] = c;\
982 rec_len++;\
983 } while(0)
984
985 lineterm = PyString_AsString(dialect->lineterminator);
986 if (lineterm == NULL)
987 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000988
989 rec_len = self->rec_len;
990
Andrew McNamarac89f2842005-01-12 07:44:42 +0000991 /* If this is not the first field we need a field separator */
992 if (self->num_fields > 0)
993 ADDCH(dialect->delimiter);
994
995 /* Handle preceding quote */
996 if (copy_phase && *quoted)
997 ADDCH(dialect->quotechar);
998
999 /* Copy/count field data */
Skip Montanarob4a04172003-03-20 23:29:12 +00001000 for (i = 0;; i++) {
1001 char c = field[i];
Andrew McNamarac89f2842005-01-12 07:44:42 +00001002 int want_escape = 0;
Skip Montanarob4a04172003-03-20 23:29:12 +00001003
1004 if (c == '\0')
1005 break;
Skip Montanarob4a04172003-03-20 23:29:12 +00001006
Andrew McNamarac89f2842005-01-12 07:44:42 +00001007 if (c == dialect->delimiter ||
1008 c == dialect->escapechar ||
1009 c == dialect->quotechar ||
1010 strchr(lineterm, c)) {
1011 if (dialect->quoting == QUOTE_NONE)
1012 want_escape = 1;
Skip Montanarob4a04172003-03-20 23:29:12 +00001013 else {
Andrew McNamarac89f2842005-01-12 07:44:42 +00001014 if (c == dialect->quotechar) {
1015 if (dialect->doublequote)
1016 ADDCH(dialect->quotechar);
1017 else
1018 want_escape = 1;
1019 }
1020 if (!want_escape)
1021 *quoted = 1;
1022 }
1023 if (want_escape) {
1024 if (!dialect->escapechar) {
1025 PyErr_Format(error_obj,
1026 "need to escape, but no escapechar set");
1027 return -1;
1028 }
1029 ADDCH(dialect->escapechar);
Skip Montanarob4a04172003-03-20 23:29:12 +00001030 }
1031 }
1032 /* Copy field character into record buffer.
1033 */
Andrew McNamarac89f2842005-01-12 07:44:42 +00001034 ADDCH(c);
Skip Montanarob4a04172003-03-20 23:29:12 +00001035 }
1036
1037 /* If field is empty check if it needs to be quoted.
1038 */
1039 if (i == 0 && quote_empty) {
1040 if (dialect->quoting == QUOTE_NONE) {
1041 PyErr_Format(error_obj,
1042 "single empty field record must be quoted");
1043 return -1;
Andrew McNamaradd3e6cb2005-01-07 06:46:50 +00001044 }
1045 else
Skip Montanarob4a04172003-03-20 23:29:12 +00001046 *quoted = 1;
1047 }
1048
Skip Montanarob4a04172003-03-20 23:29:12 +00001049 if (*quoted) {
1050 if (copy_phase)
Andrew McNamarac89f2842005-01-12 07:44:42 +00001051 ADDCH(dialect->quotechar);
Skip Montanarob4a04172003-03-20 23:29:12 +00001052 else
Andrew McNamarac89f2842005-01-12 07:44:42 +00001053 rec_len += 2;
Skip Montanarob4a04172003-03-20 23:29:12 +00001054 }
Skip Montanarob4a04172003-03-20 23:29:12 +00001055 return rec_len;
Andrew McNamarac89f2842005-01-12 07:44:42 +00001056#undef ADDCH
Skip Montanarob4a04172003-03-20 23:29:12 +00001057}
1058
1059static int
1060join_check_rec_size(WriterObj *self, int rec_len)
1061{
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001062
1063 if (rec_len < 0 || rec_len > INT_MAX - MEM_INCR) {
1064 PyErr_NoMemory();
1065 return 0;
1066 }
1067
Skip Montanarob4a04172003-03-20 23:29:12 +00001068 if (rec_len > self->rec_size) {
1069 if (self->rec_size == 0) {
1070 self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
Andrew McNamaradcfb38c2003-06-09 05:59:23 +00001071 if (self->rec != NULL)
1072 PyMem_Free(self->rec);
Skip Montanarob4a04172003-03-20 23:29:12 +00001073 self->rec = PyMem_Malloc(self->rec_size);
1074 }
1075 else {
1076 char *old_rec = self->rec;
1077
1078 self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
1079 self->rec = PyMem_Realloc(self->rec, self->rec_size);
1080 if (self->rec == NULL)
1081 PyMem_Free(old_rec);
1082 }
1083 if (self->rec == NULL) {
1084 PyErr_NoMemory();
1085 return 0;
1086 }
1087 }
1088 return 1;
1089}
1090
1091static int
1092join_append(WriterObj *self, char *field, int *quoted, int quote_empty)
1093{
1094 int rec_len;
1095
1096 rec_len = join_append_data(self, field, quote_empty, quoted, 0);
1097 if (rec_len < 0)
1098 return 0;
1099
1100 /* grow record buffer if necessary */
1101 if (!join_check_rec_size(self, rec_len))
1102 return 0;
1103
1104 self->rec_len = join_append_data(self, field, quote_empty, quoted, 1);
1105 self->num_fields++;
1106
1107 return 1;
1108}
1109
1110static int
1111join_append_lineterminator(WriterObj *self)
1112{
1113 int terminator_len;
Andrew McNamaracf0fd5a2005-01-12 01:16:35 +00001114 char *terminator;
Skip Montanarob4a04172003-03-20 23:29:12 +00001115
1116 terminator_len = PyString_Size(self->dialect->lineterminator);
Neal Norwitzc6a989a2006-05-10 06:57:58 +00001117 if (terminator_len == -1)
1118 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +00001119
1120 /* grow record buffer if necessary */
1121 if (!join_check_rec_size(self, self->rec_len + terminator_len))
1122 return 0;
1123
Andrew McNamaracf0fd5a2005-01-12 01:16:35 +00001124 terminator = PyString_AsString(self->dialect->lineterminator);
1125 if (terminator == NULL)
1126 return 0;
1127 memmove(self->rec + self->rec_len, terminator, terminator_len);
Skip Montanarob4a04172003-03-20 23:29:12 +00001128 self->rec_len += terminator_len;
1129
1130 return 1;
1131}
1132
1133PyDoc_STRVAR(csv_writerow_doc,
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001134"writerow(sequence)\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001135"\n"
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001136"Construct and write a CSV record from a sequence of fields. Non-string\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001137"elements will be converted to string.");
1138
1139static PyObject *
1140csv_writerow(WriterObj *self, PyObject *seq)
1141{
1142 DialectObj *dialect = self->dialect;
1143 int len, i;
1144
1145 if (!PySequence_Check(seq))
1146 return PyErr_Format(error_obj, "sequence expected");
1147
1148 len = PySequence_Length(seq);
1149 if (len < 0)
1150 return NULL;
1151
1152 /* Join all fields in internal buffer.
1153 */
1154 join_reset(self);
1155 for (i = 0; i < len; i++) {
1156 PyObject *field;
1157 int append_ok;
1158 int quoted;
1159
1160 field = PySequence_GetItem(seq, i);
1161 if (field == NULL)
1162 return NULL;
1163
Andrew McNamarac89f2842005-01-12 07:44:42 +00001164 switch (dialect->quoting) {
1165 case QUOTE_NONNUMERIC:
1166 quoted = !PyNumber_Check(field);
1167 break;
1168 case QUOTE_ALL:
1169 quoted = 1;
1170 break;
1171 default:
1172 quoted = 0;
1173 break;
Skip Montanarob4a04172003-03-20 23:29:12 +00001174 }
1175
1176 if (PyString_Check(field)) {
Skip Montanaro577c7a72003-04-12 19:17:14 +00001177 append_ok = join_append(self,
1178 PyString_AS_STRING(field),
Skip Montanarob4a04172003-03-20 23:29:12 +00001179 &quoted, len == 1);
1180 Py_DECREF(field);
1181 }
1182 else if (field == Py_None) {
1183 append_ok = join_append(self, "", &quoted, len == 1);
1184 Py_DECREF(field);
1185 }
1186 else {
1187 PyObject *str;
1188
1189 str = PyObject_Str(field);
1190 Py_DECREF(field);
1191 if (str == NULL)
1192 return NULL;
1193
Skip Montanaro577c7a72003-04-12 19:17:14 +00001194 append_ok = join_append(self, PyString_AS_STRING(str),
Skip Montanarob4a04172003-03-20 23:29:12 +00001195 &quoted, len == 1);
1196 Py_DECREF(str);
1197 }
1198 if (!append_ok)
1199 return NULL;
1200 }
1201
1202 /* Add line terminator.
1203 */
1204 if (!join_append_lineterminator(self))
1205 return 0;
1206
1207 return PyObject_CallFunction(self->writeline,
1208 "(s#)", self->rec, self->rec_len);
1209}
1210
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001211PyDoc_STRVAR(csv_writerows_doc,
1212"writerows(sequence of sequences)\n"
1213"\n"
1214"Construct and write a series of sequences to a csv file. Non-string\n"
1215"elements will be converted to string.");
1216
Skip Montanarob4a04172003-03-20 23:29:12 +00001217static PyObject *
1218csv_writerows(WriterObj *self, PyObject *seqseq)
1219{
1220 PyObject *row_iter, *row_obj, *result;
1221
1222 row_iter = PyObject_GetIter(seqseq);
1223 if (row_iter == NULL) {
1224 PyErr_SetString(PyExc_TypeError,
Skip Montanaro98f16e02003-04-11 23:10:13 +00001225 "writerows() argument must be iterable");
Skip Montanarob4a04172003-03-20 23:29:12 +00001226 return NULL;
1227 }
1228 while ((row_obj = PyIter_Next(row_iter))) {
1229 result = csv_writerow(self, row_obj);
1230 Py_DECREF(row_obj);
1231 if (!result) {
1232 Py_DECREF(row_iter);
1233 return NULL;
1234 }
1235 else
1236 Py_DECREF(result);
1237 }
1238 Py_DECREF(row_iter);
1239 if (PyErr_Occurred())
1240 return NULL;
1241 Py_INCREF(Py_None);
1242 return Py_None;
1243}
1244
1245static struct PyMethodDef Writer_methods[] = {
1246 { "writerow", (PyCFunction)csv_writerow, METH_O, csv_writerow_doc},
Skip Montanaro860fc0b2003-04-12 18:57:52 +00001247 { "writerows", (PyCFunction)csv_writerows, METH_O, csv_writerows_doc},
Skip Montanarob4a04172003-03-20 23:29:12 +00001248 { NULL, NULL }
1249};
1250
1251#define W_OFF(x) offsetof(WriterObj, x)
1252
1253static struct PyMemberDef Writer_memberlist[] = {
1254 { "dialect", T_OBJECT, W_OFF(dialect), RO },
1255 { NULL }
1256};
1257
1258static void
1259Writer_dealloc(WriterObj *self)
1260{
Andrew McNamara77ead872005-01-10 02:09:41 +00001261 PyObject_GC_UnTrack(self);
Skip Montanarob4a04172003-03-20 23:29:12 +00001262 Py_XDECREF(self->dialect);
1263 Py_XDECREF(self->writeline);
Andrew McNamaradcfb38c2003-06-09 05:59:23 +00001264 if (self->rec != NULL)
1265 PyMem_Free(self->rec);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001266 PyObject_GC_Del(self);
1267}
1268
1269static int
1270Writer_traverse(WriterObj *self, visitproc visit, void *arg)
1271{
Thomas Woutersc6e55062006-04-15 21:47:09 +00001272 Py_VISIT(self->dialect);
1273 Py_VISIT(self->writeline);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001274 return 0;
1275}
1276
1277static int
1278Writer_clear(WriterObj *self)
1279{
Thomas Woutersedf17d82006-04-15 17:28:34 +00001280 Py_CLEAR(self->dialect);
1281 Py_CLEAR(self->writeline);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001282 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +00001283}
1284
1285PyDoc_STRVAR(Writer_Type_doc,
1286"CSV writer\n"
1287"\n"
1288"Writer objects are responsible for generating tabular data\n"
1289"in CSV format from sequence input.\n"
1290);
1291
1292static PyTypeObject Writer_Type = {
1293 PyObject_HEAD_INIT(NULL)
1294 0, /*ob_size*/
1295 "_csv.writer", /*tp_name*/
1296 sizeof(WriterObj), /*tp_basicsize*/
1297 0, /*tp_itemsize*/
1298 /* methods */
1299 (destructor)Writer_dealloc, /*tp_dealloc*/
1300 (printfunc)0, /*tp_print*/
1301 (getattrfunc)0, /*tp_getattr*/
1302 (setattrfunc)0, /*tp_setattr*/
1303 (cmpfunc)0, /*tp_compare*/
1304 (reprfunc)0, /*tp_repr*/
1305 0, /*tp_as_number*/
1306 0, /*tp_as_sequence*/
1307 0, /*tp_as_mapping*/
1308 (hashfunc)0, /*tp_hash*/
1309 (ternaryfunc)0, /*tp_call*/
1310 (reprfunc)0, /*tp_str*/
1311 0, /*tp_getattro*/
1312 0, /*tp_setattro*/
1313 0, /*tp_as_buffer*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001314 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1315 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Skip Montanarob4a04172003-03-20 23:29:12 +00001316 Writer_Type_doc,
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001317 (traverseproc)Writer_traverse, /*tp_traverse*/
1318 (inquiry)Writer_clear, /*tp_clear*/
Skip Montanarob4a04172003-03-20 23:29:12 +00001319 0, /*tp_richcompare*/
1320 0, /*tp_weaklistoffset*/
1321 (getiterfunc)0, /*tp_iter*/
1322 (getiterfunc)0, /*tp_iternext*/
1323 Writer_methods, /*tp_methods*/
1324 Writer_memberlist, /*tp_members*/
1325 0, /*tp_getset*/
1326};
1327
1328static PyObject *
1329csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)
1330{
Andrew McNamara91b97462005-01-11 01:07:23 +00001331 PyObject * output_file, * dialect = NULL;
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001332 WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +00001333
1334 if (!self)
1335 return NULL;
1336
1337 self->dialect = NULL;
1338 self->writeline = NULL;
1339
1340 self->rec = NULL;
1341 self->rec_size = 0;
1342 self->rec_len = 0;
1343 self->num_fields = 0;
1344
Raymond Hettinger1761a7c2004-06-20 04:23:19 +00001345 if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) {
Skip Montanarob4a04172003-03-20 23:29:12 +00001346 Py_DECREF(self);
1347 return NULL;
1348 }
1349 self->writeline = PyObject_GetAttrString(output_file, "write");
1350 if (self->writeline == NULL || !PyCallable_Check(self->writeline)) {
1351 PyErr_SetString(PyExc_TypeError,
Andrew McNamara5cfd8372005-01-12 11:39:50 +00001352 "argument 1 must have a \"write\" method");
Skip Montanarob4a04172003-03-20 23:29:12 +00001353 Py_DECREF(self);
1354 return NULL;
1355 }
Andrew McNamara91b97462005-01-11 01:07:23 +00001356 self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
Skip Montanarob4a04172003-03-20 23:29:12 +00001357 if (self->dialect == NULL) {
1358 Py_DECREF(self);
1359 return NULL;
1360 }
Andrew McNamara77ead872005-01-10 02:09:41 +00001361 PyObject_GC_Track(self);
Skip Montanarob4a04172003-03-20 23:29:12 +00001362 return (PyObject *)self;
1363}
1364
1365/*
1366 * DIALECT REGISTRY
1367 */
1368static PyObject *
1369csv_list_dialects(PyObject *module, PyObject *args)
1370{
1371 return PyDict_Keys(dialects);
1372}
1373
1374static PyObject *
Andrew McNamara86625972005-01-11 01:28:33 +00001375csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs)
Skip Montanarob4a04172003-03-20 23:29:12 +00001376{
Andrew McNamara86625972005-01-11 01:28:33 +00001377 PyObject *name_obj, *dialect_obj = NULL;
1378 PyObject *dialect;
Skip Montanarob4a04172003-03-20 23:29:12 +00001379
Andrew McNamara86625972005-01-11 01:28:33 +00001380 if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj))
Skip Montanarob4a04172003-03-20 23:29:12 +00001381 return NULL;
Andrew McNamara37d2bdf2005-01-10 12:22:48 +00001382 if (!IS_BASESTRING(name_obj)) {
Skip Montanarob4a04172003-03-20 23:29:12 +00001383 PyErr_SetString(PyExc_TypeError,
1384 "dialect name must be a string or unicode");
1385 return NULL;
1386 }
Andrew McNamara86625972005-01-11 01:28:33 +00001387 dialect = _call_dialect(dialect_obj, kwargs);
1388 if (dialect == NULL)
1389 return NULL;
1390 if (PyDict_SetItem(dialects, name_obj, dialect) < 0) {
1391 Py_DECREF(dialect);
Skip Montanarob4a04172003-03-20 23:29:12 +00001392 return NULL;
1393 }
Andrew McNamara86625972005-01-11 01:28:33 +00001394 Py_DECREF(dialect);
Skip Montanarob4a04172003-03-20 23:29:12 +00001395 Py_INCREF(Py_None);
1396 return Py_None;
1397}
1398
1399static PyObject *
Skip Montanaro577c7a72003-04-12 19:17:14 +00001400csv_unregister_dialect(PyObject *module, PyObject *name_obj)
Skip Montanarob4a04172003-03-20 23:29:12 +00001401{
Skip Montanarob4a04172003-03-20 23:29:12 +00001402 if (PyDict_DelItem(dialects, name_obj) < 0)
1403 return PyErr_Format(error_obj, "unknown dialect");
1404 Py_INCREF(Py_None);
1405 return Py_None;
1406}
1407
1408static PyObject *
Skip Montanaro577c7a72003-04-12 19:17:14 +00001409csv_get_dialect(PyObject *module, PyObject *name_obj)
Skip Montanarob4a04172003-03-20 23:29:12 +00001410{
Skip Montanarob4a04172003-03-20 23:29:12 +00001411 return get_dialect_from_registry(name_obj);
1412}
1413
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001414static PyObject *
Andrew McNamara31d88962005-01-12 03:45:10 +00001415csv_field_size_limit(PyObject *module, PyObject *args)
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001416{
1417 PyObject *new_limit = NULL;
1418 long old_limit = field_limit;
1419
Andrew McNamara31d88962005-01-12 03:45:10 +00001420 if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit))
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001421 return NULL;
1422 if (new_limit != NULL) {
1423 if (!PyInt_Check(new_limit)) {
1424 PyErr_Format(PyExc_TypeError,
1425 "limit must be an integer");
1426 return NULL;
1427 }
1428 field_limit = PyInt_AsLong(new_limit);
1429 }
1430 return PyInt_FromLong(old_limit);
1431}
1432
Skip Montanarob4a04172003-03-20 23:29:12 +00001433/*
1434 * MODULE
1435 */
1436
1437PyDoc_STRVAR(csv_module_doc,
1438"CSV parsing and writing.\n"
1439"\n"
1440"This module provides classes that assist in the reading and writing\n"
1441"of Comma Separated Value (CSV) files, and implements the interface\n"
1442"described by PEP 305. Although many CSV files are simple to parse,\n"
1443"the format is not formally defined by a stable specification and\n"
1444"is subtle enough that parsing lines of a CSV file with something\n"
1445"like line.split(\",\") is bound to fail. The module supports three\n"
1446"basic APIs: reading, writing, and registration of dialects.\n"
1447"\n"
1448"\n"
1449"DIALECT REGISTRATION:\n"
1450"\n"
1451"Readers and writers support a dialect argument, which is a convenient\n"
1452"handle on a group of settings. When the dialect argument is a string,\n"
1453"it identifies one of the dialects previously registered with the module.\n"
1454"If it is a class or instance, the attributes of the argument are used as\n"
1455"the settings for the reader or writer:\n"
1456"\n"
1457" class excel:\n"
1458" delimiter = ','\n"
1459" quotechar = '\"'\n"
1460" escapechar = None\n"
1461" doublequote = True\n"
1462" skipinitialspace = False\n"
Johannes Gijsbers8d3b9dd2004-08-15 12:23:10 +00001463" lineterminator = '\\r\\n'\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001464" quoting = QUOTE_MINIMAL\n"
1465"\n"
1466"SETTINGS:\n"
1467"\n"
1468" * quotechar - specifies a one-character string to use as the \n"
1469" quoting character. It defaults to '\"'.\n"
1470" * delimiter - specifies a one-character string to use as the \n"
1471" field separator. It defaults to ','.\n"
1472" * skipinitialspace - specifies how to interpret whitespace which\n"
1473" immediately follows a delimiter. It defaults to False, which\n"
1474" means that whitespace immediately following a delimiter is part\n"
1475" of the following field.\n"
1476" * lineterminator - specifies the character sequence which should \n"
1477" terminate rows.\n"
1478" * quoting - controls when quotes should be generated by the writer.\n"
1479" It can take on any of the following module constants:\n"
1480"\n"
1481" csv.QUOTE_MINIMAL means only when required, for example, when a\n"
1482" field contains either the quotechar or the delimiter\n"
1483" csv.QUOTE_ALL means that quotes are always placed around fields.\n"
1484" csv.QUOTE_NONNUMERIC means that quotes are always placed around\n"
Skip Montanaro148eb6a2003-12-02 18:57:47 +00001485" fields which do not parse as integers or floating point\n"
1486" numbers.\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001487" csv.QUOTE_NONE means that quotes are never placed around fields.\n"
1488" * escapechar - specifies a one-character string used to escape \n"
1489" the delimiter when quoting is set to QUOTE_NONE.\n"
1490" * doublequote - controls the handling of quotes inside fields. When\n"
1491" True, two consecutive quotes are interpreted as one during read,\n"
1492" and when writing, each quote character embedded in the data is\n"
1493" written as two quotes\n");
1494
1495PyDoc_STRVAR(csv_reader_doc,
1496" csv_reader = reader(iterable [, dialect='excel']\n"
1497" [optional keyword args])\n"
1498" for row in csv_reader:\n"
1499" process(row)\n"
1500"\n"
1501"The \"iterable\" argument can be any object that returns a line\n"
1502"of input for each iteration, such as a file object or a list. The\n"
1503"optional \"dialect\" parameter is discussed below. The function\n"
1504"also accepts optional keyword arguments which override settings\n"
1505"provided by the dialect.\n"
1506"\n"
1507"The returned object is an iterator. Each iteration returns a row\n"
Johannes Gijsbers8d3b9dd2004-08-15 12:23:10 +00001508"of the CSV file (which can span multiple input lines):\n");
Skip Montanarob4a04172003-03-20 23:29:12 +00001509
1510PyDoc_STRVAR(csv_writer_doc,
1511" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1512" [optional keyword args])\n"
Fredrik Lundh4aaaa492006-04-04 16:51:13 +00001513" for row in sequence:\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001514" csv_writer.writerow(row)\n"
1515"\n"
1516" [or]\n"
1517"\n"
1518" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1519" [optional keyword args])\n"
1520" csv_writer.writerows(rows)\n"
1521"\n"
1522"The \"fileobj\" argument can be any object that supports the file API.\n");
1523
1524PyDoc_STRVAR(csv_list_dialects_doc,
1525"Return a list of all know dialect names.\n"
1526" names = csv.list_dialects()");
1527
1528PyDoc_STRVAR(csv_get_dialect_doc,
1529"Return the dialect instance associated with name.\n"
1530" dialect = csv.get_dialect(name)");
1531
1532PyDoc_STRVAR(csv_register_dialect_doc,
1533"Create a mapping from a string name to a dialect class.\n"
1534" dialect = csv.register_dialect(name, dialect)");
1535
1536PyDoc_STRVAR(csv_unregister_dialect_doc,
1537"Delete the name/dialect mapping associated with a string name.\n"
1538" csv.unregister_dialect(name)");
1539
Andrew McNamara31d88962005-01-12 03:45:10 +00001540PyDoc_STRVAR(csv_field_size_limit_doc,
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001541"Sets an upper limit on parsed fields.\n"
Andrew McNamara31d88962005-01-12 03:45:10 +00001542" csv.field_size_limit([limit])\n"
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001543"\n"
1544"Returns old limit. If limit is not given, no new limit is set and\n"
1545"the old limit is returned");
1546
Skip Montanarob4a04172003-03-20 23:29:12 +00001547static struct PyMethodDef csv_methods[] = {
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001548 { "reader", (PyCFunction)csv_reader,
1549 METH_VARARGS | METH_KEYWORDS, csv_reader_doc},
1550 { "writer", (PyCFunction)csv_writer,
1551 METH_VARARGS | METH_KEYWORDS, csv_writer_doc},
1552 { "list_dialects", (PyCFunction)csv_list_dialects,
1553 METH_NOARGS, csv_list_dialects_doc},
1554 { "register_dialect", (PyCFunction)csv_register_dialect,
Andrew McNamara86625972005-01-11 01:28:33 +00001555 METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001556 { "unregister_dialect", (PyCFunction)csv_unregister_dialect,
1557 METH_O, csv_unregister_dialect_doc},
1558 { "get_dialect", (PyCFunction)csv_get_dialect,
1559 METH_O, csv_get_dialect_doc},
Andrew McNamara31d88962005-01-12 03:45:10 +00001560 { "field_size_limit", (PyCFunction)csv_field_size_limit,
1561 METH_VARARGS, csv_field_size_limit_doc},
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001562 { NULL, NULL }
Skip Montanarob4a04172003-03-20 23:29:12 +00001563};
1564
1565PyMODINIT_FUNC
1566init_csv(void)
1567{
1568 PyObject *module;
Skip Montanarob4a04172003-03-20 23:29:12 +00001569 StyleDesc *style;
1570
1571 if (PyType_Ready(&Dialect_Type) < 0)
1572 return;
1573
1574 if (PyType_Ready(&Reader_Type) < 0)
1575 return;
1576
1577 if (PyType_Ready(&Writer_Type) < 0)
1578 return;
1579
1580 /* Create the module and add the functions */
1581 module = Py_InitModule3("_csv", csv_methods, csv_module_doc);
1582 if (module == NULL)
1583 return;
1584
1585 /* Add version to the module. */
Skip Montanaro7b01a832003-04-12 19:23:46 +00001586 if (PyModule_AddStringConstant(module, "__version__",
1587 MODULE_VERSION) == -1)
Skip Montanarob4a04172003-03-20 23:29:12 +00001588 return;
1589
1590 /* Add _dialects dictionary */
1591 dialects = PyDict_New();
1592 if (dialects == NULL)
1593 return;
1594 if (PyModule_AddObject(module, "_dialects", dialects))
1595 return;
1596
1597 /* Add quote styles into dictionary */
1598 for (style = quote_styles; style->name; style++) {
Skip Montanaro7b01a832003-04-12 19:23:46 +00001599 if (PyModule_AddIntConstant(module, style->name,
1600 style->style) == -1)
Skip Montanarob4a04172003-03-20 23:29:12 +00001601 return;
1602 }
1603
1604 /* Add the Dialect type */
Skip Montanaro32c5d422005-06-15 13:35:08 +00001605 Py_INCREF(&Dialect_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +00001606 if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
1607 return;
1608
1609 /* Add the CSV exception object to the module. */
1610 error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
1611 if (error_obj == NULL)
1612 return;
1613 PyModule_AddObject(module, "Error", error_obj);
1614}