[Python-modules-commits] [aiopg] 01/03: Import aiopg_0.13.0.orig.tar.gz

Piotr Ożarowski piotr at moszumanska.debian.org
Wed Dec 21 11:25:01 UTC 2016


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

piotr pushed a commit to branch master
in repository aiopg.

commit 181e65ac1649d3c59d25f2f5f89de27d5cd07bf9
Author: Piotr Ożarowski <piotr at debian.org>
Date:   Wed Dec 21 12:20:02 2016 +0100

    Import aiopg_0.13.0.orig.tar.gz
---
 CHANGES.txt                 | 14 ++++++++++++++
 PKG-INFO                    | 16 +++++++++++++++-
 aiopg.egg-info/PKG-INFO     | 16 +++++++++++++++-
 aiopg.egg-info/requires.txt |  2 +-
 aiopg/__init__.py           |  2 +-
 aiopg/connection.py         | 36 +++++++++++++++++++++++++++++-------
 aiopg/sa/connection.py      | 23 +++++++++++++++++------
 aiopg/sa/engine.py          | 23 +++++++++++++++++++++--
 aiopg/sa/result.py          | 15 +++++++++++++--
 setup.py                    |  2 +-
 10 files changed, 127 insertions(+), 22 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 9b6dcd8..f3a77af 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,20 @@
 CHANGES
 -------
 
+0.13.0 (2016-12-02)
+^^^^^^^^^^^^^^^^^^^
+
+* Add `async with` support to `.begin_nested()` #208
+
+* Fix connection.cancel() #212 #223
+
+* Raise informative error on unexpected connection closing #191
+
+* Added support for python types columns issues #217
+
+* Added support for default values in SA table issues #206
+
+
 0.12.0 (2016-10-09)
 ^^^^^^^^^^^^^^^^^^^
 
diff --git a/PKG-INFO b/PKG-INFO
index 21d4917..f4aafa9 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: aiopg
-Version: 0.12.0
+Version: 0.13.0
 Summary: Postgres integration with asyncio.
 Home-page: https://aiopg.readthedocs.io
 Author: Andrew Svetlov
@@ -95,6 +95,20 @@ Description: aiopg
         CHANGES
         -------
         
+        0.13.0 (2016-12-02)
+        ^^^^^^^^^^^^^^^^^^^
+        
+        * Add `async with` support to `.begin_nested()` #208
+        
+        * Fix connection.cancel() #212 #223
+        
+        * Raise informative error on unexpected connection closing #191
+        
+        * Added support for python types columns issues #217
+        
+        * Added support for default values in SA table issues #206
+        
+        
         0.12.0 (2016-10-09)
         ^^^^^^^^^^^^^^^^^^^
         
diff --git a/aiopg.egg-info/PKG-INFO b/aiopg.egg-info/PKG-INFO
index 21d4917..f4aafa9 100644
--- a/aiopg.egg-info/PKG-INFO
+++ b/aiopg.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: aiopg
-Version: 0.12.0
+Version: 0.13.0
 Summary: Postgres integration with asyncio.
 Home-page: https://aiopg.readthedocs.io
 Author: Andrew Svetlov
@@ -95,6 +95,20 @@ Description: aiopg
         CHANGES
         -------
         
+        0.13.0 (2016-12-02)
+        ^^^^^^^^^^^^^^^^^^^
+        
+        * Add `async with` support to `.begin_nested()` #208
+        
+        * Fix connection.cancel() #212 #223
+        
+        * Raise informative error on unexpected connection closing #191
+        
+        * Added support for python types columns issues #217
+        
+        * Added support for default values in SA table issues #206
+        
+        
         0.12.0 (2016-10-09)
         ^^^^^^^^^^^^^^^^^^^
         
diff --git a/aiopg.egg-info/requires.txt b/aiopg.egg-info/requires.txt
index 223e082..dd36c53 100644
--- a/aiopg.egg-info/requires.txt
+++ b/aiopg.egg-info/requires.txt
@@ -1,4 +1,4 @@
 psycopg2>=2.5.2
 
 [sa]
-sqlalchemy>=0.9
+sqlalchemy>=1.1
diff --git a/aiopg/__init__.py b/aiopg/__init__.py
index 76d9924..bf467c9 100644
--- a/aiopg/__init__.py
+++ b/aiopg/__init__.py
@@ -10,7 +10,7 @@ from .pool import create_pool, Pool
 __all__ = ('connect', 'create_pool', 'Connection', 'Cursor', 'Pool',
            'version', 'version_info', 'DEFAULT_TIMEOUT')
 
-__version__ = '0.12.0'
+__version__ = '0.13.0'
 
 version = __version__ + ' , Python ' + sys.version
 
