Hello community,

here is the log from the commit of package python3-psycopg2 for 
openSUSE:Factory checked in at 2015-06-16 14:05:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python3-psycopg2 (Old)
 and      /work/SRC/openSUSE:Factory/.python3-psycopg2.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python3-psycopg2"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python3-psycopg2/python3-psycopg2.changes        
2015-02-11 16:45:01.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python3-psycopg2.new/python3-psycopg2.changes   
2015-06-16 14:06:00.000000000 +0200
@@ -1,0 +2,12 @@
+Tue Jun 16 04:06:47 UTC 2015 - a...@gmx.de
+
+- update to version 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`).
+
+-------------------------------------------------------------------

Old:
----
  psycopg2-2.6.tar.gz

New:
----
  psycopg2-2.6.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python3-psycopg2.spec ++++++
--- /var/tmp/diff_new_pack.8lArY0/_old  2015-06-16 14:06:01.000000000 +0200
+++ /var/tmp/diff_new_pack.8lArY0/_new  2015-06-16 14:06:01.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           python3-psycopg2
-Version:        2.6
+Version:        2.6.1
 Release:        0
 Summary:        Python-PostgreSQL Database Adapter
 License:        SUSE-LGPL-3.0-with-openssl-exception and 
(SUSE-LGPL-3.0-with-openssl-exception or ZPL-2.0)

++++++ psycopg2-2.6.tar.gz -> psycopg2-2.6.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/MANIFEST new/psycopg2-2.6.1/MANIFEST
--- old/psycopg2-2.6/MANIFEST   2015-02-09 11:02:19.000000000 +0100
+++ new/psycopg2-2.6.1/MANIFEST 2015-06-15 11:50:31.000000000 +0200
@@ -10,9 +10,11 @@
 setup.cfg
 setup.py
 doc/COPYING.LESSER
-doc/README
+doc/Makefile
+doc/README.rst
 doc/SUCCESS
 doc/pep-0249.txt
+doc/requirements.txt
 doc/src/Makefile
 doc/src/advanced.rst
 doc/src/conf.py
@@ -30,6 +32,7 @@
 doc/src/tz.rst
 doc/src/usage.rst
 doc/src/_static/psycopg.css
+doc/src/tools/pypi_docs_upload.py
 doc/src/tools/stitch_text.py
 doc/src/tools/lib/dbapi_extension.py
 doc/src/tools/lib/sql_role.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/MANIFEST.in 
new/psycopg2-2.6.1/MANIFEST.in
--- old/psycopg2-2.6/MANIFEST.in        2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/MANIFEST.in      2015-06-15 11:48:36.000000000 +0200
@@ -2,7 +2,8 @@
 recursive-include lib *.py
 recursive-include tests *.py
 recursive-include examples *.py somehackers.jpg whereareyou.jpg
-recursive-include doc README SUCCESS COPYING.LESSER pep-0249.txt
+include doc/README.rst doc/SUCCESS doc/COPYING.LESSER doc/pep-0249.txt
+include doc/Makefile doc/requirements.txt
 recursive-include doc/src *.rst *.py *.css Makefile
 recursive-include scripts *.py *.sh
 include scripts/maketypes.sh scripts/buildtypes.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/Makefile new/psycopg2-2.6.1/Makefile
--- old/psycopg2-2.6/Makefile   2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/Makefile 2015-06-15 11:48:36.000000000 +0200
@@ -102,10 +102,10 @@
 
 # docs depend on the build as it partly use introspection.
 doc/html/genindex.html: $(PLATLIB) $(PURELIB) $(SOURCE_DOC)
-       PYTHONPATH=:$(BUILD_DIR):$$PYTHONPATH $(MAKE) -C doc html
+       $(MAKE) -C doc html
 
 doc/psycopg2.txt: $(PLATLIB) $(PURELIB) $(SOURCE_DOC)
-       PYTHONPATH=$(BUILD_DIR):$$PYTHONPATH $(MAKE) -C doc text
+       $(MAKE) -C doc text
 
 doc/docs.zip: doc/html/genindex.html
        (cd doc/html && zip -r ../docs.zip *)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/NEWS new/psycopg2-2.6.1/NEWS
--- old/psycopg2-2.6/NEWS       2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/NEWS     2015-06-15 11:48:36.000000000 +0200
@@ -1,6 +1,15 @@
 Current release
 ---------------
 
+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`).
+
+
 What's new in psycopg 2.6
 -------------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/PKG-INFO new/psycopg2-2.6.1/PKG-INFO
--- old/psycopg2-2.6/PKG-INFO   2015-02-09 11:02:19.000000000 +0100
+++ new/psycopg2-2.6.1/PKG-INFO 2015-06-15 11:50:31.000000000 +0200
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: psycopg2
-Version: 2.6
+Version: 2.6.1
 Summary: psycopg2 - Python-PostgreSQL Database Adapter
 Home-page: http://initd.org/psycopg/
 Author: Federico Di Gregorio
 Author-email: f...@initd.org
 License: LGPL with exceptions or ZPL
