[Python-modules-commits] [asyncpg] 01/03: Import asyncpg_0.8.1.orig.tar.gz

Piotr Ożarowski piotr at moszumanska.debian.org
Tue Dec 27 22:35:16 UTC 2016


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

piotr pushed a commit to branch master
in repository asyncpg.

commit 16390366eb2519ca69e25b8639219dfa1eed2b9a
Author: Piotr Ożarowski <piotr at debian.org>
Date:   Tue Dec 27 23:31:20 2016 +0100

    Import asyncpg_0.8.1.orig.tar.gz
---
 Makefile                     |    8 +-
 PKG-INFO                     |   93 +-
 README.rst                   |    4 +-
 asyncpg.egg-info/PKG-INFO    |   93 +-
 asyncpg.egg-info/SOURCES.txt |    1 +
 asyncpg/_testbase.py         |   42 +-
 asyncpg/cluster.py           |   87 +-
 asyncpg/connection.py        |   44 +-
 asyncpg/introspection.py     |  116 +
 asyncpg/protocol/protocol.c  | 7843 +++++++++++++++++++++++++++++-------------
 asyncpg/serverversion.py     |   33 +
 asyncpg/types.py             |    7 +-
 docs/api/index.rst           |    2 +-
 docs/conf.py                 |    3 +-
 setup.cfg                    |    4 +-
 setup.py                     |   12 +-
 tests/test_codecs.py         |   20 +-
 tests/test_pool.py           |   75 +-
 tests/test_prepare.py        |    6 +
 tests/test_record.py         |    3 +-
 20 files changed, 6085 insertions(+), 2411 deletions(-)

diff --git a/Makefile b/Makefile
index f5402ab..2f310e4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-.PHONY: compile debug test clean all
+.PHONY: compile debug test quicktest clean all
 
 
 PYTHON ?= python
@@ -33,6 +33,10 @@ test:
 	USE_UVLOOP=1 $(PYTHON) -m unittest discover -s tests
 
 
+quicktest:
+	$(PYTHON) -m unittest discover -s tests
+
+
 sdist: clean compile test
 	$(PYTHON) setup.py sdist
 
@@ -41,5 +45,5 @@ release: clean compile test
 	$(PYTHON) setup.py sdist upload
 
 
-htmldocs:
+htmldocs: compile
 	$(MAKE) -C docs html
diff --git a/PKG-INFO b/PKG-INFO
index 542463f..76babe9 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,99 @@
 Metadata-Version: 1.1
 Name: asyncpg
-Version: 0.7.0
+Version: 0.8.1
 Summary: An asyncio PosgtreSQL driver
-Home-page: UNKNOWN
+Home-page: https://github.com/MagicStack/asyncpg
 Author: MagicStack Inc
 Author-email: hello at magic.io
 License: Apache License, Version 2.0
-Description: UNKNOWN
+Description: asyncpg -- A fast PostgreSQL Database Client Library for Python/asyncio
+        =======================================================================
+        
+        .. image:: https://travis-ci.org/MagicStack/asyncpg.svg?branch=master
+            :target: https://travis-ci.org/MagicStack/asyncpg
+        
+        .. image:: https://ci.appveyor.com/api/projects/status/9rwppnxphgc8bqoj/branch/master?svg=true
+            :target: https://ci.appveyor.com/project/magicstack/asyncpg
+        
+        .. image:: https://img.shields.io/pypi/v/asyncpg.svg
+            :target: https://pypi.python.org/pypi/asyncpg
+        
+        **asyncpg** is a database interface library designed specifically for
+        PostgreSQL and Python/asyncio.  asyncpg is an efficient, clean implementation
+        of PostgreSQL server binary protocol for use with Python's ``asyncio``
+        framework.  You can read more about asyncpg in an introductory
+        `blog post <http://magic.io/blog/asyncpg-1m-rows-from-postgres-to-python/>`_.
+        
+        
+        Documentation
+        -------------
+        
+        The project documentation can be found
+        `here <https://magicstack.github.io/asyncpg/current/>`_.
+        
+        
+        Performance
+        -----------
+        
+        In our testing asyncpg is, on average, **3x** faster than psycopg2
+        (and its asyncio variant -- aiopg).
+        
+        .. image:: performance.png
+            :target: http://magic.io/blog/asyncpg-1m-rows-from-postgres-to-python/
+        
+        The above results are a geometric mean of benchmarks obtained with PostgreSQL
+        `client driver benchmarking toolbench <https://github.com/MagicStack/pgbench>`_.
+        
+        
+        Features
+        --------
+        
+        asyncpg implements PostgreSQL server protocol natively and exposes its
+        features directly, as opposed to hiding them behind a generic facade
+        like DB-API.
+        
+        This enables asyncpg to have easy-to-use support for:
+        
+        * **prepared statements**
+        * **scrollable cursors**
+        * **partial iteration** on query results
+        * automatic encoding and decoding of composite types, arrays,
+          and any combination of those
+        * straightforward support for custom data types
+        
+        
+        Installation
+        ------------
+        
+        asyncpg requires Python 3.5 and is available on PyPI.
+        Use pip to install it::
+        
+            $ pip install asyncpg
+        
+        
+        Basic Usage
+        -----------
+        
+        .. code-block:: python
+        
+            import asyncio
+            import asyncpg
+        
+            async def run():
+                conn = await asyncpg.connect(user='user', password='password',
+                                             database='database', host='127.0.0.1')
+                values = await conn.fetch('''SELECT * FROM mytable''')
+                await conn.close()
+        
+            loop = asyncio.get_event_loop()
+            loop.run_until_complete(run())
+        
+        
+        License
+        -------
+        
+        asyncpg is developed and distributed under the Apache 2.0 license.
+        
 Platform: POSIX
 Classifier: License :: OSI Approved :: Apache Software License
 Classifier: Intended Audience :: Developers
