[Python-modules-commits] [psycopg2] 01/08: Import psycopg2_2.6.2.orig.tar.gz

Scott Kitterman kitterman at moszumanska.debian.org
Fri Jul 15 21:12:16 UTC 2016


This is an automated email from the git hooks/post-receive script.

kitterman pushed a commit to branch master
in repository psycopg2.

commit 894d88c3aab2afbcec2240f0de6a7cde407315a6
Author: Scott Kitterman <scott at kitterman.com>
Date:   Thu Jul 14 23:12:49 2016 -0400

    Import psycopg2_2.6.2.orig.tar.gz
---
 MANIFEST.in                               |  2 +-
 Makefile                                  |  9 +---
 NEWS                                      | 29 ++++++++++-
 PKG-INFO                                  |  5 +-
 doc/src/advanced.rst                      |  4 +-
 doc/src/conf.py                           |  4 +-
 doc/src/cursor.rst                        |  5 +-
 doc/src/extras.rst                        |  3 ++
 doc/src/faq.rst                           | 31 ++++++++++++
 doc/src/install.rst                       | 24 +++++++++-
 doc/src/usage.rst                         | 10 +++-
 lib/errorcodes.py                         | 14 +++++-
 lib/extras.py                             | 23 +++++----
 lib/pool.py                               |  4 +-
 lib/psycopg1.py                           |  2 +-
 psycopg/adapter_datetime.c                |  2 +-
 psycopg/adapter_qstring.c                 | 80 +++++++++++++++++++++----------
 psycopg/adapter_qstring.h                 |  3 ++
 psycopg/config.h                          | 11 +++--
 psycopg/connection_type.c                 |  2 +-
 psycopg/cursor_type.c                     |  2 +-
 psycopg/pqpath.c                          | 55 ++++++++++++++++-----
 psycopg/psycopgmodule.c                   |  5 +-
 PKG-INFO => psycopg2.egg-info/PKG-INFO    |  5 +-
 MANIFEST => psycopg2.egg-info/SOURCES.txt |  9 ++--
 psycopg2.egg-info/dependency_links.txt    |  1 +
 psycopg2.egg-info/top_level.txt           |  1 +
 scripts/make_errorcodes.py                |  2 +-
 setup.cfg                                 | 34 +++----------
 setup.py                                  | 15 ++++--
 tests/__init__.py                         |  2 +
 tests/test_connection.py                  | 24 ++++++----
 tests/test_cursor.py                      | 77 +++++++++++++++++++++++++----
 tests/test_errcodes.py                    | 65 +++++++++++++++++++++++++
 tests/test_quote.py                       | 65 ++++++++++++++++++++++---
 tests/test_types_basic.py                 | 15 +++---
 tests/testconfig.py                       |  4 +-
 tests/testutils.py                        | 31 ++++++++++--
 38 files changed, 524 insertions(+), 155 deletions(-)

diff --git a/MANIFEST.in b/MANIFEST.in
index 66fc265..0d34fd3 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -8,4 +8,4 @@ recursive-include doc/src *.rst *.py *.css Makefile
 recursive-include scripts *.py *.sh
 include scripts/maketypes.sh scripts/buildtypes.py
 include AUTHORS README.rst INSTALL LICENSE NEWS
-include PKG-INFO MANIFEST.in MANIFEST setup.py setup.cfg Makefile
+include MANIFEST.in setup.py setup.cfg Makefile
diff --git a/Makefile b/Makefile
index 232f0d0..a8f491e 100644
--- a/Makefile
+++ b/Makefile
@@ -92,14 +92,9 @@ $(PACKAGE)/tests/%.py: tests/%.py
 	$(PYTHON) setup.py build_py $(BUILD_OPT)
 	touch $@
 
-$(SDIST): MANIFEST $(SOURCE)
+$(SDIST): $(SOURCE)
 	$(PYTHON) setup.py sdist $(SDIST_OPT)
 
-MANIFEST: MANIFEST.in $(SOURCE)
-	# Run twice as MANIFEST.in includes MANIFEST
-	$(PYTHON) setup.py sdist --manifest-only
-	$(PYTHON) setup.py sdist --manifest-only
-
 # docs depend on the build as it partly use introspection.
 doc/html/genindex.html: $(PLATLIB) $(PURELIB) $(SOURCE_DOC)
 	$(MAKE) -C doc html
@@ -111,5 +106,5 @@ doc/docs.zip: doc/html/genindex.html
 	(cd doc/html && zip -r ../docs.zip *)
 
 clean:
-	rm -rf build MANIFEST
+	rm -rf build
 	$(MAKE) -C doc clean
diff --git a/NEWS b/NEWS
index d2c85d3..415411c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,13 +1,38 @@
 Current release
 ---------------
 
