1 | /* module.c - the module itself
|
---|
2 | *
|
---|
3 | * Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
---|
4 | *
|
---|
5 | * This file is part of pysqlite.
|
---|
6 | *
|
---|
7 | * This software is provided 'as-is', without any express or implied
|
---|
8 | * warranty. In no event will the authors be held liable for any damages
|
---|
9 | * arising from the use of this software.
|
---|
10 | *
|
---|
11 | * Permission is granted to anyone to use this software for any purpose,
|
---|
12 | * including commercial applications, and to alter it and redistribute it
|
---|
13 | * freely, subject to the following restrictions:
|
---|
14 | *
|
---|
15 | * 1. The origin of this software must not be misrepresented; you must not
|
---|
16 | * claim that you wrote the original software. If you use this software
|
---|
17 | * in a product, an acknowledgment in the product documentation would be
|
---|
18 | * appreciated but is not required.
|
---|
19 | * 2. Altered source versions must be plainly marked as such, and must not be
|
---|
20 | * misrepresented as being the original software.
|
---|
21 | * 3. This notice may not be removed or altered from any source distribution.
|
---|
22 | */
|
---|
23 |
|
---|
24 | #include "connection.h"
|
---|
25 | #include "statement.h"
|
---|
26 | #include "cursor.h"
|
---|
27 | #include "cache.h"
|
---|
28 | #include "prepare_protocol.h"
|
---|
29 | #include "microprotocols.h"
|
---|
30 | #include "row.h"
|
---|
31 |
|
---|
32 | #if SQLITE_VERSION_NUMBER >= 3003003
|
---|
33 | #define HAVE_SHARED_CACHE
|
---|
34 | #endif
|
---|
35 |
|
---|
36 | /* static objects at module-level */
|
---|
37 |
|
---|
38 | PyObject* pysqlite_Error, *pysqlite_Warning, *pysqlite_InterfaceError, *pysqlite_DatabaseError,
|
---|
39 | *pysqlite_InternalError, *pysqlite_OperationalError, *pysqlite_ProgrammingError,
|
---|
40 | *pysqlite_IntegrityError, *pysqlite_DataError, *pysqlite_NotSupportedError, *pysqlite_OptimizedUnicode;
|
---|
41 |
|
---|
42 | PyObject* converters;
|
---|
43 | int _enable_callback_tracebacks;
|
---|
44 | int pysqlite_BaseTypeAdapted;
|
---|
45 |
|
---|
46 | static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
|
---|
47 | kwargs)
|
---|
48 | {
|
---|
49 | /* Python seems to have no way of extracting a single keyword-arg at
|
---|
50 | * C-level, so this code is redundant with the one in connection_init in
|
---|
51 | * connection.c and must always be copied from there ... */
|
---|
52 |
|
---|
53 | static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
|
---|
54 | PyObject* database;
|
---|
55 | int detect_types = 0;
|
---|
56 | PyObject* isolation_level;
|
---|
57 | PyObject* factory = NULL;
|
---|
58 | int check_same_thread = 1;
|
---|
59 | int cached_statements;
|
---|
60 | double timeout = 5.0;
|
---|
61 |
|
---|
62 | PyObject* result;
|
---|
63 |
|
---|
64 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOi", kwlist,
|
---|
65 | &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
|
---|
66 | {
|
---|
67 | return NULL;
|
---|
68 | }
|
---|
69 |
|
---|
70 | if (factory == NULL) {
|
---|
71 | factory = (PyObject*)&pysqlite_ConnectionType;
|
---|
72 | }
|
---|
73 |
|
---|
74 | result = PyObject_Call(factory, args, kwargs);
|
---|
75 |
|
---|
76 | return result;
|
---|
77 | }
|
---|
78 |
|
---|
79 | PyDoc_STRVAR(module_connect_doc,
|
---|
80 | "connect(database[, timeout, isolation_level, detect_types, factory])\n\
|
---|
81 | \n\
|
---|
82 | Opens a connection to the SQLite database file *database*. You can use\n\
|
---|
83 | \":memory:\" to open a database connection to a database that resides in\n\
|
---|
84 | RAM instead of on disk.");
|
---|
85 |
|
---|
86 | static PyObject* module_complete(PyObject* self, PyObject* args, PyObject*
|
---|
87 | kwargs)
|
---|
88 | {
|
---|
89 | static char *kwlist[] = {"statement", NULL, NULL};
|
---|
90 | char* statement;
|
---|
91 |
|
---|
92 | PyObject* result;
|
---|
93 |
|
---|
94 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement))
|
---|
95 | {
|
---|
96 | return NULL;
|
---|
97 | }
|
---|
98 |
|
---|
99 | if (sqlite3_complete(statement)) {
|
---|
100 | result = Py_True;
|
---|
101 | } else {
|
---|
102 | result = Py_False;
|
---|
103 | }
|
---|
104 |
|
---|
105 | Py_INCREF(result);
|
---|
106 |
|
---|
107 | return result;
|
---|
108 | }
|
---|
109 |
|
---|
110 | PyDoc_STRVAR(module_complete_doc,
|
---|
111 | "complete_statement(sql)\n\
|
---|
112 | \n\
|
---|
113 | Checks if a string contains a complete SQL statement. Non-standard.");
|
---|
114 |
|
---|
115 | #ifdef HAVE_SHARED_CACHE
|
---|
116 | static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject*
|
---|
117 | kwargs)
|
---|
118 | {
|
---|
119 | static char *kwlist[] = {"do_enable", NULL, NULL};
|
---|
120 | int do_enable;
|
---|
121 | int rc;
|
---|
122 |
|
---|
123 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable))
|
---|
124 | {
|
---|
125 | return NULL;
|
---|
126 | }
|
---|
127 |
|
---|
128 | rc = sqlite3_enable_shared_cache(do_enable);
|
---|
129 |
|
---|
130 | if (rc != SQLITE_OK) {
|
---|
131 | PyErr_SetString(pysqlite_OperationalError, "Changing the shared_cache flag failed");
|
---|
132 | return NULL;
|
---|
133 | } else {
|
---|
134 | Py_INCREF(Py_None);
|
---|
135 | return Py_None;
|
---|
136 | }
|
---|
137 | }
|
---|
138 |
|
---|
139 | PyDoc_STRVAR(module_enable_shared_cache_doc,
|
---|
140 | "enable_shared_cache(do_enable)\n\
|
---|
141 | \n\
|
---|
142 | Enable or disable shared cache mode for the calling thread.\n\
|
---|
143 | Experimental/Non-standard.");
|
---|
144 | #endif /* HAVE_SHARED_CACHE */
|
---|
145 |
|
---|
146 | static PyObject* module_register_adapter(PyObject* self, PyObject* args)
|
---|
147 | {
|
---|
148 | PyTypeObject* type;
|
---|
149 | PyObject* caster;
|
---|
150 | int rc;
|
---|
151 |
|
---|
152 | if (!PyArg_ParseTuple(args, "OO", &type, &caster)) {
|
---|
153 | return NULL;
|
---|
154 | }
|
---|
155 |
|
---|
156 | /* a basic type is adapted; there's a performance optimization if that's not the case
|
---|
157 | * (99 % of all usages) */
|
---|
158 | if (type == &PyInt_Type || type == &PyLong_Type || type == &PyFloat_Type
|
---|
159 | || type == &PyString_Type || type == &PyUnicode_Type || type == &PyBuffer_Type) {
|
---|
160 | pysqlite_BaseTypeAdapted = 1;
|
---|
161 | }
|
---|
162 |
|
---|
163 | rc = pysqlite_microprotocols_add(type, (PyObject*)&pysqlite_PrepareProtocolType, caster);
|
---|
164 | if (rc == -1)
|
---|
165 | return NULL;
|
---|
166 |
|
---|
167 | Py_INCREF(Py_None);
|
---|
168 | return Py_None;
|
---|
169 | }
|
---|
170 |
|
---|
171 | PyDoc_STRVAR(module_register_adapter_doc,
|
---|
172 | "register_adapter(type, callable)\n\
|
---|
173 | \n\
|
---|
174 | Registers an adapter with pysqlite's adapter registry. Non-standard.");
|
---|
175 |
|
---|
176 | static PyObject* module_register_converter(PyObject* self, PyObject* args)
|
---|
177 | {
|
---|
178 | PyObject* orig_name;
|
---|
179 | PyObject* name = NULL;
|
---|
180 | PyObject* callable;
|
---|
181 | PyObject* retval = NULL;
|
---|
182 |
|
---|
183 | if (!PyArg_ParseTuple(args, "SO", &orig_name, &callable)) {
|
---|
184 | return NULL;
|
---|
185 | }
|
---|
186 |
|
---|
187 | /* convert the name to upper case */
|
---|
188 | name = PyObject_CallMethod(orig_name, "upper", "");
|
---|
189 | if (!name) {
|
---|
190 | goto error;
|
---|
191 | }
|
---|
192 |
|
---|
193 | if (PyDict_SetItem(converters, name, callable) != 0) {
|
---|
194 | goto error;
|
---|
195 | }
|
---|
196 |
|
---|
197 | Py_INCREF(Py_None);
|
---|
198 | retval = Py_None;
|
---|
199 | error:
|
---|
200 | Py_XDECREF(name);
|
---|
201 | return retval;
|
---|
202 | }
|
---|
203 |
|
---|
204 | PyDoc_STRVAR(module_register_converter_doc,
|
---|
205 | "register_converter(typename, callable)\n\
|
---|
206 | \n\
|
---|
207 | Registers a converter with pysqlite. Non-standard.");
|
---|
208 |
|
---|
209 | static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args)
|
---|
210 | {
|
---|
211 | if (!PyArg_ParseTuple(args, "i", &_enable_callback_tracebacks)) {
|
---|
212 | return NULL;
|
---|
213 | }
|
---|
214 |
|
---|
215 | Py_INCREF(Py_None);
|
---|
216 | return Py_None;
|
---|
217 | }
|
---|
218 |
|
---|
219 | PyDoc_STRVAR(enable_callback_tracebacks_doc,
|
---|
220 | "enable_callback_tracebacks(flag)\n\
|
---|
221 | \n\
|
---|
222 | Enable or disable callback functions throwing errors to stderr.");
|
---|
223 |
|
---|
224 | static void converters_init(PyObject* dict)
|
---|
225 | {
|
---|
226 | converters = PyDict_New();
|
---|
227 | if (!converters) {
|
---|
228 | return;
|
---|
229 | }
|
---|
230 |
|
---|
231 | PyDict_SetItemString(dict, "converters", converters);
|
---|
232 | }
|
---|
233 |
|
---|
234 | static PyMethodDef module_methods[] = {
|
---|
235 | {"connect", (PyCFunction)module_connect,
|
---|
236 | METH_VARARGS | METH_KEYWORDS, module_connect_doc},
|
---|
237 | {"complete_statement", (PyCFunction)module_complete,
|
---|
238 | METH_VARARGS | METH_KEYWORDS, module_complete_doc},
|
---|
239 | #ifdef HAVE_SHARED_CACHE
|
---|
240 | {"enable_shared_cache", (PyCFunction)module_enable_shared_cache,
|
---|
241 | METH_VARARGS | METH_KEYWORDS, module_enable_shared_cache_doc},
|
---|
242 | #endif
|
---|
243 | {"register_adapter", (PyCFunction)module_register_adapter,
|
---|
244 | METH_VARARGS, module_register_adapter_doc},
|
---|
245 | {"register_converter", (PyCFunction)module_register_converter,
|
---|
246 | METH_VARARGS, module_register_converter_doc},
|
---|
247 | {"adapt", (PyCFunction)pysqlite_adapt, METH_VARARGS,
|
---|
248 | pysqlite_adapt_doc},
|
---|
249 | {"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks,
|
---|
250 | METH_VARARGS, enable_callback_tracebacks_doc},
|
---|
251 | {NULL, NULL}
|
---|
252 | };
|
---|
253 |
|
---|
254 | struct _IntConstantPair {
|
---|
255 | char* constant_name;
|
---|
256 | int constant_value;
|
---|
257 | };
|
---|
258 |
|
---|
259 | typedef struct _IntConstantPair IntConstantPair;
|
---|
260 |
|
---|
261 | static IntConstantPair _int_constants[] = {
|
---|
262 | {"PARSE_DECLTYPES", PARSE_DECLTYPES},
|
---|
263 | {"PARSE_COLNAMES", PARSE_COLNAMES},
|
---|
264 |
|
---|
265 | {"SQLITE_OK", SQLITE_OK},
|
---|
266 | {"SQLITE_DENY", SQLITE_DENY},
|
---|
267 | {"SQLITE_IGNORE", SQLITE_IGNORE},
|
---|
268 | {"SQLITE_CREATE_INDEX", SQLITE_CREATE_INDEX},
|
---|
269 | {"SQLITE_CREATE_TABLE", SQLITE_CREATE_TABLE},
|
---|
270 | {"SQLITE_CREATE_TEMP_INDEX", SQLITE_CREATE_TEMP_INDEX},
|
---|
271 | {"SQLITE_CREATE_TEMP_TABLE", SQLITE_CREATE_TEMP_TABLE},
|
---|
272 | {"SQLITE_CREATE_TEMP_TRIGGER", SQLITE_CREATE_TEMP_TRIGGER},
|
---|
273 | {"SQLITE_CREATE_TEMP_VIEW", SQLITE_CREATE_TEMP_VIEW},
|
---|
274 | {"SQLITE_CREATE_TRIGGER", SQLITE_CREATE_TRIGGER},
|
---|
275 | {"SQLITE_CREATE_VIEW", SQLITE_CREATE_VIEW},
|
---|
276 | {"SQLITE_DELETE", SQLITE_DELETE},
|
---|
277 | {"SQLITE_DROP_INDEX", SQLITE_DROP_INDEX},
|
---|
278 | {"SQLITE_DROP_TABLE", SQLITE_DROP_TABLE},
|
---|
279 | {"SQLITE_DROP_TEMP_INDEX", SQLITE_DROP_TEMP_INDEX},
|
---|
280 | {"SQLITE_DROP_TEMP_TABLE", SQLITE_DROP_TEMP_TABLE},
|
---|
281 | {"SQLITE_DROP_TEMP_TRIGGER", SQLITE_DROP_TEMP_TRIGGER},
|
---|
282 | {"SQLITE_DROP_TEMP_VIEW", SQLITE_DROP_TEMP_VIEW},
|
---|
283 | {"SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER},
|
---|
284 | {"SQLITE_DROP_VIEW", SQLITE_DROP_VIEW},
|
---|
285 | {"SQLITE_INSERT", SQLITE_INSERT},
|
---|
286 | {"SQLITE_PRAGMA", SQLITE_PRAGMA},
|
---|
287 | {"SQLITE_READ", SQLITE_READ},
|
---|
288 | {"SQLITE_SELECT", SQLITE_SELECT},
|
---|
289 | {"SQLITE_TRANSACTION", SQLITE_TRANSACTION},
|
---|
290 | {"SQLITE_UPDATE", SQLITE_UPDATE},
|
---|
291 | {"SQLITE_ATTACH", SQLITE_ATTACH},
|
---|
292 | {"SQLITE_DETACH", SQLITE_DETACH},
|
---|
293 | #if SQLITE_VERSION_NUMBER >= 3002001
|
---|
294 | {"SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE},
|
---|
295 | {"SQLITE_REINDEX", SQLITE_REINDEX},
|
---|
296 | #endif
|
---|
297 | #if SQLITE_VERSION_NUMBER >= 3003000
|
---|
298 | {"SQLITE_ANALYZE", SQLITE_ANALYZE},
|
---|
299 | #endif
|
---|
300 | {(char*)NULL, 0}
|
---|
301 | };
|
---|
302 |
|
---|
303 | PyMODINIT_FUNC init_sqlite3(void)
|
---|
304 | {
|
---|
305 | PyObject *module, *dict;
|
---|
306 | PyObject *tmp_obj;
|
---|
307 | int i;
|
---|
308 |
|
---|
309 | module = Py_InitModule("_sqlite3", module_methods);
|
---|
310 |
|
---|
311 | if (!module ||
|
---|
312 | (pysqlite_row_setup_types() < 0) ||
|
---|
313 | (pysqlite_cursor_setup_types() < 0) ||
|
---|
314 | (pysqlite_connection_setup_types() < 0) ||
|
---|
315 | (pysqlite_cache_setup_types() < 0) ||
|
---|
316 | (pysqlite_statement_setup_types() < 0) ||
|
---|
317 | (pysqlite_prepare_protocol_setup_types() < 0)
|
---|
318 | ) {
|
---|
319 | return;
|
---|
320 | }
|
---|
321 |
|
---|
322 | Py_INCREF(&pysqlite_ConnectionType);
|
---|
323 | PyModule_AddObject(module, "Connection", (PyObject*) &pysqlite_ConnectionType);
|
---|
324 | Py_INCREF(&pysqlite_CursorType);
|
---|
325 | PyModule_AddObject(module, "Cursor", (PyObject*) &pysqlite_CursorType);
|
---|
326 | Py_INCREF(&pysqlite_CacheType);
|
---|
327 | PyModule_AddObject(module, "Statement", (PyObject*)&pysqlite_StatementType);
|
---|
328 | Py_INCREF(&pysqlite_StatementType);
|
---|
329 | PyModule_AddObject(module, "Cache", (PyObject*) &pysqlite_CacheType);
|
---|
330 | Py_INCREF(&pysqlite_PrepareProtocolType);
|
---|
331 | PyModule_AddObject(module, "PrepareProtocol", (PyObject*) &pysqlite_PrepareProtocolType);
|
---|
332 | Py_INCREF(&pysqlite_RowType);
|
---|
333 | PyModule_AddObject(module, "Row", (PyObject*) &pysqlite_RowType);
|
---|
334 |
|
---|
335 | if (!(dict = PyModule_GetDict(module))) {
|
---|
336 | goto error;
|
---|
337 | }
|
---|
338 |
|
---|
339 | /*** Create DB-API Exception hierarchy */
|
---|
340 |
|
---|
341 | if (!(pysqlite_Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_StandardError, NULL))) {
|
---|
342 | goto error;
|
---|
343 | }
|
---|
344 | PyDict_SetItemString(dict, "Error", pysqlite_Error);
|
---|
345 |
|
---|
346 | if (!(pysqlite_Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_StandardError, NULL))) {
|
---|
347 | goto error;
|
---|
348 | }
|
---|
349 | PyDict_SetItemString(dict, "Warning", pysqlite_Warning);
|
---|
350 |
|
---|
351 | /* Error subclasses */
|
---|
352 |
|
---|
353 | if (!(pysqlite_InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", pysqlite_Error, NULL))) {
|
---|
354 | goto error;
|
---|
355 | }
|
---|
356 | PyDict_SetItemString(dict, "InterfaceError", pysqlite_InterfaceError);
|
---|
357 |
|
---|
358 | if (!(pysqlite_DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", pysqlite_Error, NULL))) {
|
---|
359 | goto error;
|
---|
360 | }
|
---|
361 | PyDict_SetItemString(dict, "DatabaseError", pysqlite_DatabaseError);
|
---|
362 |
|
---|
363 | /* pysqlite_DatabaseError subclasses */
|
---|
364 |
|
---|
365 | if (!(pysqlite_InternalError = PyErr_NewException(MODULE_NAME ".InternalError", pysqlite_DatabaseError, NULL))) {
|
---|
366 | goto error;
|
---|
367 | }
|
---|
368 | PyDict_SetItemString(dict, "InternalError", pysqlite_InternalError);
|
---|
369 |
|
---|
370 | if (!(pysqlite_OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", pysqlite_DatabaseError, NULL))) {
|
---|
371 | goto error;
|
---|
372 | }
|
---|
373 | PyDict_SetItemString(dict, "OperationalError", pysqlite_OperationalError);
|
---|
374 |
|
---|
375 | if (!(pysqlite_ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", pysqlite_DatabaseError, NULL))) {
|
---|
376 | goto error;
|
---|
377 | }
|
---|
378 | PyDict_SetItemString(dict, "ProgrammingError", pysqlite_ProgrammingError);
|
---|
379 |
|
---|
380 | if (!(pysqlite_IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", pysqlite_DatabaseError,NULL))) {
|
---|
381 | goto error;
|
---|
382 | }
|
---|
383 | PyDict_SetItemString(dict, "IntegrityError", pysqlite_IntegrityError);
|
---|
384 |
|
---|
385 | if (!(pysqlite_DataError = PyErr_NewException(MODULE_NAME ".DataError", pysqlite_DatabaseError, NULL))) {
|
---|
386 | goto error;
|
---|
387 | }
|
---|
388 | PyDict_SetItemString(dict, "DataError", pysqlite_DataError);
|
---|
389 |
|
---|
390 | if (!(pysqlite_NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", pysqlite_DatabaseError, NULL))) {
|
---|
391 | goto error;
|
---|
392 | }
|
---|
393 | PyDict_SetItemString(dict, "NotSupportedError", pysqlite_NotSupportedError);
|
---|
394 |
|
---|
395 | /* We just need "something" unique for pysqlite_OptimizedUnicode. It does not really
|
---|
396 | * need to be a string subclass. Just anything that can act as a special
|
---|
397 | * marker for us. So I pulled PyCell_Type out of my magic hat.
|
---|
398 | */
|
---|
399 | Py_INCREF((PyObject*)&PyCell_Type);
|
---|
400 | pysqlite_OptimizedUnicode = (PyObject*)&PyCell_Type;
|
---|
401 | PyDict_SetItemString(dict, "OptimizedUnicode", pysqlite_OptimizedUnicode);
|
---|
402 |
|
---|
403 | /* Set integer constants */
|
---|
404 | for (i = 0; _int_constants[i].constant_name != 0; i++) {
|
---|
405 | tmp_obj = PyInt_FromLong(_int_constants[i].constant_value);
|
---|
406 | if (!tmp_obj) {
|
---|
407 | goto error;
|
---|
408 | }
|
---|
409 | PyDict_SetItemString(dict, _int_constants[i].constant_name, tmp_obj);
|
---|
410 | Py_DECREF(tmp_obj);
|
---|
411 | }
|
---|
412 |
|
---|
413 | if (!(tmp_obj = PyString_FromString(PYSQLITE_VERSION))) {
|
---|
414 | goto error;
|
---|
415 | }
|
---|
416 | PyDict_SetItemString(dict, "version", tmp_obj);
|
---|
417 | Py_DECREF(tmp_obj);
|
---|
418 |
|
---|
419 | if (!(tmp_obj = PyString_FromString(sqlite3_libversion()))) {
|
---|
420 | goto error;
|
---|
421 | }
|
---|
422 | PyDict_SetItemString(dict, "sqlite_version", tmp_obj);
|
---|
423 | Py_DECREF(tmp_obj);
|
---|
424 |
|
---|
425 | /* initialize microprotocols layer */
|
---|
426 | pysqlite_microprotocols_init(dict);
|
---|
427 |
|
---|
428 | /* initialize the default converters */
|
---|
429 | converters_init(dict);
|
---|
430 |
|
---|
431 | _enable_callback_tracebacks = 0;
|
---|
432 |
|
---|
433 | pysqlite_BaseTypeAdapted = 0;
|
---|
434 |
|
---|
435 | /* Original comment from _bsddb.c in the Python core. This is also still
|
---|
436 | * needed nowadays for Python 2.3/2.4.
|
---|
437 | *
|
---|
438 | * PyEval_InitThreads is called here due to a quirk in python 1.5
|
---|
439 | * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
|
---|
440 | * The global interpreter lock is not initialized until the first
|
---|
441 | * thread is created using thread.start_new_thread() or fork() is
|
---|
442 | * called. that would cause the ALLOW_THREADS here to segfault due
|
---|
443 | * to a null pointer reference if no threads or child processes
|
---|
444 | * have been created. This works around that and is a no-op if
|
---|
445 | * threads have already been initialized.
|
---|
446 | * (see pybsddb-users mailing list post on 2002-08-07)
|
---|
447 | */
|
---|
448 | #ifdef WITH_THREAD
|
---|
449 | PyEval_InitThreads();
|
---|
450 | #endif
|
---|
451 |
|
---|
452 | error:
|
---|
453 | if (PyErr_Occurred())
|
---|
454 | {
|
---|
455 | PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed");
|
---|
456 | }
|
---|
457 | }
|
---|