From ccae5cae34051d6640ec6cbce6d9313778c509d3 Mon Sep 17 00:00:00 2001 From: Federico Di Gregorio Date: Thu, 27 Sep 2018 10:15:40 +0200 Subject: [PATCH 1/3] Expose PGconn* raw pointer on the connection as a PyCapsule --- psycopg/connection_type.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index 6a66d48d..724cf853 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -822,6 +822,19 @@ psyco_conn_deferrable_set(connectionObject *self, PyObject *pyvalue) return 0; } +/* _raw_pgconn - expose PGconn* as a Python capsule */ + +#define psyco_conn__raw_pgconn_doc \ +"Return the internal PGconn* as a Python Capsule." + +static PyObject * +psyco_conn__raw_pgconn_get(connectionObject *self) +{ + EXC_IF_CONN_CLOSED(self); + + return PyCapsule_New(self->pgconn, "psycopg2.connection._raw_pgconn", NULL); +} + /* set_client_encoding method - set client encoding */ @@ -1243,6 +1256,10 @@ static struct PyGetSetDef connectionObject_getsets[] = { (getter)psyco_conn_deferrable_get, (setter)psyco_conn_deferrable_set, psyco_conn_deferrable_doc }, + { "_raw_pgconn", + (getter)psyco_conn__raw_pgconn_get, + NULL, + psyco_conn__raw_pgconn_doc }, {NULL} }; #undef EXCEPTION_GETTER From 81addddaee2c690e925bb8f381e7bcb02ca97687 Mon Sep 17 00:00:00 2001 From: Federico Di Gregorio Date: Sun, 7 Oct 2018 13:54:24 +0200 Subject: [PATCH 2/3] Added connection.get_native_connection() --- doc/src/connection.rst | 16 +++++++++++++++- psycopg/connection_type.c | 16 +++++++--------- tests/test_connection.py | 5 +++++ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/doc/src/connection.rst b/doc/src/connection.rst index 2910f301..545cd727 100644 --- a/doc/src/connection.rst +++ b/doc/src/connection.rst @@ -768,7 +768,7 @@ The ``connection`` class support. - .. rubric:: Methods related to asynchronous support. + .. rubric:: Methods related to asynchronous support .. versionadded:: 2.2.0 @@ -813,6 +813,20 @@ The ``connection`` class Return `!True` if the connection is executing an asynchronous operation. + .. rubric:: Interoperation with other C API modules + + .. method:: get_native_connection() + + Return the internal `PGconn*` wrapped in a PyCapsule object. This is + only useful for passing the `libpq` raw connection associated to this + connection object to other C-level modules that may have a use for it. + + .. seealso:: Python C API `Capsules`__ docs. + + .. __: https://docs.python.org/3.1/c-api/capsule.html + + .. versionadded:: 2.8 + .. testcode:: :hide: diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index 724cf853..635aa306 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -822,17 +822,17 @@ psyco_conn_deferrable_set(connectionObject *self, PyObject *pyvalue) return 0; } -/* _raw_pgconn - expose PGconn* as a Python capsule */ +/* psyco_get_native_connection - expose PGconn* as a Python capsule */ -#define psyco_conn__raw_pgconn_doc \ -"Return the internal PGconn* as a Python Capsule." +#define psyco_get_native_connection_doc \ +"get_native_connection() -- Return the internal PGconn* as a Python Capsule." static PyObject * -psyco_conn__raw_pgconn_get(connectionObject *self) +psyco_get_native_connection(connectionObject *self) { EXC_IF_CONN_CLOSED(self); - return PyCapsule_New(self->pgconn, "psycopg2.connection._raw_pgconn", NULL); + return PyCapsule_New(self->pgconn, "psycopg2.connection.native_connection", NULL); } @@ -1190,6 +1190,8 @@ static struct PyMethodDef connectionObject_methods[] = { METH_NOARGS, psyco_conn_isexecuting_doc}, {"cancel", (PyCFunction)psyco_conn_cancel, METH_NOARGS, psyco_conn_cancel_doc}, + {"get_native_connection", (PyCFunction)psyco_get_native_connection, + METH_NOARGS, psyco_get_native_connection_doc}, {NULL} }; @@ -1256,10 +1258,6 @@ static struct PyGetSetDef connectionObject_getsets[] = { (getter)psyco_conn_deferrable_get, (setter)psyco_conn_deferrable_set, psyco_conn_deferrable_doc }, - { "_raw_pgconn", - (getter)psyco_conn__raw_pgconn_get, - NULL, - psyco_conn__raw_pgconn_doc }, {NULL} }; #undef EXCEPTION_GETTER diff --git a/tests/test_connection.py b/tests/test_connection.py index 1342f9f8..3b8f7750 100755 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -340,6 +340,11 @@ class ConnectionTests(ConnectingTestCase): self.assert_(c.closed, "connection failed so it must be closed") self.assert_('foobar' not in c.dsn, "password was not obscured") + def test_get_native_connection(self): + conn = self.connect() + capsule = conn.get_native_connection() + # we can't do anything else in Python + self.assertIsNotNone(capsule) class ParseDsnTestCase(ConnectingTestCase): def test_parse_dsn(self): From f56392a245e9d6a0b914e86ca799fd0d4178f689 Mon Sep 17 00:00:00 2001 From: Federico Di Gregorio Date: Sun, 7 Oct 2018 13:55:11 +0200 Subject: [PATCH 3/3] Allow SPHINXBUILD on command line --- .gitignore | 1 + doc/Makefile | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 356570ed..4175bb88 100644 --- a/.gitignore +++ b/.gitignore @@ -15,5 +15,6 @@ env env? .idea .tox +.vscode/ /rel /wheels diff --git a/doc/Makefile b/doc/Makefile index 558d0a75..81ec4096 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -10,7 +10,8 @@ check: doctest PYTHON := python$(PYTHON_VERSION) PYTHON_VERSION ?= $(shell $(PYTHON) -c 'import sys; print ("%d.%d" % sys.version_info[:2])') -SPHOPTS=PYTHONPATH=$$(pwd)/../build/lib.$(PYTHON_VERSION)/ SPHINXBUILD=$$(pwd)/env/bin/sphinx-build +SPHINXBUILD ?= $$(pwd)/env/bin/sphinx-build +SPHOPTS = PYTHONPATH=$$(pwd)/../build/lib.$(PYTHON_VERSION)/ SPHINXBUILD=$(SPHINXBUILD) html: $(MAKE) PYTHON=$(PYTHON) -C .. package