mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-07-04 03:33:03 +03:00
Fixed bug #192 (Decimal support not safe for use with multiple sub
interpreters) as proposed by Graham Dumpleton. If running in the main interpreter, use a cached version of the Decimal object. Else repeat the object lookup.
This commit is contained in:
parent
63773ad1e0
commit
e1dd9ca843
|
@ -1,3 +1,8 @@
|
||||||
|
2007-10-21 Daniele Varrazzo <daniele.varrazzo@gmail.com>
|
||||||
|
|
||||||
|
* Fixed bug #192 (Decimal support not safe for use with multiple sub
|
||||||
|
interpreters) as proposed by Graham Dumpleton.
|
||||||
|
|
||||||
2007-09-08 Federico Di Gregorio <fog@initd.org>
|
2007-09-08 Federico Di Gregorio <fog@initd.org>
|
||||||
|
|
||||||
* Added MonoDevelop project, yahi!
|
* Added MonoDevelop project, yahi!
|
||||||
|
|
|
@ -130,7 +130,7 @@ typedef struct {
|
||||||
} encodingPair;
|
} encodingPair;
|
||||||
|
|
||||||
/* the Decimal type, used by the DECIMAL typecaster */
|
/* the Decimal type, used by the DECIMAL typecaster */
|
||||||
extern PyObject *decimalType;
|
extern PyObject *psyco_GetDecimalType(void);
|
||||||
|
|
||||||
/* some utility functions */
|
/* some utility functions */
|
||||||
extern void psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
|
extern void psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
|
||||||
|
|
|
@ -62,7 +62,6 @@ PyObject *pyPsycopgTzLOCAL = NULL;
|
||||||
PyObject *pyPsycopgTzFixedOffsetTimezone = NULL;
|
PyObject *pyPsycopgTzFixedOffsetTimezone = NULL;
|
||||||
|
|
||||||
PyObject *psycoEncodings = NULL;
|
PyObject *psycoEncodings = NULL;
|
||||||
PyObject *decimalType = NULL;
|
|
||||||
|
|
||||||
/** connect module-level function **/
|
/** connect module-level function **/
|
||||||
#define psyco_connect_doc \
|
#define psyco_connect_doc \
|
||||||
|
@ -330,7 +329,8 @@ psyco_adapters_init(PyObject *mod)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DECIMAL
|
#ifdef HAVE_DECIMAL
|
||||||
microprotocols_add((PyTypeObject*)decimalType, NULL, (PyObject*)&asisType);
|
microprotocols_add((PyTypeObject*)psyco_GetDecimalType(),
|
||||||
|
NULL, (PyObject*)&asisType);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,14 +554,55 @@ psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* psyco_decimal_init
|
|
||||||
|
|
||||||
Initialize the module's pointer to the decimal type. */
|
/* Return nonzero if the current one is the main interpreter */
|
||||||
|
static int
|
||||||
void
|
psyco_is_main_interp()
|
||||||
psyco_decimal_init(void)
|
|
||||||
{
|
{
|
||||||
|
static PyInterpreterState *main_interp = NULL; /* Cached reference */
|
||||||
|
PyInterpreterState *interp;
|
||||||
|
|
||||||
|
if (main_interp) {
|
||||||
|
return (main_interp == PyThreadState_Get()->interp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No cached value: cache the proper value and try again. */
|
||||||
|
interp = PyInterpreterState_Head();
|
||||||
|
while (interp->next)
|
||||||
|
interp = interp->next;
|
||||||
|
|
||||||
|
main_interp = interp;
|
||||||
|
assert (main_interp);
|
||||||
|
return psyco_is_main_interp();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* psyco_GetDecimalType
|
||||||
|
|
||||||
|
Return a new reference to the adapter for decimal type.
|
||||||
|
|
||||||
|
If decimals should be used but the module import fails, fall back on
|
||||||
|
the float type.
|
||||||
|
|
||||||
|
If decimals are not to be used, return NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
psyco_GetDecimalType(void)
|
||||||
|
{
|
||||||
|
PyObject *decimalType = NULL;
|
||||||
|
static PyObject *cachedType = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_DECIMAL
|
#ifdef HAVE_DECIMAL
|
||||||
|
|
||||||
|
/* Use the cached object if running from the main interpreter. */
|
||||||
|
int can_cache = psyco_is_main_interp();
|
||||||
|
if (can_cache && cachedType) {
|
||||||
|
Py_INCREF(cachedType);
|
||||||
|
return cachedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a new reference to the Decimal type. */
|
||||||
PyObject *decimal = PyImport_ImportModule("decimal");
|
PyObject *decimal = PyImport_ImportModule("decimal");
|
||||||
if (decimal) {
|
if (decimal) {
|
||||||
decimalType = PyObject_GetAttrString(decimal, "Decimal");
|
decimalType = PyObject_GetAttrString(decimal, "Decimal");
|
||||||
|
@ -572,7 +613,15 @@ psyco_decimal_init(void)
|
||||||
decimalType = (PyObject *)&PyFloat_Type;
|
decimalType = (PyObject *)&PyFloat_Type;
|
||||||
Py_INCREF(decimalType);
|
Py_INCREF(decimalType);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
/* Store the object from future uses. */
|
||||||
|
if (can_cache && !cachedType) {
|
||||||
|
cachedType = decimalType;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_DECIMAL */
|
||||||
|
|
||||||
|
return decimalType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -731,7 +780,6 @@ init_psycopg(void)
|
||||||
/* other mixed initializations of module-level variables */
|
/* other mixed initializations of module-level variables */
|
||||||
psycoEncodings = PyDict_New();
|
psycoEncodings = PyDict_New();
|
||||||
psyco_encodings_fill(psycoEncodings);
|
psyco_encodings_fill(psycoEncodings);
|
||||||
psyco_decimal_init();
|
|
||||||
|
|
||||||
/* set some module's parameters */
|
/* set some module's parameters */
|
||||||
PyModule_AddStringConstant(module, "__version__", PSYCOPG_VERSION);
|
PyModule_AddStringConstant(module, "__version__", PSYCOPG_VERSION);
|
||||||
|
|
|
@ -120,6 +120,7 @@ static PyObject *
|
||||||
typecast_DECIMAL_cast(char *s, Py_ssize_t len, PyObject *curs)
|
typecast_DECIMAL_cast(char *s, Py_ssize_t len, PyObject *curs)
|
||||||
{
|
{
|
||||||
PyObject *res = NULL;
|
PyObject *res = NULL;
|
||||||
|
PyObject *decimalType;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
|
||||||
if (s == NULL) {Py_INCREF(Py_None); return Py_None;}
|
if (s == NULL) {Py_INCREF(Py_None); return Py_None;}
|
||||||
|
@ -127,7 +128,9 @@ typecast_DECIMAL_cast(char *s, Py_ssize_t len, PyObject *curs)
|
||||||
if ((buffer = PyMem_Malloc(len+1)) == NULL)
|
if ((buffer = PyMem_Malloc(len+1)) == NULL)
|
||||||
return PyErr_NoMemory();
|
return PyErr_NoMemory();
|
||||||
strncpy(buffer, s, (size_t) len); buffer[len] = '\0';
|
strncpy(buffer, s, (size_t) len); buffer[len] = '\0';
|
||||||
|
decimalType = psyco_GetDecimalType();
|
||||||
res = PyObject_CallFunction(decimalType, "s", buffer);
|
res = PyObject_CallFunction(decimalType, "s", buffer);
|
||||||
|
Py_DECREF(decimalType);
|
||||||
PyMem_Free(buffer);
|
PyMem_Free(buffer);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user