[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