[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