-Download-URL: http://initd.org/psycopg/tarballs/PSYCOPG-2-6/psycopg2-2.6.tar.gz
+Download-URL: 
http://initd.org/psycopg/tarballs/PSYCOPG-2-6/psycopg2-2.6.1.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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/doc/Makefile 
new/psycopg2-2.6.1/doc/Makefile
--- old/psycopg2-2.6/doc/Makefile       1970-01-01 01:00:00.000000000 +0100
+++ new/psycopg2-2.6.1/doc/Makefile     2015-06-15 11:48:36.000000000 +0200
@@ -0,0 +1,41 @@
+.PHONY: env help clean html text doctest
+
+docs: html text
+
+check: doctest
+
+# The environment is currently required to build the documentation.
+# It is not clean by 'make clean'
+
+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
+
+html:
+       $(MAKE) PYTHON=$(PYTHON) -C .. package
+       $(MAKE) $(SPHOPTS) -C src $@
+       cp -r src/_build/html .
+
+text:
+       $(MAKE) PYTHON=$(PYTHON) -C .. package
+       $(MAKE) $(SPHOPTS) -C src $@
+       cd src && tools/stitch_text.py index.rst _build/text > ../psycopg2.txt
+
+doctest:
+       $(MAKE) PYTHON=$(PYTHON) -C .. package
+       $(MAKE) $(SPHOPTS) -C src $@
+
+upload:
+       # this command requires ssh configured to the proper target
+       tar czf - -C html . | ssh psycoweb tar xzvf - -C docs/current
+       # this command requires a .pypirc with the right privileges
+       python src/tools/pypi_docs_upload.py psycopg2 $$(pwd)/html
+
+clean:
+       $(MAKE) $(SPHOPTS) -C src $@
+       rm -rf html psycopg2.txt
+
+env: requirements.txt
+       virtualenv env
+       ./env/bin/pip install -r requirements.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/doc/README new/psycopg2-2.6.1/doc/README
--- old/psycopg2-2.6/doc/README 2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/doc/README       1970-01-01 01:00:00.000000000 +0100
@@ -1,42 +0,0 @@
-How to build psycopg documentation
-----------------------------------
-
-- Install Sphinx, maybe in a virtualenv. Tested with Sphinx 0.6.4::
-
-    ~$ virtualenv pd
-    New python executable in pd/bin/python
-    Installing setuptools............done.
-    ~$ cd pd
-    ~/pd$ source bin/activate
-    (pd)~/pd$ 
-
-- Install Sphinx in the env::
-
-    (pd)~/pd$ easy_install sphinx
-    Searching for sphinx
-    Reading http://pypi.python.org/simple/sphinx/
-    Reading http://sphinx.pocoo.org/
-    Best match: Sphinx 0.6.4
-    ...
-    Finished processing dependencies for sphinx
-
-- Build psycopg2 and ensure the package can be imported (it will be used for
-  reading the version number, autodocs etc.)::
-
-    (pd)~/pd/psycopg2$ python setup.py build
-    (pd)~/pd/psycopg2$ python setup.py install
-    running install
-    ...
-    creating ~/pd/lib/python2.6/site-packages/psycopg2
-    ...
-
-- Move to the ``doc`` dir and run ``make`` from there::
-
-    (pd)~/pd/psycopg2$ cd doc/
-    (pd)~/pd/psycopg2/doc$ make
-    Running Sphinx v0.6.4
-    ...
-
-You should have the rendered documentation in ``./html`` and the text file
-``psycopg2.txt`` now.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/doc/README.rst 
new/psycopg2-2.6.1/doc/README.rst
--- old/psycopg2-2.6/doc/README.rst     1970-01-01 01:00:00.000000000 +0100
+++ new/psycopg2-2.6.1/doc/README.rst   2015-06-15 11:48:36.000000000 +0200
@@ -0,0 +1,26 @@
+How to build psycopg documentation
+----------------------------------
+
+Building the documentation usually requires building the library too for
+introspection, so you will need the same prerequisites_.  The only extra
+prerequisite is virtualenv_: the packages needed to build the docs will be
+installed when building the env.
+
+.. _prerequisites: 
http://initd.org/psycopg/docs/install.html#install-from-source
+.. _virtualenv: https://virtualenv.pypa.io/en/latest/
+
+Build the env once with::
+
+    make env
+
+Then you can build the documentation with::
+
+    make
+
+Or the single targets::
+
+    make html
+    make text
+
+You should find the rendered documentation in the ``html`` dir and the text
+file ``psycopg2.txt``.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/doc/requirements.txt 
new/psycopg2-2.6.1/doc/requirements.txt
--- old/psycopg2-2.6/doc/requirements.txt       1970-01-01 01:00:00.000000000 
+0100
+++ new/psycopg2-2.6.1/doc/requirements.txt     2015-06-15 11:48:36.000000000 
+0200
@@ -0,0 +1,3 @@
+# Packages only needed to build the docs
+Pygments>=1.5
+Sphinx>=1.2,<=1.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/doc/src/advanced.rst 
new/psycopg2-2.6.1/doc/src/advanced.rst
--- old/psycopg2-2.6/doc/src/advanced.rst       2015-02-09 11:00:35.000000000 
+0100
+++ new/psycopg2-2.6.1/doc/src/advanced.rst     2015-06-15 11:48:36.000000000 
+0200
@@ -291,7 +291,7 @@
         else:
             conn.poll()
             while conn.notifies:
-                notify = conn.notifies.pop()
+                notify = conn.notifies.pop(0)
                 print "Got NOTIFY:", notify.pid, notify.channel, notify.payload
 
 Running the script and executing a command such as :sql:`NOTIFY test, 'hello'`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/doc/src/connection.rst 
