Full Code of MagicStack/asyncpg for AI

master db8ecc2a38e1 cached
121 files
1.1 MB
271.9k tokens
1440 symbols
1 requests
Download .txt
Showing preview only (1,165K chars total). Download the full file or copy to clipboard to get everything.
Repository: MagicStack/asyncpg
Branch: master
Commit: db8ecc2a38e1
Files: 121
Total size: 1.1 MB

Directory structure:
gitextract_qed7mic1/

├── .clang-format
├── .clangd
├── .flake8
├── .github/
│   ├── ISSUE_TEMPLATE.md
│   ├── RELEASING.rst
│   ├── release_log.py
│   └── workflows/
│       ├── install-krb5.sh
│       ├── install-postgres.sh
│       ├── release.yml
│       └── tests.yml
├── .gitignore
├── .gitmodules
├── AUTHORS
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.rst
├── asyncpg/
│   ├── .gitignore
│   ├── __init__.py
│   ├── _asyncio_compat.py
│   ├── _testbase/
│   │   ├── __init__.py
│   │   └── fuzzer.py
│   ├── _version.py
│   ├── cluster.py
│   ├── compat.py
│   ├── connect_utils.py
│   ├── connection.py
│   ├── connresource.py
│   ├── cursor.py
│   ├── exceptions/
│   │   ├── __init__.py
│   │   └── _base.py
│   ├── introspection.py
│   ├── pool.py
│   ├── prepared_stmt.py
│   ├── protocol/
│   │   ├── .gitignore
│   │   ├── __init__.py
│   │   ├── codecs/
│   │   │   ├── __init__.py
│   │   │   ├── array.pyx
│   │   │   ├── base.pxd
│   │   │   ├── base.pyx
│   │   │   ├── pgproto.pyx
│   │   │   ├── range.pyx
│   │   │   ├── record.pyx
│   │   │   └── textutils.pyx
│   │   ├── consts.pxi
│   │   ├── coreproto.pxd
│   │   ├── coreproto.pyx
│   │   ├── cpythonx.pxd
│   │   ├── encodings.pyx
│   │   ├── pgtypes.pxi
│   │   ├── prepared_stmt.pxd
│   │   ├── prepared_stmt.pyx
│   │   ├── protocol.pxd
│   │   ├── protocol.pyi
│   │   ├── protocol.pyx
│   │   ├── record/
│   │   │   ├── pythoncapi_compat.h
│   │   │   ├── pythoncapi_compat_extras.h
│   │   │   ├── recordobj.c
│   │   │   └── recordobj.h
│   │   ├── record.pyi
│   │   ├── recordcapi.pxd
│   │   ├── scram.pxd
│   │   ├── scram.pyx
│   │   ├── settings.pxd
│   │   └── settings.pyx
│   ├── serverversion.py
│   ├── transaction.py
│   ├── types.py
│   └── utils.py
├── docs/
│   ├── .gitignore
│   ├── Makefile
│   ├── _static/
│   │   └── theme_overrides.css
│   ├── api/
│   │   └── index.rst
│   ├── conf.py
│   ├── faq.rst
│   ├── index.rst
│   ├── installation.rst
│   ├── requirements.txt
│   └── usage.rst
├── pyproject.toml
├── setup.py
├── tests/
│   ├── __init__.py
│   ├── certs/
│   │   ├── ca.cert.pem
│   │   ├── ca.crl.pem
│   │   ├── ca.key.pem
│   │   ├── client.cert.pem
│   │   ├── client.csr.pem
│   │   ├── client.key.pem
│   │   ├── client.key.protected.pem
│   │   ├── client_ca.cert.pem
│   │   ├── client_ca.cert.srl
│   │   ├── client_ca.key.pem
│   │   ├── gen.py
│   │   ├── server.cert.pem
│   │   ├── server.crl.pem
│   │   └── server.key.pem
│   ├── test__environment.py
│   ├── test__sourcecode.py
│   ├── test_adversity.py
│   ├── test_cache_invalidation.py
│   ├── test_cancellation.py
│   ├── test_codecs.py
│   ├── test_connect.py
│   ├── test_copy.py
│   ├── test_cursor.py
│   ├── test_exceptions.py
│   ├── test_execute.py
│   ├── test_introspection.py
│   ├── test_listeners.py
│   ├── test_logging.py
│   ├── test_pool.py
│   ├── test_prepare.py
│   ├── test_record.py
│   ├── test_subinterpreters.py
│   ├── test_test.py
│   ├── test_timeout.py
│   ├── test_transaction.py
│   ├── test_types.py
│   └── test_utils.py
└── tools/
    ├── generate_exceptions.py
    └── generate_type_map.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .clang-format
================================================
# A clang-format style that approximates Python's PEP 7
BasedOnStyle: Google
AlwaysBreakAfterReturnType: All
AllowShortIfStatementsOnASingleLine: false
AlignAfterOpenBracket: Align
BreakBeforeBraces: Stroustrup
ColumnLimit: 95
DerivePointerAlignment: false
IndentWidth: 4
Language: Cpp
PointerAlignment: Right
ReflowComments: true
SpaceBeforeParens: ControlStatements
SpacesInParentheses: false
TabWidth: 4
UseTab: Never
SortIncludes: false


================================================
FILE: .clangd
================================================
Diagnostics:
  Includes:
    IgnoreHeader:
      - "pythoncapi_compat.*\\.h"


================================================
FILE: .flake8
================================================
[flake8]
select = C90,E,F,W,Y0
ignore = E402,E731,W503,W504,E252
exclude = .git,__pycache__,build,dist,.eggs,.github,.local,.venv*,.tox
per-file-ignores = *.pyi: F401,F403,F405,F811,E127,E128,E203,E266,E301,E302,E305,E501,E701,E704,E741,B303,W503,W504


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
<!--
Thank you for reporting an issue/feature request.

If this is a feature request, please disregard this template.  If this is
a bug report, please answer to the questions below.

It will be much easier for us to fix the issue if a test case that reproduces
the problem is provided, with clear instructions on how to run it.

Thank you!
-->

* **asyncpg version**:
* **PostgreSQL version**:
* **Do you use a PostgreSQL SaaS?  If so, which?  Can you reproduce
  the issue with a local PostgreSQL install?**:
