cStringIO.c revision e138828d0360da3782ce56ba8161b45d1505252f
1
2#include "Python.h"
3#include "import.h"
4#include "cStringIO.h"
5#include "structmember.h"
6
7PyDoc_STRVAR(cStringIO_module_documentation,
8"A simple fast partial StringIO replacement.\n"
9"\n"
10"This module provides a simple useful replacement for\n"
11"the StringIO module that is written in C.  It does not provide the\n"
12"full generality of StringIO, but it provides enough for most\n"
13"applications and is especially useful in conjunction with the\n"
14"pickle module.\n"
15"\n"
16"Usage:\n"
17"\n"
18"  from cStringIO import StringIO\n"
19"\n"
20"  an_output_stream=StringIO()\n"
21"  an_output_stream.write(some_stuff)\n"
22"  ...\n"
23"  value=an_output_stream.getvalue()\n"
24"\n"
25"  an_input_stream=StringIO(a_string)\n"
26"  spam=an_input_stream.readline()\n"
27"  spam=an_input_stream.read(5)\n"
28"  an_input_stream.seek(0)           # OK, start over\n"
29"  spam=an_input_stream.read()       # and read it all\n"
30"  \n"
31"If someone else wants to provide a more complete implementation,\n"
32"go for it. :-)  \n"
33"\n"
34"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
35
36#define UNLESS(E) if (!(E))
37
38
39/* Declaration for file-like objects that manage data as strings
40
41   The IOobject type should be though of as a common base type for
42   Iobjects, which provide input (read-only) StringIO objects and
43   Oobjects, which provide read-write objects.  Most of the methods
44   depend only on common data.
45*/
46
47typedef struct {
48  PyObject_HEAD
49  char *buf;
50  int pos, string_size;
51} IOobject;
52
53#define IOOOBJECT(O) ((IOobject*)(O))
54
55/* Declarations for objects of type StringO */
56
57typedef struct { /* Subtype of IOobject */
58  PyObject_HEAD
59  char *buf;
60  int pos, string_size;
61
62  int buf_size, softspace;
63} Oobject;
64
65/* Declarations for objects of type StringI */
66
67typedef struct { /* Subtype of IOobject */
68  PyObject_HEAD
69  char *buf;
70  int pos, string_size;
71  /* We store a reference to the object here in order to keep
72     the buffer alive during the lifetime of the Iobject. */
73  PyObject *pbuf;
74} Iobject;
75
76/* IOobject (common) methods */
77
78PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
79
80static int
81IO__opencheck(IOobject *self) {
82        UNLESS (self->buf) {
83                PyErr_SetString(PyExc_ValueError,
84                                "I/O operation on closed file");
85                return 0;
86        }
87        return 1;
88}
89
90static PyObject *
91IO_get_closed(IOobject *self, void *closure)
92{
93	PyObject *result = Py_False;
94
95	if (self->buf == NULL)
96		result = Py_True;
97	Py_INCREF(result);
98	return result;
99}
100
101static PyGetSetDef file_getsetlist[] = {
102	{"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
103	{0},
104};
105
106static PyObject *
107IO_flush(IOobject *self, PyObject *unused) {
108
109        UNLESS (IO__opencheck(self)) return NULL;
110
111        Py_INCREF(Py_None);
112        return Py_None;
113}
114
115PyDoc_STRVAR(IO_getval__doc__,
116"getvalue([use_pos]) -- Get the string value."
117"\n"
118"If use_pos is specified and is a true value, then the string returned\n"
119"will include only the text up to the current file position.\n");
120
121static PyObject *
122IO_cgetval(PyObject *self) {
123        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
124        return PyString_FromStringAndSize(((IOobject*)self)->buf,
125                                          ((IOobject*)self)->pos);
126}
127
128static PyObject *
129IO_getval(IOobject *self, PyObject *args) {
130        PyObject *use_pos=Py_None;
131        int s;
132
133        UNLESS (IO__opencheck(self)) return NULL;
134        UNLESS (PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;
135
136        if (PyObject_IsTrue(use_pos)) {
137                  s=self->pos;
138                  if (s > self->string_size) s=self->string_size;
139        }
140        else
141                  s=self->string_size;
142        return PyString_FromStringAndSize(self->buf, s);
143}
144
145PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
146
147static PyObject *
148IO_isatty(IOobject *self, PyObject *unused) {
149	Py_INCREF(Py_False);
150        return Py_False;
151}
152
153PyDoc_STRVAR(IO_read__doc__,
154"read([s]) -- Read s characters, or the rest of the string");
155
156static int
157IO_cread(PyObject *self, char **output, int  n) {
158        int l;
159
160        UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
161        l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;
162        if (n < 0 || n > l) {
163                n = l;
164                if (n < 0) n=0;
165        }
166
167        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
168        ((IOobject*)self)->pos += n;
169        return n;
170}
171
172static PyObject *
173IO_read(IOobject *self, PyObject *args) {
174        int n = -1;
175        char *output;
176
177        UNLESS (PyArg_ParseTuple(args, "|i:read", &n)) return NULL;
178
179        if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;
180
181        return PyString_FromStringAndSize(output, n);
182}
183
184PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
185
186static int
187IO_creadline(PyObject *self, char **output) {
188        char *n, *s;
189        int l;
190
191        UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
192
193        for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
194               s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size;
195             n < s && *n != '\n'; n++);
196        if (n < s) n++;
197
198        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
199        l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
200        ((IOobject*)self)->pos += l;
201        return l;
202}
203
204static PyObject *
205IO_readline(IOobject *self, PyObject *args) {
206        int n, m=-1;
207        char *output;
208
209        if (args)
210                UNLESS (PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
211
212        if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
213        if (m >= 0 && m < n) {
214                m = n - m;
215                n -= m;
216                self->pos -= m;
217        }
218        return PyString_FromStringAndSize(output, n);
219}
220
221PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
222
223static PyObject *
224IO_readlines(IOobject *self, PyObject *args) {
225	int n;
226	char *output;
227	PyObject *result, *line;
228        int hint = 0, length = 0;
229
230        UNLESS (PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;
231
232	result = PyList_New(0);
233	if (!result)
234		return NULL;
235
236	while (1){
237		if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
238                        goto err;
239		if (n == 0)
240			break;
241		line = PyString_FromStringAndSize (output, n);
242		if (!line)
243                        goto err;
244		PyList_Append (result, line);
245		Py_DECREF (line);
246                length += n;
247                if (hint > 0 && length >= hint)
248			break;
249	}
250	return result;
251 err:
252        Py_DECREF(result);
253        return NULL;
254}
255
256PyDoc_STRVAR(IO_reset__doc__,
257"reset() -- Reset the file position to the beginning");
258
259static PyObject *
260IO_reset(IOobject *self, PyObject *unused) {
261
262        UNLESS (IO__opencheck(self)) return NULL;
263
264        self->pos = 0;
265
266        Py_INCREF(Py_None);
267        return Py_None;
268}
269
270PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
271
272static PyObject *
273IO_tell(IOobject *self, PyObject *unused) {
274
275        UNLESS (IO__opencheck(self)) return NULL;
276
277        return PyInt_FromLong(self->pos);
278}
279
280PyDoc_STRVAR(IO_truncate__doc__,
281"truncate(): truncate the file at the current position.");
282
283static PyObject *
284IO_truncate(IOobject *self, PyObject *args) {
285        int pos = -1;
286
287        UNLESS (IO__opencheck(self)) return NULL;
288        UNLESS (PyArg_ParseTuple(args, "|i:truncate", &pos)) return NULL;
289        if (pos < 0) pos = self->pos;
290
291        if (self->string_size > pos) self->string_size = pos;
292
293        Py_INCREF(Py_None);
294        return Py_None;
295}
296
297static PyObject *
298IO_iternext(Iobject *self)
299{
300	PyObject *next;
301	next = IO_readline((IOobject *)self, NULL);
302	if (!next)
303		return NULL;
304	if (!PyString_GET_SIZE(next)) {
305		Py_DECREF(next);
306		PyErr_SetNone(PyExc_StopIteration);
307		return NULL;
308	}
309	return next;
310}
311
312
313
314
315/* Read-write object methods */
316
317PyDoc_STRVAR(O_seek__doc__,
318"seek(position)       -- set the current position\n"
319"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
320
321static PyObject *
322O_seek(Oobject *self, PyObject *args) {
323        int position, mode = 0;
324
325        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
326        UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode))
327                return NULL;
328
329        if (mode == 2) {
330                position += self->string_size;
331        }
332        else if (mode == 1) {
333                position += self->pos;
334        }
335
336        if (position > self->buf_size) {
337                  self->buf_size*=2;
338                  if (self->buf_size <= position) self->buf_size=position+1;
339                  UNLESS (self->buf=(char*)
340                          realloc(self->buf,self->buf_size*sizeof(char))) {
341                      self->buf_size=self->pos=0;
342                      return PyErr_NoMemory();
343                    }
344          }
345        else if (position < 0) position=0;
346
347        self->pos=position;
348
349        while (--position >= self->string_size) self->buf[position]=0;
350
351        Py_INCREF(Py_None);
352        return Py_None;
353}
354
355PyDoc_STRVAR(O_write__doc__,
356"write(s) -- Write a string to the file"
357"\n\nNote (hack:) writing None resets the buffer");
358
359
360static int
361O_cwrite(PyObject *self, char *c, int  l) {
362        int newl;
363        Oobject *oself;
364
365        UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
366        oself = (Oobject *)self;
367
368        newl = oself->pos+l;
369        if (newl >= oself->buf_size) {
370            oself->buf_size *= 2;
371            if (oself->buf_size <= newl)
372                    oself->buf_size = newl+1;
373            UNLESS (oself->buf =
374                    (char*)realloc(oself->buf,
375                                   (oself->buf_size) * sizeof(char))) {
376                    PyErr_SetString(PyExc_MemoryError,"out of memory");
377                    oself->buf_size = oself->pos = 0;
378                    return -1;
379              }
380          }
381
382        memcpy(oself->buf+oself->pos,c,l);
383
384        oself->pos += l;
385
386        if (oself->string_size < oself->pos) {
387            oself->string_size = oself->pos;
388        }
389
390        return l;
391}
392
393static PyObject *
394O_write(Oobject *self, PyObject *args) {
395        char *c;
396        int l;
397
398        UNLESS (PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
399
400        if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;
401
402        Py_INCREF(Py_None);
403        return Py_None;
404}
405
406PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
407
408static PyObject *
409O_close(Oobject *self, PyObject *unused) {
410        if (self->buf != NULL) free(self->buf);
411        self->buf = NULL;
412
413        self->pos = self->string_size = self->buf_size = 0;
414
415        Py_INCREF(Py_None);
416        return Py_None;
417}
418
419
420PyDoc_STRVAR(O_writelines__doc__,
421"writelines(sequence_of_strings): write each string");
422static PyObject *
423O_writelines(Oobject *self, PyObject *args) {
424        PyObject *tmp = 0;
425	static PyObject *joiner = NULL;
426
427	if (!joiner) {
428		PyObject *empty_string = PyString_FromString("");
429		if (empty_string == NULL)
430			return NULL;
431		joiner = PyObject_GetAttrString(empty_string, "join");
432		Py_DECREF(empty_string);
433		if (joiner == NULL)
434			return NULL;
435	}
436
437        if (PyObject_Size(args) < 0) return NULL;
438
439        tmp = PyObject_CallFunction(joiner, "O", args);
440        UNLESS (tmp) return NULL;
441
442        args = Py_BuildValue("(O)", tmp);
443        Py_DECREF(tmp);
444        UNLESS (args) return NULL;
445
446        tmp = O_write(self, args);
447        Py_DECREF(args);
448        return tmp;
449}
450
451static struct PyMethodDef O_methods[] = {
452  /* Common methods: */
453  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
454  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
455  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
456  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
457  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
458  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
459  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
460  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
461  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
462
463  /* Read-write StringIO specific  methods: */
464  {"close",      (PyCFunction)O_close,      METH_NOARGS,  O_close__doc__},
465  {"seek",       (PyCFunction)O_seek,       METH_VARARGS, O_seek__doc__},
466  {"write",	 (PyCFunction)O_write,      METH_VARARGS, O_write__doc__},
467  {"writelines", (PyCFunction)O_writelines, METH_O,	  O_writelines__doc__},
468  {NULL,	 NULL}		/* sentinel */
469};
470
471static PyMemberDef O_memberlist[] = {
472	{"softspace",	T_INT,	offsetof(Oobject, softspace),	0,
473	 "flag indicating that a space needs to be printed; used by print"},
474	 /* getattr(f, "closed") is implemented without this table */
475	{NULL} /* Sentinel */
476};
477
478static void
479O_dealloc(Oobject *self) {
480        if (self->buf != NULL)
481                free(self->buf);
482        PyObject_Del(self);
483}
484
485PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
486
487static PyTypeObject Otype = {
488  PyObject_HEAD_INIT(NULL)
489  0,	       			/*ob_size*/
490  "cStringIO.StringIO",   	/*tp_name*/
491  sizeof(Oobject),       	/*tp_basicsize*/
492  0,	       			/*tp_itemsize*/
493  /* methods */
494  (destructor)O_dealloc,	/*tp_dealloc*/
495  (printfunc)0,			/*tp_print*/
496  0,		 		/*tp_getattr */
497  0,		 		/*tp_setattr */
498  (cmpfunc)0,			/*tp_compare*/
499  (reprfunc)0,			/*tp_repr*/
500  0,				/*tp_as_number*/
501  0,				/*tp_as_sequence*/
502  0,				/*tp_as_mapping*/
503  (hashfunc)0,			/*tp_hash*/
504  (ternaryfunc)0,		/*tp_call*/
505  (reprfunc)0,			/*tp_str*/
506  0,				/*tp_getattro */
507  0,				/*tp_setattro */
508  0,				/*tp_as_buffer */
509  Py_TPFLAGS_DEFAULT,		/*tp_flags*/
510  Otype__doc__, 		/*tp_doc */
511  0,				/*tp_traverse */
512  0,				/*tp_clear */
513  0,				/*tp_richcompare */
514  0,				/*tp_weaklistoffset */
515  PyObject_SelfIter,		/*tp_iter */
516  (iternextfunc)IO_iternext,	/*tp_iternext */
517  O_methods,			/*tp_methods */
518  O_memberlist,			/*tp_members */
519  file_getsetlist,		/*tp_getset */
520};
521
522static PyObject *
523newOobject(int  size) {
524        Oobject *self;
525
526        self = PyObject_New(Oobject, &Otype);
527        if (self == NULL)
528                return NULL;
529        self->pos=0;
530        self->string_size = 0;
531        self->softspace = 0;
532
533        UNLESS (self->buf=malloc(size*sizeof(char))) {
534                  PyErr_SetString(PyExc_MemoryError,"out of memory");
535                  self->buf_size = 0;
536                  return NULL;
537          }
538
539        self->buf_size=size;
540        return (PyObject*)self;
541}
542
543/* End of code for StringO objects */
544/* -------------------------------------------------------- */
545
546static PyObject *
547I_close(Iobject *self, PyObject *unused) {
548        Py_XDECREF(self->pbuf);
549        self->pbuf = NULL;
550        self->buf = NULL;
551
552        self->pos = self->string_size = 0;
553
554        Py_INCREF(Py_None);
555        return Py_None;
556}
557
558static PyObject *
559I_seek(Iobject *self, PyObject *args) {
560        int position, mode = 0;
561
562        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
563        UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode))
564                return NULL;
565
566        if (mode == 2) position += self->string_size;
567        else if (mode == 1) position += self->pos;
568
569        if (position < 0) position=0;
570
571        self->pos=position;
572
573        Py_INCREF(Py_None);
574        return Py_None;
575}
576
577static struct PyMethodDef I_methods[] = {
578  /* Common methods: */
579  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
580  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
581  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
582  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
583  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
584  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
585  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
586  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
587  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
588
589  /* Read-only StringIO specific  methods: */
590  {"close",     (PyCFunction)I_close,    METH_NOARGS,  O_close__doc__},
591  {"seek",      (PyCFunction)I_seek,     METH_VARARGS, O_seek__doc__},
592  {NULL,	NULL}
593};
594
595static void
596I_dealloc(Iobject *self) {
597  Py_XDECREF(self->pbuf);
598  PyObject_Del(self);
599}
600
601
602PyDoc_STRVAR(Itype__doc__,
603"Simple type for treating strings as input file streams");
604
605static PyTypeObject Itype = {
606  PyObject_HEAD_INIT(NULL)
607  0,					/*ob_size*/
608  "cStringIO.StringIO",			/*tp_name*/
609  sizeof(Iobject),			/*tp_basicsize*/
610  0,					/*tp_itemsize*/
611  /* methods */
612  (destructor)I_dealloc,		/*tp_dealloc*/
613  (printfunc)0,				/*tp_print*/
614  0,		 			/* tp_getattr */
615  (setattrfunc)0,			/*tp_setattr*/
616  (cmpfunc)0,				/*tp_compare*/
617  (reprfunc)0,				/*tp_repr*/
618  0,					/*tp_as_number*/
619  0,					/*tp_as_sequence*/
620  0,					/*tp_as_mapping*/
621  (hashfunc)0,				/*tp_hash*/
622  (ternaryfunc)0,			/*tp_call*/
623  (reprfunc)0,				/*tp_str*/
624  0,					/* tp_getattro */
625  0,					/* tp_setattro */
626  0,					/* tp_as_buffer */
627  Py_TPFLAGS_DEFAULT,			/* tp_flags */
628  Itype__doc__,				/* tp_doc */
629  0,					/* tp_traverse */
630  0,					/* tp_clear */
631  0,					/* tp_richcompare */
632  0,					/* tp_weaklistoffset */
633  PyObject_SelfIter,			/* tp_iter */
634  (iternextfunc)IO_iternext,		/* tp_iternext */
635  I_methods,				/* tp_methods */
636  0,					/* tp_members */
637  file_getsetlist,			/* tp_getset */
638};
639
640static PyObject *
641newIobject(PyObject *s) {
642  Iobject *self;
643  char *buf;
644  int size;
645
646  if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
647      PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
648		   s->ob_type->tp_name);
649      return NULL;
650  }
651  UNLESS (self = PyObject_New(Iobject, &Itype)) return NULL;
652  Py_INCREF(s);
653  self->buf=buf;
654  self->string_size=size;
655  self->pbuf=s;
656  self->pos=0;
657
658  return (PyObject*)self;
659}
660
661/* End of code for StringI objects */
662/* -------------------------------------------------------- */
663
664
665PyDoc_STRVAR(IO_StringIO__doc__,
666"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
667
668static PyObject *
669IO_StringIO(PyObject *self, PyObject *args) {
670  PyObject *s=0;
671
672  if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
673
674  if (s) return newIobject(s);
675  return newOobject(128);
676}
677
678/* List of methods defined in the module */
679
680static struct PyMethodDef IO_methods[] = {
681  {"StringIO",	(PyCFunction)IO_StringIO,
682   METH_VARARGS,	IO_StringIO__doc__},
683  {NULL,		NULL}		/* sentinel */
684};
685
686
687/* Initialization function for the module (*must* be called initcStringIO) */
688
689static struct PycStringIO_CAPI CAPI = {
690  IO_cread,
691  IO_creadline,
692  O_cwrite,
693  IO_cgetval,
694  newOobject,
695  newIobject,
696  &Itype,
697  &Otype,
698};
699
700#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
701#define PyMODINIT_FUNC void
702#endif
703PyMODINIT_FUNC
704initcStringIO(void) {
705  PyObject *m, *d, *v;
706
707
708  /* Create the module and add the functions */
709  m = Py_InitModule4("cStringIO", IO_methods,
710		     cStringIO_module_documentation,
711		     (PyObject*)NULL,PYTHON_API_VERSION);
712
713  /* Add some symbolic constants to the module */
714  d = PyModule_GetDict(m);
715
716  /* Export C API */
717  Itype.ob_type=&PyType_Type;
718  Otype.ob_type=&PyType_Type;
719  if (PyType_Ready(&Otype) < 0) return;
720  if (PyType_Ready(&Itype) < 0) return;
721  PyDict_SetItemString(d,"cStringIO_CAPI",
722		       v = PyCObject_FromVoidPtr(&CAPI,NULL));
723  Py_XDECREF(v);
724
725  /* Export Types */
726  PyDict_SetItemString(d,"InputType",  (PyObject*)&Itype);
727  PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
728
729  /* Maybe make certain warnings go away */
730  if (0) PycString_IMPORT;
731}
732