blob: c628927b53a29456b6e1cc250962058d63d88f56 [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
Christian Heimese93237d2007-12-19 02:37:44 +0000128#define ReaderObject_Check(v) (Py_TYPE(v) == &Reader_Type)
Skip Montanarob4a04172003-03-20 23:29:12 +0000129
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);
Christian Heimese93237d2007-12-19 02:37:44 +0000313 Py_TYPE(self)->tp_free((PyObject *)self);
Skip Montanarob4a04172003-03-20 23:29:12 +0000314}
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 = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000463 PyVarObject_HEAD_INIT(NULL, 0)
Skip Montanarob4a04172003-03-20 23:29:12 +0000464 "_csv.Dialect", /* tp_name */
465 sizeof(DialectObj), /* tp_basicsize */
466 0, /* tp_itemsize */
467 /* methods */
468 (destructor)Dialect_dealloc, /* tp_dealloc */
469 (printfunc)0, /* tp_print */
470 (getattrfunc)0, /* tp_getattr */
471 (setattrfunc)0, /* tp_setattr */
472 (cmpfunc)0, /* tp_compare */
473 (reprfunc)0, /* tp_repr */
474 0, /* tp_as_number */
475 0, /* tp_as_sequence */
476 0, /* tp_as_mapping */
477 (hashfunc)0, /* tp_hash */
478 (ternaryfunc)0, /* tp_call */
479 (reprfunc)0, /* tp_str */
480 0, /* tp_getattro */
481 0, /* tp_setattro */
482 0, /* tp_as_buffer */
483 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
484 Dialect_Type_doc, /* tp_doc */
485 0, /* tp_traverse */
486 0, /* tp_clear */
487 0, /* tp_richcompare */
488 0, /* tp_weaklistoffset */
489 0, /* tp_iter */
490 0, /* tp_iternext */
Andrew McNamara1196cf12005-01-07 04:42:45 +0000491 0, /* tp_methods */
Skip Montanarob4a04172003-03-20 23:29:12 +0000492 Dialect_memberlist, /* tp_members */
493 Dialect_getsetlist, /* tp_getset */
494 0, /* tp_base */
495 0, /* tp_dict */
496 0, /* tp_descr_get */
497 0, /* tp_descr_set */
498 0, /* tp_dictoffset */
Andrew McNamara29bf4e42005-01-11 04:49:53 +0000499 0, /* tp_init */
500 0, /* tp_alloc */
Skip Montanarob4a04172003-03-20 23:29:12 +0000501 dialect_new, /* tp_new */
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000502 0, /* tp_free */
Skip Montanarob4a04172003-03-20 23:29:12 +0000503};
504
Andrew McNamara91b97462005-01-11 01:07:23 +0000505/*
506 * Return an instance of the dialect type, given a Python instance or kwarg
507 * description of the dialect
508 */
509static PyObject *
510_call_dialect(PyObject *dialect_inst, PyObject *kwargs)
511{
512 PyObject *ctor_args;
513 PyObject *dialect;
514
515 ctor_args = Py_BuildValue(dialect_inst ? "(O)" : "()", dialect_inst);
516 if (ctor_args == NULL)
517 return NULL;
518 dialect = PyObject_Call((PyObject *)&Dialect_Type, ctor_args, kwargs);
519 Py_DECREF(ctor_args);
520 return dialect;
521}
522
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000523/*
524 * READER
525 */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000526static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000527parse_save_field(ReaderObj *self)
528{
529 PyObject *field;
530
531 field = PyString_FromStringAndSize(self->field, self->field_len);
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000532 if (field == NULL)
533 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000534 self->field_len = 0;
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000535 if (self->numeric_field) {
536 PyObject *tmp;
537
538 self->numeric_field = 0;
539 tmp = PyNumber_Float(field);
540 if (tmp == NULL) {
541 Py_DECREF(field);
542 return -1;
543 }
544 Py_DECREF(field);
545 field = tmp;
546 }
547 PyList_Append(self->fields, field);
548 Py_DECREF(field);
549 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000550}
551
552static int
553parse_grow_buff(ReaderObj *self)
554{
555 if (self->field_size == 0) {
556 self->field_size = 4096;
Andrew McNamaradcfb38c2003-06-09 05:59:23 +0000557 if (self->field != NULL)
558 PyMem_Free(self->field);
Skip Montanarob4a04172003-03-20 23:29:12 +0000559 self->field = PyMem_Malloc(self->field_size);
560 }
561 else {
562 self->field_size *= 2;
563 self->field = PyMem_Realloc(self->field, self->field_size);
564 }
565 if (self->field == NULL) {
566 PyErr_NoMemory();
567 return 0;
568 }
569 return 1;
570}
571
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000572static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000573parse_add_char(ReaderObj *self, char c)
574{
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000575 if (self->field_len >= field_limit) {
576 PyErr_Format(error_obj, "field larger than field limit (%ld)",
577 field_limit);
578 return -1;
579 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000580 if (self->field_len == self->field_size && !parse_grow_buff(self))
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000581 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000582 self->field[self->field_len++] = c;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000583 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000584}
585
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000586static int
Skip Montanarob4a04172003-03-20 23:29:12 +0000587parse_process_char(ReaderObj *self, char c)
588{
589 DialectObj *dialect = self->dialect;
590
591 switch (self->state) {
592 case START_RECORD:
593 /* start of record */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000594 if (c == '\0')
Skip Montanarob4a04172003-03-20 23:29:12 +0000595 /* empty line - return [] */
596 break;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000597 else if (c == '\n' || c == '\r') {
598 self->state = EAT_CRNL;
599 break;
600 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000601 /* normal character - handle as START_FIELD */
602 self->state = START_FIELD;
603 /* fallthru */
604 case START_FIELD:
605 /* expecting field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000606 if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000607 /* save empty field - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000608 if (parse_save_field(self) < 0)
609 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000610 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000611 }
Andrew McNamara1196cf12005-01-07 04:42:45 +0000612 else if (c == dialect->quotechar &&
613 dialect->quoting != QUOTE_NONE) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000614 /* start quoted field */
615 self->state = IN_QUOTED_FIELD;
616 }
617 else if (c == dialect->escapechar) {
618 /* possible escaped character */
619 self->state = ESCAPED_CHAR;
620 }
621 else if (c == ' ' && dialect->skipinitialspace)
622 /* ignore space at start of field */
623 ;
624 else if (c == dialect->delimiter) {
625 /* save empty field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000626 if (parse_save_field(self) < 0)
627 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000628 }
629 else {
630 /* begin new unquoted field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000631 if (dialect->quoting == QUOTE_NONNUMERIC)
632 self->numeric_field = 1;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000633 if (parse_add_char(self, c) < 0)
634 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000635 self->state = IN_FIELD;
636 }
637 break;
638
639 case ESCAPED_CHAR:
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000640 if (c == '\0')
641 c = '\n';
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000642 if (parse_add_char(self, c) < 0)
643 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000644 self->state = IN_FIELD;
645 break;
646
647 case IN_FIELD:
648 /* in unquoted field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000649 if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000650 /* end of line - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000651 if (parse_save_field(self) < 0)
652 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000653 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000654 }
655 else if (c == dialect->escapechar) {
656 /* possible escaped character */
657 self->state = ESCAPED_CHAR;
658 }
659 else if (c == dialect->delimiter) {
660 /* save field - wait for new field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000661 if (parse_save_field(self) < 0)
662 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000663 self->state = START_FIELD;
664 }
665 else {
666 /* normal character - save in field */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000667 if (parse_add_char(self, c) < 0)
668 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000669 }
670 break;
671
672 case IN_QUOTED_FIELD:
673 /* in quoted field */
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000674 if (c == '\0')
675 ;
Skip Montanarob4a04172003-03-20 23:29:12 +0000676 else if (c == dialect->escapechar) {
677 /* Possible escape character */
678 self->state = ESCAPE_IN_QUOTED_FIELD;
679 }
Andrew McNamara1196cf12005-01-07 04:42:45 +0000680 else if (c == dialect->quotechar &&
681 dialect->quoting != QUOTE_NONE) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000682 if (dialect->doublequote) {
683 /* doublequote; " represented by "" */
684 self->state = QUOTE_IN_QUOTED_FIELD;
685 }
686 else {
687 /* end of quote part of field */
688 self->state = IN_FIELD;
689 }
690 }
691 else {
692 /* normal character - save in field */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000693 if (parse_add_char(self, c) < 0)
694 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000695 }
696 break;
697
698 case ESCAPE_IN_QUOTED_FIELD:
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000699 if (c == '\0')
700 c = '\n';
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000701 if (parse_add_char(self, c) < 0)
702 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000703 self->state = IN_QUOTED_FIELD;
704 break;
705
706 case QUOTE_IN_QUOTED_FIELD:
707 /* doublequote - seen a quote in an quoted field */
708 if (dialect->quoting != QUOTE_NONE &&
709 c == dialect->quotechar) {
710 /* save "" as " */
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000711 if (parse_add_char(self, c) < 0)
712 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000713 self->state = IN_QUOTED_FIELD;
714 }
715 else if (c == dialect->delimiter) {
716 /* save field - wait for new field */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000717 if (parse_save_field(self) < 0)
718 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000719 self->state = START_FIELD;
720 }
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000721 else if (c == '\n' || c == '\r' || c == '\0') {
Skip Montanarob4a04172003-03-20 23:29:12 +0000722 /* end of line - return [fields] */
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000723 if (parse_save_field(self) < 0)
724 return -1;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000725 self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
Skip Montanarob4a04172003-03-20 23:29:12 +0000726 }
727 else if (!dialect->strict) {
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000728 if (parse_add_char(self, c) < 0)
729 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000730 self->state = IN_FIELD;
731 }
732 else {
733 /* illegal */
Andrew McNamara5cfd8372005-01-12 11:39:50 +0000734 PyErr_Format(error_obj, "'%c' expected after '%c'",
Skip Montanarob4a04172003-03-20 23:29:12 +0000735 dialect->delimiter,
736 dialect->quotechar);
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000737 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000738 }
739 break;
740
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000741 case EAT_CRNL:
742 if (c == '\n' || c == '\r')
743 ;
744 else if (c == '\0')
745 self->state = START_RECORD;
746 else {
747 PyErr_Format(error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?");
748 return -1;
749 }
750 break;
751
Skip Montanarob4a04172003-03-20 23:29:12 +0000752 }
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000753 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000754}
755
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000756static int
757parse_reset(ReaderObj *self)
758{
759 Py_XDECREF(self->fields);
760 self->fields = PyList_New(0);
761 if (self->fields == NULL)
762 return -1;
763 self->field_len = 0;
764 self->state = START_RECORD;
765 self->numeric_field = 0;
766 return 0;
767}
Skip Montanarob4a04172003-03-20 23:29:12 +0000768
769static PyObject *
Skip Montanarob4a04172003-03-20 23:29:12 +0000770Reader_iternext(ReaderObj *self)
771{
772 PyObject *lineobj;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000773 PyObject *fields = NULL;
774 char *line, c;
775 int linelen;
Skip Montanarob4a04172003-03-20 23:29:12 +0000776
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000777 if (parse_reset(self) < 0)
778 return NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000779 do {
780 lineobj = PyIter_Next(self->input_iter);
781 if (lineobj == NULL) {
782 /* End of input OR exception */
783 if (!PyErr_Occurred() && self->field_len != 0)
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000784 PyErr_Format(error_obj,
785 "newline inside string");
Skip Montanarob4a04172003-03-20 23:29:12 +0000786 return NULL;
787 }
Andrew McNamara7f2053e2005-01-12 11:17:16 +0000788 ++self->line_num;
Skip Montanarob4a04172003-03-20 23:29:12 +0000789
Skip Montanarob4a04172003-03-20 23:29:12 +0000790 line = PyString_AsString(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000791 linelen = PyString_Size(lineobj);
Skip Montanarob4a04172003-03-20 23:29:12 +0000792
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000793 if (line == NULL || linelen < 0) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000794 Py_DECREF(lineobj);
795 return NULL;
796 }
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000797 while (linelen--) {
798 c = *line++;
799 if (c == '\0') {
800 Py_DECREF(lineobj);
801 PyErr_Format(error_obj,
802 "line contains NULL byte");
803 goto err;
804 }
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000805 if (parse_process_char(self, c) < 0) {
806 Py_DECREF(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000807 goto err;
Andrew McNamarae4d05c42005-01-11 07:32:02 +0000808 }
809 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000810 Py_DECREF(lineobj);
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000811 if (parse_process_char(self, 0) < 0)
812 goto err;
Skip Montanarob4a04172003-03-20 23:29:12 +0000813 } while (self->state != START_RECORD);
814
815 fields = self->fields;
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000816 self->fields = NULL;
817err:
Skip Montanarob4a04172003-03-20 23:29:12 +0000818 return fields;
819}
820
821static void
822Reader_dealloc(ReaderObj *self)
823{
Andrew McNamara77ead872005-01-10 02:09:41 +0000824 PyObject_GC_UnTrack(self);
Skip Montanarob4a04172003-03-20 23:29:12 +0000825 Py_XDECREF(self->dialect);
826 Py_XDECREF(self->input_iter);
827 Py_XDECREF(self->fields);
Andrew McNamaradcfb38c2003-06-09 05:59:23 +0000828 if (self->field != NULL)
829 PyMem_Free(self->field);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000830 PyObject_GC_Del(self);
831}
832
833static int
834Reader_traverse(ReaderObj *self, visitproc visit, void *arg)
835{
Thomas Woutersc6e55062006-04-15 21:47:09 +0000836 Py_VISIT(self->dialect);
837 Py_VISIT(self->input_iter);
838 Py_VISIT(self->fields);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000839 return 0;
840}
841
842static int
843Reader_clear(ReaderObj *self)
844{
Thomas Woutersedf17d82006-04-15 17:28:34 +0000845 Py_CLEAR(self->dialect);
846 Py_CLEAR(self->input_iter);
847 Py_CLEAR(self->fields);
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000848 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000849}
850
851PyDoc_STRVAR(Reader_Type_doc,
852"CSV reader\n"
853"\n"
854"Reader objects are responsible for reading and parsing tabular data\n"
855"in CSV format.\n"
856);
857
858static struct PyMethodDef Reader_methods[] = {
859 { NULL, NULL }
860};
Andrew McNamaraf69d94f2005-01-13 11:30:54 +0000861#define R_OFF(x) offsetof(ReaderObj, x)
862
863static struct PyMemberDef Reader_memberlist[] = {
864 { "dialect", T_OBJECT, R_OFF(dialect), RO },
865 { "line_num", T_ULONG, R_OFF(line_num), RO },
866 { NULL }
867};
868
Skip Montanarob4a04172003-03-20 23:29:12 +0000869
870static PyTypeObject Reader_Type = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000871 PyVarObject_HEAD_INIT(NULL, 0)
Skip Montanarob4a04172003-03-20 23:29:12 +0000872 "_csv.reader", /*tp_name*/
873 sizeof(ReaderObj), /*tp_basicsize*/
874 0, /*tp_itemsize*/
875 /* methods */
876 (destructor)Reader_dealloc, /*tp_dealloc*/
877 (printfunc)0, /*tp_print*/
878 (getattrfunc)0, /*tp_getattr*/
879 (setattrfunc)0, /*tp_setattr*/
880 (cmpfunc)0, /*tp_compare*/
881 (reprfunc)0, /*tp_repr*/
882 0, /*tp_as_number*/
883 0, /*tp_as_sequence*/
884 0, /*tp_as_mapping*/
885 (hashfunc)0, /*tp_hash*/
886 (ternaryfunc)0, /*tp_call*/
887 (reprfunc)0, /*tp_str*/
888 0, /*tp_getattro*/
889 0, /*tp_setattro*/
890 0, /*tp_as_buffer*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000891 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
892 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000893 Reader_Type_doc, /*tp_doc*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000894 (traverseproc)Reader_traverse, /*tp_traverse*/
895 (inquiry)Reader_clear, /*tp_clear*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000896 0, /*tp_richcompare*/
897 0, /*tp_weaklistoffset*/
Andrew McNamara575a00b2005-01-06 02:25:41 +0000898 PyObject_SelfIter, /*tp_iter*/
Skip Montanarob4a04172003-03-20 23:29:12 +0000899 (getiterfunc)Reader_iternext, /*tp_iternext*/
900 Reader_methods, /*tp_methods*/
901 Reader_memberlist, /*tp_members*/
902 0, /*tp_getset*/
903
904};
905
906static PyObject *
907csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
908{
Andrew McNamara91b97462005-01-11 01:07:23 +0000909 PyObject * iterator, * dialect = NULL;
Jeremy Hylton42a8aed2003-04-14 02:20:55 +0000910 ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +0000911
912 if (!self)
913 return NULL;
914
915 self->dialect = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000916 self->fields = NULL;
917 self->input_iter = NULL;
Skip Montanarob4a04172003-03-20 23:29:12 +0000918 self->field = NULL;
919 self->field_size = 0;
Andrew McNamara7f2053e2005-01-12 11:17:16 +0000920 self->line_num = 0;
Andrew McNamara0f0599d2005-01-12 09:45:18 +0000921
922 if (parse_reset(self) < 0) {
923 Py_DECREF(self);
924 return NULL;
925 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000926
Raymond Hettinger1761a7c2004-06-20 04:23:19 +0000927 if (!PyArg_UnpackTuple(args, "", 1, 2, &iterator, &dialect)) {
Skip Montanarob4a04172003-03-20 23:29:12 +0000928 Py_DECREF(self);
929 return NULL;
930 }
931 self->input_iter = PyObject_GetIter(iterator);
932 if (self->input_iter == NULL) {
933 PyErr_SetString(PyExc_TypeError,
934 "argument 1 must be an iterator");
935 Py_DECREF(self);
936 return NULL;
937 }
Andrew McNamara91b97462005-01-11 01:07:23 +0000938 self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
Skip Montanarob4a04172003-03-20 23:29:12 +0000939 if (self->dialect == NULL) {
940 Py_DECREF(self);
941 return NULL;
942 }
Skip Montanarob4a04172003-03-20 23:29:12 +0000943
Andrew McNamara77ead872005-01-10 02:09:41 +0000944 PyObject_GC_Track(self);
Skip Montanarob4a04172003-03-20 23:29:12 +0000945 return (PyObject *)self;
946}
947
948/*
949 * WRITER
950 */
951/* ---------------------------------------------------------------- */
952static void
953join_reset(WriterObj *self)
954{
955 self->rec_len = 0;
956 self->num_fields = 0;
957}
958
959#define MEM_INCR 32768
960
961/* Calculate new record length or append field to record. Return new
962 * record length.
963 */
964static int
965join_append_data(WriterObj *self, char *field, int quote_empty,
966 int *quoted, int copy_phase)
967{
968 DialectObj *dialect = self->dialect;
969 int i, rec_len;
Andrew McNamarac89f2842005-01-12 07:44:42 +0000970 char *lineterm;
971
972#define ADDCH(c) \
973 do {\
974 if (copy_phase) \
975 self->rec[rec_len] = c;\
976 rec_len++;\
977 } while(0)
978
979 lineterm = PyString_AsString(dialect->lineterminator);
980 if (lineterm == NULL)
981 return -1;
Skip Montanarob4a04172003-03-20 23:29:12 +0000982
983 rec_len = self->rec_len;
984
Andrew McNamarac89f2842005-01-12 07:44:42 +0000985 /* If this is not the first field we need a field separator */
986 if (self->num_fields > 0)
987 ADDCH(dialect->delimiter);
988
989 /* Handle preceding quote */
990 if (copy_phase && *quoted)
991 ADDCH(dialect->quotechar);
992
993 /* Copy/count field data */
Skip Montanarob4a04172003-03-20 23:29:12 +0000994 for (i = 0;; i++) {
995 char c = field[i];
Andrew McNamarac89f2842005-01-12 07:44:42 +0000996 int want_escape = 0;
Skip Montanarob4a04172003-03-20 23:29:12 +0000997
998 if (c == '\0')
999 break;
Skip Montanarob4a04172003-03-20 23:29:12 +00001000
Andrew McNamarac89f2842005-01-12 07:44:42 +00001001 if (c == dialect->delimiter ||
1002 c == dialect->escapechar ||
1003 c == dialect->quotechar ||
1004 strchr(lineterm, c)) {
1005 if (dialect->quoting == QUOTE_NONE)
1006 want_escape = 1;
Skip Montanarob4a04172003-03-20 23:29:12 +00001007 else {
Andrew McNamarac89f2842005-01-12 07:44:42 +00001008 if (c == dialect->quotechar) {
1009 if (dialect->doublequote)
1010 ADDCH(dialect->quotechar);
1011 else
1012 want_escape = 1;
1013 }
1014 if (!want_escape)
1015 *quoted = 1;
1016 }
1017 if (want_escape) {
1018 if (!dialect->escapechar) {
1019 PyErr_Format(error_obj,
1020 "need to escape, but no escapechar set");
1021 return -1;
1022 }
1023 ADDCH(dialect->escapechar);
Skip Montanarob4a04172003-03-20 23:29:12 +00001024 }
1025 }
1026 /* Copy field character into record buffer.
1027 */
Andrew McNamarac89f2842005-01-12 07:44:42 +00001028 ADDCH(c);
Skip Montanarob4a04172003-03-20 23:29:12 +00001029 }
1030
1031 /* If field is empty check if it needs to be quoted.
1032 */
1033 if (i == 0 && quote_empty) {
1034 if (dialect->quoting == QUOTE_NONE) {
1035 PyErr_Format(error_obj,
1036 "single empty field record must be quoted");
1037 return -1;
Andrew McNamaradd3e6cb2005-01-07 06:46:50 +00001038 }
1039 else
Skip Montanarob4a04172003-03-20 23:29:12 +00001040 *quoted = 1;
1041 }
1042
Skip Montanarob4a04172003-03-20 23:29:12 +00001043 if (*quoted) {
1044 if (copy_phase)
Andrew McNamarac89f2842005-01-12 07:44:42 +00001045 ADDCH(dialect->quotechar);
Skip Montanarob4a04172003-03-20 23:29:12 +00001046 else
Andrew McNamarac89f2842005-01-12 07:44:42 +00001047 rec_len += 2;
Skip Montanarob4a04172003-03-20 23:29:12 +00001048 }
Skip Montanarob4a04172003-03-20 23:29:12 +00001049 return rec_len;
Andrew McNamarac89f2842005-01-12 07:44:42 +00001050#undef ADDCH
Skip Montanarob4a04172003-03-20 23:29:12 +00001051}
1052
1053static int
1054join_check_rec_size(WriterObj *self, int rec_len)
1055{
1056 if (rec_len > self->rec_size) {
1057 if (self->rec_size == 0) {
1058 self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
Andrew McNamaradcfb38c2003-06-09 05:59:23 +00001059 if (self->rec != NULL)
1060 PyMem_Free(self->rec);
Skip Montanarob4a04172003-03-20 23:29:12 +00001061 self->rec = PyMem_Malloc(self->rec_size);
1062 }
1063 else {
1064 char *old_rec = self->rec;
1065
1066 self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
1067 self->rec = PyMem_Realloc(self->rec, self->rec_size);
1068 if (self->rec == NULL)
1069 PyMem_Free(old_rec);
1070 }
1071 if (self->rec == NULL) {
1072 PyErr_NoMemory();
1073 return 0;
1074 }
1075 }
1076 return 1;
1077}
1078
1079static int
1080join_append(WriterObj *self, char *field, int *quoted, int quote_empty)
1081{
1082 int rec_len;
1083
1084 rec_len = join_append_data(self, field, quote_empty, quoted, 0);
1085 if (rec_len < 0)
1086 return 0;
1087
1088 /* grow record buffer if necessary */
1089 if (!join_check_rec_size(self, rec_len))
1090 return 0;
1091
1092 self->rec_len = join_append_data(self, field, quote_empty, quoted, 1);
1093 self->num_fields++;
1094
1095 return 1;
1096}
1097
1098static int
1099join_append_lineterminator(WriterObj *self)
1100{
1101 int terminator_len;
Andrew McNamaracf0fd5a2005-01-12 01:16:35 +00001102 char *terminator;
Skip Montanarob4a04172003-03-20 23:29:12 +00001103
1104 terminator_len = PyString_Size(self->dialect->lineterminator);
Neal Norwitzc6a989a2006-05-10 06:57:58 +00001105 if (terminator_len == -1)
1106 return 0;
Skip Montanarob4a04172003-03-20 23:29:12 +00001107
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 Woutersc6e55062006-04-15 21:47:09 +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 Woutersedf17d82006-04-15 17:28:34 +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 = {
Martin v. Löwis68192102007-07-21 06:55:02 +00001281 PyVarObject_HEAD_INIT(NULL, 0)
Skip Montanarob4a04172003-03-20 23:29:12 +00001282 "_csv.writer", /*tp_name*/
1283 sizeof(WriterObj), /*tp_basicsize*/
1284 0, /*tp_itemsize*/
1285 /* methods */
1286 (destructor)Writer_dealloc, /*tp_dealloc*/
1287 (printfunc)0, /*tp_print*/
1288 (getattrfunc)0, /*tp_getattr*/
1289 (setattrfunc)0, /*tp_setattr*/
1290 (cmpfunc)0, /*tp_compare*/
1291 (reprfunc)0, /*tp_repr*/
1292 0, /*tp_as_number*/
1293 0, /*tp_as_sequence*/
1294 0, /*tp_as_mapping*/
1295 (hashfunc)0, /*tp_hash*/
1296 (ternaryfunc)0, /*tp_call*/
1297 (reprfunc)0, /*tp_str*/
1298 0, /*tp_getattro*/
1299 0, /*tp_setattro*/
1300 0, /*tp_as_buffer*/
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001301 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1302 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Skip Montanarob4a04172003-03-20 23:29:12 +00001303 Writer_Type_doc,
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001304 (traverseproc)Writer_traverse, /*tp_traverse*/
1305 (inquiry)Writer_clear, /*tp_clear*/
Skip Montanarob4a04172003-03-20 23:29:12 +00001306 0, /*tp_richcompare*/
1307 0, /*tp_weaklistoffset*/
1308 (getiterfunc)0, /*tp_iter*/
1309 (getiterfunc)0, /*tp_iternext*/
1310 Writer_methods, /*tp_methods*/
1311 Writer_memberlist, /*tp_members*/
1312 0, /*tp_getset*/
1313};
1314
1315static PyObject *
1316csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)
1317{
Andrew McNamara91b97462005-01-11 01:07:23 +00001318 PyObject * output_file, * dialect = NULL;
Jeremy Hylton42a8aed2003-04-14 02:20:55 +00001319 WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +00001320
1321 if (!self)
1322 return NULL;
1323
1324 self->dialect = NULL;
1325 self->writeline = NULL;
1326
1327 self->rec = NULL;
1328 self->rec_size = 0;
1329 self->rec_len = 0;
1330 self->num_fields = 0;
1331
Raymond Hettinger1761a7c2004-06-20 04:23:19 +00001332 if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) {
Skip Montanarob4a04172003-03-20 23:29:12 +00001333 Py_DECREF(self);
1334 return NULL;
1335 }
1336 self->writeline = PyObject_GetAttrString(output_file, "write");
1337 if (self->writeline == NULL || !PyCallable_Check(self->writeline)) {
1338 PyErr_SetString(PyExc_TypeError,
Andrew McNamara5cfd8372005-01-12 11:39:50 +00001339 "argument 1 must have a \"write\" method");
Skip Montanarob4a04172003-03-20 23:29:12 +00001340 Py_DECREF(self);
1341 return NULL;
1342 }
Andrew McNamara91b97462005-01-11 01:07:23 +00001343 self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
Skip Montanarob4a04172003-03-20 23:29:12 +00001344 if (self->dialect == NULL) {
1345 Py_DECREF(self);
1346 return NULL;
1347 }
Andrew McNamara77ead872005-01-10 02:09:41 +00001348 PyObject_GC_Track(self);
Skip Montanarob4a04172003-03-20 23:29:12 +00001349 return (PyObject *)self;
1350}
1351
1352/*
1353 * DIALECT REGISTRY
1354 */
1355static PyObject *
1356csv_list_dialects(PyObject *module, PyObject *args)
1357{
1358 return PyDict_Keys(dialects);
1359}
1360
1361static PyObject *
Andrew McNamara86625972005-01-11 01:28:33 +00001362csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs)
Skip Montanarob4a04172003-03-20 23:29:12 +00001363{
Andrew McNamara86625972005-01-11 01:28:33 +00001364 PyObject *name_obj, *dialect_obj = NULL;
1365 PyObject *dialect;
Skip Montanarob4a04172003-03-20 23:29:12 +00001366
Andrew McNamara86625972005-01-11 01:28:33 +00001367 if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj))
Skip Montanarob4a04172003-03-20 23:29:12 +00001368 return NULL;
Andrew McNamara37d2bdf2005-01-10 12:22:48 +00001369 if (!IS_BASESTRING(name_obj)) {
Skip Montanarob4a04172003-03-20 23:29:12 +00001370 PyErr_SetString(PyExc_TypeError,
1371 "dialect name must be a string or unicode");
1372 return NULL;
1373 }
Andrew McNamara86625972005-01-11 01:28:33 +00001374 dialect = _call_dialect(dialect_obj, kwargs);
1375 if (dialect == NULL)
1376 return NULL;
1377 if (PyDict_SetItem(dialects, name_obj, dialect) < 0) {
1378 Py_DECREF(dialect);
Skip Montanarob4a04172003-03-20 23:29:12 +00001379 return NULL;
1380 }
Andrew McNamara86625972005-01-11 01:28:33 +00001381 Py_DECREF(dialect);
Skip Montanarob4a04172003-03-20 23:29:12 +00001382 Py_INCREF(Py_None);
1383 return Py_None;
1384}
1385
1386static PyObject *
Skip Montanaro577c7a72003-04-12 19:17:14 +00001387csv_unregister_dialect(PyObject *module, PyObject *name_obj)
Skip Montanarob4a04172003-03-20 23:29:12 +00001388{
Skip Montanarob4a04172003-03-20 23:29:12 +00001389 if (PyDict_DelItem(dialects, name_obj) < 0)
1390 return PyErr_Format(error_obj, "unknown dialect");
1391 Py_INCREF(Py_None);
1392 return Py_None;
1393}
1394
1395static PyObject *
Skip Montanaro577c7a72003-04-12 19:17:14 +00001396csv_get_dialect(PyObject *module, PyObject *name_obj)
Skip Montanarob4a04172003-03-20 23:29:12 +00001397{
Skip Montanarob4a04172003-03-20 23:29:12 +00001398 return get_dialect_from_registry(name_obj);
1399}
1400
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001401static PyObject *
Andrew McNamara31d88962005-01-12 03:45:10 +00001402csv_field_size_limit(PyObject *module, PyObject *args)
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001403{
1404 PyObject *new_limit = NULL;
1405 long old_limit = field_limit;
1406
Andrew McNamara31d88962005-01-12 03:45:10 +00001407 if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit))
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001408 return NULL;
1409 if (new_limit != NULL) {
1410 if (!PyInt_Check(new_limit)) {
1411 PyErr_Format(PyExc_TypeError,
1412 "limit must be an integer");
1413 return NULL;
1414 }
1415 field_limit = PyInt_AsLong(new_limit);
1416 }
1417 return PyInt_FromLong(old_limit);
1418}
1419
Skip Montanarob4a04172003-03-20 23:29:12 +00001420/*
1421 * MODULE
1422 */
1423
1424PyDoc_STRVAR(csv_module_doc,
1425"CSV parsing and writing.\n"
1426"\n"
1427"This module provides classes that assist in the reading and writing\n"
1428"of Comma Separated Value (CSV) files, and implements the interface\n"
1429"described by PEP 305. Although many CSV files are simple to parse,\n"
1430"the format is not formally defined by a stable specification and\n"
1431"is subtle enough that parsing lines of a CSV file with something\n"
1432"like line.split(\",\") is bound to fail. The module supports three\n"
1433"basic APIs: reading, writing, and registration of dialects.\n"
1434"\n"
1435"\n"
1436"DIALECT REGISTRATION:\n"
1437"\n"
1438"Readers and writers support a dialect argument, which is a convenient\n"
1439"handle on a group of settings. When the dialect argument is a string,\n"
1440"it identifies one of the dialects previously registered with the module.\n"
1441"If it is a class or instance, the attributes of the argument are used as\n"
1442"the settings for the reader or writer:\n"
1443"\n"
1444" class excel:\n"
1445" delimiter = ','\n"
1446" quotechar = '\"'\n"
1447" escapechar = None\n"
1448" doublequote = True\n"
1449" skipinitialspace = False\n"
Johannes Gijsbers8d3b9dd2004-08-15 12:23:10 +00001450" lineterminator = '\\r\\n'\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001451" quoting = QUOTE_MINIMAL\n"
1452"\n"
1453"SETTINGS:\n"
1454"\n"
1455" * quotechar - specifies a one-character string to use as the \n"
1456" quoting character. It defaults to '\"'.\n"
1457" * delimiter - specifies a one-character string to use as the \n"
1458" field separator. It defaults to ','.\n"
1459" * skipinitialspace - specifies how to interpret whitespace which\n"
1460" immediately follows a delimiter. It defaults to False, which\n"
1461" means that whitespace immediately following a delimiter is part\n"
1462" of the following field.\n"
1463" * lineterminator - specifies the character sequence which should \n"
1464" terminate rows.\n"
1465" * quoting - controls when quotes should be generated by the writer.\n"
1466" It can take on any of the following module constants:\n"
1467"\n"
1468" csv.QUOTE_MINIMAL means only when required, for example, when a\n"
1469" field contains either the quotechar or the delimiter\n"
1470" csv.QUOTE_ALL means that quotes are always placed around fields.\n"
1471" csv.QUOTE_NONNUMERIC means that quotes are always placed around\n"
Skip Montanaro148eb6a2003-12-02 18:57:47 +00001472" fields which do not parse as integers or floating point\n"
1473" numbers.\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001474" csv.QUOTE_NONE means that quotes are never placed around fields.\n"
1475" * escapechar - specifies a one-character string used to escape \n"
1476" the delimiter when quoting is set to QUOTE_NONE.\n"
1477" * doublequote - controls the handling of quotes inside fields. When\n"
1478" True, two consecutive quotes are interpreted as one during read,\n"
1479" and when writing, each quote character embedded in the data is\n"
1480" written as two quotes\n");
1481
1482PyDoc_STRVAR(csv_reader_doc,
1483" csv_reader = reader(iterable [, dialect='excel']\n"
1484" [optional keyword args])\n"
1485" for row in csv_reader:\n"
1486" process(row)\n"
1487"\n"
1488"The \"iterable\" argument can be any object that returns a line\n"
1489"of input for each iteration, such as a file object or a list. The\n"
1490"optional \"dialect\" parameter is discussed below. The function\n"
1491"also accepts optional keyword arguments which override settings\n"
1492"provided by the dialect.\n"
1493"\n"
1494"The returned object is an iterator. Each iteration returns a row\n"
Johannes Gijsbers8d3b9dd2004-08-15 12:23:10 +00001495"of the CSV file (which can span multiple input lines):\n");
Skip Montanarob4a04172003-03-20 23:29:12 +00001496
1497PyDoc_STRVAR(csv_writer_doc,
1498" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1499" [optional keyword args])\n"
Fredrik Lundh4aaaa492006-04-04 16:51:13 +00001500" for row in sequence:\n"
Skip Montanarob4a04172003-03-20 23:29:12 +00001501" csv_writer.writerow(row)\n"
1502"\n"
1503" [or]\n"
1504"\n"
1505" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1506" [optional keyword args])\n"
1507" csv_writer.writerows(rows)\n"
1508"\n"
1509"The \"fileobj\" argument can be any object that supports the file API.\n");
1510
1511PyDoc_STRVAR(csv_list_dialects_doc,
1512"Return a list of all know dialect names.\n"
1513" names = csv.list_dialects()");
1514
1515PyDoc_STRVAR(csv_get_dialect_doc,
1516"Return the dialect instance associated with name.\n"
1517" dialect = csv.get_dialect(name)");
1518
1519PyDoc_STRVAR(csv_register_dialect_doc,
1520"Create a mapping from a string name to a dialect class.\n"
1521" dialect = csv.register_dialect(name, dialect)");
1522
1523PyDoc_STRVAR(csv_unregister_dialect_doc,
1524"Delete the name/dialect mapping associated with a string name.\n"
1525" csv.unregister_dialect(name)");
1526
Andrew McNamara31d88962005-01-12 03:45:10 +00001527PyDoc_STRVAR(csv_field_size_limit_doc,
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001528"Sets an upper limit on parsed fields.\n"
Andrew McNamara31d88962005-01-12 03:45:10 +00001529" csv.field_size_limit([limit])\n"
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001530"\n"
1531"Returns old limit. If limit is not given, no new limit is set and\n"
1532"the old limit is returned");
1533
Skip Montanarob4a04172003-03-20 23:29:12 +00001534static struct PyMethodDef csv_methods[] = {
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001535 { "reader", (PyCFunction)csv_reader,
1536 METH_VARARGS | METH_KEYWORDS, csv_reader_doc},
1537 { "writer", (PyCFunction)csv_writer,
1538 METH_VARARGS | METH_KEYWORDS, csv_writer_doc},
1539 { "list_dialects", (PyCFunction)csv_list_dialects,
1540 METH_NOARGS, csv_list_dialects_doc},
1541 { "register_dialect", (PyCFunction)csv_register_dialect,
Andrew McNamara86625972005-01-11 01:28:33 +00001542 METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001543 { "unregister_dialect", (PyCFunction)csv_unregister_dialect,
1544 METH_O, csv_unregister_dialect_doc},
1545 { "get_dialect", (PyCFunction)csv_get_dialect,
1546 METH_O, csv_get_dialect_doc},
Andrew McNamara31d88962005-01-12 03:45:10 +00001547 { "field_size_limit", (PyCFunction)csv_field_size_limit,
1548 METH_VARARGS, csv_field_size_limit_doc},
Andrew McNamarae4d05c42005-01-11 07:32:02 +00001549 { NULL, NULL }
Skip Montanarob4a04172003-03-20 23:29:12 +00001550};
1551
1552PyMODINIT_FUNC
1553init_csv(void)
1554{
1555 PyObject *module;
Skip Montanarob4a04172003-03-20 23:29:12 +00001556 StyleDesc *style;
1557
1558 if (PyType_Ready(&Dialect_Type) < 0)
1559 return;
1560
1561 if (PyType_Ready(&Reader_Type) < 0)
1562 return;
1563
1564 if (PyType_Ready(&Writer_Type) < 0)
1565 return;
1566
1567 /* Create the module and add the functions */
1568 module = Py_InitModule3("_csv", csv_methods, csv_module_doc);
1569 if (module == NULL)
1570 return;
1571
1572 /* Add version to the module. */
Skip Montanaro7b01a832003-04-12 19:23:46 +00001573 if (PyModule_AddStringConstant(module, "__version__",
1574 MODULE_VERSION) == -1)
Skip Montanarob4a04172003-03-20 23:29:12 +00001575 return;
1576
1577 /* Add _dialects dictionary */
1578 dialects = PyDict_New();
1579 if (dialects == NULL)
1580 return;
1581 if (PyModule_AddObject(module, "_dialects", dialects))
1582 return;
1583
1584 /* Add quote styles into dictionary */
1585 for (style = quote_styles; style->name; style++) {
Skip Montanaro7b01a832003-04-12 19:23:46 +00001586 if (PyModule_AddIntConstant(module, style->name,
1587 style->style) == -1)
Skip Montanarob4a04172003-03-20 23:29:12 +00001588 return;
1589 }
1590
1591 /* Add the Dialect type */
Skip Montanaro32c5d422005-06-15 13:35:08 +00001592 Py_INCREF(&Dialect_Type);
Skip Montanarob4a04172003-03-20 23:29:12 +00001593 if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
1594 return;
1595
1596 /* Add the CSV exception object to the module. */
1597 error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
1598 if (error_obj == NULL)
1599 return;
1600 PyModule_AddObject(module, "Error", error_obj);
1601}