new/psycopg2-2.6.1/doc/src/connection.rst
--- old/psycopg2-2.6/doc/src/connection.rst     2015-02-09 11:00:35.000000000 
+0100
+++ new/psycopg2-2.6.1/doc/src/connection.rst   2015-06-15 11:48:36.000000000 
+0200
@@ -351,17 +351,14 @@
     .. method:: set_session(isolation_level=None, readonly=None, 
deferrable=None, autocommit=None)
 
         Set one or more parameters for the next transactions or statements in
-        the current session. See |SET TRANSACTION|_ for further details.
-
-        .. |SET TRANSACTION| replace:: :sql:`SET TRANSACTION`
-        .. _SET TRANSACTION: 
http://www.postgresql.org/docs/current/static/sql-set-transaction.html
+        the current session.
 
         :param isolation_level: set the `isolation level`_ for the next
-            transactions/statements.  The value can be one of the
-            :ref:`constants <isolation-level-constants>` defined in the
-            `~psycopg2.extensions` module or one of the literal values
-            ``READ UNCOMMITTED``, ``READ COMMITTED``, ``REPEATABLE READ``,
-            ``SERIALIZABLE``.
+            transactions/statements.  The value can be one of the literal
+            values ``READ UNCOMMITTED``, ``READ COMMITTED``, ``REPEATABLE
+            READ``, ``SERIALIZABLE`` or the equivalent :ref:`constant
+            <isolation-level-constants>` defined in the `~psycopg2.extensions`
+            module.
         :param readonly: if `!True`, set the connection to read only;
             read/write if `!False`.
         :param deferrable: if `!True`, set the connection to deferrable;
@@ -370,19 +367,14 @@
             PostgreSQL session setting but an alias for setting the
             `autocommit` attribute.
 
-        Parameter passed as `!None` (the default for all) will not be changed.
-        The parameters *isolation_level*, *readonly* and *deferrable* also
-        accept the string ``DEFAULT`` as a value: the effect is to reset the
-        parameter to the server default.
-
         .. _isolation level:
             http://www.postgresql.org/docs/current/static/transaction-iso.html
 
-        The function must be invoked with no transaction in progress. At every
-        function invocation, only the specified parameters are changed.
-
-        The default for the values are defined by the server configuration:
-        see values for |default_transaction_isolation|__,
+        Arguments set to `!None` (the default for all) will not be changed.
+        The parameters *isolation_level*, *readonly* and *deferrable* also
+        accept the string ``DEFAULT`` as a value: the effect is to reset the
+        parameter to the server default.  Defaults are defined by the server
+        configuration: see values for |default_transaction_isolation|__,
         |default_transaction_read_only|__, |default_transaction_deferrable|__.
 
         .. |default_transaction_isolation| replace:: 
:sql:`default_transaction_isolation`
@@ -392,12 +384,20 @@
         .. |default_transaction_deferrable| replace:: 
:sql:`default_transaction_deferrable`
         .. __: 
http://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-DEFERRABLE
 
+        The function must be invoked with no transaction in progress.
+
         .. note::
 
             There is currently no builtin method to read the current value for
             the parameters: use :sql:`SHOW default_transaction_...` to read
             the values from the backend.
 
+        .. seealso:: |SET TRANSACTION|_ for further details about the behaviour
+            of the transaction parameters in the server.
+
+            .. |SET TRANSACTION| replace:: :sql:`SET TRANSACTION`
+            .. _SET TRANSACTION: 
http://www.postgresql.org/docs/current/static/sql-set-transaction.html
+
         .. versionadded:: 2.4.2
 
 
@@ -419,8 +419,8 @@
 
             By default, any query execution, including a simple :sql:`SELECT`
             will start a transaction: for long-running programs, if no further
