[Python-modules-commits] [psycopg2] 01/06: Imported Upstream version 2.7.3

Scott Kitterman kitterman at moszumanska.debian.org
Wed Aug 9 05:01:13 UTC 2017


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

kitterman pushed a commit to branch debian/master
in repository psycopg2.

commit 948e3debc862e75d96587ad7b66f4033b0e932ff
Author: Scott Kitterman <scott at kitterman.com>
Date:   Wed Aug 9 00:27:16 2017 -0400

    Imported Upstream version 2.7.3
---
 NEWS                                  |  43 +++++-
 PKG-INFO                              |  30 ++--
 README.rst                            |  26 ++--
 doc/src/connection.rst                |   3 +
 doc/src/cursor.rst                    |   5 +-
 doc/src/errorcodes.rst                |   2 +-
 doc/src/extensions.rst                |   8 +-
 doc/src/extras.rst                    |  19 ++-
 doc/src/install.rst                   |  22 ++-
 doc/src/sql.rst                       |   5 +
 doc/src/usage.rst                     |   2 +-
 lib/__init__.py                       |   2 +-
 lib/_json.py                          |   9 +-
 lib/errorcodes.py                     |   8 ++
 lib/extensions.py                     |   8 +-
 lib/extras.py                         |   6 +
 lib/pool.py                           |   2 +-
 lib/psycopg1.py                       |   4 +-
 lib/sql.py                            |  25 ++--
 psycopg/connection_type.c             |  63 ++++++++-
 psycopg/cursor.h                      |   1 +
 psycopg/cursor_int.c                  |  80 +++++++++++
 psycopg/cursor_type.c                 |  85 +-----------
 psycopg/lobject_type.c                |   5 +-
 psycopg/pqpath.c                      |  28 +++-
 psycopg/psycopg.h                     |   2 +
 psycopg/replication_connection_type.c |  56 +++-----
 psycopg/replication_cursor_type.c     |  19 ++-
 psycopg/typecast.c                    |   6 +
 psycopg/typecast_array.c              |   1 +
 psycopg/typecast_builtins.c           |   8 +-
 psycopg/typecast_datetime.c           | 248 +++++++++++++++++++++++++---------
 psycopg/typecast_mxdatetime.c         |   1 +
 psycopg/utils.c                       |  24 ++++
 psycopg2.egg-info/PKG-INFO            |  30 ++--
 scripts/make_errorcodes.py            |  15 +-
 scripts/travis_prepare.sh             |   8 +-
 scripts/travis_test.sh                |   6 +-
 setup.py                              |   7 +-
 tests/test_connection.py              | 111 +++++++++++++--
 tests/test_cursor.py                  |  75 ++++++++--
 tests/test_dates.py                   |  45 ++++++
 tests/test_green.py                   |  85 ++++++++++++
 tests/test_lobject.py                 |  14 ++
 tests/test_replication.py             |  37 +++++
 tests/test_sql.py                     |  26 +++-
 tests/test_types_extras.py            |  28 +++-
 47 files changed, 1017 insertions(+), 326 deletions(-)

diff --git a/NEWS b/NEWS
index 88689f6..6c67cb5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,44 @@
 Current release
 ---------------
 
+What's new in psycopg 2.7.3
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Restored default :sql:`timestamptz[]` typecasting to Python `!datetime`.
+  Regression introduced in Psycopg 2.7.2 (:ticket:`#578`).
+
+
+What's new in psycopg 2.7.2
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Fixed inconsistent state in externally closed connections
+  (:tickets:`#263, #311, #443`). Was fixed in 2.6.2 but not included in
+  2.7 by mistake.
+- Fixed Python exceptions propagation in green callback (:ticket:`#410`).
+- Don't display the password in `connection.dsn` when the connection
+  string is specified as an URI (:ticket:`#528`).
+- Return objects with timezone parsing "infinity" :sql:`timestamptz`
+  (:ticket:`#536`).
+- Dropped dependency on VC9 runtime on Windows binary packages
+  (:ticket:`#541`).
+- Fixed segfault in `~connection.lobject()` when *mode*\=\ `!None`
+  (:ticket:`#544`).
+- Fixed `~connection.lobject()` keyword argument *lobject_factory*
+  (:ticket:`#545`).
+- Fixed `~psycopg2.extras.ReplicationCursor.consume_stream()`
+  *keepalive_interval* argument (:ticket:`#547`).
+- Maybe fixed random import error on Python 3.6 in multiprocess
+  environment (:ticket:`#550`).
+- Fixed random `!SystemError` upon receiving abort signal (:ticket:`#551`).
+- Accept `~psycopg2.sql.Composable` objects in
+  `~psycopg2.extras.ReplicationCursor.start_replication_expert()`
+  (:ticket:`554`).
+- Parse intervals returned as microseconds from Redshift (:ticket:`#558`).
+- Added `~psycopg2.extras.Json` `!prepare()` method to consider connection
+  params when adapting (:ticket:`#562`).
+- `~psycopg2.errorcodes` map updated to PostgreSQL 10 beta 1.
+
+
 What's new in psycopg 2.7.1
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -82,6 +120,8 @@ What's new in psycopg 2.6.3
 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`).
@@ -91,7 +131,8 @@ What's new in psycopg 2.6.2
   (:ticket:`#333`).
 - Fixed `!PersistentConnectionPool` on Python 3 (:ticket:`#348`).
 - Fixed segfault on `repr()` of an unitialized connection (:ticket:`#361`).