diff --git a/README.rst b/README.rst
index ce60883..c970192 100644
--- a/README.rst
+++ b/README.rst
@@ -13,8 +13,8 @@ asyncpg -- A fast PostgreSQL Database Client Library for Python/asyncio
 **asyncpg** is a database interface library designed specifically for
 PostgreSQL and Python/asyncio.  asyncpg is an efficient, clean implementation
 of PostgreSQL server binary protocol for use with Python's ``asyncio``
-framework.  You can read more about asyncpg in an introductory blog post
-`here <http://magic.io/blog/asyncpg-1m-rows-from-postgres-to-python/>`_.
+framework.  You can read more about asyncpg in an introductory
+`blog post <http://magic.io/blog/asyncpg-1m-rows-from-postgres-to-python/>`_.
 
 
 Documentation
diff --git a/asyncpg.egg-info/PKG-INFO b/asyncpg.egg-info/PKG-INFO
index 542463f..76babe9 100644
--- a/asyncpg.egg-info/PKG-INFO
+++ b/asyncpg.egg-info/PKG-INFO
@@ -1,12 +1,99 @@
 Metadata-Version: 1.1
 Name: asyncpg
-Version: 0.7.0
+Version: 0.8.1
 Summary: An asyncio PosgtreSQL driver
-Home-page: UNKNOWN
+Home-page: https://github.com/MagicStack/asyncpg
 Author: MagicStack Inc
 Author-email: hello at magic.io
 License: Apache License, Version 2.0
-Description: UNKNOWN
+Description: asyncpg -- A fast PostgreSQL Database Client Library for Python/asyncio
+        =======================================================================
+        
+        .. image:: https://travis-ci.org/MagicStack/asyncpg.svg?branch=master
+            :target: https://travis-ci.org/MagicStack/asyncpg
+        
+        .. image:: https://ci.appveyor.com/api/projects/status/9rwppnxphgc8bqoj/branch/master?svg=true
+            :target: https://ci.appveyor.com/project/magicstack/asyncpg
+        
+        .. image:: https://img.shields.io/pypi/v/asyncpg.svg
+            :target: https://pypi.python.org/pypi/asyncpg
+        
+        **asyncpg** is a database interface library designed specifically for
+        PostgreSQL and Python/asyncio.  asyncpg is an efficient, clean implementation
+        of PostgreSQL server binary protocol for use with Python's ``asyncio``
+        framework.  You can read more about asyncpg in an introductory
+        `blog post <http://magic.io/blog/asyncpg-1m-rows-from-postgres-to-python/>`_.
+        
+        
+        Documentation
+        -------------
+        
+        The project documentation can be found
+        `here <https://magicstack.github.io/asyncpg/current/>`_.
+        
+        
+        Performance
+        -----------
+        
+        In our testing asyncpg is, on average, **3x** faster than psycopg2
+        (and its asyncio variant -- aiopg).
+        
+        .. image:: performance.png
+            :target: http://magic.io/blog/asyncpg-1m-rows-from-postgres-to-python/
+        
+        The above results are a geometric mean of benchmarks obtained with PostgreSQL
+        `client driver benchmarking toolbench <https://github.com/MagicStack/pgbench>`_.
+        
+        
+        Features
+        --------
+        
+        asyncpg implements PostgreSQL server protocol natively and exposes its
+        features directly, as opposed to hiding them behind a generic facade
+        like DB-API.
+        
+        This enables asyncpg to have easy-to-use support for:
+        
+        * **prepared statements**
+        * **scrollable cursors**
+        * **partial iteration** on query results
+        * automatic encoding and decoding of composite types, arrays,
+          and any combination of those
+        * straightforward support for custom data types
+        
+        
+        Installation
+        ------------
+        
+        asyncpg requires Python 3.5 and is available on PyPI.
+        Use pip to install it::
+        
+            $ pip install asyncpg
+        
+        
+        Basic Usage
+        -----------
+        
+        .. code-block:: python
+        
+            import asyncio
+            import asyncpg
+        
+            async def run():
+                conn = await asyncpg.connect(user='user', password='password',
+                                             database='database', host='127.0.0.1')
+                values = await conn.fetch('''SELECT * FROM mytable''')
+                await conn.close()
+        
+            loop = asyncio.get_event_loop()
+            loop.run_until_complete(run())
+        
+        
+        License
+        -------
+        
+        asyncpg is developed and distributed under the Apache 2.0 license.
+        
 Platform: POSIX
 Classifier: License :: OSI Approved :: Apache Software License
 Classifier: Intended Audience :: Developers