+What's new in psycopg 2.6.2
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Fixed inconsistent state in externally closed connections
+  (:tickets:`#263, #311, #443`).
+- Report the server response status on errors (such as :ticket:`#281`).
+- Raise `!NotSupportedError` on unhandled server response status
+  (:ticket:`#352`).
+- Allow overriding string adapter encoding with no connection (:ticket:`#331`).
+- The `~psycopg2.extras.wait_select` callback allows interrupting a
+  long-running query in an interactive shell using :kbd:`Ctrl-C`
+  (:ticket:`#333`).
+- Fixed `!PersistentConnectionPool` on Python 3 (:ticket:`#348`).
+- Fixed segfault on `repr()` of an unitialized connection (:ticket:`#361`).
+- Allow adapting bytes using `~psycopg2.extensions.QuotedString` on Python 3
+  (:ticket:`#365`).
+- Added support for setuptools/wheel (:ticket:`#370`).
+- Fix build on Windows with Python 3.5, VS 2015 (:ticket:`#380`).
+- Fixed `!errorcodes.lookup` initialization thread-safety (:ticket:`#382`).
+- Fixed `!read()` exception propagation in copy_from (:ticket:`#412`).
+- Fixed possible NULL TZ decref  (:ticket:`#424`).
+- `~psycopg2.errorcodes` map updated to PostgreSQL 9.5.
+
+
 What's new in psycopg 2.6.1
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 - Lists consisting of only `None` are escaped correctly (:ticket:`#285`).
 - Fixed deadlock in multithread programs using OpenSSL (:ticket:`#290`).
 - Correctly unlock the connection after error in flush (:ticket:`#294`).
-- Fixed ``MinTimeLoggingCursor.callproc()`` (:ticket:`#309`).
+- Fixed `!MinTimeLoggingCursor.callproc()` (:ticket:`#309`).
+- Added support for MSVC 2015 compiler (:ticket:`#350`).
 
 
 What's new in psycopg 2.6
@@ -22,7 +47,7 @@ New features:
 
 Bug fixes:
 
-- Json apapter's `!str()` returns the adapted content instead of the `!repr()`
+- Json adapter's `!str()` returns the adapted content instead of the `!repr()`
   (:ticket:`#191`).
 
 
diff --git a/PKG-INFO b/PKG-INFO
index 47ea2c1..ca22902 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: psycopg2
-Version: 2.6.1
+Version: 2.6.2
 Summary: psycopg2 - Python-PostgreSQL Database Adapter
 Home-page: http://initd.org/psycopg/
 Author: Federico Di Gregorio
 Author-email: fog at initd.org
 License: LGPL with exceptions or ZPL
