Skip to content

Commit 65a2a18

Browse files
committed
General cleanup of module init shenanigans
Pass around the module instead of its dict (getting the latter is fast if needed), mark function raising with negative results, check all errors, consistent names...
1 parent 66d5c6d commit 65a2a18

File tree

4 files changed

+90
-80
lines changed

4 files changed

+90
-80
lines changed

psycopg/microprotocols.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,19 @@ PyObject *psyco_adapters;
3838

3939
/* microprotocols_init - initialize the adapters dictionary */
4040

41-
int
42-
microprotocols_init(PyObject *dict)
41+
RAISES_NEG int
42+
microprotocols_init(PyObject *module)
4343
{
4444
/* create adapters dictionary and put it in module namespace */
45-
if ((psyco_adapters = PyDict_New()) == NULL) {
45+
if (!(psyco_adapters = PyDict_New())) {
4646
return -1;
4747
}
4848

49-
PyDict_SetItemString(dict, "adapters", psyco_adapters);
49+
Py_INCREF(psyco_adapters);
50+
if (0 > PyModule_AddObject(module, "adapters", psyco_adapters)) {
51+
Py_DECREF(psyco_adapters);
52+
return -1;
53+
}
5054

5155
return 0;
5256
}
@@ -56,7 +60,7 @@ microprotocols_init(PyObject *dict)
5660
*
5761
* Return 0 on success, else -1 and set an exception.
5862
*/
59-
int
63+
RAISES_NEG int
6064
microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
6165
{
6266
PyObject *key = NULL;

psycopg/microprotocols.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ extern HIDDEN PyObject *psyco_adapters;
4646
/** exported functions **/
4747

4848
/* used by module.c to init the microprotocols system */
49-
HIDDEN int microprotocols_init(PyObject *dict);
50-
HIDDEN int microprotocols_add(
49+
HIDDEN RAISES_NEG int microprotocols_init(PyObject *dict);
50+
HIDDEN RAISES_NEG int microprotocols_add(
5151
PyTypeObject *type, PyObject *proto, PyObject *cast);
5252

5353
HIDDEN PyObject *microprotocols_adapt(

psycopg/psycopgmodule.c

Lines changed: 74 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -294,103 +294,115 @@ psyco_libcrypto_threads_init(void)
294294
* Return 0 on success, else -1 and set an exception.
295295
*/
296296
RAISES_NEG static int
297-
psyco_adapters_init(PyObject *mod)
297+
adapters_init(PyObject *module)
298298
{
299-
PyObject *call = NULL;
299+
PyObject *dict = NULL, *obj = NULL;
300300
int rv = -1;
301301

302+
if (0 > microprotocols_init(module)) { goto exit; }
303+
302304
Dprintf("psycopgmodule: configuring adapters");
303305

304-
if (0 != microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType)) {
306+
if (0 > microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType)) {
305307
goto exit;
306308
}
307309
#if PY_MAJOR_VERSION < 3
308-
if (0 != microprotocols_add(&PyInt_Type, NULL, (PyObject*)&pintType)) {
310+
if (0 > microprotocols_add(&PyInt_Type, NULL, (PyObject*)&pintType)) {
309311
goto exit;
310312
}
311313
#endif
312-
if (0 != microprotocols_add(&PyLong_Type, NULL, (PyObject*)&pintType)) {
314+
if (0 > microprotocols_add(&PyLong_Type, NULL, (PyObject*)&pintType)) {
313315
goto exit;
314316
}
315-
if (0 != microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType)) {
317+
if (0 > microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType)) {
316318
goto exit;
317319
}
318320

319321
/* strings */
320322
#if PY_MAJOR_VERSION < 3
321-
if (0 != microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType)) {
323+
if (0 > microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType)) {
322324
goto exit;
323325
}
324326
#endif
325-
if (0 != microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType)) {
327+
if (0 > microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType)) {
326328
goto exit;
327329
}
328330

329331
/* binary */
330332
#if PY_MAJOR_VERSION < 3
331-
if (0 != microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType)) {
333+
if (0 > microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType)) {
332334
goto exit;
333335
}
334336
#else
335-
if (0 != microprotocols_add(&PyBytes_Type, NULL, (PyObject*)&binaryType)) {
337+
if (0 > microprotocols_add(&PyBytes_Type, NULL, (PyObject*)&binaryType)) {
336338
goto exit;
337339
}
338340
#endif
339341

340342
#if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 6
341-
if (0 != microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType)) {
343+
if (0 > microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType)) {
342344
goto exit;
343345
}
344346
#endif
345347
#if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 7
346-
if (0 != microprotocols_add(&PyMemoryView_Type, NULL, (PyObject*)&binaryType)) {
348+
if (0 > microprotocols_add(&PyMemoryView_Type, NULL, (PyObject*)&binaryType)) {
347349
goto exit;
348350
}
349351
#endif
350352

351-
if (0 != microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType)) {
353+
if (0 > microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType)) {
352354
goto exit;
353355
}
354356

355357
/* the module has already been initialized, so we can obtain the callable
356358
objects directly from its dictionary :) */
357-
if (!(call = PyMapping_GetItemString(mod, "DateFromPy"))) { goto exit; }
358-
if (0 != microprotocols_add(PyDateTimeAPI->DateType, NULL, call)) { goto exit; }
359-
Py_CLEAR(call);
359+
if (!(dict = PyModule_GetDict(module))) { goto exit; }
360+
361+
if (!(obj = PyMapping_GetItemString(dict, "DateFromPy"))) { goto exit; }
362+
if (0 > microprotocols_add(PyDateTimeAPI->DateType, NULL, obj)) { goto exit; }
363+
Py_CLEAR(obj);
360364

361-
if (!(call = PyMapping_GetItemString(mod, "TimeFromPy"))) { goto exit; }
362-
if (0 != microprotocols_add(PyDateTimeAPI->TimeType, NULL, call)) { goto exit; }
363-
Py_CLEAR(call);
365+
if (!(obj = PyMapping_GetItemString(dict, "TimeFromPy"))) { goto exit; }
366+
if (0 > microprotocols_add(PyDateTimeAPI->TimeType, NULL, obj)) { goto exit; }
367+
Py_CLEAR(obj);
364368

365-
if (!(call = PyMapping_GetItemString(mod, "TimestampFromPy"))) { goto exit; }
366-
if (0 != microprotocols_add(PyDateTimeAPI->DateTimeType, NULL, call)) { goto exit; }
367-
Py_CLEAR(call);
369+
if (!(obj = PyMapping_GetItemString(dict, "TimestampFromPy"))) { goto exit; }
370+
if (0 > microprotocols_add(PyDateTimeAPI->DateTimeType, NULL, obj)) { goto exit; }
371+
Py_CLEAR(obj);
368372

369-
if (!(call = PyMapping_GetItemString(mod, "IntervalFromPy"))) { goto exit; }
370-
if (0 != microprotocols_add(PyDateTimeAPI->DeltaType, NULL, call)) { goto exit; }
371-
Py_CLEAR(call);
373+
if (!(obj = PyMapping_GetItemString(dict, "IntervalFromPy"))) { goto exit; }
374+
if (0 > microprotocols_add(PyDateTimeAPI->DeltaType, NULL, obj)) { goto exit; }
375+
Py_CLEAR(obj);
372376

373377
#ifdef HAVE_MXDATETIME
374-
/* as above, we use the callable objects from the psycopg module */
375-
if (NULL != (call = PyMapping_GetItemString(mod, "TimestampFromMx"))) {
376-
if (0 != microprotocols_add(mxDateTime.DateTime_Type, NULL, call)) { goto exit; }
377-
Py_CLEAR(call);
378+
/* As above, we use the callable objects from the psycopg module.
379+
These object are not be available at runtime if mx.DateTime import
380+
failed (e.g. it was available at build time but not at runtime). */
381+
if (PyMapping_HasKeyString(dict, "TimestampFromMx")) {
382+
if (!(obj = PyMapping_GetItemString(dict, "TimestampFromMx"))) {
383+
goto exit;
384+
}
385+
if (0 > microprotocols_add(mxDateTime.DateTime_Type, NULL, obj)) {
386+
goto exit;
387+
}
388+
Py_CLEAR(obj);
378389

379390
/* if we found the above, we have this too. */
380-
if (!(call = PyMapping_GetItemString(mod, "TimeFromMx"))) { goto exit; }
381-
if (0 != microprotocols_add(mxDateTime.DateTimeDelta_Type, NULL, call)) { goto exit; }
382-
Py_CLEAR(call);
383-
}
384-
else {
385-
PyErr_Clear();
391+
if (!(obj = PyMapping_GetItemString(dict, "TimeFromMx"))) {
392+
goto exit;
393+
}
394+
if (0 > microprotocols_add(mxDateTime.DateTimeDelta_Type, NULL, obj)) {
395+
goto exit;
396+
}
397+
Py_CLEAR(obj);
386398
}
387399
#endif
388400

389401
/* Success! */
390402
rv = 0;
391403

392404
exit:
393-
Py_XDECREF(call);
405+
Py_XDECREF(obj);
394406

395407
return rv;
396408
}
@@ -599,7 +611,10 @@ encodings_init(PyObject *module)
599611

600612
if (!(psycoEncodings = PyDict_New())) { goto exit; }
601613
Py_INCREF(psycoEncodings);
602-
PyModule_AddObject(module, "encodings", psycoEncodings);
614+
if (0 > PyModule_AddObject(module, "encodings", psycoEncodings)) {
615+
Py_DECREF(psycoEncodings);
616+
goto exit;
617+
}
603618

604619
for (i = 0; enctable[i].pgenc != NULL; i++) {
605620
if (!(value = Text_FromUTF8(enctable[i].pyenc))) { goto exit; }
@@ -655,8 +670,8 @@ static struct {
655670
};
656671

657672

658-
static int
659-
psyco_errors_init(PyObject *module)
673+
RAISES_NEG static int
674+
errors_init(PyObject *module)
660675
{
661676
/* the names of the exceptions here reflect the organization of the
662677
psycopg2 module and not the fact the the original error objects
@@ -702,6 +717,7 @@ psyco_errors_init(PyObject *module)
702717

703718
Py_INCREF(*exctable[i].exc);
704719
if (0 > PyModule_AddObject(module, name, *exctable[i].exc)) {
720+
Py_DECREF(*exctable[i].exc);
705721
goto exit;
706722
}
707723
}
@@ -715,8 +731,7 @@ psyco_errors_init(PyObject *module)
715731
}
716732

717733

718-
RAISES_NEG
719-
static int
734+
RAISES_NEG static int
720735
add_module_constants(PyObject *module)
721736
{
722737
PyObject *tmp;
@@ -789,8 +804,7 @@ static struct {
789804
{NULL} /* Sentinel */
790805
};
791806

792-
RAISES_NEG
793-
static int
807+
RAISES_NEG static int
794808
add_module_types(PyObject *module)
795809
{
796810
int i;
@@ -805,6 +819,7 @@ add_module_types(PyObject *module)
805819

806820
Py_INCREF(type);
807821
if (0 > PyModule_AddObject(module, typetable[i].name, type)) {
822+
Py_DECREF(type);
808823
return -1;
809824
}
810825
}
@@ -832,7 +847,7 @@ datetime_init(void)
832847
if (0 > psyco_replmsg_datetime_init()) { return -1; }
833848

834849
Py_TYPE(&pydatetimeType) = &PyType_Type;
835-
if (PyType_Ready(&pydatetimeType) == -1) { return -1; }
850+
if (0 > PyType_Ready(&pydatetimeType)) { return -1; }
836851

837852
return 0;
838853
}
@@ -844,7 +859,7 @@ mxdatetime_init(PyObject *module)
844859

845860
#ifdef HAVE_MXDATETIME
846861
Py_TYPE(&mxdatetimeType) = &PyType_Type;
847-
if (PyType_Ready(&mxdatetimeType) == -1) { return -1; }
862+
if (0 > PyType_Ready(&mxdatetimeType)) { return -1; }
848863

849864
if (mxDateTime_ImportModuleAndAPI()) {
850865
Dprintf("psycopgmodule: mx.DateTime module import failed");
@@ -862,7 +877,7 @@ mxdatetime_init(PyObject *module)
862877
* remove them from the module (and, as consequence, from the adapters). */
863878
if (0 != psyco_adapter_mxdatetime_init()) {
864879
PyObject *dict;
865-
dict = PyModule_GetDict(module);
880+
if (!(dict = PyModule_GetDict(module))) { return -1; }
866881
if (0 > PyDict_DelItemString(dict, "DateFromMx")) { return -1; }
867882
if (0 > PyDict_DelItemString(dict, "TimeFromMx")) { return -1; }
868883
if (0 > PyDict_DelItemString(dict, "TimestampFromMx")) { return -1; }
@@ -957,7 +972,7 @@ static struct PyModuleDef psycopgmodule = {
957972
PyMODINIT_FUNC
958973
INIT_MODULE(_psycopg)(void)
959974
{
960-
PyObject *module = NULL, *dict;
975+
PyObject *module = NULL;
961976

962977
#ifdef PSYCOPG_DEBUG
963978
if (getenv("PSYCOPG_DEBUG"))
@@ -966,50 +981,38 @@ INIT_MODULE(_psycopg)(void)
966981

967982
Dprintf("psycopgmodule: initializing psycopg %s", xstr(PSYCOPG_VERSION));
968983

969-
/* initialize the types not exposed to the module */
984+
/* initialize libcrypto threading callbacks */
985+
psyco_libcrypto_threads_init();
986+
987+
/* initialize types and objects not exposed to the module */
970988
Py_TYPE(&typecastType) = &PyType_Type;
971-
if (PyType_Ready(&typecastType) == -1) goto exit;
989+
if (0 > PyType_Ready(&typecastType)) { goto exit; }
972990

973991
Py_TYPE(&chunkType) = &PyType_Type;
974-
if (PyType_Ready(&chunkType) == -1) goto exit;
992+
if (0 > PyType_Ready(&chunkType)) { goto exit; }
975993

976994
Py_TYPE(&errorType) = &PyType_Type;
977995
errorType.tp_base = (PyTypeObject *)PyExc_StandardError;
978-
if (PyType_Ready(&errorType) == -1) goto exit;
996+
if (0 > PyType_Ready(&errorType)) { goto exit; }
979997

980-
/* initialize libcrypto threading callbacks */
981-
psyco_libcrypto_threads_init();
998+
if (!(psyco_null = Bytes_FromString("NULL"))) { goto exit; }
982999

983-
/* initialize the module and grab module's dictionary */
1000+
/* initialize the module */
9841001
#if PY_MAJOR_VERSION < 3
9851002
module = Py_InitModule("_psycopg", psycopgMethods);
9861003
#else
9871004
module = PyModule_Create(&psycopgmodule);
9881005
#endif
9891006
if (!module) { goto exit; }
9901007

991-
/* other mixed initializations of module-level variables */
992-
if (!(psyco_null = Bytes_FromString("NULL"))) { goto exit; }
993-
9941008
if (0 > add_module_constants(module)) { goto exit; }
9951009
if (0 > add_module_types(module)) { goto exit; }
9961010
if (0 > datetime_init()) { goto exit; }
9971011
if (0 > mxdatetime_init(module)) { goto exit; }
998-
999-
/* encodings dictionary in module dictionary */
10001012
if (0 > encodings_init(module)) { goto exit; }
1001-
1002-
dict = PyModule_GetDict(module);
1003-
1004-
/* initialize default set of typecasters */
1005-
if (0 != typecast_init(dict)) { goto exit; }
1006-
1007-
/* initialize microprotocols layer */
1008-
microprotocols_init(dict);
1009-
if (0 != psyco_adapters_init(dict)) { goto exit; }
1010-
1011-
/* create a standard set of exceptions and add them to the module's dict */
1012-
if (0 != psyco_errors_init(module)) { goto exit; }
1013+
if (0 > typecast_init(module)) { goto exit; }
1014+
if (0 > adapters_init(module)) { goto exit; }
1015+
if (0 > errors_init(module)) { goto exit; }
10131016

10141017
Dprintf("psycopgmodule: module initialization complete");
10151018

psycopg/typecast.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,14 @@ PyObject *psyco_default_binary_cast;
252252
/* typecast_init - initialize the dictionary and create default types */
253253

254254
RAISES_NEG int
255-
typecast_init(PyObject *dict)
255+
typecast_init(PyObject *module)
256256
{
257257
int i;
258258
int rv = -1;
259259
typecastObject *t = NULL;
260+
PyObject *dict = NULL;
261+
262+
if (!(dict = PyModule_GetDict(module))) { goto exit; }
260263

261264
/* create type dictionary and put it in module namespace */
262265
if (!(psyco_types = PyDict_New())) { goto exit; }
@@ -285,7 +288,7 @@ typecast_init(PyObject *dict)
285288
t = NULL;
286289
}
287290

288-
/* create and save a default cast object (but does not register it) */
291+
/* create and save a default cast object (but do not register it) */
289292
psyco_default_cast = typecast_from_c(&typecast_default, dict);
290293

291294
/* register the date/time typecasters with their original names */

0 commit comments

Comments
 (0)