-            action is taken, the session will remain "idle in transaction", a
-            condition non desiderable for several reasons (locks are held by
+            action is taken, the session will remain "idle in transaction", an
+            undesirable condition for several reasons (locks are held by
             the session, tables bloat...). For long lived scripts, either
             ensure to terminate a transaction as soon as possible or use an
             autocommit connection.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/doc/src/cursor.rst 
new/psycopg2-2.6.1/doc/src/cursor.rst
--- old/psycopg2-2.6/doc/src/cursor.rst 2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/doc/src/cursor.rst       2015-06-15 11:48:36.000000000 
+0200
@@ -524,6 +524,13 @@
             >>> cur.fetchall()
             [(6, 42, 'foo'), (7, 74, 'bar')]
 
+        .. note:: the name of the table is not quoted: if the table name
+            contains uppercase letters or special characters it must be quoted
+            with double quotes::
+
+                cur.copy_from(f, '"TABLE"')
+
+
         .. versionchanged:: 2.0.6
             added the *columns* parameter.
 
@@ -553,6 +560,12 @@
             2|\N|dada
             ...
 
+        .. note:: the name of the table is not quoted: if the table name
+            contains uppercase letters or special characters it must be quoted
+            with double quotes::
+
+                cur.copy_to(f, '"TABLE"')
+
         .. versionchanged:: 2.0.6
             added the *columns* parameter.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/doc/src/tools/pypi_docs_upload.py 
new/psycopg2-2.6.1/doc/src/tools/pypi_docs_upload.py
--- old/psycopg2-2.6/doc/src/tools/pypi_docs_upload.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/psycopg2-2.6.1/doc/src/tools/pypi_docs_upload.py        2015-06-15 
11:48:36.000000000 +0200
@@ -0,0 +1,166 @@
+# -*- coding: utf-8 -*-
+"""
+    Standalone script to upload a project docs on PyPI
+
+    Hacked together from the following distutils extension, avaliable from
+    https://bitbucket.org/jezdez/sphinx-pypi-upload/overview (ver. 0.2.1)
+
+    sphinx_pypi_upload
+    ~~~~~~~~~~~~~~~~~~
+
+    setuptools command for uploading Sphinx documentation to PyPI
+
+    :author: Jannis Leidel
+    :contact: jan...@leidel.info
+    :copyright: Copyright 2009, Jannis Leidel.
+    :license: BSD, see LICENSE for details.
+"""
+
+import os
+import sys
+import socket
+import zipfile
+import httplib
+import base64
+import urlparse
+import tempfile
+import cStringIO as StringIO
+from ConfigParser import ConfigParser
+
+from distutils import log
+from distutils.command.upload import upload
+from distutils.errors import DistutilsOptionError
+
+class UploadDoc(object):
+    """Distutils command to upload Sphinx documentation."""
+    def __init__(self, name, upload_dir, repository=None):
+        self.name = name
+        self.upload_dir = upload_dir
+
+        p = ConfigParser()
+        p.read(os.path.expanduser('~/.pypirc'))
+        self.username = p.get('pypi', 'username')
+        self.password = p.get('pypi', 'password')
+
+        self.show_response = False
+        self.repository = repository or upload.DEFAULT_REPOSITORY
+
+    def create_zipfile(self):
+        # name = self.distribution.metadata.get_name()
+        name = self.name
+        tmp_dir = tempfile.mkdtemp()
+        tmp_file = os.path.join(tmp_dir, "%s.zip" % name)
+        zip_file = zipfile.ZipFile(tmp_file, "w")
+        for root, dirs, files in os.walk(self.upload_dir):
+            if not files:
+                raise DistutilsOptionError, \
+                      "no files found in upload directory '%s'" % 
self.upload_dir
+            for name in files:
+                full = os.path.join(root, name)
+                relative = root[len(self.upload_dir):].lstrip(os.path.sep)
+                dest = os.path.join(relative, name)
+                zip_file.write(full, dest)
+        zip_file.close()
+        return tmp_file
+
+    def upload_file(self, filename):
+        content = open(filename,'rb').read()
+        # meta = self.distribution.metadata
+        data = {
+            ':action': 'doc_upload',
+            'name': self.name, # meta.get_name(),
+            'content': (os.path.basename(filename),content),
+        }
+        # set up the authentication
+        auth = "Basic " + base64.encodestring(self.username + ":" + 
self.password).strip()
+
+        # Build up the MIME payload for the POST data
+        boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
+        sep_boundary = '\n--' + boundary
+        end_boundary = sep_boundary + '--'
+        body = StringIO.StringIO()
+        for key, value in data.items():
+            # handle multiple entries for the same name
+            if type(value) != type([]):
+                value = [value]
+            for value in value:
+                if type(value) is tuple:
+                    fn = ';filename="%s"' % value[0]
+                    value = value[1]
+                else:
+                    fn = ""
+                value = str(value)
+                body.write(sep_boundary)
+                body.write('\nContent-Disposition: form-data; name="%s"'%key)
+                body.write(fn)
+                body.write("\n\n")
+                body.write(value)
+                if value and value[-1] == '\r':
+                    body.write('\n')  # write an extra newline (lurve Macs)
+        body.write(end_boundary)
+        body.write("\n")
+        body = body.getvalue()
+
+        self.announce("Submitting documentation to %s" % (self.repository), 
log.INFO)
+
+        # build the Request
+        # We can't use urllib2 since we need to send the Basic
+        # auth right with the first request
+        schema, netloc, url, params, query, fragments = \
+            urlparse.urlparse(self.repository)
+        assert not params and not query and not fragments
+        if schema == 'http':
+            http = httplib.HTTPConnection(netloc)
+        elif schema == 'https':
+            http = httplib.HTTPSConnection(netloc)
+        else:
+            raise AssertionError, "unsupported schema "+schema
+
+        data = ''
+        loglevel = log.INFO
+        try:
+            http.connect()
+            http.putrequest("POST", url)
+            http.putheader('Content-type',
+                           'multipart/form-data; boundary=%s'%boundary)
+            http.putheader('Content-length', str(len(body)))
+            http.putheader('Authorization', auth)
+            http.endheaders()
+            http.send(body)
+        except socket.error, e:
+            self.announce(str(e), log.ERROR)
+            return
+
+        response = http.getresponse()
+        if response.status == 200:
+            self.announce('Server response (%s): %s' % (response.status, 
response.reason),
+                          log.INFO)
+        elif response.status == 301:
+            location = response.getheader('Location')
+            if location is None:
+                location = 'http://packages.python.org/%s/' % self.name # 
meta.get_name()
+            self.announce('Upload successful. Visit %s' % location,
+                          log.INFO)
+        else:
+            self.announce('Upload failed (%s): %s' % (response.status, 
response.reason),
+                          log.ERROR)
+        if self.show_response:
+            print '-'*75, response.read(), '-'*75
+
+    def run(self):
+        zip_file = self.create_zipfile()
+        self.upload_file(zip_file)
+        os.remove(zip_file)
+
+    def announce(self, msg, *args, **kwargs):
+        print msg
+
+if __name__ == '__main__':
+    if len(sys.argv) != 3:
+        print >>sys.stderr, "usage: %s PROJECT UPLOAD_DIR" % sys.argv[0]
+        sys.exit(2)
+
+    project, upload_dir = sys.argv[1:]
+    up = UploadDoc(project, upload_dir=upload_dir)
+    up.run()
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/doc/src/usage.rst 
new/psycopg2-2.6.1/doc/src/usage.rst
--- old/psycopg2-2.6/doc/src/usage.rst  2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/doc/src/usage.rst        2015-06-15 11:48:36.000000000 
+0200
@@ -679,7 +679,7 @@
 
     By default even a simple :sql:`SELECT` will start a transaction: in
     long-running programs, if no further action is taken, the session will
-    remain "idle in transaction", a condition non desiderable for several
+    remain "idle in transaction", an undesirable condition for several
     reasons (locks are held by the session, tables bloat...). For long lived
     scripts, either make sure to terminate a transaction as soon as possible or
     use an autocommit connection.
@@ -705,13 +705,28 @@
 
 When a connection exits the ``with`` block, if no exception has been raised by
 the block, the transaction is committed. In case of exception the transaction
-is rolled back. In no case the connection is closed: a connection can be used
-in more than a ``with`` statement and each ``with`` block is effectively
-wrapped in a transaction.
+is rolled back.
 
 When a cursor exits the ``with`` block it is closed, releasing any resource
 eventually associated with it. The state of the transaction is not affected.
 
+Note that, unlike file objects or other resources, exiting the connection's
+``with`` block *doesn't close the connection* but only the transaction
+associated with it: a connection can be used in more than a ``with`` statement
+and each ``with`` block is effectively wrapped in a separate transaction::
+
+    conn = psycopg2.connect(DSN)
+
+    with conn:
+        with conn.cursor() as curs:
+            curs.execute(SQL1)
+
+    with conn:
+        with conn.cursor() as curs:
+            curs.execute(SQL2)
+
+    conn.close()
+
 
 
 .. index::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/lib/extras.py 
new/psycopg2-2.6.1/lib/extras.py
--- old/psycopg2-2.6/lib/extras.py      2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/lib/extras.py    2015-06-15 11:48:36.000000000 +0200
@@ -434,7 +434,7 @@
 
     def callproc(self, procname, vars=None):
         self.timestamp = _time.time()
-        return LoggingCursor.execute(self, procname, vars)
+        return LoggingCursor.callproc(self, procname, vars)
 
 
 # a dbtype and adapter for Python UUID type
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/psycopg/adapter_list.c 
new/psycopg2-2.6.1/psycopg/adapter_list.c
--- old/psycopg2-2.6/psycopg/adapter_list.c     2015-02-09 11:00:35.000000000 
+0100
+++ new/psycopg2-2.6.1/psycopg/adapter_list.c   2015-06-15 11:48:36.000000000 
+0200
@@ -39,6 +39,14 @@
     /*  adapt the list by calling adapt() recursively and then wrapping
         everything into "ARRAY[]" */
     PyObject *tmp = NULL, *str = NULL, *joined = NULL, *res = NULL;
+
+    /*  list consisting of only NULL don't work with the ARRAY[] construct
+     *  so we use the {NULL,...} syntax. Note however that list of lists where
+     *  some element is a list of only null still fails: for that we should use
+     *  the '{...}' syntax uniformly but we cannot do it in the current
+     *  infrastructure. TODO in psycopg3 */
+    int all_nulls = 1;
+
     Py_ssize_t i, len;
 
     len = PyList_GET_SIZE(self->wrapped);
@@ -60,6 +68,7 @@
             quoted = microprotocol_getquoted(wrapped,
                                        (connectionObject*)self->connection);
             if (quoted == NULL) goto error;
+            all_nulls = 0;
         }
 
         /* here we don't loose a refcnt: SET_ITEM does not change the
@@ -74,7 +83,12 @@
     joined = PyObject_CallMethod(str, "join", "(O)", tmp);
     if (joined == NULL) goto error;
 
-    res = Bytes_FromFormat("ARRAY[%s]", Bytes_AsString(joined));
+    /* PG doesn't like ARRAY[NULL..] */
+    if (!all_nulls) {
+        res = Bytes_FromFormat("ARRAY[%s]", Bytes_AsString(joined));
+    } else {
+        res = Bytes_FromFormat("'{%s}'", Bytes_AsString(joined));
+    }
 
  error:
     Py_XDECREF(tmp);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/psycopg/connection_type.c 
