[Python-modules-commits] [aiopg] 01/03: Import aiopg_0.9.2.orig.tar.gz
Piotr Ożarowski
piotr at moszumanska.debian.org
Thu Apr 14 18:51:37 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 4cae258b3ea012dd941c52173a67b4a07df68c70
Author: Piotr Ożarowski <piotr at debian.org>
Date: Thu Apr 14 20:47:20 2016 +0200
Import aiopg_0.9.2.orig.tar.gz
---
CHANGES.txt | 33 +++++++
PKG-INFO | 97 +++++++++++++-------
README.rst | 60 ++++++------
aiopg.egg-info/PKG-INFO | 97 +++++++++++++-------
aiopg.egg-info/SOURCES.txt | 1 +
aiopg.egg-info/requires.txt | 2 +-
aiopg.egg-info/top_level.txt | 1 -
aiopg/__init__.py | 2 +-
aiopg/connection.py | 174 ++++++++++++++++++++++++-----------
aiopg/cursor.py | 29 +++++-
aiopg/pool.py | 135 +++++++++++----------------
aiopg/sa/connection.py | 14 ++-
aiopg/sa/engine.py | 42 ++++++++-
aiopg/sa/result.py | 14 +++
aiopg/sa/transaction.py | 14 +++
aiopg/utils.py | 214 +++++++++++++++++++++++++++++++++++++++++++
setup.cfg | 4 +-
setup.py | 4 +-
18 files changed, 691 insertions(+), 246 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index a32784e..07bc8c4 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,39 @@
CHANGES
-------
+0.9.2 (2016-01-31)
+^^^^^^^^^^^^^^^^^^
+
+* Make pool.release return asyncio.Future, so we can wait on it in
+ `__aexit__` #102
+
+* Add support for uuid type #103
+
+0.9.1 (2016-01-17)
+^^^^^^^^^^^^^^^^^^
+
+* Documentation update #101
+
+0.9.0 (2016-01-14)
+^^^^^^^^^^^^^^^^^^
+
+* Add async context managers for transactions #91
+
+* Support async iterator in ResultProxy #92
+
+* Add async with for engine #90
+
+0.8.0 (2015-12-31)
+^^^^^^^^^^^^^^^^^^
+
+* Add PostgreSQL notification support #58
+
+* Support pools with unlimited size #59
+
+* Cancel current DB operation on asyncio timeout #66
+
+* Add async with support for Pool, Connection, Cursor #88
+
0.7.0 (2015-04-22)
^^^^^^^^^^^^^^^^^^
diff --git a/PKG-INFO b/PKG-INFO
index 292c121..ec5334c 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: aiopg
-Version: 0.7.0
+Version: 0.9.2
Summary: Postgres integration with asyncio.
Home-page: http://aiopg.readthedocs.org
Author: Andrew Svetlov
@@ -8,7 +8,7 @@ Author-email: andrew.svetlov at gmail.com
License: BSD
Download-URL: https://pypi.python.org/pypi/aiopg
Description: aiopg
- =======
+ =====
.. image:: https://travis-ci.org/aio-libs/aiopg.svg?branch=master
:target: https://travis-ci.org/aio-libs/aiopg
.. image:: https://coveralls.io/repos/aio-libs/aiopg/badge.svg
@@ -23,24 +23,23 @@ Description: aiopg
::
- import asyncio
- from aiopg.pool import create_pool
-
- dsn = 'dbname=jetty user=nick password=1234 host=localhost port=5432'
-
-
- @asyncio.coroutine
- def test_select():
- pool = yield from create_pool(dsn)
+ import asyncio
+ import aiopg
- with (yield from pool) as conn:
- cur = yield from conn.cursor()
- yield from cur.execute('SELECT 1')
- ret = yield from cur.fetchone()
- assert ret == (1,), ret
+ dsn = 'dbname=aiopg user=aiopg password=passwd host=127.0.0.1'
+ async def go():
+ pool = await aiopg.create_pool(dsn)
+ async with pool.acquire() as conn:
+ async with conn.cursor() as cur:
+ await cur.execute("SELECT 1")
+ ret = []
+ async for row in cur:
+ ret.append(row)
+ assert ret == [(1,)]
- asyncio.get_event_loop().run_until_complete(test_select())
+ loop = asyncio.get_event_loop()
+ loop.run_until_complete(go())
Example of SQLAlchemy optional integration
@@ -50,9 +49,9 @@ Description: aiopg
import asyncio
from aiopg.sa import create_engine
+ from sqlalchemy.schema import CreateTable
import sqlalchemy as sa
-
metadata = sa.MetaData()
tbl = sa.Table('tbl', metadata,
@@ -60,35 +59,69 @@ Description: aiopg
sa.Column('val', sa.String(255)))
- @asyncio.coroutine
- def go():
- engine = yield from create_engine(user='aiopg',
- database='aiopg',
- host='127.0.0.1',
- password='passwd')
+ async def go():
+ async with create_engine(user='aiopg',
+ database='aiopg',
+ host='127.0.0.1',
+ password='passwd') as engine:
- with (yield from engine) as conn:
- yield from conn.execute(tbl.insert().values(val='abc'))
+ async with engine.acquire() as conn:
+ await conn.execute(tbl.insert().values(val='abc'))
- res = yield from conn.execute(tbl.select())
- for row in res:
+ async for row in conn.execute(tbl.select()):
print(row.id, row.val)
-
asyncio.get_event_loop().run_until_complete(go())
+ For ``yield from`` based code see ``./examples`` folder, files with
+ ``old_style`` part in their names.
+
.. _PostgreSQL: http://www.postgresql.org/
.. _asyncio: http://docs.python.org/3.4/library/asyncio.html
Please use::
- $ python3 runtests.py
+ $ make test
- for executing project's unittests
+ for executing the project's unittests. See CONTRIBUTING.rst for details
+ on how to set up your environment to run the tests.
CHANGES
-------
+ 0.9.2 (2016-01-31)
+ ^^^^^^^^^^^^^^^^^^
+
+ * Make pool.release return asyncio.Future, so we can wait on it in
+ `__aexit__` #102
+
+ * Add support for uuid type #103
+
+ 0.9.1 (2016-01-17)
+ ^^^^^^^^^^^^^^^^^^
+
+ * Documentation update #101
+
+ 0.9.0 (2016-01-14)
+ ^^^^^^^^^^^^^^^^^^
+
+ * Add async context managers for transactions #91
+
+ * Support async iterator in ResultProxy #92
+
+ * Add async with for engine #90
+
+ 0.8.0 (2015-12-31)
+ ^^^^^^^^^^^^^^^^^^
+
+ * Add PostgreSQL notification support #58
+
+ * Support pools with unlimited size #59
+
+ * Cancel current DB operation on asyncio timeout #66
+
+ * Add async with support for Pool, Connection, Cursor #88
+
0.7.0 (2015-04-22)
^^^^^^^^^^^^^^^^^^
@@ -211,5 +244,3 @@ Classifier: Environment :: Web Environment
Classifier: Development Status :: 4 - Beta
Classifier: Topic :: Database
Classifier: Topic :: Database :: Front-Ends
-Requires: psycopg2
-Provides: aiopg
diff --git a/README.rst b/README.rst
index 71ce126..704759c 100644
--- a/README.rst
+++ b/README.rst
@@ -1,5 +1,5 @@
aiopg
-=======
+=====
.. image:: https://travis-ci.org/aio-libs/aiopg.svg?branch=master
:target: https://travis-ci.org/aio-libs/aiopg
.. image:: https://coveralls.io/repos/aio-libs/aiopg/badge.svg
@@ -14,24 +14,23 @@ Example
::
- import asyncio
- from aiopg.pool import create_pool
-
- dsn = 'dbname=jetty user=nick password=1234 host=localhost port=5432'
-
-
- @asyncio.coroutine
- def test_select():
- pool = yield from create_pool(dsn)
+ import asyncio
+ import aiopg
- with (yield from pool) as conn:
- cur = yield from conn.cursor()
- yield from cur.execute('SELECT 1')
- ret = yield from cur.fetchone()
- assert ret == (1,), ret
+ dsn = 'dbname=aiopg user=aiopg password=passwd host=127.0.0.1'
+ async def go():
+ pool = await aiopg.create_pool(dsn)
+ async with pool.acquire() as conn:
+ async with conn.cursor() as cur:
+ await cur.execute("SELECT 1")
+ ret = []
+ async for row in cur:
+ ret.append(row)
+ assert ret == [(1,)]
- asyncio.get_event_loop().run_until_complete(test_select())
+ loop = asyncio.get_event_loop()
+ loop.run_until_complete(go())
Example of SQLAlchemy optional integration
@@ -41,9 +40,9 @@ Example of SQLAlchemy optional integration
import asyncio
from aiopg.sa import create_engine
+ from sqlalchemy.schema import CreateTable
import sqlalchemy as sa
-
metadata = sa.MetaData()
tbl = sa.Table('tbl', metadata,
@@ -51,28 +50,29 @@ Example of SQLAlchemy optional integration
sa.Column('val', sa.String(255)))
- @asyncio.coroutine
- def go():
- engine = yield from create_engine(user='aiopg',
- database='aiopg',
- host='127.0.0.1',
- password='passwd')
+ async def go():
+ async with create_engine(user='aiopg',
+ database='aiopg',
+ host='127.0.0.1',
+ password='passwd') as engine:
- with (yield from engine) as conn:
- yield from conn.execute(tbl.insert().values(val='abc'))
+ async with engine.acquire() as conn:
+ await conn.execute(tbl.insert().values(val='abc'))
- res = yield from conn.execute(tbl.select())
- for row in res:
+ async for row in conn.execute(tbl.select()):
print(row.id, row.val)
-
asyncio.get_event_loop().run_until_complete(go())
+For ``yield from`` based code see ``./examples`` folder, files with
+``old_style`` part in their names.
+
.. _PostgreSQL: http://www.postgresql.org/
.. _asyncio: http://docs.python.org/3.4/library/asyncio.html
Please use::
- $ python3 runtests.py
+ $ make test
-for executing project's unittests
+for executing the project's unittests. See CONTRIBUTING.rst for details
+on how to set up your environment to run the tests.
diff --git a/aiopg.egg-info/PKG-INFO b/aiopg.egg-info/PKG-INFO
index 292c121..ec5334c 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.7.0
+Version: 0.9.2
Summary: Postgres integration with asyncio.
Home-page: http://aiopg.readthedocs.org
Author: Andrew Svetlov
@@ -8,7 +8,7 @@ Author-email: andrew.svetlov at gmail.com
License: BSD
Download-URL: https://pypi.python.org/pypi/aiopg
Description: aiopg
- =======
+ =====
.. image:: https://travis-ci.org/aio-libs/aiopg.svg?branch=master
:target: https://travis-ci.org/aio-libs/aiopg
.. image:: https://coveralls.io/repos/aio-libs/aiopg/badge.svg
@@ -23,24 +23,23 @@ Description: aiopg
::
- import asyncio
- from aiopg.pool import create_pool
-
- dsn = 'dbname=jetty user=nick password=1234 host=localhost port=5432'
-
-
- @asyncio.coroutine
- def test_select():
- pool = yield from create_pool(dsn)
+ import asyncio
+ import aiopg
- with (yield from pool) as conn:
- cur = yield from conn.cursor()
- yield from cur.execute('SELECT 1')
- ret = yield from cur.fetchone()
- assert ret == (1,), ret
+ dsn = 'dbname=aiopg user=aiopg password=passwd host=127.0.0.1'
+ async def go():
+ pool = await aiopg.create_pool(dsn)
+ async with pool.acquire() as conn:
+ async with conn.cursor() as cur:
+ await cur.execute("SELECT 1")
+ ret = []
+ async for row in cur:
+ ret.append(row)
+ assert ret == [(1,)]
- asyncio.get_event_loop().run_until_complete(test_select())
+ loop = asyncio.get_event_loop()
+ loop.run_until_complete(go())
Example of SQLAlchemy optional integration
@@ -50,9 +49,9 @@ Description: aiopg
import asyncio
from aiopg.sa import create_engine
+ from sqlalchemy.schema import CreateTable
import sqlalchemy as sa
-
metadata = sa.MetaData()
tbl = sa.Table('tbl', metadata,
@@ -60,35 +59,69 @@ Description: aiopg
sa.Column('val', sa.String(255)))
- @asyncio.coroutine
- def go():
- engine = yield from create_engine(user='aiopg',
- database='aiopg',
- host='127.0.0.1',
- password='passwd')
+ async def go():
+ async with create_engine(user='aiopg',
+ database='aiopg',
+ host='127.0.0.1',
+ password='passwd') as engine:
- with (yield from engine) as conn:
- yield from conn.execute(tbl.insert().values(val='abc'))
+ async with engine.acquire() as conn:
+ await conn.execute(tbl.insert().values(val='abc'))
- res = yield from conn.execute(tbl.select())
- for row in res:
+ async for row in conn.execute(tbl.select()):
print(row.id, row.val)
-
asyncio.get_event_loop().run_until_complete(go())
+ For ``yield from`` based code see ``./examples`` folder, files with
+ ``old_style`` part in their names.
+
.. _PostgreSQL: http://www.postgresql.org/
.. _asyncio: http://docs.python.org/3.4/library/asyncio.html
Please use::
- $ python3 runtests.py
+ $ make test
- for executing project's unittests
+ for executing the project's unittests. See CONTRIBUTING.rst for details
+ on how to set up your environment to run the tests.
CHANGES
-------
+ 0.9.2 (2016-01-31)
+ ^^^^^^^^^^^^^^^^^^
+
+ * Make pool.release return asyncio.Future, so we can wait on it in
+ `__aexit__` #102
+
+ * Add support for uuid type #103
+
+ 0.9.1 (2016-01-17)
+ ^^^^^^^^^^^^^^^^^^
+
+ * Documentation update #101
+
+ 0.9.0 (2016-01-14)
+ ^^^^^^^^^^^^^^^^^^
+
+ * Add async context managers for transactions #91
+
+ * Support async iterator in ResultProxy #92
+
+ * Add async with for engine #90
+
+ 0.8.0 (2015-12-31)
+ ^^^^^^^^^^^^^^^^^^
+
+ * Add PostgreSQL notification support #58
+
+ * Support pools with unlimited size #59
+
+ * Cancel current DB operation on asyncio timeout #66
+
+ * Add async with support for Pool, Connection, Cursor #88
+
0.7.0 (2015-04-22)
^^^^^^^^^^^^^^^^^^
@@ -211,5 +244,3 @@ Classifier: Environment :: Web Environment
Classifier: Development Status :: 4 - Beta
Classifier: Topic :: Database
Classifier: Topic :: Database :: Front-Ends
-Requires: psycopg2
-Provides: aiopg
diff --git a/aiopg.egg-info/SOURCES.txt b/aiopg.egg-info/SOURCES.txt
index 2bc989d..e5b66bc 100644
--- a/aiopg.egg-info/SOURCES.txt
+++ b/aiopg.egg-info/SOURCES.txt
@@ -8,6 +8,7 @@ aiopg/connection.py
aiopg/cursor.py
aiopg/log.py
aiopg/pool.py
+aiopg/utils.py
aiopg.egg-info/PKG-INFO
aiopg.egg-info/SOURCES.txt
aiopg.egg-info/dependency_links.txt
diff --git a/aiopg.egg-info/requires.txt b/aiopg.egg-info/requires.txt
index 8fa73e6..223e082 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
\ No newline at end of file
+sqlalchemy>=0.9
diff --git a/aiopg.egg-info/top_level.txt b/aiopg.egg-info/top_level.txt
index 1a7dfbe..53fc9ad 100644
--- a/aiopg.egg-info/top_level.txt
+++ b/aiopg.egg-info/top_level.txt
@@ -1,2 +1 @@
aiopg
-tests
diff --git a/aiopg/__init__.py b/aiopg/__init__.py
index d29159e..8458391 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.7.0'
+__version__ = '0.9.2'
version = __version__ + ' , Python ' + sys.version
diff --git a/aiopg/connection.py b/aiopg/connection.py
index 6548808..864e8a4 100644
--- a/aiopg/connection.py
+++ b/aiopg/connection.py
@@ -1,6 +1,9 @@
import asyncio
+import errno
import sys
+import traceback
import warnings
+import weakref
import psycopg2
from psycopg2.extensions import (
@@ -8,13 +11,14 @@ from psycopg2.extensions import (
from psycopg2 import extras
from .cursor import Cursor
+from .utils import _ContextManager, PY_35
__all__ = ('connect',)
TIMEOUT = 60.0
-PY_34 = sys.version_info >= (3, 4)
+PY_341 = sys.version_info >= (3, 4, 1)
@asyncio.coroutine
@@ -35,9 +39,8 @@ def _enable_hstore(conn):
return tuple(rv0), tuple(rv1)
- at asyncio.coroutine
-def connect(dsn=None, *, timeout=TIMEOUT, loop=None,
- enable_json=True, enable_hstore=True, echo=False, **kwargs):
+def connect(dsn=None, *, timeout=TIMEOUT, loop=None, enable_json=True,
+ enable_hstore=True, enable_uuid=True, echo=False, **kwargs):
"""A factory for connecting to PostgreSQL.
The coroutine accepts all parameters that psycopg2.connect() does
@@ -46,6 +49,15 @@ def connect(dsn=None, *, timeout=TIMEOUT, loop=None,
Returns instantiated Connection object.
"""
+ coro = _connect(dsn=dsn, timeout=timeout, loop=loop,
+ enable_json=enable_json, enable_hstore=enable_hstore,
+ enable_uuid=enable_uuid, echo=echo, **kwargs)
+ return _ContextManager(coro)
+
+
+ at asyncio.coroutine
+def _connect(dsn=None, *, timeout=TIMEOUT, loop=None, enable_json=True,
+ enable_hstore=True, enable_uuid=True, echo=False, **kwargs):
if loop is None:
loop = asyncio.get_event_loop()
@@ -58,6 +70,8 @@ def connect(dsn=None, *, timeout=TIMEOUT, loop=None,
raise
if enable_json:
extras.register_default_json(conn._conn)
+ if enable_uuid:
+ extras.register_uuid(conn_or_curs=conn._conn)
if enable_hstore:
oids = yield from _enable_hstore(conn)
if oids is not None:
@@ -74,59 +88,64 @@ class Connection:
"""
+ _source_traceback = None
+
def __init__(self, dsn, loop, timeout, waiter, echo, **kwargs):
self._loop = loop
self._conn = psycopg2.connect(dsn, async=True, **kwargs)
self._dsn = self._conn.dsn
- assert self._conn.isexecuting(), "Is conn async at all???"
+ assert self._conn.isexecuting(), "Is conn an async at all???"
self._fileno = self._conn.fileno()
self._timeout = timeout
self._waiter = waiter
- self._reading = False
self._writing = False
self._echo = echo
- self._ready()
-
- def _ready(self):
- if self._waiter is None:
- self._fatal_error("Fatal error on aiopg connection: "
- "bad state in _ready callback")
+ self._notifies = asyncio.Queue(loop=loop)
+ self._weakref = weakref.ref(self)
+ self._loop.add_reader(self._fileno, self._ready, self._weakref)
+ if loop.get_debug():
+ self._source_traceback = traceback.extract_stack(sys._getframe(1))
+
+ @staticmethod
+ def _ready(weak_self):
+ self = weak_self()
+ if self is None:
return
+ waiter = self._waiter
+
try:
state = self._conn.poll()
+ while self._conn.notifies:
+ notify = self._conn.notifies.pop(0)
+ self._notifies.put_nowait(notify)
except (psycopg2.Warning, psycopg2.Error) as exc:
- if self._reading:
- self._loop.remove_reader(self._fileno)
- self._reading = False
- if self._writing:
- self._loop.remove_writer(self._fileno)
- self._writing = False
- if not self._waiter.cancelled():
- self._waiter.set_exception(exc)
+ try:
+ if self._writing:
+ self._writing = False
+ self._loop.remove_writer(self._fileno)
+ except OSError as exc2:
+ if exc2.errno != errno.EBADF:
+ # EBADF is ok for closed file descriptor
+ # chain exception otherwise
+ exc2.__cause__ = exc
+ exc = exc2
+ if waiter is not None and not waiter.done():
+ waiter.set_exception(exc)
else:
if state == POLL_OK:
- if self._reading:
- self._loop.remove_reader(self._fileno)
- self._reading = False
if self._writing:
self._loop.remove_writer(self._fileno)
self._writing = False
- if not self._waiter.cancelled():
- self._waiter.set_result(None)
+ if waiter is not None and not waiter.done():
+ waiter.set_result(None)
elif state == POLL_READ:
- if not self._reading:
- self._loop.add_reader(self._fileno, self._ready)
- self._reading = True
if self._writing:
self._loop.remove_writer(self._fileno)
self._writing = False
elif state == POLL_WRITE:
- if self._reading:
- self._loop.remove_reader(self._fileno)
- self._reading = False
if not self._writing:
- self._loop.add_writer(self._fileno, self._ready)
+ self._loop.add_writer(self._fileno, self._ready, weak_self)
self._writing = True
elif state == POLL_ERROR:
self._fatal_error("Fatal error on aiopg connection: "
@@ -157,16 +176,30 @@ class Connection:
@asyncio.coroutine
def _poll(self, waiter, timeout):
assert waiter is self._waiter, (waiter, self._waiter)
- self._ready()
+ self._ready(self._weakref)
+
+ @asyncio.coroutine
+ def cancel():
+ if not self._isexecuting():
+ return
+ self._waiter = asyncio.Future(loop=self._loop)
+ self._conn.cancel()
+ try:
+ yield from self._waiter
+ except psycopg2.extensions.QueryCanceledError:
+ pass
+
try:
yield from asyncio.wait_for(self._waiter, timeout, loop=self._loop)
+ except (asyncio.CancelledError, asyncio.TimeoutError) as exc:
+ yield from asyncio.shield(cancel(), loop=self._loop)
+ raise exc
finally:
self._waiter = None
def _isexecuting(self):
return self._conn.isexecuting()
- @asyncio.coroutine
def cursor(self, name=None, cursor_factory=None,
scrollable=None, withhold=False, timeout=None):
"""A coroutine that returns a new cursor object using the connection.
@@ -179,18 +212,26 @@ class Connection:
psycopg in asynchronous mode.
"""
+ coro = self._cursor(name=name, cursor_factory=cursor_factory,
+ scrollable=scrollable, withhold=withhold,
+ timeout=timeout)
+ return _ContextManager(coro)
+
+ @asyncio.coroutine
+ def _cursor(self, name=None, cursor_factory=None,
+ scrollable=None, withhold=False, timeout=None):
if timeout is None:
timeout = self._timeout
- impl = yield from self._cursor(name=name,
- cursor_factory=cursor_factory,
- scrollable=scrollable,
- withhold=withhold)
+ impl = yield from self._cursor_impl(name=name,
+ cursor_factory=cursor_factory,
+ scrollable=scrollable,
+ withhold=withhold)
return Cursor(self, impl, timeout, self._echo)
@asyncio.coroutine
- def _cursor(self, name=None, cursor_factory=None,
- scrollable=None, withhold=False):
+ def _cursor_impl(self, name=None, cursor_factory=None,
+ scrollable=None, withhold=False):
if cursor_factory is None:
impl = self._conn.cursor(name=name,
scrollable=scrollable, withhold=withhold)
@@ -203,12 +244,10 @@ class Connection:
"""Remove the connection from the event_loop and close it."""
# N.B. If connection contains uncommitted transaction the
# transaction will be discarded
- if self._reading:
- self._loop.remove_reader(self._fileno)
- self._reading = False
+ self._loop.remove_reader(self._fileno)
if self._writing:
- self._loop.remove_writer(self._fileno)
self._writing = False
+ self._loop.remove_writer(self._fileno)
self._conn.close()
if self._waiter is not None and not self._waiter.done():
self._waiter.set_exception(
@@ -276,11 +315,24 @@ class Connection:
@asyncio.coroutine
def cancel(self, timeout=None):
"""Cancel the current database operation."""
- waiter = self._create_waiter('cancel')
- self._conn.cancel()
- if timeout is None:
- timeout = self._timeout
- yield from self._poll(waiter, timeout)
+ if timeout is not None:
+ warnings.warn('timeout parameter is deprecated and never used',
+ DeprecationWarning)
+ if self._waiter is not None:
+ self._waiter.cancel()
+ if not self._isexecuting():
+ return
+
+ @asyncio.coroutine
+ def cancel():
+ self._waiter = asyncio.Future(loop=self._loop)
+ self._conn.cancel()
+ try:
+ yield from self._waiter
+ except psycopg2.extensions.QueryCanceledError:
+ pass
+
+ yield from asyncio.shield(cancel(), loop=self._loop)
@asyncio.coroutine
def reset(self):
@@ -395,9 +447,29 @@ class Connection:
"""Return echo mode status."""
return self._echo
- if PY_34: # pragma: no branch
+ if PY_341: # pragma: no branch
def __del__(self):
if not self._conn.closed:
+ self.close()
warnings.warn("Unclosed connection {!r}".format(self),
ResourceWarning)
- self.close()
+
+ context = {'connection': self,
+ 'message': 'Unclosed connection'}
+ if self._source_traceback is not None:
+ context['source_traceback'] = self._source_traceback
+ self._loop.call_exception_handler(context)
+
+ @property
+ def notifies(self):
+ """Return notification queue."""
+ return self._notifies
+
+ if PY_35: # pragma: no branch
+ @asyncio.coroutine
+ def __aenter__(self):
+ return self
+
+ @asyncio.coroutine
+ def __aexit__(self, exc_type, exc_val, exc_tb):
+ self.close()
diff --git a/aiopg/cursor.py b/aiopg/cursor.py
index a22c307..f63ee4a 100644
--- a/aiopg/cursor.py
+++ b/aiopg/cursor.py
@@ -4,6 +4,7 @@ import warnings
import psycopg2
from .log import logger
+from .utils import PY_35
class Cursor:
@@ -108,8 +109,11 @@ class Cursor:
except:
self._conn._waiter = None
raise
- else:
+ try:
yield from self._conn._poll(waiter, timeout)
+ except asyncio.TimeoutError:
+ self._impl.close()
+ raise
@asyncio.coroutine
def executemany(self, operation, seq_of_parameters):
@@ -372,3 +376,26 @@ class Cursor:
raise StopIteration
else:
yield row
+
+ if PY_35: # pragma: no branch
+
+ @asyncio.coroutine
+ def __aiter__(self):
+ return self
+
+ @asyncio.coroutine
+ def __anext__(self):
+ ret = yield from self.fetchone()
+ if ret is not None:
+ return ret
+ else:
+ raise StopAsyncIteration # noqa
+
+ @asyncio.coroutine
+ def __aenter__(self):
+ return self
+
+ @asyncio.coroutine
+ def __aexit__(self, exc_type, exc_val, exc_tb):
+ self.close()
+ return
diff --git a/aiopg/pool.py b/aiopg/pool.py
index 5a6b5b7..bc2b93b 100644
--- a/aiopg/pool.py
+++ b/aiopg/pool.py
@@ -8,23 +8,37 @@ from psycopg2.extensions import TRANSACTION_STATUS_IDLE
from .connection import connect, TIMEOUT
from .log import logger
+from .utils import (PY_35, _PoolContextManager, _PoolConnectionContextManager,
+ _PoolCursorContextManager, _PoolAcquireContextManager)
-PY_34 = sys.version_info >= (3, 4)
+PY_341 = sys.version_info >= (3, 4, 1)
- at asyncio.coroutine
def create_pool(dsn=None, *, minsize=10, maxsize=10,
loop=None, timeout=TIMEOUT,
- enable_json=True, enable_hstore=True,
+ enable_json=True, enable_hstore=True, enable_uuid=True,
echo=False,
**kwargs):
+ coro = _create_pool(dsn=dsn, minsize=minsize, maxsize=maxsize, loop=loop,
+ timeout=timeout, enable_json=enable_json,
+ enable_hstore=enable_hstore, enable_uuid=enable_uuid,
+ echo=echo, **kwargs)
+ return _PoolContextManager(coro)
+
+
+ at asyncio.coroutine
+def _create_pool(dsn=None, *, minsize=10, maxsize=10,
+ loop=None, timeout=TIMEOUT,
+ enable_json=True, enable_hstore=True, enable_uuid=True,
+ echo=False,
+ **kwargs):
if loop is None:
loop = asyncio.get_event_loop()
pool = Pool(dsn, minsize, maxsize, loop, timeout,
enable_json=enable_json, enable_hstore=enable_hstore,
- echo=echo,
+ enable_uuid=enable_uuid, echo=echo,
**kwargs)
if minsize > 0:
with (yield from pool._cond):
@@ -36,10 +50,10 @@ class Pool(asyncio.AbstractServer):
"""Connection pool"""
def __init__(self, dsn, minsize, maxsize, loop, timeout, *,
- enable_json, enable_hstore, echo, **kwargs):
+ enable_json, enable_hstore, enable_uuid, echo, **kwargs):
if minsize < 0:
raise ValueError("minsize should be zero or greater")
- if maxsize < minsize:
+ if maxsize < minsize and maxsize != 0:
raise ValueError("maxsize should be not less than minsize")
self._dsn = dsn
self._minsize = minsize
@@ -47,10 +61,11 @@ class Pool(asyncio.AbstractServer):
self._timeout = timeout
self._enable_json = enable_json
self._enable_hstore = enable_hstore
+ self._enable_uuid = enable_uuid
self._echo = echo
self._conn_kwargs = kwargs
self._acquiring = 0
- self._free = collections.deque(maxlen=maxsize)
+ self._free = collections.deque(maxlen=maxsize or None)
self._cond = asyncio.Condition(loop=loop)
self._used = set()
self._terminated = set()
@@ -90,6 +105,10 @@ class Pool(asyncio.AbstractServer):
yield from conn.close()
self._cond.notify()
+ @property
+ def closed(self):
+ return self._closed
+
def close(self):
"""Close pool.
@@ -134,9 +153,13 @@ class Pool(asyncio.AbstractServer):
self._closed = True
- @asyncio.coroutine
def acquire(self):
"""Acquire free connection from the pool."""
+ coro = self._acquire()
+ return _PoolAcquireContextManager(coro, self)
+
+ @asyncio.coroutine
+ def _acquire(self):
if self._closing:
raise RuntimeError("Cannot acquire connection after closing pool")
with (yield from self._cond):
@@ -160,6 +183,7 @@ class Pool(asyncio.AbstractServer):
self._dsn, loop=self._loop, timeout=self._timeout,
enable_json=self._enable_json,
enable_hstore=self._enable_hstore,
+ enable_uuid=self._enable_uuid,
echo=self._echo,
**self._conn_kwargs)
# raise exception if pool is closing
@@ -177,6 +201,7 @@ class Pool(asyncio.AbstractServer):
self._dsn, loop=self._loop, timeout=self._timeout,
... 613 lines suppressed ...
--
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