cStringIO.c revision af68c874a6803b4e90b616077a602c0593719a1d
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		if (PyList_Append (result, line) == -1) {
245			Py_DECREF (line);
246			goto err;
247		}
248		Py_DECREF (line);
249                length += n;
250                if (hint > 0 && length >= hint)
251			break;
252	}
253	return result;
254 err:
255        Py_DECREF(result);
256        return NULL;
257}
258
259PyDoc_STRVAR(IO_reset__doc__,
260"reset() -- Reset the file position to the beginning");
261
262static PyObject *
263IO_reset(IOobject *self, PyObject *unused) {
264
265        UNLESS (IO__opencheck(self)) return NULL;
266
267        self->pos = 0;
268
269        Py_INCREF(Py_None);
270        return Py_None;
271}
272
273PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
274
275static PyObject *
276IO_tell(IOobject *self, PyObject *unused) {
277
278        UNLESS (IO__opencheck(self)) return NULL;
279
280        return PyInt_FromLong(self->pos);
281}
282
283PyDoc_STRVAR(IO_truncate__doc__,
284"truncate(): truncate the file at the current position.");
285
286static PyObject *
287IO_truncate(IOobject *self, PyObject *args) {
288        int pos = -1;
289
290        UNLESS (IO__opencheck(self)) return NULL;
291        UNLESS (PyArg_ParseTuple(args, "|i:truncate", &pos)) return NULL;
292        if (pos < 0) pos = self->pos;
293
294        if (self->string_size > pos) self->string_size = pos;
295        self->pos = self->string_size;
296
297        Py_INCREF(Py_None);
298        return Py_None;
299}
300
301static PyObject *
302IO_iternext(Iobject *self)
303{
304	PyObject *next;
305	next = IO_readline((IOobject *)self, NULL);
306	if (!next)
307		return NULL;
308	if (!PyString_GET_SIZE(next)) {
309		Py_DECREF(next);
310		PyErr_SetNone(PyExc_StopIteration);
311		return NULL;
312	}
313	return next;
314}
315
316
317
318
319/* Read-write object methods */
320
321PyDoc_STRVAR(O_seek__doc__,
322"seek(position)       -- set the current position\n"
323"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
324
325static PyObject *
326O_seek(Oobject *self, PyObject *args) {
327        int position, mode = 0;
328
329        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
330        UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode))
331                return NULL;
332
333        if (mode == 2) {
334                position += self->string_size;
335        }
336        else if (mode == 1) {
337                position += self->pos;
338        }
339
340        if (position > self->buf_size) {
341                  self->buf_size*=2;
342                  if (self->buf_size <= position) self->buf_size=position+1;
343                  UNLESS (self->buf = (char*)
344                          realloc(self->buf,self->buf_size)) {
345                      self->buf_size=self->pos=0;
346                      return PyErr_NoMemory();
347                    }
348          }
349        else if (position < 0) position=0;
350
351        self->pos=position;
352
353        while (--position >= self->string_size) self->buf[position]=0;
354
355        Py_INCREF(Py_None);
356        return Py_None;
357}
358
359PyDoc_STRVAR(O_write__doc__,
360"write(s) -- Write a string to the file"
361"\n\nNote (hack:) writing None resets the buffer");
362
363
364static int
365O_cwrite(PyObject *self, const char *c, int  l) {
366        int newl;
367        Oobject *oself;
368
369        UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
370        oself = (Oobject *)self;
371
372        newl = oself->pos+l;
373        if (newl >= oself->buf_size) {
374            oself->buf_size *= 2;
375            if (oself->buf_size <= newl)
376                    oself->buf_size = newl+1;
377            UNLESS (oself->buf =
378                    (char*)realloc(oself->buf, oself->buf_size)) {
379                    PyErr_SetString(PyExc_MemoryError,"out of memory");
380                    oself->buf_size = oself->pos = 0;
381                    return -1;
382              }
383          }
384
385        memcpy(oself->buf+oself->pos,c,l);
386
387        oself->pos += l;
388
389        if (oself->string_size < oself->pos) {
390            oself->string_size = oself->pos;
391        }
392
393        return l;
394}
395
396static PyObject *
397O_write(Oobject *self, PyObject *args) {
398        char *c;
399        int l;
400
401        UNLESS (PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
402
403        if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;
404
405        Py_INCREF(Py_None);
406        return Py_None;
407}
408
409PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
410
411static PyObject *
412O_close(Oobject *self, PyObject *unused) {
413        if (self->buf != NULL) free(self->buf);
414        self->buf = NULL;
415
416        self->pos = self->string_size = self->buf_size = 0;
417
418        Py_INCREF(Py_None);
419        return Py_None;
420}
421
422PyDoc_STRVAR(O_writelines__doc__,
423"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
424"\n"
425"Note that newlines are not added.  The sequence can be any iterable object\n"
426"producing strings. This is equivalent to calling write() for each string.");
427static PyObject *
428O_writelines(Oobject *self, PyObject *args) {
429	PyObject *it, *s;
430
431	it = PyObject_GetIter(args);
432	if (it == NULL)
433		return NULL;
434	while ((s = PyIter_Next(it)) != NULL) {
435		int n;
436		char *c;
437		if (PyString_AsStringAndSize(s, &c, &n) == -1) {
438			Py_DECREF(it);
439			Py_DECREF(s);
440			return NULL;
441		}
442		if (O_cwrite((PyObject *)self, c, n) == -1) {
443			Py_DECREF(it);
444			Py_DECREF(s);
445			return NULL;
446               }
447               Py_DECREF(s);
448       }
449
450       Py_DECREF(it);
451
452       /* See if PyIter_Next failed */
453       if (PyErr_Occurred())
454               return NULL;
455
456       Py_RETURN_NONE;
457}
458static struct PyMethodDef O_methods[] = {
459  /* Common methods: */
460  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
461  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
462  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
463  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
464  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
465  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
466  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
467  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
468  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
469
470  /* Read-write StringIO specific  methods: */
471  {"close",      (PyCFunction)O_close,      METH_NOARGS,  O_close__doc__},
472  {"seek",       (PyCFunction)O_seek,       METH_VARARGS, O_seek__doc__},
473  {"write",	 (PyCFunction)O_write,      METH_VARARGS, O_write__doc__},
474  {"writelines", (PyCFunction)O_writelines, METH_O,	  O_writelines__doc__},
475  {NULL,	 NULL}		/* sentinel */
476};
477
478static PyMemberDef O_memberlist[] = {
479	{"softspace",	T_INT,	offsetof(Oobject, softspace),	0,
480	 "flag indicating that a space needs to be printed; used by print"},
481	 /* getattr(f, "closed") is implemented without this table */
482	{NULL} /* Sentinel */
483};
484
485static void
486O_dealloc(Oobject *self) {
487        if (self->buf != NULL)
488                free(self->buf);
489        PyObject_Del(self);
490}
491
492PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
493
494static PyTypeObject Otype = {
495  PyObject_HEAD_INIT(NULL)
496  0,	       			/*ob_size*/
497  "cStringIO.StringO",   	/*tp_name*/
498  sizeof(Oobject),       	/*tp_basicsize*/
499  0,	       			/*tp_itemsize*/
500  /* methods */
501  (destructor)O_dealloc,	/*tp_dealloc*/
502  (printfunc)0,			/*tp_print*/
503  0,		 		/*tp_getattr */
504  0,		 		/*tp_setattr */
505  (cmpfunc)0,			/*tp_compare*/
506  (reprfunc)0,			/*tp_repr*/
507  0,				/*tp_as_number*/
508  0,				/*tp_as_sequence*/
509  0,				/*tp_as_mapping*/
510  (hashfunc)0,			/*tp_hash*/
511  (ternaryfunc)0,		/*tp_call*/
512  (reprfunc)0,			/*tp_str*/
513  0,				/*tp_getattro */
514  0,				/*tp_setattro */
515  0,				/*tp_as_buffer */
516  Py_TPFLAGS_DEFAULT,		/*tp_flags*/
517  Otype__doc__, 		/*tp_doc */
518  0,				/*tp_traverse */
519  0,				/*tp_clear */
520  0,				/*tp_richcompare */
521  0,				/*tp_weaklistoffset */
522  PyObject_SelfIter,		/*tp_iter */
523  (iternextfunc)IO_iternext,	/*tp_iternext */
524  O_methods,			/*tp_methods */
525  O_memberlist,			/*tp_members */
526  file_getsetlist,		/*tp_getset */
527};
528
529static PyObject *
530newOobject(int  size) {
531        Oobject *self;
532
533        self = PyObject_New(Oobject, &Otype);
534        if (self == NULL)
535                return NULL;
536        self->pos=0;
537        self->string_size = 0;
538        self->softspace = 0;
539
540        UNLESS (self->buf = (char *)malloc(size)) {
541                  PyErr_SetString(PyExc_MemoryError,"out of memory");
542                  self->buf_size = 0;
543                  return NULL;
544          }
545
546        self->buf_size=size;
547        return (PyObject*)self;
548}
549
550/* End of code for StringO objects */
551/* -------------------------------------------------------- */
552
553static PyObject *
554I_close(Iobject *self, PyObject *unused) {
555        Py_XDECREF(self->pbuf);
556        self->pbuf = NULL;
557        self->buf = NULL;
558
559        self->pos = self->string_size = 0;
560
561        Py_INCREF(Py_None);
562        return Py_None;
563}
564
565static PyObject *
566I_seek(Iobject *self, PyObject *args) {
567        int position, mode = 0;
568
569        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
570        UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode))
571                return NULL;
572
573        if (mode == 2) position += self->string_size;
574        else if (mode == 1) position += self->pos;
575
576        if (position < 0) position=0;
577
578        self->pos=position;
579
580        Py_INCREF(Py_None);
581        return Py_None;
582}
583
584static struct PyMethodDef I_methods[] = {
585  /* Common methods: */
586  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
587  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
588  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
589  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
590  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
591  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
592  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
593  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
594  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
595
596  /* Read-only StringIO specific  methods: */
597  {"close",     (PyCFunction)I_close,    METH_NOARGS,  O_close__doc__},
598  {"seek",      (PyCFunction)I_seek,     METH_VARARGS, O_seek__doc__},
599  {NULL,	NULL}
600};
601
602static void
603I_dealloc(Iobject *self) {
604  Py_XDECREF(self->pbuf);
605  PyObject_Del(self);
606}
607
608
609PyDoc_STRVAR(Itype__doc__,
610"Simple type for treating strings as input file streams");
611
612static PyTypeObject Itype = {
613  PyObject_HEAD_INIT(NULL)
614  0,					/*ob_size*/
615  "cStringIO.StringI",			/*tp_name*/
616  sizeof(Iobject),			/*tp_basicsize*/
617  0,					/*tp_itemsize*/
618  /* methods */
619  (destructor)I_dealloc,		/*tp_dealloc*/
620  (printfunc)0,				/*tp_print*/
621  0,		 			/* tp_getattr */
622  (setattrfunc)0,			/*tp_setattr*/
623  (cmpfunc)0,				/*tp_compare*/
624  (reprfunc)0,				/*tp_repr*/
625  0,					/*tp_as_number*/
626  0,					/*tp_as_sequence*/
627  0,					/*tp_as_mapping*/
628  (hashfunc)0,				/*tp_hash*/
629  (ternaryfunc)0,			/*tp_call*/
630  (reprfunc)0,				/*tp_str*/
631  0,					/* tp_getattro */
632  0,					/* tp_setattro */
633  0,					/* tp_as_buffer */
634  Py_TPFLAGS_DEFAULT,			/* tp_flags */
635  Itype__doc__,				/* tp_doc */
636  0,					/* tp_traverse */
637  0,					/* tp_clear */
638  0,					/* tp_richcompare */
639  0,					/* tp_weaklistoffset */
640  PyObject_SelfIter,			/* tp_iter */
641  (iternextfunc)IO_iternext,		/* tp_iternext */
642  I_methods,				/* tp_methods */
643  0,					/* tp_members */
644  file_getsetlist,			/* tp_getset */
645};
646
647static PyObject *
648newIobject(PyObject *s) {
649  Iobject *self;
650  char *buf;
651  int size;
652
653  if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
654      PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
655		   s->ob_type->tp_name);
656      return NULL;
657  }
658  UNLESS (self = PyObject_New(Iobject, &Itype)) return NULL;
659  Py_INCREF(s);
660  self->buf=buf;
661  self->string_size=size;
662  self->pbuf=s;
663  self->pos=0;
664
665  return (PyObject*)self;
666}
667
668/* End of code for StringI objects */
669/* -------------------------------------------------------- */
670
671
672PyDoc_STRVAR(IO_StringIO__doc__,
673"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
674
675static PyObject *
676IO_StringIO(PyObject *self, PyObject *args) {
677  PyObject *s=0;
678
679  if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
680
681  if (s) return newIobject(s);
682  return newOobject(128);
683}
684
685/* List of methods defined in the module */
686
687static struct PyMethodDef IO_methods[] = {
688  {"StringIO",	(PyCFunction)IO_StringIO,
689   METH_VARARGS,	IO_StringIO__doc__},
690  {NULL,		NULL}		/* sentinel */
691};
692
693
694/* Initialization function for the module (*must* be called initcStringIO) */
695
696static struct PycStringIO_CAPI CAPI = {
697  IO_cread,
698  IO_creadline,
699  O_cwrite,
700  IO_cgetval,
701  newOobject,
702  newIobject,
703  &Itype,
704  &Otype,
705};
706
707#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
708#define PyMODINIT_FUNC void
709#endif
710PyMODINIT_FUNC
711initcStringIO(void) {
712  PyObject *m, *d, *v;
713
714
715  /* Create the module and add the functions */
716  m = Py_InitModule4("cStringIO", IO_methods,
717		     cStringIO_module_documentation,
718		     (PyObject*)NULL,PYTHON_API_VERSION);
719
720  /* Add some symbolic constants to the module */
721  d = PyModule_GetDict(m);
722
723  /* Export C API */
724  Itype.ob_type=&PyType_Type;
725  Otype.ob_type=&PyType_Type;
726  if (PyType_Ready(&Otype) < 0) return;
727  if (PyType_Ready(&Itype) < 0) return;
728  PyDict_SetItemString(d,"cStringIO_CAPI",
729		       v = PyCObject_FromVoidPtr(&CAPI,NULL));
730  Py_XDECREF(v);
731
732  /* Export Types */
733  PyDict_SetItemString(d,"InputType",  (PyObject*)&Itype);
734  PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
735
736  /* Maybe make certain warnings go away */
737  if (0) PycString_IMPORT;
738}
739