mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-25 18:33:44 +03:00
Don't fail import if mx.DateTime module is not found at import time
A better fix for ticket #53.
This commit is contained in:
parent
05659c0d16
commit
c8ec747903
4
NEWS
4
NEWS
|
@ -9,8 +9,8 @@ What's new in psycopg 2.4.2
|
|||
default isolation level.
|
||||
- Fixed bug with multithread code potentially causing loss of sync
|
||||
with the server communication or lock of the client (ticket #55).
|
||||
- Don't build mx.DateTime support if the module can't be imported
|
||||
(ticket #53).
|
||||
- Don't fail import if mx.DateTime module can't be found, even if its
|
||||
support was built (ticket #53).
|
||||
- Fixed escape for negative numbers prefixed by minus operator
|
||||
(ticket #57).
|
||||
|
||||
|
|
|
@ -45,11 +45,11 @@ typedef struct {
|
|||
} pydatetimeObject;
|
||||
|
||||
|
||||
HIDDEN int psyco_adapter_datetime_init(void);
|
||||
|
||||
/* functions exported to psycopgmodule.c */
|
||||
#ifdef PSYCOPG_DEFAULT_PYDATETIME
|
||||
|
||||
HIDDEN int psyco_adapter_datetime_init(void);
|
||||
|
||||
HIDDEN PyObject *psyco_Date(PyObject *module, PyObject *args);
|
||||
#define psyco_Date_doc \
|
||||
"Date(year, month, day) -> new date\n\n" \
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#define PSYCOPG_MODULE
|
||||
#include "psycopg/psycopg.h"
|
||||
|
||||
/* TODO: check if still compiles ok: I have no mx on this box */
|
||||
#include "psycopg/adapter_mxdatetime.h"
|
||||
#include "psycopg/microprotocols_proto.h"
|
||||
|
||||
|
@ -34,13 +33,16 @@
|
|||
#include <string.h>
|
||||
|
||||
|
||||
/* Return 0 on success, -1 on failure, but don't set an exception */
|
||||
|
||||
int
|
||||
psyco_adapter_mxdatetime_init(void)
|
||||
{
|
||||
Dprintf("psyco_adapter_mxdatetime_init: mx.DateTime init");
|
||||
|
||||
if(mxDateTime_ImportModuleAndAPI()) {
|
||||
PyErr_SetString(PyExc_ImportError, "mx.DateTime initialization failed");
|
||||
if (mxDateTime_ImportModuleAndAPI()) {
|
||||
Dprintf("psyco_adapter_mxdatetime_init: mx.DateTime initialization failed");
|
||||
PyErr_Clear();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -360,10 +360,16 @@ psyco_adapters_init(PyObject *mod)
|
|||
|
||||
#ifdef HAVE_MXDATETIME
|
||||
/* as above, we use the callable objects from the psycopg module */
|
||||
call = PyMapping_GetItemString(mod, "TimestampFromMx");
|
||||
microprotocols_add(mxDateTime.DateTime_Type, NULL, call);
|
||||
call = PyMapping_GetItemString(mod, "TimeFromMx");
|
||||
microprotocols_add(mxDateTime.DateTimeDelta_Type, NULL, call);
|
||||
if (NULL != (call = PyMapping_GetItemString(mod, "TimestampFromMx"))) {
|
||||
microprotocols_add(mxDateTime.DateTime_Type, NULL, call);
|
||||
|
||||
/* if we found the above, we have this too. */
|
||||
call = PyMapping_GetItemString(mod, "TimeFromMx");
|
||||
microprotocols_add(mxDateTime.DateTimeDelta_Type, NULL, call);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -792,6 +798,7 @@ static PyMethodDef psycopgMethods[] = {
|
|||
METH_VARARGS, psyco_IntervalFromPy_doc},
|
||||
|
||||
#ifdef HAVE_MXDATETIME
|
||||
/* to be deleted if not found at import time */
|
||||
{"DateFromMx", (PyCFunction)psyco_DateFromMx,
|
||||
METH_VARARGS, psyco_DateFromMx_doc},
|
||||
{"TimeFromMx", (PyCFunction)psyco_TimeFromMx,
|
||||
|
@ -885,12 +892,16 @@ INIT_MODULE(_psycopg)(void)
|
|||
#ifdef HAVE_MXDATETIME
|
||||
Py_TYPE(&mxdatetimeType) = &PyType_Type;
|
||||
if (PyType_Ready(&mxdatetimeType) == -1) goto exit;
|
||||
if (mxDateTime_ImportModuleAndAPI() != 0) {
|
||||
Dprintf("initpsycopg: why marc hide mx.DateTime again?!");
|
||||
PyErr_SetString(PyExc_ImportError, "can't import mx.DateTime module");
|
||||
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
|
||||
}
|
||||
if (psyco_adapter_mxdatetime_init()) { goto exit; }
|
||||
#endif
|
||||
|
||||
/* import python builtin datetime module, if available */
|
||||
|
@ -967,6 +978,16 @@ INIT_MODULE(_psycopg)(void)
|
|||
/* 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 */
|
||||
typecast_init(dict);
|
||||
|
||||
|
@ -999,7 +1020,6 @@ INIT_MODULE(_psycopg)(void)
|
|||
lobjectType.tp_alloc = PyType_GenericAlloc;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MXDATETIME
|
||||
mxdatetimeType.tp_alloc = PyType_GenericAlloc;
|
||||
#endif
|
||||
|
|
|
@ -292,13 +292,14 @@ typecast_init(PyObject *dict)
|
|||
|
||||
/* register the date/time typecasters with their original names */
|
||||
#ifdef HAVE_MXDATETIME
|
||||
if (psyco_typecast_mxdatetime_init()) { return -1; }
|
||||
for (i = 0; typecast_mxdatetime[i].name != NULL; i++) {
|
||||
typecastObject *t;
|
||||
Dprintf("typecast_init: initializing %s", typecast_mxdatetime[i].name);
|
||||
t = (typecastObject *)typecast_from_c(&(typecast_mxdatetime[i]), dict);
|
||||
if (t == NULL) return -1;
|
||||
PyDict_SetItem(dict, t->name, (PyObject *)t);
|
||||
if (0 == psyco_typecast_mxdatetime_init()) {
|
||||
for (i = 0; typecast_mxdatetime[i].name != NULL; i++) {
|
||||
typecastObject *t;
|
||||
Dprintf("typecast_init: initializing %s", typecast_mxdatetime[i].name);
|
||||
t = (typecastObject *)typecast_from_c(&(typecast_mxdatetime[i]), dict);
|
||||
if (t == NULL) return -1;
|
||||
PyDict_SetItem(dict, t->name, (PyObject *)t);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -25,13 +25,17 @@
|
|||
|
||||
#include "mxDateTime.h"
|
||||
|
||||
|
||||
/* Return 0 on success, -1 on failure, but don't set an exception */
|
||||
|
||||
static int
|
||||
psyco_typecast_mxdatetime_init(void)
|
||||
{
|
||||
Dprintf("psyco_typecast_mxdatetime_init: mx.DateTime init");
|
||||
|
||||
if(mxDateTime_ImportModuleAndAPI()) {
|
||||
PyErr_SetString(PyExc_ImportError, "mx.DateTime initialization failed");
|
||||
if (mxDateTime_ImportModuleAndAPI()) {
|
||||
Dprintf("psyco_typecast_mxdatetime_init: mx.DateTime initialization failed");
|
||||
PyErr_Clear();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
19
setup.py
19
setup.py
|
@ -450,18 +450,13 @@ if parser.has_option('build_ext', 'mx_include_dir'):
|
|||
else:
|
||||
mxincludedir = os.path.join(get_python_inc(plat_specific=1), "mx")
|
||||
if os.path.exists(mxincludedir):
|
||||
# Check if mx.datetime is importable at all: see ticket #53
|
||||
try:
|
||||
import mx.DateTime
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
include_dirs.append(mxincludedir)
|
||||
define_macros.append(('HAVE_MXDATETIME','1'))
|
||||
sources.append('adapter_mxdatetime.c')
|
||||
depends.extend(['adapter_mxdatetime.h', 'typecast_mxdatetime.c'])
|
||||
have_mxdatetime = True
|
||||
version_flags.append('mx')
|
||||
# Build the support for mx: we will check at runtime if it can be imported
|
||||
include_dirs.append(mxincludedir)
|
||||
define_macros.append(('HAVE_MXDATETIME','1'))
|
||||
sources.append('adapter_mxdatetime.c')
|
||||
depends.extend(['adapter_mxdatetime.h', 'typecast_mxdatetime.c'])
|
||||
have_mxdatetime = True
|
||||
version_flags.append('mx')
|
||||
|
||||
# now decide which package will be the default for date/time typecasts
|
||||
if have_pydatetime and (use_pydatetime or not have_mxdatetime):
|
||||
|
|
Loading…
Reference in New Issue
Block a user