mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-10-31 15:57:31 +03:00 
			
		
		
		
	Merge branch 'libpq-version'
This commit is contained in:
		
						commit
						8d4ac25b56
					
				
							
								
								
									
										11
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								NEWS
									
									
									
									
									
								
							|  | @ -1,6 +1,17 @@ | ||||||
| Current release | Current release | ||||||
| --------------- | --------------- | ||||||
| 
 | 
 | ||||||
|  | What's new in psycopg 2.7 | ||||||
|  | ------------------------- | ||||||
|  | 
 | ||||||
|  | New features: | ||||||
|  | 
 | ||||||
|  | - Added `~psycopg2.__libpq_version__` and | ||||||
|  |   `~psycopg2.extensions.libpq_version()` to inspect the version of the | ||||||
|  |   ``libpq`` library the module was compiled/loaded with | ||||||
|  |   (:tickets:`#35, #323`). | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| What's new in psycopg 2.6.1 | What's new in psycopg 2.6.1 | ||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -197,6 +197,18 @@ functionalities defined by the |DBAPI|_. | ||||||
| 
 | 
 | ||||||
|     .. versionadded:: 2.2.0 |     .. versionadded:: 2.2.0 | ||||||
| 
 | 
 | ||||||
|  | .. function:: libpq_version() | ||||||
|  | 
 | ||||||
|  |     Return the version number of the ``libpq`` dynamic library loaded as an | ||||||
|  |     integer, in the same format of `~connection.server_version`. | ||||||
|  | 
 | ||||||
|  |     Raise `~psycopg2.NotSupportedError` if the ``psycopg2`` module was | ||||||
|  |     compiled with a ``libpq`` version lesser than 9.1 (which can be detected | ||||||
|  |     by the `~psycopg2.__libpq_version__` constant). | ||||||
|  | 
 | ||||||
|  |     .. seealso:: libpq docs for `PQlibVersion()`__. | ||||||
|  | 
 | ||||||
|  |         .. __: http://www.postgresql.org/docs/current/static/libpq-misc.html#LIBPQ-PQLIBVERSION | ||||||
| 
 | 
 | ||||||
| .. _sql-adaptation-objects: | .. _sql-adaptation-objects: | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -109,6 +109,13 @@ The module interface respects the standard defined in the |DBAPI|_. | ||||||
|     by the interface.  For `psycopg2` is ``pyformat``.  See also |     by the interface.  For `psycopg2` is ``pyformat``.  See also | ||||||
|     :ref:`query-parameters`. |     :ref:`query-parameters`. | ||||||
| 
 | 
 | ||||||
|  | .. data:: __libpq_version__ | ||||||
|  | 
 | ||||||
|  |    Integer constant reporting the version of the ``libpq`` library this | ||||||
|  |    ``psycopg2`` module was compiled with (in the same format of | ||||||
|  |    `~connection.server_version`).  If this value is lesser than ``90100`` | ||||||
|  |    then you may query the version of the actually loaded library using the | ||||||
|  |    `~psycopg2.extensions.libpq_version()` function. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| .. index:: | .. index:: | ||||||
|  |  | ||||||
|  | @ -57,7 +57,7 @@ from psycopg2._psycopg import IntegrityError, InterfaceError, InternalError | ||||||
| from psycopg2._psycopg import NotSupportedError, OperationalError | from psycopg2._psycopg import NotSupportedError, OperationalError | ||||||
| 
 | 
 | ||||||
| from psycopg2._psycopg import _connect, apilevel, threadsafety, paramstyle | from psycopg2._psycopg import _connect, apilevel, threadsafety, paramstyle | ||||||
| from psycopg2._psycopg import __version__ | from psycopg2._psycopg import __version__, __libpq_version__ | ||||||
| 
 | 
 | ||||||
| from psycopg2 import tz | from psycopg2 import tz | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -56,7 +56,7 @@ try: | ||||||
| except ImportError: | except ImportError: | ||||||
|     pass |     pass | ||||||
| 
 | 
 | ||||||
