diff options
author | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2019-01-23 14:17:07 +0000 |
---|---|---|
committer | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2019-01-23 14:17:07 +0000 |
commit | 00cb2636f51456766f94773437dde759e9df0974 (patch) | |
tree | 930c18cc7e3ff9540b66d51a7ae96746c0ff94fa | |
parent | 63040e5134486cdbb8fb831d53177ff4055daadd (diff) | |
parent | 65a2a18a1baee52da372c931230163fed407f81a (diff) | |
download | psycopg2-00cb2636f51456766f94773437dde759e9df0974.tar.gz |
Merge branch 'module-init-cleanup'
-rw-r--r-- | psycopg/adapter_datetime.c | 2 | ||||
-rw-r--r-- | psycopg/adapter_datetime.h | 2 | ||||
-rw-r--r-- | psycopg/microprotocols.c | 14 | ||||
-rw-r--r-- | psycopg/microprotocols.h | 4 | ||||
-rw-r--r-- | psycopg/psycopg.h | 57 | ||||
-rw-r--r-- | psycopg/psycopgmodule.c | 516 | ||||
-rw-r--r-- | psycopg/replication_cursor.h | 2 | ||||
-rw-r--r-- | psycopg/replication_message.h | 2 | ||||
-rw-r--r-- | psycopg/typecast.c | 8 |
9 files changed, 282 insertions, 325 deletions
diff --git a/psycopg/adapter_datetime.c b/psycopg/adapter_datetime.c index a78311e..b201ae2 100644 --- a/psycopg/adapter_datetime.c +++ b/psycopg/adapter_datetime.c @@ -35,7 +35,7 @@ #include <string.h> -int +RAISES_NEG int psyco_adapter_datetime_init(void) { Dprintf("psyco_adapter_datetime_init: datetime init"); diff --git a/psycopg/adapter_datetime.h b/psycopg/adapter_datetime.h index 09abd88..6cc7589 100644 --- a/psycopg/adapter_datetime.h +++ b/psycopg/adapter_datetime.h @@ -45,7 +45,7 @@ typedef struct { } pydatetimeObject; -HIDDEN int psyco_adapter_datetime_init(void); +RAISES_NEG HIDDEN int psyco_adapter_datetime_init(void); /* functions exported to psycopgmodule.c */ #ifdef PSYCOPG_DEFAULT_PYDATETIME diff --git a/psycopg/microprotocols.c b/psycopg/microprotocols.c index 0e74cee..1139519 100644 --- a/psycopg/microprotocols.c +++ b/psycopg/microprotocols.c @@ -38,15 +38,19 @@ PyObject *psyco_adapters; /* microprotocols_init - initialize the adapters dictionary */ -int -microprotocols_init(PyObject *dict) +RAISES_NEG int +microprotocols_init(PyObject *module) { /* create adapters dictionary and put it in module namespace */ - if ((psyco_adapters = PyDict_New()) == NULL) { + if (!(psyco_adapters = PyDict_New())) { return -1; } - PyDict_SetItemString(dict, "adapters", psyco_adapters); + Py_INCREF(psyco_adapters); + if (0 > PyModule_AddObject(module, "adapters", psyco_adapters)) { + Py_DECREF(psyco_adapters); + return -1; + } return 0; } @@ -56,7 +60,7 @@ microprotocols_init(PyObject *dict) * * Return 0 on success, else -1 and set an exception. */ -int +RAISES_NEG int microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) { PyObject *key = NULL; diff --git a/psycopg/microprotocols.h b/psycopg/microprotocols.h index df084c5..1c2340f 100644 --- a/psycopg/microprotocols.h +++ b/psycopg/microprotocols.h @@ -46,8 +46,8 @@ extern HIDDEN PyObject *psyco_adapters; /** exported functions **/ /* used by module.c to init the microprotocols system */ -HIDDEN int microprotocols_init(PyObject *dict); -HIDDEN int microprotocols_add( +HIDDEN RAISES_NEG int microprotocols_init(PyObject *dict); +HIDDEN RAISES_NEG int microprotocols_add( PyTypeObject *type, PyObject *proto, PyObject *cast); HIDDEN PyObject *microprotocols_adapt( diff --git a/psycopg/psycopg.h b/psycopg/psycopg.h index 7b623fa..365a57c 100644 --- a/psycopg/psycopg.h +++ b/psycopg/psycopg.h @@ -47,75 +47,18 @@ extern "C" { #define THREADSAFETY 2 #define PARAMSTYLE "pyformat" -/* C API functions */ -#define psyco_errors_fill_NUM 0 -#define psyco_errors_fill_RETURN void -#define psyco_errors_fill_PROTO (PyObject *dict) -#define psyco_errors_set_NUM 1 -#define psyco_errors_set_RETURN void -#define psyco_errors_set_PROTO (PyObject *type) - -/* Total number of C API pointers */ -#define PSYCOPG_API_pointers 2 - -#ifdef PSYCOPG_MODULE - - /** This section is used when compiling psycopgmodule.c & co. **/ -HIDDEN psyco_errors_fill_RETURN psyco_errors_fill psyco_errors_fill_PROTO; -HIDDEN psyco_errors_set_RETURN psyco_errors_set psyco_errors_set_PROTO; - /* global exceptions */ extern HIDDEN PyObject *Error, *Warning, *InterfaceError, *DatabaseError, *InternalError, *OperationalError, *ProgrammingError, *IntegrityError, *DataError, *NotSupportedError; extern HIDDEN PyObject *QueryCanceledError, *TransactionRollbackError; -/* python versions and compatibility stuff */ -#ifndef PyMODINIT_FUNC -#define PyMODINIT_FUNC void -#endif - -#else - /** This section is used in modules that use psycopg's C API **/ - -static void **PSYCOPG_API; - -#define psyco_errors_fill \ - (*(psyco_errors_fill_RETURN (*)psyco_errors_fill_PROTO) \ - PSYCOPG_API[psyco_errors_fill_NUM]) -#define psyco_errors_set \ - (*(psyco_errors_set_RETURN (*)psyco_errors_set_PROTO) \ - PSYCOPG_API[psyco_errors_set_NUM]) - -/* Return -1 and set exception on error, 0 on success. */ -static int -import_psycopg(void) -{ - PyObject *module = PyImport_ImportModule("psycopg"); - - if (module != NULL) { - PyObject *c_api_object = PyObject_GetAttrString(module, "_C_API"); - if (c_api_object == NULL) return -1; - if (PyCObject_Check(c_api_object)) - PSYCOPG_API = (void **)PyCObject_AsVoidPtr(c_api_object); - Py_DECREF(c_api_object); - } - return 0; -} - -#endif - /* postgresql<->python encoding map */ extern HIDDEN PyObject *psycoEncodings; /* SQL NULL */ extern HIDDEN PyObject *psyco_null; -typedef struct { - char *pgenc; - char *pyenc; -} encodingPair; - /* Exceptions docstrings */ #define Error_doc \ "Base class for error exceptions." diff --git a/psycopg/psycopgmodule.c b/psycopg/psycopgmodule.c index a372b89..8f9aa53 100644 --- a/psycopg/psycopgmodule.c +++ b/psycopg/psycopgmodule.c @@ -60,7 +60,6 @@ /* some module-level variables, like the datetime module */ #include <datetime.h> #include "psycopg/adapter_datetime.h" -HIDDEN PyObject *pyDateTimeModuleP = NULL; HIDDEN PyObject *psycoEncodings = NULL; #ifdef PSYCOPG_DEBUG @@ -274,6 +273,8 @@ psyco_libcrypto_threads_init(void) { PyObject *m; + Dprintf("psycopgmodule: configuring libpq libcrypto callbacks "); + /* importing the ssl module sets up Python's libcrypto callbacks */ if ((m = PyImport_ImportModule("ssl"))) { /* disable libcrypto setup in libpq, so it won't stomp on the callbacks @@ -292,94 +293,108 @@ psyco_libcrypto_threads_init(void) * * Return 0 on success, else -1 and set an exception. */ -static int -psyco_adapters_init(PyObject *mod) +RAISES_NEG static int +adapters_init(PyObject *module) { - PyObject *call = NULL; + PyObject *dict = NULL, *obj = NULL; int rv = -1; - if (0 != microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType)) { + if (0 > microprotocols_init(module)) { goto exit; } + + Dprintf("psycopgmodule: configuring adapters"); + + if (0 > microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType)) { goto exit; } #if PY_MAJOR_VERSION < 3 - if (0 != microprotocols_add(&PyInt_Type, NULL, (PyObject*)&pintType)) { + if (0 > microprotocols_add(&PyInt_Type, NULL, (PyObject*)&pintType)) { goto exit; } #endif - if (0 != microprotocols_add(&PyLong_Type, NULL, (PyObject*)&pintType)) { + if (0 > microprotocols_add(&PyLong_Type, NULL, (PyObject*)&pintType)) { goto exit; } - if (0 != microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType)) { + if (0 > microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType)) { goto exit; } /* strings */ #if PY_MAJOR_VERSION < 3 - if (0 != microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType)) { + if (0 > microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType)) { goto exit; } #endif - if (0 != microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType)) { + if (0 > microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType)) { goto exit; } /* binary */ #if PY_MAJOR_VERSION < 3 - if (0 != microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType)) { + if (0 > microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType)) { goto exit; } #else - if (0 != microprotocols_add(&PyBytes_Type, NULL, (PyObject*)&binaryType)) { + if (0 > microprotocols_add(&PyBytes_Type, NULL, (PyObject*)&binaryType)) { goto exit; } #endif #if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 6 - if (0 != microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType)) { + if (0 > microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType)) { goto exit; } #endif #if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 7 - if (0 != microprotocols_add(&PyMemoryView_Type, NULL, (PyObject*)&binaryType)) { + if (0 > microprotocols_add(&PyMemoryView_Type, NULL, (PyObject*)&binaryType)) { goto exit; } #endif - if (0 != microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType)) { + if (0 > microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType)) { goto exit; } /* the module has already been initialized, so we can obtain the callable objects directly from its dictionary :) */ - if (!(call = PyMapping_GetItemString(mod, "DateFromPy"))) { goto exit; } - if (0 != microprotocols_add(PyDateTimeAPI->DateType, NULL, call)) { goto exit; } - Py_CLEAR(call); + if (!(dict = PyModule_GetDict(module))) { goto exit; } - if (!(call = PyMapping_GetItemString(mod, "TimeFromPy"))) { goto exit; } - if (0 != microprotocols_add(PyDateTimeAPI->TimeType, NULL, call)) { goto exit; } - Py_CLEAR(call); + if (!(obj = PyMapping_GetItemString(dict, "DateFromPy"))) { goto exit; } + if (0 > microprotocols_add(PyDateTimeAPI->DateType, NULL, obj)) { goto exit; } + Py_CLEAR(obj); - if (!(call = PyMapping_GetItemString(mod, "TimestampFromPy"))) { goto exit; } - if (0 != microprotocols_add(PyDateTimeAPI->DateTimeType, NULL, call)) { goto exit; } - Py_CLEAR(call); + if (!(obj = PyMapping_GetItemString(dict, "TimeFromPy"))) { goto exit; } + if (0 > microprotocols_add(PyDateTimeAPI->TimeType, NULL, obj)) { goto exit; } + Py_CLEAR(obj); - if (!(call = PyMapping_GetItemString(mod, "IntervalFromPy"))) { goto exit; } - if (0 != microprotocols_add(PyDateTimeAPI->DeltaType, NULL, call)) { goto exit; } - Py_CLEAR(call); + if (!(obj = PyMapping_GetItemString(dict, "TimestampFromPy"))) { goto exit; } + if (0 > microprotocols_add(PyDateTimeAPI->DateTimeType, NULL, obj)) { goto exit; } + Py_CLEAR(obj); + + if (!(obj = PyMapping_GetItemString(dict, "IntervalFromPy"))) { goto exit; } + if (0 > microprotocols_add(PyDateTimeAPI->DeltaType, NULL, obj)) { goto exit; } + Py_CLEAR(obj); #ifdef HAVE_MXDATETIME - /* as above, we use the callable objects from the psycopg module */ - if (NULL != (call = PyMapping_GetItemString(mod, "TimestampFromMx"))) { - if (0 != microprotocols_add(mxDateTime.DateTime_Type, NULL, call)) { goto exit; } - Py_CLEAR(call); + /* As above, we use the callable objects from the psycopg module. + These object are not be available at runtime if mx.DateTime import + failed (e.g. it was available at build time but not at runtime). */ + if (PyMapping_HasKeyString(dict, "TimestampFromMx")) { + if (!(obj = PyMapping_GetItemString(dict, "TimestampFromMx"))) { + goto exit; + } + if (0 > microprotocols_add(mxDateTime.DateTime_Type, NULL, obj)) { + goto exit; + } + Py_CLEAR(obj); /* if we found the above, we have this too. */ - if (!(call = PyMapping_GetItemString(mod, "TimeFromMx"))) { goto exit; } - if (0 != microprotocols_add(mxDateTime.DateTimeDelta_Type, NULL, call)) { goto exit; } - Py_CLEAR(call); - } - else { - PyErr_Clear(); + if (!(obj = PyMapping_GetItemString(dict, "TimeFromMx"))) { + goto exit; + } + if (0 > microprotocols_add(mxDateTime.DateTimeDelta_Type, NULL, obj)) { + goto exit; + } + Py_CLEAR(obj); } #endif @@ -387,7 +402,7 @@ psyco_adapters_init(PyObject *mod) rv = 0; exit: - Py_XDECREF(call); + Py_XDECREF(obj); return rv; } @@ -499,11 +514,11 @@ exit: } -/* psyco_encodings_fill - - Fill the module's postgresql<->python encoding table */ - -static encodingPair encodings[] = { +/* Fill the module's postgresql<->python encoding table */ +static struct { + char *pgenc; + char *pyenc; +} enctable[] = { {"ABC", "cp1258"}, {"ALT", "cp866"}, {"BIG5", "big5"}, @@ -585,15 +600,28 @@ static encodingPair encodings[] = { * * Return 0 on success, else -1 and set an exception. */ -static int psyco_encodings_fill(PyObject *dict) +RAISES_NEG static int +encodings_init(PyObject *module) { PyObject *value = NULL; - encodingPair *enc; + int i; int rv = -1; - for (enc = encodings; enc->pgenc != NULL; enc++) { - if (!(value = Text_FromUTF8(enc->pyenc))) { goto exit; } - if (0 != PyDict_SetItemString(dict, enc->pgenc, value)) { goto exit; } + Dprintf("psycopgmodule: initializing encodings table"); + + if (!(psycoEncodings = PyDict_New())) { goto exit; } + Py_INCREF(psycoEncodings); + if (0 > PyModule_AddObject(module, "encodings", psycoEncodings)) { + Py_DECREF(psycoEncodings); + goto exit; + } + + for (i = 0; enctable[i].pgenc != NULL; i++) { + if (!(value = Text_FromUTF8(enctable[i].pyenc))) { goto exit; } + if (0 > PyDict_SetItemString( + psycoEncodings, enctable[i].pgenc, value)) { + goto exit; + } Py_CLEAR(value); } rv = 0; @@ -604,9 +632,7 @@ exit: return rv; } -/* psyco_errors_init, psyco_errors_fill (callable from C) - - Initialize the module's exceptions and after that a dictionary with a full +/* Initialize the module's exceptions and after that a dictionary with a full set of exceptions. */ PyObject *Error, *Warning, *InterfaceError, *DatabaseError, @@ -644,8 +670,8 @@ static struct { }; -static int -psyco_errors_init(void) +RAISES_NEG static int +errors_init(PyObject *module) { /* the names of the exceptions here reflect the organization of the psycopg2 module and not the fact the the original error objects @@ -656,6 +682,8 @@ psyco_errors_init(void) PyObject *str = NULL; int rv = -1; + Dprintf("psycopgmodule: initializing basic exceptions"); + /* 'Error' has been defined elsewhere: only init the other classes */ Error = (PyObject *)&errorType; @@ -664,7 +692,7 @@ psyco_errors_init(void) if (exctable[i].docstr) { if (!(str = Text_FromUTF8(exctable[i].docstr))) { goto exit; } - if (0 != PyDict_SetItemString(dict, "__doc__", str)) { goto exit; } + if (0 > PyDict_SetItemString(dict, "__doc__", str)) { goto exit; } Py_CLEAR(str); } @@ -679,6 +707,21 @@ psyco_errors_init(void) Py_CLEAR(dict); } + for (i = 0; exctable[i].name; i++) { + char *name; + if (NULL == exctable[i].exc) { continue; } + + /* the name is the part after the last dot */ + name = strrchr(exctable[i].name, '.'); + name = name ? name + 1 : exctable[i].name; + + Py_INCREF(*exctable[i].exc); + if (0 > PyModule_AddObject(module, name, *exctable[i].exc)) { + Py_DECREF(*exctable[i].exc); + goto exit; + } + } + rv = 0; exit: @@ -687,40 +730,162 @@ exit: return rv; } -void -psyco_errors_fill(PyObject *dict) -{ - int i; - char *name; - for (i = 0; exctable[i].name; i++) { - if (NULL == exctable[i].exc) { continue; } +RAISES_NEG static int +add_module_constants(PyObject *module) +{ + PyObject *tmp; + Dprintf("psycopgmodule: initializing module constants"); + + if (0 > PyModule_AddStringConstant(module, + "__version__", xstr(PSYCOPG_VERSION))) + { return -1; } + + if (0 > PyModule_AddStringConstant(module, + "__doc__", "psycopg2 PostgreSQL driver")) + { return -1; } + + if (0 > PyModule_AddIntConstant(module, + "__libpq_version__", PG_VERSION_NUM)) + { return -1; } + + if (0 > PyModule_AddObject(module, + "apilevel", tmp = Text_FromUTF8(APILEVEL))) + { + Py_XDECREF(tmp); + return -1; + } - /* the name is the part after the last dot */ - name = strrchr(exctable[i].name, '.'); - name = name ? name + 1 : exctable[i].name; + if (0 > PyModule_AddObject(module, + "threadsafety", tmp = PyInt_FromLong(THREADSAFETY))) + { + Py_XDECREF(tmp); + return -1; + } - PyDict_SetItemString(dict, name, *exctable[i].exc); + if (0 > PyModule_AddObject(module, + "paramstyle", tmp = Text_FromUTF8(PARAMSTYLE))) + { + Py_XDECREF(tmp); + return -1; } + + if (0 > PyModule_AddIntMacro(module, REPLICATION_PHYSICAL)) { return -1; } + if (0 > PyModule_AddIntMacro(module, REPLICATION_LOGICAL)) { return -1; } + + return 0; } -void -psyco_errors_set(PyObject *type) + +static struct { + char *name; + PyTypeObject *type; +} typetable[] = { + { "connection", &connectionType }, + { "cursor", &cursorType }, + { "ReplicationConnection", &replicationConnectionType }, + { "ReplicationCursor", &replicationCursorType }, + { "ReplicationMessage", &replicationMessageType }, + { "ISQLQuote", &isqlquoteType }, + { "Column", &columnType }, + { "Notify", ¬ifyType }, + { "Xid", &xidType }, + { "ConnectionInfo", &connInfoType }, + { "Diagnostics", &diagnosticsType }, + { "AsIs", &asisType }, + { "Binary", &binaryType }, + { "Boolean", &pbooleanType }, + { "Decimal", &pdecimalType }, + { "Int", &pintType }, + { "Float", &pfloatType }, + { "List", &listType }, + { "QuotedString", &qstringType }, + { "lobject", &lobjectType }, + {NULL} /* Sentinel */ +}; + +RAISES_NEG static int +add_module_types(PyObject *module) { int i; - char *name; - for (i = 0; exctable[i].name; i++) { - if (NULL == exctable[i].exc) { continue; } + Dprintf("psycopgmodule: initializing module types"); - /* the name is the part after the last dot */ - name = strrchr(exctable[i].name, '.'); - name = name ? name + 1 : exctable[i].name; + for (i = 0; typetable[i].name; i++) { + PyObject *type = (PyObject *)typetable[i].type; + + Py_TYPE(typetable[i].type) = &PyType_Type; + if (0 > PyType_Ready(typetable[i].type)) { return -1; } + + Py_INCREF(type); + if (0 > PyModule_AddObject(module, typetable[i].name, type)) { + Py_DECREF(type); + return -1; + } + } + return 0; +} + + +RAISES_NEG static int +datetime_init(void) +{ + PyObject *dt = NULL; - PyObject_SetAttrString(type, name, *exctable[i].exc); + Dprintf("psycopgmodule: datetime module"); + + /* import python builtin datetime module, if available */ + if (!(dt = PyImport_ImportModule("datetime"))) { + return -1; } + Py_DECREF(dt); + + /* Initialize the PyDateTimeAPI everywhere is used */ + PyDateTime_IMPORT; + if (0 > psyco_adapter_datetime_init()) { return -1; } + if (0 > psyco_repl_curs_datetime_init()) { return -1; } + if (0 > psyco_replmsg_datetime_init()) { return -1; } + + Py_TYPE(&pydatetimeType) = &PyType_Type; + if (0 > PyType_Ready(&pydatetimeType)) { return -1; } + + return 0; } +RAISES_NEG static int +mxdatetime_init(PyObject *module) +{ + Dprintf("psycopgmodule: initializing mx.DateTime module"); + +#ifdef HAVE_MXDATETIME + Py_TYPE(&mxdatetimeType) = &PyType_Type; + if (0 > PyType_Ready(&mxdatetimeType)) { return -1; } + + if (mxDateTime_ImportModuleAndAPI()) { + Dprintf("psycopgmodule: mx.DateTime module import failed"); + PyErr_Clear(); + + /* only fail if the mx typacaster should have been the default */ +#ifdef PSYCOPG_DEFAULT_MXDATETIME + PyErr_SetString(PyExc_ImportError, + "can't import mx.DateTime module (requested as default adapter)"); + return -1; +#endif + } + + /* If we can't find mx.DateTime objects at runtime, + * remove them from the module (and, as consequence, from the adapters). */ + if (0 != psyco_adapter_mxdatetime_init()) { + PyObject *dict; + if (!(dict = PyModule_GetDict(module))) { return -1; } + if (0 > PyDict_DelItemString(dict, "DateFromMx")) { return -1; } + if (0 > PyDict_DelItemString(dict, "TimeFromMx")) { return -1; } + if (0 > PyDict_DelItemString(dict, "TimestampFromMx")) { return -1; } + if (0 > PyDict_DelItemString(dict, "IntervalFromMx")) { return -1; } + } +#endif + return 0; +} /** method table and module initialization **/ @@ -801,132 +966,38 @@ static struct PyModuleDef psycopgmodule = { }; #endif +#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ +#define PyMODINIT_FUNC void +#endif PyMODINIT_FUNC INIT_MODULE(_psycopg)(void) { -#if PY_VERSION_HEX < 0x03020000 - static void *PSYCOPG_API[PSYCOPG_API_pointers]; - PyObject *c_api_object; -#endif - - PyObject *module = NULL, *dict; + PyObject *module = NULL; #ifdef PSYCOPG_DEBUG if (getenv("PSYCOPG_DEBUG")) psycopg_debug_enabled = 1; #endif - Dprintf("initpsycopg: initializing psycopg %s", xstr(PSYCOPG_VERSION)); + Dprintf("psycopgmodule: initializing psycopg %s", xstr(PSYCOPG_VERSION)); - /* initialize all the new types and then the module */ - Py_TYPE(&connectionType) = &PyType_Type; - if (PyType_Ready(&connectionType) == -1) goto exit; - - Py_TYPE(&cursorType) = &PyType_Type; - if (PyType_Ready(&cursorType) == -1) goto exit; - - Py_TYPE(&replicationConnectionType) = &PyType_Type; - if (PyType_Ready(&replicationConnectionType) == -1) goto exit; - - Py_TYPE(&replicationCursorType) = &PyType_Type; - if (PyType_Ready(&replicationCursorType) == -1) goto exit; - - Py_TYPE(&replicationMessageType) = &PyType_Type; - if (PyType_Ready(&replicationMessageType) == -1) goto exit; + /* initialize libcrypto threading callbacks */ + psyco_libcrypto_threads_init(); + /* initialize types and objects not exposed to the module */ Py_TYPE(&typecastType) = &PyType_Type; - if (PyType_Ready(&typecastType) == -1) goto exit; - - Py_TYPE(&qstringType) = &PyType_Type; - if (PyType_Ready(&qstringType) == -1) goto exit; - - Py_TYPE(&binaryType) = &PyType_Type; - if (PyType_Ready(&binaryType) == -1) goto exit; - - Py_TYPE(&isqlquoteType) = &PyType_Type; - if (PyType_Ready(&isqlquoteType) == -1) goto exit; - - Py_TYPE(&pbooleanType) = &PyType_Type; - if (PyType_Ready(&pbooleanType) == -1) goto exit; - - Py_TYPE(&pintType) = &PyType_Type; - if (PyType_Ready(&pintType) == -1) goto exit; - - Py_TYPE(&pfloatType) = &PyType_Type; - if (PyType_Ready(&pfloatType) == -1) goto exit; - - Py_TYPE(&pdecimalType) = &PyType_Type; - if (PyType_Ready(&pdecimalType) == -1) goto exit; - - Py_TYPE(&asisType) = &PyType_Type; - if (PyType_Ready(&asisType) == -1) goto exit; - - Py_TYPE(&listType) = &PyType_Type; - if (PyType_Ready(&listType) == -1) goto exit; + if (0 > PyType_Ready(&typecastType)) { goto exit; } Py_TYPE(&chunkType) = &PyType_Type; - if (PyType_Ready(&chunkType) == -1) goto exit; - - Py_TYPE(&columnType) = &PyType_Type; - if (PyType_Ready(&columnType) == -1) goto exit; - - Py_TYPE(¬ifyType) = &PyType_Type; - if (PyType_Ready(¬ifyType) == -1) goto exit; - - Py_TYPE(&xidType) = &PyType_Type; - if (PyType_Ready(&xidType) == -1) goto exit; + if (0 > PyType_Ready(&chunkType)) { goto exit; } Py_TYPE(&errorType) = &PyType_Type; errorType.tp_base = (PyTypeObject *)PyExc_StandardError; - if (PyType_Ready(&errorType) == -1) goto exit; - - Py_TYPE(&connInfoType) = &PyType_Type; - if (PyType_Ready(&connInfoType) == -1) goto exit; - - Py_TYPE(&diagnosticsType) = &PyType_Type; - if (PyType_Ready(&diagnosticsType) == -1) goto exit; + if (0 > PyType_Ready(&errorType)) { goto exit; } - Py_TYPE(&lobjectType) = &PyType_Type; - if (PyType_Ready(&lobjectType) == -1) goto exit; + if (!(psyco_null = Bytes_FromString("NULL"))) { goto exit; } - /* initialize libcrypto threading callbacks */ - psyco_libcrypto_threads_init(); - - /* import mx.DateTime module, if necessary */ -#ifdef HAVE_MXDATETIME - Py_TYPE(&mxdatetimeType) = &PyType_Type; - if (PyType_Ready(&mxdatetimeType) == -1) goto exit; - - if (0 != mxDateTime_ImportModuleAndAPI()) { - PyErr_Clear(); - - /* only fail if the mx typacaster should have been the default */ -#ifdef PSYCOPG_DEFAULT_MXDATETIME - PyErr_SetString(PyExc_ImportError, - "can't import mx.DateTime module (requested as default adapter)"); - goto exit; -#endif - } -#endif - - /* import python builtin datetime module, if available */ - pyDateTimeModuleP = PyImport_ImportModule("datetime"); - if (pyDateTimeModuleP == NULL) { - Dprintf("initpsycopg: can't import datetime module"); - PyErr_SetString(PyExc_ImportError, "can't import datetime module"); - goto exit; - } - - /* Initialize the PyDateTimeAPI everywhere is used */ - PyDateTime_IMPORT; - if (psyco_adapter_datetime_init()) { goto exit; } - if (psyco_repl_curs_datetime_init()) { goto exit; } - if (psyco_replmsg_datetime_init()) { goto exit; } - - Py_TYPE(&pydatetimeType) = &PyType_Type; - if (PyType_Ready(&pydatetimeType) == -1) goto exit; - - /* initialize the module and grab module's dictionary */ + /* initialize the module */ #if PY_MAJOR_VERSION < 3 module = Py_InitModule("_psycopg", psycopgMethods); #else @@ -934,81 +1005,16 @@ INIT_MODULE(_psycopg)(void) #endif if (!module) { goto exit; } - dict = PyModule_GetDict(module); - - /* initialize all the module's exported functions */ - /* PyBoxer_API[PyBoxer_Fake_NUM] = (void *)PyBoxer_Fake; */ - - /* Create a CObject containing the API pointer array's address */ - /* If anybody asks for a PyCapsule we'll deal with it. */ -#if PY_VERSION_HEX < 0x03020000 - c_api_object = PyCObject_FromVoidPtr((void *)PSYCOPG_API, NULL); - if (c_api_object != NULL) - PyModule_AddObject(module, "_C_API", c_api_object); -#endif - - /* other mixed initializations of module-level variables */ - if (!(psycoEncodings = PyDict_New())) { goto exit; } - if (0 != psyco_encodings_fill(psycoEncodings)) { goto exit; } - psyco_null = Bytes_FromString("NULL"); - - /* set some module's parameters */ - PyModule_AddStringConstant(module, "__version__", xstr(PSYCOPG_VERSION)); - PyModule_AddStringConstant(module, "__doc__", "psycopg PostgreSQL driver"); - PyModule_AddIntConstant(module, "__libpq_version__", PG_VERSION_NUM); - PyModule_AddIntMacro(module, REPLICATION_PHYSICAL); - PyModule_AddIntMacro(module, REPLICATION_LOGICAL); - PyModule_AddObject(module, "apilevel", Text_FromUTF8(APILEVEL)); - PyModule_AddObject(module, "threadsafety", PyInt_FromLong(THREADSAFETY)); - PyModule_AddObject(module, "paramstyle", Text_FromUTF8(PARAMSTYLE)); - - /* put new types in module dictionary */ - PyModule_AddObject(module, "connection", (PyObject*)&connectionType); - PyModule_AddObject(module, "cursor", (PyObject*)&cursorType); - PyModule_AddObject(module, "ReplicationConnection", (PyObject*)&replicationConnectionType); - PyModule_AddObject(module, "ReplicationCursor", (PyObject*)&replicationCursorType); - PyModule_AddObject(module, "ReplicationMessage", (PyObject*)&replicationMessageType); - PyModule_AddObject(module, "ISQLQuote", (PyObject*)&isqlquoteType); - PyModule_AddObject(module, "Column", (PyObject*)&columnType); - PyModule_AddObject(module, "Notify", (PyObject*)¬ifyType); - PyModule_AddObject(module, "Xid", (PyObject*)&xidType); - PyModule_AddObject(module, "ConnectionInfo", (PyObject*)&connInfoType); - PyModule_AddObject(module, "Diagnostics", (PyObject*)&diagnosticsType); - PyModule_AddObject(module, "AsIs", (PyObject*)&asisType); - PyModule_AddObject(module, "Binary", (PyObject*)&binaryType); - PyModule_AddObject(module, "Boolean", (PyObject*)&pbooleanType); - PyModule_AddObject(module, "Decimal", (PyObject*)&pdecimalType); - PyModule_AddObject(module, "Int", (PyObject*)&pintType); - PyModule_AddObject(module, "Float", (PyObject*)&pfloatType); - PyModule_AddObject(module, "List", (PyObject*)&listType); - PyModule_AddObject(module, "QuotedString", (PyObject*)&qstringType); - PyModule_AddObject(module, "lobject", (PyObject*)&lobjectType); - - /* encodings dictionary in module dictionary */ - PyModule_AddObject(module, "encodings", psycoEncodings); - -#ifdef HAVE_MXDATETIME - /* If we can't find mx.DateTime objects at runtime, - * remove them from the module (and, as consequence, from the adapters). */ - if (0 != psyco_adapter_mxdatetime_init()) { - PyDict_DelItemString(dict, "DateFromMx"); - PyDict_DelItemString(dict, "TimeFromMx"); - PyDict_DelItemString(dict, "TimestampFromMx"); - PyDict_DelItemString(dict, "IntervalFromMx"); - } -#endif - /* initialize default set of typecasters */ - if (0 != typecast_init(dict)) { goto exit; } - - /* initialize microprotocols layer */ - microprotocols_init(dict); - if (0 != psyco_adapters_init(dict)) { goto exit; } - - /* create a standard set of exceptions and add them to the module's dict */ - if (0 != psyco_errors_init()) { goto exit; } - psyco_errors_fill(dict); + if (0 > add_module_constants(module)) { goto exit; } + if (0 > add_module_types(module)) { goto exit; } + if (0 > datetime_init()) { goto exit; } + if (0 > mxdatetime_init(module)) { goto exit; } + if (0 > encodings_init(module)) { goto exit; } + if (0 > typecast_init(module)) { goto exit; } + if (0 > adapters_init(module)) { goto exit; } + if (0 > errors_init(module)) { goto exit; } - Dprintf("initpsycopg: module initialization complete"); + Dprintf("psycopgmodule: module initialization complete"); exit: #if PY_MAJOR_VERSION > 2 diff --git a/psycopg/replication_cursor.h b/psycopg/replication_cursor.h index 71c6e19..2d69bc8 100644 --- a/psycopg/replication_cursor.h +++ b/psycopg/replication_cursor.h @@ -50,7 +50,7 @@ typedef struct replicationCursorObject { } replicationCursorObject; -RAISES_NEG int psyco_repl_curs_datetime_init(void); +RAISES_NEG HIDDEN int psyco_repl_curs_datetime_init(void); #ifdef __cplusplus } diff --git a/psycopg/replication_message.h b/psycopg/replication_message.h index b4d93d6..9ba0da2 100644 --- a/psycopg/replication_message.h +++ b/psycopg/replication_message.h @@ -48,7 +48,7 @@ struct replicationMessageObject { int64_t send_time; }; -RAISES_NEG int psyco_replmsg_datetime_init(void); +RAISES_NEG HIDDEN int psyco_replmsg_datetime_init(void); #ifdef __cplusplus } diff --git a/psycopg/typecast.c b/psycopg/typecast.c index 005cce0..f6ea928 100644 --- a/psycopg/typecast.c +++ b/psycopg/typecast.c @@ -252,11 +252,14 @@ PyObject *psyco_default_binary_cast; /* typecast_init - initialize the dictionary and create default types */ RAISES_NEG int -typecast_init(PyObject *dict) +typecast_init(PyObject *module) { int i; int rv = -1; typecastObject *t = NULL; + PyObject *dict = NULL; + + if (!(dict = PyModule_GetDict(module))) { goto exit; } /* create type dictionary and put it in module namespace */ if (!(psyco_types = PyDict_New())) { goto exit; } @@ -278,13 +281,14 @@ typecast_init(PyObject *dict) /* export binary object */ if (typecast_builtins[i].values == typecast_BINARY_types) { + Py_INCREF((PyObject *)t); psyco_default_binary_cast = (PyObject *)t; } Py_DECREF((PyObject *)t); t = NULL; } - /* create and save a default cast object (but does not register it) */ + /* create and save a default cast object (but do not register it) */ psyco_default_cast = typecast_from_c(&typecast_default, dict); /* register the date/time typecasters with their original names */ |