diff --git a/asyncpg.egg-info/SOURCES.txt b/asyncpg.egg-info/SOURCES.txt
index fc196ec..5cc7811 100644
--- a/asyncpg.egg-info/SOURCES.txt
+++ b/asyncpg.egg-info/SOURCES.txt
@@ -13,6 +13,7 @@ asyncpg/cursor.py
 asyncpg/introspection.py
 asyncpg/pool.py
 asyncpg/prepared_stmt.py
+asyncpg/serverversion.py
 asyncpg/transaction.py
 asyncpg/types.py
 asyncpg.egg-info/PKG-INFO
diff --git a/asyncpg/_testbase.py b/asyncpg/_testbase.py
index b45f18b..daf9cdf 100644
--- a/asyncpg/_testbase.py
+++ b/asyncpg/_testbase.py
@@ -70,17 +70,19 @@ class TestCaseMeta(type(unittest.TestCase)):
 
 class TestCase(unittest.TestCase, metaclass=TestCaseMeta):
 
-    def setUp(self):
+    @classmethod
+    def setUpClass(cls):
         if os.environ.get('USE_UVLOOP'):
             import uvloop
             asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
 
         loop = asyncio.new_event_loop()
         asyncio.set_event_loop(None)
-        self.loop = loop
+        cls.loop = loop
 
-    def tearDown(self):
-        self.loop.close()
+    @classmethod
+    def tearDownClass(cls):
+        cls.loop.close()
         asyncio.set_event_loop(None)
 
     @contextlib.contextmanager
@@ -97,7 +99,16 @@ class TestCase(unittest.TestCase, metaclass=TestCaseMeta):
 _default_cluster = None
 
 
-def _start_cluster(server_settings={}):
+def _start_cluster(ClusterCls, cluster_kwargs, server_settings):
+    cluster = ClusterCls(**cluster_kwargs)
+    cluster.init()
+    cluster.trust_local_connections()
+    cluster.start(port='dynamic', server_settings=server_settings)
+    atexit.register(_shutdown_cluster, cluster)
+    return cluster
+
+
+def _start_default_cluster(server_settings={}):
     global _default_cluster
 
     if _default_cluster is None:
@@ -106,12 +117,8 @@ def _start_cluster(server_settings={}):
             # Using existing cluster, assuming it is initialized and running
             _default_cluster = pg_cluster.RunningCluster()
         else:
-            _default_cluster = pg_cluster.TempCluster()
-            _default_cluster.init()
-            _default_cluster.trust_local_connections()
-            _default_cluster.start(port='dynamic',
-                                   server_settings=server_settings)
-            atexit.register(_shutdown_cluster, _default_cluster)
+            _default_cluster = _start_cluster(
+                pg_cluster.TempCluster, {}, server_settings)
 
     return _default_cluster
 
@@ -122,9 +129,10 @@ def _shutdown_cluster(cluster):
 
 
 class ClusterTestCase(TestCase):