* **Python version**:
* **Platform**:
* **Do you use pgbouncer?**:
* **Did you install asyncpg with pip?**:
* **If you built asyncpg locally, which version of Cython did you use?**:
* **Can the issue be reproduced under both asyncio and
  [uvloop](https://github.com/magicstack/uvloop)?**:

<!-- Enter your issue details below this comment. -->


================================================
FILE: .github/RELEASING.rst
================================================
Releasing asyncpg
=================

When making an asyncpg release follow the below checklist.

1. Remove the ``.dev0`` suffix from ``__version__`` in ``asyncpg/__init__.py``.

2. Make a release commit:

   .. code-block:: shell

      $ git commit -a -m "asyncpg vX.Y.0"

   Here, X.Y.0 is the ``__version__`` in ``asyncpg/__init__.py``.

3. Force push into the "releases" branch on Github:

   .. code-block:: shell

      $ git push --force origin master:releases

4. Wait for CI to make the release build.  If there are errors,
   investigate, fix and repeat steps 2 through 4.

5. Prepare the release changelog by cleaning and categorizing the output of
   ``.github/release_log.py``.  Look at previous releases for examples
   of changelog formatting:

   .. code-block:: shell

      $ .github/release_log.py <previously-released-version-tag>

6. Make an annotated, signed git tag and use the changelog as the tag
   annotation:

   .. code-block:: shell

      $ git tag -s vX.Y.0
      <paste changelog>

7. Push the release commit and the new tag to master on Github:

   .. code-block:: shell

      $ git push --follow-tags

8. Wait for CI to publish the build to PyPI.

9. Edit the release on Github and paste the same content you used for
   the tag annotation (Github treats tag annotations as plain text,
   rather than Markdown.)

10. Open master for development by bumping the minor component of
    ``__version__`` in ``asyncpg/__init__.py`` and appending the ``.dev0``
    suffix.


================================================
FILE: .github/release_log.py
================================================
#!/usr/bin/env python3
#
# Copyright (C) 2016-present the asyncpg authors and contributors
# <see AUTHORS file>
#
# This module is part of asyncpg and is released under
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0


import json
import requests
import re
import sys


BASE_URL = 'https://api.github.com/repos/magicstack/asyncpg/compare'


def main():
    if len(sys.argv) < 2:
        print('pass a sha1 hash as a first argument')
        sys.exit(1)

    from_hash = sys.argv[1]
    if len(sys.argv) > 2:
        to_hash = sys.argv[2]

    r = requests.get(f'{BASE_URL}/{from_hash}...{to_hash}')
    data = json.loads(r.text)

    for commit in data['commits']:
        message = commit['commit']['message']
        first_line = message.partition('\n\n')[0]
        if commit.get('author'):
            username = '@{}'.format(commit['author']['login'])
        else:
            username = commit['commit']['author']['name']
        sha = commit["sha"][:8]

        m = re.search(r'\#(?P<num>\d+)\b', message)
        if m:
            issue_num = m.group('num')
        else:
            issue_num = None

        print(f'* {first_line}')
        print(f'  (by {username} in {sha}', end='')
        print(')')
        print()


if __name__ == '__main__':
    main()


================================================
FILE: .github/workflows/install-krb5.sh
================================================
#!/bin/bash

set -Eexuo pipefail
shopt -s nullglob

if [[ $OSTYPE == linux* ]]; then
    if [ "$(id -u)" = "0" ]; then
        SUDO=
    else
        SUDO=sudo
    fi

    if [ -e /etc/os-release ]; then
        source /etc/os-release
    elif [ -e /etc/centos-release ]; then
        ID="centos"
        VERSION_ID=$(cat /etc/centos-release | cut -f3 -d' ' | cut -f1 -d.)
    else
        echo "install-krb5.sh: cannot determine which Linux distro this is" >&2
        exit 1
    fi

    if [ "${ID}" = "debian" -o "${ID}" = "ubuntu" ]; then
        export DEBIAN_FRONTEND=noninteractive

        $SUDO apt-get update
        $SUDO apt-get install -y --no-install-recommends \
            libkrb5-dev krb5-user krb5-kdc krb5-admin-server
    elif [ "${ID}" = "almalinux" ]; then
        $SUDO dnf install -y krb5-server krb5-workstation krb5-libs krb5-devel
    elif [ "${ID}" = "centos" ]; then
        $SUDO yum install -y krb5-server krb5-workstation krb5-libs krb5-devel
    elif [ "${ID}" = "alpine" ]; then
        $SUDO apk add krb5 krb5-server krb5-dev
    else
        echo "install-krb5.sh: Unsupported linux distro: ${distro}" >&2
        exit 1
    fi
else
    echo "install-krb5.sh: unsupported OS: ${OSTYPE}" >&2
    exit 1
fi


================================================
FILE: .github/workflows/install-postgres.sh
================================================
#!/bin/bash

set -Eexuo pipefail
shopt -s nullglob

if [[ $OSTYPE == linux* ]]; then
    PGVERSION=${PGVERSION:-12}

    if [ -e /etc/os-release ]; then
        source /etc/os-release
    elif [ -e /etc/centos-release ]; then
        ID="centos"
        VERSION_ID=$(cat /etc/centos-release | cut -f3 -d' ' | cut -f1 -d.)
    else
        echo "install-postgres.sh: cannot determine which Linux distro this is" >&2
        exit 1
    fi

    if [ "${ID}" = "debian" -o "${ID}" = "ubuntu" ]; then
        export DEBIAN_FRONTEND=noninteractive

        apt-get install -y --no-install-recommends curl gnupg ca-certificates
        curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
        mkdir -p /etc/apt/sources.list.d/
        echo "deb https://apt.postgresql.org/pub/repos/apt/ ${VERSION_CODENAME}-pgdg main" \
            >> /etc/apt/sources.list.d/pgdg.list
        apt-get update
        apt-get install -y --no-install-recommends \
            "postgresql-${PGVERSION}" \
            "postgresql-contrib-${PGVERSION}"
    elif [ "${ID}" = "almalinux" ]; then
        yum install -y \
            "postgresql-server" \
            "postgresql-devel" \
            "postgresql-contrib"
    elif [ "${ID}" = "centos" ]; then
        el="EL-${VERSION_ID%.*}-$(arch)"
        baseurl="https://download.postgresql.org/pub/repos/yum/reporpms"
        yum install -y "${baseurl}/${el}/pgdg-redhat-repo-latest.noarch.rpm"
        if [ ${VERSION_ID%.*} -ge 8 ]; then
            dnf -qy module disable postgresql
        fi
        yum install -y \
            "postgresql${PGVERSION}-server" \
            "postgresql${PGVERSION}-contrib"
        ln -s "/usr/pgsql-${PGVERSION}/bin/pg_config" "/usr/local/bin/pg_config"
    elif [ "${ID}" = "alpine" ]; then
        apk add shadow postgresql postgresql-dev postgresql-contrib
    else
        echo "install-postgres.sh: unsupported Linux distro: ${distro}" >&2
        exit 1
    fi

    useradd -m -s /bin/bash apgtest

elif [[ $OSTYPE == darwin* ]]; then
    brew install postgresql

else
    echo "install-postgres.sh: unsupported OS: ${OSTYPE}" >&2
    exit 1
fi


================================================
FILE: .github/workflows/release.yml
================================================
name: Release

on:
  pull_request:
    branches:
      - "master"
      - "ci"
      - "[0-9]+.[0-9x]+*"
    paths:
      - "asyncpg/_version.py"

jobs:
  validate-release-request:
    runs-on: ubuntu-latest
    steps:
    - name: Validate release PR
      uses: edgedb/action-release/validate-pr@master
      id: checkver
      with:
        require_team: Release Managers
        require_approval: no
        github_token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }}
        version_file: asyncpg/_version.py
        version_line_pattern: |
          __version__(?:\s*:\s*typing\.Final)?\s*=\s*(?:['"])([[:PEP440:]])(?:['"])

    - name: Stop if not approved
      if: steps.checkver.outputs.approved != 'true'
      run: |
        echo ::error::PR is not approved yet.
        exit 1

    - name: Store release version for later use
      env:
        VERSION: ${{ steps.checkver.outputs.version }}
      run: |
        mkdir -p dist/
        echo "${VERSION}" > dist/VERSION

    - uses: actions/upload-artifact@v4
      with:
        name: dist-version
        path: dist/VERSION

  build-sdist:
    needs: validate-release-request
    runs-on: ubuntu-latest

    env:
      PIP_DISABLE_PIP_VERSION_CHECK: 1

    steps:
    - uses: actions/checkout@v5
      with:
        fetch-depth: 50
        submodules: true
        persist-credentials: false

    - name: Set up Python
      uses: actions/setup-python@v6
      with:
        python-version: "3.x"

    - name: Build source distribution
      run: |
        pip install -U setuptools wheel pip
        python setup.py sdist

    - uses: actions/upload-artifact@v4
      with:
        name: dist-sdist
        path: dist/*.tar.*

  build-wheels-matrix:
    needs: validate-release-request
    runs-on: ubuntu-latest
    outputs:
      include: ${{ steps.set-matrix.outputs.include }}
    steps:
      - uses: actions/checkout@v5
        with:
          persist-credentials: false
      - uses: actions/setup-python@v6
        with:
          python-version: "3.x"
      - run: pip install cibuildwheel==3.3.0
      - id: set-matrix
        run: |
          MATRIX_INCLUDE=$(
            {
              cibuildwheel --print-build-identifiers --platform linux --archs x86_64,aarch64 | grep cp |  jq -nRc '{"only": inputs, "os": "ubuntu-latest"}' \
              && cibuildwheel --print-build-identifiers --platform macos --archs x86_64,arm64 | grep cp |  jq -nRc '{"only": inputs, "os": "macos-latest"}' \
              && cibuildwheel --print-build-identifiers --platform windows --archs x86,AMD64 | grep cp |  jq -nRc '{"only": inputs, "os": "windows-latest"}'
            } | jq -sc
          )
          echo "include=$MATRIX_INCLUDE" >> $GITHUB_OUTPUT

  build-wheels:
    needs: build-wheels-matrix
    runs-on: ${{ matrix.os }}
    name: Build ${{ matrix.only }}

    strategy:
      fail-fast: false
      matrix:
        include: ${{ fromJson(needs.build-wheels-matrix.outputs.include) }}

    defaults:
      run:
        shell: bash

    env:
      PIP_DISABLE_PIP_VERSION_CHECK: 1

    steps:
    - uses: actions/checkout@v5
      with:
        fetch-depth: 50
        submodules: true
        persist-credentials: false

    - name: Set up QEMU
      if: runner.os == 'Linux'
      uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392  # v3.6.0

    - uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc  # v3.3.0
      with:
        only: ${{ matrix.only }}
      env:
        CIBW_BUILD_VERBOSITY: 1

    - uses: actions/upload-artifact@v4
      with:
        name: dist-wheels-${{ matrix.only }}
        path: wheelhouse/*.whl

  merge-artifacts:
    runs-on: ubuntu-latest
    needs: [build-sdist, build-wheels]
    steps:
      - name: Merge Artifacts
        uses: actions/upload-artifact/merge@v4
        with:
          name: dist
          delete-merged: true

  publish-docs:
    needs: [build-sdist, build-wheels]
    runs-on: ubuntu-latest

    env:
      PIP_DISABLE_PIP_VERSION_CHECK: 1

    steps:
    - name: Checkout source
      uses: actions/checkout@v5
      with:
        fetch-depth: 5
        submodules: true
        persist-credentials: false

    - name: Set up Python
      uses: actions/setup-python@v6
      with:
        python-version: "3.x"

    - name: Build docs
      run: |
        pip install --group docs
        pip install -e .
        make htmldocs

    - name: Checkout gh-pages
      uses: actions/checkout@v5
      with:
        fetch-depth: 5
        ref: gh-pages
        path: docs/gh-pages
        persist-credentials: false

    - name: Sync docs
      run: |
        rsync -a docs/_build/html/ docs/gh-pages/current/

    - name: Commit and push docs
      uses: magicstack/gha-commit-and-push@master
      with:
        target_branch: gh-pages
        workdir: docs/gh-pages
        commit_message: Automatic documentation update
        github_token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }}
        ssh_key: ${{ secrets.RELEASE_BOT_SSH_KEY }}
        gpg_key: ${{ secrets.RELEASE_BOT_GPG_KEY }}
        gpg_key_id: "5C468778062D87BF!"

  publish:
    needs: [build-sdist, build-wheels, publish-docs]
    runs-on: ubuntu-latest

    environment:
      name: pypi
      url: https://pypi.org/p/asyncpg
    permissions:
      id-token: write
      attestations: write
      contents: write
      deployments: write

    steps:
    - uses: actions/checkout@v5
      with:
        fetch-depth: 5
        submodules: false
        persist-credentials: false

    - uses: actions/download-artifact@v4
      with:
        name: dist
        path: dist/

    - name: Extract Release Version
      id: relver
      run: |
        set -e
        echo "version=$(cat dist/VERSION)" >> $GITHUB_OUTPUT
        rm dist/VERSION

    - name: Merge and tag the PR
      uses: edgedb/action-release/merge@master
      with:
        github_token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }}
        ssh_key: ${{ secrets.RELEASE_BOT_SSH_KEY }}
        gpg_key: ${{ secrets.RELEASE_BOT_GPG_KEY }}
        gpg_key_id: "5C468778062D87BF!"
        tag_name: v${{ steps.relver.outputs.version }}

    - name: Publish Github Release
      uses: elprans/gh-action-create-release@master
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        tag_name: v${{ steps.relver.outputs.version }}
        release_name: v${{ steps.relver.outputs.version }}
        target: ${{ github.event.pull_request.base.ref }}
        body: ${{ github.event.pull_request.body }}

    - run: |
        ls -al dist/

    - name: Upload to PyPI
      uses: pypa/gh-action-pypi-publish@release/v1
      with:
        attestations: true


================================================
FILE: .github/workflows/tests.yml
================================================
name: Tests

on:
  push:
    branches:
      - master
      - ci
  pull_request:
    branches:
      - master

jobs:
  test-platforms:
    # NOTE: this matrix is for testing various combinations of Python and OS
    # versions on the system-installed PostgreSQL version (which is usually
    # fairly recent). For a PostgreSQL version matrix see the test-postgres
    # job.
    strategy:
      matrix:
        python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]
        os: [ubuntu-latest, macos-latest, windows-latest]
        loop: [asyncio, uvloop]
        exclude:
          # uvloop does not support windows
          - loop: uvloop
            os: windows-latest

    runs-on: ${{ matrix.os }}

    permissions: {}

    defaults:
      run:
        shell: bash

    env:
      PIP_DISABLE_PIP_VERSION_CHECK: 1

    steps:
    - uses: actions/checkout@v5
      with:
        fetch-depth: 50
        submodules: true
        persist-credentials: false

    - name: Check if release PR.
      uses: edgedb/action-release/validate-pr@master
      id: release
      with:
        github_token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }}
        missing_version_ok: yes
        version_file: asyncpg/_version.py
        version_line_pattern: |
          __version__(?:\s*:\s*typing\.Final)?\s*=\s*(?:['"])([[:PEP440:]])(?:['"])

    - name: Setup PostgreSQL
      if: "!steps.release.outputs.is_release && matrix.os == 'macos-latest'"
      run: |
        POSTGRES_FORMULA="postgresql@18"
        brew install "$POSTGRES_FORMULA"
        echo "$(brew --prefix "$POSTGRES_FORMULA")/bin" >> $GITHUB_PATH

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v6
      if: "!steps.release.outputs.is_release"
      with:
        python-version: ${{ matrix.python-version }}

    - name: Install Python Deps
      if: "!steps.release.outputs.is_release"
      run: |
        [ "$RUNNER_OS" = "Linux" ] && .github/workflows/install-krb5.sh
        python -m pip install -U pip setuptools wheel
        python -m pip install --group test
        python -m pip install -e .

    - name: Test
      if: "!steps.release.outputs.is_release"
      env:
        LOOP_IMPL: ${{ matrix.loop }}
      run: |
        if [ "${LOOP_IMPL}" = "uvloop" ]; then
          env USE_UVLOOP=1 python -m unittest -v tests.suite
        else
          python -m unittest -v tests.suite
        fi

  test-postgres:
    strategy:
      matrix:
        postgres-version: ["9.5", "9.6", "10", "11", "12", "13", "14", "15", "16", "17", "18"]

    runs-on: ubuntu-latest

    permissions: {}

    env:
      PIP_DISABLE_PIP_VERSION_CHECK: 1

    steps:
    - uses: actions/checkout@v5
      with:
        fetch-depth: 50
        submodules: true
        persist-credentials: false

    - name: Check if release PR.
      uses: edgedb/action-release/validate-pr@master
      id: release
      with:
        github_token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }}
        missing_version_ok: yes
        version_file: asyncpg/_version.py
        version_line_pattern: |
          __version__(?:\s*:\s*typing\.Final)?\s*=\s*(?:['"])([[:PEP440:]])(?:['"])

    - name: Set up PostgreSQL
      if: "!steps.release.outputs.is_release"
      env:
        PGVERSION: ${{ matrix.postgres-version }}
        DISTRO_NAME: focal
      run: |
        sudo env DISTRO_NAME="${DISTRO_NAME}" PGVERSION="${PGVERSION}" \
          .github/workflows/install-postgres.sh
        echo PGINSTALLATION="/usr/lib/postgresql/${PGVERSION}/bin" \
          >> "${GITHUB_ENV}"

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v6
      if: "!steps.release.outputs.is_release"
      with:
        python-version: "3.x"

    - name: Install Python Deps
      if: "!steps.release.outputs.is_release"
      run: |
        [ "$RUNNER_OS" = "Linux" ] && .github/workflows/install-krb5.sh
        python -m pip install -U pip setuptools wheel
        python -m pip install --group test
        python -m pip install -e .

    - name: Test
      if: "!steps.release.outputs.is_release"
      env:
        PGVERSION: ${{ matrix.postgres-version }}
      run: |
        python -m unittest -v tests.suite

  # This job exists solely to act as the test job aggregate to be
  # targeted by branch policies.
  regression-tests:
    name: "Regression Tests"
    needs: [test-platforms, test-postgres]
    runs-on: ubuntu-latest
    permissions: {}

    steps:
      - run: echo OK


================================================
FILE: .gitignore
================================================
*._*
*.pyc
*.pyo
*.ymlc
*.ymlc~
*.scssc
*.so
*.pyd
*~
.#*
.DS_Store
.project
.pydevproject
.settings
.idea
/.ropeproject
\#*#
/pub
/test*.py
/.local
/perf.data*
/config_local.yml
/build
__pycache__/
.d8_history
/*.egg
/*.egg-info
/dist
/.cache
docs/_build
*,cover
.coverage
/.pytest_cache/
/.eggs
/.vscode
/.zed
/.mypy_cache
/.venv*
/.tox
/compile_commands.json


================================================
FILE: .gitmodules
================================================
[submodule "asyncpg/pgproto"]
	path = asyncpg/pgproto
	url = https://github.com/MagicStack/py-pgproto.git


================================================
FILE: AUTHORS
================================================
Main contributors
=================

MagicStack Inc.:
    Elvis Pranskevichus <elvis@magic.io>
    Yury Selivanov <yury@magic.io>


================================================
FILE: LICENSE
================================================
Copyright (C) 2016-present the asyncpg authors and contributors.

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright (C) 2016-present the asyncpg authors and contributors
   <see AUTHORS file>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: MANIFEST.in
================================================
recursive-include docs *.py *.rst Makefile *.css
recursive-include examples *.py
recursive-include tests *.py *.pem
recursive-include asyncpg *.pyx *.pxd *.pxi *.py *.pyi *.c *.h
include LICENSE README.rst Makefile performance.png .flake8


================================================
FILE: Makefile
================================================
.PHONY: compile debug test quicktest clean all


PYTHON ?= python
ROOT = $(dir $(realpath $(firstword $(MAKEFILE_LIST))))


all: compile


clean:
	rm -fr dist/ doc/_build/
	rm -fr asyncpg/pgproto/*.c asyncpg/pgproto/*.html
	rm -fr asyncpg/pgproto/codecs/*.html
	rm -fr asyncpg/pgproto/*.so
	rm -fr asyncpg/protocol/*.c asyncpg/protocol/*.html
	rm -fr asyncpg/protocol/*.so build *.egg-info
	rm -fr asyncpg/protocol/codecs/*.html
	find . -name '__pycache__' | xargs rm -rf


compile:
	env ASYNCPG_BUILD_CYTHON_ALWAYS=1 $(PYTHON) -m pip install -e .


debug:
	env ASYNCPG_DEBUG=1 $(PYTHON) -m pip install -e .

test:
	PYTHONASYNCIODEBUG=1 $(PYTHON) -m unittest -v tests.suite
	$(PYTHON) -m unittest -v tests.suite
	USE_UVLOOP=1 $(PYTHON) -m unittest -v tests.suite


testinstalled:
	cd "$${HOME}" && $(PYTHON) $(ROOT)/tests/__init__.py


quicktest:
	$(PYTHON) -m unittest -v tests.suite


htmldocs:
	$(PYTHON) -m pip install -e .[docs]
	$(MAKE) -C docs html


================================================
FILE: README.rst
================================================
asyncpg -- A fast PostgreSQL Database Client Library for Python/asyncio
=======================================================================

.. image:: https://github.com/MagicStack/asyncpg/workflows/Tests/badge.svg
   :target: https://github.com/MagicStack/asyncpg/actions?query=workflow%3ATests+branch%3Amaster
   :alt: GitHub Actions status
.. 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/>`_.

asyncpg requires Python 3.9 or later and is supported for PostgreSQL
versions 9.5 to 18.  Other PostgreSQL versions or other databases
implementing the PostgreSQL protocol *may* work, but are not being
actively tested.


Documentation
-------------

The project documentation can be found
`here <https://magicstack.github.io/asyncpg/current/>`_.


Performance
-----------

In our testing asyncpg is, on average, **5x** faster than psycopg3.

.. image:: https://raw.githubusercontent.com/MagicStack/asyncpg/master/performance.png?fddca40ab0
    :target: https://gistpreview.github.io/?0ed296e93523831ea0918d42dd1258c2

The above results are a geometric mean of benchmarks obtained with PostgreSQL
`client driver benchmarking toolbench <https://github.com/MagicStack/pgbench>`_
in June 2023 (click on the chart to see full details).


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 is available on PyPI.  When not using GSSAPI/SSPI authentication it
has no dependencies.  Use pip to install::

    $ pip install asyncpg

If you need GSSAPI/SSPI authentication, use::

    $ pip install 'asyncpg[gssauth]'

For more details, please `see the documentation
<https://magicstack.github.io/asyncpg/current/installation.html>`_.


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 WHERE id = $1',
            10,
        )
        await conn.close()

    asyncio.run(run())


License
-------

asyncpg is developed and distributed under the Apache 2.0 license.


================================================
FILE: asyncpg/.gitignore
================================================
*.html


================================================
FILE: asyncpg/__init__.py
================================================
# Copyright (C) 2016-present the asyncpg authors and contributors
# <see AUTHORS file>
#
# This module is part of asyncpg and is released under
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0

from __future__ import annotations

from .connection import connect, Connection  # NOQA
from .exceptions import *  # NOQA
from .pool import create_pool, Pool  # NOQA
from .protocol import Record  # NOQA
from .types import *  # NOQA


from ._version import __version__  # NOQA

from . import exceptions


__all__: tuple[str, ...] = (
    'connect', 'create_pool', 'Pool', 'Record', 'Connection'
)
__all__ += exceptions.__all__ # NOQA


================================================
FILE: asyncpg/_asyncio_compat.py
================================================
# Backports from Python/Lib/asyncio for older Pythons
#
# Copyright (c) 2001-2023 Python Software Foundation; All Rights Reserved
#
# SPDX-License-Identifier: PSF-2.0

from __future__ import annotations

import asyncio
import functools
import sys
import typing

if typing.TYPE_CHECKING:
    from . import compat

if sys.version_info < (3, 11):
    from async_timeout import timeout as timeout_ctx
else:
    from asyncio import timeout as timeout_ctx

_T = typing.TypeVar('_T')


async def wait_for(fut: compat.Awaitable[_T], timeout: float | None) -> _T:
    """Wait for the single Future or coroutine to complete, with timeout.

    Coroutine will be wrapped in Task.

    Returns result of the Future or coroutine.  When a timeout occurs,
    it cancels the task and raises TimeoutError.  To avoid the task
    cancellation, wrap it in shield().

    If the wait is cancelled, the task is also cancelled.

    If the task supresses the cancellation and returns a value instead,
    that value is returned.

    This function is a coroutine.
    """
    # The special case for timeout <= 0 is for the following case:
    #
    # async def test_waitfor():
    #     func_started = False
    #
    #     async def func():
    #         nonlocal func_started
    #         func_started = True
    #
    #     try:
    #         await asyncio.wait_for(func(), 0)
    #     except asyncio.TimeoutError:
    #         assert not func_started
    #     else:
    #         assert False
    #
    # asyncio.run(test_waitfor())

    if timeout is not None and timeout <= 0:
        fut = asyncio.ensure_future(fut)

        if fut.done():
            return fut.result()

        await _cancel_and_wait(fut)
        try:
            return fut.result()
        except asyncio.CancelledError as exc:
            raise TimeoutError from exc

    async with timeout_ctx(timeout):
        return await fut


async def _cancel_and_wait(fut: asyncio.Future[_T]) -> None:
    """Cancel the *fut* future or task and wait until it completes."""

    loop = asyncio.get_running_loop()
    waiter = loop.create_future()
    cb = functools.partial(_release_waiter, waiter)
    fut.add_done_callback(cb)

    try:
        fut.cancel()
        # We cannot wait on *fut* directly to make
        # sure _cancel_and_wait itself is reliably cancellable.
        await waiter
    finally:
        fut.remove_done_callback(cb)


def _release_waiter(waiter: asyncio.Future[typing.Any], *args: object) -> None:
    if not waiter.done():
        waiter.set_result(None)


================================================
FILE: asyncpg/_testbase/__init__.py
================================================
# Copyright (C) 2016-present the asyncpg authors and contributors
# <see AUTHORS file>
#
# This module is part of asyncpg and is released under
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0


import asyncio
import atexit
import contextlib
import functools
import inspect
import logging
import os
import re
import textwrap
import time
import traceback
import unittest


import asyncpg
from asyncpg import cluster as pg_cluster
from asyncpg import connection as pg_connection
from asyncpg import pool as pg_pool

from . import fuzzer


@contextlib.contextmanager
def silence_asyncio_long_exec_warning():
    def flt(log_record):
        msg = log_record.getMessage()
        return not msg.startswith('Executing ')

    logger = logging.getLogger('asyncio')
    logger.addFilter(flt)
    try:
        yield
    finally:
        logger.removeFilter(flt)


def with_timeout(timeout):
    def wrap(func):
        func.__timeout__ = timeout
        return func

    return wrap


class TestCaseMeta(type(unittest.TestCase)):
    TEST_TIMEOUT = None

    @staticmethod
    def _iter_methods(bases, ns):
        for base in bases:
            for methname in dir(base):
                if not methname.startswith('test_'):
                    continue

                meth = getattr(base, methname)
                if not inspect.iscoroutinefunction(meth):
                    continue

                yield methname, meth

        for methname, meth in ns.items():
            if not methname.startswith('test_'):
                continue

            if not inspect.iscoroutinefunction(meth):
                continue

            yield methname, meth

    def __new__(mcls, name, bases, ns):
        for methname, meth in mcls._iter_methods(bases, ns):
            @functools.wraps(meth)
            def wrapper(self, *args, __meth__=meth, **kwargs):
                coro = __meth__(self, *args, **kwargs)
                timeout = getattr(__meth__, '__timeout__', mcls.TEST_TIMEOUT)
                if timeout:
                    coro = asyncio.wait_for(coro, timeout)
                    try:
                        self.loop.run_until_complete(coro)
                    except asyncio.TimeoutError:
                        raise self.failureException(
                            'test timed out after {} seconds'.format(
                                timeout)) from None
                else:
                    self.loop.run_until_complete(coro)
            ns[methname] = wrapper

        return super().__new__(mcls, name, bases, ns)


class TestCase(unittest.TestCase, metaclass=TestCaseMeta):

    @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)
        cls.loop = loop

    @classmethod
    def tearDownClass(cls):
        cls.loop.close()
        asyncio.set_event_loop(None)

    def setUp(self):
        self.loop.set_exception_handler(self.loop_exception_handler)
        self.__unhandled_exceptions = []

    def tearDown(self):
        excs = []
        for exc in self.__unhandled_exceptions:
            if isinstance(exc, ConnectionResetError):
                texc = traceback.TracebackException.from_exception(
                    exc, lookup_lines=False)
                if texc.stack[-1].name == "_call_connection_lost":
                    # On Windows calling socket.shutdown may raise
                    # ConnectionResetError, which happens in the
                    # finally block of _call_connection_lost.
                    continue
            excs.append(exc)

        if excs:
            formatted = []

            for i, context in enumerate(excs):
                formatted.append(self._format_loop_exception(context, i + 1))

            self.fail(
                'unexpected exceptions in asynchronous code:\n' +
                '\n'.join(formatted))

    @contextlib.contextmanager
    def assertRunUnder(self, delta):
        st = time.monotonic()
        try:
            yield
        finally:
            elapsed = time.monotonic() - st
            if elapsed > delta:
                raise AssertionError(
                    'running block took {:0.3f}s which is longer '
                    'than the expected maximum of {:0.3f}s'.format(
                        elapsed, delta))

    @contextlib.contextmanager
    def assertLoopErrorHandlerCalled(self, msg_re: str):
        contexts = []

        def handler(loop, ctx):
            contexts.append(ctx)

        old_handler = self.loop.get_exception_handler()
        self.loop.set_exception_handler(handler)
        try:
            yield

            for ctx in contexts:
                msg = ctx.get('message')
                if msg and re.search(msg_re, msg):
                    return

            raise AssertionError(
                'no message matching {!r} was logged with '
                'loop.call_exception_handler()'.format(msg_re))

        finally:
            self.loop.set_exception_handler(old_handler)

    def loop_exception_handler(self, loop, context):
        self.__unhandled_exceptions.append(context)
        loop.default_exception_handler(context)

    def _format_loop_exception(self, context, n):
        message = context.get('message', 'Unhandled exception in event loop')
        exception = context.get('exception')
        if exception is not None:
            exc_info = (type(exception), exception, exception.__traceback__)
        else:
            exc_info = None

        lines = []
        for key in sorted(context):
            if key in {'message', 'exception'}:
                continue
            value = context[key]
            if key == 'source_traceback':
                tb = ''.join(traceback.format_list(value))
                value = 'Object created at (most recent call last):\n'
                value += tb.rstrip()
            else:
                try:
                    value = repr(value)
                except Exception as ex:
                    value = ('Exception in __repr__ {!r}; '
                             'value type: {!r}'.format(ex, type(value)))
            lines.append('[{}]: {}\n\n'.format(key, value))

        if exc_info is not None:
            lines.append('[exception]:\n')
            formatted_exc = textwrap.indent(
                ''.join(traceback.format_exception(*exc_info)), '  ')
            lines.append(formatted_exc)

        details = textwrap.indent(''.join(lines), '    ')
        return '{:02d}. {}:\n{}\n'.format(n, message, details)


_default_cluster = None


def _init_cluster(ClusterCls, cluster_kwargs, initdb_options=None):
    cluster = ClusterCls(**cluster_kwargs)
    cluster.init(**(initdb_options or {}))
    cluster.trust_local_connections()
    atexit.register(_shutdown_cluster, cluster)
    return cluster


def _get_initdb_options(initdb_options=None):
    if not initdb_options:
        initdb_options = {}
    else:
        initdb_options = dict(initdb_options)

    # Make the default superuser name stable.
    if 'username' not in initdb_options:
        initdb_options['username'] = 'postgres'

    return initdb_options


def _init_default_cluster(initdb_options=None):
    global _default_cluster

    if _default_cluster is None:
        pg_host = os.environ.get('PGHOST')
        if pg_host:
            # Using existing cluster, assuming it is initialized and running
            _default_cluster = pg_cluster.RunningCluster()
        else:
            _default_cluster = _init_cluster(
                pg_cluster.TempCluster,
                cluster_kwargs={
                    "data_dir_suffix": ".apgtest",
                },
                initdb_options=_get_initdb_options(initdb_options),
            )

    return _default_cluster


def _shutdown_cluster(cluster):
    if cluster.get_status() == 'running':
        cluster.stop()
    if cluster.get_status() != 'not-initialized':
        cluster.destroy()


def create_pool(dsn=None, *,
                min_size=10,
                max_size=10,
                max_queries=50000,
                max_inactive_connection_lifetime=60.0,
                connect=None,
                setup=None,
                init=None,
                loop=None,
                pool_class=pg_pool.Pool,
                connection_class=pg_connection.Connection,
                record_class=asyncpg.Record,
                **connect_kwargs):
    return pool_class(
        dsn,
        min_size=min_size,
        max_size=max_size,
        max_queries=max_queries,
        loop=loop,
        connect=connect,
        setup=setup,
        init=init,
        max_inactive_connection_lifetime=max_inactive_connection_lifetime,
        connection_class=connection_class,
        record_class=record_class,
        **connect_kwargs,
    )


class ClusterTestCase(TestCase):
    @classmethod
    def get_server_settings(cls):
        settings = {
            'log_connections': 'on'
        }

        if cls.cluster.get_pg_version() >= (11, 0):
            # JITting messes up timing tests, and
            # is not essential for testing.
            settings['jit'] = 'off'

        return settings

    @classmethod
    def new_cluster(cls, ClusterCls, *, cluster_kwargs={}, initdb_options={}):
        cluster = _init_cluster(ClusterCls, cluster_kwargs,
                                _get_initdb_options(initdb_options))
        cls._clusters.append(cluster)
        return cluster

    @classmethod
    def start_cluster(cls, cluster, *, server_settings={}):
        cluster.start(port='dynamic', server_settings=server_settings)

    @classmethod
    def setup_cluster(cls):
        cls.cluster = _init_default_cluster()

        if cls.cluster.get_status() != 'running':
            cls.cluster.start(
                port='dynamic', server_settings=cls.get_server_settings())

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls._clusters = []
        cls.setup_cluster()

    @classmethod
    def tearDownClass(cls):
        super().tearDownClass()
        for cluster in cls._clusters:
            if cluster is not _default_cluster:
                cluster.stop()
                cluster.destroy()
        cls._clusters = []

    @classmethod
    def get_connection_spec(cls, kwargs={}):
        conn_spec = cls.cluster.get_connection_spec()
        if kwargs.get('dsn'):
            conn_spec.pop('host')
        conn_spec.update(kwargs)
        if not os.environ.get('PGHOST') and not kwargs.get('dsn'):
            if 'database' not in conn_spec:
                conn_spec['database'] = 'postgres'
            if 'user' not in conn_spec:
                conn_spec['user'] = 'postgres'
        return conn_spec

    @classmethod
    def connect(cls, **kwargs):
        conn_spec = cls.get_connection_spec(kwargs)
        return pg_connection.connect(**conn_spec, loop=cls.loop)

    def setUp(self):
        super().setUp()
        self._pools = []

    def tearDown(self):
        super().tearDown()
        for pool in self._pools:
            pool.terminate()
        self._pools = []

    def create_pool(self, pool_class=pg_pool.Pool,
                    connection_class=pg_connection.Connection, **kwargs):
        conn_spec = self.get_connection_spec(kwargs)
        pool = create_pool(loop=self.loop, pool_class=pool_class,
                           connection_class=connection_class, **conn_spec)
        self._pools.append(pool)
        return pool


class ProxiedClusterTestCase(ClusterTestCase):
    @classmethod
    def get_server_settings(cls):
        settings = dict(super().get_server_settings())
        settings['listen_addresses'] = '127.0.0.1'
        return settings

    @classmethod
    def get_proxy_settings(cls):
        return {'fuzzing-mode': None}

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        conn_spec = cls.cluster.get_connection_spec()
        host = conn_spec.get('host')
        if not host:
            host = '127.0.0.1'
        elif host.startswith('/'):
            host = '127.0.0.1'
        cls.proxy = fuzzer.TCPFuzzingProxy(
            backend_host=host,
            backend_port=conn_spec['port'],
        )
        cls.proxy.start()

    @classmethod
    def tearDownClass(cls):
        cls.proxy.stop()
        super().tearDownClass()

    @classmethod
    def get_connection_spec(cls, kwargs):
        conn_spec = super().get_connection_spec(kwargs)
        conn_spec['host'] = cls.proxy.listening_addr
        conn_spec['port'] = cls.proxy.listening_port
        return conn_spec

    def tearDown(self):
        self.proxy.reset()
        super().tearDown()


def with_connection_options(**options):
    if not options:
        raise ValueError('no connection options were specified')

    def wrap(func):
        func.__connect_options__ = options
        return func

    return wrap


class ConnectedTestCase(ClusterTestCase):

    def setUp(self):
        super().setUp()

        # Extract options set up with `with_connection_options`.
        test_func = getattr(self, self._testMethodName).__func__
        opts = getattr(test_func, '__connect_options__', {})
        self.con = self.loop.run_until_complete(self.connect(**opts))
        self.server_version = self.con.get_server_version()

    def tearDown(self):
        try:
            self.loop.run_until_complete(self.con.close())
            self.con = None
        finally:
            super().tearDown()


class HotStandbyTestCase(ClusterTestCase):

    @classmethod
    def setup_cluster(cls):
        cls.master_cluster = cls.new_cluster(pg_cluster.TempCluster)
        cls.start_cluster(
            cls.master_cluster,
            server_settings={
                'max_wal_senders': 10,
                'wal_level': 'hot_standby'
            }
        )

        con = None

        try:
            con = cls.loop.run_until_complete(
                cls.master_cluster.connect(
                    database='postgres', user='postgres', loop=cls.loop))

            cls.loop.run_until_complete(
                con.execute('''
                    CREATE ROLE replication WITH LOGIN REPLICATION
                '''))

            cls.master_cluster.trust_local_replication_by('replication')

            conn_spec = cls.master_cluster.get_connection_spec()

            cls.standby_cluster = cls.new_cluster(
                pg_cluster.HotStandbyCluster,
                cluster_kwargs={
                    'master': conn_spec,
                    'replication_user': 'replication'
                }
            )
            cls.start_cluster(
                cls.standby_cluster,
                server_settings={
                    'hot_standby': True
                }
            )

        finally:
            if con is not None:
                cls.loop.run_until_complete(con.close())

    @classmethod
    def get_cluster_connection_spec(cls, cluster, kwargs={}):
        conn_spec = cluster.get_connection_spec()
        if kwargs.get('dsn'):
            conn_spec.pop('host')
        conn_spec.update(kwargs)
        if not os.environ.get('PGHOST') and not kwargs.get('dsn'):
            if 'database' not in conn_spec:
                conn_spec['database'] = 'postgres'
            if 'user' not in conn_spec:
                conn_spec['user'] = 'postgres'
        return conn_spec

    @classmethod
    def get_connection_spec(cls, kwargs={}):
        primary_spec = cls.get_cluster_connection_spec(
            cls.master_cluster, kwargs
        )
        standby_spec = cls.get_cluster_connection_spec(
            cls.standby_cluster, kwargs
        )
        return {
            'host': [primary_spec['host'], standby_spec['host']],
            'port': [primary_spec['port'], standby_spec['port']],
            'database': primary_spec['database'],
            'user': primary_spec['user'],
            **kwargs
        }

    @classmethod
    def connect_primary(cls, **kwargs):
        conn_spec = cls.get_cluster_connection_spec(cls.master_cluster, kwargs)
        return pg_connection.connect(**conn_spec, loop=cls.loop)

    @classmethod
    def connect_standby(cls, **kwargs):
        conn_spec = cls.get_cluster_connection_spec(
            cls.standby_cluster,
            kwargs
        )
        return pg_connection.connect(**conn_spec, loop=cls.loop)


================================================
FILE: asyncpg/_testbase/fuzzer.py
================================================
# Copyright (C) 2016-present the asyncpg authors and contributors
# <see AUTHORS file>
#
# This module is part of asyncpg and is released under
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0


import asyncio
import socket
import threading
import typing

from asyncpg import cluster


class StopServer(Exception):
    pass


class TCPFuzzingProxy:
    def __init__(self, *, listening_addr: str='127.0.0.1',
                 listening_port: typing.Optional[int]=None,
                 backend_host: str, backend_port: int,
                 settings: typing.Optional[dict]=None) -> None:
        self.listening_addr = listening_addr
        self.listening_port = listening_port
        self.backend_host = backend_host
        self.backend_port = backend_port
        self.settings = settings or {}
        self.loop = None
        self.connectivity = None
        self.connectivity_loss = None
        self.stop_event = None
        self.connections = {}
        self.sock = None
        self.listen_task = None

    async def _wait(self, work):
        work_task = asyncio.ensure_future(work)
        stop_event_task = asyncio.ensure_future(self.stop_event.wait())

        try:
            await asyncio.wait(
                [work_task, stop_event_task],
                return_when=asyncio.FIRST_COMPLETED)

            if self.stop_event.is_set():
                raise StopServer()
            else:
                return work_task.result()
        finally:
            if not work_task.done():
                work_task.cancel()
            if not stop_event_task.done():
                stop_event_task.cancel()

    def start(self):
        started = threading.Event()
        self.thread = threading.Thread(
            target=self._start_thread, args=(started,))
        self.thread.start()
        if not started.wait(timeout=2):
            raise RuntimeError('fuzzer proxy failed to start')

    def stop(self):
        self.loop.call_soon_threadsafe(self._stop)
        self.thread.join()

    def _stop(self):
        self.stop_event.set()

    def _start_thread(self, started_event):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

        self.connectivity = asyncio.Event()
        self.connectivity.set()
        self.connectivity_loss = asyncio.Event()
        self.stop_event = asyncio.Event()

        if self.listening_port is None:
            self.listening_port = cluster.find_available_port()

        self.sock = socket.socket()
        self.sock.bind((self.listening_addr, self.listening_port))
        self.sock.listen(50)
        self.sock.setblocking(False)

        try:
            self.loop.run_until_complete(self._main(started_event))
        finally:
            self.loop.close()

    async def _main(self, started_event):
        self.listen_task = asyncio.ensure_future(self.listen())
        # Notify the main thread that we are ready to go.
        started_event.set()
        try:
            await self.listen_task
        finally:
            for c in list(self.connections):
                c.close()
            await asyncio.sleep(0.01)
            if hasattr(self.loop, 'remove_reader'):
                self.loop.remove_reader(self.sock.fileno())
            self.sock.close()

    async def listen(self):
        while True:
            try:
                client_sock, _ = await self._wait(
                    self.loop.sock_accept(self.sock))

                backend_sock = socket.socket()
                backend_sock.setblocking(False)

                await self._wait(self.loop.sock_connect(
                    backend_sock, (self.backend_host, self.backend_port)))
            except StopServer:
                break

            conn = Connection(client_sock, backend_sock, self)
            conn_task = self.loop.create_task(conn.handle())
            self.connections[conn] = conn_task

    def trigger_connectivity_loss(self):
        self.loop.call_soon_threadsafe(self._trigger_connectivity_loss)

    def _trigger_connectivity_loss(self):
        self.connectivity.clear()
        self.connectivity_loss.set()

    def restore_connectivity(self):
        self.loop.call_soon_threadsafe(self._restore_connectivity)

    def _restore_connectivity(self):
        self.connectivity.set()
        self.connectivity_loss.clear()

    def reset(self):
        self.restore_connectivity()

    def _close_connection(self, connection):
        conn_task = self.connections.pop(connection, None)
        if conn_task is not None:
            conn_task.cancel()

    def close_all_connections(self):
        for conn in list(self.connections):
            self.loop.call_soon_threadsafe(self._close_connection, conn)


class Connection:
    def __init__(self, client_sock, backend_sock, proxy):
        self.client_sock = client_sock
        self.backend_sock = backend_sock
        self.proxy = proxy
        self.loop = proxy.loop
        self.connectivity = proxy.connectivity
        self.connectivity_loss = proxy.connectivity_loss
        self.proxy_to_backend_task = None
        self.proxy_from_backend_task = None
        self.is_closed = False

    def close(self):
        if self.is_closed:
            return

        self.is_closed = True

        if self.proxy_to_backend_task is not None:
            self.proxy_to_backend_task.cancel()
            self.proxy_to_backend_task = None

        if self.proxy_from_backend_task is not None:
            self.proxy_from_backend_task.cancel()
            self.proxy_from_backend_task = None

        self.proxy._close_connection(self)

    async def handle(self):
        self.proxy_to_backend_task = asyncio.ensure_future(
            self.proxy_to_backend())

        self.proxy_from_backend_task = asyncio.ensure_future(
            self.proxy_from_backend())

        try:
            await asyncio.wait(
                [self.proxy_to_backend_task, self.proxy_from_backend_task],
                return_when=asyncio.FIRST_COMPLETED)

        finally:
            if self.proxy_to_backend_task is not None:
                self.proxy_to_backend_task.cancel()

            if self.proxy_from_backend_task is not None:
                self.proxy_from_backend_task.cancel()

            # Asyncio fails to properly remove the readers and writers
            # when the task doing recv() or send() is cancelled, so
            # we must remove the readers and writers manually before
            # closing the sockets.
            self.loop.remove_reader(self.client_sock.fileno())
            self.loop.remove_writer(self.client_sock.fileno())
            self.loop.remove_reader(self.backend_sock.fileno())
            self.loop.remove_writer(self.backend_sock.fileno())

            self.client_sock.close()
            self.backend_sock.close()

    async def _read(self, sock, n):
        read_task = asyncio.ensure_future(
            self.loop.sock_recv(sock, n))
        conn_event_task = asyncio.ensure_future(
            self.connectivity_loss.wait())

        try:
            await asyncio.wait(
                [read_task, conn_event_task],
                return_when=asyncio.FIRST_COMPLETED)

            if self.connectivity_loss.is_set():
                return None
            else:
                return read_task.result()
        finally:
            if not self.loop.is_closed():
                if not read_task.done():
                    read_task.cancel()
                if not conn_event_task.done():
                    conn_event_task.cancel()

    async def _write(self, sock, data):
        write_task = asyncio.ensure_future(
            self.loop.sock_sendall(sock, data))
        conn_event_task = asyncio.ensure_future(
            self.connectivity_loss.wait())

        try:
            await asyncio.wait(
                [write_task, conn_event_task],
                return_when=asyncio.FIRST_COMPLETED)

            if self.connectivity_loss.is_set():
                return None
            else:
                return write_task.result()
        finally:
            if not self.loop.is_closed():
                if not write_task.done():
                    write_task.cancel()
                if not conn_event_task.done():
                    conn_event_task.cancel()

    async def proxy_to_backend(self):
        buf = None

        try:
            while True:
                await self.connectivity.wait()
                if buf is not None:
                    data = buf
                    buf = None
                else:
                    data = await self._read(self.client_sock, 4096)
                if data == b'':
                    break
                if self.connectivity_loss.is_set():
                    if data:
                        buf = data
                    continue
                await self._write(self.backend_sock, data)

        except ConnectionError:
            pass

        finally:
            if not self.loop.is_closed():
                self.loop.call_soon(self.close)

    async def proxy_from_backend(self):
        buf = None

        try:
            while True:
                await self.connectivity.wait()
                if buf is not None:
                    data = buf
                    buf = None
                else:
                    data = await self._read(self.backend_sock, 4096)
                if data == b'':
                    break
                if self.connectivity_loss.is_set():
                    if data:
                        buf = data
                    continue
                await self._write(self.client_sock, data)

        except ConnectionError:
            pass

        finally:
            if not self.loop.is_closed():
                self.loop.call_soon(self.close)


================================================
FILE: asyncpg/_version.py
================================================
# This file MUST NOT contain anything but the __version__ assignment.
#
# When making a release, change the value of __version__
# to an appropriate value, and open a pull request against
# the correct branch (master if making a new feature release).
# The commit message MUST contain a properly formatted release
# log, and the commit must be signed.
#
# The release automation will: build and test the packages for the
# supported platforms, publish the packages on PyPI, merge the PR
# to the target branch, create a Git tag pointing to the commit.

from __future__ import annotations

import typing

__version__: typing.Final = '0.32.0.dev0'


================================================
FILE: asyncpg/cluster.py
================================================
# Copyright (C) 2016-present the asyncpg authors and contributors
# <see AUTHORS file>
#
# This module is part of asyncpg and is released under
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0


import asyncio
import os
import os.path
import platform
import random
import re
import shutil
import socket
import string
import subprocess
import sys
import tempfile
import textwrap
import time

import asyncpg
from asyncpg import serverversion


_system = platform.uname().system

if _system == 'Windows':
    def platform_exe(name):
        if name.endswith('.exe'):
            return name
        return name + '.exe'
else:
    def platform_exe(name):
        return name


def find_available_port():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        sock.bind(('127.0.0.1', 0))
        return sock.getsockname()[1]
    except Exception:
        return None
    finally:
        sock.close()


def _world_readable_mkdtemp(suffix=None, prefix=None, dir=None):
    name = "".join(random.choices(string.ascii_lowercase, k=8))
    if dir is None:
        dir = tempfile.gettempdir()
    if prefix is None:
        prefix = tempfile.gettempprefix()
    if suffix is None:
        suffix = ""
    fn = os.path.join(dir, prefix + name + suffix)
    os.mkdir(fn, 0o755)
    return fn


def _mkdtemp(suffix=None, prefix=None, dir=None):
    if _system == 'Windows' and os.environ.get("GITHUB_ACTIONS"):
        # Due to mitigations introduced in python/cpython#118486
        # when Python runs in a session created via an SSH connection
        # tempfile.mkdtemp creates directories that are not accessible.
        return _world_readable_mkdtemp(suffix, prefix, dir)
    else:
        return tempfile.mkdtemp(suffix, prefix, dir)


class ClusterError(Exception):
    pass


class Cluster:
    def __init__(self, data_dir, *, pg_config_path=None):
        self._data_dir = data_dir
        self._pg_config_path = pg_config_path
        self._pg_bin_dir = (
            os.environ.get('PGINSTALLATION')
            or os.environ.get('PGBIN')
        )
        self._pg_ctl = None
        self._daemon_pid = None
        self._daemon_process = None
        self._connection_addr = None
        self._connection_spec_override = None

    def get_pg_version(self):
        return self._pg_version

    def is_managed(self):
        return True

    def get_data_dir(self):
        return self._data_dir

    def get_status(self):
        if self._pg_ctl is None:
            self._init_env()

        process = subprocess.run(
            [self._pg_ctl, 'status', '-D', self._data_dir],
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.stdout, process.stderr

        if (process.returncode == 4 or not os.path.exists(self._data_dir) or
                not os.listdir(self._data_dir)):
            return 'not-initialized'
        elif process.returncode == 3:
            return 'stopped'
        elif process.returncode == 0:
            r = re.match(r'.*PID\s?:\s+(\d+).*', stdout.decode())
            if not r:
                raise ClusterError(
                    'could not parse pg_ctl status output: {}'.format(
                        stdout.decode()))
            self._daemon_pid = int(r.group(1))
            return self._test_connection(timeout=0)
        else:
            raise ClusterError(
                'pg_ctl status exited with status {:d}: {}'.format(
                    process.returncode, stderr))

    async def connect(self, loop=None, **kwargs):
        conn_info = self.get_connection_spec()
        conn_info.update(kwargs)
        return await asyncpg.connect(loop=loop, **conn_info)

    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))

        settings = dict(settings)
        if 'encoding' not in settings:
            settings['encoding'] = 'UTF-8'

        if settings:
            settings_args = ['--{}={}'.format(k, v)
                             for k, v in settings.items()]
            extra_args = ['-o'] + [' '.join(settings_args)]
        else:
            extra_args = []

        os.makedirs(self._data_dir, exist_ok=True)
        process = subprocess.run(
            [self._pg_ctl, 'init', '-D', self._data_dir] + extra_args,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            cwd=self._data_dir,
        )

        output = process.stdout

        if process.returncode != 0:
            raise ClusterError(
                'pg_ctl init exited with status {:d}:\n{}'.format(
                    process.returncode, output.decode()))

        return output.decode()

    def start(self, wait=60, *, server_settings={}, **opts):
        """Start the cluster."""
        status = self.get_status()
        if status == 'running':
            return
        elif status == 'not-initialized':
            raise ClusterError(
                'cluster in {!r} has not been initialized'.format(
                    self._data_dir))

        port = opts.pop('port', None)
        if port == 'dynamic':
            port = find_available_port()

        extra_args = ['--{}={}'.format(k, v) for k, v in opts.items()]
        extra_args.append('--port={}'.format(port))

        sockdir = server_settings.get('unix_socket_directories')
        if sockdir is None:
            sockdir = server_settings.get('unix_socket_directory')
        if sockdir is None and _system != 'Windows':
            sockdir = tempfile.gettempdir()

        ssl_key = server_settings.get('ssl_key_file')
        if ssl_key:
            # Make sure server certificate key file has correct permissions.
            keyfile = os.path.join(self._data_dir, 'srvkey.pem')
            shutil.copy(ssl_key, keyfile)
            os.chmod(keyfile, 0o600)
            server_settings = server_settings.copy()
            server_settings['ssl_key_file'] = keyfile

        if sockdir is not None:
            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)])

        if _system == 'Windows':
            # On Windows we have to use pg_ctl as direct execution
            # of postgres daemon under an Administrative account
            # is not permitted and there is no easy way to drop
            # privileges.
            if os.getenv('ASYNCPG_DEBUG_SERVER'):
                stdout = sys.stdout
                print(
                    'asyncpg.cluster: Running',
                    ' '.join([
                        self._pg_ctl, 'start', '-D', self._data_dir,
                        '-o', ' '.join(extra_args)
                    ]),
                    file=sys.stderr,
                )
            else:
                stdout = subprocess.DEVNULL

            process = subprocess.run(
                [self._pg_ctl, 'start', '-D', self._data_dir,
                 '-o', ' '.join(extra_args)],
                stdout=stdout,
                stderr=subprocess.STDOUT,
                cwd=self._data_dir,
            )

            if process.returncode != 0:
                if process.stderr:
                    stderr = ':\n{}'.format(process.stderr.decode())
                else:
                    stderr = ''
                raise ClusterError(
                    'pg_ctl start exited with status {:d}{}'.format(
                        process.returncode, stderr))
        else:
            if os.getenv('ASYNCPG_DEBUG_SERVER'):
                stdout = sys.stdout
            else:
                stdout = subprocess.DEVNULL

            self._daemon_process = \
                subprocess.Popen(
                    [self._postgres, '-D', self._data_dir, *extra_args],
                    stdout=stdout,
                    stderr=subprocess.STDOUT,
                    cwd=self._data_dir,
                )

            self._daemon_pid = self._daemon_process.pid

        self._test_connection(timeout=wait)

    def reload(self):
        """Reload server configuration."""
        status = self.get_status()
        if status != 'running':
            raise ClusterError('cannot reload: cluster is not running')

        process = subprocess.run(
            [self._pg_ctl, 'reload', '-D', self._data_dir],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=self._data_dir,
        )

        stderr = process.stderr

        if process.returncode != 0:
            raise ClusterError(
                'pg_ctl stop exited with status {:d}: {}'.format(
                    process.returncode, stderr.decode()))

    def stop(self, wait=60):
        process = subprocess.run(
            [self._pg_ctl, 'stop', '-D', self._data_dir, '-t', str(wait),
             '-m', 'fast'],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=self._data_dir,
        )

        stderr = process.stderr

        if process.returncode != 0:
            raise ClusterError(
                'pg_ctl stop exited with status {:d}: {}'.format(
                    process.returncode, stderr.decode()))

        if (self._daemon_process is not None and
                self._daemon_process.returncode is None):
            self._daemon_process.kill()

    def destroy(self):
        status = self.get_status()
        if status == 'stopped' or status == 'not-initialized':
            shutil.rmtree(self._data_dir)
        else:
            raise ClusterError('cannot destroy {} cluster'.format(status))

    def _get_connection_spec(self):
        if self._connection_addr is None:
            self._connection_addr = self._connection_addr_from_pidfile()

        if self._connection_addr is not None:
            if self._connection_spec_override:
                args = self._connection_addr.copy()
                args.update(self._connection_spec_override)
                return args
            else:
                return self._connection_addr

    def get_connection_spec(self):
        status = self.get_status()
        if status != 'running':
            raise ClusterError('cluster is not running')

        return self._get_connection_spec()

    def override_connection_spec(self, **kwargs):
        self._connection_spec_override = kwargs

    def reset_wal(self, *, oid=None, xid=None):
        status = self.get_status()
        if status == 'not-initialized':
            raise ClusterError(
                'cannot modify WAL status: cluster is not initialized')

        if status == 'running':
            raise ClusterError(
                'cannot modify WAL status: cluster is running')

        opts = []
        if oid is not None:
            opts.extend(['-o', str(oid)])
        if xid is not None:
            opts.extend(['-x', str(xid)])
        if not opts:
            return

        opts.append(self._data_dir)

        try:
            reset_wal = self._find_pg_binary('pg_resetwal')
        except ClusterError:
            reset_wal = self._find_pg_binary('pg_resetxlog')

        process = subprocess.run(
            [reset_wal] + opts,
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        stderr = process.stderr

        if process.returncode != 0:
            raise ClusterError(
                'pg_resetwal exited with status {:d}: {}'.format(
                    process.returncode, stderr.decode()))

    def reset_hba(self):
        """Remove all records from pg_hba.conf."""
        status = self.get_status()
        if status == 'not-initialized':
            raise ClusterError(
                'cannot modify HBA records: cluster is not initialized')

        pg_hba = os.path.join(self._data_dir, 'pg_hba.conf')

        try:
            with open(pg_hba, 'w'):
                pass
        except IOError as e:
            raise ClusterError(
                'cannot modify HBA records: {}'.format(e)) from e

    def add_hba_entry(self, *, type='host', database, user, address=None,
                      auth_method, auth_options=None):
        """Add a record to pg_hba.conf."""
        status = self.get_status()
        if status == 'not-initialized':
            raise ClusterError(
                'cannot modify HBA records: cluster is not initialized')

        if type not in {'local', 'host', 'hostssl', 'hostnossl'}:
            raise ValueError('invalid HBA record type: {!r}'.format(type))

        pg_hba = os.path.join(self._data_dir, 'pg_hba.conf')

        record = '{} {} {}'.format(type, database, user)

        if type != 'local':
            if address is None:
                raise ValueError(
                    '{!r} entry requires a valid address'.format(type))
            else:
                record += ' {}'.format(address)

        record += ' {}'.format(auth_method)

        if auth_options is not None:
            record += ' ' + ' '.join(
                '{}={}'.format(k, v) for k, v in auth_options)

        try:
            with open(pg_hba, 'a') as f:
                print(record, file=f)
        except IOError as e:
            raise ClusterError(
                'cannot modify HBA records: {}'.format(e)) from e

    def trust_local_connections(self):
        self.reset_hba()

        if _system != 'Windows':
            self.add_hba_entry(type='local', database='all',
                               user='all', auth_method='trust')
        self.add_hba_entry(type='host', address='127.0.0.1/32',
                           database='all', user='all',
                           auth_method='trust')
        self.add_hba_entry(type='host', address='::1/128',
                           database='all', user='all',
                           auth_method='trust')
        status = self.get_status()
        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):
        if not self._pg_bin_dir:
            pg_config = self._find_pg_config(self._pg_config_path)
            pg_config_data = self._run_pg_config(pg_config)

            self._pg_bin_dir = pg_config_data.get('bindir')
            if not self._pg_bin_dir:
                raise ClusterError(
                    'pg_config output did not provide the BINDIR value')

        self._pg_ctl = self._find_pg_binary('pg_ctl')
        self._postgres = self._find_pg_binary('postgres')
        self._pg_version = self._get_pg_version()

    def _connection_addr_from_pidfile(self):
        pidfile = os.path.join(self._data_dir, 'postmaster.pid')

        try:
            with open(pidfile, 'rt') as f:
                piddata = f.read()
        except FileNotFoundError:
            return None

        lines = piddata.splitlines()

        if len(lines) < 6:
            # A complete postgres pidfile is at least 6 lines
            return None

        pmpid = int(lines[0])
        if self._daemon_pid and pmpid != self._daemon_pid:
            # This might be an old pidfile left from previous postgres
            # daemon run.
            return None

        portnum = lines[3]
        sockdir = lines[4]
        hostaddr = lines[5]

        if sockdir:
            if sockdir[0] != '/':
                # Relative sockdir
                sockdir = os.path.normpath(
                    os.path.join(self._data_dir, sockdir))
            host_str = sockdir
        else:
            host_str = hostaddr

        if host_str == '*':
            host_str = 'localhost'
        elif host_str == '0.0.0.0':
            host_str = '127.0.0.1'
        elif host_str == '::':
            host_str = '::1'

        return {
            'host': host_str,
            'port': portnum
        }

    def _test_connection(self, timeout=60):
        self._connection_addr = None

        loop = asyncio.new_event_loop()

        try:
            for i in range(timeout):
                if self._connection_addr is None:
                    conn_spec = self._get_connection_spec()
                    if conn_spec is None:
                        time.sleep(1)
                        continue

                try:
                    con = loop.run_until_complete(
                        asyncpg.connect(database='postgres',
                                        user='postgres',
                                        timeout=5, loop=loop,
                                        **self._connection_addr))
                except (OSError, asyncio.TimeoutError,
                        asyncpg.CannotConnectNowError,
                        asyncpg.PostgresConnectionError):
                    time.sleep(1)
                    continue
                except asyncpg.PostgresError:
                    # Any other error other than ServerNotReadyError or
                    # ConnectionError is interpreted to indicate the server is
                    # up.
                    break
                else:
                    loop.run_until_complete(con.close())
                    break
        finally:
            loop.close()

        return 'running'

    def _run_pg_config(self, pg_config_path):
        process = subprocess.run(
            pg_config_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.stdout, process.stderr

        if process.returncode != 0:
            raise ClusterError('pg_config exited with status {:d}: {}'.format(
                process.returncode, stderr))
        else:
            config = {}

            for line in stdout.splitlines():
                k, eq, v = line.decode('utf-8').partition('=')
                if eq:
                    config[k.strip().lower()] = v.strip()

            return config

    def _find_pg_config(self, pg_config_path):
        if pg_config_path is None:
            pg_install = (
                os.environ.get('PGINSTALLATION')
                or os.environ.get('PGBIN')
            )
            if pg_install:
                pg_config_path = platform_exe(
                    os.path.join(pg_install, 'pg_config'))
            else:
                pathenv = os.environ.get('PATH').split(os.pathsep)
                for path in pathenv:
                    pg_config_path = platform_exe(
                        os.path.join(path, 'pg_config'))
                    if os.path.exists(pg_config_path):
                        break
                else:
                    pg_config_path = None

        if not pg_config_path:
            raise ClusterError('could not find pg_config executable')

        if not os.path.isfile(pg_config_path):
            raise ClusterError('{!r} is not an executable'.format(
                pg_config_path))

        return pg_config_path

    def _find_pg_binary(self, binary):
        bpath = platform_exe(os.path.join(self._pg_bin_dir, binary))

        if not os.path.isfile(bpath):
            raise ClusterError(
                'could not find {} executable: '.format(binary) +
                '{!r} does not exist or is not a file'.format(bpath))

        return bpath

    def _get_pg_version(self):
        process = subprocess.run(
            [self._postgres, '--version'],
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.stdout, process.stderr

        if process.returncode != 0:
            raise ClusterError(
                'postgres --version exited with status {:d}: {}'.format(
                    process.returncode, stderr))

        version_string = stdout.decode('utf-8').strip(' \n')
        prefix = 'postgres (PostgreSQL) '
        if not version_string.startswith(prefix):
            raise ClusterError(
                'could not determine server version from {!r}'.format(
                    version_string))
        version_string = version_string[len(prefix):]

        return serverversion.split_server_version_string(version_string)


class TempCluster(Cluster):
    def __init__(self, *,
                 data_dir_suffix=None, data_dir_prefix=None,
                 data_dir_parent=None, pg_config_path=None):
        self._data_dir = _mkdtemp(suffix=data_dir_suffix,
                                  prefix=data_dir_prefix,
                                  dir=data_dir_parent)
        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()))

        if self._pg_version < (12, 0):
            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)))
        else:
            f = open(os.path.join(self._data_dir, 'standby.signal'), 'w')
            f.close()

        return output.decode()

    def start(self, wait=60, *, server_settings={}, **opts):
        if self._pg_version >= (12, 0):
            server_settings = server_settings.copy()
            server_settings['primary_conninfo'] = (
                '"host={host} port={port} user={user}"'.format(
                    host=self._master['host'],
                    port=self._master['port'],
                    user=self._repl_user,
                )
            )

        super().start(wait=wait, server_settings=server_settings, **opts)


class RunningCluster(Cluster):
    def __init__(self, **kwargs):
        self.conn_spec = kwargs

    def is_managed(self):
        return False

    def get_connection_spec(self):
        return dict(self.conn_spec)

    def get_status(self):
        return 'running'

    def init(self, **settings):
        pass

    def start(self, wait=60, **settings):
        pass

    def stop(self, wait=60):
        pass

    def destroy(self):
        pass

    def reset_hba(self):
        raise ClusterError('cannot modify HBA records of unmanaged cluster')

    def add_hba_entry(self, *, type='host', database, user, address=None,
                      auth_method, auth_options=None):
        raise ClusterError('cannot modify HBA records of unmanaged cluster')


================================================
FILE: asyncpg/compat.py
================================================
# Copyright (C) 2016-present the asyncpg authors and contributors
# <see AUTHORS file>
#
# This module is part of asyncpg and is released under
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0

from __future__ import annotations

import enum
import pathlib
import platform
import typing
import sys

if typing.TYPE_CHECKING:
    import asyncio

SYSTEM: typing.Final = platform.uname().system


if sys.platform == 'win32':
    import ctypes.wintypes

    CSIDL_APPDATA: typing.Final = 0x001a

    def get_pg_home_directory() -> pathlib.Path | None:
        # We cannot simply use expanduser() as that returns the user's
        # home directory, whereas Postgres stores its config in
        # %AppData% on Windows.
        buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH)
        r = ctypes.windll.shell32.SHGetFolderPathW(0, CSIDL_APPDATA, 0, 0, buf)
        if r:
            return None
        else:
            return pathlib.Path(buf.value) / 'postgresql'

else:
    def get_pg_home_directory() -> pathlib.Path | None:
        try:
            return pathlib.Path.home()
        except (RuntimeError, KeyError):
            return None


async def wait_closed(stream: asyncio.StreamWriter) -> None:
    # Not all asyncio versions have StreamWriter.wait_closed().
    if hasattr(stream, 'wait_closed'):
        try:
            await stream.wait_closed()
        except ConnectionResetError:
            # On Windows wait_closed() sometimes propagates
            # ConnectionResetError which is totally unnecessary.
            pass


if sys.version_info < (3, 12):
    def markcoroutinefunction(c):  # type: ignore
        pass
else:
    from inspect import markcoroutinefunction  # noqa: F401


if sys.version_info < (3, 12):
    from ._asyncio_compat import wait_for as wait_for  # noqa: F401
else:
    from asyncio import wait_for as wait_for  # noqa: F401


if sys.version_info < (3, 11):
    from ._asyncio_compat import timeout_ctx as timeout  # noqa: F401
else:
    from asyncio import timeout as timeout  # noqa: F401

if sys.version_info < (3, 9):
    from typing import (  # noqa: F401
        Awaitable as Awaitable,
    )
else:
    from collections.abc import (  # noqa: F401
        Awaitable as Awaitable,
    )

if sys.version_info < (3, 11):
    class StrEnum(str, enum.Enum):
        __str__ = str.__str__
        __repr__ = enum.Enum.__repr__
else:
    from enum import StrEnum as StrEnum  # noqa: F401


================================================
FILE: asyncpg/connect_utils.py
================================================
# Copyright (C) 2016-present the asyncpg authors and contributors
# <see AUTHORS file>
#
# This module is part of asyncpg and is released under
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0

from __future__ import annotations

import asyncio
import configparser
import collections
from collections.abc import Callable
import enum
import functools
import getpass
import os
import pathlib
import platform
import random
import re
import socket
import ssl as ssl_module
import stat
import struct
import sys
import typing
import urllib.parse
import warnings
import inspect

from . import compat
from . import exceptions
from . import protocol


class SSLMode(enum.IntEnum):
    disable = 0
    allow = 1
    prefer = 2
    require = 3
    verify_ca = 4
    verify_full = 5

    @classmethod
    def parse(cls, sslmode):
        if isinstance(sslmode, cls):
            return sslmode
        return getattr(cls, sslmode.replace('-', '_'))


class SSLNegotiation(compat.StrEnum):
    postgres = "postgres"
    direct = "direct"


_ConnectionParameters = collections.namedtuple(
    'ConnectionParameters',
    [
        'user',
        'password',
        'database',
        'ssl',
        'sslmode',
        'ssl_negotiation',
        'server_settings',
        'target_session_attrs',
        'krbsrvname',
        'gsslib',
    ])


_ClientConfiguration = collections.namedtuple(
    'ConnectionConfiguration',
    [
        'command_timeout',
        'statement_cache_size',
        'max_cached_statement_lifetime',
        'max_cacheable_statement_size',
    ])


_system = platform.uname().system


if _system == 'Windows':
    PGPASSFILE = 'pgpass.conf'
else:
    PGPASSFILE = '.pgpass'


PG_SERVICEFILE = '.pg_service.conf'


def _read_password_file(passfile: pathlib.Path) \
        -> typing.List[typing.Tuple[str, ...]]:

    passtab = []

    try:
        if not passfile.exists():
            return []

        if not passfile.is_file():
            warnings.warn(
                'password file {!r} is not a plain file'.format(passfile))

            return []

        if _system != 'Windows':
            if passfile.stat().st_mode & (stat.S_IRWXG | stat.S_IRWXO):
                warnings.warn(
                    'password file {!r} has group or world access; '
                    'permissions should be u=rw (0600) or less'.format(
                        passfile))

                return []

        with passfile.open('rt') as f:
            for line in f:
                line = line.strip()
                if not line or line.startswith('#'):
                    # Skip empty lines and comments.
                    continue
                # Backslash escapes both itself and the colon,
                # which is a record separator.
                line = line.replace(R'\\', '\n')
                passtab.append(tuple(
                    p.replace('\n', R'\\')
                    for p in re.split(r'(?<!\\):', line, maxsplit=4)
                ))
    except IOError:
        pass

    return passtab


def _read_password_from_pgpass(
        *, passfile: typing.Optional[pathlib.Path],
        hosts: typing.List[str],
        ports: typing.List[int],
        database: str,
        user: str):
    """Parse the pgpass file and return the matching password.

    :return:
        Password string, if found, ``None`` otherwise.
    """

    passtab = _read_password_file(passfile)
    if not passtab:
        return None

    for host, port in zip(hosts, ports):
        if host.startswith('/'):
            # Unix sockets get normalized into 'localhost'
            host = 'localhost'

        for phost, pport, pdatabase, puser, ppassword in passtab:
            if phost != '*' and phost != host:
                continue
            if pport != '*' and pport != str(port):
                continue
            if pdatabase != '*' and pdatabase != database:
                continue
            if puser != '*' and puser != user:
                continue

            # Found a match.
            return ppassword

    return None


def _validate_port_spec(hosts, port):
    if isinstance(port, list) and len(port) > 1:
        # If there is a list of ports, its length must
        # match that of the host list.
        if len(port) != len(hosts):
            raise exceptions.ClientConfigurationError(
                'could not match {} port numbers to {} hosts'.format(
                    len(port), len(hosts)))
    elif isinstance(port, list) and len(port) == 1:
        port = [port[0] for _ in range(len(hosts))]
    else:
        port = [port for _ in range(len(hosts))]

    return port


def _parse_hostlist(hostlist, port, *, unquote=False):
    if ',' in hostlist:
        # A comma-separated list of host addresses.
        hostspecs = hostlist.split(',')
    else:
        hostspecs = [hostlist]

    hosts = []
    hostlist_ports = []

    if not port:
        portspec = os.environ.get('PGPORT')
        if portspec:
            if ',' in portspec:
                default_port = [int(p) for p in portspec.split(',')]
            else:
                default_port = int(portspec)
        else:
            default_port = 5432

        default_port = _validate_port_spec(hostspecs, default_port)

    else:
        port = _validate_port_spec(hostspecs, port)

    for i, hostspec in enumerate(hostspecs):
        if hostspec[0] == '/':
            # Unix socket
            addr = hostspec
            hostspec_port = ''
        elif hostspec[0] == '[':
            # IPv6 address
            m = re.match(r'(?:\[([^\]]+)\])(?::([0-9]+))?', hostspec)
            if m:
                addr = m.group(1)
                hostspec_port = m.group(2)
            else:
                raise exceptions.ClientConfigurationError(
                    'invalid IPv6 address in the connection URI: {!r}'.format(
                        hostspec
                    )
                )
        else:
            # IPv4 address
            addr, _, hostspec_port = hostspec.partition(':')

        if unquote:
            addr = urllib.parse.unquote(addr)

        hosts.append(addr)
        if not port:
            if hostspec_port:
                if unquote:
                    hostspec_port = urllib.parse.unquote(hostspec_port)
                hostlist_ports.append(int(hostspec_port))
            else:
                hostlist_ports.append(default_port[i])

    if not port:
        port = hostlist_ports

    return hosts, port


def _parse_tls_version(tls_version):
    if tls_version.startswith('SSL'):
        raise exceptions.ClientConfigurationError(
            f"Unsupported TLS version: {tls_version}"
        )
    try:
        return ssl_module.TLSVersion[tls_version.replace('.', '_')]
    except KeyError:
        raise exceptions.ClientConfigurationError(
            f"No such TLS version: {tls_version}"
        )


def _dot_postgresql_path(filename) -> typing.Optional[pathlib.Path]:
    try:
        homedir = pathlib.Path.home()
    except (RuntimeError, KeyError):
        return None

    return (homedir / '.postgresql' / filename).resolve()


def _parse_connect_dsn_and_args(*, dsn, host, port, user,
                                password, passfile, database, ssl,
                                service, servicefile,
                                direct_tls, server_settings,
                                target_session_attrs, krbsrvname, gsslib):
    # `auth_hosts` is the version of host information for the purposes
    # of reading the pgpass file.
    auth_hosts = None
    sslcert = sslkey = sslrootcert = sslcrl = sslpassword = None
    ssl_min_protocol_version = ssl_max_protocol_version = None
    sslnegotiation = None

    if dsn:
        parsed = urllib.parse.urlparse(dsn)

        query = None
        if parsed.query:
            query = urllib.parse.parse_qs(parsed.query, strict_parsing=True)
            for key, val in query.items():
                if isinstance(val, list):
                    query[key] = val[-1]

            if 'service' in query:
                val = query.pop('service')
                if not service and val:
                    service = val

        connection_service_file = servicefile

        if connection_service_file is None:
            connection_service_file = os.getenv('PGSERVICEFILE')

        if connection_service_file is None:
            homedir = compat.get_pg_home_directory()
            if homedir:
                connection_service_file = homedir / PG_SERVICEFILE
            else:
                connection_service_file = None
        else:
            connection_service_file = pathlib.Path(connection_service_file)

        if parsed.scheme not in {'postgresql', 'postgres'}:
            raise exceptions.ClientConfigurationError(
                'invalid DSN: scheme is expected to be either '
                '"postgresql" or "postgres", got {!r}'.format(parsed.scheme))

        if parsed.netloc:
            if '@' in parsed.netloc:
                dsn_auth, _, dsn_hostspec = parsed.netloc.partition('@')
            else:
                dsn_hostspec = parsed.netloc
                dsn_auth = ''
        else:
            dsn_auth = dsn_hostspec = ''

        if dsn_auth:
            dsn_user, _, dsn_password = dsn_auth.partition(':')
        else:
            dsn_user = dsn_password = ''

        if not host and dsn_hostspec:
            host, port = _parse_hostlist(dsn_hostspec, port, unquote=True)

        if parsed.path and database is None:
            dsn_database = parsed.path
            if dsn_database.startswith('/'):
                dsn_database = dsn_database[1:]
            database = urllib.parse.unquote(dsn_database)

        if user is None and dsn_user:
            user = urllib.parse.unquote(dsn_user)

        if password is None and dsn_password:
            password = urllib.parse.unquote(dsn_password)

        if query:

            if 'port' in query:
                val = query.pop('port')
                if not port and val:
                    port = [int(p) for p in val.split(',')]

            if 'host' in query:
                val = query.pop('host')
                if not host and val:
                    host, port = _parse_hostlist(val, port)

            if 'dbname' in query:
                val = query.pop('dbname')
                if database is None:
                    database = val

            if 'database' in query:
                val = query.pop('database')
                if database is None:
                    database = val

            if 'user' in query:
                val = query.pop('user')
                if user is None:
                    user = val

            if 'password' in query:
                val = query.pop('password')
                if password is None:
                    password = val

            if 'passfile' in query:
                val = query.pop('passfile')
                if passfile is None:
                    passfile = val

            if 'sslmode' in query:
                val = query.pop('sslmode')
                if ssl is None:
                    ssl = val

            if 'sslcert' in query:
                sslcert = query.pop('sslcert')

            if 'sslkey' in query:
                sslkey = query.pop('sslkey')

            if 'sslrootcert' in query:
                sslrootcert = query.pop('sslrootcert')

            if 'sslnegotiation' in query:
                sslnegotiation = query.pop('sslnegotiation')

            if 'sslcrl' in query:
                sslcrl = query.pop('sslcrl')

            if 'sslpassword' in query:
                sslpassword = query.pop('sslpassword')

            if 'ssl_min_protocol_version' in query:
                ssl_min_protocol_version = query.pop(
                    'ssl_min_protocol_version'
                )

            if 'ssl_max_protocol_version' in query:
                ssl_max_protocol_version = query.pop(
                    'ssl_max_protocol_version'
                )

            if 'target_session_attrs' in query:
                dsn_target_session_attrs = query.pop(
                    'target_session_attrs'
                )
                if target_session_attrs is None:
                    target_session_attrs = dsn_target_session_attrs

            if 'krbsrvname' in query:
                val = query.pop('krbsrvname')
                if krbsrvname is None:
                    krbsrvname = val

            if 'gsslib' in query:
                val = query.pop('gsslib')
                if gsslib is None:
                    gsslib = val

            if 'service' in query:
                val = query.pop('service')
                if service is None:
                    service = val

            if query:
                if server_settings is None:
                    server_settings = query
                else:
                    server_settings = {**query, **server_settings}

        if connection_service_file is not None and service is not None:
            pg_service = configparser.ConfigParser()
            pg_service.read(connection_service_file)
            if service in pg_service.sections():
                service_params = pg_service[service]
                if 'port' in service_params:
                    val = service_params.pop('port')
                    if not port and val:
                        port = [int(p) for p in val.split(',')]

                if 'host' in service_params:
                    val = service_params.pop('host')
                    if not host and val:
                        host, port = _parse_hostlist(val, port)

                if 'dbname' in service_params:
                    val = service_params.pop('dbname')
                    if database is None:
                        database = val

                if 'database' in service_params:
                    val = service_params.pop('database')
                    if database is None:
                        database = val

                if 'user' in service_params:
                    val = service_params.pop('user')
                    if user is None:
                        user = val

                if 'password' in service_params:
                    val = service_params.pop('password')
                    if password is None:
                        password = val

                if 'passfile' in service_params:
                    val = service_params.pop('passfile')
                    if passfile is None:
                        passfile = val

                if 'sslmode' in service_params:
                    val = service_params.pop('sslmode')
                    if ssl is None:
                        ssl = val

                if 'sslcert' in service_params:
                    val = service_params.pop('sslcert')
                    if sslcert is None:
                        sslcert = val

                if 'sslkey' in service_params:
                    val = service_params.pop('sslkey')
                    if sslkey is None:
                        sslkey = val

                if 'sslrootcert' in service_params:
                    val = service_params.pop('sslrootcert')
                    if sslrootcert is None:
                        sslrootcert = val

                if 'sslnegotiation' in service_params:
                    val = service_params.pop('sslnegotiation')
                    if sslnegotiation is None:
                        sslnegotiation = val

                if 'sslcrl' in service_params:
                    val = service_params.pop('sslcrl')
                    if sslcrl is None:
                        sslcrl = val

                if 'sslpassword' in service_params:
                    val = service_params.pop('sslpassword')
                    if sslpassword is None:
                        sslpassword = val

                if 'ssl_min_protocol_version' in service_params:
                    val = service_params.pop(
                        'ssl_min_protocol_version'
                    )
                    if ssl_min_protocol_version is None:
                        ssl_min_protocol_version = val

                if 'ssl_max_protocol_version' in service_params:
                    val = service_params.pop(
                        'ssl_max_protocol_version'
                    )
                    if ssl_max_protocol_version is None:
                        ssl_max_protocol_version = val

                if 'target_session_attrs' in service_params:
                    dsn_target_session_attrs = service_params.pop(
                        'target_session_attrs'
                    )
                    if target_session_attrs is None:
                        target_session_attrs = dsn_target_session_attrs

                if 'krbsrvname' in service_params:
                    val = service_params.pop('krbsrvname')
                    if krbsrvname is None:
                        krbsrvname = val

                if 'gsslib' in service_params:
                    val = service_params.pop('gsslib')
                    if gsslib is None:
                        gsslib = val
    if not service:
        service = os.environ.get('PGSERVICE')
    if not host:
        hostspec = os.environ.get('PGHOST')
        if hostspec:
            host, port = _parse_hostlist(hostspec, port)

    if not host:
        auth_hosts = ['localhost']

        if _system == 'Windows':
            host = ['localhost']
        else:
            host = ['/run/postgresql', '/var/run/postgresql',
                    '/tmp', '/private/tmp', 'localhost']

    if not isinstance(host, (list, tuple)):
        host = [host]

    if auth_hosts is None:
        auth_hosts = host

    if not port:
        portspec = os.environ.get('PGPORT')
        if portspec:
            if ',' in portspec:
                port = [int(p) for p in portspec.split(',')]
            else:
                port = int(portspec)
        else:
            port = 5432

    elif isinstance(port, (list, tuple)):
        port = [int(p) for p in port]

    else:
        port = int(port)

    port = _validate_port_spec(host, port)

    if user is None:
        user = os.getenv('PGUSER')
        if not user:
            user = getpass.getuser()

    if password is None:
        password = os.getenv('PGPASSWORD')

    if database is None:
        database = os.getenv('PGDATABASE')

    if database is None:
        database = user

    if user is None:
        raise exceptions.ClientConfigurationError(
            'could not determine user name to connect with')

    if database is None:
        raise exceptions.ClientConfigurationError(
            'could not determine database name to connect to')

    if password is None:
        if passfile is None:
            passfile = os.getenv('PGPASSFILE')

        if passfile is None:
            homedir = compat.get_pg_home_directory()
            if homedir:
                passfile = homedir / PGPASSFILE
            else:
                passfile = None
        else:
            passfile = pathlib.Path(passfile)

        if passfile is not None:
            password = _read_password_from_pgpass(
                hosts=auth_hosts, ports=port,
                database=database, user=user,
                passfile=passfile)

    addrs = []
    have_tcp_addrs = False
    for h, p in zip(host, port):
        if h.startswith('/'):
            # UNIX socket name
            if '.s.PGSQL.' not in h:
                h = os.path.join(h, '.s.PGSQL.{}'.format(p))
            addrs.append(h)
        else:
            # TCP host/port
            addrs.append((h, p))
            have_tcp_addrs = True

    if not addrs:
        raise exceptions.InternalClientError(
            'could not determine the database address to connect to')

    if ssl is None:
        ssl = os.getenv('PGSSLMODE')

    if ssl is None and have_tcp_addrs:
        ssl = 'prefer'

    if direct_tls is not None:
        sslneg = (
            SSLNegotiation.direct if direct_tls else SSLNegotiation.postgres
        )
    else:
        if sslnegotiation is None:
            sslnegotiation = os.environ.get("PGSSLNEGOTIATION")

        if sslnegotiation is not None:
            try:
                sslneg = SSLNegotiation(sslnegotiation)
            except ValueError:
                modes = ', '.join(
                    m.name.replace('_', '-')
                    for m in SSLNegotiation
                )
                raise exceptions.ClientConfigurationError(
                    f'`sslnegotiation` parameter must be one of: {modes}'
                ) from None
        else:
            sslneg = SSLNegotiation.postgres

    if isinstance(ssl, (str, SSLMode)):
        try:
            sslmode = SSLMode.parse(ssl)
        except AttributeError:
            modes = ', '.join(m.name.replace('_', '-') for m in SSLMode)
            raise exceptions.ClientConfigurationError(
                '`sslmode` parameter must be one of: {}'.format(modes)
            ) from None

        # docs at https://www.postgresql.org/docs/10/static/libpq-connect.html
        if sslmode < SSLMode.allow:
            ssl = False
        else:
            ssl = ssl_module.SSLContext(ssl_module.PROTOCOL_TLS_CLIENT)
            ssl.check_hostname = sslmode >= SSLMode.verify_full
            if sslmode < SSLMode.require:
                ssl.verify_mode = ssl_module.CERT_NONE
            else:
                if sslrootcert is None:
                    sslrootcert = os.getenv('PGSSLROOTCERT')
                if sslrootcert:
                    ssl.load_verify_locations(cafile=sslrootcert)
                    ssl.verify_mode = ssl_module.CERT_REQUIRED
                else:
                    try:
                        sslrootcert = _dot_postgresql_path('root.crt')
                        if sslrootcert is not None:
                            ssl.load_verify_locations(cafile=sslrootcert)
                        else:
                            raise exceptions.ClientConfigurationError(
                                'cannot determine location of user '
                                'PostgreSQL configuration directory'
                            )
                    except (
                        exceptions.ClientConfigurationError,
                        FileNotFoundError,
                        NotADirectoryError,
                    ):
                        if sslmode > SSLMode.require:
                            if sslrootcert is None:
                                sslrootcert = '~/.postgresql/root.crt'
                                detail = (
                                    'Could not determine location of user '
                                    'home directory (HOME is either unset, '
                                    'inaccessible, or does not point to a '
                                    'valid directory)'
                                )
                            else:
                                detail = None
                            raise exceptions.ClientConfigurationError(
                                f'root certificate file "{sslrootcert}" does '
                                f'not exist or cannot be accessed',
                                hint='Provide the certificate file directly '
                                     f'or make sure "{sslrootcert}" '
                                     'exists and is readable.',
                                detail=detail,
                            )
                        elif sslmode == SSLMode.require:
                            ssl.verify_mode = ssl_module.CERT_NONE
                        else:
                            assert False, 'unreachable'
                    else:
                        ssl.verify_mode = ssl_module.CERT_REQUIRED

                if sslcrl is None:
                    sslcrl = os.getenv('PGSSLCRL')
                if sslcrl:
                    ssl.load_verify_locations(cafile=sslcrl)
                    ssl.verify_flags |= ssl_module.VERIFY_CRL_CHECK_CHAIN
                else:
                    sslcrl = _dot_postgresql_path('root.crl')
                    if sslcrl is not None:
                        try:
                            ssl.load_verify_locations(cafile=sslcrl)
                        except (
                            FileNotFoundError,
                            NotADirectoryError,
                        ):
                            pass
                        else:
                            ssl.verify_flags |= \
                                ssl_module.VERIFY_CRL_CHECK_CHAIN

            if sslkey is None:
                sslkey = os.getenv('PGSSLKEY')
            if not sslkey:
                sslkey = _dot_postgresql_path('postgresql.key')
                if sslkey is not None and not sslkey.exists():
                    sslkey = None
            if not sslpassword:
                sslpassword = ''
            if sslcert is None:
                sslcert = os.getenv('PGSSLCERT')
            if sslcert:
                ssl.load_cert_chain(
                    sslcert, keyfile=sslkey, password=lambda: sslpassword
                )
            else:
                sslcert = _dot_postgresql_path('postgresql.crt')
                if sslcert is not None:
                    try:
                        ssl.load_cert_chain(
                            sslcert,
                            keyfile=sslkey,
                            password=lambda: sslpassword
                        )
                    except (FileNotFoundError, NotADirectoryError):
                        pass

            # OpenSSL 1.1.1 keylog file, copied from create_default_context()
            if hasattr(ssl, 'keylog_filename'):
                keylogfile = os.environ.get('SSLKEYLOGFILE')
                if keylogfile and not sys.flags.ignore_environment:
                    ssl.keylog_filename = keylogfile

            if ssl_min_protocol_version is None:
                ssl_min_protocol_version = os.getenv('PGSSLMINPROTOCOLVERSION')
            if ssl_min_protocol_version:
                ssl.minimum_version = _parse_tls_version(
                    ssl_min_protocol_version
                )
            else:
                ssl.minimum_version = _parse_tls_version('TLSv1.2')

            if ssl_max_protocol_version is None:
                ssl_max_protocol_version = os.getenv('PGSSLMAXPROTOCOLVERSION')
            if ssl_max_protocol_version:
                ssl.maximum_version = _parse_tls_version(
                    ssl_max_protocol_version
                )

    elif ssl is True:
        ssl = ssl_module.create_default_context()
        sslmode = SSLMode.verify_full
    else:
        sslmode = SSLMode.disable

    if server_settings is not None and (
            not isinstance(server_settings, dict) or
            not all(isinstance(k, str) for k in server_settings) or
            not all(isinstance(v, str) for v in server_settings.values())):
        raise exceptions.ClientConfigurationError(
            'server_settings is expected to be None or '
            'a Dict[str, str]')

    if target_session_attrs is None:
        target_session_attrs = os.getenv(
            "PGTARGETSESSIONATTRS", SessionAttribute.any
        )
    try:
        target_session_attrs = SessionAttribute(target_session_attrs)
    except ValueError:
        raise exceptions.ClientConfigurationError(
            "target_session_attrs is expected to be one of "
            "{!r}"
            ", got {!r}".format(
                SessionAttribute.__members__.values, target_session_attrs
            )
        ) from None

    if krbsrvname is None:
        krbsrvname = os.getenv('PGKRBSRVNAME')

    if gsslib is None:
        gsslib = os.getenv('PGGSSLIB')
        if gsslib is None:
            gsslib = 'sspi' if _system == 'Windows' else 'gssapi'
    if gsslib not in {'gssapi', 'sspi'}:
        raise exceptions.ClientConfigurationError(
            "gsslib parameter must be either 'gssapi' or 'sspi'"
            ", got {!r}".format(gsslib))

    params = _ConnectionParameters(
        user=user, password=password, database=database, ssl=ssl,
        sslmode=sslmode, ssl_negotiation=sslneg,
        server_settings=server_settings,
        target_session_attrs=target_session_attrs,
        krbsrvname=krbsrvname, gsslib=gsslib)

    return addrs, params


def _parse_connect_arguments(*, dsn, host, port, user, password, passfile,
                             database, command_timeout,
                             statement_cache_size,
                             max_cached_statement_lifetime,
                             max_cacheable_statement_size,
                             ssl, direct_tls, server_settings,
                             target_session_attrs, krbsrvname, gsslib,
                             service, servicefile):
    local_vars = locals()
    for var_name in {'max_cacheable_statement_size',
                     'max_cached_statement_lifetime',
                     'statement_cache_size'}:
        var_val = local_vars[var_name]
        if var_val is None or isinstance(var_val, bool) or var_val < 0:
            raise ValueError(
                '{} is expected to be greater '
                'or equal to 0, got {!r}'.format(var_name, var_val))

    if command_timeout is not None:
        try:
            if isinstance(command_timeout, bool):
                raise ValueError
            command_timeout = float(command_timeout)
            if command_timeout <= 0:
                raise ValueError
        except ValueError:
            raise ValueError(
                'invalid command_timeout value: '
                'expected greater than 0 float (got {!r})'.format(
                    command_timeout)) from None

    addrs, params = _parse_connect_dsn_and_args(
        dsn=dsn, host=host, port=port, user=user,
        password=password, passfile=passfile, ssl=ssl,
        direct_tls=direct_tls, database=database,
        server_settings=server_settings,
        target_session_attrs=target_session_attrs,
        krbsrvname=krbsrvname, gsslib=gsslib,
        service=service, servicefile=servicefile)

    config = _ClientConfiguration(
        command_timeout=command_timeout,
        statement_cache_size=statement_cache_size,
        max_cached_statement_lifetime=max_cached_statement_lifetime,
        max_cacheable_statement_size=max_cacheable_statement_size,)

    return addrs, params, config


class TLSUpgradeProto(asyncio.Protocol):
    def __init__(
        self,
        loop: asyncio.AbstractEventLoop,
        host: str,
        port: int,
        ssl_context: ssl_module.SSLContext,
        ssl_is_advisory: bool,
    ) -> None:
        self.on_data = _create_future(loop)
        self.host = host
        self.port = port
        self.ssl_context = ssl_context
        self.ssl_is_advisory = ssl_is_advisory

    def data_received(self, data: bytes) -> None:
        if data == b'S':
            self.on_data.set_result(True)
        elif (self.ssl_is_advisory and
                self.ssl_context.verify_mode == ssl_module.CERT_NONE and
                data == b'N'):
            # ssl_is_advisory will imply that ssl.verify_mode == CERT_NONE,
            # since the only way to get ssl_is_advisory is from
            # sslmode=prefer. But be extra sure to disallow insecure
            # connections when the ssl context asks for real security.
            self.on_data.set_result(False)
        else:
            self.on_data.set_exception(
                ConnectionError(
                    'PostgreSQL server at "{host}:{port}" '
                    'rejected SSL upgrade'.format(
                        host=self.host, port=self.port)))

    def connection_lost(self, exc: typing.Optional[Exception]) -> None:
        if not self.on_data.done():
            if exc is None:
                exc = ConnectionError('unexpected connection_lost() call')
            self.on_data.set_exception(exc)


_ProctolFactoryR = typing.TypeVar(
    "_ProctolFactoryR", bound=asyncio.protocols.Protocol
)


async def _create_ssl_connection(
    # TODO: The return type is a specific combination of subclasses of
    # asyncio.protocols.Protocol that we can't express. For now, having the
    # return type be dependent on signature of the factory is an improvement
    protocol_factory: Callable[[], _ProctolFactoryR],
    host: str,
    port: int,
    *,
    loop: asyncio.AbstractEventLoop,
    ssl_context: ssl_module.SSLContext,
    ssl_is_advisory: bool = False,
) -> typing.Tuple[asyncio.Transport, _ProctolFactoryR]:

    tr, pr = await loop.create_connection(
        lambda: TLSUpgradeProto(loop, host, port,
                                ssl_context, ssl_is_advisory),
        host, port)

    tr.write(struct.pack('!ll', 8, 80877103))  # SSLRequest message.

    try:
        do_ssl_upgrade = await pr.on_data
    except (Exception, asyncio.CancelledError):
        tr.close()
        raise

    if hasattr(loop, 'start_tls'):
        if do_ssl_upgrade:
            try:
                new_tr = await loop.start_tls(
                    tr, pr, ssl_context, server_hostname=host)
                assert new_tr is not None
            except (Exception, asyncio.CancelledError):
                tr.close()
                raise
        else:
            new_tr = tr

        pg_proto = protocol_factory()
        pg_proto.is_ssl = do_ssl_upgrade
        pg_proto.connection_made(new_tr)
        new_tr.set_protocol(pg_proto)

        return new_tr, pg_proto
    else:
        conn_factory = functools.partial(
            loop.create_connection, protocol_factory)

        if do_ssl_upgrade:
            conn_factory = functools.partial(
                conn_factory, ssl=ssl_context, server_hostname=host)

        sock = _get_socket(tr)
        sock = sock.dup()
        _set_nodelay(sock)
        tr.close()

        try:
            new_tr, pg_proto = await conn_factory(sock=sock)
            pg_proto.is_ssl = do_ssl_upgrade
            return new_tr, pg_proto
        except (Exception, asyncio.CancelledError):
            sock.close()
            raise


async def _connect_addr(
    *,
    addr,
    loop,
    params,
    config,
    connection_class,
    record_class
):
    assert loop is not None

    params_input = params
    if callable(params.password):
        password = params.password()
        if inspect.isawaitable(password):
            password = await password

        params = params._replace(password=password)
    args = (addr, loop, config, connection_class, record_class, params_input)

    # prepare the params (which attempt has ssl) for the 2 attempts
    if params.sslmode == SSLMode.allow:
        params_retry = params
        params = params._replace(ssl=None)
    elif params.sslmode == SSLMode.prefer:
        params_retry = params._replace(ssl=None)
    else:
        # skip retry if we don't have to
        return await __connect_addr(params, False, *args)

    # first attempt
    try:
        return await __connect_addr(params, True, *args)
    except _RetryConnectSignal:
        pass

    # second attempt
    return await __connect_addr(params_retry, False, *args)


class _RetryConnectSignal(Exception):
    pass


async def __connect_addr(
    params,
    retry,
    addr,
    loop,
    config,
    connection_class,
    record_class,
    params_input,
):
    connected = _create_future(loop)

    proto_factory = lambda: protocol.Protocol(
        addr, connected, params, record_class, loop)

    if isinstance(addr, str):
        # UNIX socket
        connector = loop.create_unix_connection(proto_factory, addr)

    elif params.ssl and params.ssl_negotiation is SSLNegotiation.direct:
        # if ssl and ssl_negotiation is `direct`, skip STARTTLS and perform
        # direct SSL connection
        connector = loop.create_connection(
            proto_factory, *addr, ssl=params.ssl
        )

    elif params.ssl:
        connector = _create_ssl_connection(
            proto_factory, *addr, loop=loop, ssl_context=params.ssl,
            ssl_is_advisory=params.sslmode == SSLMode.prefer)
    else:
        connector = loop.create_connection(proto_factory, *addr)

    tr, pr = await connector

    try:
        await connected
    except (
        exceptions.InvalidAuthorizationSpecificationError,
        exceptions.ConnectionDoesNotExistError,  # seen on Windows
    ):
        tr.close()

        # retry=True here is a redundant check because we don't want to
        # accidentally raise the internal _RetryConnectSignal to the user
        if retry and (
            params.sslmode == SSLMode.allow and not pr.is_ssl or
            params.sslmode == SSLMode.prefer and pr.is_ssl
        ):
            # Trigger retry when:
            #   1. First attempt with sslmode=allow, ssl=None failed
            #   2. First attempt with sslmode=prefer, ssl=ctx failed while the
            #      server claimed to support SSL (returning "S" for SSLRequest)
            #      (likely because pg_hba.conf rejected the connection)
            raise _RetryConnectSignal()

        else:
            # but will NOT retry if:
            #   1. First attempt with sslmode=prefer failed but the server
            #      doesn't support SSL (returning 'N' for SSLRequest), because
            #      we already tried to connect without SSL thru ssl_is_advisory
            #   2. Second attempt with sslmode=prefer, ssl=None failed
            #   3. Second attempt with sslmode=allow, ssl=ctx failed
            #   4. Any other sslmode
            raise

    except (Exception, asyncio.CancelledError):
        tr.close()
        raise

    con = connection_class(pr, tr, loop, addr, config, params_input)
    pr.set_connection(con)
    return con


class SessionAttribute(str, enum.Enum):
    any = 'any'
    primary = 'primary'
    standby = 'standby'
    prefer_standby = 'prefer-standby'
    read_write = "read-write"
    read_only = "read-only"


def _accept_in_hot_standby(should_be_in_hot_standby: bool):
    """
    If the server didn't report "in_hot_standby" at startup, we must determine
    the state by checking "SELECT pg_catalog.pg_is_in_recovery()".
    If the server allows a connection and states it is in recovery it must
    be a replica/standby server.
    """
    async def can_be_used(connection):
        settings = connection.get_settings()
        hot_standby_status = getattr(settings, 'in_hot_standby', None)
        if hot_standby_status is not None:
            is_in_hot_standby = hot_standby_status == 'on'
        else:
            is_in_hot_standby = await connection.fetchval(
                "SELECT pg_catalog.pg_is_in_recovery()"
            )
        return is_in_hot_standby == should_be_in_hot_standby

    return can_be_used


def _accept_read_only(should_be_read_only: bool):
    """
    Verify the server has not set default_transaction_read_only=True
    """
    async def can_be_used(connection):
        settings = connection.get_settings()
        is_readonly = getattr(settings, 'default_transaction_read_only', 'off')

        if is_readonly == "on":
            return should_be_read_only

        return await _accept_in_hot_standby(should_be_read_only)(connection)
    return can_be_used


async def _accept_any(_):
    return True


target_attrs_check = {
    SessionAttribute.any: _accept_any,
    SessionAttribute.primary: _accept_in_hot_standby(False),
    SessionAttribute.standby: _accept_in_hot_standby(True),
    SessionAttribute.prefer_standby: _accept_in_hot_standby(True),
    SessionAttribute.read_write: _accept_read_only(False),
    SessionAttribute.read_only: _accept_read_only(True),
}


async def _can_use_connection(connection, attr: SessionAttribute):
    can_use = target_attrs_check[attr]
    return await can_use(connection)


async def _connect(*, loop, connection_class, record_class, **kwargs):
    if loop is None:
        loop = asyncio.get_event_loop()

    addrs, params, config = _parse_connect_arguments(**kwargs)
    target_attr = params.target_session_attrs

    candidates = []
    chosen_connection = None
    last_error = None
    try:
        for addr in addrs:
            try:
                conn = await _connect_addr(
                    addr=addr,
                    loop=loop,
                    params=params,
                    config=config,
                    connection_class=connection_class,
                    record_class=record_class,
                )
                candidates.append(conn)
                if await _can_use_connection(conn, target_attr):
                    chosen_connection = conn
                    break
            except OSError as ex:
                last_error = ex
        else:
            if target_attr == SessionAttribute.prefer_standby and candidates:
                chosen_connection = random.choice(candidates)
    finally:

        async def _close_candidates(conns, chosen):
            await asyncio.gather(
                *(c.close() for c in conns if c is not chosen),
                return_exceptions=True
            )
        if candidates:
            asyncio.create_task(
                _close_candidates(candidates, chosen_connection))

    if chosen_connection:
        return chosen_connection

    raise last_error or exceptions.TargetServerAttributeNotMatched(
        'None of the hosts match the target attribute requirement '
        '{!r}'.format(target_attr)
    )


async def _cancel(*, loop, addr, params: _ConnectionParameters,
                  backend_pid, backend_secret):

    class CancelProto(asyncio.Protocol):

        def __init__(self):
            self.on_disconnect = _create_future(loop)
            self.is_ssl = False

        def connection_lost(self, exc):
            if not self.on_disconnect.done():
                self.on_disconnect.set_result(True)

    if isinstance(addr, str):
        tr, pr = await loop.create_unix_connection(CancelProto, addr)
    else:
        if params.ssl and params.sslmode != SSLMode.allow:
            tr, pr = await _create_ssl_connection(
                CancelProto,
                *addr,
                loop=loop,
                ssl_context=params.ssl,
                ssl_is_advisory=params.sslmode == SSLMode.prefer)
        else:
            tr, pr = await loop.create_connection(
                CancelProto, *addr)
            _set_nodelay(_get_socket(tr))

    # Pack a CancelRequest message
    msg = struct.pack('!llll', 16, 80877102, backend_pid, backend_secret)

    try:
        tr.write(msg)
        await pr.on_disconnect
    finally:
        tr.close()


def _get_socket(transport):
    sock = transport.get_extra_info('socket')
    if sock is None:
        # Shouldn't happen with any asyncio-complaint event loop.
        raise ConnectionError(
            'could not get the socket for transport {!r}'.format(transport))
    return sock


def _set_nodelay(sock):
    if not hasattr(socket, 'AF_UNIX') or sock.family != socket.AF_UNIX:
        sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)


def _create_future(loop):
    try:
        create_future = loop.create_future
    except AttributeError:
        return asyncio.Future(loop=loop)
    else:
        return create_future()


================================================
FILE: asyncpg/connection.py
================================================
# Copyright (C) 2016-present the asyncpg authors and contributors
# <see AUTHORS file>
#
# This module is part of asyncpg and is released under
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0


import asyncio
import asyncpg
import collections
import collections.abc
import contextlib
import functools
import itertools
import inspect
import os
import sys
import time
import traceback
import typing
import warnings
import weakref

from . import compat
from . import connect_utils
from . import cursor
from . import exceptions
from . import introspection
from . import prepared_stmt
from . import protocol
from . import serverversion
from . import transaction
from . import utils


class ConnectionMeta(type):

    def __instancecheck__(cls, instance):
        mro = type(instance).__mro__
        return Connection in mro or _ConnectionProxy in mro


class Connection(metaclass=ConnectionMeta):
    """A representation of a database session.

    Connections are created by calling :func:`~asyncpg.connection.connect`.
    """

    __slots__ = ('_protocol', '_transport', '_loop',
                 '_top_xact', '_aborted',
                 '_pool_release_ctr', '_stmt_cache', '_stmts_to_close',
                 '_stmt_cache_enabled',
                 '_listeners', '_server_version', '_server_caps',
                 '_intro_query', '_reset_query', '_proxy',
                 '_stmt_exclusive_section', '_config', '_params', '_addr',
                 '_log_listeners', '_termination_listeners', '_cancellations',
                 '_source_traceback', '_query_loggers', '__weakref__')

    def __init__(self, protocol, transport, loop,
                 addr,
                 config: connect_utils._ClientConfiguration,
                 params: connect_utils._ConnectionParameters):
        self._protocol = protocol
        self._transport = transport
        self._loop = loop
        self._top_xact = None
        self._aborted = False
        # Incremented every time the connection is released back to a pool.
        # Used to catch invalid references to connection-related resources
        # post-release (e.g. explicit prepared statements).
        self._pool_release_ctr = 0

        self._addr = addr
        self._config = config
        self._params = params

        self._stmt_cache = _StatementCache(
            loop=loop,
            max_size=config.statement_cache_size,
            on_remove=functools.partial(
                _weak_maybe_gc_stmt, weakref.ref(self)),
            max_lifetime=config.max_cached_statement_lifetime)

        self._stmts_to_close = set()
        self._stmt_cache_enabled = config.statement_cache_size > 0

        self._listeners = {}
        self._log_listeners = set()
        self._cancellations = set()
        self._termination_listeners = set()
        self._query_loggers = set()

        settings = self._protocol.get_settings()
        ver_string = settings.server_version
        self._server_version = \
            serverversion.split_server_version_string(ver_string)

        self._server_caps = _detect_server_capabilities(
            self._server_version, settings)

        if self._server_version < (14, 0):
            self._intro_query = introspection.INTRO_LOOKUP_TYPES_13
        else:
            self._intro_query = introspection.INTRO_LOOKUP_TYPES

        self._reset_query = None
        self._proxy = None

        # Used to serialize operations that might involve anonymous
        # statements.  Specifically, we want to make the following
        # operation atomic:
        #    ("prepare an anonymous statement", "use the statement")
        #
        # Used for `con.fetchval()`, `con.fetch()`, `con.fetchrow()`,
        # `con.execute()`, and `con.executemany()`.
        self._stmt_exclusive_section = _Atomic()

        if loop.get_debug():
            self._source_traceback = _extract_stack()
        else:
            self._source_traceback = None

    def __del__(self):
        if not self.is_closed() and self._protocol is not None:
            if self._source_traceback:
                msg = "unclosed connection {!r}; created at:\n {}".format(
                    self, self._source_traceback)
            else:
                msg = (
                    "unclosed connection {!r}; run in asyncio debug "
                    "mode to show the traceback of connection "
                    "origin".format(self)
                )

            warnings.warn(msg, ResourceWarning)
            if not self._loop.is_closed():
                self.terminate()

    async def add_listener(self, channel, callback):
        """Add a listener for Postgres notifications.

        :param str channel: Channel to listen on.

        :param callable callback:
            A callable or a coroutine function receiving the following
            arguments:
            **connection**: a Connection the callback is registered with;
            **pid**: PID of the Postgres server that sent the notification;
            **channel**: name of the channel the notification was sent to;
            **payload**: the payload.

        .. versionchanged:: 0.24.0
            The ``callback`` argument may be a coroutine function.
        """
        self._check_open()
        if channel not in self._listeners:
            await self.fetch('LISTEN {}'.format(utils._quote_ident(channel)))
            self._listeners[channel] = set()
        self._listeners[channel].add(_Callback.from_callable(callback))

    async def remove_listener(self, channel, callback):
        """Remove a listening callback on the specified channel."""
        if self.is_closed():
            return
        if channel not in self._listeners:
            return
        cb = _Callback.from_callable(callback)
        if cb not in self._listeners[channel]:
            return
        self._listeners[channel].remove(cb)
        if not self._listeners[channel]:
            del self._listeners[channel]
            await self.fetch('UNLISTEN {}'.format(utils._quote_ident(channel)))

    def add_log_listener(self, callback):
        """Add a listener for Postgres log messages.

        It will be called when asyncronous NoticeResponse is received
        from the connection.  Possible message types are: WARNING, NOTICE,
        DEBUG, INFO, or LOG.

        :param callable callback:
            A callable or a coroutine function receiving the following
            arguments:
            **connection**: a Connection the callback is registered with;
            **message**: the `exceptions.PostgresLogMessage` message.

        .. versionadded:: 0.12.0

        .. versionchanged:: 0.24.0
            The ``callback`` argument may be a coroutine function.
        """
        if self.is_closed():
            raise exceptions.InterfaceError('connection is closed')
        self._log_listeners.add(_Callback.from_callable(callback))

    def remove_log_listener(self, callback):
        """Remove a listening callback for log messages.

        .. versionadded:: 0.12.0
        """
        self._log_listeners.discard(_Callback.from_callable(callback))

    def add_termination_listener(self, callback):
        """Add a listener that will be called when the connection is closed.

        :param callable callback:
            A callable or a coroutine function receiving one argument:
            **connection**: a Connection the callback is registered with.

        .. versionadded:: 0.21.0

        .. versionchanged:: 0.24.0
            The ``callback`` argument may be a coroutine function.
        """
        self._termination_listeners.add(_Callback.from_callable(callback))

    def remove_termination_listener(self, callback):
        """Remove a listening callback for connection termination.

        :param callable callback:
            The callable or coroutine function that was passed to
            :meth:`Connection.add_termination_listener`.

        .. versionadded:: 0.21.0
        """
        self._termination_listeners.discard(_Callback.from_callable(callback))

    def add_query_logger(self, callback):
        """Add a logger that will be called when queries are executed.

        :param callable callback:
            A callable or a coroutine function receiving one argument:
            **record**, a LoggedQuery containing `query`, `args`, `timeout`,
            `elapsed`, `exception`, `conn_addr`, and `conn_params`.

        .. versionadded:: 0.29.0
        """
        self._query_loggers.add(_Callback.from_callable(callback))

    def remove_query_logger(self, callback):
        """Remove a query logger callback.

        :param callable callback:
            The callable or coroutine function that was passed to
            :meth:`Connection.add_query_logger`.

        .. versionadded:: 0.29.0
        """
        self._query_loggers.discard(_Callback.from_callable(callback))

    def get_server_pid(self):
        """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)

        .. versionadded:: 0.8.0
        """
        return self._server_version

    def get_settings(self):
        """Return connection settings.

        :return: :class:`~asyncpg.ConnectionSettings`.
        """
        return self._protocol.get_settings()

    def transaction(self, *, isolation=None, readonly=False,
                    deferrable=False):
        """Create a :class:`~transaction.Transaction` object.

        Refer to `PostgreSQL documentation`_ on the meaning of transaction
        parameters.

        :param isolation: Transaction isolation mode, can be one of:
                          `'serializable'`, `'repeatable_read'`,
                          `'read_uncommitted'`, `'read_committed'`. If not
                          specified, the behavior is up to the server and
                          session, which is usually ``read_committed``.

        :param readonly: Specifies whether or not this transaction is
                         read-only.

        :param deferrable: Specifies whether or not this transaction is
                           deferrable.

        .. _`PostgreSQL documentation`:
                https://www.postgresql.org/docs/
                current/static/sql-set-transaction.html
        """
        self._check_open()
        return transaction.Transaction(self, isolation, readonly, deferrable)

    def is_in_transaction(self):
        """Return True if Connection is currently inside a transaction.

        :return bool: True if inside transaction, False otherwise.

        .. versionadded:: 0.16.0
        """
        return self._protocol.is_in_transaction()

    async def execute(
        self,
        query: str,
        *args,
        timeout: typing.Optional[float]=None,
    ) -> str:
        """Execute an SQL command (or commands).

        This method can execute many SQL commands at once, when no arguments
        are provided.

        Example:

        .. code-block:: pycon

            >>> await con.execute('''
            ...     CREATE TABLE mytab (a int);
            ...     INSERT INTO mytab (a) VALUES (100), (200), (300);
            ... ''')
            INSERT 0 3

            >>> await con.execute('''
            ...     INSERT INTO mytab (a) VALUES ($1), ($2)
            ... ''', 10, 20)
            INSERT 0 2

        :param args: Query arguments.
        :param float timeout: Optional timeout value in seconds.
        :return str: Status of the last SQL command.

        .. versionchanged:: 0.5.4
           Made it possible to pass query arguments.
        """
        self._check_open()

        if not args:
            if self._query_loggers:
                with self._time_and_log(query, args, timeout):
                    result = await self._protocol.query(query, timeout)
            else:
                result = await self._protocol.query(query, timeout)
            return result

        _, status, _ = await self._execute(
            query,
            args,
            0,
            timeout,
            return_status=True,
        )
        return status.decode()

    async def executemany(
        self,
        command: str,
        args,
        *,
        timeout: typing.Optional[float]=None,
    ):
        """Execute an SQL *command* for each sequence of arguments in *args*.

        Example:

        .. code-block:: pycon

            >>> await con.executemany('''
            ...     INSERT INTO mytab (a) VALUES ($1, $2, $3);
            ... ''', [(1, 2, 3), (4, 5, 6)])

        :param command: Command to execute.
        :param args: An iterable containing sequences of arguments.
        :param float timeout: Optional timeout value in seconds.
        :return None: This method discards the results of the operations.

        .. versionadded:: 0.7.0

        .. versionchanged:: 0.11.0
           `timeout` became a keyword-only parameter.

        .. versionchanged:: 0.22.0
           ``executemany()`` is now an atomic operation, which means that
           either all executions succeed, or none at all.  This is in contrast
           to prior versions, where the effect of already-processed iterations
           would remain in place when an error has occurred, unless
           ``executemany()`` was called in a transaction.
        """
        self._check_open()
        return await self._executemany(command, args, timeout)

    async def _get_statement(
        self,
        query,
        timeout,
        *,
        named: typing.Union[str, bool, None] = False,
        use_cache=True,
        ignore_custom_codec=False,
        record_class=None
    ):
        if record_class is None:
            record_class = self._protocol.get_record_class()
        else:
            _check_record_class(record_class)

        if use_cache:
            statement = self._stmt_cache.get(
                (query, record_class, ignore_custom_codec)
            )
            if statement is not None:
                return statement

            # Only use the cache when:
            #  * `statement_cache_size` is greater than 0;
            #  * query size is less than `max_cacheable_statement_size`.
            use_cache = (
                self._stmt_cache_enabled
                and (
                    not self._config.max_cacheable_statement_size
                    or len(query) <= self._config.max_cacheable_statement_size
                )
            )

        if isinstance(named, str):
            stmt_name = named
        elif use_cache or named:
            stmt_name = self._get_unique_id('stmt')
        else:
            stmt_name = ''

        statement = await self._protocol.prepare(
            stmt_name,
            query,
            timeout,
            record_class=record_class,
            ignore_custom_codec=ignore_custom_codec,
        )
        need_reprepare = False
        types_with_missing_codecs = statement._init_types()
        tries = 0
        while types_with_missing_codecs:
            settings = self._protocol.get_settings()

            # Introspect newly seen types and populate the
            # codec cache.
            types, intro_stmt = await self._introspect_types(
                types_with_missing_codecs, timeout)

            settings.register_data_types(types)

            # The introspection query has used an anonymous statement,
            # which has blown away the anonymous statement we've prepared
            # for the query, so we need to re-prepare it.
            need_reprepare = not intro_stmt.name and not statement.name
            types_with_missing_codecs = statement._init_types()
            tries += 1
            if tries > 5:
                # In the vast majority of cases there will be only
                # one iteration.  In rare cases, there might be a race
                # with reload_schema_state(), which would cause a
                # second try.  More than five is clearly a bug.
                raise exceptions.InternalClientError(
                    'could not resolve query result and/or argument types '
                    'in {} attempts'.format(tries)
                )

        # Now that types have been resolved, populate the codec pipeline
        # for the statement.
        statement._init_codecs()

        if (
            need_reprepare
            or (not statement.name and not self._stmt_cache_enabled)
        ):
            # Mark this anonymous prepared statement as "unprepared",
            # causing it to get re-Parsed in next bind_execute.
            # We always do this when stmt_cache_size is set to 0 assuming
            # people are running PgBouncer which is mishandling implicit
            # transactions.
            statement.mark_unprepared()

        if use_cache:
            self._stmt_cache.put(
                (query, record_class, ignore_custom_codec), statement)

        # If we've just created a new statement object, check if there
        # are any statements for GC.
        if self._stmts_to_close:
            await self._cleanup_stmts()

        return statement

    async def _introspect_types(self, typeoids, timeout):
        if self._server_caps.jit:
            try:
                cfgrow, _ = await self.__execute(
                    """
                    SELECT
                        current_setting('jit') AS cur,
                        set_config('jit', 'off', false) AS new
                    """,
                    (),
                    0,
                    timeout,
                    ignore_custom_codec=True,
                )
                jit_state = cfgrow[0]['cur']
            except exceptions.UndefinedObjectError:
                jit_state = 'off'
        else:
            jit_state = 'off'

        result = await self.__execute(
            self._intro_query,
            (list(typeoids),),
            0,
            timeout,
            ignore_custom_codec=True,
        )

        if jit_state != 'off':
            await self.__execute(
                """
                SELECT
                    set_config('jit', $1, false)
                """,
                (jit_state,),
                0,
                timeout,
                ignore_custom_codec=True,
            )

        return result

    async def _introspect_type(self, typename, schema):
        if schema == 'pg_catalog' and not typename.endswith("[]"):
            typeoid = protocol.BUILTIN_TYPE_NAME_MAP.get(typename.lower())
            if typeoid is not None:
                return introspection.TypeRecord((typeoid, None, b"b"))

        rows = await self._execute(
            introspection.TYPE_BY_NAME,
            [typename, schema],
            limit=1,
            timeout=None,
            ignore_custom_codec=True,
        )

        if not rows:
            raise ValueError(
                'unknown type: {}.{}'.format(schema, typename))

        return rows[0]

    def cursor(
        self,
        query,
        *args,
        prefetch=None,
        timeout=None,
        record_class=None
    ):
        """Return a *cursor factory* for the specified query.

        :param args:
            Query arguments.
        :param int prefetch:
            The number of rows the *cursor iterator*
            will prefetch (defaults to ``50``.)
        :param float timeout:
            Optional timeout in seconds.
        :param type record_class:
            If specified, the class to use for records returned by this cursor.
            Must be a subclass of :class:`~asyncpg.Record`.  If not specified,
            a per-connection *record_class* is used.

        :return:
            A :class:`~cursor.CursorFactory` object.

        .. versionchanged:: 0.22.0
            Added the *record_class* parameter.
        """
        self._check_open()
        return cursor.CursorFactory(
            self,
            query,
            None,
            args,
            prefetch,
            timeout,
            record_class,
        )

    async def prepare(
        self,
        query,
        *,
        name=None,
        timeout=None,
        record_class=None,
    ):
        """Create a *prepared statement* for the specified query.

        :param str query:
            Text of the query to create a prepared statement for.
        :param str name:
            Optional name of the returned prepared statement.  If not
            specified, the name is auto-generated.
        :param float timeout:
            Optional timeout value in seconds.
        :param type record_class:
            If specified, the class to use for records returned by the
            prepared statement.  Must be a subclass of
            :class:`~asyncpg.Record`.  If not specified, a per-connection
            *record_class* is used.

        :return:
            A :class:`~prepared_stmt.PreparedStatement` instance.

        .. versionchanged:: 0.22.0
            Added the *record_class* parameter.

        .. versionchanged:: 0.25.0
            Added the *name* parameter.
        """
        return await self._prepare(
            query,
            name=name,
            timeout=timeout,
            record_class=record_class,
        )

    async def _prepare(
        self,
        query,
        *,
        name: typing.Union[str, bool, None] = None,
        timeout=None,
        use_cache: bool=False,
        record_class=None
    ):
        self._check_open()
        if name is None:
            name = self._stmt_cache_enabled
        stmt = await self._get_statement(
            query,
            timeout,
            named=name,
            use_cache=use_cache,
            record_class=record_class,
        )
        return prepared_stmt.PreparedStatement(self, query, stmt)

    async def fetch(
        self,
        query,
        *args,
        timeout=None,
        record_class=None
    ) -> list:
        """Run a query and return the results as a list of :class:`Record`.

        :param str query:
            Query text.
        :param args:
            Query arguments.
        :param float timeout:
            Optional timeout value in seconds.
        :param type record_class:
            If specified, the class to use for records returned by this method.
            Must be a subclass of :class:`~asyncpg.Record`.  If not specified,
            a per-connection *record_class* is used.

        :return list:
            A list of :class:`~asyncpg.Record` instances.  If specified, the
            actual type of list elements would be *record_class*.

        .. versionchanged:: 0.22.0
            Added the *record_class* parameter.
        """
        self._check_open()
        return await self._execute(
            query,
            args,
            0,
            timeout,
            record_class=record_class,
        )

    async def fetchval(self, query, *args, column=0, timeout=None):
        """Run a query and return a value in the first row.

        :param str query: Query text.
        :param args: Query arguments.
        :param int column: Numeric index within the record of the value to
                           return (defaults to 0).
        :param float timeout: Optional timeout value in seconds.
                            If not specified, defaults to the value of
                            ``command_timeout`` argument to the ``Connection``
                            instance constructor.

        :return: The value of the specified column of the first record, or
                 None if no records were returned by the query.
        """
        self._check_open()
        data = await self._execute(query, args, 1, timeout)
        if not data:
            return None
        return data[0][column]

    async def fetchrow(
        self,
        query,
        *args,
        timeout=None,
        record_class=None
    ):
        """Run a query and return the first row.

        :param str query:
            Query text
        :param args:
            Query arguments
        :param float timeout:
            Optional timeout value in seconds.
        :param type record_class:
            If specified, the class to use for the value returned by this
            method.  Must be a subclass of :class:`~asyncpg.Record`.
            If not specified, a per-connection *record_class* is used.

        :return:
            The first row as a :class:`~asyncpg.Record` instance, or None if
            no records were returned by the query.  If specified,
            *record_class* is used as the type for the result value.

        .. versionchanged:: 0.22.0
            Added the *record_class* parameter.
        """
        self._check_open()
        data = await self._execute(
            query,
            args,
            1,
            timeout,
            record_class=record_class,
        )
        if not data:
            return None
        return data[0]

    async def fetchmany(
        self,
        query,
        args,
        *,
        timeout: typing.Optional[float]=None,
        record_class=None,
    ):
        """Run a query for each sequence of arguments in *args*
        and return the results as a list of :class:`Record`.

        :param query:
            Query to execute.
        :param args:
            An iterable containing sequences of arguments for the query.
        :param float timeout:
            Optional timeout value in seconds.
        :param type record_class:
            If specified, the class to use for records returned by this method.
            Must be a subclass of :class:`~asyncpg.Record`.  If not specified,
            a per-connection *record_class* is used.

        :return list:
            A list of :class:`~asyncpg.Record` instances.  If specified, the
            actual type of list elements would be *record_class*.

        Example:

        .. code-block:: pycon

            >>> rows = await con.fetchmany('''
            ...         INSERT INTO mytab (a, b) VALUES ($1, $2) RETURNING a;
            ...     ''', [('x', 1), ('y', 2), ('z', 3)])
            >>> rows
            [<Record row=('x',)>, <Record row=('y',)>, <Record row=('z',)>]

        .. versionadded:: 0.30.0
        """
        self._check_open()
        return await self._executemany(
            query, args, timeout, return_rows=True, record_class=record_class
        )

    async def copy_from_table(self, table_name, *, output,
                              columns=None, schema_name=None, timeout=None,
                              format=None, oids=None, delimiter=None,
                              null=None, header=None, quote=None,
                              escape=None, force_quote=None, encoding=None):
        """Copy table contents to a file or file-like object.

        :param str table_name:
            The name of the table to copy data from.

        :param output:
            A :term:`path-like object <python:path-like object>`,
            or a :term:`file-like object <python:file-like object>`, or
            a :term:`coroutine function <python:coroutine function>`
            that takes a ``bytes`` instance as a sole argument.

        :param list columns:
            An optional list of column names to copy.

        :param str schema_name:
            An optional schema name to qualify the table.

        :param float timeout:
            Optional timeout value in seconds.

        The remaining keyword arguments are ``COPY`` statement options,
        see `COPY statement documentation`_ for details.

        :return: The status string of the COPY command.

        Example:

        .. code-block:: pycon

            >>> import asyncpg
            >>> import asyncio
            >>> async def run():
            ...     con = await asyncpg.connect(user='postgres')
            ...     result = await con.copy_from_table(
            ...         'mytable', columns=('foo', 'bar'),
            ...         output='file.csv', format='csv')
            ...     print(result)
            ...
            >>> asyncio.run(run())
            'COPY 100'

        .. _`COPY statement documentation`:
            https://www.postgresql.org/docs/current/static/sql-copy.html

        .. versionadded:: 0.11.0
        """
        tabname = utils._quote_ident(table_name)
        if schema_name:
            tabname = utils._quote_ident(schema_name) + '.' + tabname

        if columns:
            cols = '({})'.format(
                ', '.join(utils._quote_ident(c) for c in columns))
        else:
            cols = ''

        opts = self._format_copy_opts(
            format=format, oids=oids, delimiter=delimiter,
            null=null, header=header, quote=quote, escape=escape,
            force_quote=force_quote, encoding=encoding
        )

        copy_stmt = 'COPY {tab}{cols} TO STDOUT {opts}'.format(
            tab=tabname, cols=cols, opts=opts)

        return await self._copy_out(copy_stmt, output, timeout)

    async def copy_from_query(self, query, *args, output,
                              timeout=None, format=None, oids=None,
                              delimiter=None, null=None, header=None,
                              quote=None, escape=None, force_quote=None,
                              encoding=None):
        """Copy the results of a query to a file or file-like object.

        :param str query:
            The query to copy the results of.

        :param args:
            Query arguments.

        :param output:
            A :term:`path-like object <python:path-like object>`,
            or a :term:`file-like object <python:file-like object>`, or
            a :term:`coroutine function <python:coroutine function>`
            that takes a ``bytes`` instance as a sole argument.

        :param float timeout:
            Optional timeout value in seconds.

        The remaining keyword arguments are ``COPY`` statement options,
        see `COPY statement documentation`_ for details.

        :return: The status string of the COPY command.

        Example:

        .. code-block:: pycon

            >>> import asyncpg
            >>> import asyncio
            >>> async def run():
            ...     con = await asyncpg.connect(user='postgres')
            ...     result = await con.copy_from_query(
            ...         'SELECT foo, bar FROM mytable WHERE foo > $1', 10,
            ...         output='file.csv', format='csv')
            ...     print(result)
            ...
            >>> asyncio.run(run())
            'COPY 10'

        .. _`COPY statement documentation`:
            https://www.postgresql.org/docs/current/static/sql-copy.html

        .. versionadded:: 0.11.0
        """
        opts = self._format_copy_opts(
            format=format, oids=oids, delimiter=delimiter,
            null=null, header=header, quote=quote, escape=escape,
            force_quote=force_quote, encoding=encoding
        )

        if args:
            query = await utils._mogrify(self, query, args)

        copy_stmt = 'COPY ({query}) TO STDOUT {opts}'.format(
            query=query, opts=opts)

        return await self._copy_out(copy_stmt, output, timeout)

    async def copy_to_table(self, table_name, *, source,
                            columns=None, schema_name=None, timeout=None,
                            format=None, oids=None, freeze=None,
                            delimiter=None, null=None, header=None,
                            quote=None, escape=None, force_quote=None,
                            force_not_null=None, force_null=None,
                            encoding=None, where=None):
        """Copy data to the specified table.

        :param str table_name:
            The name of the table to copy data to.

        :param source:
            A :term:`path-like object <python:path-like object>`,
            or a :term:`file-like object <python:file-like object>`, or
            an :term:`asynchronous iterable <python:asynchronous iterable>`
            that returns ``bytes``, or an object supporting the
            :ref:`buffer protocol <python:bufferobjects>`.

        :param list columns:
            An optional list of column names to copy.

        :param str schema_name:
            An optional schema name to qualify the table.

        :param str where:
            An optional SQL expression used to filter rows when copying.

            .. note::

                Usage of this parameter requires support for the
                ``COPY FROM ... WHERE`` syntax, introduced in
                PostgreSQL version 12.

        :param float timeout:
            Optional timeout value in seconds.

        The remaining keyword arguments are ``COPY`` statement options,
        see `COPY statement documentation`_ for details.

        :return: The status string of the COPY command.

        Example:

        .. code-block:: pycon

            >>> import asyncpg
            >>> import asyncio
            >>> async def run():
            ...     con = await asyncpg.connect(user='postgres')
            ...     result = await con.copy_to_table(
            ...         'mytable', source='datafile.tbl')
            ...     print(result)
            ...
            >>> asyncio.run(run())
            'COPY 140000'

        .. _`COPY statement documentation`:
            https://www.postgresql.org/docs/current/static/sql-copy.html

        .. versionadded:: 0.11.0

        .. versionadded:: 0.29.0
            Added the *where* parameter.
        """
        tabname = utils._quote_ident(table_name)
        if schema_name:
            tabname = utils._quote_ident(schema_name) + '.' + tabname

        if columns:
            cols = '({})'.format(
                ', '.join(utils._quote_ident(c) for c in columns))
        else:
            cols = ''

        cond = self._format_copy_where(where)
        opts = self._format_copy_opts(
            format=format, oids=oids, freeze=freeze, delimiter=delimiter,
            null=null, header=header, quote=quote, escape=escape,
            force_not_null=force_not_null, force_null=force_null,
            encoding=encoding
        )

        copy_stmt = 'COPY {tab}{cols} FROM STDIN {opts} {cond}'.format(
            tab=tabname, cols=cols, opts=opts, cond=cond)

        return await self._copy_in(copy_stmt, source, timeout)

    async def copy_records_to_table(self, table_name, *, records,
                                    columns=None, schema_name=None,
                                    timeout=None, where=None):
        """Copy a list of records to the specified table using binary COPY.

        :param str table_name:
            The name of the table to copy data to.

        :param records:
            An iterable returning row tuples to copy into the table.
            :term:`Asynchronous iterables <python:asynchronous iterable>`
            are also supported.

        :param list columns:
            An optional list of column names to copy.

        :param str schema_name:
            An optional schema name to qualify the table.

        :param str where:
            An optional SQL expression used to filter rows when copying.

            .. note::

                Usage of this parameter requires support for the
                ``COPY FROM ... WHERE`` syntax, introduced in
                PostgreSQL version 12.


        :param float timeout:
            Optional timeout value in seconds.

        :return: The status string of the COPY command.

        Example:

        .. code-block:: pycon

            >>> import asyncpg
            >>> import asyncio
            >>> async def run():
            ...     con = await asyncpg.connect(user='postgres')
            ...     result = await con.copy_records_to_table(
            ...         'mytable', records=[
            ...             (1, 'foo', 'bar'),
            ...             (2, 'ham', 'spam')])
            ...     print(result)
            ...
            >>> asyncio.run(run())
            'COPY 2'

        Asynchronous record iterables are also supported:

        .. code-block:: pycon

            >>> import asyncpg
            >>> import asyncio
            >>> async def run():
            ...     con = await asyncpg.connect(user='postgres')
            ...     async def record_gen(size):
            ...         for i in range(size):
            ...             yield (i,)
            ...     result = await con.copy_records_to_table(
            ...         'mytable', records=record_gen(100))
            ...     print(result)
            ...
            >>> asyncio.run(run())
            'COPY 100'

        .. versionadded:: 0.11.0

        .. versionchanged:: 0.24.0
            The ``records`` argument may be an asynchronous iterable.

        .. versionadded:: 0.29.0
            Added the *where* parameter.
        """
        tabname = utils._quote_ident(table_name)
        if schema_name:
            tabname = utils._quote_ident(schema_name) + '.' + tabname

        if columns:
            col_list = ', '.join(utils._quote_ident(c) for c in columns)
            cols = '({})'.format(col_list)
        else:
            col_list = '*'
            cols = ''

        intro_query = 'SELECT {cols} FROM {tab} LIMIT 1'.format(
            tab=tabname, cols=col_list)

        intro_ps = await self.prepare(intro_query)

        cond = self._format_copy_where(where)
        opts = '(FORMAT binary)'

        copy_stmt = 'COPY {tab}{cols} FROM STDIN {opts} {cond}'.format(
            tab=tabname, cols=cols, opts=opts, cond=cond)

        return await self._protocol.copy_in(
            copy_stmt, None, None, records, intro_ps._state, timeout)

    def _format_copy_where(self, where):
        if where and not self._server_caps.sql_copy_from_where:
            raise exceptions.UnsupportedServerFeatureError(
                'the `where` parameter requires PostgreSQL 12 or later')

        if where:
            where_clause = 'WHERE ' + where
        else:
            where_clause = ''

        return where_clause

    def _format_copy_opts(self, *, format=None, oids=None, freeze=None,
                          delimiter=None, null=None, header=None, quote=None,
                          escape=None, force_quote=None, force_not_null=None,
                          force_null=None, encoding=None):
        kwargs = dict(locals())
        kwargs.pop('self')
        opts = []

        if force_quote is not None and isinstance(force_quote, bool):
            kwargs.pop('force_quote')
            if force_quote:
                opts.append('FORCE_QUOTE *')

        for k, v in kwargs.items():
            if v is not None:
                if k in ('force_not_null', 'force_null', 'force_quote'):
                    v = '(' + ', '.join(utils._quote_ident(c) for c in v) + ')'
                elif k in ('oids', 'freeze', 'header'):
                    v = str(v)
                else:
                    v = utils._quote_literal(v)

                opts.append('{} {}'.format(k.upper(), v))

        if opts:
            return '(' + ', '.join(opts) + ')'
        else:
            return ''

    async def _copy_out(self, copy_stmt, output, timeout):
        try:
            path = os.fspath(output)
        except TypeError:
            # output is not a path-like object
            path = None

        writer = None
        opened_by_us = False
        run_in_executor = self._loop.run_in_executor

        if path is not None:
            # a path
            f = await run_in_executor(None, open, path, 'wb')
            opened_by_us = True
        elif hasattr(output, 'write'):
            # file-like
            f = output
        elif callable(output):
            # assuming calling output returns an awaitable.
            writer = output
        else:
            raise TypeError(
                'output is expected to be a file-like object, '
                'a path-like object or a coroutine function, '
                'not {}'.format(type(output).__name__)
            )

        if writer is None:
            async def _writer(data):
                await run_in_executor(None, f.write, data)
            writer = _writer

        try:
            return await self._protocol.copy_out(copy_stmt, writer, timeout)
        finally:
            if opened_by_us:
                f.close()

    async def _copy_in(self, copy_stmt, source, timeout):
        try:
            path = os.fspath(source)
        except TypeError:
            # source is not a path-like object
            path = None

        f = None
        reader = None
        data = None
        opened_by_us = False
        run_in_executor = self._loop.run_in_executor

        if path is not None:
            # a path
            f = await run_in_executor(None, open, path, 'rb')
            opened_by_us = True
        elif hasattr(source, 'read'):
            # file-like
            f = source
        elif isinstance(source, collections.abc.AsyncIterable):
            # assuming calling output returns an awaitable.
            # copy_in() is designed to handle very large amounts of data, and
            # the source async iterable is allowed to return an arbitrary
            # amount of data on every iteration.
            reader = source
        else:
            # assuming source is an instance supporting the buffer protocol.
            data = source

        if f is not None:
            # Copying from a file-like object.
            class _Reader:
                def __aiter__(self):
                    return self

                async def __anext__(self):
                    data = await run_in_executor(None, f.read, 524288)
                    if len(data) == 0:
                        raise StopAsyncIteration
                    else:
                        return data

            reader = _Reader()

        try:
            return await self._protocol.copy_in(
                copy_stmt, reader, data, None, None, timeout)
        finally:
            if opened_by_us:
                await run_in_executor(None, f.close)

    async def set_type_codec(self, typename, *,
                             schema='public', encoder, decoder,
                             format='text'):
        """Set an encoder/decoder pair for the specified data type.

        :param typename:
            Name of the data type the codec is for.

        :param schema:
            Schema name of the data type the codec is for
            (defaults to ``'public'``)

        :param format:
            The type of the argument received by the *decoder* callback,
            and the type of the *encoder* callback return value.

            If *format* is ``'text'`` (the default), the exchange datum is a
            ``str`` instance containing valid text representation of the
            data type.

            If *format* is ``'binary'``, the exchange datum is a ``bytes``
            instance containing valid _binary_ representation of the
            data type.

            If *format* is ``'tuple'``, the exchange datum is a type-specific
            ``tuple`` of values.  The table below lists supported data
            types and their format for this mode.

            +-----------------+---------------------------------------------+
            |  Type           |                Tuple layout                 |
            +=================+=============================================+
            | ``interval``    | (``months``, ``days``, ``microseconds``)    |
            +-----------------+---------------------------------------------+
            | ``date``        | (``date ordinal relative to Jan 1 2000``,)  |
            |                 | ``-2^31`` for negative infinity timestamp   |
            |                 | ``2^31-1`` for positive infinity timestamp. |
            +-----------------+---------------------------------------------+
            | ``timestamp``   | (``microseconds relative to Jan 1 2000``,)  |
            |                 | ``-2^63`` for negative infinity timestamp   |
            |                 | ``2^63-1`` for positive infinity timestamp. |
            +-----------------+---------------------------------------------+
            | ``timestamp     | (``microseconds relative to Jan 1 2000      |
            | with time zone``| UTC``,)                                     |
            |                 | ``-2^63`` for negative infinity timestamp   |
            |                 | ``2^63-1`` for positive infinity timestamp. |
            +-----------------+---------------------------------------------+
            | ``time``        | (``microseconds``,)                         |
            +-----------------+---------------------------------------------+
            | ``time with     | (``microseconds``,                          |
            | time zone``     | ``time zone offset in seconds``)            |
            +-----------------+---------------------------------------------+
            | any composite   | Composite value elements                    |
            | type            |                                             |
            +-----------------+---------------------------------------------+

        :param encoder:
            Callable accepting a Python object as a single argument and
            returning a value encoded according to *format*.

        :param decoder:
            Callable accepting a single argument encoded according to *format*
            and returning a decoded Python object.

        Example:

        .. code-block:: pycon

            >>> import asyncpg
            >>> import asyncio
            >>> import datetime
            >>> from dateutil.relativedelta import relativedelta
            >>> async def run():
            ...     con = await asyncpg.connect(user='postgres')
            ...     def encoder(delta):
            ...         ndelta = delta.normalized()
            ...         return (ndelta.years * 12 + ndelta.months,
            ...                 ndelta.days,
            ...                 ((ndelta.hours * 3600 +
            ...                    ndelta.minutes * 60 +
            ...                    ndelta.seconds) * 1000000 +
            ...                  ndelta.microseconds))
            ...     def decoder(tup):
            ...         return relativedelta(months=tup[0], days=tup[1],
            ...                              microseconds=tup[2])
            ...     await con.set_type_codec(
            ...         'interval', schema='pg_catalog', encoder=encoder,
            ...         decoder=decoder, format='tuple')
            ...     result = await con.fetchval(
            ...         "SELECT '2 years 3 mons 1 day'::interval")
            ...     print(result)
            ...     print(datetime.datetime(2002, 1, 1) + result)
            ...
            >>> asyncio.run(run())
            relativedelta(years=+2, months=+3, days=+1)
            2004-04-02 00:00:00

        .. versionadded:: 0.12.0
            Added the ``format`` keyword argument and support for 'tuple'
            format.

        .. versionchanged:: 0.12.0
            The ``binary`` keyword argument is deprecated in favor of
            ``format``.

        .. versionchanged:: 0.13.0
            The ``binary`` keyword argument was removed in favor of
            ``format``.

        .. versionchanged:: 0.29.0
            Custom codecs for composite types are now supported with
            ``format='tuple'``.

        .. note::

           It is recommended to use the ``'binary'`` or ``'tuple'`` *format*
           whenever possible and if the underlying type supports it. Asyncpg
           currently does not support text I/O for composite and range types,
           and some other functionality, such as
           :meth:`Connection.copy_to_table`, does not support types with text
           codecs.
        """
        self._check_open()
        settings = self._protocol.get_settings()
        typeinfo = await self._introspect_type(typename, schema)
        full_typeinfos = []
        if introspection.is_scalar_type(typeinfo):
            kind = 'scalar'
        elif introspection.is_composite_type(typeinfo):
            if format != 'tuple':
                raise exceptions.UnsupportedClientFeatureError(
                    'only tuple-format codecs can be used on composite types',
                    hint="Use `set_type_codec(..., format='tuple')` and "
                         "pass/interpret data as a Python tuple.  See an "
                         "example at https://magicstack.github.io/asyncpg/"
                         "current/usage.html#example-decoding-complex-types",
                )
            kind = 'composite'
            full_typeinfos, _ = await self._introspect_types(
                (typeinfo['oid'],), 10)
        else:
            raise exceptions.InterfaceError(
                f'cannot use custom codec on type {schema}.{typename}: '
                f'it is neither a scalar type nor a composite type'
            )
        if introspection.is_domain_type(typeinfo):
            raise exceptions.UnsupportedClientFeatureError(
                'custom codecs on domain types are not supported',
                hint='Set the codec on the base type.',
                detail=(
                    'PostgreSQL does not distinguish domains from '
                    'their base types in query results at the protocol level.'
                )
            )

        oid = typeinfo['oid']
        settings.add_python_codec(
            oid, typename, schema, full_typeinfos, kind,
            encoder, decoder, format)

        # Statement cache is no longer valid due to codec changes.
        self._drop_local_statement_cache()

    async def reset_type_codec(self, typename, *, schema='public'):
        """Reset *typename* codec to the default implementation.

        :param typename:
            Name of the data type the codec is for.

        :param schema:
            Schema name of the data type the codec is for
            (defaults to ``'public'``)

        .. versionadded:: 0.12.0
        """

        typeinfo = await self._introspect_type(typename, schema)
        self._protocol.get_settings().remove_python_codec(
            typeinfo['oid'], typename, schema)

        # Statement cache is no longer valid due to codec changes.
        self._drop_local_statement_cache()

    async def set_builtin_type_codec(self, typename, *,
                                     schema='public', codec_name,
                                     format=None):
        """Set a builtin codec for the specified scalar data type.

        This method has two uses.  The first is to register a builtin
        codec for an extension type without a stable OID, such as 'hstore'.
        The second use is to declare that an extension type or a
        user-defined type is wire-compatible with a certain builtin
        data type and should be exchanged as such.

        :param typename:
            Name of the data type the codec is for.

        :param schema:
            Schema name of the data type the codec is for
            (defaults to ``'public'``).

        :param codec_name:
            The name of the builtin codec to use for the type.
            This should be either the name of a known core type
            (such as ``"int"``), or the name of a supported extension
            type.  Currently, the only supported extension type is
            ``"pg_contrib.hstore"``.

        :param format:
            If *format* is ``None`` (the default), all formats supported
            by the target codec are declared to be supported for *typename*.
            If *format* is ``'text'`` or ``'binary'``, then only the
            specified format is declared to be supported for *typename*.

        .. versionchanged:: 0.18.0
            The *codec_name* argument can be the name of any known
            core data type.  Added the *format* keyword argument.
        """
        self._check_open()
        typeinfo = await self._introspect_type(typename, schema)
        if not introspection.is_scalar_type(typeinfo):
            raise exceptions.InterfaceError(
                'cannot alias non-scalar type {}.{}'.format(
                    schema, typename))

        oid = typeinfo['oid']

        self._protocol.get_settings().set_builtin_type_codec(
            oid, typename, schema, 'scalar', codec_name, format)

        # Statement cache is no longer valid due to codec changes.
        self._drop_local_statement_cache()

    def is_closed(self):
        """Return ``True`` if the connection is closed, ``False`` otherwise.

        :return bool: ``True`` if the connection is closed, ``False``
                      otherwise.
        """
        return self._aborted or not self._protocol.is_connected()

    async def close(self, *, timeout=None):
        """Close the connection gracefully.

        :param float timeout:
            Optional timeout value in seconds.

        .. versionchanged:: 0.14.0
           Added the *timeout* parameter.
        """
        try:
            if not self.is_closed():
                await self._protocol.close(timeout)
        except (Exception, asyncio.CancelledError):
            # If we fail to close gracefully, abort the connection.
            self._abort()
            raise
        finally:
            self._cleanup()

    def terminate(self):
        """Terminate the connection without waiting for pending data."""
        if not self.is_closed():
            self._abort()
        self._cleanup()

    async def _reset(self):
        self._check_open()
        self._listeners.clear()
        self._log_listeners.clear()

        if self._protocol.is_in_transaction() or self._top_xact is not None:
            if self._top_xact is None or not self._top_xact._managed:
                # Managed transactions are guaranteed to __aexit__
                # correctly.
                self._loop.call_exception_handler({
                    'message': 'Resetting connection with an '
                               'active transaction {!r}'.format(self)
                })

            self._top_xact = None
            await self.execute("ROLLBACK")

    async def reset(self, *, timeout=None):
        """Reset the connection state.

        Calling this will reset the connection session state to a state
        resembling that of a newly obtained connection.  Namely, an open
        transaction (if any) is rolled back, open cursors are closed,
        all `LISTEN <https://www.postgresql.org/docs/current/sql-listen.html>`_
        registrations are removed, all session configuration
        variables are reset to their default values, and all advisory locks
        are released.

        Note that the above describes the default query returned by
        :meth:`Connection.get_reset_query`.  If one overloads the method
        by subclassing ``Connection``, then this method will do whatever
        the overloaded method returns, except open transactions are always
        terminated and any callbacks registered by
        :meth:`Connection.add_listener` or :meth:`Connection.add_log_listener`
        are removed.

        :param float timeout:
            A timeout for resetting the connection.  If not specified, defaults
            to no timeout.
        """
        async with compat.timeout(timeout):
            await self._reset()
            reset_query = self.get_reset_query()
            if reset_query:
                await self.execute(reset_query)

    def _abort(self):
        # Put the connection into the aborted state.
        self._aborted = True
        self._protocol.abort()
        self._protocol = None

    def _cleanup(self):
        self._call_termination_listeners()
        # Free the resources associated with this connection.
        # This must be called when a connection is terminated.

        if self._proxy is not None:
            # Connection is a member of a pool, so let the pool
            # know that this connection is dead.
            self._proxy._holder._release_on_close()

        self._mark_stmts_as_closed()
        self._listeners.clear()
        self._log_listeners.clear()
        self._query_loggers.clear()
        self._clean_tasks()

    def _clean_tasks(self):
        # Wrap-up any remaining tasks associated with this connection.
        if self._cancellations:
            for fut in self._cancellations:
                if not fut.done():
                    fut.cancel()
            self._cancellations.clear()

    def _check_open(self):
        if self.is_closed():
            raise exceptions.InterfaceError('connection is closed')

    def _get_unique_id(self, prefix):
        global _uid
        _uid += 1
        return '__asyncpg_{}_{:x}__'.format(prefix, _uid)

    def _mark_stmts_as_closed(self):
        for stmt in self._stmt_cache.iter_statements():
            stmt.mark_closed()

        for stmt in self._stmts_to_close:
            stmt.mark_closed()

        self._stmt_cache.clear()
        self._stmts_to_close.clear()

    def _maybe_gc_stmt(self, stmt):
        if (
            stmt.refs == 0
            and stmt.name
            and not self._stmt_cache.has(
                (stmt.query, stmt.record_class, stmt.ignore_custom_codec)
            )
        ):
            # If low-level `stmt` isn't referenced from any high-level
            # `PreparedStatement` object and is not in the `_stmt_cache`:
            #
            #  * mark it as closed, which will make it non-usable
            #    for any `PreparedStatement` or for methods like
            #    `Connection.fetch()`.
            #
            # * schedule it to be formally closed on the server.
            stmt.mark_closed()
            self._stmts_to_close.add(stmt)

    async def _cleanup_stmts(self):
        # Called whenever we create a new prepared statement in
        # `Connection._get_statement()` and `_stmts_to_close` is
        # not empty.
        to_close = self._stmts_to_close
        self._stmts_to_close = set()
        for stmt in to_close:
            # It is imperative that statements are cleaned properly,
            # so we ignore the timeout.
            await self._protocol.close_statement(stmt, protocol.NO_TIMEOUT)

    async def _cancel(self, waiter):
        try:
            # Open new connection to the server
            await connect_utils._cancel(
                loop=self._loop, addr=self._addr, params=self._params,
                backend_pid=self._protocol.backend_pid,
                backend_secret=self._protocol.backend_secret)
        except ConnectionResetError as ex:
            # On some systems Postgres will reset the connection
            # after processing the cancellation command.
            if not waiter.done():
                waiter.set_exception(ex)
        except asyncio.CancelledError:
            # There are two scenarios in which the cancellation
            # itself will be cancelled: 1) the connection is being closed,
            # 2) the event loop is being shut down.
            # In either case we do not care about the propagation of
            # the CancelledError, and don't want the loop to warn about
            # an unretrieved exception.
            pass
        except (Exception, asyncio.CancelledError) as ex:
            if not waiter.done():
                waiter.set_exception(ex)
        finally:
            self._cancellations.discard(
                asyncio.current_task(self._loop))
            if not waiter.done():
                waiter.set_result(None)

    def _cancel_current_command(self, waiter):
        self._cancellations.add(self._loop.create_task(self._cancel(waiter)))

    def _process_log_message(self, fields, last_query):
        if not self._log_listeners:
            return

        message = exceptions.PostgresLogMessage.new(fields, query=last_query)

        con_ref = self._unwrap()
        for cb in self._log_listeners:
            if cb.is_async:
                self._loop.create_task(cb.cb(con_ref, message))
            else:
                self._loop.call_soon(cb.cb, con_ref, message)

    def _call_termination_listeners(self):
        if not self._termination_listeners:
            return

        con_ref = self._unwrap()
        for cb in self._ter
Download .txt
gitextract_qed7mic1/

├── .clang-format
├── .clangd
├── .flake8
├── .github/
│   ├── ISSUE_TEMPLATE.md
│   ├── RELEASING.rst
│   ├── release_log.py
│   └── workflows/
│       ├── install-krb5.sh
│       ├── install-postgres.sh
│       ├── release.yml
│       └── tests.yml
├── .gitignore
├── .gitmodules
├── AUTHORS
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.rst
├── asyncpg/
│   ├── .gitignore
│   ├── __init__.py
│   ├── _asyncio_compat.py
│   ├── _testbase/
│   │   ├── __init__.py
│   │   └── fuzzer.py
│   ├── _version.py
│   ├── cluster.py
│   ├── compat.py
│   ├── connect_utils.py
│   ├── connection.py
│   ├── connresource.py
│   ├── cursor.py
│   ├── exceptions/
│   │   ├── __init__.py
│   │   └── _base.py
│   ├── introspection.py
│   ├── pool.py
│   ├── prepared_stmt.py
│   ├── protocol/
│   │   ├── .gitignore
│   │   ├── __init__.py
│   │   ├── codecs/
│   │   │   ├── __init__.py
│   │   │   ├── array.pyx
│   │   │   ├── base.pxd
│   │   │   ├── base.pyx
│   │   │   ├── pgproto.pyx
│   │   │   ├── range.pyx
│   │   │   ├── record.pyx
│   │   │   └── textutils.pyx
│   │   ├── consts.pxi
│   │   ├── coreproto.pxd
│   │   ├── coreproto.pyx
│   │   ├── cpythonx.pxd
│   │   ├── encodings.pyx
│   │   ├── pgtypes.pxi
│   │   ├── prepared_stmt.pxd
│   │   ├── prepared_stmt.pyx
│   │   ├── protocol.pxd
│   │   ├── protocol.pyi
│   │   ├── protocol.pyx
│   │   ├── record/
│   │   │   ├── pythoncapi_compat.h
│   │   │   ├── pythoncapi_compat_extras.h
│   │   │   ├── recordobj.c
│   │   │   └── recordobj.h
│   │   ├── record.pyi
│   │   ├── recordcapi.pxd
│   │   ├── scram.pxd
│   │   ├── scram.pyx
│   │   ├── settings.pxd
│   │   └── settings.pyx
│   ├── serverversion.py
│   ├── transaction.py
│   ├── types.py
│   └── utils.py
├── docs/
│   ├── .gitignore
│   ├── Makefile
│   ├── _static/
│   │   └── theme_overrides.css
│   ├── api/
│   │   └── index.rst
│   ├── conf.py
│   ├── faq.rst
│   ├── index.rst
│   ├── installation.rst
│   ├── requirements.txt
│   └── usage.rst
├── pyproject.toml
├── setup.py
├── tests/
│   ├── __init__.py
│   ├── certs/
│   │   ├── ca.cert.pem
│   │   ├── ca.crl.pem
│   │   ├── ca.key.pem
│   │   ├── client.cert.pem
│   │   ├── client.csr.pem
│   │   ├── client.key.pem
│   │   ├── client.key.protected.pem
│   │   ├── client_ca.cert.pem
│   │   ├── client_ca.cert.srl
│   │   ├── client_ca.key.pem
│   │   ├── gen.py
│   │   ├── server.cert.pem
│   │   ├── server.crl.pem
│   │   └── server.key.pem
│   ├── test__environment.py
│   ├── test__sourcecode.py
│   ├── test_adversity.py
│   ├── test_cache_invalidation.py
│   ├── test_cancellation.py
│   ├── test_codecs.py
│   ├── test_connect.py
│   ├── test_copy.py
│   ├── test_cursor.py
│   ├── test_exceptions.py
│   ├── test_execute.py
│   ├── test_introspection.py
│   ├── test_listeners.py
│   ├── test_logging.py
│   ├── test_pool.py
│   ├── test_prepare.py
│   ├── test_record.py
│   ├── test_subinterpreters.py
│   ├── test_test.py
│   ├── test_timeout.py
│   ├── test_transaction.py
│   ├── test_types.py
│   └── test_utils.py
└── tools/
    ├── generate_exceptions.py
    └── generate_type_map.py
Download .txt
SYMBOL INDEX (1440 symbols across 53 files)

FILE: .github/release_log.py
  function main (line 19) | def main():

FILE: asyncpg/_asyncio_compat.py
  function wait_for (line 25) | async def wait_for(fut: compat.Awaitable[_T], timeout: float | None) -> _T:
  function _cancel_and_wait (line 75) | async def _cancel_and_wait(fut: asyncio.Future[_T]) -> None:
  function _release_waiter (line 92) | def _release_waiter(waiter: asyncio.Future[typing.Any], *args: object) -...

FILE: asyncpg/_testbase/__init__.py
  function silence_asyncio_long_exec_warning (line 31) | def silence_asyncio_long_exec_warning():
  function with_timeout (line 44) | def with_timeout(timeout):
  class TestCaseMeta (line 52) | class TestCaseMeta(type(unittest.TestCase)):
    method _iter_methods (line 56) | def _iter_methods(bases, ns):
    method __new__ (line 77) | def __new__(mcls, name, bases, ns):
  class TestCase (line 98) | class TestCase(unittest.TestCase, metaclass=TestCaseMeta):
    method setUpClass (line 101) | def setUpClass(cls):
    method tearDownClass (line 111) | def tearDownClass(cls):
    method setUp (line 115) | def setUp(self):
    method tearDown (line 119) | def tearDown(self):
    method assertRunUnder (line 143) | def assertRunUnder(self, delta):
    method assertLoopErrorHandlerCalled (line 156) | def assertLoopErrorHandlerCalled(self, msg_re: str):
    method loop_exception_handler (line 179) | def loop_exception_handler(self, loop, context):
    method _format_loop_exception (line 183) | def _format_loop_exception(self, context, n):
  function _init_cluster (line 221) | def _init_cluster(ClusterCls, cluster_kwargs, initdb_options=None):
  function _get_initdb_options (line 229) | def _get_initdb_options(initdb_options=None):
  function _init_default_cluster (line 242) | def _init_default_cluster(initdb_options=None):
  function _shutdown_cluster (line 262) | def _shutdown_cluster(cluster):
  function create_pool (line 269) | def create_pool(dsn=None, *,
  class ClusterTestCase (line 298) | class ClusterTestCase(TestCase):
    method get_server_settings (line 300) | def get_server_settings(cls):
    method new_cluster (line 313) | def new_cluster(cls, ClusterCls, *, cluster_kwargs={}, initdb_options=...
    method start_cluster (line 320) | def start_cluster(cls, cluster, *, server_settings={}):
    method setup_cluster (line 324) | def setup_cluster(cls):
    method setUpClass (line 332) | def setUpClass(cls):
    method tearDownClass (line 338) | def tearDownClass(cls):
    method get_connection_spec (line 347) | def get_connection_spec(cls, kwargs={}):
    method connect (line 360) | def connect(cls, **kwargs):
    method setUp (line 364) | def setUp(self):
    method tearDown (line 368) | def tearDown(self):
    method create_pool (line 374) | def create_pool(self, pool_class=pg_pool.Pool,
  class ProxiedClusterTestCase (line 383) | class ProxiedClusterTestCase(ClusterTestCase):
    method get_server_settings (line 385) | def get_server_settings(cls):
    method get_proxy_settings (line 391) | def get_proxy_settings(cls):
    method setUpClass (line 395) | def setUpClass(cls):
    method tearDownClass (line 410) | def tearDownClass(cls):
    method get_connection_spec (line 415) | def get_connection_spec(cls, kwargs):
    method tearDown (line 421) | def tearDown(self):
  function with_connection_options (line 426) | def with_connection_options(**options):
  class ConnectedTestCase (line 437) | class ConnectedTestCase(ClusterTestCase):
    method setUp (line 439) | def setUp(self):
    method tearDown (line 448) | def tearDown(self):
  class HotStandbyTestCase (line 456) | class HotStandbyTestCase(ClusterTestCase):
    method setup_cluster (line 459) | def setup_cluster(cls):
    method get_cluster_connection_spec (line 504) | def get_cluster_connection_spec(cls, cluster, kwargs={}):
    method get_connection_spec (line 517) | def get_connection_spec(cls, kwargs={}):
    method connect_primary (line 533) | def connect_primary(cls, **kwargs):
    method connect_standby (line 538) | def connect_standby(cls, **kwargs):

FILE: asyncpg/_testbase/fuzzer.py
  class StopServer (line 16) | class StopServer(Exception):
  class TCPFuzzingProxy (line 20) | class TCPFuzzingProxy:
    method __init__ (line 21) | def __init__(self, *, listening_addr: str='127.0.0.1',
    method _wait (line 38) | async def _wait(self, work):
    method start (line 57) | def start(self):
    method stop (line 65) | def stop(self):
    method _stop (line 69) | def _stop(self):
    method _start_thread (line 72) | def _start_thread(self, started_event):
    method _main (line 94) | async def _main(self, started_event):
    method listen (line 108) | async def listen(self):
    method trigger_connectivity_loss (line 126) | def trigger_connectivity_loss(self):
    method _trigger_connectivity_loss (line 129) | def _trigger_connectivity_loss(self):
    method restore_connectivity (line 133) | def restore_connectivity(self):
    method _restore_connectivity (line 136) | def _restore_connectivity(self):
    method reset (line 140) | def reset(self):
    method _close_connection (line 143) | def _close_connection(self, connection):
    method close_all_connections (line 148) | def close_all_connections(self):
  class Connection (line 153) | class Connection:
    method __init__ (line 154) | def __init__(self, client_sock, backend_sock, proxy):
    method close (line 165) | def close(self):
    method handle (line 181) | async def handle(self):
    method _read (line 212) | async def _read(self, sock, n):
    method _write (line 234) | async def _write(self, sock, data):
    method proxy_to_backend (line 256) | async def proxy_to_backend(self):
    method proxy_from_backend (line 282) | async def proxy_from_backend(self):

FILE: asyncpg/cluster.py
  function platform_exe (line 30) | def platform_exe(name):
  function platform_exe (line 35) | def platform_exe(name):
  function find_available_port (line 39) | def find_available_port():
  function _world_readable_mkdtemp (line 50) | def _world_readable_mkdtemp(suffix=None, prefix=None, dir=None):
  function _mkdtemp (line 63) | def _mkdtemp(suffix=None, prefix=None, dir=None):
  class ClusterError (line 73) | class ClusterError(Exception):
  class Cluster (line 77) | class Cluster:
    method __init__ (line 78) | def __init__(self, data_dir, *, pg_config_path=None):
    method get_pg_version (line 91) | def get_pg_version(self):
    method is_managed (line 94) | def is_managed(self):
    method get_data_dir (line 97) | def get_data_dir(self):
    method get_status (line 100) | def get_status(self):
    method connect (line 127) | async def connect(self, loop=None, **kwargs):
    method init (line 132) | def init(self, **settings):
    method start (line 167) | def start(self, wait=60, *, server_settings={}, **opts):
    method reload (line 262) | def reload(self):
    method stop (line 282) | def stop(self, wait=60):
    method destroy (line 302) | def destroy(self):
    method _get_connection_spec (line 309) | def _get_connection_spec(self):
    method get_connection_spec (line 321) | def get_connection_spec(self):
    method override_connection_spec (line 328) | def override_connection_spec(self, **kwargs):
    method reset_wal (line 331) | def reset_wal(self, *, oid=None, xid=None):
    method reset_hba (line 367) | def reset_hba(self):
    method add_hba_entry (line 383) | def add_hba_entry(self, *, type='host', database, user, address=None,
    method trust_local_connections (line 418) | def trust_local_connections(self):
    method trust_local_replication_by (line 434) | def trust_local_replication_by(self, user):
    method _init_env (line 448) | def _init_env(self):
    method _connection_addr_from_pidfile (line 462) | def _connection_addr_from_pidfile(self):
    method _test_connection (line 508) | def _test_connection(self, timeout=60):
    method _run_pg_config (line 545) | def _run_pg_config(self, pg_config_path):
    method _find_pg_config (line 563) | def _find_pg_config(self, pg_config_path):
    method _find_pg_binary (line 591) | def _find_pg_binary(self, binary):
    method _get_pg_version (line 601) | def _get_pg_version(self):
  class TempCluster (line 623) | class TempCluster(Cluster):
    method __init__ (line 624) | def __init__(self, *,
  class HotStandbyCluster (line 633) | class HotStandbyCluster(TempCluster):
    method __init__ (line 634) | def __init__(self, *,
    method _init_env (line 646) | def _init_env(self):
    method init (line 650) | def init(self, **settings):
    method start (line 685) | def start(self, wait=60, *, server_settings={}, **opts):
  class RunningCluster (line 699) | class RunningCluster(Cluster):
    method __init__ (line 700) | def __init__(self, **kwargs):
    method is_managed (line 703) | def is_managed(self):
    method get_connection_spec (line 706) | def get_connection_spec(self):
    method get_status (line 709) | def get_status(self):
    method init (line 712) | def init(self, **settings):
    method start (line 715) | def start(self, wait=60, **settings):
    method stop (line 718) | def stop(self, wait=60):
    method destroy (line 721) | def destroy(self):
    method reset_hba (line 724) | def reset_hba(self):
    method add_hba_entry (line 727) | def add_hba_entry(self, *, type='host', database, user, address=None,

FILE: asyncpg/compat.py
  function get_pg_home_directory (line 26) | def get_pg_home_directory() -> pathlib.Path | None:
  function get_pg_home_directory (line 38) | def get_pg_home_directory() -> pathlib.Path | None:
  function wait_closed (line 45) | async def wait_closed(stream: asyncio.StreamWriter) -> None:
  function markcoroutinefunction (line 57) | def markcoroutinefunction(c):  # type: ignore
  class StrEnum (line 84) | class StrEnum(str, enum.Enum):

FILE: asyncpg/connect_utils.py
  class SSLMode (line 36) | class SSLMode(enum.IntEnum):
    method parse (line 45) | def parse(cls, sslmode):
  class SSLNegotiation (line 51) | class SSLNegotiation(compat.StrEnum):
  function _read_password_file (line 94) | def _read_password_file(passfile: pathlib.Path) \
  function _read_password_from_pgpass (line 137) | def _read_password_from_pgpass(
  function _validate_port_spec (line 174) | def _validate_port_spec(hosts, port):
  function _parse_hostlist (line 190) | def _parse_hostlist(hostlist, port, *, unquote=False):
  function _parse_tls_version (line 254) | def _parse_tls_version(tls_version):
  function _dot_postgresql_path (line 267) | def _dot_postgresql_path(filename) -> typing.Optional[pathlib.Path]:
  function _parse_connect_dsn_and_args (line 276) | def _parse_connect_dsn_and_args(*, dsn, host, port, user,
  function _parse_connect_arguments (line 862) | def _parse_connect_arguments(*, dsn, host, port, user, password, passfile,
  class TLSUpgradeProto (line 911) | class TLSUpgradeProto(asyncio.Protocol):
    method __init__ (line 912) | def __init__(
    method data_received (line 926) | def data_received(self, data: bytes) -> None:
    method connection_lost (line 944) | def connection_lost(self, exc: typing.Optional[Exception]) -> None:
  function _create_ssl_connection (line 956) | async def _create_ssl_connection(
  function _connect_addr (line 1022) | async def _connect_addr(
  class _RetryConnectSignal (line 1062) | class _RetryConnectSignal(Exception):
  function __connect_addr (line 1066) | async def __connect_addr(
  class SessionAttribute (line 1141) | class SessionAttribute(str, enum.Enum):
  function _accept_in_hot_standby (line 1150) | def _accept_in_hot_standby(should_be_in_hot_standby: bool):
  function _accept_read_only (line 1171) | def _accept_read_only(should_be_read_only: bool):
  function _accept_any (line 1186) | async def _accept_any(_):
  function _can_use_connection (line 1200) | async def _can_use_connection(connection, attr: SessionAttribute):
  function _connect (line 1205) | async def _connect(*, loop, connection_class, record_class, **kwargs):
  function _cancel (line 1255) | async def _cancel(*, loop, addr, params: _ConnectionParameters,
  function _get_socket (line 1293) | def _get_socket(transport):
  function _set_nodelay (line 1302) | def _set_nodelay(sock):
  function _create_future (line 1307) | def _create_future(loop):

FILE: asyncpg/connection.py
  class ConnectionMeta (line 36) | class ConnectionMeta(type):
    method __instancecheck__ (line 38) | def __instancecheck__(cls, instance):
  class Connection (line 43) | class Connection(metaclass=ConnectionMeta):
    method __init__ (line 59) | def __init__(self, protocol, transport, loop,
    method __del__ (line 123) | def __del__(self):
    method add_listener (line 139) | async def add_listener(self, channel, callback):
    method remove_listener (line 161) | async def remove_listener(self, channel, callback):
    method add_log_listener (line 175) | def add_log_listener(self, callback):
    method remove_log_listener (line 197) | def remove_log_listener(self, callback):
    method add_termination_listener (line 204) | def add_termination_listener(self, callback):
    method remove_termination_listener (line 218) | def remove_termination_listener(self, callback):
    method add_query_logger (line 229) | def add_query_logger(self, callback):
    method remove_query_logger (line 241) | def remove_query_logger(self, callback):
    method get_server_pid (line 252) | def get_server_pid(self):
    method get_server_version (line 256) | def get_server_version(self):
    method get_settings (line 272) | def get_settings(self):
    method transaction (line 279) | def transaction(self, *, isolation=None, readonly=False,
    method is_in_transaction (line 305) | def is_in_transaction(self):
    method execute (line 314) | async def execute(
    method executemany (line 366) | async def executemany(
    method _get_statement (line 403) | async def _get_statement(
    method _introspect_types (line 505) | async def _introspect_types(self, typeoids, timeout):
    method _introspect_type (line 547) | async def _introspect_type(self, typename, schema):
    method cursor (line 567) | def cursor(
    method prepare (line 606) | async def prepare(
    method _prepare (line 645) | async def _prepare(
    method fetch (line 666) | async def fetch(
    method fetchval (line 702) | async def fetchval(self, query, *args, column=0, timeout=None):
    method fetchrow (line 723) | async def fetchrow(
    method fetchmany (line 763) | async def fetchmany(
    method copy_from_table (line 806) | async def copy_from_table(self, table_name, *, output,
    method copy_from_query (line 878) | async def copy_from_query(self, query, *args, output,
    method copy_to_table (line 940) | async def copy_to_table(self, table_name, *, source,
    method copy_records_to_table (line 1028) | async def copy_records_to_table(self, table_name, *, records,
    method _format_copy_where (line 1130) | def _format_copy_where(self, where):
    method _format_copy_opts (line 1142) | def _format_copy_opts(self, *, format=None, oids=None, freeze=None,
    method _copy_out (line 1171) | async def _copy_out(self, copy_stmt, output, timeout):
    method _copy_in (line 1210) | async def _copy_in(self, copy_stmt, source, timeout):
    method set_type_codec (line 1262) | async def set_type_codec(self, typename, *,
    method reset_type_codec (line 1424) | async def reset_type_codec(self, typename, *, schema='public'):
    method set_builtin_type_codec (line 1444) | async def set_builtin_type_codec(self, typename, *,
    method is_closed (line 1494) | def is_closed(self):
    method close (line 1502) | async def close(self, *, timeout=None):
    method terminate (line 1521) | def terminate(self):
    method _reset (line 1527) | async def _reset(self):
    method reset (line 1544) | async def reset(self, *, timeout=None):
    method _abort (line 1573) | def _abort(self):
    method _cleanup (line 1579) | def _cleanup(self):
    method _clean_tasks (line 1595) | def _clean_tasks(self):
    method _check_open (line 1603) | def _check_open(self):
    method _get_unique_id (line 1607) | def _get_unique_id(self, prefix):
    method _mark_stmts_as_closed (line 1612) | def _mark_stmts_as_closed(self):
    method _maybe_gc_stmt (line 1622) | def _maybe_gc_stmt(self, stmt):
    method _cleanup_stmts (line 1641) | async def _cleanup_stmts(self):
    method _cancel (line 1652) | async def _cancel(self, waiter):
    method _cancel_current_command (line 1681) | def _cancel_current_command(self, waiter):
    method _process_log_message (line 1684) | def _process_log_message(self, fields, last_query):
    method _call_termination_listeners (line 1697) | def _call_termination_listeners(self):
    method _process_notification (line 1710) | def _process_notification(self, pid, channel, payload):
    method _unwrap (line 1721) | def _unwrap(self):
    method get_reset_query (line 1732) | def get_reset_query(self):
    method _set_proxy (line 1761) | def _set_proxy(self, proxy):
    method _check_listeners (line 1769) | def _check_listeners(self, listeners, listener_type):
    method _on_release (line 1781) | def _on_release(self, stacklevel=1):
    method _drop_local_statement_cache (line 1792) | def _drop_local_statement_cache(self):
    method _drop_global_statement_cache (line 1795) | def _drop_global_statement_cache(self):
    method _drop_local_type_cache (line 1804) | def _drop_local_type_cache(self):
    method _drop_global_type_cache (line 1807) | def _drop_global_type_cache(self):
    method reload_schema_state (line 1816) | async def reload_schema_state(self):
    method _execute (line 1861) | async def _execute(
    method query_logger (line 1885) | def query_logger(self, callback):
    method _time_and_log (line 1915) | def _time_and_log(self, query, args, timeout):
    method __execute (line 1940) | async def __execute(
    method _executemany (line 1979) | async def _executemany(
    method _do_execute (line 2002) | async def _do_execute(
  function connect (line 2083) | async def connect(dsn=None, *,
  class _StatementCacheEntry (line 2469) | class _StatementCacheEntry:
    method __init__ (line 2473) | def __init__(self, cache, query, statement):
  class _StatementCache (line 2480) | class _StatementCache:
    method __init__ (line 2485) | def __init__(self, *, loop, max_size, on_remove, max_lifetime):
    method __len__ (line 2510) | def __len__(self):
    method get_max_size (line 2513) | def get_max_size(self):
    method set_max_size (line 2516) | def set_max_size(self, new_size):
    method get_max_lifetime (line 2521) | def get_max_lifetime(self):
    method set_max_lifetime (line 2524) | def set_max_lifetime(self, new_lifetime):
    method get (line 2532) | def get(self, query, *, promote=True):
    method has (line 2555) | def has(self, query):
    method put (line 2558) | def put(self, query, statement):
    method iter_statements (line 2569) | def iter_statements(self):
    method clear (line 2572) | def clear(self):
    method _set_entry_timeout (line 2585) | def _set_entry_timeout(self, entry):
    method _new_entry (line 2594) | def _new_entry(self, query, statement):
    method _on_entry_expired (line 2599) | def _on_entry_expired(self, entry):
    method _clear_entry_callback (line 2606) | def _clear_entry_callback(self, entry):
    method _maybe_cleanup (line 2610) | def _maybe_cleanup(self):
  class _Callback (line 2621) | class _Callback(typing.NamedTuple):
    method from_callable (line 2627) | def from_callable(cls, cb: typing.Callable[..., None]) -> '_Callback':
  class _Atomic (line 2641) | class _Atomic:
    method __init__ (line 2644) | def __init__(self):
    method __enter__ (line 2647) | def __enter__(self):
    method __exit__ (line 2653) | def __exit__(self, t, e, tb):
  class _ConnectionProxy (line 2657) | class _ConnectionProxy:
  function _detect_server_capabilities (line 2676) | def _detect_server_capabilities(server_version, connection_settings):
  function _extract_stack (line 2725) | def _extract_stack(limit=10):
  function _check_record_class (line 2746) | def _check_record_class(record_class):
  function _weak_maybe_gc_stmt (line 2767) | def _weak_maybe_gc_stmt(weak_ref, stmt):

FILE: asyncpg/connresource.py
  function guarded (line 14) | def guarded(meth):
  class ConnectionResource (line 25) | class ConnectionResource:
    method __init__ (line 28) | def __init__(self, connection):
    method _check_conn_validity (line 32) | def _check_conn_validity(self, meth_name):

FILE: asyncpg/cursor.py
  class CursorFactory (line 14) | class CursorFactory(connresource.ConnectionResource):
    method __init__ (line 30) | def __init__(
    method __aiter__ (line 51) | def __aiter__(self):
    method __await__ (line 64) | def __await__(self):
    method __del__ (line 77) | def __del__(self):
  class BaseCursor (line 83) | class BaseCursor(connresource.ConnectionResource):
    method __init__ (line 94) | def __init__(self, connection, query, state, args, record_class):
    method _check_ready (line 105) | def _check_ready(self):
    method _bind_exec (line 118) | async def _bind_exec(self, n, timeout):
    method _bind (line 133) | async def _bind(self, timeout):
    method _exec (line 149) | async def _exec(self, n, timeout):
    method _close_portal (line 161) | async def _close_portal(self, timeout):
    method __repr__ (line 172) | def __repr__(self):
    method __del__ (line 188) | def __del__(self):
  class CursorIterator (line 194) | class CursorIterator(BaseCursor):
    method __init__ (line 198) | def __init__(
    method __aiter__ (line 219) | def __aiter__(self):
    method __anext__ (line 223) | async def __anext__(self):
  class Cursor (line 250) | class Cursor(BaseCursor):
    method _init (line 255) | async def _init(self, timeout):
    method fetch (line 269) | async def fetch(self, n, *, timeout=None):
    method fetchrow (line 287) | async def fetchrow(self, *, timeout=None):
    method forward (line 304) | async def forward(self, n, *, timeout=None) -> int:

FILE: asyncpg/exceptions/__init__.py
  class PostgresWarning (line 8) | class PostgresWarning(_base.PostgresLogMessage, Warning):
  class DynamicResultSetsReturned (line 12) | class DynamicResultSetsReturned(PostgresWarning):
  class ImplicitZeroBitPadding (line 16) | class ImplicitZeroBitPadding(PostgresWarning):
  class NullValueEliminatedInSetFunction (line 20) | class NullValueEliminatedInSetFunction(PostgresWarning):
  class PrivilegeNotGranted (line 24) | class PrivilegeNotGranted(PostgresWarning):
  class PrivilegeNotRevoked (line 28) | class PrivilegeNotRevoked(PostgresWarning):
  class StringDataRightTruncation (line 32) | class StringDataRightTruncation(PostgresWarning):
  class DeprecatedFeature (line 36) | class DeprecatedFeature(PostgresWarning):
  class NoData (line 40) | class NoData(PostgresWarning):
  class NoAdditionalDynamicResultSetsReturned (line 44) | class NoAdditionalDynamicResultSetsReturned(NoData):
  class SQLStatementNotYetCompleteError (line 48) | class SQLStatementNotYetCompleteError(_base.PostgresError):
  class PostgresConnectionError (line 52) | class PostgresConnectionError(_base.PostgresError):
  class ConnectionDoesNotExistError (line 56) | class ConnectionDoesNotExistError(PostgresConnectionError):
  class ConnectionFailureError (line 60) | class ConnectionFailureError(PostgresConnectionError):
  class ClientCannotConnectError (line 64) | class ClientCannotConnectError(PostgresConnectionError):
  class ConnectionRejectionError (line 68) | class ConnectionRejectionError(PostgresConnectionError):
  class TransactionResolutionUnknownError (line 72) | class TransactionResolutionUnknownError(PostgresConnectionError):
  class ProtocolViolationError (line 76) | class ProtocolViolationError(PostgresConnectionError):
  class TriggeredActionError (line 80) | class TriggeredActionError(_base.PostgresError):
  class FeatureNotSupportedError (line 84) | class FeatureNotSupportedError(_base.PostgresError):
  class InvalidCachedStatementError (line 88) | class InvalidCachedStatementError(FeatureNotSupportedError):
  class InvalidTransactionInitiationError (line 92) | class InvalidTransactionInitiationError(_base.PostgresError):
  class LocatorError (line 96) | class LocatorError(_base.PostgresError):
  class InvalidLocatorSpecificationError (line 100) | class InvalidLocatorSpecificationError(LocatorError):
  class InvalidGrantorError (line 104) | class InvalidGrantorError(_base.PostgresError):
  class InvalidGrantOperationError (line 108) | class InvalidGrantOperationError(InvalidGrantorError):
  class InvalidRoleSpecificationError (line 112) | class InvalidRoleSpecificationError(_base.PostgresError):
  class DiagnosticsError (line 116) | class DiagnosticsError(_base.PostgresError):
  class StackedDiagnosticsAccessedWithoutActiveHandlerError (line 120) | class StackedDiagnosticsAccessedWithoutActiveHandlerError(DiagnosticsErr...
  class InvalidArgumentForXqueryError (line 124) | class InvalidArgumentForXqueryError(_base.PostgresError):
  class CaseNotFoundError (line 128) | class CaseNotFoundError(_base.PostgresError):
  class CardinalityViolationError (line 132) | class CardinalityViolationError(_base.PostgresError):
  class DataError (line 136) | class DataError(_base.PostgresError):
  class ArraySubscriptError (line 140) | class ArraySubscriptError(DataError):
  class CharacterNotInRepertoireError (line 144) | class CharacterNotInRepertoireError(DataError):
  class DatetimeFieldOverflowError (line 148) | class DatetimeFieldOverflowError(DataError):
  class DivisionByZeroError (line 152) | class DivisionByZeroError(DataError):
  class ErrorInAssignmentError (line 156) | class ErrorInAssignmentError(DataError):
  class EscapeCharacterConflictError (line 160) | class EscapeCharacterConflictError(DataError):
  class IndicatorOverflowError (line 164) | class IndicatorOverflowError(DataError):
  class IntervalFieldOverflowError (line 168) | class IntervalFieldOverflowError(DataError):
  class InvalidArgumentForLogarithmError (line 172) | class InvalidArgumentForLogarithmError(DataError):
  class InvalidArgumentForNtileFunctionError (line 176) | class InvalidArgumentForNtileFunctionError(DataError):
  class InvalidArgumentForNthValueFunctionError (line 180) | class InvalidArgumentForNthValueFunctionError(DataError):
  class InvalidArgumentForPowerFunctionError (line 184) | class InvalidArgumentForPowerFunctionError(DataError):
  class InvalidArgumentForWidthBucketFunctionError (line 188) | class InvalidArgumentForWidthBucketFunctionError(DataError):
  class InvalidCharacterValueForCastError (line 192) | class InvalidCharacterValueForCastError(DataError):
  class InvalidDatetimeFormatError (line 196) | class InvalidDatetimeFormatError(DataError):
  class InvalidEscapeCharacterError (line 200) | class InvalidEscapeCharacterError(DataError):
  class InvalidEscapeOctetError (line 204) | class InvalidEscapeOctetError(DataError):
  class InvalidEscapeSequenceError (line 208) | class InvalidEscapeSequenceError(DataError):
  class NonstandardUseOfEscapeCharacterError (line 212) | class NonstandardUseOfEscapeCharacterError(DataError):
  class InvalidIndicatorParameterValueError (line 216) | class InvalidIndicatorParameterValueError(DataError):
  class InvalidParameterValueError (line 220) | class InvalidParameterValueError(DataError):
  class InvalidPrecedingOrFollowingSizeError (line 224) | class InvalidPrecedingOrFollowingSizeError(DataError):
  class InvalidRegularExpressionError (line 228) | class InvalidRegularExpressionError(DataError):
  class InvalidRowCountInLimitClauseError (line 232) | class InvalidRowCountInLimitClauseError(DataError):
  class InvalidRowCountInResultOffsetClauseError (line 236) | class InvalidRowCountInResultOffsetClauseError(DataError):
  class InvalidTablesampleArgumentError (line 240) | class InvalidTablesampleArgumentError(DataError):
  class InvalidTablesampleRepeatError (line 244) | class InvalidTablesampleRepeatError(DataError):
  class InvalidTimeZoneDisplacementValueError (line 248) | class InvalidTimeZoneDisplacementValueError(DataError):
  class InvalidUseOfEscapeCharacterError (line 252) | class InvalidUseOfEscapeCharacterError(DataError):
  class MostSpecificTypeMismatchError (line 256) | class MostSpecificTypeMismatchError(DataError):
  class NullValueNotAllowedError (line 260) | class NullValueNotAllowedError(DataError):
  class NullValueNoIndicatorParameterError (line 264) | class NullValueNoIndicatorParameterError(DataError):
  class NumericValueOutOfRangeError (line 268) | class NumericValueOutOfRangeError(DataError):
  class SequenceGeneratorLimitExceededError (line 272) | class SequenceGeneratorLimitExceededError(DataError):
  class StringDataLengthMismatchError (line 276) | class StringDataLengthMismatchError(DataError):
  class StringDataRightTruncationError (line 280) | class StringDataRightTruncationError(DataError):
  class SubstringError (line 284) | class SubstringError(DataError):
  class TrimError (line 288) | class TrimError(DataError):
  class UnterminatedCStringError (line 292) | class UnterminatedCStringError(DataError):
  class ZeroLengthCharacterStringError (line 296) | class ZeroLengthCharacterStringError(DataError):
  class PostgresFloatingPointError (line 300) | class PostgresFloatingPointError(DataError):
  class InvalidTextRepresentationError (line 304) | class InvalidTextRepresentationError(DataError):
  class InvalidBinaryRepresentationError (line 308) | class InvalidBinaryRepresentationError(DataError):
  class BadCopyFileFormatError (line 312) | class BadCopyFileFormatError(DataError):
  class UntranslatableCharacterError (line 316) | class UntranslatableCharacterError(DataError):
  class NotAnXmlDocumentError (line 320) | class NotAnXmlDocumentError(DataError):
  class InvalidXmlDocumentError (line 324) | class InvalidXmlDocumentError(DataError):
  class InvalidXmlContentError (line 328) | class InvalidXmlContentError(DataError):
  class InvalidXmlCommentError (line 332) | class InvalidXmlCommentError(DataError):
  class InvalidXmlProcessingInstructionError (line 336) | class InvalidXmlProcessingInstructionError(DataError):
  class DuplicateJsonObjectKeyValueError (line 340) | class DuplicateJsonObjectKeyValueError(DataError):
  class InvalidArgumentForSQLJsonDatetimeFunctionError (line 344) | class InvalidArgumentForSQLJsonDatetimeFunctionError(DataError):
  class InvalidJsonTextError (line 348) | class InvalidJsonTextError(DataError):
  class InvalidSQLJsonSubscriptError (line 352) | class InvalidSQLJsonSubscriptError(DataError):
  class MoreThanOneSQLJsonItemError (line 356) | class MoreThanOneSQLJsonItemError(DataError):
  class NoSQLJsonItemError (line 360) | class NoSQLJsonItemError(DataError):
  class NonNumericSQLJsonItemError (line 364) | class NonNumericSQLJsonItemError(DataError):
  class NonUniqueKeysInAJsonObjectError (line 368) | class NonUniqueKeysInAJsonObjectError(DataError):
  class SingletonSQLJsonItemRequiredError (line 372) | class SingletonSQLJsonItemRequiredError(DataError):
  class SQLJsonArrayNotFoundError (line 376) | class SQLJsonArrayNotFoundError(DataError):
  class SQLJsonMemberNotFoundError (line 380) | class SQLJsonMemberNotFoundError(DataError):
  class SQLJsonNumberNotFoundError (line 384) | class SQLJsonNumberNotFoundError(DataError):
  class SQLJsonObjectNotFoundError (line 388) | class SQLJsonObjectNotFoundError(DataError):
  class TooManyJsonArrayElementsError (line 392) | class TooManyJsonArrayElementsError(DataError):
  class TooManyJsonObjectMembersError (line 396) | class TooManyJsonObjectMembersError(DataError):
  class SQLJsonScalarRequiredError (line 400) | class SQLJsonScalarRequiredError(DataError):
  class SQLJsonItemCannotBeCastToTargetTypeError (line 404) | class SQLJsonItemCannotBeCastToTargetTypeError(DataError):
  class IntegrityConstraintViolationError (line 408) | class IntegrityConstraintViolationError(_base.PostgresError):
  class RestrictViolationError (line 412) | class RestrictViolationError(IntegrityConstraintViolationError):
  class NotNullViolationError (line 416) | class NotNullViolationError(IntegrityConstraintViolationError):
  class ForeignKeyViolationError (line 420) | class ForeignKeyViolationError(IntegrityConstraintViolationError):
  class UniqueViolationError (line 424) | class UniqueViolationError(IntegrityConstraintViolationError):
  class CheckViolationError (line 428) | class CheckViolationError(IntegrityConstraintViolationError):
  class ExclusionViolationError (line 432) | class ExclusionViolationError(IntegrityConstraintViolationError):
  class InvalidCursorStateError (line 436) | class InvalidCursorStateError(_base.PostgresError):
  class InvalidTransactionStateError (line 440) | class InvalidTransactionStateError(_base.PostgresError):
  class ActiveSQLTransactionError (line 444) | class ActiveSQLTransactionError(InvalidTransactionStateError):
  class BranchTransactionAlreadyActiveError (line 448) | class BranchTransactionAlreadyActiveError(InvalidTransactionStateError):
  class HeldCursorRequiresSameIsolationLevelError (line 452) | class HeldCursorRequiresSameIsolationLevelError(InvalidTransactionStateE...
  class InappropriateAccessModeForBranchTransactionError (line 456) | class InappropriateAccessModeForBranchTransactionError(
  class InappropriateIsolationLevelForBranchTransactionError (line 461) | class InappropriateIsolationLevelForBranchTransactionError(
  class NoActiveSQLTransactionForBranchTransactionError (line 466) | class NoActiveSQLTransactionForBranchTransactionError(
  class ReadOnlySQLTransactionError (line 471) | class ReadOnlySQLTransactionError(InvalidTransactionStateError):
  class SchemaAndDataStatementMixingNotSupportedError (line 475) | class SchemaAndDataStatementMixingNotSupportedError(
  class NoActiveSQLTransactionError (line 480) | class NoActiveSQLTransactionError(InvalidTransactionStateError):
  class InFailedSQLTransactionError (line 484) | class InFailedSQLTransactionError(InvalidTransactionStateError):
  class IdleInTransactionSessionTimeoutError (line 488) | class IdleInTransactionSessionTimeoutError(InvalidTransactionStateError):
  class TransactionTimeoutError (line 492) | class TransactionTimeoutError(InvalidTransactionStateError):
  class InvalidSQLStatementNameError (line 496) | class InvalidSQLStatementNameError(_base.PostgresError):
  class TriggeredDataChangeViolationError (line 500) | class TriggeredDataChangeViolationError(_base.PostgresError):
  class InvalidAuthorizationSpecificationError (line 504) | class InvalidAuthorizationSpecificationError(_base.PostgresError):
  class InvalidPasswordError (line 508) | class InvalidPasswordError(InvalidAuthorizationSpecificationError):
  class DependentPrivilegeDescriptorsStillExistError (line 512) | class DependentPrivilegeDescriptorsStillExistError(_base.PostgresError):
  class DependentObjectsStillExistError (line 516) | class DependentObjectsStillExistError(
  class InvalidTransactionTerminationError (line 521) | class InvalidTransactionTerminationError(_base.PostgresError):
  class SQLRoutineError (line 525) | class SQLRoutineError(_base.PostgresError):
  class FunctionExecutedNoReturnStatementError (line 529) | class FunctionExecutedNoReturnStatementError(SQLRoutineError):
  class ModifyingSQLDataNotPermittedError (line 533) | class ModifyingSQLDataNotPermittedError(SQLRoutineError):
  class ProhibitedSQLStatementAttemptedError (line 537) | class ProhibitedSQLStatementAttemptedError(SQLRoutineError):
  class ReadingSQLDataNotPermittedError (line 541) | class ReadingSQLDataNotPermittedError(SQLRoutineError):
  class InvalidCursorNameError (line 545) | class InvalidCursorNameError(_base.PostgresError):
  class ExternalRoutineError (line 549) | class ExternalRoutineError(_base.PostgresError):
  class ContainingSQLNotPermittedError (line 553) | class ContainingSQLNotPermittedError(ExternalRoutineError):
  class ModifyingExternalRoutineSQLDataNotPermittedError (line 557) | class ModifyingExternalRoutineSQLDataNotPermittedError(ExternalRoutineEr...
  class ProhibitedExternalRoutineSQLStatementAttemptedError (line 561) | class ProhibitedExternalRoutineSQLStatementAttemptedError(
  class ReadingExternalRoutineSQLDataNotPermittedError (line 566) | class ReadingExternalRoutineSQLDataNotPermittedError(ExternalRoutineError):
  class ExternalRoutineInvocationError (line 570) | class ExternalRoutineInvocationError(_base.PostgresError):
  class InvalidSqlstateReturnedError (line 574) | class InvalidSqlstateReturnedError(ExternalRoutineInvocationError):
  class NullValueInExternalRoutineNotAllowedError (line 578) | class NullValueInExternalRoutineNotAllowedError(
  class TriggerProtocolViolatedError (line 583) | class TriggerProtocolViolatedError(ExternalRoutineInvocationError):
  class SrfProtocolViolatedError (line 587) | class SrfProtocolViolatedError(ExternalRoutineInvocationError):
  class EventTriggerProtocolViolatedError (line 591) | class EventTriggerProtocolViolatedError(ExternalRoutineInvocationError):
  class SavepointError (line 595) | class SavepointError(_base.PostgresError):
  class InvalidSavepointSpecificationError (line 599) | class InvalidSavepointSpecificationError(SavepointError):
  class InvalidCatalogNameError (line 603) | class InvalidCatalogNameError(_base.PostgresError):
  class InvalidSchemaNameError (line 607) | class InvalidSchemaNameError(_base.PostgresError):
  class TransactionRollbackError (line 611) | class TransactionRollbackError(_base.PostgresError):
  class TransactionIntegrityConstraintViolationError (line 615) | class TransactionIntegrityConstraintViolationError(TransactionRollbackEr...
  class SerializationError (line 619) | class SerializationError(TransactionRollbackError):
  class StatementCompletionUnknownError (line 623) | class StatementCompletionUnknownError(TransactionRollbackError):
  class DeadlockDetectedError (line 627) | class DeadlockDetectedError(TransactionRollbackError):
  class SyntaxOrAccessError (line 631) | class SyntaxOrAccessError(_base.PostgresError):
  class PostgresSyntaxError (line 635) | class PostgresSyntaxError(SyntaxOrAccessError):
  class InsufficientPrivilegeError (line 639) | class InsufficientPrivilegeError(SyntaxOrAccessError):
  class CannotCoerceError (line 643) | class CannotCoerceError(SyntaxOrAccessError):
  class GroupingError (line 647) | class GroupingError(SyntaxOrAccessError):
  class WindowingError (line 651) | class WindowingError(SyntaxOrAccessError):
  class InvalidRecursionError (line 655) | class InvalidRecursionError(SyntaxOrAccessError):
  class InvalidForeignKeyError (line 659) | class InvalidForeignKeyError(SyntaxOrAccessError):
  class InvalidNameError (line 663) | class InvalidNameError(SyntaxOrAccessError):
  class NameTooLongError (line 667) | class NameTooLongError(SyntaxOrAccessError):
  class ReservedNameError (line 671) | class ReservedNameError(SyntaxOrAccessError):
  class DatatypeMismatchError (line 675) | class DatatypeMismatchError(SyntaxOrAccessError):
  class IndeterminateDatatypeError (line 679) | class IndeterminateDatatypeError(SyntaxOrAccessError):
  class CollationMismatchError (line 683) | class CollationMismatchError(SyntaxOrAccessError):
  class IndeterminateCollationError (line 687) | class IndeterminateCollationError(SyntaxOrAccessError):
  class WrongObjectTypeError (line 691) | class WrongObjectTypeError(SyntaxOrAccessError):
  class GeneratedAlwaysError (line 695) | class GeneratedAlwaysError(SyntaxOrAccessError):
  class UndefinedColumnError (line 699) | class UndefinedColumnError(SyntaxOrAccessError):
  class UndefinedFunctionError (line 703) | class UndefinedFunctionError(SyntaxOrAccessError):
  class UndefinedTableError (line 707) | class UndefinedTableError(SyntaxOrAccessError):
  class UndefinedParameterError (line 711) | class UndefinedParameterError(SyntaxOrAccessError):
  class UndefinedObjectError (line 715) | class UndefinedObjectError(SyntaxOrAccessError):
  class DuplicateColumnError (line 719) | class DuplicateColumnError(SyntaxOrAccessError):
  class DuplicateCursorError (line 723) | class DuplicateCursorError(SyntaxOrAccessError):
  class DuplicateDatabaseError (line 727) | class DuplicateDatabaseError(SyntaxOrAccessError):
  class DuplicateFunctionError (line 731) | class DuplicateFunctionError(SyntaxOrAccessError):
  class DuplicatePreparedStatementError (line 735) | class DuplicatePreparedStatementError(SyntaxOrAccessError):
  class DuplicateSchemaError (line 739) | class DuplicateSchemaError(SyntaxOrAccessError):
  class DuplicateTableError (line 743) | class DuplicateTableError(SyntaxOrAccessError):
  class DuplicateAliasError (line 747) | class DuplicateAliasError(SyntaxOrAccessError):
  class DuplicateObjectError (line 751) | class DuplicateObjectError(SyntaxOrAccessError):
  class AmbiguousColumnError (line 755) | class AmbiguousColumnError(SyntaxOrAccessError):
  class AmbiguousFunctionError (line 759) | class AmbiguousFunctionError(SyntaxOrAccessError):
  class AmbiguousParameterError (line 763) | class AmbiguousParameterError(SyntaxOrAccessError):
  class AmbiguousAliasError (line 767) | class AmbiguousAliasError(SyntaxOrAccessError):
  class InvalidColumnReferenceError (line 771) | class InvalidColumnReferenceError(SyntaxOrAccessError):
  class InvalidColumnDefinitionError (line 775) | class InvalidColumnDefinitionError(SyntaxOrAccessError):
  class InvalidCursorDefinitionError (line 779) | class InvalidCursorDefinitionError(SyntaxOrAccessError):
  class InvalidDatabaseDefinitionError (line 783) | class InvalidDatabaseDefinitionError(SyntaxOrAccessError):
  class InvalidFunctionDefinitionError (line 787) | class InvalidFunctionDefinitionError(SyntaxOrAccessError):
  class InvalidPreparedStatementDefinitionError (line 791) | class InvalidPreparedStatementDefinitionError(SyntaxOrAccessError):
  class InvalidSchemaDefinitionError (line 795) | class InvalidSchemaDefinitionError(SyntaxOrAccessError):
  class InvalidTableDefinitionError (line 799) | class InvalidTableDefinitionError(SyntaxOrAccessError):
  class InvalidObjectDefinitionError (line 803) | class InvalidObjectDefinitionError(SyntaxOrAccessError):
  class WithCheckOptionViolationError (line 807) | class WithCheckOptionViolationError(_base.PostgresError):
  class InsufficientResourcesError (line 811) | class InsufficientResourcesError(_base.PostgresError):
  class DiskFullError (line 815) | class DiskFullError(InsufficientResourcesError):
  class OutOfMemoryError (line 819) | class OutOfMemoryError(InsufficientResourcesError):
  class TooManyConnectionsError (line 823) | class TooManyConnectionsError(InsufficientResourcesError):
  class ConfigurationLimitExceededError (line 827) | class ConfigurationLimitExceededError(InsufficientResourcesError):
  class ProgramLimitExceededError (line 831) | class ProgramLimitExceededError(_base.PostgresError):
  class StatementTooComplexError (line 835) | class StatementTooComplexError(ProgramLimitExceededError):
  class TooManyColumnsError (line 839) | class TooManyColumnsError(ProgramLimitExceededError):
  class TooManyArgumentsError (line 843) | class TooManyArgumentsError(ProgramLimitExceededError):
  class ObjectNotInPrerequisiteStateError (line 847) | class ObjectNotInPrerequisiteStateError(_base.PostgresError):
  class ObjectInUseError (line 851) | class ObjectInUseError(ObjectNotInPrerequisiteStateError):
  class CantChangeRuntimeParamError (line 855) | class CantChangeRuntimeParamError(ObjectNotInPrerequisiteStateError):
  class LockNotAvailableError (line 859) | class LockNotAvailableError(ObjectNotInPrerequisiteStateError):
  class UnsafeNewEnumValueUsageError (line 863) | class UnsafeNewEnumValueUsageError(ObjectNotInPrerequisiteStateError):
  class OperatorInterventionError (line 867) | class OperatorInterventionError(_base.PostgresError):
  class QueryCanceledError (line 871) | class QueryCanceledError(OperatorInterventionError):
  class AdminShutdownError (line 875) | class AdminShutdownError(OperatorInterventionError):
  class CrashShutdownError (line 879) | class CrashShutdownError(OperatorInterventionError):
  class CannotConnectNowError (line 883) | class CannotConnectNowError(OperatorInterventionError):
  class DatabaseDroppedError (line 887) | class DatabaseDroppedError(OperatorInterventionError):
  class IdleSessionTimeoutError (line 891) | class IdleSessionTimeoutError(OperatorInterventionError):
  class PostgresSystemError (line 895) | class PostgresSystemError(_base.PostgresError):
  class PostgresIOError (line 899) | class PostgresIOError(PostgresSystemError):
  class UndefinedFileError (line 903) | class UndefinedFileError(PostgresSystemError):
  class DuplicateFileError (line 907) | class DuplicateFileError(PostgresSystemError):
  class FileNameTooLongError (line 911) | class FileNameTooLongError(PostgresSystemError):
  class SnapshotTooOldError (line 915) | class SnapshotTooOldError(_base.PostgresError):
  class ConfigFileError (line 919) | class ConfigFileError(_base.PostgresError):
  class LockFileExistsError (line 923) | class LockFileExistsError(ConfigFileError):
  class FDWError (line 927) | class FDWError(_base.PostgresError):
  class FDWColumnNameNotFoundError (line 931) | class FDWColumnNameNotFoundError(FDWError):
  class FDWDynamicParameterValueNeededError (line 935) | class FDWDynamicParameterValueNeededError(FDWError):
  class FDWFunctionSequenceError (line 939) | class FDWFunctionSequenceError(FDWError):
  class FDWInconsistentDescriptorInformationError (line 943) | class FDWInconsistentDescriptorInformationError(FDWError):
  class FDWInvalidAttributeValueError (line 947) | class FDWInvalidAttributeValueError(FDWError):
  class FDWInvalidColumnNameError (line 951) | class FDWInvalidColumnNameError(FDWError):
  class FDWInvalidColumnNumberError (line 955) | class FDWInvalidColumnNumberError(FDWError):
  class FDWInvalidDataTypeError (line 959) | class FDWInvalidDataTypeError(FDWError):
  class FDWInvalidDataTypeDescriptorsError (line 963) | class FDWInvalidDataTypeDescriptorsError(FDWError):
  class FDWInvalidDescriptorFieldIdentifierError (line 967) | class FDWInvalidDescriptorFieldIdentifierError(FDWError):
  class FDWInvalidHandleError (line 971) | class FDWInvalidHandleError(FDWError):
  class FDWInvalidOptionIndexError (line 975) | class FDWInvalidOptionIndexError(FDWError):
  class FDWInvalidOptionNameError (line 979) | class FDWInvalidOptionNameError(FDWError):
  class FDWInvalidStringLengthOrBufferLengthError (line 983) | class FDWInvalidStringLengthOrBufferLengthError(FDWError):
  class FDWInvalidStringFormatError (line 987) | class FDWInvalidStringFormatError(FDWError):
  class FDWInvalidUseOfNullPointerError (line 991) | class FDWInvalidUseOfNullPointerError(FDWError):
  class FDWTooManyHandlesError (line 995) | class FDWTooManyHandlesError(FDWError):
  class FDWOutOfMemoryError (line 999) | class FDWOutOfMemoryError(FDWError):
  class FDWNoSchemasError (line 1003) | class FDWNoSchemasError(FDWError):
  class FDWOptionNameNotFoundError (line 1007) | class FDWOptionNameNotFoundError(FDWError):
  class FDWReplyHandleError (line 1011) | class FDWReplyHandleError(FDWError):
  class FDWSchemaNotFoundError (line 1015) | class FDWSchemaNotFoundError(FDWError):
  class FDWTableNotFoundError (line 1019) | class FDWTableNotFoundError(FDWError):
  class FDWUnableToCreateExecutionError (line 1023) | class FDWUnableToCreateExecutionError(FDWError):
  class FDWUnableToCreateReplyError (line 1027) | class FDWUnableToCreateReplyError(FDWError):
  class FDWUnableToEstablishConnectionError (line 1031) | class FDWUnableToEstablishConnectionError(FDWError):
  class PLPGSQLError (line 1035) | class PLPGSQLError(_base.PostgresError):
  class RaiseError (line 1039) | class RaiseError(PLPGSQLError):
  class NoDataFoundError (line 1043) | class NoDataFoundError(PLPGSQLError):
  class TooManyRowsError (line 1047) | class TooManyRowsError(PLPGSQLError):
  class AssertError (line 1051) | class AssertError(PLPGSQLError):
  class InternalServerError (line 1055) | class InternalServerError(_base.PostgresError):
  class DataCorruptedError (line 1059) | class DataCorruptedError(InternalServerError):
  class IndexCorruptedError (line 1063) | class IndexCorruptedError(InternalServerError):

FILE: asyncpg/exceptions/_base.py
  function _is_asyncpg_class (line 21) | def _is_asyncpg_class(cls):
  class PostgresMessageMeta (line 26) | class PostgresMessageMeta(type):
    method __new__ (line 50) | def __new__(mcls, name, bases, dct):
    method get_message_class_for_sqlstate (line 74) | def get_message_class_for_sqlstate(mcls, code):
  class PostgresMessage (line 78) | class PostgresMessage(metaclass=PostgresMessageMeta):
    method _get_error_class (line 81) | def _get_error_class(cls, fields):
    method _get_error_dict (line 86) | def _get_error_dict(cls, fields, query):
    method _make_constructor (line 100) | def _make_constructor(cls, fields, query=None):
    method as_dict (line 156) | def as_dict(self):
  class PostgresError (line 165) | class PostgresError(PostgresMessage, Exception):
    method __str__ (line 168) | def __str__(self):
    method new (line 178) | def new(cls, fields, query=None):
  class FatalPostgresError (line 185) | class FatalPostgresError(PostgresError):
  class UnknownPostgresError (line 189) | class UnknownPostgresError(FatalPostgresError):
  class InterfaceMessage (line 193) | class InterfaceMessage:
    method __init__ (line 194) | def __init__(self, *, detail=None, hint=None):
    method __str__ (line 198) | def __str__(self):
  class InterfaceError (line 208) | class InterfaceError(InterfaceMessage, Exception):
    method __init__ (line 211) | def __init__(self, msg, *, detail=None, hint=None):
    method with_msg (line 215) | def with_msg(self, msg):
  class ClientConfigurationError (line 225) | class ClientConfigurationError(InterfaceError, ValueError):
  class DataError (line 229) | class DataError(InterfaceError, ValueError):
  class UnsupportedClientFeatureError (line 233) | class UnsupportedClientFeatureError(InterfaceError):
  class UnsupportedServerFeatureError (line 237) | class UnsupportedServerFeatureError(InterfaceError):
  class InterfaceWarning (line 241) | class InterfaceWarning(InterfaceMessage, UserWarning):
    method __init__ (line 244) | def __init__(self, msg, *, detail=None, hint=None):
  class InternalClientError (line 249) | class InternalClientError(Exception):
  class ProtocolError (line 253) | class ProtocolError(InternalClientError):
  class TargetServerAttributeNotMatched (line 257) | class TargetServerAttributeNotMatched(InternalClientError):
  class OutdatedSchemaCacheError (line 261) | class OutdatedSchemaCacheError(InternalClientError):
    method __init__ (line 264) | def __init__(self, msg, *, schema=None, data_type=None, position=None):
  class PostgresLogMessage (line 271) | class PostgresLogMessage(PostgresMessage):
    method __str__ (line 274) | def __str__(self):
    method __setattr__ (line 277) | def __setattr__(self, name, val):
    method new (line 282) | def new(cls, fields, query=None):

FILE: asyncpg/introspection.py
  function TypeRecord (line 272) | def TypeRecord(
  function is_scalar_type (line 284) | def is_scalar_type(typeinfo: protocol.Record) -> bool:
  function is_domain_type (line 291) | def is_domain_type(typeinfo: protocol.Record) -> bool:
  function is_composite_type (line 295) | def is_composite_type(typeinfo: protocol.Record) -> bool:

FILE: asyncpg/pool.py
  class PoolConnectionProxyMeta (line 28) | class PoolConnectionProxyMeta(type):
    method __new__ (line 30) | def __new__(
    method _wrap_connection_method (line 58) | def _wrap_connection_method(
  class PoolConnectionProxy (line 78) | class PoolConnectionProxy(connection._ConnectionProxy,
    method __init__ (line 84) | def __init__(
    method __getattr__ (line 91) | def __getattr__(self, attr: str) -> Any:
    method _detach (line 95) | def _detach(self) -> Optional[connection.Connection]:
    method __repr__ (line 103) | def __repr__(self) -> str:
  class PoolConnectionHolder (line 112) | class PoolConnectionHolder:
    method __init__ (line 120) | def __init__(
    method is_connected (line 141) | def is_connected(self) -> bool:
    method is_idle (line 144) | def is_idle(self) -> bool:
    method connect (line 147) | async def connect(self) -> None:
    method acquire (line 158) | async def acquire(self) -> PoolConnectionProxy:
    method release (line 195) | async def release(self, timeout: Optional[float]) -> None:
    method wait_until_released (line 258) | async def wait_until_released(self) -> None:
    method close (line 264) | async def close(self) -> None:
    method terminate (line 270) | def terminate(self) -> None:
    method _setup_inactive_callback (line 276) | def _setup_inactive_callback(self) -> None:
    method _maybe_cancel_inactive_callback (line 285) | def _maybe_cancel_inactive_callback(self) -> None:
    method _deactivate_inactive_connection (line 290) | def _deactivate_inactive_connection(self) -> None:
    method _release_on_close (line 304) | def _release_on_close(self) -> None:
    method _release (line 309) | def _release(self) -> None:
  class Pool (line 329) | class Pool:
    method __init__ (line 348) | def __init__(self, *connect_args,
    method _async__init__ (line 429) | async def _async__init__(self):
    method _initialize (line 445) | async def _initialize(self):
    method is_closing (line 478) | def is_closing(self):
    method get_size (line 485) | def get_size(self):
    method get_min_size (line 492) | def get_min_size(self):
    method get_max_size (line 499) | def get_max_size(self):
    method get_idle_size (line 506) | def get_idle_size(self):
    method set_connect_args (line 513) | def set_connect_args(self, dsn=None, **connect_kwargs):
    method _get_new_connection (line 537) | async def _get_new_connection(self):
    method execute (line 577) | async def execute(
    method executemany (line 594) | async def executemany(
    method fetch (line 613) | async def fetch(
    method fetchval (line 636) | async def fetchval(self, query, *args, column=0, timeout=None):
    method fetchrow (line 650) | async def fetchrow(self, query, *args, timeout=None, record_class=None):
    method fetchmany (line 667) | async def fetchmany(self, query, args, *, timeout=None, record_class=N...
    method copy_from_table (line 683) | async def copy_from_table(
    method copy_from_query (line 728) | async def copy_from_query(
    method copy_to_table (line 770) | async def copy_to_table(
    method copy_records_to_table (line 823) | async def copy_records_to_table(
    method acquire (line 852) | def acquire(self, *, timeout=None):
    method _acquire (line 877) | async def _acquire(self, timeout):
    method release (line 901) | async def release(self, connection, *, timeout=None):
    method close (line 939) | async def close(self):
    method _warn_on_long_close (line 984) | def _warn_on_long_close(self):
    method terminate (line 990) | def terminate(self):
    method expire_connections (line 999) | async def expire_connections(self):
    method _check_init (line 1009) | def _check_init(self):
    method _drop_statement_cache (line 1020) | def _drop_statement_cache(self):
    method _drop_type_cache (line 1026) | def _drop_type_cache(self):
    method __await__ (line 1032) | def __await__(self):
    method __aenter__ (line 1035) | async def __aenter__(self):
    method __aexit__ (line 1039) | async def __aexit__(self, *exc):
  class PoolAcquireContext (line 1043) | class PoolAcquireContext:
    method __init__ (line 1047) | def __init__(self, pool: Pool, timeout: Optional[float]) -> None:
    method __aenter__ (line 1053) | async def __aenter__(self):
    method __aexit__ (line 1059) | async def __aexit__(
    method __await__ (line 1070) | def __await__(self):
  function create_pool (line 1075) | def create_pool(dsn=None, *,

FILE: asyncpg/prepared_stmt.py
  class PreparedStatement (line 16) | class PreparedStatement(connresource.ConnectionResource):
    method __init__ (line 21) | def __init__(self, connection, query, state):
    method get_name (line 29) | def get_name(self) -> str:
    method get_query (line 37) | def get_query(self) -> str:
    method get_statusmsg (line 48) | def get_statusmsg(self) -> str:
    method get_parameters (line 62) | def get_parameters(self):
    method get_attributes (line 79) | def get_attributes(self):
    method cursor (line 104) | def cursor(self, *args, prefetch=None,
    method explain (line 126) | async def explain(self, *args, analyze=False):
    method fetch (line 168) | async def fetch(self, *args, timeout=None):
    method fetchval (line 181) | async def fetchval(self, *args, column=0, timeout=None):
    method fetchrow (line 200) | async def fetchrow(self, *args, timeout=None):
    method fetchmany (line 215) | async def fetchmany(self, args, *, timeout=None):
    method executemany (line 236) | async def executemany(self, args, *, timeout: typing.Optional[float]=N...
    method __do_execute (line 254) | async def __do_execute(self, executor):
    method __bind_execute (line 267) | async def __bind_execute(self, args, limit, timeout):
    method _check_open (line 274) | def _check_open(self, meth_name):
    method _check_conn_validity (line 280) | def _check_conn_validity(self, meth_name):
    method __del__ (line 284) | def __del__(self):

FILE: asyncpg/protocol/protocol.pyi
  class ConnectionSettings (line 43) | class ConnectionSettings(asyncpg.pgproto.pgproto.CodecContext):
    method __init__ (line 45) | def __init__(self, conn_key: object) -> None: ...
    method add_python_codec (line 46) | def add_python_codec(
    method clear_type_cache (line 57) | def clear_type_cache(self) -> None: ...
    method get_data_codec (line 58) | def get_data_codec(
    method get_text_codec (line 61) | def get_text_codec(self) -> CodecInfo: ...
    method register_data_types (line 62) | def register_data_types(self, types: Iterable[object]) -> None: ...
    method remove_python_codec (line 63) | def remove_python_codec(
    method set_builtin_type_codec (line 66) | def set_builtin_type_codec(
    method __getattr__ (line 75) | def __getattr__(self, name: str) -> Any: ...
    method __reduce__ (line 76) | def __reduce__(self) -> Any: ...
  class PreparedStatementState (line 79) | class PreparedStatementState(Generic[_Record]):
    method __init__ (line 88) | def __init__(
    method _get_parameters (line 96) | def _get_parameters(self) -> tuple[Type, ...]: ...
    method _get_attributes (line 97) | def _get_attributes(self) -> tuple[Attribute, ...]: ...
    method _init_types (line 98) | def _init_types(self) -> set[int]: ...
    method _init_codecs (line 99) | def _init_codecs(self) -> None: ...
    method attach (line 100) | def attach(self) -> None: ...
    method detach (line 101) | def detach(self) -> None: ...
    method mark_closed (line 102) | def mark_closed(self) -> None: ...
    method mark_unprepared (line 103) | def mark_unprepared(self) -> None: ...
    method __reduce__ (line 104) | def __reduce__(self) -> Any: ...
  class CoreProtocol (line 106) | class CoreProtocol:
    method __init__ (line 110) | def __init__(self, addr: object, con_params: _ConnectionParameters) ->...
    method is_in_transaction (line 111) | def is_in_transaction(self) -> bool: ...
    method __reduce__ (line 112) | def __reduce__(self) -> Any: ...
  class BaseProtocol (line 114) | class BaseProtocol(CoreProtocol, Generic[_Record]):
    method __init__ (line 118) | def __init__(
    method set_connection (line 126) | def set_connection(self, connection: object) -> None: ...
    method get_server_pid (line 127) | def get_server_pid(self, *args: object, **kwargs: object) -> int: ...
    method get_settings (line 128) | def get_settings(self, *args: object, **kwargs: object) -> ConnectionS...
    method get_record_class (line 129) | def get_record_class(self) -> type[_Record]: ...
    method abort (line 130) | def abort(self) -> None: ...
    method bind (line 131) | async def bind(
    method bind_execute (line 139) | async def bind_execute(
    method bind_execute (line 149) | async def bind_execute(
    method bind_execute (line 159) | async def bind_execute(
    method bind_execute_many (line 168) | async def bind_execute_many(
    method close (line 175) | async def close(self, timeout: _TimeoutType) -> None: ...
    method _get_timeout (line 176) | def _get_timeout(self, timeout: _TimeoutType) -> float | None: ...
    method _is_cancelling (line 177) | def _is_cancelling(self) -> bool: ...
    method _wait_for_cancellation (line 178) | async def _wait_for_cancellation(self) -> None: ...
    method close_statement (line 179) | async def close_statement(
    method copy_in (line 182) | async def copy_in(self, *args: object, **kwargs: object) -> str: ...
    method copy_out (line 183) | async def copy_out(self, *args: object, **kwargs: object) -> str: ...
    method execute (line 184) | async def execute(self, *args: object, **kwargs: object) -> Any: ...
    method is_closed (line 185) | def is_closed(self, *args: object, **kwargs: object) -> Any: ...
    method is_connected (line 186) | def is_connected(self, *args: object, **kwargs: object) -> Any: ...
    method data_received (line 187) | def data_received(self, data: object) -> None: ...
    method connection_made (line 188) | def connection_made(self, transport: object) -> None: ...
    method connection_lost (line 189) | def connection_lost(self, exc: Exception | None) -> None: ...
    method pause_writing (line 190) | def pause_writing(self, *args: object, **kwargs: object) -> Any: ...
    method prepare (line 192) | async def prepare(
    method prepare (line 203) | async def prepare(
    method close_portal (line 213) | async def close_portal(self, portal_name: str, timeout: _TimeoutType) ...
    method query (line 214) | async def query(self, *args: object, **kwargs: object) -> str: ...
    method resume_writing (line 215) | def resume_writing(self, *args: object, **kwargs: object) -> Any: ...
    method __reduce__ (line 216) | def __reduce__(self) -> Any: ...
  class Codec (line 219) | class Codec:
    method __reduce__ (line 221) | def __reduce__(self) -> Any: ...
  class DataCodecConfig (line 223) | class DataCodecConfig:
    method __init__ (line 225) | def __init__(self) -> None: ...
    method add_python_codec (line 226) | def add_python_codec(
    method add_types (line 238) | def add_types(self, types: Iterable[object]) -> Any: ...
    method clear_type_cache (line 239) | def clear_type_cache(self) -> None: ...
    method declare_fallback_codec (line 240) | def declare_fallback_codec(self, oid: int, name: str, schema: str) -> ...
    method remove_python_codec (line 241) | def remove_python_codec(
    method set_builtin_type_codec (line 244) | def set_builtin_type_codec(
    method __reduce__ (line 253) | def __reduce__(self) -> Any: ...
  class Protocol (line 255) | class Protocol(BaseProtocol[_Record], asyncio.protocols.Protocol): ...
  class Timer (line 257) | class Timer:
    method __init__ (line 258) | def __init__(self, budget: float | None) -> None: ...
    method __enter__ (line 259) | def __enter__(self) -> None: ...
    method __exit__ (line 260) | def __exit__(self, et: object, e: object, tb: object) -> None: ...
    method get_remaining_budget (line 261) | def get_remaining_budget(self) -> float: ...
    method has_budget_greater_than (line 262) | def has_budget_greater_than(self, amount: float) -> bool: ...
  class SCRAMAuthentication (line 265) | class SCRAMAuthentication:

FILE: asyncpg/protocol/record.pyi
  class Record (line 13) | class Record:
    method get (line 15) | def get(self, key: str) -> Any | None: ...
    method get (line 17) | def get(self, key: str, default: _T) -> Any | _T: ...
    method items (line 18) | def items(self) -> Iterator[tuple[str, Any]]: ...
    method keys (line 19) | def keys(self) -> Iterator[str]: ...
    method values (line 20) | def values(self) -> Iterator[Any]: ...
    method __getitem__ (line 22) | def __getitem__(self, index: str) -> Any: ...
    method __getitem__ (line 24) | def __getitem__(self, index: int) -> Any: ...
    method __getitem__ (line 26) | def __getitem__(self, index: slice) -> tuple[Any, ...]: ...
    method __iter__ (line 27) | def __iter__(self) -> Iterator[Any]: ...
    method __contains__ (line 28) | def __contains__(self, x: object) -> bool: ...
    method __len__ (line 29) | def __len__(self) -> int: ...

FILE: asyncpg/protocol/record/pythoncapi_compat.h
  function PyObject (line 64) | static inline PyObject* _Py_NewRef(PyObject *obj)
  function PyObject (line 75) | static inline PyObject* _Py_XNewRef(PyObject *obj)
  function _Py_SET_REFCNT (line 86) | static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
  function _Py_SET_TYPE (line 133) | static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
  function _Py_SET_SIZE (line 143) | static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
  function PyCodeObject (line 153) | static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
  function PyCodeObject (line 161) | static inline PyCodeObject* _PyFrame_GetCodeBorrow(PyFrameObject *frame)
  function PyFrameObject (line 171) | static inline PyFrameObject* PyFrame_GetBack(PyFrameObject *frame)
  function PyFrameObject (line 179) | static inline PyFrameObject* _PyFrame_GetBackBorrow(PyFrameObject *frame)
  function PyObject (line 190) | static inline PyObject* PyFrame_GetLocals(PyFrameObject *frame)
  function PyObject (line 206) | static inline PyObject* PyFrame_GetGlobals(PyFrameObject *frame)
  function PyObject (line 215) | static inline PyObject* PyFrame_GetBuiltins(PyFrameObject *frame)
  function PyFrame_GetLasti (line 224) | static inline int PyFrame_GetLasti(PyFrameObject *frame)
  function PyObject (line 243) | static inline PyObject* PyFrame_GetVar(PyFrameObject *frame, PyObject *n...
  function PyObject (line 276) | static inline PyObject*
  function PyInterpreterState (line 297) | static inline PyInterpreterState *
  function PyFrameObject (line 308) | static inline PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate)
  function PyFrameObject (line 316) | static inline PyFrameObject*
  function PyInterpreterState (line 328) | static inline PyInterpreterState* PyInterpreterState_Get(void)
  function PyThreadState_GetID (line 348) | static inline uint64_t PyThreadState_GetID(PyThreadState *tstate)
  function PyThreadState_EnterTracing (line 357) | static inline void PyThreadState_EnterTracing(PyThreadState *tstate)
  function PyThreadState_LeaveTracing (line 370) | static inline void PyThreadState_LeaveTracing(PyThreadState *tstate)
  function PyObject (line 387) | static inline PyObject* PyObject_CallNoArgs(PyObject *func)
  function PyObject (line 398) | static inline PyObject* PyObject_CallOneArg(PyObject *func, PyObject *arg)
  function PyModule_AddObjectRef (line 407) | static inline int
  function PyModule_AddType (line 432) | static inline int PyModule_AddType(PyObject *module, PyTypeObject *type)
  function PyObject_GC_IsTracked (line 456) | static inline int PyObject_GC_IsTracked(PyObject* obj)
  function PyObject_GC_IsFinalized (line 465) | static inline int PyObject_GC_IsFinalized(PyObject *obj)
  function _Py_IS_TYPE (line 475) | static inline int _Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
  function PyFloat_Pack2 (line 487) | static inline int PyFloat_Pack2(double x, char *p, int le)
  function PyFloat_Unpack2 (line 490) | static inline double PyFloat_Unpack2(const char *p, int le)
  function PyFloat_Pack4 (line 501) | static inline int PyFloat_Pack4(double x, char *p, int le)
  function PyFloat_Pack8 (line 504) | static inline int PyFloat_Pack8(double x, char *p, int le)
  function PyFloat_Unpack4 (line 507) | static inline double PyFloat_Unpack4(const char *p, int le)
  function PyFloat_Unpack8 (line 510) | static inline double PyFloat_Unpack8(const char *p, int le)
  function PyObject (line 517) | static inline PyObject* PyCode_GetCode(PyCodeObject *code)
  function PyObject (line 526) | static inline PyObject* PyCode_GetVarnames(PyCodeObject *code)
  function PyObject (line 534) | static inline PyObject* PyCode_GetFreevars(PyCodeObject *code)
  function PyObject (line 542) | static inline PyObject* PyCode_GetCellvars(PyCodeObject *code)
  function PyObject (line 561) | static inline PyObject* PyImport_AddModuleRef(const char *name)
  function PyWeakref_GetRef (line 570) | static inline int PyWeakref_GetRef(PyObject *ref, PyObject **pobj)
  function Py_ssize_t (line 601) | static inline Py_ssize_t PyVectorcall_NARGS(size_t n)
  function PyObject (line 610) | static inline PyObject*
  function PyObject_GetOptionalAttr (line 686) | static inline int
  function PyObject_GetOptionalAttrString (line 708) | static inline int
  function PyMapping_GetOptionalItem (line 732) | static inline int
  function PyMapping_GetOptionalItemString (line 746) | static inline int
  function PyMapping_HasKeyWithError (line 769) | static inline int
  function PyMapping_HasKeyStringWithError (line 778) | static inline int
  function PyObject_HasAttrWithError (line 792) | static inline int
  function PyObject_HasAttrStringWithError (line 801) | static inline int
  function PyDict_GetItemRef (line 815) | static inline int
  function PyDict_GetItemStringRef (line 835) | static inline int
  function PyModule_Add (line 857) | static inline int
  function Py_IsFinalizing (line 872) | static inline int Py_IsFinalizing(void)
  function PyDict_ContainsString (line 886) | static inline int PyDict_ContainsString(PyObject *op, const char *key)
  function PyLong_AsInt (line 901) | static inline int PyLong_AsInt(PyObject *obj)
  function PyObject_VisitManagedDict (line 923) | static inline int
  function PyObject_ClearManagedDict (line 934) | static inline void
  function PyThreadState (line 948) | static inline PyThreadState*
  function PyUnicode_EqualToUTF8AndSize (line 958) | static inline int
  function PyUnicode_EqualToUTF8 (line 1021) | static inline int
  function PyList_Extend (line 1031) | static inline int
  function PyList_Clear (line 1037) | static inline int
  function PyDict_Pop (line 1046) | static inline int
  function PyDict_PopString (line 1088) | static inline int
  type Py_ssize_t (line 1108) | typedef Py_ssize_t Py_hash_t;
  function Py_hash_t (line 1114) | static inline Py_hash_t Py_HashPointer(const void *ptr)
  type _PyTime_t (line 1128) | typedef _PyTime_t PyTime_t;
  function PyTime_AsSecondsDouble (line 1132) | static inline double PyTime_AsSecondsDouble(PyTime_t t)
  function PyTime_Monotonic (line 1135) | static inline int PyTime_Monotonic(PyTime_t *result)
  function PyTime_Time (line 1138) | static inline int PyTime_Time(PyTime_t *result)
  function PyTime_PerfCounter (line 1141) | static inline int PyTime_PerfCounter(PyTime_t *result)
  function PyObject (line 1240) | static inline PyObject* Py_GetConstant(unsigned int constant_id)
  function PyObject (line 1293) | static inline PyObject* Py_GetConstantBorrowed(unsigned int constant_id)
  function PyObject (line 1304) | static inline PyObject *
  function PyDict_SetDefaultRef (line 1316) | static inline int
  type PyUnicodeWriter (line 1362) | typedef struct PyUnicodeWriter PyUnicodeWriter;
  function PyUnicodeWriter_Discard (line 1364) | static inline void PyUnicodeWriter_Discard(PyUnicodeWriter *writer)
  function PyUnicodeWriter (line 1370) | static inline PyUnicodeWriter* PyUnicodeWriter_Create(Py_ssize_t length)
  function PyObject (line 1395) | static inline PyObject* PyUnicodeWriter_Finish(PyUnicodeWriter *writer)
  function PyUnicodeWriter_WriteChar (line 1403) | static inline int
  function PyUnicodeWriter_WriteStr (line 1415) | static inline int
  function PyUnicodeWriter_WriteRepr (line 1428) | static inline int
  function PyUnicodeWriter_WriteUTF8 (line 1441) | static inline int
  function PyUnicodeWriter_WriteASCII (line 1459) | static inline int
  function PyUnicodeWriter_WriteWideChar (line 1471) | static inline int
  function PyUnicodeWriter_WriteSubstring (line 1489) | static inline int
  function PyUnicodeWriter_Format (line 1511) | static inline int
  function PyLong_GetSign (line 1530) | static inline int PyLong_GetSign(PyObject *obj, int *sign)
  function PyLong_IsPositive (line 1544) | static inline int PyLong_IsPositive(PyObject *obj)
  function PyLong_IsNegative (line 1553) | static inline int PyLong_IsNegative(PyObject *obj)
  function PyLong_IsZero (line 1562) | static inline int PyLong_IsZero(PyObject *obj)
  function PyUnicode_Equal (line 1575) | static inline int PyUnicode_Equal(PyObject *str1, PyObject *str2)
  function PyObject (line 1605) | static inline PyObject* PyBytes_Join(PyObject *sep, PyObject *iterable)
  function Py_hash_t (line 1613) | static inline Py_hash_t Py_HashBuffer(const void *ptr, Py_ssize_t len)
  function PyIter_NextItem (line 1634) | static inline int PyIter_NextItem(PyObject *iter, PyObject **item)
  function PyObject (line 1665) | static inline PyObject* PyLong_FromInt32(int32_t value)
  function PyObject (line 1671) | static inline PyObject* PyLong_FromInt64(int64_t value)
  function PyObject (line 1677) | static inline PyObject* PyLong_FromUInt32(uint32_t value)
  function PyObject (line 1683) | static inline PyObject* PyLong_FromUInt64(uint64_t value)
  function PyLong_AsInt32 (line 1689) | static inline int PyLong_AsInt32(PyObject *obj, int32_t *pvalue)
  function PyLong_AsInt64 (line 1700) | static inline int PyLong_AsInt64(PyObject *obj, int64_t *pvalue)
  function PyLong_AsUInt32 (line 1711) | static inline int PyLong_AsUInt32(PyObject *obj, uint32_t *pvalue)
  function PyLong_AsUInt64 (line 1729) | static inline int PyLong_AsUInt64(PyObject *obj, uint64_t *pvalue)
  function _PyLong_SetSignAndDigitCount (line 1745) | static inline void
  function Py_ssize_t (line 1757) | static inline Py_ssize_t
  function digit (line 1767) | static inline digit*
  type PyLongLayout (line 1777) | typedef struct PyLongLayout {
  type PyLongExport (line 1784) | typedef struct PyLongExport {
  type PyLongWriter (line 1792) | typedef struct PyLongWriter PyLongWriter;
  function PyLongLayout (line 1794) | static inline const PyLongLayout*
  function PyLong_Export (line 1807) | static inline int
  function PyLong_FreeExport (line 1850) | static inline void
  function PyLongWriter (line 1861) | static inline PyLongWriter*
  function PyLongWriter_Discard (line 1880) | static inline void
  function PyObject (line 1889) | static inline PyObject*
  function FILE (line 1954) | static inline FILE* Py_fopen(PyObject *path, const char *mode)
  function Py_fclose (line 1987) | static inline int Py_fclose(FILE *file)
  function PyObject (line 1995) | static inline PyObject*
  function PyConfig_GetInt (line 2187) | static inline int
  function PyUnstable_Object_IsUniquelyReferenced (line 2217) | static inline int PyUnstable_Object_IsUniquelyReferenced(PyObject *obj)
  function PyObject (line 2234) | static inline PyObject*
  function PyObject (line 2251) | static inline PyObject*
  function PySys_GetOptionalAttrString (line 2266) | static inline int
  function PySys_GetOptionalAttr (line 2280) | static inline int
  type PyBytesWriter (line 2299) | typedef struct PyBytesWriter {
  function Py_ssize_t (line 2305) | static inline Py_ssize_t
  function _PyBytesWriter_Resize_impl (line 2317) | static inline int
  function Py_ssize_t (line 2375) | static inline Py_ssize_t
  function PyBytesWriter_Discard (line 2381) | static inline void
  function PyBytesWriter (line 2392) | static inline PyBytesWriter*
  function PyObject (line 2419) | static inline PyObject*
  function PyObject (line 2446) | static inline PyObject*
  function PyObject (line 2452) | static inline PyObject*
  function PyBytesWriter_Resize (line 2465) | static inline int
  function PyBytesWriter_Grow (line 2479) | static inline int
  function PyBytesWriter_WriteBytes (line 2510) | static inline int
  function PyBytesWriter_Format (line 2536) | static inline int

FILE: asyncpg/protocol/record/pythoncapi_compat_extras.h
  function PyObject (line 12) | PyObject *

FILE: asyncpg/protocol/record/recordobj.c
  type record_freelist_state (line 30) | typedef struct {
  type record_module_state (line 35) | typedef struct {
  function record_module_state (line 44) | static inline record_module_state *
  function record_module_state (line 55) | static inline record_module_state *
  type PyModuleDef (line 68) | struct PyModuleDef
  function record_module_state (line 70) | static inline record_module_state *
  function record_freelist_state (line 79) | static inline record_freelist_state *
  function PyObject (line 102) | PyObject *
  function record_dealloc (line 170) | static void
  function record_traverse (line 216) | static int
  function Py_hash_t (line 244) | static Py_hash_t
  function Py_ssize_t (line 272) | static Py_ssize_t
  function record_contains (line 279) | static int
  function PyObject (line 289) | static PyObject *
  function PyObject (line 300) | static PyObject *
  type item_by_name_result_t (line 422) | typedef enum item_by_name_result {
  function item_by_name_result_t (line 431) | static item_by_name_result_t
  function PyObject (line 476) | static PyObject *
  function PyObject (line 546) | static PyObject *
  function PyObject (line 625) | static PyObject *
  function PyObject (line 639) | static PyObject *
  function PyObject (line 652) | static PyObject *
  function PyObject (line 663) | static PyObject *
  function PyObject (line 676) | static PyObject *
  function PyObject (line 712) | static PyObject *
  type ApgRecordIterObject (line 773) | typedef struct {
  function record_iter_dealloc (line 778) | static void
  function record_iter_traverse (line 788) | static int
  function PyObject (line 795) | static PyObject *
  function PyObject (line 818) | static PyObject *
  function PyObject (line 852) | static PyObject *
  type ApgRecordItemsObject (line 868) | typedef struct {
  function record_items_dealloc (line 874) | static void
  function record_items_traverse (line 885) | static int
  function PyObject (line 893) | static PyObject *
  function PyObject (line 942) | static PyObject *
  function PyObject (line 976) | static PyObject *
  function record_desc_dealloc (line 1003) | static void
  function record_desc_traverse (line 1014) | static int
  function PyObject (line 1022) | static PyObject *
  function PyObject (line 1066) | static PyObject *
  function PyObject (line 1091) | static PyObject *
  function record_module_exec (line 1163) | static int
  function record_module_traverse (line 1204) | static int
  function record_module_clear (line 1220) | static int
  function record_module_free (line 1257) | static void
  type PyModuleDef (line 1274) | struct PyModuleDef
  function PyMODINIT_FUNC (line 1285) | PyMODINIT_FUNC

FILE: asyncpg/protocol/record/recordobj.h
  type ApgRecordDescObject (line 7) | typedef struct {
  type ApgRecordObject (line 14) | typedef struct {

FILE: asyncpg/serverversion.py
  class _VersionDict (line 24) | class _VersionDict(typing.TypedDict):
  function split_server_version_string (line 32) | def split_server_version_string(version_string: str) -> ServerVersion:

FILE: asyncpg/transaction.py
  class TransactionState (line 14) | class TransactionState(enum.Enum):
  class Transaction (line 36) | class Transaction(connresource.ConnectionResource):
    method __init__ (line 47) | def __init__(self, connection, isolation, readonly, deferrable):
    method __aenter__ (line 63) | async def __aenter__(self):
    method __aexit__ (line 70) | async def __aexit__(self, extype, ex, tb):
    method start (line 96) | async def start(self):
    method __check_state_base (line 153) | def __check_state_base(self, opname):
    method __check_state (line 167) | def __check_state(self, opname):
    method __commit (line 175) | async def __commit(self):
    method __rollback (line 194) | async def __rollback(self):
    method commit (line 214) | async def commit(self):
    method rollback (line 222) | async def rollback(self):
    method __repr__ (line 229) | def __repr__(self):

FILE: asyncpg/types.py
  class Type (line 26) | class Type(typing.NamedTuple):
  class Attribute (line 41) | class Attribute(typing.NamedTuple):
  class ServerVersion (line 51) | class ServerVersion(typing.NamedTuple):
  class _RangeValue (line 62) | class _RangeValue(typing.Protocol):
    method __eq__ (line 63) | def __eq__(self, __value: object) -> bool:
    method __lt__ (line 66) | def __lt__(self, __other: Self, /) -> bool:
    method __gt__ (line 69) | def __gt__(self, __other: Self, /) -> bool:
  class Range (line 76) | class Range(typing.Generic[_RV]):
    method __init__ (line 87) | def __init__(
    method lower (line 107) | def lower(self) -> _RV | None:
    method lower_inc (line 111) | def lower_inc(self) -> bool:
    method lower_inf (line 115) | def lower_inf(self) -> bool:
    method upper (line 119) | def upper(self) -> _RV | None:
    method upper_inc (line 123) | def upper_inc(self) -> bool:
    method upper_inf (line 127) | def upper_inf(self) -> bool:
    method isempty (line 131) | def isempty(self) -> bool:
    method _issubset_lower (line 134) | def _issubset_lower(self, other: Self) -> bool:
    method _issubset_upper (line 145) | def _issubset_upper(self, other: Self) -> bool:
    method issubset (line 156) | def issubset(self, other: Self) -> bool:
    method issuperset (line 164) | def issuperset(self, other: Self) -> bool:
    method __bool__ (line 167) | def __bool__(self) -> bool:
    method __eq__ (line 170) | def __eq__(self, other: object) -> bool:
    method __hash__ (line 188) | def __hash__(self) -> int:
    method __repr__ (line 197) | def __repr__(self) -> str:

FILE: asyncpg/utils.py
  function _quote_ident (line 11) | def _quote_ident(ident):
  function _quote_literal (line 15) | def _quote_literal(string):
  function _mogrify (line 19) | async def _mogrify(conn, query, args):

FILE: setup.py
  function git_commitish (line 60) | def git_commitish():
  class VersionMixin (line 78) | class VersionMixin:
    method _fix_version (line 80) | def _fix_version(self, filename):
  class sdist (line 95) | class sdist(setuptools_sdist.sdist, VersionMixin):
    method make_release_tree (line 97) | def make_release_tree(self, base_dir, files):
  class build_py (line 102) | class build_py(setuptools_build_py.build_py, VersionMixin):
    method build_module (line 104) | def build_module(self, module, module_file, package):
  class build_ext (line 113) | class build_ext(setuptools_build_ext.build_ext):
    method initialize_options (line 124) | def initialize_options(self):
    method finalize_options (line 153) | def finalize_options(self):

FILE: tests/__init__.py
  function suite (line 13) | def suite():

FILE: tests/certs/gen.py
  function _new_cert (line 12) | def _new_cert(issuer=None, is_issuer=False, serial_number=None, **subject):
  function _write_cert (line 132) | def _write_cert(path, cert_key_pair, password=None):
  function new_ca (line 154) | def new_ca(path, **subject):
  function new_cert (line 160) | def new_cert(
  function new_crl (line 170) | def new_crl(path, issuer, cert):
  function main (line 190) | def main():

FILE: tests/test__environment.py
  class TestEnvironment (line 17) | class TestEnvironment(tb.ConnectedTestCase):
    method test_environment_server_version (line 20) | async def test_environment_server_version(self):
    method test_environment_asyncpg_version (line 35) | async def test_environment_asyncpg_version(self):

FILE: tests/test__sourcecode.py
  function find_root (line 13) | def find_root():
  class TestCodeQuality (line 17) | class TestCodeQuality(unittest.TestCase):
    method test_flake8 (line 19) | def test_flake8(self):
    method test_mypy (line 42) | def test_mypy(self):

FILE: tests/test_adversity.py
  class TestConnectionLoss (line 21) | class TestConnectionLoss(tb.ProxiedClusterTestCase):
    method test_connection_close_timeout (line 23) | async def test_connection_close_timeout(self):
    method test_pool_acquire_timeout (line 30) | async def test_pool_acquire_timeout(self):
    method test_pool_release_timeout (line 47) | async def test_pool_release_timeout(self):
    method test_pool_handles_abrupt_connection_loss (line 59) | async def test_pool_handles_abrupt_connection_loss(self):

FILE: tests/test_cache_invalidation.py
  class TestCacheInvalidation (line 15) | class TestCacheInvalidation(tb.ConnectedTestCase):
    method _get_cached_statements (line 17) | def _get_cached_statements(self, connection=None):
    method _check_statements_are_not_closed (line 22) | def _check_statements_are_not_closed(self, statements):
    method _check_statements_are_closed (line 26) | def _check_statements_are_closed(self, statements):
    method test_prepare_cache_invalidation_silent (line 30) | async def test_prepare_cache_invalidation_silent(self):
    method test_prepare_cache_invalidation_in_transaction (line 51) | async def test_prepare_cache_invalidation_in_transaction(self):
    method test_prepare_cache_invalidation_in_pool (line 78) | async def test_prepare_cache_invalidation_in_pool(self):
    method test_type_cache_invalidation_in_transaction (line 125) | async def test_type_cache_invalidation_in_transaction(self):
    method test_type_cache_invalidation_in_cancelled_transaction (line 156) | async def test_type_cache_invalidation_in_cancelled_transaction(self):
    method test_prepared_type_cache_invalidation (line 195) | async def test_prepared_type_cache_invalidation(self):
    method test_type_cache_invalidation_on_drop_type_attr (line 250) | async def test_type_cache_invalidation_on_drop_type_attr(self):
    method test_type_cache_invalidation_on_change_attr (line 278) | async def test_type_cache_invalidation_on_change_attr(self):
    method test_type_cache_invalidation_in_pool (line 309) | async def test_type_cache_invalidation_in_pool(self):

FILE: tests/test_cancellation.py
  class TestCancellation (line 14) | class TestCancellation(tb.ConnectedTestCase):
    method test_cancellation_01 (line 16) | async def test_cancellation_01(self):
    method test_cancellation_02 (line 67) | async def test_cancellation_02(self):
    method test_cancellation_03 (line 74) | async def test_cancellation_03(self):
    method test_cancellation_04 (line 91) | async def test_cancellation_04(self):

FILE: tests/test_codecs.py
  function _timezone (line 23) | def _timezone(offset):
  function _system_timezone (line 28) | def _system_timezone():
  class TestCodecs (line 468) | class TestCodecs(tb.ConnectedTestCase):
    method test_standard_codecs (line 470) | async def test_standard_codecs(self):
    method test_all_builtin_types_handled (line 546) | async def test_all_builtin_types_handled(self):
    method test_void (line 555) | async def test_void(self):
    method test_bitstring (line 560) | def test_bitstring(self):
    method test_interval (line 587) | async def test_interval(self):
    method test_numeric (line 600) | async def test_numeric(self):
    method test_unhandled_type_fallback (line 667) | async def test_unhandled_type_fallback(self):
    method test_invalid_input (line 687) | async def test_invalid_input(self):
    method test_arrays (line 791) | async def test_arrays(self):
    method test_composites (line 897) | async def test_composites(self):
    method test_domains (line 976) | async def test_domains(self):
    method test_range_types (line 1011) | async def test_range_types(self):
    method test_multirange_types (line 1060) | async def test_multirange_types(self):
    method test_extra_codec_alias (line 1113) | async def test_extra_codec_alias(self):
    method test_custom_codec_text (line 1186) | async def test_custom_codec_text(self):
    method test_custom_codec_binary (line 1240) | async def test_custom_codec_binary(self):
    method test_custom_codec_on_domain (line 1320) | async def test_custom_codec_on_domain(self):
    method test_custom_codec_on_stdsql_types (line 1338) | async def test_custom_codec_on_stdsql_types(self):
    method test_custom_codec_on_enum (line 1371) | async def test_custom_codec_on_enum(self):
    method test_custom_codec_on_enum_array (line 1388) | async def test_custom_codec_on_enum_array(self):
    method test_custom_codec_override_binary (line 1416) | async def test_custom_codec_override_binary(self):
    method test_custom_codec_override_text (line 1440) | async def test_custom_codec_override_text(self):
    method test_custom_codec_override_tuple (line 1487) | async def test_custom_codec_override_tuple(self):
    method test_custom_codec_composite_tuple (line 1547) | async def test_custom_codec_composite_tuple(self):
    method test_custom_codec_composite_non_tuple (line 1574) | async def test_custom_codec_composite_non_tuple(self):
    method test_timetz_encoding (line 1594) | async def test_timetz_encoding(self):
    method test_composites_in_arrays (line 1615) | async def test_composites_in_arrays(self):
    method test_table_as_composite (line 1637) | async def test_table_as_composite(self):
    method test_relacl_array_type (line 1655) | async def test_relacl_array_type(self):
    method test_enum (line 1744) | async def test_enum(self):
    method test_unknown_type_text_fallback (line 1769) | async def test_unknown_type_text_fallback(self):
    method test_enum_in_array (line 1853) | async def test_enum_in_array(self):
    method test_enum_and_range (line 1873) | async def test_enum_and_range(self):
    method test_enum_in_composite (line 1898) | async def test_enum_in_composite(self):
    method test_enum_function_return (line 1916) | async def test_enum_function_return(self):
    method test_no_result (line 1937) | async def test_no_result(self):
    method test_array_with_custom_json_text_codec (line 1941) | async def test_array_with_custom_json_text_codec(self):
  class TestCodecsLargeOIDs (line 1980) | class TestCodecsLargeOIDs(tb.ConnectedTestCase):
    method setup_cluster (line 1984) | def setup_cluster(cls):
    method test_custom_codec_large_oid (line 1989) | async def test_custom_codec_large_oid(self):

FILE: tests/test_connect.py
  function mock_dot_postgresql (line 60) | def mock_dot_postgresql(*, ca=True, crl=False, client=False, protected=F...
  function mock_no_home_dir (line 86) | def mock_no_home_dir():
  function mock_dev_null_home_dir (line 94) | def mock_dev_null_home_dir():
  class TestSettings (line 102) | class TestSettings(tb.ConnectedTestCase):
    method test_get_settings_01 (line 104) | async def test_get_settings_01(self):
    method test_server_version_01 (line 109) | async def test_server_version_01(self):
    method test_server_version_02 (line 119) | def test_server_version_02(self):
  class BaseTestAuthentication (line 143) | class BaseTestAuthentication(tb.ConnectedTestCase):
    method setUp (line 146) | def setUp(self):
    method tearDown (line 202) | def tearDown(self):
  class TestAuthentication (line 219) | class TestAuthentication(BaseTestAuthentication):
    method _try_connect (line 228) | async def _try_connect(self, **kwargs):
    method test_auth_bad_user (line 241) | async def test_auth_bad_user(self):
    method test_auth_trust (line 246) | async def test_auth_trust(self):
    method test_auth_reject (line 250) | async def test_auth_reject(self):
    method test_auth_password_cleartext (line 256) | async def test_auth_password_cleartext(self):
    method test_auth_password_cleartext_callable (line 269) | async def test_auth_password_cleartext_callable(self):
    method test_auth_password_cleartext_callable_coroutine (line 288) | async def test_auth_password_cleartext_callable_coroutine(self):
    method test_auth_password_cleartext_callable_awaitable (line 307) | async def test_auth_password_cleartext_callable_awaitable(self):
    method test_auth_password_md5 (line 326) | async def test_auth_password_md5(self):
    method test_auth_password_scram_sha_256 (line 337) | async def test_auth_password_scram_sha_256(self):
    method test_auth_md5_unsupported (line 385) | async def test_auth_md5_unsupported(self, _):
  class TestGssAuthentication (line 397) | class TestGssAuthentication(BaseTestAuthentication):
    method setUpClass (line 399) | def setUpClass(cls):
    method get_server_settings (line 424) | def get_server_settings(cls):
    method setup_cluster (line 430) | def setup_cluster(cls):
    method test_auth_gssapi_ok (line 435) | async def test_auth_gssapi_ok(self):
    method test_auth_gssapi_bad_srvname (line 439) | async def test_auth_gssapi_bad_srvname(self):
    method test_auth_gssapi_bad_user (line 447) | async def test_auth_gssapi_bad_user(self):
  class TestSspiAuthentication (line 457) | class TestSspiAuthentication(BaseTestAuthentication):
    method setUpClass (line 459) | def setUpClass(cls):
    method test_auth_sspi (line 467) | async def test_auth_sspi(self):
  class TestConnectParams (line 479) | class TestConnectParams(tb.TestCase):
    method environ (line 1109) | def environ(self, **kwargs):
    method run_testcase (line 1131) | def run_testcase(self, testcase):
    method test_test_connect_params_environ (line 1213) | def test_test_connect_params_environ(self):
    method test_test_connect_params_run_testcase (line 1240) | def test_test_connect_params_run_testcase(self):
    method test_connect_params (line 1255) | def test_connect_params(self):
    method test_connect_connection_service_file (line 1259) | def test_connect_connection_service_file(self):
    method test_connect_pgpass_regular (line 1364) | def test_connect_pgpass_regular(self):
    method test_connect_pgpass_badness_mode (line 1538) | def test_connect_pgpass_badness_mode(self):
    method test_connect_pgpass_badness_non_file (line 1562) | def test_connect_pgpass_badness_non_file(self):
    method test_connect_pgpass_nonexistent (line 1583) | def test_connect_pgpass_nonexistent(self):
    method test_connect_pgpass_inaccessible_file (line 1601) | def test_connect_pgpass_inaccessible_file(self):
    method test_connect_pgpass_inaccessible_directory (line 1622) | def test_connect_pgpass_inaccessible_directory(self):
    method test_connect_args_validation (line 1646) | async def test_connect_args_validation(self):
  class TestConnection (line 1659) | class TestConnection(tb.ConnectedTestCase):
    method test_connection_isinstance (line 1661) | async def test_connection_isinstance(self):
    method test_connection_use_after_close (line 1666) | async def test_connection_use_after_close(self):
    method test_connection_ssl_to_no_ssl_server (line 1698) | async def test_connection_ssl_to_no_ssl_server(self):
    method test_connection_sslmode_no_ssl_server (line 1709) | async def test_connection_sslmode_no_ssl_server(self):
    method test_connection_implicit_host (line 1747) | async def test_connection_implicit_host(self):
    method test_connection_no_home_dir (line 1756) | async def test_connection_no_home_dir(self):
  class BaseTestSSLConnection (line 1796) | class BaseTestSSLConnection(tb.ConnectedTestCase):
    method get_server_settings (line 1798) | def get_server_settings(cls):
    method setup_cluster (line 1813) | def setup_cluster(cls):
    method setUp (line 1818) | def setUp(self):
    method tearDown (line 1835) | def tearDown(self):
    method _add_hba_entry (line 1847) | def _add_hba_entry(self):
  class TestSSLConnection (line 1852) | class TestSSLConnection(BaseTestSSLConnection):
    method _add_hba_entry (line 1853) | def _add_hba_entry(self):
    method test_ssl_connection_custom_context (line 1864) | async def test_ssl_connection_custom_context(self):
    method test_ssl_connection_sslmode (line 1883) | async def test_ssl_connection_sslmode(self):
    method test_ssl_connection_default_context (line 1943) | async def test_ssl_connection_default_context(self):
    method test_ssl_connection_pool (line 1956) | async def test_ssl_connection_pool(self):
    method test_executemany_uvloop_ssl_issue_700 (line 1981) | async def test_executemany_uvloop_ssl_issue_700(self):
    method test_tls_version (line 2005) | async def test_tls_version(self):
  class TestClientSSLConnection (line 2058) | class TestClientSSLConnection(BaseTestSSLConnection):
    method _add_hba_entry (line 2059) | def _add_hba_entry(self):
    method test_ssl_connection_client_auth_fails_with_wrong_setup (line 2070) | async def test_ssl_connection_client_auth_fails_with_wrong_setup(self):
    method _test_works (line 2086) | async def _test_works(self, **conn_args):
    method test_ssl_connection_client_auth_custom_context (line 2094) | async def test_ssl_connection_client_auth_custom_context(self):
    method test_ssl_connection_client_auth_dsn (line 2111) | async def test_ssl_connection_client_auth_dsn(self):
    method test_ssl_connection_client_auth_env (line 2128) | async def test_ssl_connection_client_auth_env(self):
    method test_ssl_connection_client_auth_dot_postgresql (line 2142) | async def test_ssl_connection_client_auth_dot_postgresql(self):
  class TestNoSSLConnection (line 2151) | class TestNoSSLConnection(BaseTestSSLConnection):
    method _add_hba_entry (line 2152) | def _add_hba_entry(self):
    method test_nossl_connection_sslmode (line 2163) | async def test_nossl_connection_sslmode(self):
    method test_nossl_connection_prefer_cancel (line 2205) | async def test_nossl_connection_prefer_cancel(self):
    method test_nossl_connection_pool (line 2219) | async def test_nossl_connection_pool(self):
  class TestConnectionGC (line 2243) | class TestConnectionGC(tb.ClusterTestCase):
    method _run_no_explicit_close_test (line 2245) | async def _run_no_explicit_close_test(self):
    method test_no_explicit_close_no_debug (line 2268) | async def test_no_explicit_close_no_debug(self):
    method test_no_explicit_close_with_debug (line 2279) | async def test_no_explicit_close_with_debug(self):
  class TestConnectionAttributes (line 2294) | class TestConnectionAttributes(tb.HotStandbyTestCase):
    method _run_connection_test (line 2296) | async def _run_connection_test(
    method test_target_server_attribute_port (line 2303) | async def test_target_server_attribute_port(self):
    method test_target_attribute_not_matched (line 2327) | async def test_target_attribute_not_matched(self):
    method test_prefer_standby_when_standby_is_up (line 2348) | async def test_prefer_standby_when_standby_is_up(self):
    method test_prefer_standby_picks_master_when_standby_is_down (line 2355) | async def test_prefer_standby_picks_master_when_standby_is_down(self):
  function _get_connected_host (line 2375) | def _get_connected_host(con):

FILE: tests/test_copy.py
  class TestCopyFrom (line 19) | class TestCopyFrom(tb.ConnectedTestCase):
    method test_copy_from_table_basics (line 21) | async def test_copy_from_table_basics(self):
    method test_copy_from_table_large_rows (line 85) | async def test_copy_from_table_large_rows(self):
    method test_copy_from_query_basics (line 120) | async def test_copy_from_query_basics(self):
    method test_copy_from_query_with_args (line 146) | async def test_copy_from_query_with_args(self):
    method test_copy_from_query_to_path (line 171) | async def test_copy_from_query_to_path(self):
    method test_copy_from_query_to_path_like (line 193) | async def test_copy_from_query_to_path_like(self):
    method test_copy_from_query_to_bad_output (line 223) | async def test_copy_from_query_to_bad_output(self):
    method test_copy_from_query_to_sink (line 234) | async def test_copy_from_query_to_sink(self):
    method test_copy_from_query_cancellation_explicit (line 261) | async def test_copy_from_query_cancellation_explicit(self):
    method test_copy_from_query_cancellation_on_sink_error (line 283) | async def test_copy_from_query_cancellation_on_sink_error(self):
    method test_copy_from_query_cancellation_while_waiting_for_data (line 302) | async def test_copy_from_query_cancellation_while_waiting_for_data(self):
    method test_copy_from_query_timeout_1 (line 322) | async def test_copy_from_query_timeout_1(self):
    method test_copy_from_query_timeout_2 (line 340) | async def test_copy_from_query_timeout_2(self):
  class TestCopyTo (line 364) | class TestCopyTo(tb.ConnectedTestCase):
    method test_copy_to_table_basics (line 366) | async def test_copy_to_table_basics(self):
    method test_copy_to_table_large_rows (line 462) | async def test_copy_to_table_large_rows(self):
    method test_copy_to_table_from_bytes_like (line 489) | async def test_copy_to_table_from_bytes_like(self):
    method test_copy_to_table_fail_in_source_1 (line 501) | async def test_copy_to_table_fail_in_source_1(self):
    method test_copy_to_table_fail_in_source_2 (line 526) | async def test_copy_to_table_fail_in_source_2(self):
    method test_copy_to_table_timeout (line 555) | async def test_copy_to_table_timeout(self):
    method test_copy_to_table_from_file_path (line 584) | async def test_copy_to_table_from_file_path(self):
    method test_copy_records_to_table_1 (line 626) | async def test_copy_records_to_table_1(self):
    method test_copy_records_to_table_where (line 650) | async def test_copy_records_to_table_where(self):
    method test_copy_records_to_table_async (line 679) | async def test_copy_records_to_table_async(self):
    method test_copy_records_to_table_no_binary_codec (line 703) | async def test_copy_records_to_table_no_binary_codec(self):

FILE: tests/test_cursor.py
  class TestIterableCursor (line 14) | class TestIterableCursor(tb.ConnectedTestCase):
    method test_cursor_iterable_01 (line 16) | async def test_cursor_iterable_01(self):
    method test_cursor_iterable_02 (line 31) | async def test_cursor_iterable_02(self):
    method test_cursor_iterable_03 (line 51) | async def test_cursor_iterable_03(self):
    method test_cursor_iterable_04 (line 65) | async def test_cursor_iterable_04(self):
    method test_cursor_iterable_05 (line 74) | async def test_cursor_iterable_05(self):
    method test_cursor_iterable_06 (line 83) | async def test_cursor_iterable_06(self):
  class TestCursor (line 104) | class TestCursor(tb.ConnectedTestCase):
    method test_cursor_01 (line 106) | async def test_cursor_01(self):
    method test_cursor_02 (line 112) | async def test_cursor_02(self):
    method test_cursor_03 (line 150) | async def test_cursor_03(self):
    method test_cursor_04 (line 157) | async def test_cursor_04(self):

FILE: tests/test_exceptions.py
  class TestExceptions (line 12) | class TestExceptions(tb.ConnectedTestCase):
    method test_exceptions_exported (line 14) | def test_exceptions_exported(self):
    method test_exceptions_unpacking (line 25) | async def test_exceptions_unpacking(self):
    method test_exceptions_str (line 36) | async def test_exceptions_str(self):

FILE: tests/test_execute.py
  class TestExecuteScript (line 15) | class TestExecuteScript(tb.ConnectedTestCase):
    method test_execute_script_1 (line 17) | async def test_execute_script_1(self):
    method test_execute_script_2 (line 29) | async def test_execute_script_2(self):
    method test_execute_script_3 (line 43) | async def test_execute_script_3(self):
    method test_execute_script_check_transactionality (line 52) | async def test_execute_script_check_transactionality(self):
    method test_execute_exceptions_1 (line 66) | async def test_execute_exceptions_1(self):
    method test_execute_script_interrupted_close (line 72) | async def test_execute_script_interrupted_close(self):
    method test_execute_script_interrupted_terminate (line 85) | async def test_execute_script_interrupted_terminate(self):
  class TestExecuteMany (line 102) | class TestExecuteMany(tb.ConnectedTestCase):
    method setUp (line 103) | def setUp(self):
    method tearDown (line 108) | def tearDown(self):
    method test_executemany_basic (line 112) | async def test_executemany_basic(self):
    method test_executemany_returning (line 142) | async def test_executemany_returning(self):
    method test_executemany_bad_input (line 181) | async def test_executemany_bad_input(self):
    method test_executemany_error_in_input_gen (line 200) | async def test_executemany_error_in_input_gen(self):
    method test_executemany_server_failure (line 215) | async def test_executemany_server_failure(self):
    method test_executemany_server_failure_after_writes (line 225) | async def test_executemany_server_failure_after_writes(self):
    method test_executemany_server_failure_during_writes (line 235) | async def test_executemany_server_failure_during_writes(self):
    method test_executemany_client_failure_after_writes (line 256) | async def test_executemany_client_failure_after_writes(self):
    method test_executemany_timeout (line 264) | async def test_executemany_timeout(self):
    method test_executemany_timeout_flow_control (line 272) | async def test_executemany_timeout_flow_control(self):
    method test_executemany_client_failure_in_transaction (line 304) | async def test_executemany_client_failure_in_transaction(self):
    method test_executemany_client_server_failure_conflict (line 319) | async def test_executemany_client_server_failure_conflict(self):
    method test_executemany_prepare (line 328) | async def test_executemany_prepare(self):

FILE: tests/test_introspection.py
  class SlowIntrospectionConnection (line 18) | class SlowIntrospectionConnection(apg_con.Connection):
    method _introspect_types (line 22) | async def _introspect_types(self, *args, **kwargs):
  class TestIntrospection (line 28) | class TestIntrospection(tb.ConnectedTestCase):
    method setUpClass (line 30) | def setUpClass(cls):
    method tearDownClass (line 37) | def tearDownClass(cls):
    method get_server_settings (line 47) | def get_server_settings(cls):
    method setUp (line 52) | def setUp(self):
    method _add_custom_codec (line 56) | async def _add_custom_codec(self, conn):
    method test_introspection_on_large_db (line 67) | async def test_introspection_on_large_db(self):
    method test_introspection_no_stmt_cache_01 (line 82) | async def test_introspection_no_stmt_cache_01(self):
    method test_introspection_no_stmt_cache_02 (line 103) | async def test_introspection_no_stmt_cache_02(self):
    method test_introspection_no_stmt_cache_03 (line 125) | async def test_introspection_no_stmt_cache_03(self):
    method test_introspection_sticks_for_ps (line 135) | async def test_introspection_sticks_for_ps(self):
    method test_introspection_retries_after_cache_bust (line 160) | async def test_introspection_retries_after_cache_bust(self):
    method test_introspection_loads_basetypes_of_domains (line 201) | async def test_introspection_loads_basetypes_of_domains(self):

FILE: tests/test_listeners.py
  class TestListeners (line 17) | class TestListeners(tb.ClusterTestCase):
    method test_listen_01 (line 19) | async def test_listen_01(self):
    method test_listen_02 (line 72) | async def test_listen_02(self):
    method test_listen_notletters (line 90) | async def test_listen_notletters(self):
    method test_dangling_listener_warns (line 108) | async def test_dangling_listener_warns(self):
  class TestLogListeners (line 121) | class TestLogListeners(tb.ConnectedTestCase):
    method test_log_listener_01 (line 126) | async def test_log_listener_01(self):
    method test_log_listener_02 (line 230) | async def test_log_listener_02(self):
    method test_log_listener_03 (line 271) | async def test_log_listener_03(self):
    method test_dangling_log_listener_warns (line 301) | async def test_dangling_log_listener_warns(self):
  class TestConnectionTerminationListener (line 318) | class TestConnectionTerminationListener(tb.ProxiedClusterTestCase):
    method test_connection_termination_callback_called_on_remote (line 320) | async def test_connection_termination_callback_called_on_remote(self):
    method test_connection_termination_callback_called_on_local (line 344) | async def test_connection_termination_callback_called_on_local(self):

FILE: tests/test_logging.py
  class LogCollector (line 7) | class LogCollector:
    method __init__ (line 8) | def __init__(self):
    method __call__ (line 11) | def __call__(self, record):
  class TestQueryLogging (line 15) | class TestQueryLogging(tb.ConnectedTestCase):
    method test_logging_context (line 17) | async def test_logging_context(self):
    method test_error_logging (line 40) | async def test_error_logging(self):

FILE: tests/test_pool.py
  class SlowResetConnection (line 30) | class SlowResetConnection(pg_connection.Connection):
    method reset (line 32) | async def reset(self, *, timeout=None):
  class SlowCancelConnection (line 37) | class SlowCancelConnection(pg_connection.Connection):
    method _cancel (line 39) | async def _cancel(self, waiter):
  class TestPool (line 44) | class TestPool(tb.ConnectedTestCase):
    method test_pool_01 (line 46) | async def test_pool_01(self):
    method test_pool_02 (line 61) | async def test_pool_02(self):
    method test_pool_03 (line 75) | async def test_pool_03(self):
    method test_pool_04 (line 86) | async def test_pool_04(self):
    method test_pool_05 (line 109) | async def test_pool_05(self):
    method test_pool_06 (line 123) | async def test_pool_06(self):
    method test_pool_07 (line 137) | async def test_pool_07(self):
    method test_pool_08 (line 197) | async def test_pool_08(self):
    method test_pool_09 (line 205) | async def test_pool_09(self):
    method test_pool_10 (line 223) | async def test_pool_10(self):
    method test_pool_11 (line 233) | async def test_pool_11(self):
    method test_pool_12 (line 290) | async def test_pool_12(self):
    method test_pool_13 (line 300) | async def test_pool_13(self):
    method test_pool_init_run_until_complete (line 314) | def test_pool_init_run_until_complete(self):
    method test_pool_exception_in_setup_and_init (line 319) | async def test_pool_exception_in_setup_and_init(self):
    method test_pool_auth (line 362) | async def test_pool_auth(self):
    method test_pool_handles_task_cancel_in_acquire_with_timeout (line 412) | async def test_pool_handles_task_cancel_in_acquire_with_timeout(self):
    method test_pool_handles_task_cancel_in_release (line 432) | async def test_pool_handles_task_cancel_in_release(self):
    method test_pool_handles_query_cancel_in_release (line 453) | async def test_pool_handles_query_cancel_in_release(self):
    method test_pool_no_acquire_deadlock (line 474) | async def test_pool_no_acquire_deadlock(self):
    method test_pool_config_persistence (line 489) | async def test_pool_config_persistence(self):
    method test_pool_release_in_xact (line 518) | async def test_pool_release_in_xact(self):
    method test_pool_connection_methods (line 547) | async def test_pool_connection_methods(self):
    method test_pool_connection_execute_many (line 598) | async def test_pool_connection_execute_many(self):
    method test_pool_max_inactive_time_01 (line 626) | async def test_pool_max_inactive_time_01(self):
    method test_pool_max_inactive_time_02 (line 645) | async def test_pool_max_inactive_time_02(self):
    method test_pool_max_inactive_time_03 (line 668) | async def test_pool_max_inactive_time_03(self):
    method test_pool_max_inactive_time_04 (line 688) | async def test_pool_max_inactive_time_04(self):
    method test_pool_max_inactive_time_05 (line 719) | async def test_pool_max_inactive_time_05(self):
    method test_pool_handles_inactive_connection_errors (line 737) | async def test_pool_handles_inactive_connection_errors(self):
    method test_pool_size_and_capacity (line 757) | async def test_pool_size_and_capacity(self):
    method test_pool_closing (line 778) | async def test_pool_closing(self):
    method test_pool_handles_transaction_exit_in_asyncgen_1 (line 789) | async def test_pool_handles_transaction_exit_in_asyncgen_1(self):
    method test_pool_handles_transaction_exit_in_asyncgen_2 (line 810) | async def test_pool_handles_transaction_exit_in_asyncgen_2(self):
    method test_pool_handles_asyncgen_finalization (line 834) | async def test_pool_handles_asyncgen_finalization(self):
    method test_pool_close_waits_for_release (line 855) | async def test_pool_close_waits_for_release(self):
    method test_pool_close_timeout (line 878) | async def test_pool_close_timeout(self):
    method test_pool_expire_connections (line 897) | async def test_pool_expire_connections(self):
    method test_pool_set_connection_args (line 910) | async def test_pool_set_connection_args(self):
    method test_pool_init_race (line 953) | async def test_pool_init_race(self):
    method test_pool_init_and_use_race (line 967) | async def test_pool_init_and_use_race(self):
    method test_pool_remote_close (line 982) | async def test_pool_remote_close(self):
  class TestPoolReconnectWithTargetSessionAttrs (line 1009) | class TestPoolReconnectWithTargetSessionAttrs(tb.ClusterTestCase):
    method setup_cluster (line 1012) | def setup_cluster(cls):
    method simulate_cluster_recovery_mode (line 1016) | async def simulate_cluster_recovery_mode(self):
    method test_full_reconnect_on_node_change_role (line 1034) | async def test_full_reconnect_on_node_change_role(self):
  class TestHotStandby (line 1073) | class TestHotStandby(tb.HotStandbyTestCase):
    method create_pool (line 1074) | def create_pool(self, **kwargs):
    method test_standby_pool_01 (line 1079) | async def test_standby_pool_01(self):
    method test_standby_cursors (line 1095) | async def test_standby_cursors(self):

FILE: tests/test_prepare.py
  class TestPrepare (line 17) | class TestPrepare(tb.ConnectedTestCase):
    method test_prepare_01 (line 19) | async def test_prepare_01(self):
    method test_prepare_02 (line 33) | async def test_prepare_02(self):
    method test_prepare_03 (line 37) | async def test_prepare_03(self):
    method test_prepare_04 (line 65) | async def test_prepare_04(self):
    method test_prepare_05_unknownoid (line 83) | async def test_prepare_05_unknownoid(self):
    method test_prepare_06_interrupted_close (line 87) | async def test_prepare_06_interrupted_close(self):
    method test_prepare_07_interrupted_terminate (line 103) | async def test_prepare_07_interrupted_terminate(self):
    method test_prepare_08_big_result (line 120) | async def test_prepare_08_big_result(self):
    method test_prepare_09_raise_error (line 129) | async def test_prepare_09_raise_error(self):
    method test_prepare_10_stmt_lru (line 144) | async def test_prepare_10_stmt_lru(self):
    method test_prepare_11_stmt_gc (line 197) | async def test_prepare_11_stmt_gc(self):
    method test_prepare_12_stmt_gc (line 216) | async def test_prepare_12_stmt_gc(self):
    method test_prepare_13_connect (line 243) | async def test_prepare_13_connect(self):
    method test_prepare_14_explain (line 254) | async def test_prepare_14_explain(self):
    method test_prepare_15_stmt_gc_cache_disabled (line 284) | async def test_prepare_15_stmt_gc_cache_disabled(self):
    method test_prepare_16_command_result (line 314) | async def test_prepare_16_command_result(self):
    method test_prepare_17_stmt_closed_lru (line 341) | async def test_prepare_17_stmt_closed_lru(self):
    method test_prepare_18_empty_result (line 350) | async def test_prepare_18_empty_result(self):
    method test_prepare_19_concurrent_calls (line 361) | async def test_prepare_19_concurrent_calls(self):
    method test_prepare_20_concurrent_calls (line 375) | async def test_prepare_20_concurrent_calls(self):
    method test_prepare_21_errors (line 397) | async def test_prepare_21_errors(self):
    method test_prepare_22_empty (line 405) | async def test_prepare_22_empty(self):
    method test_prepare_statement_invalid (line 415) | async def test_prepare_statement_invalid(self):
    method test_prepare_23_no_stmt_cache_seq (line 434) | async def test_prepare_23_no_stmt_cache_seq(self):
    method test_prepare_24_max_lifetime (line 465) | async def test_prepare_24_max_lifetime(self):
    method test_prepare_25_max_lifetime_reset (line 486) | async def test_prepare_25_max_lifetime_reset(self):
    method test_prepare_26_max_lifetime_max_size (line 502) | async def test_prepare_26_max_lifetime_max_size(self):
    method test_prepare_27_max_cacheable_statement_size (line 518) | async def test_prepare_27_max_cacheable_statement_size(self):
    method test_prepare_28_max_args (line 538) | async def test_prepare_28_max_args(self):
    method test_prepare_29_duplicates (line 548) | async def test_prepare_29_duplicates(self):
    method test_prepare_30_invalid_arg_count (line 561) | async def test_prepare_30_invalid_arg_count(self):
    method test_prepare_31_pgbouncer_note (line 572) | async def test_prepare_31_pgbouncer_note(self):
    method test_prepare_does_not_use_cache (line 597) | async def test_prepare_does_not_use_cache(self):
    method test_prepare_explicitly_named (line 604) | async def test_prepare_explicitly_named(self):
    method test_prepare_fetchmany (line 615) | async def test_prepare_fetchmany(self):

FILE: tests/test_record.py
  class CustomRecord (line 25) | class CustomRecord(asyncpg.Record):
  class AnotherCustomRecord (line 29) | class AnotherCustomRecord(asyncpg.Record):
  class TestRecord (line 33) | class TestRecord(tb.ConnectedTestCase):
    method checkref (line 36) | def checkref(self, *objs):
    method test_record_gc (line 48) | def test_record_gc(self):
    method test_record_freelist_ok (line 73) | def test_record_freelist_ok(self):
    method test_record_len_getindex (line 78) | def test_record_len_getindex(self):
    method test_record_slice (line 104) | def test_record_slice(self):
    method test_record_immutable (line 113) | def test_record_immutable(self):
    method test_record_repr (line 118) | def test_record_repr(self):
    method test_record_iter (line 144) | def test_record_iter(self):
    method test_record_values (line 150) | def test_record_values(self):
    method test_record_keys (line 157) | def test_record_keys(self):
    method test_record_items (line 163) | def test_record_items(self):
    method test_record_hash (line 200) | def test_record_hash(self):
    method test_record_contains (line 221) | def test_record_contains(self):
    method test_record_cmp (line 233) | def test_record_cmp(self):
    method test_record_get (line 284) | def test_record_get(self):
    method test_record_not_pickleable (line 291) | def test_record_not_pickleable(self):
    method test_record_empty (line 296) | def test_record_empty(self):
    method test_record_duplicate_colnames (line 311) | async def test_record_duplicate_colnames(self):
    method test_record_isinstance (line 341) | async def test_record_isinstance(self):
    method test_record_no_new (line 346) | async def test_record_no_new(self):
    method test_record_subclass_01 (line 355) | async def test_record_subclass_01(self):
    method test_record_subclass_02 (line 380) | async def test_record_subclass_02(self):
    method test_record_subclass_03 (line 427) | async def test_record_subclass_03(self):
    method test_record_subclass_04 (line 474) | async def test_record_subclass_04(self):
    method test_record_subclass_05 (line 520) | async def test_record_subclass_05(self):
    method test_record_subclass_06 (line 537) | async def test_record_subclass_06(self):

FILE: tests/test_subinterpreters.py
  class TestSubinterpreters (line 17) | class TestSubinterpreters(unittest.TestCase):
    method test_record_module_loads_in_subinterpreter (line 18) | def test_record_module_loads_in_subinterpreter(self) -> None:
    method test_record_module_state_isolation (line 35) | def test_record_module_state_isolation(self) -> None:

FILE: tests/test_test.py
  class BaseSimpleTestCase (line 16) | class BaseSimpleTestCase:
    method test_tests_zero_error (line 18) | async def test_tests_zero_error(self):
  class TestTests (line 23) | class TestTests(unittest.TestCase):
    method test_tests_fail_1 (line 25) | def test_tests_fail_1(self):
  class TestHelpers (line 38) | class TestHelpers(tb.TestCase):
    method test_tests_assertLoopErrorHandlerCalled_01 (line 40) | async def test_tests_assertLoopErrorHandlerCalled_01(self):

FILE: tests/test_timeout.py
  class TestTimeout (line 18) | class TestTimeout(tb.ConnectedTestCase):
    method test_timeout_01 (line 20) | async def test_timeout_01(self):
    method test_timeout_02 (line 28) | async def test_timeout_02(self):
    method test_timeout_03 (line 38) | async def test_timeout_03(self):
    method test_timeout_04 (line 48) | async def test_timeout_04(self):
    method test_timeout_05 (line 65) | async def test_timeout_05(self):
    method test_timeout_06 (line 74) | async def test_timeout_06(self):
    method test_invalid_timeout (line 112) | async def test_invalid_timeout(self):
  class TestConnectionCommandTimeout (line 127) | class TestConnectionCommandTimeout(tb.ConnectedTestCase):
    method test_command_timeout_01 (line 130) | async def test_command_timeout_01(self):
  class SlowPrepareConnection (line 139) | class SlowPrepareConnection(pg_connection.Connection):
    method _get_statement (line 141) | async def _get_statement(self, query, timeout, **kwargs):
  class TestTimeoutCoversPrepare (line 146) | class TestTimeoutCoversPrepare(tb.ConnectedTestCase):
    method test_timeout_covers_prepare_01 (line 150) | async def test_timeout_covers_prepare_01(self):

FILE: tests/test_transaction.py
  class TestTransaction (line 13) | class TestTransaction(tb.ConnectedTestCase):
    method test_transaction_regular (line 15) | async def test_transaction_regular(self):
    method test_transaction_nested (line 47) | async def test_transaction_nested(self):
    method test_transaction_interface_errors (line 113) | async def test_transaction_interface_errors(self):
    method test_transaction_within_manual_transaction (line 162) | async def test_transaction_within_manual_transaction(self):
    method test_isolation_level (line 183) | async def test_isolation_level(self):
    method test_nested_isolation_level (line 214) | async def test_nested_isolation_level(self):

FILE: tests/test_types.py
  class TestTypes (line 13) | class TestTypes(tb.TestCase):
    method test_range_issubset (line 15) | def test_range_issubset(self):

FILE: tests/test_utils.py
  class TestUtils (line 14) | class TestUtils(tb.ConnectedTestCase):
    method test_mogrify_simple (line 16) | async def test_mogrify_simple(self):
    method test_mogrify_multiple (line 32) | async def test_mogrify_multiple(self):

FILE: tools/generate_exceptions.py
  function _get_error_name (line 39) | def _get_error_name(sqlstatename, msgtype, sqlstate):
  function main (line 68) | def main():

FILE: tools/generate_type_map.py
  function runner (line 46) | async def runner(args):
  function main (line 113) | def main():
Condensed preview — 121 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,191K chars).
[
  {
    "path": ".clang-format",
    "chars": 441,
    "preview": "# A clang-format style that approximates Python's PEP 7\nBasedOnStyle: Google\nAlwaysBreakAfterReturnType: All\nAllowShortI"
  },
  {
    "path": ".clangd",
    "chars": 77,
    "preview": "Diagnostics:\n  Includes:\n    IgnoreHeader:\n      - \"pythoncapi_compat.*\\\\.h\"\n"
  },
  {
    "path": ".flake8",
    "chars": 252,
    "preview": "[flake8]\nselect = C90,E,F,W,Y0\nignore = E402,E731,W503,W504,E252\nexclude = .git,__pycache__,build,dist,.eggs,.github,.lo"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 855,
    "preview": "<!--\nThank you for reporting an issue/feature request.\n\nIf this is a feature request, please disregard this template.  I"
  },
  {
    "path": ".github/RELEASING.rst",
    "chars": 1502,
    "preview": "Releasing asyncpg\n=================\n\nWhen making an asyncpg release follow the below checklist.\n\n1. Remove the ``.dev0``"
  },
  {
    "path": ".github/release_log.py",
    "chars": 1292,
    "preview": "#!/usr/bin/env python3\n#\n# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This"
  },
  {
    "path": ".github/workflows/install-krb5.sh",
    "chars": 1242,
    "preview": "#!/bin/bash\n\nset -Eexuo pipefail\nshopt -s nullglob\n\nif [[ $OSTYPE == linux* ]]; then\n    if [ \"$(id -u)\" = \"0\" ]; then\n "
  },
  {
    "path": ".github/workflows/install-postgres.sh",
    "chars": 2137,
    "preview": "#!/bin/bash\n\nset -Eexuo pipefail\nshopt -s nullglob\n\nif [[ $OSTYPE == linux* ]]; then\n    PGVERSION=${PGVERSION:-12}\n\n   "
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 6655,
    "preview": "name: Release\n\non:\n  pull_request:\n    branches:\n      - \"master\"\n      - \"ci\"\n      - \"[0-9]+.[0-9x]+*\"\n    paths:\n    "
  },
  {
    "path": ".github/workflows/tests.yml",
    "chars": 4495,
    "preview": "name: Tests\n\non:\n  push:\n    branches:\n      - master\n      - ci\n  pull_request:\n    branches:\n      - master\n\njobs:\n  t"
  },
  {
    "path": ".gitignore",
    "chars": 362,
    "preview": "*._*\n*.pyc\n*.pyo\n*.ymlc\n*.ymlc~\n*.scssc\n*.so\n*.pyd\n*~\n.#*\n.DS_Store\n.project\n.pydevproject\n.settings\n.idea\n/.ropeproject"
  },
  {
    "path": ".gitmodules",
    "chars": 106,
    "preview": "[submodule \"asyncpg/pgproto\"]\n\tpath = asyncpg/pgproto\n\turl = https://github.com/MagicStack/py-pgproto.git\n"
  },
  {
    "path": "AUTHORS",
    "chars": 130,
    "preview": "Main contributors\n=================\n\nMagicStack Inc.:\n    Elvis Pranskevichus <elvis@magic.io>\n    Yury Selivanov <yury@"
  },
  {
    "path": "LICENSE",
    "chars": 11466,
    "preview": "Copyright (C) 2016-present the asyncpg authors and contributors.\n\n                                 Apache License\n      "
  },
  {
    "path": "MANIFEST.in",
    "chars": 239,
    "preview": "recursive-include docs *.py *.rst Makefile *.css\nrecursive-include examples *.py\nrecursive-include tests *.py *.pem\nrecu"
  },
  {
    "path": "Makefile",
    "chars": 956,
    "preview": ".PHONY: compile debug test quicktest clean all\n\n\nPYTHON ?= python\nROOT = $(dir $(realpath $(firstword $(MAKEFILE_LIST)))"
  },
  {
    "path": "README.rst",
    "chars": 2990,
    "preview": "asyncpg -- A fast PostgreSQL Database Client Library for Python/asyncio\n================================================"
  },
  {
    "path": "asyncpg/.gitignore",
    "chars": 7,
    "preview": "*.html\n"
  },
  {
    "path": "asyncpg/__init__.py",
    "chars": 647,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/_asyncio_compat.py",
    "chars": 2540,
    "preview": "# Backports from Python/Lib/asyncio for older Pythons\n#\n# Copyright (c) 2001-2023 Python Software Foundation; All Rights"
  },
  {
    "path": "asyncpg/_testbase/__init__.py",
    "chars": 16499,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/_testbase/fuzzer.py",
    "chars": 9804,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/_version.py",
    "chars": 646,
    "preview": "# This file MUST NOT contain anything but the __version__ assignment.\n#\n# When making a release, change the value of __v"
  },
  {
    "path": "asyncpg/cluster.py",
    "chars": 24476,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/compat.py",
    "chars": 2459,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/connect_utils.py",
    "chars": 43438,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/connection.py",
    "chars": 99069,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/connresource.py",
    "chars": 1384,
    "preview": "\n# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of async"
  },
  {
    "path": "asyncpg/cursor.py",
    "chars": 9160,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/exceptions/__init__.py",
    "chars": 29157,
    "preview": "# GENERATED FROM postgresql/src/backend/utils/errcodes.txt\n# DO NOT MODIFY, use tools/generate_exceptions.py to update\n\n"
  },
  {
    "path": "asyncpg/exceptions/_base.py",
    "chars": 9260,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/introspection.py",
    "chars": 9340,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/pool.py",
    "chars": 42368,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/prepared_stmt.py",
    "chars": 9783,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/.gitignore",
    "chars": 5,
    "preview": "/*.c\n"
  },
  {
    "path": "asyncpg/protocol/__init__.py",
    "chars": 359,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/codecs/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "asyncpg/protocol/codecs/array.pyx",
    "chars": 29486,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/codecs/base.pxd",
    "chars": 6614,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/codecs/base.pyx",
    "chars": 34460,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/codecs/pgproto.pyx",
    "chars": 17175,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/codecs/range.pyx",
    "chars": 6359,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/codecs/record.pyx",
    "chars": 2362,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/codecs/textutils.pyx",
    "chars": 2011,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/consts.pxi",
    "chars": 381,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/coreproto.pxd",
    "chars": 6215,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/coreproto.pyx",
    "chars": 41005,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/cpythonx.pxd",
    "chars": 613,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/encodings.pyx",
    "chars": 1634,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/pgtypes.pxi",
    "chars": 6918,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/prepared_stmt.pxd",
    "chars": 1115,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/prepared_stmt.pyx",
    "chars": 13036,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/protocol.pxd",
    "chars": 1927,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/protocol.pyi",
    "chars": 9108,
    "preview": "import asyncio\nimport asyncio.protocols\nimport hmac\nfrom codecs import CodecInfo\nfrom collections.abc import Callable, I"
  },
  {
    "path": "asyncpg/protocol/protocol.pyx",
    "chars": 34473,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/record/pythoncapi_compat.h",
    "chars": 69898,
    "preview": "// Header file providing new C API functions to old Python versions.\n//\n// File distributed under the Zero Clause BSD (0"
  },
  {
    "path": "asyncpg/protocol/record/pythoncapi_compat_extras.h",
    "chars": 1962,
    "preview": "#ifndef PYTHONCAPI_COMPAT_EXTRAS\n#define PYTHONCAPI_COMPAT_EXTRAS\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <Pyt"
  },
  {
    "path": "asyncpg/protocol/record/recordobj.c",
    "chars": 34423,
    "preview": "/* Big parts of this file are copied (with modifications) from\n   CPython/Objects/tupleobject.c.\n\n   Portions Copyright "
  },
  {
    "path": "asyncpg/protocol/record/recordobj.h",
    "chars": 699,
    "preview": "#ifndef APG_RECORDOBJ_H\n#define APG_RECORDOBJ_H\n\n#include <Python.h>\n\n\ntypedef struct {\n    PyObject_HEAD\n    PyObject *"
  },
  {
    "path": "asyncpg/protocol/record.pyi",
    "chars": 741,
    "preview": "from typing import (\n    Any,\n    TypeVar,\n    overload,\n)\n\nfrom collections.abc import Iterator\n\n\n_T = TypeVar(\"_T\")\n\n\n"
  },
  {
    "path": "asyncpg/protocol/recordcapi.pxd",
    "chars": 360,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/scram.pxd",
    "chars": 1299,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/scram.pyx",
    "chars": 14594,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/settings.pxd",
    "chars": 1066,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/protocol/settings.pyx",
    "chars": 3777,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/serverversion.py",
    "chars": 2133,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/transaction.py",
    "chars": 8497,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/types.py",
    "chars": 5512,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "asyncpg/utils.py",
    "chars": 1495,
    "preview": "# Copyright (C) 2016-present the ayncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncpg"
  },
  {
    "path": "docs/.gitignore",
    "chars": 18,
    "preview": "_build\n_templates\n"
  },
  {
    "path": "docs/Makefile",
    "chars": 7614,
    "preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD "
  },
  {
    "path": "docs/_static/theme_overrides.css",
    "chars": 266,
    "preview": "/* override table width restrictions */\n@media screen and (min-width: 767px) {\n\n   .wy-table-responsive table td {\n     "
  },
  {
    "path": "docs/api/index.rst",
    "chars": 9249,
    "preview": ".. _asyncpg-api-reference:\n\n=============\nAPI Reference\n=============\n\n.. module:: asyncpg\n    :synopsis: A fast Postgre"
  },
  {
    "path": "docs/conf.py",
    "chars": 2379,
    "preview": "#!/usr/bin/env python3\n\nimport os\nimport sys\n\nsys.path.insert(0, os.path.abspath('..'))\n\nversion_file = os.path.join(os."
  },
  {
    "path": "docs/faq.rst",
    "chars": 3709,
    "preview": ".. _asyncpg-faq:\n\n\nFrequently Asked Questions\n==========================\n\nDoes asyncpg support DB-API?\n~~~~~~~~~~~~~~~~~"
  },
  {
    "path": "docs/index.rst",
    "chars": 917,
    "preview": ".. image:: https://github.com/MagicStack/asyncpg/workflows/Tests/badge.svg\n   :target: https://github.com/MagicStack/asy"
  },
  {
    "path": "docs/installation.rst",
    "chars": 2134,
    "preview": ".. _asyncpg-installation:\n\n\nInstallation\n============\n\n**asyncpg** has no external dependencies when not using GSSAPI/SS"
  },
  {
    "path": "docs/requirements.txt",
    "chars": 39,
    "preview": "sphinxcontrib-asyncio\nsphinx_rtd_theme\n"
  },
  {
    "path": "docs/usage.rst",
    "chars": 18172,
    "preview": ".. _asyncpg-examples:\n\n\nasyncpg Usage\n=============\n\nThe interaction with the database normally starts with a call to\n:f"
  },
  {
    "path": "pyproject.toml",
    "chars": 3710,
    "preview": "[project]\nname = \"asyncpg\"\ndescription = \"An asyncio PostgreSQL driver\"\nauthors = [{name = \"MagicStack Inc\", email = \"he"
  },
  {
    "path": "setup.py",
    "chars": 8706,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/__init__.py",
    "chars": 627,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/certs/ca.cert.pem",
    "chars": 2191,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIGJjCCBA6gAwIBAgIICJCUmtkcj2MwDQYJKoZIhvcNAQELBQAwgaExCzAJBgNV\nBAYTAkNBMRAwDgYDVQQIDAdPbnR"
  },
  {
    "path": "tests/certs/ca.crl.pem",
    "chars": 1097,
    "preview": "-----BEGIN X509 CRL-----\nMIIDAjCB6wIBATANBgkqhkiG9w0BAQsFADCBoTELMAkGA1UEBhMCQ0ExEDAOBgNV\nBAgMB09udGFyaW8xEDAOBgNVBAcMB1"
  },
  {
    "path": "tests/certs/ca.key.pem",
    "chars": 3243,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIJKAIBAAKCAgEAj/qApdKq0XkpVo/sr3xs+vFEKpuo6C/VYHgNE73PEttyGt0u\n98HE03RoSEMDDmiLlsvptyd"
  },
  {
    "path": "tests/certs/client.cert.pem",
    "chars": 1452,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIEAzCCAuugAwIBAgIUPfej8IQ/5bCrihqWImrq2vKPOq0wDQYJKoZIhvcNAQEL\nBQAwgaMxCzAJBgNVBAYTAkNBMRA"
  },
  {
    "path": "tests/certs/client.csr.pem",
    "chars": 1066,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIC2zCCAcMCAQAwgZUxCzAJBgNVBAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAw\nDgYDVQQHDAdUb3JvbnR"
  },
  {
    "path": "tests/certs/client.key.pem",
    "chars": 1675,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAmOI/0iT8pFEsr0Yy+gfybUs74bKuvwbPfoumYokxH8+nBMv7\nWk6RhIaE7JPcLD3+RZYslEK"
  },
  {
    "path": "tests/certs/client.key.protected.pem",
    "chars": 1766,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: AES-256-CBC,B222CD7D00828606A07DBC489D400921\n\nLRHsNGUsD"
  },
  {
    "path": "tests/certs/client_ca.cert.pem",
    "chars": 1505,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIEKTCCAxGgAwIBAgIUKmL8tfNS9LIB6GLB9RpZpTyk3uIwDQYJKoZIhvcNAQEL\nBQAwgaMxCzAJBgNVBAYTAkNBMRA"
  },
  {
    "path": "tests/certs/client_ca.cert.srl",
    "chars": 41,
    "preview": "3DF7A3F0843FE5B0AB8A1A96226AEADAF28F3AAD\n"
  },
  {
    "path": "tests/certs/client_ca.key.pem",
    "chars": 1679,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAptRYfxKiWExfZguQDva53bIqYa4lJwZA86Qu0peBUcsdE6zy\nHNgVv4XSMim1FH12KQ4KPKu"
  },
  {
    "path": "tests/certs/gen.py",
    "chars": 6930,
    "preview": "import datetime\nimport os\n\nfrom cryptography import x509\nfrom cryptography.hazmat import backends\nfrom cryptography.hazm"
  },
  {
    "path": "tests/certs/server.cert.pem",
    "chars": 2451,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIG5jCCBM6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgaExCzAJBgNVBAYTAkNB\nMRAwDgYDVQQIDAdPbnRhcmlvMRA"
  },
  {
    "path": "tests/certs/server.crl.pem",
    "chars": 1097,
    "preview": "-----BEGIN X509 CRL-----\nMIIDAjCB6wIBATANBgkqhkiG9w0BAQsFADCBoTELMAkGA1UEBhMCQ0ExEDAOBgNV\nBAgMB09udGFyaW8xEDAOBgNVBAcMB1"
  },
  {
    "path": "tests/certs/server.key.pem",
    "chars": 3243,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIJKQIBAAKCAgEA3F017q/obCM1SsHY5dFz72pFgVMhBIZ6kdIInbFv7RmEykZz\nubbJnrgwgYDO5FKGUNO+a80"
  },
  {
    "path": "tests/test__environment.py",
    "chars": 1441,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test__sourcecode.py",
    "chars": 2214,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_adversity.py",
    "chars": 3176,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_cache_invalidation.py",
    "chars": 16559,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_cancellation.py",
    "chars": 3119,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_codecs.py",
    "chars": 68302,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_connect.py",
    "chars": 82962,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_copy.py",
    "chars": 21958,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_cursor.py",
    "chars": 5923,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_exceptions.py",
    "chars": 2024,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_execute.py",
    "chars": 12170,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_introspection.py",
    "chars": 7536,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_listeners.py",
    "chars": 11656,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_logging.py",
    "chars": 1550,
    "preview": "import asyncio\n\nfrom asyncpg import _testbase as tb\nfrom asyncpg import exceptions\n\n\nclass LogCollector:\n    def __init_"
  },
  {
    "path": "tests/test_pool.py",
    "chars": 38666,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_prepare.py",
    "chars": 22707,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_record.py",
    "chars": 18447,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_subinterpreters.py",
    "chars": 2055,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_test.py",
    "chars": 1289,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_timeout.py",
    "chars": 6493,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_transaction.py",
    "chars": 9623,
    "preview": "# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncp"
  },
  {
    "path": "tests/test_types.py",
    "chars": 2088,
    "preview": "# Copyright (C) 2016-present the ayncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncpg"
  },
  {
    "path": "tests/test_utils.py",
    "chars": 1198,
    "preview": "# Copyright (C) 2016-present the ayncpg authors and contributors\n# <see AUTHORS file>\n#\n# This module is part of asyncpg"
  },
  {
    "path": "tools/generate_exceptions.py",
    "chars": 5257,
    "preview": "#!/usr/bin/env python3\n#\n# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This"
  },
  {
    "path": "tools/generate_type_map.py",
    "chars": 3717,
    "preview": "#!/usr/bin/env python3\n#\n# Copyright (C) 2016-present the asyncpg authors and contributors\n# <see AUTHORS file>\n#\n# This"
  }
]

About this extraction

This page contains the full source code of the MagicStack/asyncpg GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 121 files (1.1 MB), approximately 271.9k tokens, and a symbol index with 1440 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!