-- Allow adapting bytes using QuotedString on Python 3 too (:ticket:`#365`).
+- 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`).
diff --git a/PKG-INFO b/PKG-INFO
index 9a7352a..8ec7484 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: psycopg2
-Version: 2.7.1
+Version: 2.7.3
 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-7/psycopg2-2.7.1.tar.gz
+Download-URL: http://initd.org/psycopg/tarballs/PSYCOPG-2-7/psycopg2-2.7.3.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
@@ -27,7 +27,7 @@ Description: Psycopg is the most popular PostgreSQL database adapter for the Pyt
         Documentation
         -------------
         
-        Documentation is included in the 'doc' directory and is `available online`__.
+        Documentation is included in the ``doc`` directory and is `available online`__.
         
         .. __: http://initd.org/psycopg/docs/
         
@@ -36,22 +36,20 @@ Description: Psycopg is the most popular PostgreSQL database adapter for the Pyt
         ------------
         
         If your ``pip`` version supports wheel_ packages it should be possible to
-        install a binary version of Psycopg including all the dependencies. Just run::
+        install a binary version of Psycopg including all the dependencies from PyPI_.
+        Just run::
         
-            pip install psycopg2
+            $ pip install -U pip      # make sure your pip is up-to-date
+            $ pip install psycopg2
         
-        If you want to build Psycopg from source you will need some prerequisite (a C
-        compiler, Python and libpq development packages). If you have what you need
-        the standard::
-        
-            python setup.py build
-            sudo python setup.py install
-        
-        should work no problem.  In case you have any problem check the 'install' and
-        the 'faq' documents in the docs or online__.
+        If you want to build Psycopg from source you will need some prerequisites (a C
+        compiler, development packages): please check the install_ and the faq_
+        documents in the ``doc`` dir for the details.
         
         .. _wheel: http://pythonwheels.com/
-        .. __: http://initd.org/psycopg/docs/install.html#install-from-source
+        .. _PyPI: https://pypi.python.org/pypi/psycopg2
+        .. _install: http://initd.org/psycopg/docs/install.html#install-from-source
+        .. _faq: http://initd.org/psycopg/docs/faq.html#faq-compile
         
         For any other resource (source code repository, bug tracker, mailing list)
         please check the `project homepage`__.
@@ -67,7 +65,7 @@ Description: Psycopg is the most popular PostgreSQL database adapter for the Pyt
             :alt: Linux and OSX build status
         
         .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/psycopg/psycopg2?branch=master&svg=true
-            :target: https://ci.appveyor.com/project/psycopg/psycopg2
+            :target: https://ci.appveyor.com/project/psycopg/psycopg2/branch/master
             :alt: Windows build status
         
 Platform: any
diff --git a/README.rst b/README.rst
index efbe38e..69b1d83 100644
--- a/README.rst
+++ b/README.rst
@@ -21,7 +21,7 @@ Psycopg 2 is both Unicode and Python 3 friendly.
 Documentation
 -------------
 
-Documentation is included in the 'doc' directory and is `available online`__.
+Documentation is included in the ``doc`` directory and is `available online`__.
 
 .. __: http://initd.org/psycopg/docs/
 
@@ -30,22 +30,20 @@ Installation
 ------------
 
 If your ``pip`` version supports wheel_ packages it should be possible to
-install a binary version of Psycopg including all the dependencies. Just run::
+install a binary version of Psycopg including all the dependencies from PyPI_.
+Just run::
 
-    pip install psycopg2
+    $ pip install -U pip      # make sure your pip is up-to-date
+    $ pip install psycopg2
 
-If you want to build Psycopg from source you will need some prerequisite (a C
-compiler, Python and libpq development packages). If you have what you need
-the standard::
-
-    python setup.py build
-    sudo python setup.py install
-
-should work no problem.  In case you have any problem check the 'install' and
-the 'faq' documents in the docs or online__.
+If you want to build Psycopg from source you will need some prerequisites (a C
+compiler, development packages): please check the install_ and the faq_
+documents in the ``doc`` dir for the details.
 
 .. _wheel: http://pythonwheels.com/
-.. __: http://initd.org/psycopg/docs/install.html#install-from-source
+.. _PyPI: https://pypi.python.org/pypi/psycopg2
+.. _install: http://initd.org/psycopg/docs/install.html#install-from-source
+.. _faq: http://initd.org/psycopg/docs/faq.html#faq-compile
 
 For any other resource (source code repository, bug tracker, mailing list)
 please check the `project homepage`__.
@@ -61,5 +59,5 @@ please check the `project homepage`__.
     :alt: Linux and OSX build status
 
 .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/psycopg/psycopg2?branch=master&svg=true
-    :target: https://ci.appveyor.com/project/psycopg/psycopg2
+    :target: https://ci.appveyor.com/project/psycopg/psycopg2/branch/master
     :alt: Windows build status
diff --git a/doc/src/connection.rst b/doc/src/connection.rst
index 53f908f..fbbc53e 100644
--- a/doc/src/connection.rst
+++ b/doc/src/connection.rst
@@ -343,6 +343,9 @@ The ``connection`` class
         Read-only string containing the connection string used by the
         connection.
 
+        If a password was specified in the connection string it will be
+        obscured.
+
 
     .. index::
         pair: Transaction; Autocommit
diff --git a/doc/src/cursor.rst b/doc/src/cursor.rst
index c03cea8..417ab6c 100644
--- a/doc/src/cursor.rst
+++ b/doc/src/cursor.rst
@@ -601,7 +601,10 @@ The ``cursor`` class
         The *sql* statement should be in the form :samp:`COPY {table} TO
         STDOUT` to export :samp:`{table}` to the *file* object passed as
         argument or :samp:`COPY {table} FROM STDIN` to import the content of
-        the *file* object into :samp:`{table}`.
+        the *file* object into :samp:`{table}`. If you need to compose a
+        :sql:`COPY` statement dynamically (because table, fields, or query
+        parameters are in Python variables) you may use the objects provided
+        by the `psycopg2.sql` module.
 
         *file* must be a readable file-like object (as required by
         `~cursor.copy_from()`) for *sql* statement :sql:`COPY ... FROM STDIN`
diff --git a/doc/src/errorcodes.rst b/doc/src/errorcodes.rst
index d662d0c..ed40b1f 100644
--- a/doc/src/errorcodes.rst
+++ b/doc/src/errorcodes.rst
@@ -50,7 +50,7 @@ An example of the available constants defined in the module:
     '42P01'
 
 Constants representing all the error values defined by PostgreSQL versions
-between 8.1 and 9.4 are included in the module.
+between 8.1 and 10 beta 1 are included in the module.
 
 
 .. autofunction:: lookup(code)
diff --git a/doc/src/extensions.rst b/doc/src/extensions.rst
index ae40b72..8545fcf 100644
--- a/doc/src/extensions.rst
+++ b/doc/src/extensions.rst
@@ -548,8 +548,6 @@ Other functions
     The *scope* must be a `connection` or a `cursor`, the underlying
     connection encoding is used for any necessary character conversion.
 
-    Requires libpq >= 9.0.
-
     .. versionadded:: 2.7
 
     .. seealso:: libpq docs for `PQescapeIdentifier()`__
@@ -825,10 +823,12 @@ from the database.  See :ref:`unicode-handling` for details.
 
 .. data:: PYDATE
           PYDATETIME
+          PYDATETIMETZ
           PYINTERVAL
           PYTIME
           PYDATEARRAY
           PYDATETIMEARRAY
+          PYDATETIMETZARRAY
           PYINTERVALARRAY
           PYTIMEARRAY
 
@@ -837,10 +837,12 @@ from the database.  See :ref:`unicode-handling` for details.
 
 .. data:: MXDATE
           MXDATETIME
+          MXDATETIMETZ
           MXINTERVAL
           MXTIME
           MXDATEARRAY
           MXDATETIMEARRAY
+          MXDATETIMETZARRAY
           MXINTERVALARRAY
           MXTIMEARRAY
 
@@ -853,3 +855,5 @@ from the database.  See :ref:`unicode-handling` for details.
         module. In older versions they can be imported from the implementation
         module `!psycopg2._psycopg`.
 
+.. versionchanged:: 2.7.2
+        added `!*DATETIMETZ*` objects.
diff --git a/doc/src/extras.rst b/doc/src/extras.rst
index f162bf1..36118e7 100644
--- a/doc/src/extras.rst
+++ b/doc/src/extras.rst
@@ -136,6 +136,11 @@ Logging cursor
 .. autoclass:: LoggingCursor
 
 
+.. note::
+
+    Queries that are executed with `cursor.executemany()` are not logged.
+
+
 .. autoclass:: MinTimeLoggingConnection
     :members: initialize,filter
 
@@ -337,7 +342,7 @@ The individual messages in the replication stream are represented by
         *This parameter should not be set with physical replication or with
         logical replication plugins that produce binary output.*
 
-        This function constructs a ``START_REPLICATION`` command and calls
+        This function constructs a |START_REPLICATION|_ command and calls
         `start_replication_expert()` internally.
 
         After starting the replication, to actually consume the incoming
@@ -345,11 +350,19 @@ The individual messages in the replication stream are represented by
         `read_message()` in case of :ref:`asynchronous connection
         <async-support>`.
 
+        .. |START_REPLICATION| replace:: :sql:`START_REPLICATION`
+        .. _START_REPLICATION: https://www.postgresql.org/docs/current/static/protocol-replication.html
+
     .. method:: start_replication_expert(command, decode=False)
 
         Start replication on the connection using provided
-        ``START_REPLICATION`` command.  See `start_replication()` for
-        description of *decode* parameter.
+        |START_REPLICATION|_ command.
+
+        :param command: The full replication command. It can be a string or a
+            `~psycopg2.sql.Composable` instance for dynamic generation.
+        :param decode: a flag indicating that unicode conversion should be
+            performed on messages received from the server.
+
 
     .. method:: consume_stream(consume, keepalive_interval=10)
 
diff --git a/doc/src/install.rst b/doc/src/install.rst
index 8290e67..9119753 100644
--- a/doc/src/install.rst
+++ b/doc/src/install.rst
@@ -56,11 +56,20 @@ using something like ``pip install -U pip``)
 .. note::
 
     The binary packages come with their own versions of a few C libraries,
-    among which libpq and libssl, which will be used regardless of other
+    among which ``libpq`` and ``libssl``, which will be used regardless of other
     libraries available on the client: upgrading the system libraries will not
     upgrade the libraries used by `!psycopg2`. Please build `!psycopg2` from
     source if you want to maintain binary upgradeability.
 
+.. warning::
+
+    Because the `!psycopg` wheel package uses its own ``libssl`` binary, it is
+    incompatible with other extension modules binding with ``libssl`` as well,
+    for instance the Python `ssl` module: the result will likely be a
+    segfault. If you need using both `!psycopg2` and other libraries using
+    ``libssl`` please :ref:`install psycopg from source
+    <install-from-source>`.
+
 If you prefer to use the system libraries available on your client you can use
 the :command:`pip` ``--no-binary`` option:
 
@@ -105,8 +114,8 @@ Build prerequisites
 These notes illustrate how to compile Psycopg on Linux. If you want to compile
 Psycopg on other platforms you may have to adjust some details accordingly.
 
-Psycopg is a C wrapper to the libpq PostgreSQL client library. To install it
-from sources you will need:
+Psycopg is a C wrapper around the libpq_ PostgreSQL client library. To install
+it from sources you will need:
 
 - A C compiler.
 
@@ -133,6 +142,13 @@ from sources you will need:
   You only need :program:`pg_config` to compile `!psycopg2`, not for its
   regular usage.
 
+Once everything is in place it's just a matter of running the standard:
+
+.. code-block:: console
+
+    $ python setup.py build
+    $ python setup.py install
+
 
 Runtime requirements
 ^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/src/sql.rst b/doc/src/sql.rst
index 0aee451..fe807c6 100644
--- a/doc/src/sql.rst
+++ b/doc/src/sql.rst
@@ -55,6 +55,11 @@ from the query parameters::
             .format(sql.Identifier('my_table')),
         [10, 20])
 
+The objects exposed by the `!sql` module can be used to compose a query as a
+Python string (using the `~Composable.as_string()` method) or passed directly
+to cursor methods such as `~cursor.execute()`, `~cursor.executemany()`,
+`~cursor.copy_expert()`.
+
 
 .. autoclass:: Composable
 
diff --git a/doc/src/usage.rst b/doc/src/usage.rst
index cde0242..660f290 100644
--- a/doc/src/usage.rst
+++ b/doc/src/usage.rst
@@ -870,7 +870,7 @@ 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
+the format accepted by `PostgreSQL COPY command`__ (data format, escaped
 characters, etc).
 
 .. __: COPY_
diff --git a/lib/__init__.py b/lib/__init__.py
index 492b924..f4d4fc7 100644
--- a/lib/__init__.py
+++ b/lib/__init__.py
@@ -65,7 +65,7 @@ from psycopg2 import tz                             # noqa
 
 # Register default adapters.
 
-import psycopg2.extensions as _ext
+from psycopg2 import extensions as _ext
 _ext.register_adapter(tuple, _ext.SQL_IN)
 _ext.register_adapter(type(None), _ext.NoneAdapter)
 
diff --git a/lib/_json.py b/lib/_json.py
index b137a2d..92a9def 100644
--- a/lib/_json.py
+++ b/lib/_json.py
@@ -66,6 +66,7 @@ class Json(object):
     """
     def __init__(self, adapted, dumps=None):
         self.adapted = adapted
+        self._conn = None
 
         if dumps is not None:
             self._dumps = dumps
@@ -93,9 +94,15 @@ class Json(object):
                 "json module not available: "
                 "you should provide a dumps function")
 
+    def prepare(self, conn):
+        self._conn = conn
+
     def getquoted(self):
         s = self.dumps(self.adapted)
-        return QuotedString(s).getquoted()
+        qs = QuotedString(s)
+        if self._conn is not None:
+            qs.prepare(self._conn)
+        return qs.getquoted()
 
     if sys.version_info < (3,):
         def __str__(self):
diff --git a/lib/errorcodes.py b/lib/errorcodes.py
index f56e25a..24fcf25 100644
--- a/lib/errorcodes.py
+++ b/lib/errorcodes.py
@@ -93,6 +93,7 @@ CLASS_PROGRAM_LIMIT_EXCEEDED = '54'
 CLASS_OBJECT_NOT_IN_PREREQUISITE_STATE = '55'
 CLASS_OPERATOR_INTERVENTION = '57'
 CLASS_SYSTEM_ERROR = '58'
+CLASS_SNAPSHOT_FAILURE = '72'
 CLASS_CONFIGURATION_FILE_ERROR = 'F0'
 CLASS_FOREIGN_DATA_WRAPPER_ERROR = 'HV'
 CLASS_PL_PGSQL_ERROR = 'P0'
@@ -172,6 +173,7 @@ INVALID_USE_OF_ESCAPE_CHARACTER = '2200C'
 INVALID_ESCAPE_OCTET = '2200D'
 ZERO_LENGTH_CHARACTER_STRING = '2200F'
 MOST_SPECIFIC_TYPE_MISMATCH = '2200G'
+SEQUENCE_GENERATOR_LIMIT_EXCEEDED = '2200H'
 NOT_AN_XML_DOCUMENT = '2200L'
 INVALID_XML_DOCUMENT = '2200M'
 INVALID_XML_CONTENT = '2200N'
@@ -233,6 +235,7 @@ SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED = '25007'
 HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL = '25008'
 NO_ACTIVE_SQL_TRANSACTION = '25P01'
 IN_FAILED_SQL_TRANSACTION = '25P02'
+IDLE_IN_TRANSACTION_SESSION_TIMEOUT = '25P03'
 
 # Class 26 - Invalid SQL Statement Name
 INVALID_SQL_STATEMENT_NAME = '26000'
@@ -314,6 +317,7 @@ WRONG_OBJECT_TYPE = '42809'
 INVALID_FOREIGN_KEY = '42830'
 CANNOT_COERCE = '42846'
 UNDEFINED_FUNCTION = '42883'
+GENERATED_ALWAYS = '428C9'
 RESERVED_NAME = '42939'
 UNDEFINED_TABLE = '42P01'
 UNDEFINED_PARAMETER = '42P02'
@@ -359,6 +363,7 @@ OBJECT_NOT_IN_PREREQUISITE_STATE = '55000'
 OBJECT_IN_USE = '55006'
 CANT_CHANGE_RUNTIME_PARAM = '55P02'
 LOCK_NOT_AVAILABLE = '55P03'
+UNSAFE_NEW_ENUM_VALUE_USAGE = '55P04'
 
 # Class 57 - Operator Intervention
 OPERATOR_INTERVENTION = '57000'
@@ -374,6 +379,9 @@ IO_ERROR = '58030'
 UNDEFINED_FILE = '58P01'
 DUPLICATE_FILE = '58P02'
 
+# Class 72 - Snapshot Failure
+SNAPSHOT_TOO_OLD = '72000'
+
 # Class F0 - Configuration File Error
 CONFIG_FILE_ERROR = 'F0000'
 LOCK_FILE_EXISTS = 'F0001'
diff --git a/lib/extensions.py b/lib/extensions.py
index 00d71f0..91b8133 100644
--- a/lib/extensions.py
+++ b/lib/extensions.py
@@ -43,16 +43,16 @@ from psycopg2._psycopg import (                             # noqa
 
 try:
     from psycopg2._psycopg import (                         # noqa
-        MXDATE, MXDATETIME, MXINTERVAL, MXTIME,
-        MXDATEARRAY, MXDATETIMEARRAY, MXINTERVALARRAY, MXTIMEARRAY,
+        MXDATE, MXDATETIME, MXDATETIMETZ, MXINTERVAL, MXTIME, MXDATEARRAY,
+        MXDATETIMEARRAY, MXDATETIMETZARRAY, MXINTERVALARRAY, MXTIMEARRAY,
         DateFromMx, TimeFromMx, TimestampFromMx, IntervalFromMx, )
 except ImportError:
     pass
 
 try:
     from psycopg2._psycopg import (                         # noqa
-        PYDATE, PYDATETIME, PYINTERVAL, PYTIME,
-        PYDATEARRAY, PYDATETIMEARRAY, PYINTERVALARRAY, PYTIMEARRAY,
+        PYDATE, PYDATETIME, PYDATETIMETZ, PYINTERVAL, PYTIME, PYDATEARRAY,
+        PYDATETIMEARRAY, PYDATETIMETZARRAY, PYINTERVALARRAY, PYTIMEARRAY,
         DateFromPy, TimeFromPy, TimestampFromPy, IntervalFromPy, )
 except ImportError:
     pass
diff --git a/lib/extras.py b/lib/extras.py
index 9e16165..69c7f32 100644
--- a/lib/extras.py
+++ b/lib/extras.py
@@ -1178,6 +1178,9 @@ def execute_batch(cur, sql, argslist, page_size=100):
     fewer multi-statement commands, each one containing at most *page_size*
     statements, resulting in a reduced number of server roundtrips.
 
+    After the execution of the functtion the `cursor.rowcount` property will
+    **not** contain a total result.
+
     """
     for page in _paginate(argslist, page_size=page_size):
         sqls = [cur.mogrify(sql, args) for args in page]
@@ -1212,6 +1215,9 @@ def execute_values(cur, sql, argslist, template=None, page_size=100):
 
     .. __: https://www.postgresql.org/docs/current/static/queries-values.html
 
+    After the execution of the functtion the `cursor.rowcount` property will
+    **not** contain a total result.
+
     While :sql:`INSERT` is an obvious candidate for this function it is
     possible to use it with other statements, for example::
 
diff --git a/lib/pool.py b/lib/pool.py
index e57875c..a91c9cc 100644
--- a/lib/pool.py
+++ b/lib/pool.py
@@ -25,7 +25,7 @@ This module implements thread-safe (and not) connection pools.
 # License for more details.
 
 import psycopg2
-import psycopg2.extensions as _ext
+from psycopg2 import extensions as _ext
 
 
 class PoolError(psycopg2.Error):
diff --git a/lib/psycopg1.py b/lib/psycopg1.py
index 3808aaa..0ee7942 100644
--- a/lib/psycopg1.py
+++ b/lib/psycopg1.py
@@ -28,12 +28,12 @@ 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 psycopg2._psycopg as _2psycopg   # noqa
+from psycopg2 import _psycopg as _2psycopg   # noqa
 from psycopg2.extensions import cursor as _2cursor
 from psycopg2.extensions import connection as _2connection
 
 from psycopg2 import *      # noqa
-import psycopg2.extensions as _ext
+from psycopg2 import extensions as _ext
 _2connect = connect
 
 
diff --git a/lib/sql.py b/lib/sql.py
index e7d42e6..d89e117 100644
--- a/lib/sql.py
+++ b/lib/sql.py
@@ -1,7 +1,7 @@
 """SQL composition utility module
 """
 
-# psycopg/sql.py - Implementation of the JSON adaptation objects
+# psycopg/sql.py - SQL composition utility module
 #
 # Copyright (C) 2016 Daniele Varrazzo  <daniele.varrazzo at gmail.com>
 #
@@ -36,8 +36,9 @@ class Composable(object):
     """
     Abstract base class for objects that can be used to compose an SQL string.
 
-    `!Composable` objects can be passed directly to `~cursor.execute()` and
-    `~cursor.executemany()` in place of the query string.
+    `!Composable` objects can be passed directly to `~cursor.execute()`,
+    `~cursor.executemany()`, `~cursor.copy_expert()` in place of the query
+    string.
 
     `!Composable` objects can be joined using the ``+`` operator: the result
     will be a `Composed` instance containing the objects joined. The operator
@@ -58,9 +59,9 @@ class Composable(object):
         :param context: the context to evaluate the string into.
         :type context: `connection` or `cursor`
 
-        The method is automatically invoked by `~cursor.execute()` and
-        `~cursor.executemany()` if a `!Composable` is passed instead of the
-        query string.
+        The method is automatically invoked by `~cursor.execute()`,
+        `~cursor.executemany()`, `~cursor.copy_expert()` if a `!Composable` is
+        passed instead of the query string.
         """
         raise NotImplementedError
 
@@ -84,11 +85,11 @@ class Composable(object):
 
 class Composed(Composable):
     """
-    A `Composable` object made of a sequence of `Composable`.
+    A `Composable` object made of a sequence of `!Composable`.
 
-    The object is usually created using `Composable` operators and methods.
+    The object is usually created using `!Composable` operators and methods.
     However it is possible to create a `!Composed` directly specifying a
-    sequence of `Composable` as arguments.
+    sequence of `!Composable` as arguments.
 
     Example::
 
@@ -290,9 +291,9 @@ class Identifier(Composable):
     """
     A `Composable` representing an SQL identifer.
 
-    Identifiers usually represent names of database objects, such as tables
-    or fields. They follow `different rules`__ than SQL string literals for
-    escaping (e.g. they use double quotes).
+    Identifiers usually represent names of database objects, such as tables or
+    fields. PostgreSQL identifiers follow `different rules`__ than SQL string
+    literals for escaping (e.g. they use double quotes instead of single).
 
     .. __: https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html# \
         SQL-SYNTAX-IDENTIFIERS
diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c
index 26100b2..8c5085b 100644
--- a/psycopg/connection_type.c
+++ b/psycopg/connection_type.c
@@ -938,7 +938,7 @@ psyco_conn_lobject(connectionObject *self, PyObject *args, PyObject *keywds)
     PyObject *obj;
 
     static char *kwlist[] = {"oid", "mode", "new_oid", "new_file",
-                             "cursor_factory", NULL};
+                             "lobject_factory", NULL};
 
     if (!PyArg_ParseTupleAndKeywords(args, keywds, "|IzIzO", kwlist,
                                      &oid, &smode, &new_oid, &new_file,
@@ -1248,10 +1248,58 @@ static struct PyGetSetDef connectionObject_getsets[] = {
 
 /* initialization and finalization methods */
 
+RAISES_NEG static int
+obscure_password(connectionObject *conn)
+{
+    PQconninfoOption *options;
+    PyObject *d = NULL, *v = NULL, *dsn = NULL;
+    char *tmp;
+    int rv = -1;
+
+    if (!conn || !conn->dsn) {
+        return 0;
+    }
+
+    if (!(options = PQconninfoParse(conn->dsn, NULL))) {
+        /* unlikely: the dsn was already tested valid */
+        return 0;
+    }
+
+    if (!(d = psycopg_dict_from_conninfo_options(
+            options, /* include_password = */ 1))) {
+        goto exit;
+    }
+    if (NULL == PyDict_GetItemString(d, "password")) {
+        /* the dsn doesn't have a password */
+        rv = 0;
+        goto exit;
+    }
+
+    /* scrub the password and put back the connection string together */
+    if (!(v = Text_FromUTF8("xxx"))) { goto exit; }
+    if (0 > PyDict_SetItemString(d, "password", v)) { goto exit; }
+    if (!(dsn = psycopg_make_dsn(Py_None, d))) { goto exit; }
+    if (!(dsn = psycopg_ensure_bytes(dsn))) { goto exit; }
+
+    /* Replace the connection string on the connection object */
+    tmp = conn->dsn;
+    psycopg_strdup(&conn->dsn, Bytes_AS_STRING(dsn), -1);
+    PyMem_Free(tmp);
+
+    rv = 0;
+
+exit:
+    PQconninfoFree(options);
+    Py_XDECREF(v);
+    Py_XDECREF(d);
+    Py_XDECREF(dsn);
+
+    return rv;
+}
+
 static int
 connection_setup(connectionObject *self, const char *dsn, long int async)
 {
-    char *pos;
     int res = -1;
 
     Dprintf("connection_setup: init connection object at %p, "
@@ -1288,15 +1336,16 @@ connection_setup(connectionObject *self, const char *dsn, long int async)
 
 exit:
     /* here we obfuscate the password even if there was a connection error */
-    pos = strstr(self->dsn, "password");
-    if (pos != NULL) {
-        for (pos = pos+9 ; *pos != '\0' && *pos != ' '; pos++)
-            *pos = 'x';
+    {
+        PyObject *ptype = NULL, *pvalue = NULL, *ptb = NULL;
+        PyErr_Fetch(&ptype, &pvalue, &ptb);
+        obscure_password(self);
+        PyErr_Restore(ptype, pvalue, ptb);
     }
-
     return res;
 }
 
+
 static int
 connection_clear(connectionObject *self)
 {
diff --git a/psycopg/cursor.h b/psycopg/cursor.h
index 3c94fe3..d89bf21 100644
--- a/psycopg/cursor.h
+++ b/psycopg/cursor.h
@@ -95,6 +95,7 @@ BORROWED HIDDEN PyObject *curs_get_cast(cursorObject *self, PyObject *oid);
 HIDDEN void curs_reset(cursorObject *self);
 HIDDEN int psyco_curs_withhold_set(cursorObject *self, PyObject *pyvalue);
 HIDDEN int psyco_curs_scrollable_set(cursorObject *self, PyObject *pyvalue);
+HIDDEN PyObject *psyco_curs_validate_sql_basic(cursorObject *self, PyObject *sql);
 
 /* exception-raising macros */
 #define EXC_IF_CURS_CLOSED(self) \
diff --git a/psycopg/cursor_int.c b/psycopg/cursor_int.c
index dd4c0d7..bacef77 100644
--- a/psycopg/cursor_int.c
+++ b/psycopg/cursor_int.c
@@ -80,3 +80,83 @@ curs_reset(cursorObject *self)
     Py_CLEAR(self->description);
     Py_CLEAR(self->casts);
 }
+
+
+/* Return 1 if `obj` is a `psycopg2.sql.Composable` instance, else 0
+ * Set an exception and return -1 in case of error.
+ */
+RAISES_NEG static int
+_curs_is_composible(PyObject *obj)
+{
+    int rv = -1;
+    PyObject *m = NULL;
+    PyObject *comp = NULL;
+
+    if (!(m = PyImport_ImportModule("psycopg2.sql"))) { goto exit; }
+    if (!(comp = PyObject_GetAttrString(m, "Composable"))) { goto exit; }
+    rv = PyObject_IsInstance(obj, comp);
+
+exit:
+    Py_XDECREF(comp);
+    Py_XDECREF(m);
+    return rv;
+
+}
+
+/* Performs very basic validation on an incoming SQL string.
+ * Returns a new reference to a str instance on success; NULL on failure,
+ * after having set an exception.
+ */
+PyObject *
+psyco_curs_validate_sql_basic(cursorObject *self, PyObject *sql)
+{
+    PyObject *rv = NULL;
+    PyObject *comp = NULL;
+    int iscomp;
+
+    if (!sql || !PyObject_IsTrue(sql)) {
+        psyco_set_error(ProgrammingError, self,
+                         "can't execute an empty query");
+        goto exit;
+    }
+
+    if (Bytes_Check(sql)) {
+        /* Necessary for ref-count symmetry with the unicode case: */
+        Py_INCREF(sql);
+        rv = sql;
+    }
+    else if (PyUnicode_Check(sql)) {
+        if (!(rv = conn_encode(self->conn, sql))) { goto exit; }
+    }
+    else if (0 != (iscomp = _curs_is_composible(sql))) {
+        if (iscomp < 0) { goto exit; }
+        if (!(comp = PyObject_CallMethod(sql, "as_string", "O", self->conn))) {
+            goto exit;
+        }
+
+        if (Bytes_Check(comp)) {
+            rv = comp;
+            comp = NULL;
+        }
+        else if (PyUnicode_Check(comp)) {
+            if (!(rv = conn_encode(self->conn, comp))) { goto exit; }
+        }
+        else {
+            PyErr_Format(PyExc_TypeError,
+                "as_string() should return a string: got %s instead",
+                Py_TYPE(comp)->tp_name);
+            goto exit;
+        }
+    }
+    else {
+        /* the  is not unicode or string, raise an error */
+        PyErr_Format(PyExc_TypeError,
+            "argument 1 must be a string or unicode object: got %s instead",
+            Py_TYPE(sql)->tp_name);
+        goto exit;
+    }
+
+exit:
+    Py_XDECREF(comp);
+    return rv;
+}
diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c
index 5031033..a70e9d3 100644
--- a/psycopg/cursor_type.c
+++ b/psycopg/cursor_type.c
@@ -267,85 +267,6 @@ _mogrify(PyObject *var, PyObject *fmt, cursorObject *curs, PyObject **new)
     return 0;
 }
 
-/* Return 1 if `obj` is a `psycopg2.sql.Composable` instance, else 0
- * Set an exception and return -1 in case of error.
- */
-RAISES_NEG static int
-_curs_is_composible(PyObject *obj)
-{
-    int rv = -1;
-    PyObject *m = NULL;
-    PyObject *comp = NULL;
-
-    if (!(m = PyImport_ImportModule("psycopg2.sql"))) { goto exit; }
-    if (!(comp = PyObject_GetAttrString(m, "Composable"))) { goto exit; }
-    rv = PyObject_IsInstance(obj, comp);
-
-exit:
-    Py_XDECREF(comp);
-    Py_XDECREF(m);
-    return rv;
-
-}
-
-static PyObject *_psyco_curs_validate_sql_basic(
-    cursorObject *self, PyObject *sql
-  )
-{
-    PyObject *rv = NULL;
-    PyObject *comp = NULL;
-    int iscomp;
-
-    /* Performs very basic validation on an incoming SQL string.
-       Returns a new reference to a str instance on success; NULL on failure,
-       after having set an exception. */
-
-    if (!sql || !PyObject_IsTrue(sql)) {
-        psyco_set_error(ProgrammingError, self,
-                         "can't execute an empty query");
-        goto exit;
-    }
-
-    if (Bytes_Check(sql)) {
-        /* Necessary for ref-count symmetry with the unicode case: */
-        Py_INCREF(sql);
-        rv = sql;
-    }
-    else if (PyUnicode_Check(sql)) {
-        if (!(rv = conn_encode(self->conn, sql))) { goto exit; }
-    }
-    else if (0 != (iscomp = _curs_is_composible(sql))) {
-        if (iscomp < 0) { goto exit; }
-        if (!(comp = PyObject_CallMethod(sql, "as_string", "O", self->conn))) {
-            goto exit;
-        }
-
-        if (Bytes_Check(comp)) {
-            rv = comp;
-            comp = NULL;
-        }
-        else if (PyUnicode_Check(comp)) {
-            if (!(rv = conn_encode(self->conn, comp))) { goto exit; }
-        }
-        else {
-            PyErr_Format(PyExc_TypeError,
-                "as_string() should return a string: got %s instead",
-                Py_TYPE(comp)->tp_name);
-            goto exit;
-        }
-    }
-    else {
-        /* the  is not unicode or string, raise an error */
-        PyErr_Format(PyExc_TypeError,
-            "argument 1 must be a string or unicode object: got %s instead",
-            Py_TYPE(sql)->tp_name);
-        goto exit;
-    }
-
-exit:
-    Py_XDECREF(comp);
-    return rv;
-}
 
 /* Merge together a query string and its arguments.
  *
@@ -425,7 +346,7 @@ _psyco_curs_execute(cursorObject *self,
     PyObject *fquery, *cvt = NULL;
     const char *scroll;
 
-    operation = _psyco_curs_validate_sql_basic(self, operation);
+    operation = psyco_curs_validate_sql_basic(self, operation);
 
     /* Any failure from here forward should 'goto fail' rather than 'return 0'
        directly. */
@@ -622,7 +543,7 @@ _psyco_curs_mogrify(cursorObject *self,
 {
... 1546 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