-    def setUp(self):
-        super().setUp()
-        self.cluster = _start_cluster({
+    @classmethod
+    def setUpClass(cls):
+        super().setUpClass()
+        cls.cluster = _start_default_cluster({
             'log_connections': 'on'
         })
 
@@ -133,6 +141,11 @@ class ClusterTestCase(TestCase):
         conn_spec.update(kwargs)
         return pg_pool.create_pool(loop=self.loop, **conn_spec)
 
+    @classmethod
+    def start_cluster(cls, ClusterCls, *,
+                      cluster_kwargs={}, server_settings={}):
+        return _start_cluster(ClusterCls, cluster_kwargs, server_settings)
+
 
 class ConnectedTestCase(ClusterTestCase):
 
@@ -144,6 +157,7 @@ class ConnectedTestCase(ClusterTestCase):
         opts = self.getExtraConnectOptions()
         self.con = self.loop.run_until_complete(
             self.cluster.connect(database='postgres', loop=self.loop, **opts))
+        self.server_version = self.con.get_server_version()
 
     def tearDown(self):
         try:
diff --git a/asyncpg/cluster.py b/asyncpg/cluster.py
index 1e6faad..b9601b5 100644
--- a/asyncpg/cluster.py
+++ b/asyncpg/cluster.py
@@ -16,9 +16,11 @@ import shutil
 import socket
 import subprocess
 import tempfile
+import textwrap
 import time
 
 import asyncpg
+from asyncpg import serverversion
 
 
 _system = platform.uname().system
@@ -170,8 +172,18 @@ class Cluster:
         extra_args = ['--{}={}'.format(k, v) for k, v in opts.items()]
         extra_args.append('--port={}'.format(port))
 
-        if 'unix_socket_directories' not in server_settings:
-            server_settings['unix_socket_directories'] = '/tmp'
+        sockdir = server_settings.get('unix_socket_directories')
+        if sockdir is None:
+            sockdir = server_settings.get('unix_socket_directory')
+        if sockdir is None:
+            sockdir = '/tmp'
+
+        if self._pg_version < (9, 3):
+            sockdir_opt = 'unix_socket_directory'
+        else:
+            sockdir_opt = 'unix_socket_directories'
+
+        server_settings[sockdir_opt] = sockdir
 
         for k, v in server_settings.items():
             extra_args.extend(['-c', '{}={}'.format(k, v)])
@@ -332,9 +344,24 @@ class Cluster:
         if status == 'running':
             self.reload()
 
+    def trust_local_replication_by(self, user):
+        if _system != 'Windows':
+            self.add_hba_entry(type='local', database='replication',
+                               user=user, auth_method='trust')
+        self.add_hba_entry(type='host', address='127.0.0.1/32',
+                           database='replication', user=user,
+                           auth_method='trust')
+        self.add_hba_entry(type='host', address='::1/128',
+                           database='replication', user=user,
+                           auth_method='trust')
+        status = self.get_status()
+        if status == 'running':
+            self.reload()
+
     def _init_env(self):
         self._pg_config = self._find_pg_config(self._pg_config_path)
         self._pg_config_data = self._run_pg_config(self._pg_config)
+        self._pg_version = self._get_pg_version()
         self._pg_ctl = self._find_pg_binary('pg_ctl')
         self._postgres = self._find_pg_binary('postgres')
 
@@ -478,6 +505,13 @@ class Cluster:
 
         return bpath
 
+    def _get_pg_version(self):
+        version_string = self._pg_config_data.get('version')
+        if not version_string:
+            raise ClusterError('could not determine PostgreSQL version')
+
+        return serverversion.split_server_version_string(version_string)
+
 
 class TempCluster(Cluster):
     def __init__(self, *,
@@ -489,6 +523,55 @@ class TempCluster(Cluster):
         super().__init__(self._data_dir, pg_config_path=pg_config_path)
 
 
+class HotStandbyCluster(TempCluster):
+    def __init__(self, *,
+                 master, replication_user,
+                 data_dir_suffix=None, data_dir_prefix=None,
+                 data_dir_parent=None, pg_config_path=None):
+        self._master = master
+        self._repl_user = replication_user
+        super().__init__(
+            data_dir_suffix=data_dir_suffix,
+            data_dir_prefix=data_dir_prefix,
+            data_dir_parent=data_dir_parent,
+            pg_config_path=pg_config_path)
+
+    def _init_env(self):
+        super()._init_env()
+        self._pg_basebackup = self._find_pg_binary('pg_basebackup')
+
+    def init(self, **settings):
+        """Initialize cluster."""
+        if self.get_status() != 'not-initialized':
+            raise ClusterError(
+                'cluster in {!r} has already been initialized'.format(
+                    self._data_dir))
+
+        process = subprocess.run(
+            [self._pg_basebackup, '-h', self._master['host'],
+             '-p', self._master['port'], '-D', self._data_dir,
+             '-U', self._repl_user],
+            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+        output = process.stdout
+
+        if process.returncode != 0:
+            raise ClusterError(
+                'pg_basebackup init exited with status {:d}:\n{}'.format(
+                    process.returncode, output.decode()))
+
+        with open(os.path.join(self._data_dir, 'recovery.conf'), 'w') as f:
+            f.write(textwrap.dedent("""\
+                standby_mode = 'on'
+                primary_conninfo = 'host={host} port={port} user={user}'
+            """.format(
+                host=self._master['host'],
+                port=self._master['port'],
+                user=self._repl_user)))
+
+        return output.decode()
+
+
 class RunningCluster(Cluster):
     def __init__(self, **kwargs):
         self.conn_spec = kwargs
diff --git a/asyncpg/connection.py b/asyncpg/connection.py
index 604c4a0..9445a9b 100644
--- a/asyncpg/connection.py
+++ b/asyncpg/connection.py
@@ -17,6 +17,7 @@ from . import cursor
 from . import introspection
 from . import prepared_stmt
 from . import protocol
+from . import serverversion
 from . import transaction
 
 
@@ -29,7 +30,8 @@ class Connection:
     __slots__ = ('_protocol', '_transport', '_loop', '_types_stmt',
                  '_type_by_name_stmt', '_top_xact', '_uid', '_aborted',
                  '_stmt_cache_max_size', '_stmt_cache', '_stmts_to_close',
-                 '_addr', '_opts', '_command_timeout', '_listeners')
+                 '_addr', '_opts', '_command_timeout', '_listeners',
+                 '_server_version', '_intro_query')
 
     def __init__(self, protocol, transport, loop, addr, opts, *,
                  statement_cache_size, command_timeout):
@@ -53,6 +55,15 @@ class Connection:
 
         self._listeners = {}
 
+        ver_string = self._protocol.get_settings().server_version
+        self._server_version = \
+            serverversion.split_server_version_string(ver_string)
+
+        if self._server_version < (9, 2):
+            self._intro_query = introspection.INTRO_LOOKUP_TYPES_91
+        else:
+            self._intro_query = introspection.INTRO_LOOKUP_TYPES
+
     async def add_listener(self, channel, callback):
         """Add a listener for Postgres notifications.
 
@@ -84,6 +95,21 @@ class Connection:
         """Return the PID of the Postgres server the connection is bound to."""
         return self._protocol.get_server_pid()
 
+    def get_server_version(self):
+        """Return the version of the connected PostgreSQL server.
+
+        The returned value is a named tuple similar to that in
+        ``sys.version_info``:
+
+        .. code-block:: pycon
+
+            >>> con.get_server_version()
+            ServerVersion(major=9, minor=6, micro=1,
+                          releaselevel='final', serial=0)
+
+        """
+        return self._server_version
+
     def get_settings(self):
         """Return connection settings.
 
@@ -188,8 +214,7 @@ class Connection:
         ready = state._init_types()
         if ready is not True:
             if self._types_stmt is None:
-                self._types_stmt = await self.prepare(
-                    introspection.INTRO_LOOKUP_TYPES)
+                self._types_stmt = await self.prepare(self._intro_query)
 
             types = await self._types_stmt.fetch(list(ready))
             protocol.get_settings().register_data_types(types)
@@ -369,11 +394,19 @@ class Connection:
 
     async def reset(self):
         self._listeners = {}
+
         await self.execute('''
+            DO $$
+            BEGIN
+                PERFORM * FROM pg_listening_channels() LIMIT 1;
+                IF FOUND THEN
+                    UNLISTEN *;
+                END IF;
+            END;
+            $$;
             SET SESSION AUTHORIZATION DEFAULT;
             RESET ALL;
             CLOSE ALL;
-            UNLISTEN *;
             SELECT pg_advisory_unlock_all();
         ''')
 
@@ -438,7 +471,8 @@ class Connection:
             except Exception as ex:
                 waiter.set_exception(ex)
             finally:
-                waiter.set_result(None)
+                if not waiter.done():  # Ensure set_exception wasn't called.
+                    waiter.set_result(None)
                 w.close()
 
         self._loop.create_task(cancel())
diff --git a/asyncpg/introspection.py b/asyncpg/introspection.py
index 07448ee..4554629 100644
--- a/asyncpg/introspection.py
+++ b/asyncpg/introspection.py
@@ -123,6 +123,122 @@ ORDER BY
 '''
 
 
+# Prior to 9.2 PostgreSQL did not have range types.
+INTRO_LOOKUP_TYPES_91 = '''\
+WITH RECURSIVE typeinfo_tree(
+    oid, ns, name, kind, basetype, elemtype, range_subtype,
+    elem_has_bin_input, elem_has_bin_output, attrtypoids, attrnames, depth)
+AS (
+    WITH composite_attrs
+    AS (
+        SELECT
+            c.reltype                                        AS comptype_oid,
+            array_agg(ia.atttypid ORDER BY ia.attnum)        AS typoids,
+            array_agg(ia.attname::text ORDER BY ia.attnum)   AS names
+        FROM
+            pg_attribute ia
+            INNER JOIN pg_class c
+                ON (ia.attrelid = c.oid)
+        WHERE
+            ia.attnum > 0 AND NOT ia.attisdropped
+        GROUP BY
+            c.reltype
+    ),
+
+    typeinfo
+    AS (
+        SELECT
+            t.oid                           AS oid,
+            ns.nspname                      AS ns,
+            t.typname                       AS name,
+            t.typtype                       AS kind,
+            (CASE WHEN t.typtype = 'd' THEN
+                (WITH RECURSIVE typebases(oid, depth) AS (
+                    SELECT
+                        t2.typbasetype      AS oid,
+                        0                   AS depth
+                    FROM
+                        pg_type t2
+                    WHERE
+                        t2.oid = t.oid
+
+                    UNION ALL
+
+                    SELECT
+                        t2.typbasetype      AS oid,
+                        tb.depth + 1        AS depth
+                    FROM
+                        pg_type t2,
+                        typebases tb
+                    WHERE
+                       tb.oid = t2.oid
+                       AND t2.typbasetype != 0
+               ) SELECT oid FROM typebases ORDER BY depth DESC LIMIT 1)
+
+               ELSE NULL
+            END)                            AS basetype,
+            t.typelem                       AS elemtype,
+            NULL::oid                       AS range_subtype,
+            elem_t.typreceive::oid != 0     AS elem_has_bin_input,
+            elem_t.typsend::oid != 0        AS elem_has_bin_output,
+            (CASE WHEN t.typtype = 'c' THEN
+                (SELECT ca.typoids
+                FROM composite_attrs AS ca
+                WHERE ca.comptype_oid = t.oid)
+
+                ELSE NULL
+            END)                            AS attrtypoids,
+            (CASE WHEN t.typtype = 'c' THEN
+                (SELECT ca.names
+                FROM composite_attrs AS ca
+                WHERE ca.comptype_oid = t.oid)
+
+                ELSE NULL
+            END)                            AS attrnames
+        FROM
+            pg_catalog.pg_type AS t
+            INNER JOIN pg_catalog.pg_namespace ns ON (
+                ns.oid = t.typnamespace)
+            LEFT JOIN pg_type elem_t ON (
+                t.typlen = -1 AND
+                t.typelem != 0 AND
+                t.typelem = elem_t.oid
+            )
+    )
+
+    SELECT
+        ti.oid, ti.ns, ti.name, ti.kind, ti.basetype, ti.elemtype,
+        ti.range_subtype, ti.elem_has_bin_input, ti.elem_has_bin_output,
+        ti.attrtypoids, ti.attrnames, 0
+    FROM
+        typeinfo AS ti
+    WHERE
+        ti.oid = any($1::oid[])
+
+    UNION ALL
+
+    SELECT
+        ti.oid, ti.ns, ti.name, ti.kind, ti.basetype, ti.elemtype,
+        ti.range_subtype, ti.elem_has_bin_input, ti.elem_has_bin_output,
+        ti.attrtypoids, ti.attrnames, tt.depth + 1
+    FROM
+        typeinfo ti,
+        typeinfo_tree tt
+    WHERE
+        (tt.elemtype IS NOT NULL AND ti.oid = tt.elemtype)
+        OR (tt.attrtypoids IS NOT NULL AND ti.oid = any(tt.attrtypoids))
+        OR (tt.range_subtype IS NOT NULL AND ti.oid = tt.range_subtype)
+)
+
+SELECT DISTINCT
+    *
+FROM
+    typeinfo_tree
+ORDER BY
+    depth DESC
+'''
+
+
 TYPE_BY_NAME = '''\
 SELECT
     t.oid,
diff --git a/asyncpg/protocol/protocol.c b/asyncpg/protocol/protocol.c
index a6e7155..4040381 100644
--- a/asyncpg/protocol/protocol.c
+++ b/asyncpg/protocol/protocol.c
@@ -1,4 +1,4 @@
-/* Generated by Cython 0.24.1 */
+/* Generated by Cython 0.25.2 */
 
 /* BEGIN: Cython Metadata
 {
@@ -21,7 +21,7 @@ END: Cython Metadata */
 #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
     #error Cython requires Python 2.6+ or Python 3.2+.
 #else
-#define CYTHON_ABI "0_24_1"
+#define CYTHON_ABI "0_25_2"
 #include <stddef.h>
 #ifndef offsetof
   #define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
@@ -43,6 +43,11 @@ END: Cython Metadata */
 #ifndef DL_EXPORT
   #define DL_EXPORT(t) t
 #endif
+#ifndef HAVE_LONG_LONG
+  #if PY_VERSION_HEX >= 0x03030000 || (PY_MAJOR_VERSION == 2 && PY_VERSION_HEX >= 0x02070000)
+    #define HAVE_LONG_LONG
+  #endif
+#endif
 #ifndef PY_LONG_LONG
   #define PY_LONG_LONG LONG_LONG
 #endif
@@ -51,13 +56,110 @@ END: Cython Metadata */
 #endif
 #ifdef PYPY_VERSION
   #define CYTHON_COMPILING_IN_PYPY 1
+  #define CYTHON_COMPILING_IN_PYSTON 0
   #define CYTHON_COMPILING_IN_CPYTHON 0
+  #undef CYTHON_USE_TYPE_SLOTS
+  #define CYTHON_USE_TYPE_SLOTS 0
+  #undef CYTHON_USE_ASYNC_SLOTS
+  #define CYTHON_USE_ASYNC_SLOTS 0
+  #undef CYTHON_USE_PYLIST_INTERNALS
+  #define CYTHON_USE_PYLIST_INTERNALS 0
+  #undef CYTHON_USE_UNICODE_INTERNALS
+  #define CYTHON_USE_UNICODE_INTERNALS 0
+  #undef CYTHON_USE_UNICODE_WRITER
+  #define CYTHON_USE_UNICODE_WRITER 0
+  #undef CYTHON_USE_PYLONG_INTERNALS
+  #define CYTHON_USE_PYLONG_INTERNALS 0
+  #undef CYTHON_AVOID_BORROWED_REFS
+  #define CYTHON_AVOID_BORROWED_REFS 1
+  #undef CYTHON_ASSUME_SAFE_MACROS
+  #define CYTHON_ASSUME_SAFE_MACROS 0
+  #undef CYTHON_UNPACK_METHODS
+  #define CYTHON_UNPACK_METHODS 0
+  #undef CYTHON_FAST_THREAD_STATE
+  #define CYTHON_FAST_THREAD_STATE 0
+  #undef CYTHON_FAST_PYCALL
+  #define CYTHON_FAST_PYCALL 0
+#elif defined(PYSTON_VERSION)
+  #define CYTHON_COMPILING_IN_PYPY 0
+  #define CYTHON_COMPILING_IN_PYSTON 1
+  #define CYTHON_COMPILING_IN_CPYTHON 0
+  #ifndef CYTHON_USE_TYPE_SLOTS
+    #define CYTHON_USE_TYPE_SLOTS 1
+  #endif
+  #undef CYTHON_USE_ASYNC_SLOTS
+  #define CYTHON_USE_ASYNC_SLOTS 0
+  #undef CYTHON_USE_PYLIST_INTERNALS
+  #define CYTHON_USE_PYLIST_INTERNALS 0
+  #ifndef CYTHON_USE_UNICODE_INTERNALS
+    #define CYTHON_USE_UNICODE_INTERNALS 1
+  #endif
+  #undef CYTHON_USE_UNICODE_WRITER
+  #define CYTHON_USE_UNICODE_WRITER 0
+  #undef CYTHON_USE_PYLONG_INTERNALS
+  #define CYTHON_USE_PYLONG_INTERNALS 0
+  #ifndef CYTHON_AVOID_BORROWED_REFS
+    #define CYTHON_AVOID_BORROWED_REFS 0
+  #endif
+  #ifndef CYTHON_ASSUME_SAFE_MACROS
+    #define CYTHON_ASSUME_SAFE_MACROS 1
+  #endif
+  #ifndef CYTHON_UNPACK_METHODS
+    #define CYTHON_UNPACK_METHODS 1
+  #endif
+  #undef CYTHON_FAST_THREAD_STATE
+  #define CYTHON_FAST_THREAD_STATE 0
+  #undef CYTHON_FAST_PYCALL
+  #define CYTHON_FAST_PYCALL 0
 #else
   #define CYTHON_COMPILING_IN_PYPY 0
+  #define CYTHON_COMPILING_IN_PYSTON 0
   #define CYTHON_COMPILING_IN_CPYTHON 1
+  #ifndef CYTHON_USE_TYPE_SLOTS
+    #define CYTHON_USE_TYPE_SLOTS 1
+  #endif
+  #if PY_MAJOR_VERSION < 3
+    #undef CYTHON_USE_ASYNC_SLOTS
+    #define CYTHON_USE_ASYNC_SLOTS 0
+  #elif !defined(CYTHON_USE_ASYNC_SLOTS)
+    #define CYTHON_USE_ASYNC_SLOTS 1
+  #endif
+  #if PY_VERSION_HEX < 0x02070000
+    #undef CYTHON_USE_PYLONG_INTERNALS
+    #define CYTHON_USE_PYLONG_INTERNALS 0
+  #elif !defined(CYTHON_USE_PYLONG_INTERNALS)
+    #define CYTHON_USE_PYLONG_INTERNALS 1
+  #endif
+  #ifndef CYTHON_USE_PYLIST_INTERNALS
+    #define CYTHON_USE_PYLIST_INTERNALS 1
+  #endif
+  #ifndef CYTHON_USE_UNICODE_INTERNALS
+    #define CYTHON_USE_UNICODE_INTERNALS 1
+  #endif
+  #if PY_VERSION_HEX < 0x030300F0
+    #undef CYTHON_USE_UNICODE_WRITER
+    #define CYTHON_USE_UNICODE_WRITER 0
+  #elif !defined(CYTHON_USE_UNICODE_WRITER)
+    #define CYTHON_USE_UNICODE_WRITER 1
+  #endif
+  #ifndef CYTHON_AVOID_BORROWED_REFS
+    #define CYTHON_AVOID_BORROWED_REFS 0
+  #endif
+  #ifndef CYTHON_ASSUME_SAFE_MACROS
+    #define CYTHON_ASSUME_SAFE_MACROS 1
+  #endif
+  #ifndef CYTHON_UNPACK_METHODS
+    #define CYTHON_UNPACK_METHODS 1
+  #endif
+  #ifndef CYTHON_FAST_THREAD_STATE
+    #define CYTHON_FAST_THREAD_STATE 1
+  #endif
+  #ifndef CYTHON_FAST_PYCALL
+    #define CYTHON_FAST_PYCALL 1
+  #endif
 #endif
-#if !defined(CYTHON_USE_PYLONG_INTERNALS) && CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000
-  #define CYTHON_USE_PYLONG_INTERNALS 1
+#if !defined(CYTHON_FAST_PYCCALL)
+#define CYTHON_FAST_PYCCALL  (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1)
 #endif
 #if CYTHON_USE_PYLONG_INTERNALS
   #include "longintrepr.h"
@@ -93,24 +195,44 @@ END: Cython Metadata */
 #ifndef Py_TPFLAGS_HAVE_FINALIZE
   #define Py_TPFLAGS_HAVE_FINALIZE 0
 #endif
+#ifndef METH_FASTCALL
+  #define METH_FASTCALL 0x80
+  typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject **args,
+                                              Py_ssize_t nargs, PyObject *kwnames);
+#else
+  #define __Pyx_PyCFunctionFast _PyCFunctionFast
+#endif
+#if CYTHON_FAST_PYCCALL
+#define __Pyx_PyFastCFunction_Check(func)\
+    ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)))))
+#else
+#define __Pyx_PyFastCFunction_Check(func) 0
+#endif
 #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
   #define CYTHON_PEP393_ENABLED 1
   #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ?\
                                               0 : _PyUnicode_Ready((PyObject *)(op)))
   #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
   #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u)   PyUnicode_MAX_CHAR_VALUE(u)
   #define __Pyx_PyUnicode_KIND(u)         PyUnicode_KIND(u)
   #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)
   #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+  #define __Pyx_PyUnicode_WRITE(k, d, i, ch)  PyUnicode_WRITE(k, d, i, ch)
   #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u)))
 #else
   #define CYTHON_PEP393_ENABLED 0