diff --git a/aiopg/connection.py b/aiopg/connection.py
index 98af36b..8718bec 100755
--- a/aiopg/connection.py
+++ b/aiopg/connection.py
@@ -113,6 +113,8 @@ class Connection:
         self._timeout = timeout
         self._waiter = waiter
         self._writing = False
+        self._cancelling = False
+        self._cancellation_waiter = None
         self._echo = echo
         self._notifies = asyncio.Queue(loop=loop)
         self._weakref = weakref.ref(self)
@@ -159,6 +161,11 @@ class Connection:
             if waiter is not None and not waiter.done():
                 waiter.set_exception(exc)
         else:
+            if self._fileno is None:
+                # connection closed
+                if waiter is not None and not waiter.done():
+                    waiter.set_exception(
+                        psycopg2.OperationalError("Connection closed"))
             if state == POLL_OK:
                 if self._writing:
                     self._loop.remove_writer(self._fileno)
@@ -194,8 +201,14 @@ class Connection:
 
     def _create_waiter(self, func_name):
         if self._waiter is not None:
-            raise RuntimeError('%s() called while another coroutine is '
-                               'already waiting for incoming data' % func_name)
+            if self._cancelling:
+                if not self._waiter.done():
+                    raise RuntimeError('%s() called while connection is '
+                                       'being cancelled' % func_name)
+            else:
+                raise RuntimeError('%s() called while another coroutine is '
+                                   'already waiting for incoming '
+                                   'data' % func_name)
         self._waiter = create_future(self._loop)
         return self._waiter
 
@@ -207,7 +220,11 @@ class Connection:
         @asyncio.coroutine
         def cancel():
             self._waiter = create_future(self._loop)
+            self._cancelling = True
+            self._cancellation_waiter = self._waiter
             self._conn.cancel()
+            if not self._conn.isexecuting():
+                return
             try:
                 yield from asyncio.wait_for(self._waiter, timeout,
                                             loop=self._loop)
@@ -221,8 +238,16 @@ class Connection:
         except (asyncio.CancelledError, asyncio.TimeoutError) as exc:
             yield from asyncio.shield(cancel(), loop=self._loop)
             raise exc
+        except psycopg2.extensions.QueryCanceledError:
+            raise asyncio.CancelledError
         finally:
-            self._waiter = None
+            if self._cancelling:
+                self._cancelling = False
+                if self._waiter is self._cancellation_waiter:
+                    self._waiter = None
+                self._cancellation_waiter = None
+            else:
+                self._waiter = None
 
     def _isexecuting(self):
         return self._conn.isexecuting()
@@ -346,14 +371,11 @@ class Connection:
     @asyncio.coroutine
     def cancel(self):
         """Cancel the current database operation."""
-        if self._waiter is not None:
-            self._waiter.cancel()
-        if not self._isexecuting():
+        if self._waiter is None:
             return
 
         @asyncio.coroutine
         def cancel():
-            self._waiter = create_future(self._loop)
             self._conn.cancel()
             try:
                 yield from self._waiter
diff --git a/aiopg/sa/connection.py b/aiopg/sa/connection.py
index 7897e89..83c9c2c 100644
--- a/aiopg/sa/connection.py
+++ b/aiopg/sa/connection.py
@@ -1,8 +1,8 @@
 import asyncio
 
 from sqlalchemy.sql import ClauseElement
-from sqlalchemy.sql.dml import UpdateBase
 from sqlalchemy.sql.ddl import DDLElement
+from sqlalchemy.sql.dml import UpdateBase
 
 from . import exc
 from .result import ResultProxy
@@ -12,7 +12,6 @@ from ..utils import _SAConnectionContextManager, _TransactionContextManager
 
 
 class SAConnection:
-
     def __init__(self, connection, engine):
         self._connection = connection
         self._transaction = None
@@ -69,6 +68,8 @@ class SAConnection:
         elif dp:
             dp = dp[0]
 
+        result_map = None
+
         if isinstance(query, str):
             yield from cursor.execute(query, dp)
         elif isinstance(query, ClauseElement):
@@ -83,8 +84,8 @@ class SAConnection:
                         raise exc.ArgumentError("Don't mix sqlalchemy SELECT "
                                                 "clause with positional "
                                                 "parameters")
-                compiled_parameters = [compiled.construct_params(
-                    dp)]
+
+                compiled_parameters = [compiled.construct_params(dp)]
                 processed_parameters = []
                 processors = compiled._bind_processors
                 for compiled_params in compiled_parameters:
@@ -95,18 +96,24 @@ class SAConnection:
                     processed_parameters.append(params)
                 post_processed_params = self._dialect.execute_sequence_format(
                     processed_parameters)
+
+                # _result_columns is a private API of Compiled,
+                # but I couldn't find any public API exposing this data.
+                result_map = compiled._result_columns
+
             else:
                 if dp:
                     raise exc.ArgumentError("Don't mix sqlalchemy DDL clause "
                                             "and execution with parameters")
                 post_processed_params = [compiled.construct_params()]