| from psycopg2._psycopg import adapt, adapters, encodings, connection, cursor, lobject, Xid | from psycopg2._psycopg import adapt, adapters, encodings, connection, cursor, lobject, Xid, libpq_version | ||||||
| from psycopg2._psycopg import string_types, binary_types, new_type, new_array_type, register_type | from psycopg2._psycopg import string_types, binary_types, new_type, new_array_type, register_type | ||||||
| from psycopg2._psycopg import ISQLQuote, Notify, Diagnostics, Column | from psycopg2._psycopg import ISQLQuote, Notify, Diagnostics, Column | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -39,7 +39,7 @@ static unsigned char * | ||||||
| binary_escape(unsigned char *from, size_t from_length, | binary_escape(unsigned char *from, size_t from_length, | ||||||
|                size_t *to_length, PGconn *conn) |                size_t *to_length, PGconn *conn) | ||||||
| { | { | ||||||
| #if PG_VERSION_HEX >= 0x080104 | #if PG_VERSION_NUM >= 80104 | ||||||
|     if (conn) |     if (conn) | ||||||
|         return PQescapeByteaConn(conn, from, from_length, to_length); |         return PQescapeByteaConn(conn, from, from_length, to_length); | ||||||
|     else |     else | ||||||
|  |  | ||||||
|  | @ -474,7 +474,7 @@ lobject_export(lobjectObject *self, const char *filename) | ||||||
|     return retvalue; |     return retvalue; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #if PG_VERSION_HEX >= 0x080300 | #if PG_VERSION_NUM >= 80300 | ||||||
| 
 | 
 | ||||||
| RAISES_NEG int | RAISES_NEG int | ||||||
| lobject_truncate(lobjectObject *self, size_t len) | lobject_truncate(lobjectObject *self, size_t len) | ||||||
|  | @ -511,4 +511,4 @@ lobject_truncate(lobjectObject *self, size_t len) | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif /* PG_VERSION_HEX >= 0x080300 */ | #endif /* PG_VERSION_NUM >= 80300 */ | ||||||
|  |  | ||||||
|  | @ -266,7 +266,7 @@ psyco_lobj_get_closed(lobjectObject *self, void *closure) | ||||||
|     return closed; |     return closed; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #if PG_VERSION_HEX >= 0x080300 | #if PG_VERSION_NUM >= 80300 | ||||||
| 
 | 
 | ||||||
| #define psyco_lobj_truncate_doc \ | #define psyco_lobj_truncate_doc \ | ||||||
| "truncate(len=0) -- Truncate large object to given size." | "truncate(len=0) -- Truncate large object to given size." | ||||||
|  | @ -327,10 +327,10 @@ static struct PyMethodDef lobjectObject_methods[] = { | ||||||
|      METH_NOARGS, psyco_lobj_unlink_doc}, |      METH_NOARGS, psyco_lobj_unlink_doc}, | ||||||
|     {"export",(PyCFunction)psyco_lobj_export, |     {"export",(PyCFunction)psyco_lobj_export, | ||||||
|      METH_VARARGS, psyco_lobj_export_doc}, |      METH_VARARGS, psyco_lobj_export_doc}, | ||||||
| #if PG_VERSION_HEX >= 0x080300 | #if PG_VERSION_NUM >= 80300 | ||||||
|     {"truncate",(PyCFunction)psyco_lobj_truncate, |     {"truncate",(PyCFunction)psyco_lobj_truncate, | ||||||
|      METH_VARARGS, psyco_lobj_truncate_doc}, |      METH_VARARGS, psyco_lobj_truncate_doc}, | ||||||
| #endif /* PG_VERSION_HEX >= 0x080300 */ | #endif /* PG_VERSION_NUM >= 80300 */ | ||||||
|     {NULL} |     {NULL} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -185,7 +185,7 @@ psyco_libcrypto_threads_init(void) | ||||||
|     if (PyImport_ImportModule("ssl") != NULL) { |     if (PyImport_ImportModule("ssl") != NULL) { | ||||||
|         /* disable libcrypto setup in libpq, so it won't stomp on the callbacks
 |         /* disable libcrypto setup in libpq, so it won't stomp on the callbacks
 | ||||||
|            that have already been set up */ |            that have already been set up */ | ||||||
| #if PG_VERSION_HEX >= 0x080400 | #if PG_VERSION_NUM >= 80400 | ||||||
|         PQinitOpenSSL(1, 0); |         PQinitOpenSSL(1, 0); | ||||||
| #endif | #endif | ||||||
|     } |     } | ||||||
|  | @ -300,6 +300,19 @@ exit: | ||||||
|     return rv; |     return rv; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #define psyco_libpq_version_doc "Query actual libpq version loaded." | ||||||
|  | 
 | ||||||
|  | static PyObject* | ||||||
|  | psyco_libpq_version(PyObject *self) | ||||||
|  | { | ||||||
|  | #if PG_VERSION_NUM >= 90100 | ||||||
|  |     return PyInt_FromLong(PQlibVersion()); | ||||||
|  | #else | ||||||
|  |     PyErr_SetString(NotSupportedError, "version discovery is not supported in libpq < 9.1"); | ||||||
|  |     return NULL; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* psyco_encodings_fill
 | /* psyco_encodings_fill
 | ||||||
| 
 | 
 | ||||||
|    Fill the module's postgresql<->python encoding table */ |    Fill the module's postgresql<->python encoding table */ | ||||||
|  | @ -704,6 +717,8 @@ static PyMethodDef psycopgMethods[] = { | ||||||
|      METH_VARARGS|METH_KEYWORDS, typecast_from_python_doc}, |      METH_VARARGS|METH_KEYWORDS, typecast_from_python_doc}, | ||||||
|     {"new_array_type", (PyCFunction)typecast_array_from_python, |     {"new_array_type", (PyCFunction)typecast_array_from_python, | ||||||
|      METH_VARARGS|METH_KEYWORDS, typecast_array_from_python_doc}, |      METH_VARARGS|METH_KEYWORDS, typecast_array_from_python_doc}, | ||||||
|  |     {"libpq_version", (PyCFunction)psyco_libpq_version, | ||||||
|  |      METH_NOARGS, psyco_libpq_version_doc}, | ||||||
| 
 | 
 | ||||||
|     {"Date",  (PyCFunction)psyco_Date, |     {"Date",  (PyCFunction)psyco_Date, | ||||||
|      METH_VARARGS, psyco_Date_doc}, |      METH_VARARGS, psyco_Date_doc}, | ||||||
|  | @ -899,6 +914,7 @@ INIT_MODULE(_psycopg)(void) | ||||||
|     /* set some module's parameters */ |     /* set some module's parameters */ | ||||||
|     PyModule_AddStringConstant(module, "__version__", PSYCOPG_VERSION); |     PyModule_AddStringConstant(module, "__version__", PSYCOPG_VERSION); | ||||||
|     PyModule_AddStringConstant(module, "__doc__", "psycopg PostgreSQL driver"); |     PyModule_AddStringConstant(module, "__doc__", "psycopg PostgreSQL driver"); | ||||||
|  |     PyModule_AddIntConstant(module, "__libpq_version__", PG_VERSION_NUM); | ||||||
|     PyModule_AddObject(module, "apilevel", Text_FromUTF8(APILEVEL)); |     PyModule_AddObject(module, "apilevel", Text_FromUTF8(APILEVEL)); | ||||||
|     PyModule_AddObject(module, "threadsafety", PyInt_FromLong(THREADSAFETY)); |     PyModule_AddObject(module, "threadsafety", PyInt_FromLong(THREADSAFETY)); | ||||||
|     PyModule_AddObject(module, "paramstyle", Text_FromUTF8(PARAMSTYLE)); |     PyModule_AddObject(module, "paramstyle", Text_FromUTF8(PARAMSTYLE)); | ||||||
|  |  | ||||||
|  | @ -62,7 +62,7 @@ psycopg_escape_string(connectionObject *conn, const char *from, Py_ssize_t len, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     { |     { | ||||||
|         #if PG_VERSION_HEX >= 0x080104 |         #if PG_VERSION_NUM >= 80104 | ||||||
|             int err; |             int err; | ||||||
|             if (conn && conn->pgconn) |             if (conn && conn->pgconn) | ||||||
|                 ql = PQescapeStringConn(conn->pgconn, to+eq+1, from, len, &err); |                 ql = PQescapeStringConn(conn->pgconn, to+eq+1, from, len, &err); | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								setup.py
									
									
									
									
									
								
							|  | @ -416,7 +416,7 @@ class psycopg_build_ext(build_ext): | ||||||
|                                                                 % pgversion) |                                                                 % pgversion) | ||||||
|                 sys.exit(1) |                 sys.exit(1) | ||||||
| 
 | 
 | ||||||
|             define_macros.append(("PG_VERSION_HEX", "0x%02X%02X%02X" % |             define_macros.append(("PG_VERSION_NUM", "%d%02d%02d" % | ||||||
|                                   (pgmajor, pgminor, pgpatch))) |                                   (pgmajor, pgminor, pgpatch))) | ||||||
| 
 | 
 | ||||||
|             # enable lo64 if libpq >= 9.3 and Python 64 bits |             # enable lo64 if libpq >= 9.3 and Python 64 bits | ||||||
|  |  | ||||||
|  | @ -320,6 +320,15 @@ import _psycopg | ||||||
|         self.assertEqual(0, proc.returncode) |         self.assertEqual(0, proc.returncode) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class TestVersionDiscovery(unittest.TestCase): | ||||||
|  |     def test_libpq_version(self): | ||||||
|  |         self.assertTrue(type(psycopg2.__libpq_version__) is int) | ||||||
|  |         try: | ||||||
|  |             self.assertTrue(type(psycopg2.extensions.libpq_version()) is int) | ||||||
|  |         except NotSupportedError: | ||||||
|  |             self.assertTrue(psycopg2.__libpq_version__ < 90100) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def test_suite(): | def test_suite(): | ||||||
|     return unittest.TestLoader().loadTestsFromName(__name__) |     return unittest.TestLoader().loadTestsFromName(__name__) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -236,6 +236,43 @@ def skip_after_postgres(*ver): | ||||||
|         return skip_after_postgres__ |         return skip_after_postgres__ | ||||||
|     return skip_after_postgres_ |     return skip_after_postgres_ | ||||||
| 
 | 
 | ||||||
|  | def libpq_version(): | ||||||
|  |     import psycopg2 | ||||||
|  |     v = psycopg2.__libpq_version__ | ||||||
|  |     if v >= 90100: | ||||||
|  |         v = psycopg2.extensions.libpq_version() | ||||||
|  |     return v | ||||||
|  | 
 | ||||||
|  | def skip_before_libpq(*ver): | ||||||
|  |     """Skip a test if libpq we're linked to is older than a certain version.""" | ||||||
|  |     ver = ver + (0,) * (3 - len(ver)) | ||||||
|  |     def skip_before_libpq_(f): | ||||||
|  |         @wraps(f) | ||||||
|  |         def skip_before_libpq__(self): | ||||||
|  |             v = libpq_version() | ||||||
|  |             if v < int("%d%02d%02d" % ver): | ||||||
|  |                 return self.skipTest("skipped because libpq %d" % v) | ||||||
|  |             else: | ||||||
|  |                 return f(self) | ||||||
|  | 
 | ||||||
|  |         return skip_before_libpq__ | ||||||
|  |     return skip_before_libpq_ | ||||||
|  | 
 | ||||||
|  | def skip_after_libpq(*ver): | ||||||
|  |     """Skip a test if libpq we're linked to is newer than a certain version.""" | ||||||
|  |     ver = ver + (0,) * (3 - len(ver)) | ||||||
|  |     def skip_after_libpq_(f): | ||||||
|  |         @wraps(f) | ||||||
|  |         def skip_after_libpq__(self): | ||||||
|  |             v = libpq_version() | ||||||
|  |             if v >= int("%d%02d%02d" % ver): | ||||||
|  |                 return self.skipTest("skipped because libpq %s" % v) | ||||||
|  |             else: | ||||||
|  |                 return f(self) | ||||||
|  | 
 | ||||||
|  |         return skip_after_libpq__ | ||||||
|  |     return skip_after_libpq_ | ||||||
|  | 
 | ||||||
| def skip_before_python(*ver): | def skip_before_python(*ver): | ||||||
|     """Skip a test on Python before a certain version.""" |     """Skip a test on Python before a certain version.""" | ||||||
|     def skip_before_python_(f): |     def skip_before_python_(f): | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user