+  #define PyUnicode_1BYTE_KIND  1
+  #define PyUnicode_2BYTE_KIND  2
+  #define PyUnicode_4BYTE_KIND  4
   #define __Pyx_PyUnicode_READY(op)       (0)
   #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
   #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u)   ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111)
   #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))
   #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))
   #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+  #define __Pyx_PyUnicode_WRITE(k, d, i, ch)  (((void)(k)), ((Py_UNICODE*)d)[i] = ch)
   #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != PyUnicode_GET_SIZE(u))
 #endif
 #if CYTHON_COMPILING_IN_PYPY
@@ -135,6 +257,13 @@ END: Cython Metadata */
   #define PyObject_Free(p)     PyMem_Free(p)
   #define PyObject_Realloc(p)  PyMem_Realloc(p)
 #endif
+#if CYTHON_COMPILING_IN_PYSTON
+  #define __Pyx_PyCode_HasFreeVars(co)  PyCode_HasFreeVars(co)
+  #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno)
+#else
+  #define __Pyx_PyCode_HasFreeVars(co)  (PyCode_GetNumFree(co) > 0)
+  #define __Pyx_PyFrame_SetLineNumber(frame, lineno)  (frame)->f_lineno = (lineno)
+#endif
 #define __Pyx_PyString_FormatSafe(a, b)   ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
 #define __Pyx_PyUnicode_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
 #if PY_MAJOR_VERSION >= 3