-Download-URL: http://initd.org/psycopg/tarballs/PSYCOPG-2-6/psycopg2-2.6.1.tar.gz
+Download-URL: http://initd.org/psycopg/tarballs/PSYCOPG-2-6/psycopg2-2.6.2.tar.gz
 Description: Psycopg is the most popular PostgreSQL database adapter for the Python
         programming language.  Its main features are the complete implementation of
         the Python DB API 2.0 specification and the thread safety (several threads can
@@ -65,6 +65,7 @@ Classifier: Programming Language :: Python :: 3.1
 Classifier: Programming Language :: Python :: 3.2
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: C
 Classifier: Programming Language :: SQL
 Classifier: Topic :: Database
diff --git a/doc/src/advanced.rst b/doc/src/advanced.rst
index 4756d01..507a0ee 100644
--- a/doc/src/advanced.rst
+++ b/doc/src/advanced.rst
@@ -47,7 +47,7 @@ it is the class where query building, execution and result type-casting into
 Python variables happens.
 
 The `~psycopg2.extras` module contains several examples of :ref:`connection
-and cursor sublcasses <cursor-subclasses>`.
+and cursor subclasses <cursor-subclasses>`.
 
 .. note::
 
@@ -270,7 +270,7 @@ wasting resources.
 
 A simple application could poll the connection from time to time to check if
 something new has arrived. A better strategy is to use some I/O completion
-function such as :py:func:`~select.select` to sleep until awaken from the kernel when there is
+function such as :py:func:`~select.select` to sleep until awakened by the kernel when there is
 some data to read on the connection, thereby using no CPU unless there is
 something to read::
 
diff --git a/doc/src/conf.py b/doc/src/conf.py
index 18b81e0..94ffa34 100644
--- a/doc/src/conf.py
+++ b/doc/src/conf.py
@@ -42,9 +42,7 @@ master_doc = 'index'
 
 # General information about the project.
 project = u'Psycopg'
-from datetime import date
-year = date.today().year
-copyright = u'2001-%s, Federico Di Gregorio, Daniele Varrazzo' % year
+copyright = u'2001-2016, Federico Di Gregorio, Daniele Varrazzo'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
diff --git a/doc/src/cursor.rst b/doc/src/cursor.rst
index 73bb537..45e6278 100644
--- a/doc/src/cursor.rst
+++ b/doc/src/cursor.rst
@@ -494,6 +494,9 @@ The ``cursor`` class
 
     .. rubric:: COPY-related methods
 
+    Efficiently copy data from file-like objects to the database and back. See
+    :ref:`copy` for an overview.
+
     .. extension::
 
         The :sql:`COPY` command is a PostgreSQL extension to the SQL standard.
@@ -502,7 +505,7 @@ The ``cursor`` class
     .. method:: copy_from(file, table, sep='\\t', null='\\\\N', size=8192, columns=None)
 
         Read data *from* the file-like object *file* appending them to
-        the table named *table*.  See :ref:`copy` for an overview.
+        the table named *table*.
 
         :param file: file-like object to read data from.  It must have both
             `!read()` and `!readline()` methods.
diff --git a/doc/src/extras.rst b/doc/src/extras.rst
index 36ef013..0e21ae5 100644
--- a/doc/src/extras.rst
+++ b/doc/src/extras.rst
@@ -611,3 +611,6 @@ Coroutine support
 
 .. autofunction:: wait_select(conn)
 
+    .. versionchanged:: 2.6.2
+        allow to cancel a query using :kbd:`Ctrl-C`, see
+        :ref:`the FAQ <faq-interrupt-query>` for an example.
diff --git a/doc/src/faq.rst b/doc/src/faq.rst
index 8f2f1ec..69273ba 100644
--- a/doc/src/faq.rst
+++ b/doc/src/faq.rst
@@ -223,6 +223,37 @@ What are the advantages or disadvantages of using named cursors?
     little memory on the client and to skip or discard parts of the result set.
 
 
+.. _faq-interrupt-query:
+.. cssclass:: faq
+
+How do I interrupt a long-running query in an interactive shell?
+    Normally the interactive shell becomes unresponsive to :kbd:`Ctrl-C` when
+    running a query. Using a connection in green mode allows Python to
+    receive and handle the interrupt, although it may leave the connection
+    broken, if the async callback doesn't handle the `!KeyboardInterrupt`
+    correctly.
+
+    Starting from psycopg 2.6.2, the `~psycopg2.extras.wait_select` callback
+    can handle a :kbd:`Ctrl-C` correctly. For previous versions, you can use
+    `this implementation`__.
+
+    .. __: http://initd.org/psycopg/articles/2014/07/20/cancelling-postgresql-statements-python/
+
+    .. code-block:: pycon
+
+        >>> psycopg2.extensions.set_wait_callback(psycopg2.extensions.wait_select)
+        >>> cnn = psycopg2.connect('')
+        >>> cur = cnn.cursor()
+        >>> cur.execute("select pg_sleep(10)")
+        ^C
+        Traceback (most recent call last):
+          File "<stdin>", line 1, in <module>
+          QueryCanceledError: canceling statement due to user request
+
+        >>> cnn.rollback()
+        >>> # You can use the connection and cursor again from here
+
+
 .. _faq-compile:
 
 Problems compiling and deploying psycopg2
diff --git a/doc/src/install.rst b/doc/src/install.rst
index ec1eeea..3a95adc 100644
--- a/doc/src/install.rst
+++ b/doc/src/install.rst
@@ -18,7 +18,7 @@ The current `!psycopg2` implementation supports:
     NOTE: keep consistent with setup.py and the /features/ page.
 
 - Python 2 versions from 2.5 to 2.7
-- Python 3 versions from 3.1 to 3.4
+- Python 3 versions from 3.1 to 3.5
 - PostgreSQL versions from 7.4 to 9.4
 
 .. _PostgreSQL: http://www.postgresql.org/
@@ -51,6 +51,16 @@ extension packages, *above all if you are a Windows or a Mac OS user*, please
 use a pre-compiled package and go straight to the :ref:`module usage <usage>`
 avoid bothering with the gory details.
 
+.. note::
+
+    Regardless of the way `!psycopg2` is installed, at runtime it will need to
+    use the libpq_ library. `!psycopg2` relies on the host OS to find the
+    library file (usually ``libpq.so`` or ``libpq.dll``): if the library is
+    installed in a standard location there is usually no problem; if the
+    library is in a non-standard location you will have to tell somehow
+    psycopg how to find it, which is OS-dependent (for instance setting a
+    suitable :envvar:`LD_LIBRARY_PATH` on Linux).
+
 
 
 .. _install-from-package:
@@ -95,7 +105,17 @@ Install from a package
     pair: Install; Windows
 
 **Microsoft Windows**
-    Jason Erickson maintains a packaged `Windows port of Psycopg`__ with
+    There are two options to install a precompiled `psycopg2` package under windows:
+
+    **Option 1:** Using `pip`__ (Included in python 2.7.9+ and python 3.4+)
+    and a binary wheel package.  Launch windows' command prompt (`cmd.exe`)
+    and execute the following command::
+    
+        pip install psycopg2
+
+    .. __: https://pip.pypa.io/en/stable/installing/
+
+    **Option 2:** Jason Erickson maintains a packaged `Windows port of Psycopg`__ with
     installation executable. Download. Double click. Done.
 
     .. __: http://www.stickpeople.com/projects/python/win-psycopg/
diff --git a/doc/src/usage.rst b/doc/src/usage.rst
index 9dd31df..3b42aeb 100644
--- a/doc/src/usage.rst
+++ b/doc/src/usage.rst
@@ -864,11 +864,19 @@ Using COPY TO and COPY FROM
 
 Psycopg `cursor` objects provide an interface to the efficient
 PostgreSQL |COPY|__ command to move data from files to tables and back.
+
+Currently no adaptation is provided between Python and PostgreSQL types on
+|COPY|: the file can be any Python file-like object but its format must be in
+the format accepted by `PostgreSQL COPY command`__ (data fromat, escaped
+characters, etc).
+
+.. __: COPY_
+
 The methods exposed are:
 
 `~cursor.copy_from()`
     Reads data *from* a file-like object appending them to a database table
-    (:sql:`COPY table FROM file` syntax). The source file must have both
+    (:sql:`COPY table FROM file` syntax). The source file must provide both
     `!read()` and `!readline()` method.
 
 `~cursor.copy_to()`
diff --git a/lib/errorcodes.py b/lib/errorcodes.py
index 12c300f..60181c1 100644
--- a/lib/errorcodes.py
+++ b/lib/errorcodes.py
@@ -38,11 +38,17 @@ def lookup(code, _cache={}):
         return _cache[code]
 
     # Generate the lookup map at first usage.
+    tmp = {}
     for k, v in globals().iteritems():
         if isinstance(v, str) and len(v) in (2, 5):
-            _cache[v] = k
+            tmp[v] = k
 
-    return lookup(code)
+    assert tmp
+
+    # Atomic update, to avoid race condition on import (bug #382)
+    _cache.update(tmp)
+
+    return _cache[code]
 
 
 # autogenerated data: do not edit below this point.
@@ -193,6 +199,8 @@ INVALID_ESCAPE_SEQUENCE = '22025'
 STRING_DATA_LENGTH_MISMATCH = '22026'
 TRIM_ERROR = '22027'
 ARRAY_SUBSCRIPT_ERROR = '2202E'
+INVALID_TABLESAMPLE_REPEAT = '2202G'
+INVALID_TABLESAMPLE_ARGUMENT = '2202H'
 FLOATING_POINT_EXCEPTION = '22P01'
 INVALID_TEXT_REPRESENTATION = '22P02'
 INVALID_BINARY_REPRESENTATION = '22P03'
@@ -265,6 +273,7 @@ INVALID_SQLSTATE_RETURNED = '39001'
 NULL_VALUE_NOT_ALLOWED = '39004'
 TRIGGER_PROTOCOL_VIOLATED = '39P01'
 SRF_PROTOCOL_VIOLATED = '39P02'
+EVENT_TRIGGER_PROTOCOL_VIOLATED = '39P03'
 
 # Class 3B - Savepoint Exception
 SAVEPOINT_EXCEPTION = '3B000'
@@ -402,6 +411,7 @@ PLPGSQL_ERROR = 'P0000'
 RAISE_EXCEPTION = 'P0001'
 NO_DATA_FOUND = 'P0002'
 TOO_MANY_ROWS = 'P0003'
+ASSERT_FAILURE = 'P0004'
 
 # Class XX - Internal Error
 INTERNAL_ERROR = 'XX000'
diff --git a/lib/extras.py b/lib/extras.py
index c9f1cbc..2713d6f 100644
--- a/lib/extras.py
+++ b/lib/extras.py
@@ -575,15 +575,20 @@ def wait_select(conn):
     from psycopg2.extensions import POLL_OK, POLL_READ, POLL_WRITE
 
     while 1:
-        state = conn.poll()
-        if state == POLL_OK:
-            break
-        elif state == POLL_READ:
-            select.select([conn.fileno()], [], [])
-        elif state == POLL_WRITE:
-            select.select([], [conn.fileno()], [])
-        else:
-            raise conn.OperationalError("bad state from poll: %s" % state)
+        try:
+            state = conn.poll()
+            if state == POLL_OK:
+                break
+            elif state == POLL_READ:
+                select.select([conn.fileno()], [], [])
+            elif state == POLL_WRITE:
+                select.select([], [conn.fileno()], [])
+            else:
+                raise conn.OperationalError("bad state from poll: %s" % state)
+        except KeyboardInterrupt:
+            conn.cancel()
+            # the loop will be broken by a server error
+            continue
 
 
 def _solve_conn_curs(conn_or_curs):
diff --git a/lib/pool.py b/lib/pool.py
index 4f858ab..8d7c4af 100644
--- a/lib/pool.py
+++ b/lib/pool.py
@@ -204,8 +204,8 @@ class PersistentConnectionPool(AbstractConnectionPool):
 
         # we we'll need the thread module, to determine thread ids, so we
         # import it here and copy it in an instance variable
-        import thread
-        self.__thread = thread
+        import thread as _thread # work around for 2to3 bug - see ticket #348
+        self.__thread = _thread
 
     def getconn(self):
         """Generate thread id and return a connection."""
diff --git a/lib/psycopg1.py b/lib/psycopg1.py
index 7a24c5f..95b36bf 100644
--- a/lib/psycopg1.py
+++ b/lib/psycopg1.py
@@ -28,7 +28,7 @@ old code while porting to psycopg 2. Import it as follows::
 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 # License for more details.
 
-import _psycopg as _2psycopg
+import psycopg2._psycopg as _2psycopg
 from psycopg2.extensions import cursor as _2cursor
 from psycopg2.extensions import connection as _2connection
 
diff --git a/psycopg/adapter_datetime.c b/psycopg/adapter_datetime.c
index 0571837..9d04df4 100644
--- a/psycopg/adapter_datetime.c
+++ b/psycopg/adapter_datetime.c
@@ -451,7 +451,7 @@ psyco_TimestampFromTicks(PyObject *self, PyObject *args)
         tz);
 
 exit:
-    Py_DECREF(tz);
+    Py_XDECREF(tz);
     Py_XDECREF(m);
     return res;
 }
diff --git a/psycopg/adapter_qstring.c b/psycopg/adapter_qstring.c
index 2e3ab0a..8c5a8f1 100644
--- a/psycopg/adapter_qstring.c
+++ b/psycopg/adapter_qstring.c
@@ -36,44 +36,56 @@ static const char *default_encoding = "latin1";
 
 /* qstring_quote - do the quote process on plain and unicode strings */
 
+const char *
+_qstring_get_encoding(qstringObject *self)
+{
+    /* if the wrapped object is an unicode object we can encode it to match
+       conn->encoding but if the encoding is not specified we don't know what
+       to do and we raise an exception */
+    if (self->conn) {
+        return self->conn->codec;
+    }
+    else {
+        return self->encoding ? self->encoding : default_encoding;
+    }
+}
+
 static PyObject *
 qstring_quote(qstringObject *self)
 {
     PyObject *str = NULL;
     char *s, *buffer = NULL;
     Py_ssize_t len, qlen;
-    const char *encoding = default_encoding;
+    const char *encoding;
     PyObject *rv = NULL;
 
-    /* if the wrapped object is an unicode object we can encode it to match
-       conn->encoding but if the encoding is not specified we don't know what
-       to do and we raise an exception */
-    if (self->conn) {
-        encoding = self->conn->codec;
-    }
-
+    encoding = _qstring_get_encoding(self);
     Dprintf("qstring_quote: encoding to %s", encoding);
 
-    if (PyUnicode_Check(self->wrapped) && encoding) {
-        str = PyUnicode_AsEncodedString(self->wrapped, encoding, NULL);
-        Dprintf("qstring_quote: got encoded object at %p", str);
-        if (str == NULL) goto exit;
+    if (PyUnicode_Check(self->wrapped)) {
+        if (encoding) {
+            str = PyUnicode_AsEncodedString(self->wrapped, encoding, NULL);
+            Dprintf("qstring_quote: got encoded object at %p", str);
+            if (str == NULL) goto exit;
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                "missing encoding to encode unicode object");
+            goto exit;
+        }
     }
 
-#if PY_MAJOR_VERSION < 3
-    /* if the wrapped object is a simple string, we don't know how to
+    /* if the wrapped object is a binary string, we don't know how to
        (re)encode it, so we pass it as-is */
-    else if (PyString_Check(self->wrapped)) {
+    else if (Bytes_Check(self->wrapped)) {
         str = self->wrapped;
         /* INCREF to make it ref-wise identical to unicode one */
         Py_INCREF(str);
     }
-#endif
 
     /* if the wrapped object is not a string, this is an error */
     else {
-        PyErr_SetString(PyExc_TypeError,
-                        "can't quote non-string object (or missing encoding)");
+        PyErr_SetString(PyExc_TypeError, "can't quote non-string object");
         goto exit;
     }
 
@@ -150,13 +162,32 @@ qstring_conform(qstringObject *self, PyObject *args)
 static PyObject *
 qstring_get_encoding(qstringObject *self)
 {
-    const char *encoding = default_encoding;
+    const char *encoding;
+    encoding = _qstring_get_encoding(self);
+    return Text_FromUTF8(encoding);
+}
 
-    if (self->conn) {
-        encoding = self->conn->codec;
-    }
+static int
+qstring_set_encoding(qstringObject *self, PyObject *pyenc)
+{
+    int rv = -1;
+    const char *tmp;
+    char *cenc;
 
-    return Text_FromUTF8(encoding);
+    /* get a C copy of the encoding (which may come from unicode) */
+    Py_INCREF(pyenc);
+    if (!(pyenc = psycopg_ensure_bytes(pyenc))) { goto exit; }
+    if (!(tmp = Bytes_AsString(pyenc))) { goto exit; }
+    if (0 > psycopg_strdup(&cenc, tmp, 0)) { goto exit; }
+
+    Dprintf("qstring_set_encoding: encoding set to %s", cenc);
+    PyMem_Free((void *)self->encoding);
+    self->encoding = cenc;
+    rv = 0;
+
+exit:
+    Py_XDECREF(pyenc);
+    return rv;
 }
 
 /** the QuotedString object **/
@@ -183,7 +214,7 @@ static PyMethodDef qstringObject_methods[] = {
 static PyGetSetDef qstringObject_getsets[] = {
     { "encoding",
         (getter)qstring_get_encoding,
-        (setter)NULL,
+        (setter)qstring_set_encoding,
         "current encoding of the adapter" },
     {NULL}
 };
@@ -216,6 +247,7 @@ qstring_dealloc(PyObject* obj)
     Py_CLEAR(self->wrapped);
     Py_CLEAR(self->buffer);
     Py_CLEAR(self->conn);
+    PyMem_Free((void *)self->encoding);
 
     Dprintf("qstring_dealloc: deleted qstring object at %p, refcnt = "
         FORMAT_CODE_PY_SSIZE_T,
diff --git a/psycopg/adapter_qstring.h b/psycopg/adapter_qstring.h
index b7b086f..8abdc5f 100644
--- a/psycopg/adapter_qstring.h
+++ b/psycopg/adapter_qstring.h
@@ -39,6 +39,9 @@ typedef struct {
     PyObject *buffer;
 
     connectionObject *conn;
+
+    const char *encoding;
+
 } qstringObject;
 
 #ifdef __cplusplus
diff --git a/psycopg/config.h b/psycopg/config.h
index b6cd419..f8e17a9 100644
--- a/psycopg/config.h
+++ b/psycopg/config.h
@@ -129,28 +129,33 @@ static int pthread_mutex_init(pthread_mutex_t *mutex, void* fake)
 /* remove the inline keyword, since it doesn't work unless C++ file */
 #define inline
 
-/* Hmmm, MSVC doesn't have a isnan/isinf function, but has _isnan function */
+/* Hmmm, MSVC <2015 doesn't have a isnan/isinf function, but has _isnan function */
 #if defined (_MSC_VER)
+#if !defined(isnan)
 #define isnan(x) (_isnan(x))
 /* The following line was hacked together from simliar code by Bjorn Reese
  * in libxml2 code */
 #define isinf(x) ((_fpclass(x) == _FPCLASS_PINF) ? 1 \
 	: ((_fpclass(x) == _FPCLASS_NINF) ? -1 : 0))
-
+#endif
 #define strcasecmp(x, y) lstrcmpi(x, y)
 #endif
 #endif
 
+/* what's this, we have no round function either? */
 #if (defined(__FreeBSD__) && __FreeBSD_version < 503000) \
     || (defined(_WIN32) && !defined(__GNUC__)) \
     || (defined(sun) || defined(__sun__)) \
         && (defined(__SunOS_5_8) || defined(__SunOS_5_9))
-/* what's this, we have no round function either? */
+
+/* round has been added in the standard library with MSVC 2015 */
+#if _MSC_VER < 1900
 static double round(double num)
 {
   return (num >= 0) ? floor(num + 0.5) : ceil(num - 0.5);
 }
 #endif
+#endif
 
 /* resolve missing isinf() function for Solaris */
 #if defined (__SVR4) && defined (__sun)
diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c
index 43abe8a..ed49911 100644
--- a/psycopg/connection_type.c
+++ b/psycopg/connection_type.c
@@ -1172,7 +1172,7 @@ connection_repr(connectionObject *self)
 {
     return PyString_FromFormat(
         "<connection object at %p; dsn: '%s', closed: %ld>",
-        self, self->dsn, self->closed);
+        self, (self->dsn ? self->dsn : "<unintialized>"), self->closed);
 }
 
 static int
diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c
index cd8d5ca..fe79bbf 100644
--- a/psycopg/cursor_type.c
+++ b/psycopg/cursor_type.c
@@ -335,7 +335,7 @@ _psyco_curs_merge_query_args(cursorObject *self,
         PyErr_Fetch(&err, &arg, &trace);
 
         if (err && PyErr_GivenExceptionMatches(err, PyExc_TypeError)) {
-            Dprintf("psyco_curs_execute: TypeError exception catched");
+            Dprintf("psyco_curs_execute: TypeError exception caught");
             PyErr_NormalizeException(&err, &arg, &trace);
 
             if (PyObject_HasAttrString(arg, "args")) {
diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c
index 5e1974b..26c1e0b 100644
--- a/psycopg/pqpath.c
+++ b/psycopg/pqpath.c
@@ -161,14 +161,16 @@ pq_raise(connectionObject *conn, cursorObject *curs, PGresult **pgres)
 
     if (conn == NULL) {
         PyErr_SetString(DatabaseError,
-            "psycopg went psycotic and raised a null error");
+            "psycopg went psychotic and raised a null error");
         return;
     }
 
-    /* if the connection has somehow beed broken, we mark the connection
+    /* if the connection has somehow been broken, we mark the connection
        object as closed but requiring cleanup */
-    if (conn->pgconn != NULL && PQstatus(conn->pgconn) == CONNECTION_BAD)
+    if (conn->pgconn != NULL && PQstatus(conn->pgconn) == CONNECTION_BAD) {
         conn->closed = 2;
+        exc = OperationalError;
+    }
 
     if (pgres == NULL && curs != NULL)
         pgres = &curs->pgres;
@@ -190,8 +192,10 @@ pq_raise(connectionObject *conn, cursorObject *curs, PGresult **pgres)
        raise and a meaningful message is better than an empty one.
        Note: it can happen without it being our error: see ticket #82 */
     if (err == NULL || err[0] == '\0') {
-        PyErr_SetString(DatabaseError,
-            "error with no message from the libpq");
+        PyErr_Format(DatabaseError,
+            "error with status %s and no message from the libpq",
+            PQresStatus(pgres == NULL ?
+                PQstatus(conn->pgconn) : PQresultStatus(*pgres)));
         return;
     }
 
@@ -200,9 +204,9 @@ pq_raise(connectionObject *conn, cursorObject *curs, PGresult **pgres)
     if (code != NULL) {
         exc = exception_from_sqlstate(code);
     }
-    else {
-        /* Fallback if there is no exception code (reported happening e.g.
-         * when the connection is closed). */
+    else if (exc == NULL) {
+        /* Fallback if there is no exception code (unless we already
+           determined that the connection was closed). */
         exc = DatabaseError;
     }
 
@@ -905,7 +909,7 @@ pq_execute(cursorObject *curs, const char *query, int async, int no_result, int
         PyErr_SetString(OperationalError, PQerrorMessage(curs->conn->pgconn));
         return -1;
     }
-    Dprintf("curs_execute: pg connection at %p OK", curs->conn->pgconn);
+    Dprintf("pq_execute: pg connection at %p OK", curs->conn->pgconn);
 
     Py_BEGIN_ALLOW_THREADS;
     pthread_mutex_lock(&(curs->conn->lock));
@@ -930,8 +934,11 @@ pq_execute(cursorObject *curs, const char *query, int async, int no_result, int
             Py_UNBLOCK_THREADS;
         }
 
-        /* dont let pgres = NULL go to pq_fetch() */
+        /* don't let pgres = NULL go to pq_fetch() */
         if (curs->pgres == NULL) {
+            if (CONNECTION_BAD == PQstatus(curs->conn->pgconn)) {
+                curs->conn->closed = 2;
+            }
             pthread_mutex_unlock(&(curs->conn->lock));
             Py_BLOCK_THREADS;
             if (!PyErr_Occurred()) {
@@ -959,6 +966,9 @@ pq_execute(cursorObject *curs, const char *query, int async, int no_result, int
 
         CLEARPGRES(curs->pgres);
         if (PQsendQuery(curs->conn->pgconn, query) == 0) {
+            if (CONNECTION_BAD == PQstatus(curs->conn->pgconn)) {
+                curs->conn->closed = 2;
+            }
             pthread_mutex_unlock(&(curs->conn->lock));
             Py_BLOCK_THREADS;
             PyErr_SetString(OperationalError,
@@ -1391,7 +1401,11 @@ _pq_copy_in_v3(cursorObject *curs)
                     Py_DECREF(str);
                 }
             }
-            PyErr_Restore(t, ex, tb);
+            /* Clear the Py exception: it will be re-raised from the libpq */
+            Py_XDECREF(t);
+            Py_XDECREF(ex);
+            Py_XDECREF(tb);
+            PyErr_Clear();
         }
         res = PQputCopyEnd(curs->conn->pgconn, buf);
     }
@@ -1595,11 +1609,26 @@ pq_fetch(cursorObject *curs, int no_result)
         ex = -1;
         break;
 
-    default:
-        Dprintf("pq_fetch: uh-oh, something FAILED: pgconn = %p", curs->conn);
+    case PGRES_BAD_RESPONSE:
+    case PGRES_NONFATAL_ERROR:
+    case PGRES_FATAL_ERROR:
+        Dprintf("pq_fetch: uh-oh, something FAILED: status = %d pgconn = %p",
+            pgstatus, curs->conn);
         pq_raise(curs->conn, curs, NULL);
         ex = -1;
         break;
+
+    default:
+        /* PGRES_COPY_BOTH, PGRES_SINGLE_TUPLE, future statuses */
+        Dprintf("pq_fetch: got unsupported result: status = %d pgconn = %p",
+            pgstatus, curs->conn);
+        PyErr_Format(NotSupportedError,
+            "got server response with unsupported status %s",
+            PQresStatus(curs->pgres == NULL ?
+                PQstatus(curs->conn->pgconn) : PQresultStatus(curs->pgres)));
+        CLEARPGRES(curs->pgres);
+        ex = -1;
+        break;
     }
 
     /* error checking, close the connection if necessary (some critical errors
diff --git a/psycopg/psycopgmodule.c b/psycopg/psycopgmodule.c
index 61e2de5..be6e334 100644
--- a/psycopg/psycopgmodule.c
+++ b/psycopg/psycopgmodule.c
@@ -181,13 +181,16 @@ psyco_register_type(PyObject *self, PyObject *args)
 static void
 psyco_libcrypto_threads_init(void)
 {
+    PyObject *m;
+
     /* importing the ssl module sets up Python's libcrypto callbacks */
-    if (PyImport_ImportModule("ssl") != NULL) {
+    if ((m = PyImport_ImportModule("ssl"))) {
         /* disable libcrypto setup in libpq, so it won't stomp on the callbacks
            that have already been set up */
 #if PG_VERSION_HEX >= 0x080400
         PQinitOpenSSL(1, 0);
 #endif
+        Py_DECREF(m);
     }
     else {
         /* might mean that Python has been compiled without OpenSSL support,
diff --git a/PKG-INFO b/psycopg2.egg-info/PKG-INFO
similarity index 97%
copy from PKG-INFO
copy to psycopg2.egg-info/PKG-INFO
index 47ea2c1..ca22902 100644
--- a/PKG-INFO
+++ b/psycopg2.egg-info/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: psycopg2
-Version: 2.6.1
+Version: 2.6.2
 Summary: psycopg2 - Python-PostgreSQL Database Adapter
 Home-page: http://initd.org/psycopg/
 Author: Federico Di Gregorio
 Author-email: fog at initd.org
 License: LGPL with exceptions or ZPL
-Download-URL: http://initd.org/psycopg/tarballs/PSYCOPG-2-6/psycopg2-2.6.1.tar.gz
+Download-URL: http://initd.org/psycopg/tarballs/PSYCOPG-2-6/psycopg2-2.6.2.tar.gz
 Description: Psycopg is the most popular PostgreSQL database adapter for the Python
         programming language.  Its main features are the complete implementation of
         the Python DB API 2.0 specification and the thread safety (several threads can
@@ -65,6 +65,7 @@ Classifier: Programming Language :: Python :: 3.1
 Classifier: Programming Language :: Python :: 3.2
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: C
 Classifier: Programming Language :: SQL
 Classifier: Topic :: Database
diff --git a/MANIFEST b/psycopg2.egg-info/SOURCES.txt
similarity index 95%
rename from MANIFEST
rename to psycopg2.egg-info/SOURCES.txt
index a9dd624..6bf01f2 100644
--- a/MANIFEST
+++ b/psycopg2.egg-info/SOURCES.txt
@@ -1,8 +1,6 @@
-# file GENERATED by distutils, do NOT edit
 AUTHORS
 INSTALL
 LICENSE
-MANIFEST
 MANIFEST.in
 Makefile
 NEWS
@@ -130,6 +128,10 @@ psycopg/typecast_mxdatetime.c
 psycopg/utils.c
 psycopg/xid.h
 psycopg/xid_type.c
+psycopg2.egg-info/PKG-INFO
+psycopg2.egg-info/SOURCES.txt
+psycopg2.egg-info/dependency_links.txt
+psycopg2.egg-info/top_level.txt
 scripts/buildtypes.py
 scripts/fix_b.py
 scripts/make_errorcodes.py
@@ -148,6 +150,7 @@ tests/test_connection.py
 tests/test_copy.py
 tests/test_cursor.py
 tests/test_dates.py
+tests/test_errcodes.py
 tests/test_extras_dictcursor.py
 tests/test_green.py
 tests/test_lobject.py
@@ -160,4 +163,4 @@ tests/test_types_basic.py
 tests/test_types_extras.py
 tests/test_with.py
 tests/testconfig.py
-tests/testutils.py
+tests/testutils.py
\ No newline at end of file
diff --git a/psycopg2.egg-info/dependency_links.txt b/psycopg2.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/psycopg2.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/psycopg2.egg-info/top_level.txt b/psycopg2.egg-info/top_level.txt
new file mode 100644
index 0000000..658130b
--- /dev/null
+++ b/psycopg2.egg-info/top_level.txt
@@ -0,0 +1 @@
+psycopg2
diff --git a/scripts/make_errorcodes.py b/scripts/make_errorcodes.py
index 122e0d5..58d05b8 100755
--- a/scripts/make_errorcodes.py
+++ b/scripts/make_errorcodes.py
@@ -33,7 +33,7 @@ def main():
     file_start = read_base_file(filename)
     # If you add a version to the list fix the docs (errorcodes.rst, err.rst)
     classes, errors = fetch_errors(
-        ['8.1', '8.2', '8.3', '8.4', '9.0', '9.1', '9.2', '9.3', '9.4'])
+        ['8.1', '8.2', '8.3', '8.4', '9.0', '9.1', '9.2', '9.3', '9.4', '9.5'])
 
     f = open(filename, "w")
     for line in file_start:
diff --git a/setup.cfg b/setup.cfg
index 90a47dd..d00ce92 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,30 +1,10 @@
 [build_ext]
-define=
+define = 
+use_pydatetime = 1
+have_ssl = 0
 
-# PSYCOPG_DISPLAY_SIZE enable display size calculation (a little slower)
-# HAVE_PQFREEMEM should be defined on PostgreSQL >= 7.4
-# PSYCOPG_DEBUG can be added to enable verbose debug information
+[egg_info]
+tag_build = 
+tag_date = 0
+tag_svn_revision = 0
 
-# "pg_config" is required to locate PostgreSQL headers and libraries needed to
-# build psycopg2. If pg_config is not in the path or is installed under a
-# different name uncomment the following option and set it to the pg_config
-# full path.
-#pg_config=
-
-# Set to 1 to use Python datetime objects for default date/time representation.
-use_pydatetime=1
-
-# If the build system does not find the mx.DateTime headers, try
-# uncommenting the following line and setting its value to the right path.
-#mx_include_dir=
-
-# For Windows only:
-# Set to 1 if the PostgreSQL library was built with OpenSSL.
-# Required to link in OpenSSL libraries and dependencies.
-have_ssl=0
-
-# Statically link against the postgresql client library.
-#static_libpq=1
-
-# Add here eventual extra libraries required to link the module.
-#libraries=
diff --git a/setup.py b/setup.py
index 975fe10..d71d489 100644
--- a/setup.py
+++ b/setup.py
@@ -41,6 +41,7 @@ Programming Language :: Python :: 3.1
 Programming Language :: Python :: 3.2
 Programming Language :: Python :: 3.3
 Programming Language :: Python :: 3.4
+Programming Language :: Python :: 3.5
 Programming Language :: C
 Programming Language :: SQL
 Topic :: Database
@@ -57,7 +58,10 @@ import os
 import sys
 import re
 import subprocess
-from distutils.core import setup, Extension
+try:
+    from setuptools import setup, Extension
+except ImportError:
+    from distutils.core import setup, Extension
 from distutils.command.build_ext import build_ext
 from distutils.sysconfig import get_python_inc
 from distutils.ccompiler import get_default_compiler
... 587 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/psycopg2.git



More information about the Python-modules-commits mailing list