mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-10-31 07:47:30 +03:00 
			
		
		
		
	Don't import psycopg2.tz into the C extension
This makes possible to import _psycopg directly, after adding the
package directory to the pythonpath. This enables hacks such as:
    sys.path.insert(0, '/path/to/psycopg2')
    import _psycopg
    sys.modules['psycopg2._psycopg'] = _psycopg
    sys.path.pop(0)
which can work around e.g. the problem of #201, freeze that cannot
freeze psycopg2. Well, freeze cannot freeze it because it's just not
designed to deal with C extensions. At least now the frozen application
can hack the pythonpath and work around the limitation by importing
_psycopg as above and then doing the rest of the imports normally.
Keeping long-lived references to python objects is bad anyway: the
tz module couldn't be reloaded before.
			
			
This commit is contained in:
		
							parent
							
								
									284677ae0a
								
							
						
					
					
						commit
						b12f6a9135
					
				|  | @ -35,9 +35,6 @@ | ||||||
| #include <string.h> | #include <string.h> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| extern HIDDEN PyObject *pyPsycopgTzModule; |  | ||||||
| extern HIDDEN PyObject *pyPsycopgTzLOCAL; |  | ||||||
| 
 |  | ||||||
| int | int | ||||||
| psyco_adapter_datetime_init(void) | psyco_adapter_datetime_init(void) | ||||||
| { | { | ||||||
|  | @ -392,9 +389,9 @@ psyco_DateFromTicks(PyObject *self, PyObject *args) | ||||||
|             Py_DECREF(args); |             Py_DECREF(args); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 	else { |     else { | ||||||
| 		PyErr_SetString(InterfaceError, "failed localtime call"); |         PyErr_SetString(InterfaceError, "failed localtime call"); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
|     return res; |     return res; | ||||||
| } | } | ||||||
|  | @ -420,9 +417,9 @@ psyco_TimeFromTicks(PyObject *self, PyObject *args) | ||||||
|             Py_DECREF(args); |             Py_DECREF(args); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 	else { |     else { | ||||||
| 		PyErr_SetString(InterfaceError, "failed localtime call"); |         PyErr_SetString(InterfaceError, "failed localtime call"); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
|     return res; |     return res; | ||||||
| } | } | ||||||
|  | @ -430,6 +427,8 @@ psyco_TimeFromTicks(PyObject *self, PyObject *args) | ||||||
| PyObject * | PyObject * | ||||||
| psyco_TimestampFromTicks(PyObject *self, PyObject *args) | psyco_TimestampFromTicks(PyObject *self, PyObject *args) | ||||||
| { | { | ||||||
|  |     PyObject *m = NULL; | ||||||
|  |     PyObject *tz = NULL; | ||||||
|     PyObject *res = NULL; |     PyObject *res = NULL; | ||||||
|     struct tm tm; |     struct tm tm; | ||||||
|     time_t t; |     time_t t; | ||||||
|  | @ -438,18 +437,25 @@ psyco_TimestampFromTicks(PyObject *self, PyObject *args) | ||||||
|     if (!PyArg_ParseTuple(args, "d", &ticks)) |     if (!PyArg_ParseTuple(args, "d", &ticks)) | ||||||
|         return NULL; |         return NULL; | ||||||
| 
 | 
 | ||||||
|  |     /* get psycopg2.tz.LOCAL from pythonland */ | ||||||
|  |     if (!(m = PyImport_ImportModule("psycopg2.tz"))) { goto exit; } | ||||||
|  |     if (!(tz = PyObject_GetAttrString(m, "LOCAL"))) { goto exit; } | ||||||
|  | 
 | ||||||
|     t = (time_t)floor(ticks); |     t = (time_t)floor(ticks); | ||||||
|     ticks -= (double)t; |     ticks -= (double)t; | ||||||
|     if (localtime_r(&t, &tm)) { |     if (!localtime_r(&t, &tm)) { | ||||||
|         res = _psyco_Timestamp( |         PyErr_SetString(InterfaceError, "failed localtime call"); | ||||||
|             tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, |         goto exit; | ||||||
|             tm.tm_hour, tm.tm_min, (double)tm.tm_sec + ticks, |  | ||||||
|             pyPsycopgTzLOCAL); |  | ||||||
|     } |     } | ||||||
| 	else { |  | ||||||
| 		PyErr_SetString(InterfaceError, "failed localtime call"); |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  |     res = _psyco_Timestamp( | ||||||
|  |         tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, | ||||||
|  |         tm.tm_hour, tm.tm_min, (double)tm.tm_sec + ticks, | ||||||
|  |         tz); | ||||||
|  | 
 | ||||||
|  | exit: | ||||||
|  |     Py_DECREF(tz); | ||||||
|  |     Py_XDECREF(m); | ||||||
|     return res; |     return res; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -39,9 +39,6 @@ | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| extern PyObject *pyPsycopgTzFixedOffsetTimezone; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /** DBAPI methods **/ | /** DBAPI methods **/ | ||||||
| 
 | 
 | ||||||
| /* close method - close the cursor */ | /* close method - close the cursor */ | ||||||
|  | @ -1842,8 +1839,17 @@ cursor_setup(cursorObject *self, connectionObject *conn, const char *name) | ||||||
|     self->tuple_factory = Py_None; |     self->tuple_factory = Py_None; | ||||||
| 
 | 
 | ||||||
|     /* default tzinfo factory */ |     /* default tzinfo factory */ | ||||||
|     Py_INCREF(pyPsycopgTzFixedOffsetTimezone); |     { | ||||||
|     self->tzinfo_factory = pyPsycopgTzFixedOffsetTimezone; |         PyObject *m = NULL; | ||||||
|  |         if ((m = PyImport_ImportModule("psycopg2.tz"))) { | ||||||
|  |             self->tzinfo_factory = PyObject_GetAttrString( | ||||||
|  |                     m, "FixedOffsetTimezone"); | ||||||
|  |             Py_DECREF(m); | ||||||
|  |         } | ||||||
|  |         if (!self->tzinfo_factory) { | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     Dprintf("cursor_setup: good cursor object at %p, refcnt = " |     Dprintf("cursor_setup: good cursor object at %p, refcnt = " | ||||||
|         FORMAT_CODE_PY_SSIZE_T, |         FORMAT_CODE_PY_SSIZE_T, | ||||||
|  |  | ||||||
|  | @ -58,11 +58,6 @@ | ||||||
| #include "psycopg/adapter_datetime.h" | #include "psycopg/adapter_datetime.h" | ||||||
| HIDDEN PyObject *pyDateTimeModuleP = NULL; | HIDDEN PyObject *pyDateTimeModuleP = NULL; | ||||||
| 
 | 
 | ||||||
| /* pointers to the psycopg.tz classes */ |  | ||||||
| HIDDEN PyObject *pyPsycopgTzModule = NULL; |  | ||||||
| HIDDEN PyObject *pyPsycopgTzLOCAL = NULL; |  | ||||||
| HIDDEN PyObject *pyPsycopgTzFixedOffsetTimezone = NULL; |  | ||||||
| 
 |  | ||||||
| HIDDEN PyObject *psycoEncodings = NULL; | HIDDEN PyObject *psycoEncodings = NULL; | ||||||
| 
 | 
 | ||||||
| #ifdef PSYCOPG_DEBUG | #ifdef PSYCOPG_DEBUG | ||||||
|  | @ -859,18 +854,6 @@ INIT_MODULE(_psycopg)(void) | ||||||
|     Py_TYPE(&pydatetimeType) = &PyType_Type; |     Py_TYPE(&pydatetimeType) = &PyType_Type; | ||||||
|     if (PyType_Ready(&pydatetimeType) == -1) goto exit; |     if (PyType_Ready(&pydatetimeType) == -1) goto exit; | ||||||
| 
 | 
 | ||||||
|     /* import psycopg2.tz anyway (TODO: replace with C-level module?) */ |  | ||||||
|     pyPsycopgTzModule = PyImport_ImportModule("psycopg2.tz"); |  | ||||||
|     if (pyPsycopgTzModule == NULL) { |  | ||||||
|         Dprintf("initpsycopg: can't import psycopg2.tz module"); |  | ||||||
|         PyErr_SetString(PyExc_ImportError, "can't import psycopg2.tz module"); |  | ||||||
|         goto exit; |  | ||||||
|     } |  | ||||||
|     pyPsycopgTzLOCAL = |  | ||||||
|         PyObject_GetAttrString(pyPsycopgTzModule, "LOCAL"); |  | ||||||
|     pyPsycopgTzFixedOffsetTimezone = |  | ||||||
|         PyObject_GetAttrString(pyPsycopgTzModule, "FixedOffsetTimezone"); |  | ||||||
| 
 |  | ||||||
|     /* initialize the module and grab module's dictionary */ |     /* initialize the module and grab module's dictionary */ | ||||||
| #if PY_MAJOR_VERSION < 3 | #if PY_MAJOR_VERSION < 3 | ||||||
|     module = Py_InitModule("_psycopg", psycopgMethods); |     module = Py_InitModule("_psycopg", psycopgMethods); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user