@@ -163,6 +292,7 @@ END: Cython Metadata */
   #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
 #endif
 #define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception)
 #if PY_MAJOR_VERSION >= 3
   #define PyIntObject                  PyLongObject
   #define PyInt_Type                   PyLong_Type
@@ -201,18 +331,20 @@ END: Cython Metadata */
 #else
   #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
 #endif
-#if PY_VERSION_HEX >= 0x030500B1
-#define __Pyx_PyAsyncMethodsStruct PyAsyncMethods
-#define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async)
-#elif CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
-typedef struct {
-    unaryfunc am_await;
-    unaryfunc am_aiter;
-    unaryfunc am_anext;
-} __Pyx_PyAsyncMethodsStruct;
-#define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved))
+#if CYTHON_USE_ASYNC_SLOTS
+  #if PY_VERSION_HEX >= 0x030500B1
+    #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods
+    #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async)
+  #else
+    typedef struct {
+        unaryfunc am_await;
+        unaryfunc am_aiter;
+        unaryfunc am_anext;
+    } __Pyx_PyAsyncMethodsStruct;
+    #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved))
+  #endif
 #else
-#define __Pyx_PyType_AsAsync(obj) NULL
+  #define __Pyx_PyType_AsAsync(obj) NULL
 #endif
 #ifndef CYTHON_RESTRICT
   #if defined(__GNUC__)
@@ -225,10 +357,39 @@ typedef struct {
     #define CYTHON_RESTRICT
   #endif
 #endif
+#ifndef CYTHON_UNUSED
... 13938 lines suppressed ...

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



More information about the Python-modules-commits mailing list