+                result_map = None
             yield from cursor.execute(str(compiled), post_processed_params[0])
         else:
             raise exc.ArgumentError("sql statement should be str or "
                                     "SQLAlchemy data "
                                     "selection/modification clause")
 
-        return ResultProxy(self, cursor, self._dialect)
+        return ResultProxy(self, cursor, self._dialect, result_map)
 
     @asyncio.coroutine
     def scalar(self, query, *multiparams, **params):
@@ -192,7 +199,6 @@ class SAConnection:
             cur.close()
             self._transaction = None
 
-    @asyncio.coroutine
     def begin_nested(self):
         """Begin a nested transaction and return a transaction handle.
 
@@ -204,6 +210,11 @@ class SAConnection:
         still controls the overall .commit() or .rollback() of the
         transaction of a whole.
         """
+        coro = self._begin_nested()
+        return _TransactionContextManager(coro)
+
+    @asyncio.coroutine
+    def _begin_nested(self):
         if self._transaction is None:
             self._transaction = RootTransaction(self)
             yield from self._begin_impl()
diff --git a/aiopg/sa/engine.py b/aiopg/sa/engine.py
index 8987139..6b1cbd4 100644
--- a/aiopg/sa/engine.py
+++ b/aiopg/sa/engine.py
@@ -2,20 +2,39 @@ import asyncio
 import json
 
 import aiopg
+
 from .connection import SAConnection
 from .exc import InvalidRequestError
-from ..utils import PY_35, _PoolContextManager, _PoolAcquireContextManager
 from ..connection import TIMEOUT
-
+from ..utils import PY_35, _PoolContextManager, _PoolAcquireContextManager
 
 try:
     from sqlalchemy.dialects.postgresql.psycopg2 import PGDialect_psycopg2
+    from sqlalchemy.dialects.postgresql.psycopg2 import PGCompiler_psycopg2
 except ImportError:  # pragma: no cover
     raise ImportError('aiopg.sa requires sqlalchemy')
 
 
+class APGCompiler_psycopg2(PGCompiler_psycopg2):
+    def construct_params(self, params=None, _group_number=None, _check=True):
+        pd = super().construct_params(params, _group_number, _check)
+
+        for column in self.prefetch:
+            pd[column.key] = self._exec_default(column.default)
+
+        return pd
+
+    def _exec_default(self, default):
+        if default.is_callable:
+            return default.arg(self.dialect)
+        else:
+            return default.arg
+
+
 _dialect = PGDialect_psycopg2(json_serializer=json.dumps,
                               json_deserializer=lambda x: x)
+
+_dialect.statement_compiler = APGCompiler_psycopg2
 _dialect.implicit_returning = True
 _dialect.supports_native_enum = True
 _dialect.supports_smallserial = True  # 9.2+
diff --git a/aiopg/sa/result.py b/aiopg/sa/result.py
index 6452814..1e47c4c 100644
--- a/aiopg/sa/result.py
+++ b/aiopg/sa/result.py
@@ -89,6 +89,11 @@ class ResultMetaData(object):
     def __init__(self, result_proxy, metadata):
         self._processors = processors = []
 
+        result_map = {}
+        if result_proxy._result_map:
+            result_map = {elem[0]: elem[3] for elem in
+                          result_proxy._result_map}
+
         # We do not strictly need to store the processor in the key mapping,
         # though it is faster in the Python version (probably because of the
         # saved attribute lookup self._processors)
@@ -113,8 +118,13 @@ class ResultMetaData(object):
             # if dialect.requires_name_normalize:
             #     colname = dialect.normalize_name(colname)
 
-            name, obj, type_ = \
-                colname, None, typemap.get(coltype, sqltypes.NULLTYPE)
+            name, obj, type_ = (
+                colname,
+                None,
+                result_map.get(
+                    colname,
+                    typemap.get(coltype, sqltypes.NULLTYPE))
+            )
 
             processor = type_._cached_result_processor(dialect, coltype)
 
@@ -215,6 +225,7 @@ class ResultProxy:
     def __init__(self, connection, cursor, dialect, result_map=None):
         self._dialect = dialect
         self._closed = False
+        self._result_map = result_map
         self._cursor = cursor
         self._connection = connection
         self._rowcount = cursor.rowcount
diff --git a/setup.py b/setup.py
index 726fcb5..94ae7e0 100644
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,7 @@ if PY_VER < (3, 4):
 def read(f):
     return open(os.path.join(os.path.dirname(__file__), f)).read().strip()
 
-extras_require = {'sa': ['sqlalchemy>=0.9'], }
+extras_require = {'sa': ['sqlalchemy>=1.1'], }
 
 
 def read_version():

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



More information about the Python-modules-commits mailing list