new/psycopg2-2.6.1/psycopg/connection_type.c
--- old/psycopg2-2.6/psycopg/connection_type.c  2015-02-09 11:00:35.000000000 
+0100
+++ new/psycopg2-2.6.1/psycopg/connection_type.c        2015-06-15 
11:48:36.000000000 +0200
@@ -840,6 +840,10 @@
     return exception;
 }
 
+
+#define psyco_conn_poll_doc \
+"poll() -> int -- Advance the connection or query process without blocking."
+
 static PyObject *
 psyco_conn_poll(connectionObject *self)
 {
@@ -980,7 +984,7 @@
     {"reset", (PyCFunction)psyco_conn_reset,
      METH_NOARGS, psyco_conn_reset_doc},
     {"poll", (PyCFunction)psyco_conn_poll,
-     METH_NOARGS, psyco_conn_lobject_doc},
+     METH_NOARGS, psyco_conn_poll_doc},
     {"fileno", (PyCFunction)psyco_conn_fileno,
      METH_NOARGS, psyco_conn_fileno_doc},
     {"isexecuting", (PyCFunction)psyco_conn_isexecuting,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/psycopg/cursor_type.c 
new/psycopg2-2.6.1/psycopg/cursor_type.c
--- old/psycopg2-2.6/psycopg/cursor_type.c      2015-02-09 11:00:35.000000000 
+0100
+++ new/psycopg2-2.6.1/psycopg/cursor_type.c    2015-06-15 11:48:36.000000000 
+0200
@@ -1546,7 +1546,7 @@
     if (sql == NULL) { goto exit; }
 
     /* This validation of file is rather weak, in that it doesn't enforce the
-       assocation between "COPY FROM" -> "read" and "COPY TO" -> "write".
+       association between "COPY FROM" -> "read" and "COPY TO" -> "write".
        However, the error handling in _pq_copy_[in|out] must be able to handle
        the case where the attempt to call file.read|write fails, so no harm
        done. */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/psycopg/lobject.h 
new/psycopg2-2.6.1/psycopg/lobject.h
--- old/psycopg2-2.6/psycopg/lobject.h  2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/psycopg/lobject.h        2015-06-15 11:48:36.000000000 
+0200
@@ -60,8 +60,8 @@
 RAISES_NEG HIDDEN Py_ssize_t lobject_read(lobjectObject *self, char *buf, 
size_t len);
 RAISES_NEG HIDDEN Py_ssize_t lobject_write(lobjectObject *self, const char 
*buf,
                                 size_t len);
-RAISES_NEG HIDDEN long lobject_seek(lobjectObject *self, long pos, int whence);
-RAISES_NEG HIDDEN long lobject_tell(lobjectObject *self);
+RAISES_NEG HIDDEN Py_ssize_t lobject_seek(lobjectObject *self, Py_ssize_t pos, 
int whence);
+RAISES_NEG HIDDEN Py_ssize_t lobject_tell(lobjectObject *self);
 RAISES_NEG HIDDEN int lobject_truncate(lobjectObject *self, size_t len);
 RAISES_NEG HIDDEN int lobject_close(lobjectObject *self);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/psycopg/lobject_int.c 
new/psycopg2-2.6.1/psycopg/lobject_int.c
--- old/psycopg2-2.6/psycopg/lobject_int.c      2015-02-09 11:00:35.000000000 
+0100
+++ new/psycopg2-2.6.1/psycopg/lobject_int.c    2015-06-15 11:48:36.000000000 
+0200
@@ -376,12 +376,12 @@
 
 /* lobject_seek - move the current position in the lo */
 
-RAISES_NEG long
-lobject_seek(lobjectObject *self, long pos, int whence)
+RAISES_NEG Py_ssize_t
+lobject_seek(lobjectObject *self, Py_ssize_t pos, int whence)
 {
     PGresult *pgres = NULL;
     char *error = NULL;
-    long where;
+    Py_ssize_t where;
 
     Dprintf("lobject_seek: fd = %d, pos = %ld, whence = %d",
             self->fd, pos, whence);
@@ -391,12 +391,12 @@
 
 #ifdef HAVE_LO64
     if (self->conn->server_version < 90300) {
-        where = (long)lo_lseek(self->conn->pgconn, self->fd, (int)pos, whence);
+        where = (Py_ssize_t)lo_lseek(self->conn->pgconn, self->fd, (int)pos, 
whence);
     } else {
-        where = lo_lseek64(self->conn->pgconn, self->fd, pos, whence);
+        where = (Py_ssize_t)lo_lseek64(self->conn->pgconn, self->fd, pos, 
whence);
     }
 #else
-    where = (long)lo_lseek(self->conn->pgconn, self->fd, (int)pos, whence);
+    where = (Py_ssize_t)lo_lseek(self->conn->pgconn, self->fd, (int)pos, 
whence);
 #endif
     Dprintf("lobject_seek: where = %ld", where);
     if (where < 0)
@@ -412,12 +412,12 @@
 
 /* lobject_tell - tell the current position in the lo */
 
-RAISES_NEG long
+RAISES_NEG Py_ssize_t
 lobject_tell(lobjectObject *self)
 {
     PGresult *pgres = NULL;
     char *error = NULL;
-    long where;
+    Py_ssize_t where;
 
     Dprintf("lobject_tell: fd = %d", self->fd);
 
@@ -426,12 +426,12 @@
 
 #ifdef HAVE_LO64
     if (self->conn->server_version < 90300) {
-        where = (long)lo_tell(self->conn->pgconn, self->fd);
+        where = (Py_ssize_t)lo_tell(self->conn->pgconn, self->fd);
     } else {
-        where = lo_tell64(self->conn->pgconn, self->fd);
+        where = (Py_ssize_t)lo_tell64(self->conn->pgconn, self->fd);
     }
 #else
-    where = (long)lo_tell(self->conn->pgconn, self->fd);
+    where = (Py_ssize_t)lo_tell(self->conn->pgconn, self->fd);
 #endif
     Dprintf("lobject_tell: where = %ld", where);
     if (where < 0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/psycopg/lobject_type.c 
new/psycopg2-2.6.1/psycopg/lobject_type.c
--- old/psycopg2-2.6/psycopg/lobject_type.c     2015-02-09 11:00:35.000000000 
+0100
+++ new/psycopg2-2.6.1/psycopg/lobject_type.c   2015-06-15 11:48:36.000000000 
+0200
@@ -105,7 +105,7 @@
         goto exit;
     }
 
-    rv = PyInt_FromLong((long)res);
+    rv = PyInt_FromSsize_t((Py_ssize_t)res);
 
 exit:
     Py_XDECREF(data);
@@ -121,7 +121,7 @@
 psyco_lobj_read(lobjectObject *self, PyObject *args)
 {
     PyObject *res;
-    long where, end;
+    Py_ssize_t where, end;
     Py_ssize_t size = -1;
     char *buffer;
 
@@ -165,10 +165,10 @@
 static PyObject *
 psyco_lobj_seek(lobjectObject *self, PyObject *args)
 {
-    long offset, pos=0;
+    Py_ssize_t offset, pos=0;
     int whence=0;
 
-    if (!PyArg_ParseTuple(args, "l|i", &offset, &whence))
+    if (!PyArg_ParseTuple(args, "n|i", &offset, &whence))
         return NULL;
 
     EXC_IF_LOBJ_CLOSED(self);
@@ -187,8 +187,8 @@
 #else
     if (offset < INT_MIN || offset > INT_MAX) {
         PyErr_Format(InterfaceError,
-            "offset out of range (%ld): this psycopg version was not built "
-            "with lobject 64 API support",
+            "offset out of range (" FORMAT_CODE_PY_SSIZE_T "): "
+            "this psycopg version was not built with lobject 64 API support",
             offset);
         return NULL;
     }
@@ -197,7 +197,7 @@
     if ((pos = lobject_seek(self, offset, whence)) < 0)
         return NULL;
 
-    return PyLong_FromLong(pos);
+    return PyInt_FromSsize_t(pos);
 }
 
 /* tell method - tell current position in the lobject */
@@ -208,7 +208,7 @@
 static PyObject *
 psyco_lobj_tell(lobjectObject *self, PyObject *args)
 {
-    long pos;
+    Py_ssize_t pos;
 
     EXC_IF_LOBJ_CLOSED(self);
     EXC_IF_LOBJ_LEVEL0(self);
@@ -217,7 +217,7 @@
     if ((pos = lobject_tell(self)) < 0)
         return NULL;
 
-    return PyLong_FromLong(pos);
+    return PyInt_FromSsize_t(pos);
 }
 
 /* unlink method - unlink (destroy) the lobject */
@@ -274,9 +274,9 @@
 static PyObject *
 psyco_lobj_truncate(lobjectObject *self, PyObject *args)
 {
-    long len = 0;
+    Py_ssize_t len = 0;
 
-    if (!PyArg_ParseTuple(args, "|l", &len))
+    if (!PyArg_ParseTuple(args, "|n", &len))
         return NULL;
 
     EXC_IF_LOBJ_CLOSED(self);
@@ -286,16 +286,16 @@
 #ifdef HAVE_LO64
     if (len > INT_MAX && self->conn->server_version < 90300) {
         PyErr_Format(NotSupportedError,
-            "len out of range (%ld): server version %d "
-            "does not support the lobject 64 API",
+            "len out of range (" FORMAT_CODE_PY_SSIZE_T "): "
+            "server version %d does not support the lobject 64 API",
             len, self->conn->server_version);
         return NULL;
     }
 #else
     if (len > INT_MAX) {
         PyErr_Format(InterfaceError,
-            "len out of range (%ld): this psycopg version was not built "
-            "with lobject 64 API support",
+            "len out of range (" FORMAT_CODE_PY_SSIZE_T "): "
+            "this psycopg version was not built with lobject 64 API support",
             len);
         return NULL;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/psycopg/pqpath.c 
new/psycopg2-2.6.1/psycopg/pqpath.c
--- old/psycopg2-2.6/psycopg/pqpath.c   2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/psycopg/pqpath.c 2015-06-15 11:48:36.000000000 +0200
@@ -980,6 +980,10 @@
         }
         else {
             /* there was an error */
+            pthread_mutex_unlock(&(curs->conn->lock));
+            Py_BLOCK_THREADS;
+            PyErr_SetString(OperationalError,
+                            PQerrorMessage(curs->conn->pgconn));
             return -1;
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/psycopg/psycopgmodule.c 
new/psycopg2-2.6.1/psycopg/psycopgmodule.c
--- old/psycopg2-2.6/psycopg/psycopgmodule.c    2015-02-09 11:00:35.000000000 
+0100
+++ new/psycopg2-2.6.1/psycopg/psycopgmodule.c  2015-06-15 11:48:36.000000000 
+0200
@@ -176,6 +176,26 @@
 }
 
 
+
+/* Make sure libcrypto thread callbacks are set up. */
+static void
+psyco_libcrypto_threads_init(void)
+{
+    /* importing the ssl module sets up Python's libcrypto callbacks */
+    if (PyImport_ImportModule("ssl") != NULL) {
+        /* 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
+    }
+    else {
+        /* might mean that Python has been compiled without OpenSSL support,
+           fall back to relying on libpq's libcrypto locking */
+        PyErr_Clear();
+    }
+}
+
 /* Initialize the default adapters map
  *
  * Return 0 on success, else -1 and set an exception.
@@ -814,6 +834,9 @@
     Py_TYPE(&lobjectType) = &PyType_Type;
     if (PyType_Ready(&lobjectType) == -1) goto exit;
 
+    /* initialize libcrypto threading callbacks */
+    psyco_libcrypto_threads_init();
+
     /* import mx.DateTime module, if necessary */
 #ifdef HAVE_MXDATETIME
     Py_TYPE(&mxdatetimeType) = &PyType_Type;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/setup.py new/psycopg2-2.6.1/setup.py
--- old/psycopg2-2.6/setup.py   2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/setup.py 2015-06-15 11:48:36.000000000 +0200
@@ -86,7 +86,7 @@
 # Take a look at http://www.python.org/dev/peps/pep-0386/
 # for a consistent versioning pattern.
 
-PSYCOPG_VERSION = '2.6'
+PSYCOPG_VERSION = '2.6.1'
 
 version_flags   = ['dt', 'dec']
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/tests/dbapi20.py 
new/psycopg2-2.6.1/tests/dbapi20.py
--- old/psycopg2-2.6/tests/dbapi20.py   2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/tests/dbapi20.py 2015-06-15 11:48:36.000000000 +0200
@@ -62,7 +62,7 @@
 # - Reversed the polarity of buggy test in test_description
 # - Test exception hierarchy correctly
 # - self.populate is now self._populate(), so if a driver stub
-#   overrides self.ddl1 this change propogates
+#   overrides self.ddl1 this change propagates
 # - VARCHAR columns now have a width, which will hopefully make the
 #   DDL even more portible (this will be reversed if it causes more problems)
 # - cursor.rowcount being checked after various execute and fetchXXX methods
@@ -804,7 +804,7 @@
             con.close()
 
     def test_setoutputsize(self):
-        # Real test for setoutputsize is driver dependant
+        # Real test for setoutputsize is driver dependent
         raise NotImplementedError('Driver needed to override this test')
 
     def test_None(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/tests/test_types_basic.py 
new/psycopg2-2.6.1/tests/test_types_basic.py
--- old/psycopg2-2.6/tests/test_types_basic.py  2015-02-09 11:00:35.000000000 
+0100
+++ new/psycopg2-2.6.1/tests/test_types_basic.py        2015-06-15 
11:48:36.000000000 +0200
@@ -192,6 +192,41 @@
             self.assertRaises(psycopg2.DataError,
                 psycopg2.extensions.STRINGARRAY, b(s), curs)
 
+    @testutils.skip_before_postgres(8, 2)
+    def testArrayOfNulls(self):
+        curs = self.conn.cursor()
+        curs.execute("""
+            create table na (
+              texta text[],
+              inta int[],
+              boola boolean[],
+
+              textaa text[][],
+              intaa int[][],
+              boolaa boolean[][]
+            )""")
+
+        curs.execute("insert into na (texta) values (%s)", ([None],))
+        curs.execute("insert into na (texta) values (%s)", (['a', None],))
+        curs.execute("insert into na (texta) values (%s)", ([None, None],))
+        curs.execute("insert into na (inta) values (%s)",  ([None],))
+        curs.execute("insert into na (inta) values (%s)",  ([42, None],))
+        curs.execute("insert into na (inta) values (%s)",  ([None, None],))
+        curs.execute("insert into na (boola) values (%s)", ([None],))
+        curs.execute("insert into na (boola) values (%s)", ([True, None],))
+        curs.execute("insert into na (boola) values (%s)", ([None, None],))
+
+        # TODO: array of array of nulls are not supported yet
+        # curs.execute("insert into na (textaa) values (%s)", ([[None]],))
+        curs.execute("insert into na (textaa) values (%s)", ([['a', None]],))
+        # curs.execute("insert into na (textaa) values (%s)", ([[None, 
None]],))
+        # curs.execute("insert into na (intaa) values (%s)",  ([[None]],))
+        curs.execute("insert into na (intaa) values (%s)",  ([[42, None]],))
+        # curs.execute("insert into na (intaa) values (%s)",  ([[None, 
None]],))
+        # curs.execute("insert into na (boolaa) values (%s)", ([[None]],))
+        curs.execute("insert into na (boolaa) values (%s)", ([[True, None]],))
+        # curs.execute("insert into na (boolaa) values (%s)", ([[None, 
None]],))
+
     @testutils.skip_from_python(3)
     def testTypeRoundtripBuffer(self):
         o1 = buffer("".join(map(chr, range(256))))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg2-2.6/tests/testutils.py 
new/psycopg2-2.6.1/tests/testutils.py
--- old/psycopg2-2.6/tests/testutils.py 2015-02-09 11:00:35.000000000 +0100
+++ new/psycopg2-2.6.1/tests/testutils.py       2015-06-15 11:48:36.000000000 
+0200
@@ -65,7 +65,8 @@
 
     unittest.TestCase.skipTest = skipTest
 
-# Silence warnings caused by the stubborness of the Python unittest maintainers
+# Silence warnings caused by the stubbornness of the Python unittest
+# maintainers
 # http://bugs.python.org/issue9424
 if not hasattr(unittest.TestCase, 'assert_') \
 or unittest.TestCase.assert_ is not unittest.TestCase.assertTrue:


Reply via email to