Merge branch 'module-init-cleanup'

This commit is contained in:
Daniele Varrazzo 2019-01-23 14:17:07 +00:00
commit 00cb2636f5
9 changed files with 283 additions and 326 deletions

View File

@ -35,7 +35,7 @@
#include <string.h>
int
RAISES_NEG int
psyco_adapter_datetime_init(void)
{
Dprintf("psyco_adapter_datetime_init: datetime init");

View File

@ -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

View File

@ -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;

View File

@ -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(

View File

@ -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."

View File

@ -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);
if (!(obj = PyMapping_GetItemString(dict, "TimeFromMx"))) {
goto exit;
}
else {
PyErr_Clear();
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)
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;
}
if (0 > PyModule_AddObject(module,
"threadsafety", tmp = PyInt_FromLong(THREADSAFETY)))
{
Py_XDECREF(tmp);
return -1;
}
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;
}
static struct {
char *name;
PyTypeObject *type;
} typetable[] = {
{ "connection", &connectionType },
{ "cursor", &cursorType },
{ "ReplicationConnection", &replicationConnectionType },
{ "ReplicationCursor", &replicationCursorType },
{ "ReplicationMessage", &replicationMessageType },
{ "ISQLQuote", &isqlquoteType },
{ "Column", &columnType },
{ "Notify", &notifyType },
{ "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;
PyDict_SetItemString(dict, name, *exctable[i].exc);
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;
}
void
psyco_errors_set(PyObject *type)
RAISES_NEG static int
datetime_init(void)
{
int i;
char *name;
PyObject *dt = NULL;
for (i = 0; exctable[i].name; i++) {
if (NULL == exctable[i].exc) { continue; }
Dprintf("psycopgmodule: datetime module");
/* the name is the part after the last dot */
name = strrchr(exctable[i].name, '.');
name = name ? name + 1 : exctable[i].name;
PyObject_SetAttrString(type, name, *exctable[i].exc);
/* 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));
/* 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;
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;
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(&notifyType) = &PyType_Type;
if (PyType_Ready(&notifyType) == -1) goto exit;
Py_TYPE(&xidType) = &PyType_Type;
if (PyType_Ready(&xidType) == -1) 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;
Py_TYPE(&lobjectType) = &PyType_Type;
if (PyType_Ready(&lobjectType) == -1) goto exit;
Dprintf("psycopgmodule: initializing psycopg %s", xstr(PSYCOPG_VERSION));
/* 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;
/* initialize types and objects not exposed to the module */
Py_TYPE(&typecastType) = &PyType_Type;
if (0 > PyType_Ready(&typecastType)) { goto exit; }
if (0 != mxDateTime_ImportModuleAndAPI()) {
PyErr_Clear();
Py_TYPE(&chunkType) = &PyType_Type;
if (0 > PyType_Ready(&chunkType)) { goto exit; }
/* 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
Py_TYPE(&errorType) = &PyType_Type;
errorType.tp_base = (PyTypeObject *)PyExc_StandardError;
if (0 > PyType_Ready(&errorType)) { goto exit; }
/* 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;
}
if (!(psyco_null = Bytes_FromString("NULL"))) { 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);
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; }
/* 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*)&notifyType);
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);
Dprintf("initpsycopg: module initialization complete");
Dprintf("psycopgmodule: module initialization complete");
exit:
#if PY_MAJOR_VERSION > 2

View File

@ -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
}

View File

@ -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
}

View File

@ -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 */