1
/* psycopgmodule.c - psycopg module (will import other C classes)
3
* Copyright (C) 2003 Federico Di Gregorio <fog@debian.org>
5
* This file is part of psycopg.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 2,
10
* or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
#define PSYCOPG_MODULE
25
#include "psycopg/config.h"
26
#include "psycopg/python.h"
27
#include "psycopg/psycopg.h"
28
#include "psycopg/connection.h"
29
#include "psycopg/cursor.h"
30
#include "psycopg/typecast.h"
31
#include "psycopg/microprotocols.h"
32
#include "psycopg/microprotocols_proto.h"
34
#include "psycopg/adapter_qstring.h"
35
#include "psycopg/adapter_binary.h"
36
#include "psycopg/adapter_pboolean.h"
37
#include "psycopg/adapter_asis.h"
38
#include "psycopg/adapter_list.h"
39
#include "psycopg/typecast_binary.h"
41
#ifdef HAVE_MXDATETIME
42
#include <mxDateTime.h>
43
#include "psycopg/adapter_mxdatetime.h"
44
mxDateTimeModule_APIObject *mxDateTimeP = NULL;
47
/* some module-level variables, like the datetime module */
48
#ifdef HAVE_PYDATETIME
50
#include "psycopg/adapter_datetime.h"
51
PyObject *pyDateTimeModuleP = NULL;
52
PyObject *pyDateTypeP = NULL;
53
PyObject *pyTimeTypeP = NULL;
54
PyObject *pyDateTimeTypeP = NULL;
55
PyObject *pyDeltaTypeP = NULL;
58
/* pointers to the psycopg.tz classes */
59
PyObject *pyPsycopgTzModule = NULL;
60
PyObject *pyPsycopgTzLOCAL = NULL;
61
PyObject *pyPsycopgTzFixedOffsetTimezone = NULL;
63
PyObject *psycoEncodings = NULL;
64
PyObject *decimalType = NULL;
66
/** connect module-level function **/
67
#define psyco_connect_doc \
68
"connect(dsn, ...) -- Create a new database connection.\n\n" \
69
"This function supports two different but equivalent sets of arguments.\n" \
70
"A single data source name or ``dsn`` string can be used to specify the\n" \
71
"connection parameters, as follows::\n\n" \
72
" psycopg2.connect(\"dbname=xxx user=xxx ...\")\n\n" \
73
"If ``dsn`` is not provided it is possible to pass the parameters as\n" \
74
"keyword arguments; e.g.::\n\n" \
75
" psycopg2.connect(database='xxx', user='xxx', ...)\n\n" \
76
"The full list of available parameters is:\n\n" \
77
"- ``dbname`` -- database name (only in 'dsn')\n" \
78
"- ``database`` -- database name (only as keyword argument)\n" \
79
"- ``host`` -- host address (defaults to UNIX socket if not provided)\n" \
80
"- ``port`` -- port number (defaults to 5432 if not provided)\n" \
81
"- ``user`` -- user name used to authenticate\n" \
82
"- ``password`` -- password used to authenticate\n" \
83
"- ``sslmode`` -- SSL mode (see PostgreSQL documentation)\n\n" \
84
"If the ``connection_factory`` keyword argument is not provided this\n" \
85
"function always return an instance of the `connection` class.\n" \
86
"Else the given sub-class of `extensions.connection` will be used to\n" \
87
"instantiate the connection object.\n\n" \
88
":return: New database connection\n" \
89
":rtype: `extensions.connection`"
92
_psyco_connect_fill_dsn(char *dsn, char *kw, char *v, int i)
94
strcpy(&dsn[i], kw); i += strlen(kw);
95
strcpy(&dsn[i], v); i += strlen(v);
100
_psyco_connect_fill_exc(connectionObject *conn)
102
/* fill the connection object with the exceptions */
103
conn->exc_Error = Error;
105
conn->exc_Warning = Warning;
107
conn->exc_InterfaceError = InterfaceError;
108
Py_INCREF(InterfaceError);
109
conn->exc_DatabaseError = DatabaseError;
110
Py_INCREF(DatabaseError);
111
conn->exc_InternalError = InternalError;
112
Py_INCREF(InternalError);
113
conn->exc_ProgrammingError = ProgrammingError;
114
Py_INCREF(ProgrammingError);
115
conn->exc_IntegrityError = IntegrityError;
116
Py_INCREF(IntegrityError);
117
conn->exc_DataError = DataError;
118
Py_INCREF(DataError);
119
conn->exc_NotSupportedError = NotSupportedError;
120
Py_INCREF(NotSupportedError);
124
psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
126
PyObject *conn, *factory = NULL;
128
int idsn=-1, iport=-1;
129
char *dsn=NULL, *database=NULL, *user=NULL, *password=NULL;
130
char *host=NULL, *sslmode=NULL;
133
static char *kwlist[] = {"dsn", "database", "host", "port",
134
"user", "password", "sslmode",
135
"connection_factory", NULL};
137
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sssisssO", kwlist,
138
&dsn, &database, &host, &iport,
139
&user, &password, &sslmode, &factory)) {
144
PyOS_snprintf(port, 16, "%d", iport);
147
int l = 45; /* len("dbname= user= password= host= port= sslmode=\0") */
149
if (database) l += strlen(database);
150
if (host) l += strlen(host);
151
if (iport > 0) l += strlen(port);
152
if (user) l += strlen(user);
153
if (password) l += strlen(password);
154
if (sslmode) l += strlen(sslmode);
156
dsn = malloc(l*sizeof(char));
158
PyErr_SetString(InterfaceError, "dynamic dsn allocation failed");
164
idsn = _psyco_connect_fill_dsn(dsn, " dbname=", database, idsn);
166
idsn = _psyco_connect_fill_dsn(dsn, " host=", host, idsn);
168
idsn = _psyco_connect_fill_dsn(dsn, " port=", port, idsn);
170
idsn = _psyco_connect_fill_dsn(dsn, " user=", user, idsn);
172
idsn = _psyco_connect_fill_dsn(dsn, " password=", password, idsn);
174
idsn = _psyco_connect_fill_dsn(dsn, " sslmode=", sslmode, idsn);
178
memmove(dsn, &dsn[1], idsn);
182
PyErr_SetString(InterfaceError, "missing dsn and no parameters");
187
Dprintf("psyco_connect: dsn = '%s'", dsn);
189
/* allocate connection, fill with errors and return it */
190
if (factory == NULL) factory = (PyObject *)&connectionType;
191
conn = PyObject_CallFunction(factory, "s", dsn);
192
if (conn) _psyco_connect_fill_exc((connectionObject*)conn);
197
/** type registration **/
198
#define psyco_register_type_doc \
199
"register_type(obj) -> None -- register obj with psycopg type system\n\n" \
201
" * `obj`: A type adapter created by `new_type()`"
203
#define typecast_from_python_doc \
204
"new_type(oids, name, adapter) -> new type object\n\n" \
205
"Create a new binding object. The object can be used with the\n" \
206
"`register_type()` function to bind PostgreSQL objects to python objects.\n\n" \
208
" * `oids`: Tuple of ``oid`` of the PostgreSQL types to convert.\n" \
209
" * `name`: Name for the new type\n" \
210
" * `adapter`: Callable to perform type conversion.\n" \
211
" It must have the signature ``fun(value, cur)`` where ``value`` is\n" \
212
" the string representation returned by PostgreSQL (`None` if ``NULL``)\n" \
213
" and ``cur`` is the cursor from which data are read."
216
psyco_register_type(PyObject *self, PyObject *args)
220
if (!PyArg_ParseTuple(args, "O!", &typecastType, &type)) {
224
typecast_add(type, 0);
231
/* default adapters */
234
psyco_adapters_init(PyObject *mod)
238
microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&asisType);
239
microprotocols_add(&PyInt_Type, NULL, (PyObject*)&asisType);
240
microprotocols_add(&PyLong_Type, NULL, (PyObject*)&asisType);
242
microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType);
243
microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType);
244
microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType);
245
microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType);
247
#ifdef HAVE_MXDATETIME
248
/* the module has already been initialized, so we can obtain the callable
249
objects directly from its dictionary :) */
250
call = PyMapping_GetItemString(mod, "TimestampFromMx");
251
microprotocols_add(mxDateTimeP->DateTime_Type, NULL, call);
252
call = PyMapping_GetItemString(mod, "TimeFromMx");
253
microprotocols_add(mxDateTimeP->DateTimeDelta_Type, NULL, call);
256
#ifdef HAVE_PYDATETIME
257
/* as above, we use the callable objects from the psycopg module */
258
call = PyMapping_GetItemString(mod, "DateFromPy");
259
microprotocols_add((PyTypeObject*)pyDateTypeP, NULL, call);
260
call = PyMapping_GetItemString(mod, "TimeFromPy");
261
microprotocols_add((PyTypeObject*)pyTimeTypeP, NULL, call);
262
call = PyMapping_GetItemString(mod, "TimestampFromPy");
263
microprotocols_add((PyTypeObject*)pyDateTimeTypeP, NULL, call);
264
call = PyMapping_GetItemString(mod, "IntervalFromPy");
265
microprotocols_add((PyTypeObject*)pyDeltaTypeP, NULL, call);
269
microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType);
273
microprotocols_add((PyTypeObject*)decimalType, NULL, (PyObject*)&asisType);
277
/* psyco_encodings_fill
279
Fill the module's postgresql<->python encoding table */
281
static encodingPair encodings[] = {
282
{"SQL_ASCII", "ascii"},
283
{"LATIN1", "latin_1"},
284
{"UNICODE", "utf_8"},
287
/* some compatibility stuff */
288
{"LATIN-1", "latin_1"},
292
static void psyco_encodings_fill(PyObject *dict)
296
for (enc = encodings; enc->pgenc != NULL; enc++) {
297
PyObject *value = PyString_FromString(enc->pyenc);
298
PyDict_SetItemString(dict, enc->pgenc, value);
303
/* psyco_errors_init, psyco_errors_fill (callable from C)
305
Initialize the module's exceptions and after that a dictionary with a full
306
set of exceptions. */
308
PyObject *Error, *Warning, *InterfaceError, *DatabaseError,
309
*InternalError, *OperationalError, *ProgrammingError,
310
*IntegrityError, *DataError, *NotSupportedError;
312
/* mapping between exception names and their PyObject */
319
{ "psycopg2.Error", &Error, 0, Error_doc },
320
{ "psycopg2.Warning", &Warning, 0, Warning_doc },
321
{ "psycopg2.InterfaceError", &InterfaceError, &Error, InterfaceError_doc },
322
{ "psycopg2.DatabaseError", &DatabaseError, &Error, DatabaseError_doc },
323
{ "psycopg2.InternalError", &InternalError, &DatabaseError, InternalError_doc },
324
{ "psycopg2.OperationalError", &OperationalError, &DatabaseError,
325
OperationalError_doc },
326
{ "psycopg2.ProgrammingError", &ProgrammingError, &DatabaseError,
327
ProgrammingError_doc },
328
{ "psycopg2.IntegrityError", &IntegrityError, &DatabaseError,
329
IntegrityError_doc },
330
{ "psycopg2.DataError", &DataError, &DatabaseError, DataError_doc },
331
{ "psycopg2.NotSupportedError", &NotSupportedError, &DatabaseError,
332
NotSupportedError_doc },
333
{NULL} /* Sentinel */
337
psyco_errors_init(void)
339
/* the names of the exceptions here reflect the oranization of the
340
psycopg2 module and not the fact the the original error objects
348
for (i=0; exctable[i].name; i++) {
351
if (exctable[i].docstr) {
352
str = PyString_FromString(exctable[i].docstr);
353
PyDict_SetItemString(dict, "__doc__", str);
356
if (exctable[i].base == 0)
357
base = PyExc_StandardError;
359
base = *exctable[i].base;
361
*exctable[i].exc = PyErr_NewException(exctable[i].name, base, dict);
366
psyco_errors_fill(PyObject *dict)
368
PyDict_SetItemString(dict, "Error", Error);
369
PyDict_SetItemString(dict, "Warning", Warning);
370
PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
371
PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
372
PyDict_SetItemString(dict, "InternalError", InternalError);
373
PyDict_SetItemString(dict, "OperationalError", OperationalError);
374
PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
375
PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
376
PyDict_SetItemString(dict, "DataError", DataError);
377
PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
381
psyco_errors_set(PyObject *type)
383
PyObject_SetAttrString(type, "Error", Error);
384
PyObject_SetAttrString(type, "Warning", Warning);
385
PyObject_SetAttrString(type, "InterfaceError", InterfaceError);
386
PyObject_SetAttrString(type, "DatabaseError", DatabaseError);
387
PyObject_SetAttrString(type, "InternalError", InternalError);
388
PyObject_SetAttrString(type, "OperationalError", OperationalError);
389
PyObject_SetAttrString(type, "ProgrammingError", ProgrammingError);
390
PyObject_SetAttrString(type, "IntegrityError", IntegrityError);
391
PyObject_SetAttrString(type, "DataError", DataError);
392
PyObject_SetAttrString(type, "NotSupportedError", NotSupportedError);
397
Create a new error of the given type with extra attributes. */
400
psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
401
char *pgerror, char *pgcode)
405
PyObject *err = PyObject_CallFunction(exc, "s", msg);
409
t = PyString_FromString(pgerror);
412
t = Py_None ; Py_INCREF(t);
414
PyObject_SetAttrString(err, "pgerror", t);
418
t = PyString_FromString(pgcode);
421
t = Py_None ; Py_INCREF(t);
423
PyObject_SetAttrString(err, "pgcode", t);
427
PyObject_SetAttrString(err, "cursor", curs);
429
PyObject_SetAttrString(err, "cursor", Py_None);
431
PyErr_SetObject(exc, err);
436
/* psyco_decimal_init
438
Initialize the module's pointer to the decimal type. */
441
psyco_decimal_init(void)
444
PyObject *decimal = PyImport_ImportModule("decimal");
446
decimalType = PyObject_GetAttrString(decimal, "Decimal");
450
decimalType = (PyObject *)&PyFloat_Type;
451
Py_INCREF(decimalType);
457
/** method table and module initialization **/
459
static PyMethodDef psycopgMethods[] = {
460
{"connect", (PyCFunction)psyco_connect,
461
METH_VARARGS|METH_KEYWORDS, psyco_connect_doc},
462
{"adapt", (PyCFunction)psyco_microprotocols_adapt,
463
METH_VARARGS, psyco_microprotocols_adapt_doc},
465
{"register_type", (PyCFunction)psyco_register_type,
466
METH_VARARGS, psyco_register_type_doc},
467
{"new_type", (PyCFunction)typecast_from_python,
468
METH_VARARGS|METH_KEYWORDS, typecast_from_python_doc},
470
{"AsIs", (PyCFunction)psyco_AsIs,
471
METH_VARARGS, psyco_AsIs_doc},
472
{"QuotedString", (PyCFunction)psyco_QuotedString,
473
METH_VARARGS, psyco_QuotedString_doc},
474
{"Boolean", (PyCFunction)psyco_Boolean,
475
METH_VARARGS, psyco_Boolean_doc},
476
{"Binary", (PyCFunction)psyco_Binary,
477
METH_VARARGS, psyco_Binary_doc},
478
{"Date", (PyCFunction)psyco_Date,
479
METH_VARARGS, psyco_Date_doc},
480
{"Time", (PyCFunction)psyco_Time,
481
METH_VARARGS, psyco_Time_doc},
482
{"Timestamp", (PyCFunction)psyco_Timestamp,
483
METH_VARARGS, psyco_Timestamp_doc},
484
{"DateFromTicks", (PyCFunction)psyco_DateFromTicks,
485
METH_VARARGS, psyco_DateFromTicks_doc},
486
{"TimeFromTicks", (PyCFunction)psyco_TimeFromTicks,
487
METH_VARARGS, psyco_TimeFromTicks_doc},
488
{"TimestampFromTicks", (PyCFunction)psyco_TimestampFromTicks,
489
METH_VARARGS, psyco_TimestampFromTicks_doc},
490
{"List", (PyCFunction)psyco_List,
491
METH_VARARGS, psyco_List_doc},
493
#ifdef HAVE_MXDATETIME
494
{"DateFromMx", (PyCFunction)psyco_DateFromMx,
495
METH_VARARGS, psyco_DateFromMx_doc},
496
{"TimeFromMx", (PyCFunction)psyco_TimeFromMx,
497
METH_VARARGS, psyco_TimeFromMx_doc},
498
{"TimestampFromMx", (PyCFunction)psyco_TimestampFromMx,
499
METH_VARARGS, psyco_TimestampFromMx_doc},
500
{"IntervalFromMx", (PyCFunction)psyco_IntervalFromMx,
501
METH_VARARGS, psyco_IntervalFromMx_doc},
504
#ifdef HAVE_PYDATETIME
505
{"DateFromPy", (PyCFunction)psyco_DateFromPy,
506
METH_VARARGS, psyco_DateFromPy_doc},
507
{"TimeFromPy", (PyCFunction)psyco_TimeFromPy,
508
METH_VARARGS, psyco_TimeFromPy_doc},
509
{"TimestampFromPy", (PyCFunction)psyco_TimestampFromPy,
510
METH_VARARGS, psyco_TimestampFromPy_doc},
511
{"IntervalFromPy", (PyCFunction)psyco_IntervalFromPy,
512
METH_VARARGS, psyco_IntervalFromPy_doc},
515
{NULL, NULL, 0, NULL} /* Sentinel */
521
static void *PSYCOPG_API[PSYCOPG_API_pointers];
523
PyObject *module, *dict;
524
PyObject *c_api_object;
526
Dprintf("initpsycopg: initializing psycopg %s", PSYCOPG_VERSION);
528
/* initialize all the new types and then the module */
529
connectionType.ob_type = &PyType_Type;
530
cursorType.ob_type = &PyType_Type;
531
typecastType.ob_type = &PyType_Type;
532
qstringType.ob_type = &PyType_Type;
533
binaryType.ob_type = &PyType_Type;
534
isqlquoteType.ob_type = &PyType_Type;
535
asisType.ob_type = &PyType_Type;
536
listType.ob_type = &PyType_Type;
537
chunkType.ob_type = &PyType_Type;
539
if (PyType_Ready(&connectionType) == -1) return;
540
if (PyType_Ready(&cursorType) == -1) return;
541
if (PyType_Ready(&typecastType) == -1) return;
542
if (PyType_Ready(&qstringType) == -1) return;
543
if (PyType_Ready(&binaryType) == -1) return;
544
if (PyType_Ready(&isqlquoteType) == -1) return;
545
if (PyType_Ready(&asisType) == -1) return;
546
if (PyType_Ready(&listType) == -1) return;
547
if (PyType_Ready(&chunkType) == -1) return;
550
pbooleanType.ob_type = &PyType_Type;
551
if (PyType_Ready(&pbooleanType) == -1) return;
554
/* import mx.DateTime module, if necessary */
555
#ifdef HAVE_MXDATETIME
556
mxdatetimeType.ob_type = &PyType_Type;
557
if (PyType_Ready(&mxdatetimeType) == -1) return;
558
if (mxDateTime_ImportModuleAndAPI() != 0) {
559
Dprintf("initpsycopg: why marc hide mx.DateTime again?!");
560
PyErr_SetString(PyExc_ImportError, "can't import mx.DateTime module");
563
mxDateTimeP = &mxDateTime;
566
/* import python builtin datetime module, if available */
567
#ifdef HAVE_PYDATETIME
568
pyDateTimeModuleP = PyImport_ImportModule("datetime");
569
if (pyDateTimeModuleP == NULL) {
570
Dprintf("initpsycopg: can't import datetime module");
571
PyErr_SetString(PyExc_ImportError, "can't import datetime module");
574
pydatetimeType.ob_type = &PyType_Type;
575
if (PyType_Ready(&pydatetimeType) == -1) return;
577
/* now we define the datetime types, this is crazy because python should
578
be doing that, not us! */
579
pyDateTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "date");
580
pyTimeTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "time");
581
pyDateTimeTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "datetime");
582
pyDeltaTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "timedelta");
585
/* import psycopg2.tz anyway (TODO: replace with C-level module?) */
586
pyPsycopgTzModule = PyImport_ImportModule("psycopg2.tz");
587
if (pyPsycopgTzModule == NULL) {
588
Dprintf("initpsycopg: can't import psycopg2.tz module");
589
PyErr_SetString(PyExc_ImportError, "can't import psycopg2.tz module");
593
PyObject_GetAttrString(pyPsycopgTzModule, "LOCAL");
594
pyPsycopgTzFixedOffsetTimezone =
595
PyObject_GetAttrString(pyPsycopgTzModule, "FixedOffsetTimezone");
597
/* initialize the module and grab module's dictionary */
598
module = Py_InitModule("_psycopg", psycopgMethods);
599
dict = PyModule_GetDict(module);
601
/* initialize all the module's exported functions */
602
/* PyBoxer_API[PyBoxer_Fake_NUM] = (void *)PyBoxer_Fake; */
604
/* Create a CObject containing the API pointer array's address */
605
c_api_object = PyCObject_FromVoidPtr((void *)PSYCOPG_API, NULL);
606
if (c_api_object != NULL)
607
PyModule_AddObject(module, "_C_API", c_api_object);
609
/* other mixed initializations of module-level variables */
610
psycoEncodings = PyDict_New();
611
psyco_encodings_fill(psycoEncodings);
612
psyco_decimal_init();
614
/* set some module's parameters */
615
PyModule_AddStringConstant(module, "__version__", PSYCOPG_VERSION);
616
PyModule_AddStringConstant(module, "__doc__", "psycopg PostgreSQL driver");
617
PyModule_AddObject(module, "apilevel", PyString_FromString(APILEVEL));
618
PyModule_AddObject(module, "threadsafety", PyInt_FromLong(THREADSAFETY));
619
PyModule_AddObject(module, "paramstyle", PyString_FromString(PARAMSTYLE));
621
/* put new types in module dictionary */
622
PyModule_AddObject(module, "connection", (PyObject*)&connectionType);
623
PyModule_AddObject(module, "cursor", (PyObject*)&cursorType);
624
PyModule_AddObject(module, "ISQLQuote", (PyObject*)&isqlquoteType);
626
/* encodings dictionary in module dictionary */
627
PyModule_AddObject(module, "encodings", psycoEncodings);
629
/* initialize default set of typecasters */
632
/* initialize microprotocols layer */
633
microprotocols_init(dict);
634
psyco_adapters_init(dict);
636
/* create a standard set of exceptions and add them to the module's dict */
638
psyco_errors_fill(dict);
640
/* Solve win32 build issue about non-constant initializer element */
641
cursorType.tp_alloc = PyType_GenericAlloc;
642
binaryType.tp_alloc = PyType_GenericAlloc;
643
isqlquoteType.tp_alloc = PyType_GenericAlloc;
644
pbooleanType.tp_alloc = PyType_GenericAlloc;
645
connectionType.tp_alloc = PyType_GenericAlloc;
646
asisType.tp_alloc = PyType_GenericAlloc;
647
qstringType.tp_alloc = PyType_GenericAlloc;
648
listType.tp_alloc = PyType_GenericAlloc;
649
chunkType.tp_alloc = PyType_GenericAlloc;
651
#ifdef HAVE_PYDATETIME
652
pydatetimeType.tp_alloc = PyType_GenericAlloc;
655
Dprintf("initpsycopg: module initialization complete");