[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[Makefile]\nindent_style = tab\n\n[*.{py,pyx,pxd,pxi,yml,h}]\nindent_size = 4\nindent_style = space\n"
  },
  {
    "path": ".flake8",
    "content": "[flake8]\nfilename = *.py,*.pyi\nignore = E402,E731,D100,D101,D102,D103,D104,D105,W503,W504,E252\nexclude = .git,__pycache__,build,dist,.eggs,postgres,vendor\n\nper-file-ignores =\n    *.pyx,*.pxd,*.pxi: E211, E222, E225, E226, E227, E999\n    *.pyi: F401, F403, F405, F811, E127, E128, E203, E266, E301, E302, E305, E501, E701, E704, E741, B303, W503, W504\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "<!--\nThanks for wanting to report an issue you've found in uvloop. Please fill in\nthe template below.\n\nIt will be much easier for us to fix the issue if a test case that reproduces\nthe problem is provided, with clear instructions on how to run it.\n\nThank you!\n-->\n\n* **uvloop version**:\n* **Python version**:\n* **Platform**:\n* **Can you reproduce the bug with `PYTHONASYNCIODEBUG` in env?**:\n* **Does uvloop behave differently from vanilla asyncio? How?**:\n\n<!-- Enter your issue details below this comment. -->\n"
  },
  {
    "path": ".github/release_log.py",
    "content": "#!/usr/bin/env python3\n\n\nimport argparse\nimport json\nimport requests\nimport re\n\n\nBASE_URL = 'https://api.github.com/repos/magicstack/uvloop/compare'\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description='Generate release log.')\n    parser.add_argument('--to', dest='to_hash', default='master', type=str)\n    parser.add_argument('--from', dest='from_hash', type=str)\n    args = parser.parse_args()\n\n    r = requests.get(f'{BASE_URL}/{args.from_hash}...{args.to_hash}')\n    data = json.loads(r.text)\n\n    for commit in data['commits']:\n        message = commit['commit']['message']\n        first_line = message.partition('\\n\\n')[0]\n        if commit.get('author'):\n            username = '@{}'.format(commit['author']['login'])\n        else:\n            username = commit['commit']['author']['name']\n        sha = commit[\"sha\"][:8]\n\n        m = re.search(r'\\#(?P<num>\\d+)\\b', message)\n        if m:\n            issue_num = m.group('num')\n        else:\n            issue_num = None\n\n        print(f'* {first_line}')\n        print(f'  (by {username} in {sha}', end='')\n        if issue_num:\n            print(f' for #{issue_num})')\n        else:\n            print(')')\n        print()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  pull_request:\n    branches:\n      - \"master\"\n      - \"ci\"\n      - \"[0-9]+.[0-9x]+*\"\n    paths:\n      - \"uvloop/_version.py\"\n\njobs:\n  validate-release-request:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Validate release PR\n      uses: edgedb/action-release/validate-pr@bae6b9134e872166b43d218dd79397c851c41c9a\n      id: checkver\n      with:\n        require_team: Release Managers\n        require_approval: no\n        github_token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }}\n        version_file: uvloop/_version.py\n        version_line_pattern: |\n          __version__\\s*=\\s*(?:['\"])([[:PEP440:]])(?:['\"])\n\n    - name: Stop if not approved\n      if: steps.checkver.outputs.approved != 'true'\n      run: |\n        echo ::error::PR is not approved yet.\n        exit 1\n\n    - name: Store release version for later use\n      env:\n        VERSION: ${{ steps.checkver.outputs.version }}\n      run: |\n        mkdir -p dist/\n        echo \"${VERSION}\" > dist/VERSION\n\n    - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02  # v4.6.2\n      with:\n        name: dist-version\n        path: dist/\n\n  build-sdist:\n    needs: validate-release-request\n    runs-on: ubuntu-22.04\n\n    env:\n      PIP_DISABLE_PIP_VERSION_CHECK: 1\n\n    steps:\n    - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608  # v4.1.0\n      with:\n        fetch-depth: 50\n        submodules: true\n\n    - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c  # v6.0.0\n      with:\n        python-version: 3.x\n\n    - name: Build source distribution\n      run: |\n        python -m pip install --upgrade setuptools wheel pip\n        python setup.py sdist\n\n    - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02  # v4.6.2\n      with:\n        name: dist-sdist\n        path: dist/*.tar.*\n\n  build-wheels:\n    needs: validate-release-request\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        os: [ubuntu-latest, macos-latest, ubuntu-22.04-arm]\n        python:\n        - \"cp38\"\n        - \"cp39\"\n        - \"cp310\"\n        - \"cp311\"\n        - \"cp312\"\n        - \"cp313\"\n        - \"cp314\"\n        - \"cp314t\"\n        cibw_arch: [\"x86_64\", \"aarch64\", \"universal2\"]\n        exclude:\n          - os: ubuntu-latest\n            cibw_arch: universal2\n          - os: ubuntu-latest\n            cibw_arch: aarch64\n          - os: macos-latest\n            cibw_arch: aarch64\n          - os: ubuntu-22.04-arm\n            cibw_arch: x86_64\n          - os: ubuntu-22.04-arm\n            cibw_arch: universal2\n\n    defaults:\n      run:\n        shell: bash\n\n    env:\n      PIP_DISABLE_PIP_VERSION_CHECK: 1\n\n    steps:\n    - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608  # v4.1.0\n      with:\n        fetch-depth: 50\n        submodules: true\n\n    - name: Install macOS deps\n      if: startsWith(matrix.os, 'macos')\n      run: |\n        brew install gnu-sed libtool autoconf automake\n\n    - uses: pypa/cibuildwheel@7c619efba910c04005a835b110b057fc28fd6e93  # v3.2.0\n      env:\n        CIBW_BUILD_VERBOSITY: 1\n        CIBW_BUILD: ${{ matrix.python }}-*\n        CIBW_ARCHS: ${{ matrix.cibw_arch }}\n        CIBW_TEST_SKIP: \"*universal2:arm64\"\n\n    - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02  # v4.6.2\n      with:\n        name: dist-wheels-${{ matrix.os }}-${{ matrix.python }}-${{ matrix.cibw_arch }}\n        path: wheelhouse/*.whl\n\n  publish:\n    needs: [build-sdist, build-wheels]\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608  # v4.1.0\n      with:\n        fetch-depth: 5\n        submodules: false\n\n    - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0  # v5.0.0\n      with:\n        pattern: dist-*\n        merge-multiple: true\n        path: dist/\n\n    - name: Extract Release Version\n      id: relver\n      run: |\n        set -e\n        echo version=$(cat dist/VERSION) >> $GITHUB_OUTPUT\n        rm dist/VERSION\n\n    - name: Merge and tag the PR\n      uses: edgedb/action-release/merge@bae6b9134e872166b43d218dd79397c851c41c9a\n      with:\n        github_token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }}\n        ssh_key: ${{ secrets.RELEASE_BOT_SSH_KEY }}\n        gpg_key: ${{ secrets.RELEASE_BOT_GPG_KEY }}\n        gpg_key_id: \"5C468778062D87BF!\"\n        tag_name: v${{ steps.relver.outputs.version }}\n\n    - name: Publish Github Release\n      uses: elprans/gh-action-create-release@master\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      with:\n        tag_name: v${{ steps.relver.outputs.version }}\n        release_name: v${{ steps.relver.outputs.version }}\n        target: ${{ github.event.pull_request.base.ref }}\n        body: ${{ github.event.pull_request.body }}\n        draft: false\n\n    - run: |\n        ls -al dist/\n\n    - name: Upload to PyPI\n      uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e  # v1.13.0\n      with:\n        user: __token__\n        password: ${{ secrets.PYPI_TOKEN }}\n        # password: ${{ secrets.TEST_PYPI_TOKEN }}\n        # repository_url: https://test.pypi.org/legacy/\n"
  },
  {
    "path": ".github/workflows/tests.yml",
    "content": "name: Tests\n\non:\n  push:\n    branches:\n      - master\n      - ci\n  pull_request:\n    branches:\n      - master\n\njobs:\n  test:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        python-version:\n        - \"3.8\"\n        - \"3.9\"\n        - \"3.10\"\n        - \"3.11\"\n        - \"3.12\"\n        - \"3.13\"\n        - \"3.14\"\n        - \"3.14t\"\n        os: [ubuntu-latest, macos-latest]\n\n    env:\n      PIP_DISABLE_PIP_VERSION_CHECK: 1\n\n    steps:\n    - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608  # v4.1.0\n      with:\n        fetch-depth: 50\n        submodules: true\n\n    - name: Check if release PR.\n      uses: edgedb/action-release/validate-pr@bae6b9134e872166b43d218dd79397c851c41c9a\n      id: release\n      with:\n        github_token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }}\n        missing_version_ok: yes\n        version_file: uvloop/_version.py\n        version_line_pattern: |\n          __version__\\s*=\\s*(?:['\"])([[:PEP440:]])(?:['\"])\n\n    - name: Set up Python ${{ matrix.python-version }}\n      uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c  # v6.0.0\n      if: steps.release.outputs.version == 0\n      with:\n        python-version: ${{ matrix.python-version }}\n        allow-prereleases: true\n\n    - name: Install macOS deps\n      if: matrix.os == 'macos-latest' && steps.release.outputs.version == 0\n      run: |\n        brew install gnu-sed libtool autoconf automake\n\n    - name: Install Python Deps\n      if: steps.release.outputs.version == 0\n      run: |\n        pip install -e .[test,dev]\n\n    - name: Test\n      if: steps.release.outputs.version == 0\n      run: |\n        make test\n\n    - name: Test (debug build)\n      if: steps.release.outputs.version == 0\n      run: |\n        make distclean && make debug && make test\n\n  # This job exists solely to act as the test job aggregate to be\n  # targeted by branch policies.\n  regression-tests:\n    name: \"Regression Tests\"\n    needs: [test]\n    runs-on: ubuntu-latest\n\n    steps:\n      - run: echo OK\n"
  },
  {
    "path": ".gitignore",
    "content": "*._*\n*.pyc\n*.pyo\n*.ymlc\n*.ymlc~\n*.scssc\n*.so\n*~\n.#*\n.DS_Store\n.project\n.pydevproject\n.settings\n.idea\n/.ropeproject\n\\#*#\n/pub\n/test*.py\n/.local\n/perf.data*\n/config_local.yml\n/build\n__pycache__/\n.d8_history\n/*.egg\n/*.egg-info\n/dist\n/.cache\ndocs/_build\nuvloop/loop.*.pyd\n/.pytest_cache/\n/.mypy_cache/\n/.vscode\n/.eggs\n/.venv*\n/wheelhouse\n/uvloop-dev\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"vendor/libuv\"]\n\tpath = vendor/libuv\n\turl = https://github.com/libuv/libuv.git\n"
  },
  {
    "path": "LICENSE-APACHE",
    "content": "Copyright (C) 2016-present the uvloop authors and contributors.\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright (c) 2015-present MagicStack Inc.  http://magic.io\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "LICENSE-MIT",
    "content": "The MIT License\n\nCopyright (C) 2016-present the uvloop authors and contributors.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "MANIFEST.in",
    "content": "recursive-include docs *.py *.rst\nrecursive-include examples *.py\nrecursive-include tests *.py *.pem\nrecursive-include uvloop *.pyx *.pxd *.pxi *.py *.c *.h *.pyi py.typed\nrecursive-include vendor/libuv *\nrecursive-exclude vendor/libuv/.git *\nrecursive-exclude vendor/libuv/docs *\nrecursive-exclude vendor/libuv/img *\ninclude LICENSE-MIT LICENSE-APACHE README.rst Makefile performance.png .flake8 mypy.ini\n"
  },
  {
    "path": "Makefile",
    "content": ".PHONY: _default clean clean-libuv distclean compile debug docs test testinstalled release setup-build ci-clean\n\n\nPYTHON ?= python\nROOT = $(dir $(realpath $(firstword $(MAKEFILE_LIST))))\n\n\n_default: compile\n\n\nclean:\n\trm -fr dist/ doc/_build/ *.egg-info uvloop/loop.*.pyd uvloop/loop_d.*.pyd\n\trm -fr uvloop/*.c uvloop/*.html uvloop/*.so\n\trm -fr uvloop/handles/*.html uvloop/includes/*.html\n\tfind . -name '__pycache__' | xargs rm -rf\n\n\nci-clean: clean\n\trm -fr build/lib.* build/temp.* build/libuv\n\n\nclean-libuv:\n\t(cd vendor/libuv; git clean -dfX)\n\n\ndistclean: clean clean-libuv\n\trm -fr build/\n\n\nsetup-build:\n\t$(PYTHON) setup.py build_ext --inplace --cython-always\n\n\ncompile: clean setup-build\n\n\ndebug: clean\n\t$(PYTHON) setup.py build_ext --inplace --debug \\\n\t\t--cython-always \\\n\t\t--cython-annotate \\\n\t\t--cython-directives=\"linetrace=True\" \\\n\t\t--define UVLOOP_DEBUG,CYTHON_TRACE,CYTHON_TRACE_NOGIL\n\n\ndocs:\n\t$(PYTHON) setup.py build_ext --inplace build_sphinx\n\n\ntest:\n\tPYTHONASYNCIODEBUG=1 $(PYTHON) -m unittest discover -v tests\n\t$(PYTHON) -m unittest discover -v tests\n\n\ntestinstalled:\n\tcd \"$${HOME}\" && $(PYTHON) -m unittest discover -v $(ROOT)/tests\n"
  },
  {
    "path": "README.rst",
    "content": ".. image:: https://img.shields.io/github/actions/workflow/status/MagicStack/uvloop/tests.yml?branch=master\n    :target: https://github.com/MagicStack/uvloop/actions/workflows/tests.yml?query=branch%3Amaster\n\n.. image:: https://img.shields.io/pypi/v/uvloop.svg\n    :target: https://pypi.python.org/pypi/uvloop\n\n.. image:: https://pepy.tech/badge/uvloop\n    :target: https://pepy.tech/project/uvloop\n    :alt: PyPI - Downloads\n\n\nuvloop is a fast, drop-in replacement of the built-in asyncio\nevent loop.  uvloop is implemented in Cython and uses libuv\nunder the hood.\n\nThe project documentation can be found\n`here <http://uvloop.readthedocs.org/>`_.  Please also check out the\n`wiki <https://github.com/MagicStack/uvloop/wiki>`_.\n\n\nPerformance\n-----------\n\nuvloop makes asyncio 2-4x faster.\n\n.. image:: https://raw.githubusercontent.com/MagicStack/uvloop/master/performance.png\n    :target: http://magic.io/blog/uvloop-blazing-fast-python-networking/\n\nThe above chart shows the performance of an echo server with different\nmessage sizes.  The *sockets* benchmark uses ``loop.sock_recv()`` and\n``loop.sock_sendall()`` methods; the *streams* benchmark uses asyncio\nhigh-level streams, created by the ``asyncio.start_server()`` function;\nand the *protocol* benchmark uses ``loop.create_server()`` with a simple\necho protocol.  Read more about uvloop in a\n`blog post <http://magic.io/blog/uvloop-blazing-fast-python-networking/>`_\nabout it.\n\n\nInstallation\n------------\n\nuvloop requires Python 3.8 or greater and is available on PyPI.\nUse pip to install it::\n\n    $ pip install uvloop\n\nNote that it is highly recommended to **upgrade pip before** installing\nuvloop with::\n\n    $ pip install -U pip\n\n\nUsing uvloop\n------------\n\nAs of uvloop 0.18, the preferred way of using it is via the\n``uvloop.run()`` helper function:\n\n\n.. code:: python\n\n    import uvloop\n\n    async def main():\n        # Main entry-point.\n        ...\n\n    uvloop.run(main())\n\n``uvloop.run()`` works by simply configuring ``asyncio.run()``\nto use uvloop, passing all of the arguments to it, such as ``debug``,\ne.g. ``uvloop.run(main(), debug=True)``.\n\nWith Python 3.11 and earlier the following alternative\nsnippet can be used:\n\n.. code:: python\n\n    import asyncio\n    import sys\n\n    import uvloop\n\n    async def main():\n        # Main entry-point.\n        ...\n\n    if sys.version_info >= (3, 11):\n        with asyncio.Runner(loop_factory=uvloop.new_event_loop) as runner:\n            runner.run(main())\n    else:\n        uvloop.install()\n        asyncio.run(main())\n\n\nBuilding From Source\n--------------------\n\nTo build uvloop, you'll need Python 3.8 or greater:\n\n1. Clone the repository:\n\n   .. code::\n\n    $ git clone --recursive git@github.com:MagicStack/uvloop.git\n    $ cd uvloop\n\n2. Create a virtual environment and activate it:\n\n   .. code::\n\n    $ python3 -m venv uvloop-dev\n    $ source uvloop-dev/bin/activate\n\n3. Install development dependencies:\n\n   ..  code::\n\n    $ pip install -e .[dev]\n\n4. Build and run tests:\n\n   .. code::\n\n    $ make\n    $ make test\n\n\nLicense\n-------\n\nuvloop is dual-licensed under MIT and Apache 2.0 licenses.\n"
  },
  {
    "path": "docs/.gitignore",
    "content": "_build\n_static\n_templates\n"
  },
  {
    "path": "docs/api/index.rst",
    "content": "API\n===\n\nIf you are looking for information on a specific function, class or method,\nthis part of the documentation is for you.\n\n\nuvloop\n------\n\n.. autoclass:: uvloop.EventLoopPolicy\n  :members:\n\n.. autofunction:: uvloop.new_event_loop\n\n.. autoclass:: uvloop.Loop\n  :members:\n  :undoc-members:\n  :inherited-members:\n\n"
  },
  {
    "path": "docs/conf.py",
    "content": "#!/usr/bin/env python3\n\nimport alabaster\nimport os\nimport sys\n\nsys.path.insert(0, os.path.abspath('..'))\n\nversion_file = os.path.join(os.path.dirname(os.path.dirname(__file__)),\n                            'uvloop', '_version.py')\n\nwith open(version_file, 'r') as f:\n    for line in f:\n        if line.startswith('__version__ ='):\n            _, _, version = line.partition('=')\n            version = version.strip(\" \\n'\\\"\")\n            break\n    else:\n        raise RuntimeError(\n            'unable to read the version from uvloop/_version.py')\n\n\n# -- General configuration ------------------------------------------------\n\nextensions = [\n    'sphinx.ext.autodoc',\n    'alabaster',\n]\ntemplates_path = ['_templates']\nsource_suffix = '.rst'\nmaster_doc = 'index'\nproject = 'uvloop'\ncopyright = '2016-present, MagicStack, Inc'\nauthor = 'Yury Selivanov'\nrelease = version\nlanguage = None\nexclude_patterns = ['_build']\npygments_style = 'sphinx'\ntodo_include_todos = False\n\n\n# -- Options for HTML output ----------------------------------------------\n\nhtml_theme = 'alabaster'\nhtml_theme_options = {\n    'description': 'uvloop is an ultra fast implementation of the '\n                   'asyncio event loop on top of libuv.',\n    'show_powered_by': False,\n}\nhtml_theme_path = [alabaster.get_path()]\nhtml_title = 'uvloop Documentation'\nhtml_short_title = 'uvloop'\nhtml_static_path = []\nhtml_sidebars = {\n    '**': [\n        'about.html',\n        'navigation.html',\n    ]\n}\nhtml_show_sourcelink = False\nhtml_show_sphinx = False\nhtml_show_copyright = True\nhtmlhelp_basename = 'uvloopdoc'\n\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {}\n\nlatex_documents = [\n    (master_doc, 'uvloop.tex', 'uvloop Documentation',\n     'Yury Selivanov', 'manual'),\n]\n\n\n# -- Options for manual page output ---------------------------------------\n\nman_pages = [\n    (master_doc, 'uvloop', 'uvloop Documentation',\n     [author], 1)\n]\n\n\n# -- Options for Texinfo output -------------------------------------------\n\ntexinfo_documents = [\n    (master_doc, 'uvloop', 'uvloop Documentation',\n     author, 'uvloop', 'One line description of project.',\n     'Miscellaneous'),\n]\n"
  },
  {
    "path": "docs/dev/index.rst",
    "content": "Developers Guide\n================\n\nThe project is hosted on `GitHub <https://github.com/MagicStack/uvloop>`_.\nand uses `GitHub Actions <https://github.com/MagicStack/uvloop/actions>`_ for\nContinuous Integration.\n\nA goal for the `uvloop` project is to provide a drop in replacement for the\n`asyncio` event loop. Any deviation from the behavior of the reference\n`asyncio` event loop is considered a bug.\n\nIf you have found a bug or have an idea for an enhancement that would\nimprove the library, use the\n`bug tracker <https://github.com/MagicStack/uvloop/issues>`_.\n\n\nGet the source\n--------------\n\n.. code-block:: console\n\n    $ git clone --recursive git@github.com:MagicStack/uvloop.git\n\nThe ``--recursive`` argument is important. It will fetch the ``libuv`` source\nfrom the `libuv` Github repository.\n\n\nBuild\n-----\n\nTo build `uvloop`, you'll need ``Cython`` and Python 3.8.\n\n.. note::\n\n    The best way to work on `uvloop` is to create a virtual env, so that\n    you'll have Cython and Python commands pointing to the correct\n    tools.\n\n    .. code-block:: console\n\n        $ python3 -m venv myvenv\n        $ source myvenv/bin/activate\n\nInstall Cython if not already present.\n\n.. code-block:: console\n\n    $ pip install Cython\n\n\nBuild `uvloop` by running the ``make`` rule from the top level directory.\n\n.. code-block:: console\n\n    $ cd uvloop\n    $ make\n\n\nTest\n----\n\nThe easiest method to run all of the unit tests is to run the ``make test``\nrule from the top level directory. This runs the standard library\n``unittest`` tool which discovers all the unit tests and runs them.\nIt actually runs them twice, once with the `PYTHONASYNCIODEBUG` enabled and\nonce without.\n\n.. code-block:: console\n\n    $ cd uvloop\n    $ make test\n\n\nIndividual Tests\n++++++++++++++++\n\nIndividual unit tests can be run using the standard library ``unittest``\nor ``pytest`` package.\n\nThe easiest approach to ensure that ``uvloop`` can be found by Python is to\ninstall the package using ``pip``:\n\n.. code-block:: console\n\n    $ cd uvloop\n    $ pip install -e .\n\nYou can then run the unit tests individually from the tests directory using\n``unittest``:\n\n.. code-block:: console\n\n    $ cd uvloop/tests\n    $ python -m unittest test_tcp\n\nor using ``pytest``:\n\n.. code-block:: console\n\n    $ cd uvloop/tests\n    $ py.test -k test_signals_sigint_uvcode\n\n\nDocumentation\n-------------\n\nTo rebuild the project documentation, developers should run the ``make docs``\nrule from the top level directory. It performs a number of steps to create\na new set of `sphinx <http://sphinx-doc.org/>`_ html content.\n\nThis step requires Sphinx to be installed. Sphinx can be installed using\npip:\n\n.. code-block:: console\n\n    $ pip install sphinx\n\nOnce Sphinx is available you can make the documentation using:\n\n.. code-block:: console\n\n    $ make docs\n"
  },
  {
    "path": "docs/index.rst",
    "content": ".. image:: https://img.shields.io/github/actions/workflow/status/MagicStack/uvloop/tests.yml?branch=master\n    :target: https://github.com/MagicStack/uvloop/actions/workflows/tests.yml?query=branch%3Amaster\n\n.. image:: https://img.shields.io/pypi/status/uvloop.svg?maxAge=2592000?style=plastic\n    :target: https://pypi.python.org/pypi/uvloop\n\n.. image:: https://img.shields.io/github/stars/magicstack/uvloop.svg?style=social&label=GitHub\n    :target: https://github.com/MagicStack/uvloop\n\n\nuvloop\n======\n\n`uvloop` is a fast, drop-in replacement of the built-in asyncio event loop.\n`uvloop` is released under the MIT license.\n\n`uvloop` and asyncio, combined with the power of async/await in Python 3.7,\nmakes it easier than ever to write high-performance networking code in Python.\n\n`uvloop` makes asyncio fast. In fact, it is at least 2x faster than nodejs,\ngevent, as well as any other Python asynchronous framework. The performance of\nuvloop-based asyncio is close to that of Go programs.\n\nYou can read more about uvloop in this\n`blog post <http://magic.io/blog/uvloop-blazing-fast-python-networking/>`_.\n\nArchitecture\n------------\n\nThe asyncio module, introduced by PEP 3156, is a collection of network\ntransports, protocols, and streams abstractions, with a pluggable event loop.\nThe event loop is the heart of asyncio. It provides APIs for:\n\n- scheduling calls,\n- transmitting data over the network,\n- performing DNS queries,\n- handling OS signals,\n- convenient abstractions to create servers and connections,\n- working with subprocesses asynchronously.\n\n`uvloop` implements the :class:`asyncio.AbstractEventLoop` interface which\nmeans that it provides a drop-in replacement of the asyncio event loop.\n\n`uvloop` is written in Cython and is built on top of libuv.\n\nlibuv is a high performance, multiplatform asynchronous I/O library used by\nnodejs. Because of how wide-spread and popular nodejs is, libuv is fast and\nstable.\n\n`uvloop` implements all asyncio event loop APIs. High-level Python objects\nwrap low-level libuv structs and functions. Inheritance is used to keep the\ncode DRY and ensure that any manual memory management is in sync with libuv\nprimitives' lifespans.\n\n\nContents\n--------\n\n.. toctree::\n   :maxdepth: 1\n\n   user/index\n   dev/index\n"
  },
  {
    "path": "docs/user/index.rst",
    "content": "User Guide\n==========\n\nThis section of the documentation provides information about how to use\nuvloop.\n\n\nInstallation\n------------\n\n`uvloop` is available from PyPI. It requires Python 3.8.\n\nUse pip to install it.\n\n.. code-block:: console\n\n    $ pip install uvloop\n\n\nUsing uvloop\n------------\n\nTo make asyncio use the event loop provided by `uvloop`, you install the\n`uvloop` event loop policy:\n\n.. code-block:: python\n\n    import asyncio\n    import uvloop\n    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())\n\n\nAlternatively, you can create an instance of the loop manually, using:\n\n.. code-block:: python\n\n    import asyncio\n    import uvloop\n    loop = uvloop.new_event_loop()\n    asyncio.set_event_loop(loop)\n"
  },
  {
    "path": "examples/bench/echoclient.py",
    "content": "# Copied with minimal modifications from curio\n# https://github.com/dabeaz/curio\n\n\nimport argparse\nimport concurrent.futures\nimport socket\nimport ssl\nimport time\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--msize', default=1000, type=int,\n                        help='message size in bytes')\n    parser.add_argument('--mpr', default=1, type=int,\n                        help='messages per request')\n    parser.add_argument('--num', default=200000, type=int,\n                        help='number of messages')\n    parser.add_argument('--times', default=1, type=int,\n                        help='number of times to run the test')\n    parser.add_argument('--workers', default=3, type=int,\n                        help='number of workers')\n    parser.add_argument('--addr', default='127.0.0.1:25000', type=str,\n                        help='address:port of echoserver')\n    parser.add_argument('--ssl', default=False, action='store_true')\n    args = parser.parse_args()\n\n    client_context = None\n    if args.ssl:\n        print('with SSL')\n        if hasattr(ssl, 'PROTOCOL_TLS'):\n            client_context = ssl.SSLContext(ssl.PROTOCOL_TLS)\n        else:\n            client_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        if hasattr(client_context, 'check_hostname'):\n            client_context.check_hostname = False\n        client_context.verify_mode = ssl.CERT_NONE\n\n    unix = False\n    if args.addr.startswith('file:'):\n        unix = True\n        addr = args.addr[5:]\n    else:\n        addr = args.addr.split(':')\n        addr[1] = int(addr[1])\n        addr = tuple(addr)\n    print('will connect to: {}'.format(addr))\n\n    MSGSIZE = args.msize\n    REQSIZE = MSGSIZE * args.mpr\n\n    msg = b'x' * (MSGSIZE - 1) + b'\\n'\n    if args.mpr:\n        msg *= args.mpr\n\n    def run_test(n):\n        print('Sending', NMESSAGES, 'messages')\n        if args.mpr:\n            n //= args.mpr\n\n        if unix:\n            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\n        else:\n            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n\n        try:\n            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n        except (OSError, NameError):\n            pass\n\n        if client_context:\n            sock = client_context.wrap_socket(sock)\n\n        sock.connect(addr)\n\n        while n > 0:\n            sock.sendall(msg)\n            nrecv = 0\n            while nrecv < REQSIZE:\n                resp = sock.recv(REQSIZE)\n                if not resp:\n                    raise SystemExit()\n                nrecv += len(resp)\n            n -= 1\n\n    TIMES = args.times\n    N = args.workers\n    NMESSAGES = args.num\n    start = time.time()\n    for _ in range(TIMES):\n        with concurrent.futures.ProcessPoolExecutor(max_workers=N) as e:\n            for _ in range(N):\n                e.submit(run_test, NMESSAGES)\n    end = time.time()\n    duration = end - start\n    print(NMESSAGES * N * TIMES, 'in', duration)\n    print(NMESSAGES * N * TIMES / duration, 'requests/sec')\n"
  },
  {
    "path": "examples/bench/echoserver.py",
    "content": "import argparse\nimport asyncio\nimport gc\nimport os.path\nimport pathlib\nimport socket\nimport ssl\n\n\nPRINT = 0\n\n\nasync def echo_server(loop, address, unix):\n    if unix:\n        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\n    else:\n        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n    sock.bind(address)\n    sock.listen(5)\n    sock.setblocking(False)\n    if PRINT:\n        print('Server listening at', address)\n    with sock:\n        while True:\n            client, addr = await loop.sock_accept(sock)\n            if PRINT:\n                print('Connection from', addr)\n            loop.create_task(echo_client(loop, client))\n\n\nasync def echo_client(loop, client):\n    try:\n        client.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n    except (OSError, NameError):\n        pass\n\n    with client:\n        while True:\n            data = await loop.sock_recv(client, 1000000)\n            if not data:\n                break\n            await loop.sock_sendall(client, data)\n    if PRINT:\n        print('Connection closed')\n\n\nasync def echo_client_streams(reader, writer):\n    sock = writer.get_extra_info('socket')\n    try:\n        sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n    except (OSError, NameError):\n        pass\n    if PRINT:\n        print('Connection from', sock.getpeername())\n    while True:\n        data = await reader.read(1000000)\n        if not data:\n            break\n        writer.write(data)\n    if PRINT:\n        print('Connection closed')\n    writer.close()\n\n\nclass EchoProtocol(asyncio.Protocol):\n    def connection_made(self, transport):\n        self.transport = transport\n\n    def connection_lost(self, exc):\n        self.transport = None\n\n    def data_received(self, data):\n        self.transport.write(data)\n\n\nclass EchoBufferedProtocol(asyncio.BufferedProtocol):\n    def connection_made(self, transport):\n        self.transport = transport\n        # Here the buffer is intended to be copied, so that the outgoing buffer\n        # won't be wrongly updated by next read\n        self.buffer = bytearray(256 * 1024)\n\n    def connection_lost(self, exc):\n        self.transport = None\n\n    def get_buffer(self, sizehint):\n        return self.buffer\n\n    def buffer_updated(self, nbytes):\n        self.transport.write(self.buffer[:nbytes])\n\n\nasync def print_debug(loop):\n    while True:\n        print(chr(27) + \"[2J\")  # clear screen\n        loop.print_debug_info()\n        await asyncio.sleep(0.5)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--uvloop', default=False, action='store_true')\n    parser.add_argument('--streams', default=False, action='store_true')\n    parser.add_argument('--proto', default=False, action='store_true')\n    parser.add_argument('--addr', default='127.0.0.1:25000', type=str)\n    parser.add_argument('--print', default=False, action='store_true')\n    parser.add_argument('--ssl', default=False, action='store_true')\n    parser.add_argument('--buffered', default=False, action='store_true')\n    args = parser.parse_args()\n\n    if args.uvloop:\n        import uvloop\n        loop = uvloop.new_event_loop()\n        print('using UVLoop')\n    else:\n        loop = asyncio.new_event_loop()\n        print('using asyncio loop')\n\n    asyncio.set_event_loop(loop)\n    loop.set_debug(False)\n\n    if args.print:\n        PRINT = 1\n\n    if hasattr(loop, 'print_debug_info'):\n        loop.create_task(print_debug(loop))\n        PRINT = 0\n\n    unix = False\n    if args.addr.startswith('file:'):\n        unix = True\n        addr = args.addr[5:]\n        if os.path.exists(addr):\n            os.remove(addr)\n    else:\n        addr = args.addr.split(':')\n        addr[1] = int(addr[1])\n        addr = tuple(addr)\n\n    print('serving on: {}'.format(addr))\n\n    server_context = None\n    if args.ssl:\n        print('with SSL')\n        if hasattr(ssl, 'PROTOCOL_TLS'):\n            server_context = ssl.SSLContext(ssl.PROTOCOL_TLS)\n        else:\n            server_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        server_context.load_cert_chain(\n            (pathlib.Path(__file__).parent.parent.parent /\n                'tests' / 'certs' / 'ssl_cert.pem'),\n            (pathlib.Path(__file__).parent.parent.parent /\n                'tests' / 'certs' / 'ssl_key.pem'))\n        if hasattr(server_context, 'check_hostname'):\n            server_context.check_hostname = False\n        server_context.verify_mode = ssl.CERT_NONE\n\n    if args.streams:\n        if args.proto:\n            print('cannot use --stream and --proto simultaneously')\n            exit(1)\n\n        if args.buffered:\n            print('cannot use --stream and --buffered simultaneously')\n            exit(1)\n\n        print('using asyncio/streams')\n        if unix:\n            coro = asyncio.start_unix_server(echo_client_streams,\n                                             addr,\n                                             ssl=server_context)\n        else:\n            coro = asyncio.start_server(echo_client_streams,\n                                        *addr,\n                                        ssl=server_context)\n        srv = loop.run_until_complete(coro)\n    elif args.proto:\n        if args.streams:\n            print('cannot use --stream and --proto simultaneously')\n            exit(1)\n\n        if args.buffered:\n            print('using buffered protocol')\n            protocol = EchoBufferedProtocol\n        else:\n            print('using simple protocol')\n            protocol = EchoProtocol\n\n        if unix:\n            coro = loop.create_unix_server(protocol, addr,\n                                           ssl=server_context)\n        else:\n            coro = loop.create_server(protocol, *addr,\n                                      ssl=server_context)\n        srv = loop.run_until_complete(coro)\n    else:\n        if args.ssl:\n            print('cannot use SSL for loop.sock_* methods')\n            exit(1)\n\n        print('using sock_recv/sock_sendall')\n        loop.create_task(echo_server(loop, addr, unix))\n    try:\n        loop.run_forever()\n    finally:\n        if hasattr(loop, 'print_debug_info'):\n            gc.collect()\n            print(chr(27) + \"[2J\")\n            loop.print_debug_info()\n\n        loop.close()\n"
  },
  {
    "path": "examples/bench/rlserver.py",
    "content": "import argparse\nimport asyncio\nimport gc\nimport os.path\nimport socket as stdsock\n\n\nPRINT = 0\n\n\nasync def echo_client_streams(reader, writer):\n    sock = writer.get_extra_info('socket')\n    try:\n        sock.setsockopt(\n            stdsock.IPPROTO_TCP, stdsock.TCP_NODELAY, 1)\n    except (OSError, NameError):\n        pass\n    if PRINT:\n        print('Connection from', sock.getpeername())\n    while True:\n        data = await reader.readline()\n        if not data:\n            break\n        writer.write(data)\n    if PRINT:\n        print('Connection closed')\n    writer.close()\n\n\nasync def print_debug(loop):\n    while True:\n        print(chr(27) + \"[2J\")  # clear screen\n        loop.print_debug_info()\n        await asyncio.sleep(0.5)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--uvloop', default=False, action='store_true')\n    parser.add_argument('--addr', default='127.0.0.1:25000', type=str)\n    parser.add_argument('--print', default=False, action='store_true')\n    args = parser.parse_args()\n\n    if args.uvloop:\n        import uvloop\n        loop = uvloop.new_event_loop()\n        print('using UVLoop')\n    else:\n        loop = asyncio.new_event_loop()\n        print('using asyncio loop')\n\n    asyncio.set_event_loop(loop)\n    loop.set_debug(False)\n\n    if args.print:\n        PRINT = 1\n\n    if hasattr(loop, 'print_debug_info'):\n        loop.create_task(print_debug(loop))\n        PRINT = 0\n\n    unix = False\n    if args.addr.startswith('file:'):\n        unix = True\n        addr = args.addr[5:]\n        if os.path.exists(addr):\n            os.remove(addr)\n    else:\n        addr = args.addr.split(':')\n        addr[1] = int(addr[1])\n        addr = tuple(addr)\n\n    print('readline performance test')\n    print('serving on: {}'.format(addr))\n\n    print('using asyncio/streams')\n    if unix:\n        coro = asyncio.start_unix_server(echo_client_streams,\n                                         addr, limit=256000)\n    else:\n        coro = asyncio.start_server(echo_client_streams,\n                                    *addr, limit=256000)\n    srv = loop.run_until_complete(coro)\n\n    try:\n        loop.run_forever()\n    finally:\n        if hasattr(loop, 'print_debug_info'):\n            gc.collect()\n            print(chr(27) + \"[2J\")\n            loop.print_debug_info()\n\n        loop.close()\n"
  },
  {
    "path": "mypy.ini",
    "content": "[mypy]\nincremental = True\nstrict = True\n\n[mypy-uvloop._testbase]\nignore_errors = True\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[project]\nname = \"uvloop\"\ndescription = \"Fast implementation of asyncio event loop on top of libuv\"\nauthors = [{name = \"Yury Selivanov\", email = \"yury@magic.io\"}]\nrequires-python = '>=3.8.1'\nreadme = \"README.rst\"\nlicense = {text = \"MIT License\"}\ndynamic = [\"version\"]\nkeywords = [\n    \"asyncio\",\n    \"networking\",\n]\nclassifiers = [\n    \"Development Status :: 5 - Production/Stable\",\n    \"Framework :: AsyncIO\",\n    \"Intended Audience :: Developers\",\n    \"License :: OSI Approved :: Apache Software License\",\n    \"License :: OSI Approved :: MIT License\",\n    \"Operating System :: POSIX\",\n    \"Operating System :: MacOS :: MacOS X\",\n    \"Programming Language :: Python :: 3 :: Only\",\n    \"Programming Language :: Python :: 3.8\",\n    \"Programming Language :: Python :: 3.9\",\n    \"Programming Language :: Python :: 3.10\",\n    \"Programming Language :: Python :: 3.11\",\n    \"Programming Language :: Python :: 3.12\",\n    \"Programming Language :: Python :: 3.13\",\n    \"Programming Language :: Python :: Implementation :: CPython\",\n    \"Topic :: System :: Networking\",\n]\n\n[project.urls]\ngithub = \"https://github.com/MagicStack/uvloop\"\n\n[project.optional-dependencies]\ntest = [\n    # pycodestyle is a dependency of flake8, but it must be frozen because\n    # their combination breaks too often\n    # (example breakage: https://gitlab.com/pycqa/flake8/issues/427)\n    'aiohttp>=3.10.5',\n    'flake8~=6.1',\n    'psutil',\n    'pycodestyle~=2.11.0',\n    'pyOpenSSL~=25.3.0',\n    'mypy>=0.800',\n]\ndev = [\n    'setuptools>=60',\n    'Cython~=3.0',\n]\ndocs = [\n    'Sphinx~=4.1.2',\n    'sphinxcontrib-asyncio~=0.3.0',\n    'sphinx_rtd_theme~=0.5.2',\n]\n\n[build-system]\nrequires = [\n    \"setuptools>=60\",\n    \"wheel\",\n    \"Cython~=3.1\",\n]\nbuild-backend = \"setuptools.build_meta\"\n\n[tool.setuptools]\nzip-safe = false\npackages = [\"uvloop\"]\n\n[tool.setuptools.exclude-package-data]\n\"*\" = [\"*.c\", \"*.h\"]\n\n[tool.cibuildwheel]\nbuild-frontend = \"build\"\ntest-extras = \"test\"\ntest-command = \"python -m unittest discover -v {project}/tests\"\n\n[tool.pytest.ini_options]\naddopts = \"--capture=no --assert=plain --strict-markers --tb=native --import-mode=importlib\"\ntestpaths = \"tests\"\nfilterwarnings = \"default\"\n"
  },
  {
    "path": "setup.py",
    "content": "import sys\n\nvi = sys.version_info\nif vi < (3, 8):\n    raise RuntimeError('uvloop requires Python 3.8 or greater')\n\nif sys.platform in ('win32', 'cygwin', 'cli'):\n    raise RuntimeError('uvloop does not support Windows at the moment')\n\nimport os\nimport os.path\nimport pathlib\nimport platform\nimport re\nimport shutil\nimport subprocess\nimport sys\n\nfrom setuptools import setup, Extension\nfrom setuptools.command.build_ext import build_ext\nfrom setuptools.command.sdist import sdist\n\n\nCYTHON_DEPENDENCY = 'Cython~=3.0'\nMACHINE = platform.machine()\nMODULES_CFLAGS = [os.getenv('UVLOOP_OPT_CFLAGS', '-O2')]\n_ROOT = pathlib.Path(__file__).parent\nLIBUV_DIR = str(_ROOT / 'vendor' / 'libuv')\nLIBUV_BUILD_DIR = str(_ROOT / 'build' / 'libuv-{}'.format(MACHINE))\n\n\ndef _libuv_build_env():\n    env = os.environ.copy()\n\n    cur_cflags = env.get('CFLAGS', '')\n    if not re.search(r'-O\\d', cur_cflags):\n        cur_cflags += ' -O2'\n\n    env['CFLAGS'] = (cur_cflags + ' -fPIC ' + env.get('ARCHFLAGS', ''))\n\n    return env\n\n\ndef _libuv_autogen(env):\n    if os.path.exists(os.path.join(LIBUV_DIR, 'configure')):\n        # No need to use autogen, the configure script is there.\n        return\n\n    if not os.path.exists(os.path.join(LIBUV_DIR, 'autogen.sh')):\n        raise RuntimeError(\n            'the libuv submodule has not been checked out; '\n            'try running \"git submodule init; git submodule update\"')\n\n    subprocess.run(\n        ['/bin/sh', 'autogen.sh'], cwd=LIBUV_DIR, env=env, check=True)\n\n\nclass uvloop_sdist(sdist):\n    def run(self):\n        # Make sure sdist archive contains configure\n        # to avoid the dependency on autotools.\n        _libuv_autogen(_libuv_build_env())\n        super().run()\n\n\nclass uvloop_build_ext(build_ext):\n    user_options = build_ext.user_options + [\n        ('cython-always', None,\n            'run cythonize() even if .c files are present'),\n        ('cython-annotate', None,\n            'Produce a colorized HTML version of the Cython source.'),\n        ('cython-directives=', None,\n            'Cythion compiler directives'),\n        ('use-system-libuv', None,\n            'Use the system provided libuv, instead of the bundled one'),\n    ]\n\n    boolean_options = build_ext.boolean_options + [\n        'cython-always',\n        'cython-annotate',\n        'use-system-libuv',\n    ]\n\n    def initialize_options(self):\n        super().initialize_options()\n        self.use_system_libuv = False\n        self.cython_always = False\n        self.cython_annotate = None\n        self.cython_directives = None\n\n    def finalize_options(self):\n        need_cythonize = self.cython_always\n        cfiles = {}\n\n        for extension in self.distribution.ext_modules:\n            for i, sfile in enumerate(extension.sources):\n                if sfile.endswith('.pyx'):\n                    prefix, ext = os.path.splitext(sfile)\n                    cfile = prefix + '.c'\n\n                    if os.path.exists(cfile) and not self.cython_always:\n                        extension.sources[i] = cfile\n                    else:\n                        if os.path.exists(cfile):\n                            cfiles[cfile] = os.path.getmtime(cfile)\n                        else:\n                            cfiles[cfile] = 0\n                        need_cythonize = True\n\n        if need_cythonize:\n            import pkg_resources\n\n            # Double check Cython presence in case setup_requires\n            # didn't go into effect (most likely because someone\n            # imported Cython before setup_requires injected the\n            # correct egg into sys.path.\n            try:\n                import Cython\n            except ImportError:\n                raise RuntimeError(\n                    'please install {} to compile uvloop from source'.format(\n                        CYTHON_DEPENDENCY))\n\n            cython_dep = pkg_resources.Requirement.parse(CYTHON_DEPENDENCY)\n            if Cython.__version__ not in cython_dep:\n                raise RuntimeError(\n                    'uvloop requires {}, got Cython=={}'.format(\n                        CYTHON_DEPENDENCY, Cython.__version__\n                    ))\n\n            from Cython.Build import cythonize\n\n            directives = {}\n            if self.cython_directives:\n                for directive in self.cython_directives.split(','):\n                    k, _, v = directive.partition('=')\n                    if v.lower() == 'false':\n                        v = False\n                    if v.lower() == 'true':\n                        v = True\n\n                    directives[k] = v\n                self.cython_directives = directives\n\n            self.distribution.ext_modules[:] = cythonize(\n                self.distribution.ext_modules,\n                compiler_directives=directives,\n                annotate=self.cython_annotate,\n                compile_time_env=dict(DEFAULT_FREELIST_SIZE=250),\n                emit_linenums=self.debug)\n\n        super().finalize_options()\n\n    def build_libuv(self):\n        env = _libuv_build_env()\n\n        # Make sure configure and friends are present in case\n        # we are building from a git checkout.\n        _libuv_autogen(env)\n\n        # Copy the libuv tree to build/ so that its build\n        # products don't pollute sdist accidentally.\n        if os.path.exists(LIBUV_BUILD_DIR):\n            shutil.rmtree(LIBUV_BUILD_DIR)\n        shutil.copytree(LIBUV_DIR, LIBUV_BUILD_DIR)\n\n        # Sometimes pip fails to preserve the timestamps correctly,\n        # in which case, make will try to run autotools again.\n        subprocess.run(\n            ['touch', 'configure.ac', 'aclocal.m4', 'configure',\n             'Makefile.am', 'Makefile.in'],\n            cwd=LIBUV_BUILD_DIR, env=env, check=True)\n\n        if 'LIBUV_CONFIGURE_HOST' in env:\n            cmd = ['./configure', '--host=' + env['LIBUV_CONFIGURE_HOST']]\n        else:\n            cmd = ['./configure']\n        subprocess.run(\n            cmd,\n            cwd=LIBUV_BUILD_DIR, env=env, check=True)\n\n        try:\n            njobs = len(os.sched_getaffinity(0))\n        except AttributeError:\n            njobs = os.cpu_count()\n        j_flag = '-j{}'.format(njobs or 1)\n        c_flag = \"CFLAGS={}\".format(env['CFLAGS'])\n        subprocess.run(\n            ['make', j_flag, c_flag],\n            cwd=LIBUV_BUILD_DIR, env=env, check=True)\n\n    def build_extensions(self):\n        if self.use_system_libuv:\n            self.compiler.add_library('uv')\n\n            if sys.platform == 'darwin' and \\\n                    os.path.exists('/opt/local/include'):\n                # Support macports on Mac OS X.\n                self.compiler.add_include_dir('/opt/local/include')\n        else:\n            libuv_lib = os.path.join(LIBUV_BUILD_DIR, '.libs', 'libuv.a')\n            if not os.path.exists(libuv_lib):\n                self.build_libuv()\n            if not os.path.exists(libuv_lib):\n                raise RuntimeError('failed to build libuv')\n\n            self.extensions[-1].extra_objects.extend([libuv_lib])\n            self.compiler.add_include_dir(os.path.join(LIBUV_DIR, 'include'))\n\n        if sys.platform.startswith('linux'):\n            self.compiler.add_library('rt')\n        elif sys.platform.startswith(('freebsd', 'dragonfly')):\n            self.compiler.add_library('kvm')\n        elif sys.platform.startswith('sunos'):\n            self.compiler.add_library('kstat')\n\n        self.compiler.add_library('pthread')\n\n        super().build_extensions()\n\n\nwith open(str(_ROOT / 'uvloop' / '_version.py')) as f:\n    for line in f:\n        if line.startswith('__version__ ='):\n            _, _, version = line.partition('=')\n            VERSION = version.strip(\" \\n'\\\"\")\n            break\n    else:\n        raise RuntimeError(\n            'unable to read the version from uvloop/_version.py')\n\n\nsetup_requires = []\n\nif not (_ROOT / 'uvloop' / 'loop.c').exists() or '--cython-always' in sys.argv:\n    # No Cython output, require Cython to build.\n    setup_requires.append(CYTHON_DEPENDENCY)\n\n\nsetup(\n    version=VERSION,\n    cmdclass={\n        'sdist': uvloop_sdist,\n        'build_ext': uvloop_build_ext\n    },\n    ext_modules=[\n        Extension(\n            \"uvloop.loop\",\n            sources=[\n                \"uvloop/loop.pyx\",\n            ],\n            extra_compile_args=MODULES_CFLAGS\n        ),\n    ],\n    setup_requires=setup_requires,\n)\n"
  },
  {
    "path": "tests/__init__.py",
    "content": ""
  },
  {
    "path": "tests/__main__.py",
    "content": "import os.path\nimport sys\nimport unittest\nimport unittest.runner\n\n\ndef suite():\n    test_loader = unittest.TestLoader()\n    test_suite = test_loader.discover(os.path.dirname(__file__))\n    return test_suite\n\n\nif __name__ == '__main__':\n    runner = unittest.runner.TextTestRunner()\n    result = runner.run(suite())\n    sys.exit(not result.wasSuccessful())\n"
  },
  {
    "path": "tests/certs/ssl_cert.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIIF8TCCBFmgAwIBAgIJAMstgJlaaVJcMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV\nBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW\nMBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODA4MjkxNDIzMTZaFw0yODA3MDcx\nNDIzMTZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj\nMCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMMCWxv\nY2FsaG9zdDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAJ8oLzdB739k\nYxZiFukBFGIpyjqYkj0I015p/sDz1MT7DljcZLBLy7OqnkLpB5tnM8256DwdihPA\n3zlnfEzTfr9DD0qFBW2H5cMCoz7X17koeRhzGDd3dkjUeBjXvR5qRosG8wM3lQug\nU7AizY+3Azaj1yN3mZ9K5a20jr58Kqinz+Xxx6sb2JfYYff2neJbBahNm5id0AD2\npi/TthZqO5DURJYo+MdgZOcy+7jEjOJsLWZd3Yzq78iM07qDjbpIoVpENZCTHTWA\nhX8LIqz0OBmh4weQpm4+plU7E4r4D82uauocWw8iyuznCTtABWO7n9fWySmf9QZC\nWYxHAFpBQs6zUVqAD7nhFdTqpQ9bRiaEnjE4HiAccPW+MAoSxFnv/rNzEzI6b4zU\nNspFMfg1aNVamdjxdpUZ1GG1Okf0yPJykqEX4PZl3La1Be2q7YZ1wydR523Xd+f3\nEO4/g+imETSKn8gyCf6Rvib175L4r2WV1CXQH7gFwZYCod6WHYq5TQIDAQABo4IB\nwDCCAbwwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA4GA1UdDwEB/wQEAwIFoDAdBgNV\nHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4E\nFgQUj+od4zNcABazi29rb9NMy7XLfFUwfQYDVR0jBHYwdIAU3b/K2ubRNLo3dSHK\nb5oIKPI1tkihUaRPME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29m\ndHdhcmUgRm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcoIJAMst\ngJlaaVJbMIGDBggrBgEFBQcBAQR3MHUwPAYIKwYBBQUHMAKGMGh0dHA6Ly90ZXN0\nY2EucHl0aG9udGVzdC5uZXQvdGVzdGNhL3B5Y2FjZXJ0LmNlcjA1BggrBgEFBQcw\nAYYpaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0Y2Evb2NzcC8wQwYD\nVR0fBDwwOjA4oDagNIYyaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0\nY2EvcmV2b2NhdGlvbi5jcmwwDQYJKoZIhvcNAQELBQADggGBACf1jFkQ9MbnKAC/\nuo17EwPxHKZfswZVpCK527LVRr33DN1DbrR5ZWchDCpV7kCOhZ+fR7sKKk22ZHSY\noH+u3PEu20J3GOB1iyY1aMNB7WvId3JvappdVWkC/VpUyFfLsGUDFuIPADmZZqCb\niJMX4loteTVfl1d4xK/1mV6Gq9MRrRqiDfpSELn+v53OM9mGspwW+NZ1CIrbCuW0\nKxZ/tPkqn8PSd9fNZR70bB7rWbnwrl+kH8xKxLl6qdlrMmg74WWwhLeQxK7+9DdP\nIaDenzqx5cwWBGY/C0HcQj0gPuy3lSs1V/q+f7Y6uspPWP51PgiJLIywXS75iRAr\n+UFGTzwAtyfTZSQoFyMmMULqfk6T5HtoVMqfRvPvK+mFDLWEstU1NIB1K/CRI7gI\nAY65ClTU+zRS/tlF8IA7tsFvgtEf8jsI9kamlidhS1gyeg4dWcVErV4aeTPB1AUv\nStPYQkKNM+NjytWHl5tNuBoDNLsc0gI/WSPiI4CIY8LwomOoiw==\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "tests/certs/ssl_key.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIG/QIBADANBgkqhkiG9w0BAQEFAASCBucwggbjAgEAAoIBgQCfKC83Qe9/ZGMW\nYhbpARRiKco6mJI9CNNeaf7A89TE+w5Y3GSwS8uzqp5C6QebZzPNueg8HYoTwN85\nZ3xM036/Qw9KhQVth+XDAqM+19e5KHkYcxg3d3ZI1HgY170eakaLBvMDN5ULoFOw\nIs2PtwM2o9cjd5mfSuWttI6+fCqop8/l8cerG9iX2GH39p3iWwWoTZuYndAA9qYv\n07YWajuQ1ESWKPjHYGTnMvu4xIzibC1mXd2M6u/IjNO6g426SKFaRDWQkx01gIV/\nCyKs9DgZoeMHkKZuPqZVOxOK+A/NrmrqHFsPIsrs5wk7QAVju5/X1skpn/UGQlmM\nRwBaQULOs1FagA+54RXU6qUPW0YmhJ4xOB4gHHD1vjAKEsRZ7/6zcxMyOm+M1DbK\nRTH4NWjVWpnY8XaVGdRhtTpH9MjycpKhF+D2Zdy2tQXtqu2GdcMnUedt13fn9xDu\nP4PophE0ip/IMgn+kb4m9e+S+K9lldQl0B+4BcGWAqHelh2KuU0CAwEAAQKCAYEA\nlKiWIYjmyRjdLKUGPTES9vWNvNmRjozV0RQ0LcoSbMMLDZkeO0UwyWqOVHUQ8+ib\njIcfEjeNJxI57oZopeHOO5vJhpNlFH+g7ltiW2qERqA1K88lSXm99Bzw6FNqhCRE\nK8ub5N9fyfJA+P4o/xm0WK8EXk5yIUV17p/9zJJxzgKgv2jsVTi3QG2OZGvn4Oug\nByomMZEGHkBDzdxz8c/cP1Tlk1RFuwSgews178k2xq7AYSM/s0YmHi7b/RSvptX6\n1v8P8kXNUe4AwTaNyrlvF2lwIadZ8h1hA7tCE2n44b7a7KfhAkwcbr1T59ioYh6P\nzxsyPT678uD51dbtD/DXJCcoeeFOb8uzkR2KNcrnQzZpCJnRq4Gp5ybxwsxxuzpr\ngz0gbNlhuWtE7EoSzmIK9t+WTS7IM2CvZymd6/OAh1Fuw6AQhSp64XRp3OfMMAAC\nIe2EPtKj4islWGT8VoUjuRYGmdRh4duAH1dkiAXOWA3R7y5a1/y/iE8KE8BtxocB\nAoHBAM8aiURgpu1Fs0Oqz6izec7KSLL3l8hmW+MKUOfk/Ybng6FrTFsL5YtzR+Ap\nwW4wwWnnIKEc1JLiZ7g8agRETK8hr5PwFXUn/GSWC0SMsazLJToySQS5LOV0tLzK\nkJ3jtNU7tnlDGNkCHTHSoVL2T/8t+IkZI/h5Z6wjlYPvU2Iu0nVIXtiG+alv4A6M\nHrh9l5or4mjB6rGnVXeYohLkCm6s/W97ahVxLMcEdbsBo1prm2JqGnSoiR/tEFC/\nQHQnbQKBwQDEu7kW0Yg9sZ89QtYtVQ1YpixFZORaUeRIRLnpEs1w7L1mCbOZ2Lj9\nJHxsH05cYAc7HJfPwwxv3+3aGAIC/dfu4VSwEFtatAzUpzlhzKS5+HQCWB4JUNNU\nMQ3+FwK2xQX4Ph8t+OzrFiYcK2g0An5UxWMa2HWIAWUOhnTOydAVsoH6yP31cVm4\n0hxoABCwflaNLNGjRUyfBpLTAcNu/YtcE+KREy7YAAgXXrhRSO4XpLsSXwLnLT7/\nYOkoBWDcTWECgcBPWnSUDZCIQ3efithMZJBciqd2Y2X19Dpq8O31HImD4jtOY0V7\ncUB/wSkeHAGwjd/eCyA2e0x8B2IEdqmMfvr+86JJxekC3dJYXCFvH5WIhsH53YCa\n3bT1KlWCLP9ib/g+58VQC0R/Cc9T4sfLePNH7D5ZkZd1wlbV30CPr+i8KwKay6MD\nxhvtLx+jk07GE+E9wmjbCMo7TclyrLoVEOlqZMAqshgApT+p9eyCPetwXuDHwa3n\nWxhHclcZCV7R4rUCgcAkdGSnxcvpIrDPOUNWwxvmAWTStw9ZbTNP8OxCNCm9cyDl\nd4bAS1h8D/a+Uk7C70hnu7Sl2w7C7Eu2zhwRUdhhe3+l4GINPK/j99i6NqGPlGpq\nxMlMEJ4YS768BqeKFpg0l85PRoEgTsphDeoROSUPsEPdBZ9BxIBlYKTkbKESZDGR\ntwzYHljx1n1NCDYPflmrb1KpXn4EOcObNghw2KqqNUUWfOeBPwBA1FxzM4BrAStp\nDBINpGS4Dc0mjViVegECgcA3hTtm82XdxQXj9LQmb/E3lKx/7H87XIOeNMmvjYuZ\niS9wKrkF+u42vyoDxcKMCnxP5056wpdST4p56r+SBwVTHcc3lGBSGcMTIfwRXrj3\nthOA2our2n4ouNIsYyTlcsQSzifwmpRmVMRPxl9fYVdEWUgB83FgHT0D9avvZnF9\nt9OccnGJXShAIZIBADhVj/JwG4FbaX42NijD5PNpVLk1Y17OV0I576T9SfaQoBjJ\naH1M/zC4aVaS0DYB/Gxq7v8=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "tests/test_aiohttp.py",
    "content": "try:\n    import aiohttp\n    import aiohttp.web\nexcept ImportError:\n    skip_tests = True\nelse:\n    skip_tests = False\n\nimport asyncio\nimport sys\nimport unittest\nimport weakref\n\nfrom uvloop import _testbase as tb\n\n\nclass _TestAioHTTP:\n\n    def test_aiohttp_basic_1(self):\n\n        PAYLOAD = '<h1>It Works!</h1>' * 10000\n\n        async def on_request(request):\n            return aiohttp.web.Response(text=PAYLOAD)\n\n        asyncio.set_event_loop(self.loop)\n        app = aiohttp.web.Application()\n        app.router.add_get('/', on_request)\n\n        runner = aiohttp.web.AppRunner(app)\n        self.loop.run_until_complete(runner.setup())\n        site = aiohttp.web.TCPSite(runner, '0.0.0.0', '0')\n        self.loop.run_until_complete(site.start())\n        port = site._server.sockets[0].getsockname()[1]\n\n        async def test():\n            # Make sure we're using the correct event loop.\n            self.assertIs(asyncio.get_event_loop(), self.loop)\n\n            for addr in (('localhost', port),\n                         ('127.0.0.1', port)):\n                async with aiohttp.ClientSession() as client:\n                    async with client.get('http://{}:{}'.format(*addr)) as r:\n                        self.assertEqual(r.status, 200)\n                        result = await r.text()\n                        self.assertEqual(result, PAYLOAD)\n\n        self.loop.run_until_complete(test())\n        self.loop.run_until_complete(runner.cleanup())\n\n    def test_aiohttp_graceful_shutdown(self):\n        if self.implementation == 'asyncio' and sys.version_info >= (3, 12, 0):\n            # In Python 3.12.0, asyncio.Server.wait_closed() waits for all\n            # existing connections to complete, before aiohttp sends\n            # on_shutdown signals.\n            # https://github.com/aio-libs/aiohttp/issues/7675#issuecomment-1752143748\n            # https://github.com/python/cpython/pull/98582\n            raise unittest.SkipTest('bug in aiohttp: #7675')\n\n        async def websocket_handler(request):\n            ws = aiohttp.web.WebSocketResponse()\n            await ws.prepare(request)\n            request.app['websockets'].add(ws)\n            try:\n                async for msg in ws:\n                    await ws.send_str(msg.data)\n            finally:\n                request.app['websockets'].discard(ws)\n            return ws\n\n        async def on_shutdown(app):\n            for ws in set(app['websockets']):\n                await ws.close(\n                    code=aiohttp.WSCloseCode.GOING_AWAY,\n                    message='Server shutdown')\n\n        asyncio.set_event_loop(self.loop)\n        app = aiohttp.web.Application()\n        app.router.add_get('/', websocket_handler)\n        app.on_shutdown.append(on_shutdown)\n        app['websockets'] = weakref.WeakSet()\n\n        runner = aiohttp.web.AppRunner(app)\n        self.loop.run_until_complete(runner.setup())\n        site = aiohttp.web.TCPSite(\n            runner,\n            '0.0.0.0',\n            0,\n            # https://github.com/aio-libs/aiohttp/pull/7188\n            shutdown_timeout=0.1,\n        )\n        self.loop.run_until_complete(site.start())\n        port = site._server.sockets[0].getsockname()[1]\n\n        async def client():\n            async with aiohttp.ClientSession() as client:\n                async with client.ws_connect(\n                        'http://127.0.0.1:{}'.format(port)) as ws:\n                    await ws.send_str(\"hello\")\n                    async for msg in ws:\n                        assert msg.data == \"hello\"\n\n        client_task = asyncio.ensure_future(client())\n\n        async def stop():\n            await asyncio.sleep(0.1)\n            try:\n                await asyncio.wait_for(runner.cleanup(), timeout=0.5)\n            finally:\n                try:\n                    client_task.cancel()\n                    await client_task\n                except asyncio.CancelledError:\n                    pass\n\n        self.loop.run_until_complete(stop())\n\n\n@unittest.skipIf(skip_tests, \"no aiohttp module\")\nclass Test_UV_AioHTTP(_TestAioHTTP, tb.UVTestCase):\n    pass\n\n\n@unittest.skipIf(skip_tests, \"no aiohttp module\")\nclass Test_AIO_AioHTTP(_TestAioHTTP, tb.AIOTestCase):\n    pass\n"
  },
  {
    "path": "tests/test_base.py",
    "content": "import asyncio\nimport fcntl\nimport logging\nimport os\nimport random\nimport sys\nimport subprocess\nimport threading\nimport time\nimport uvloop\nimport unittest\nimport weakref\n\nfrom unittest import mock\nfrom uvloop._testbase import UVTestCase, AIOTestCase\n\n\nclass _TestBase:\n\n    def test_close(self):\n        self.assertFalse(self.loop._closed)\n        self.assertFalse(self.loop.is_closed())\n        self.loop.close()\n        self.assertTrue(self.loop._closed)\n        self.assertTrue(self.loop.is_closed())\n\n        # it should be possible to call close() more than once\n        self.loop.close()\n        self.loop.close()\n\n        # operation blocked when the loop is closed\n        f = asyncio.Future()\n        self.assertRaises(RuntimeError, self.loop.run_forever)\n        self.assertRaises(RuntimeError, self.loop.run_until_complete, f)\n\n    def test_handle_weakref(self):\n        wd = weakref.WeakValueDictionary()\n        h = self.loop.call_soon(lambda: None)\n        wd['h'] = h  # Would fail without __weakref__ slot.\n\n    def test_call_soon_1(self):\n        calls = []\n\n        def cb(inc):\n            calls.append(inc)\n            self.loop.stop()\n\n        self.loop.call_soon(cb, 10)\n\n        h = self.loop.call_soon(cb, 100)\n        self.assertIn('.cb', repr(h))\n        h.cancel()\n        self.assertIn('cancelled', repr(h))\n\n        self.loop.call_soon(cb, 1)\n\n        self.loop.run_forever()\n\n        self.assertEqual(calls, [10, 1])\n\n    def test_call_soon_2(self):\n        waiter = self.loop.create_future()\n        waiter_r = weakref.ref(waiter)\n        self.loop.call_soon(lambda f: f.set_result(None), waiter)\n        self.loop.run_until_complete(waiter)\n        del waiter\n        self.assertIsNone(waiter_r())\n\n    def test_call_soon_3(self):\n        waiter = self.loop.create_future()\n        waiter_r = weakref.ref(waiter)\n        self.loop.call_soon(lambda f=waiter: f.set_result(None))\n        self.loop.run_until_complete(waiter)\n        del waiter\n        self.assertIsNone(waiter_r())\n\n    def test_call_soon_base_exc(self):\n        def cb():\n            raise KeyboardInterrupt()\n\n        self.loop.call_soon(cb)\n\n        with self.assertRaises(KeyboardInterrupt):\n            self.loop.run_forever()\n\n        self.assertFalse(self.loop.is_closed())\n\n    def test_calls_debug_reporting(self):\n        def run_test(debug, meth, stack_adj):\n            context = None\n\n            def handler(loop, ctx):\n                nonlocal context\n                context = ctx\n\n            self.loop.set_debug(debug)\n            self.loop.set_exception_handler(handler)\n\n            def cb():\n                1 / 0\n\n            meth(cb)\n            self.assertIsNone(context)\n            self.loop.run_until_complete(asyncio.sleep(0.05))\n\n            self.assertIs(type(context['exception']), ZeroDivisionError)\n            self.assertTrue(context['message'].startswith(\n                'Exception in callback'))\n\n            if debug:\n                tb = context['source_traceback']\n                self.assertEqual(tb[-1 + stack_adj].name, 'run_test')\n            else:\n                self.assertFalse('source_traceback' in context)\n\n            del context\n\n        for debug in (True, False):\n            for meth_name, meth, stack_adj in (\n                ('call_soon',\n                    self.loop.call_soon, 0),\n                ('call_later',  # `-1` accounts for lambda\n                    lambda *args: self.loop.call_later(0.01, *args), -1)\n            ):\n                with self.subTest(debug=debug, meth_name=meth_name):\n                    run_test(debug, meth, stack_adj)\n\n    def test_now_update(self):\n        async def run():\n            st = self.loop.time()\n            time.sleep(0.05)\n            return self.loop.time() - st\n\n        delta = self.loop.run_until_complete(run())\n        self.assertTrue(delta > 0.049 and delta < 0.6)\n\n    def test_call_later_1(self):\n        calls = []\n\n        def cb(inc=10, stop=False):\n            calls.append(inc)\n            self.assertTrue(self.loop.is_running())\n            if stop:\n                self.loop.call_soon(self.loop.stop)\n\n        self.loop.call_later(0.05, cb)\n\n        # canceled right away\n        h = self.loop.call_later(0.05, cb, 100, True)\n        self.assertIn('.cb', repr(h))\n        h.cancel()\n        self.assertIn('cancelled', repr(h))\n\n        self.loop.call_later(0.05, cb, 1, True)\n        self.loop.call_later(1000, cb, 1000)  # shouldn't be called\n\n        started = time.monotonic()\n        self.loop.run_forever()\n        finished = time.monotonic()\n\n        self.assertEqual(calls, [10, 1])\n        self.assertFalse(self.loop.is_running())\n\n        self.assertLess(finished - started, 0.3)\n        self.assertGreater(finished - started, 0.04)\n\n    def test_call_later_2(self):\n        # Test that loop.call_later triggers an update of\n        # libuv cached time.\n\n        async def main():\n            await asyncio.sleep(0.001)\n            time.sleep(0.01)\n            await asyncio.sleep(0.01)\n\n        started = time.monotonic()\n        self.loop.run_until_complete(main())\n        delta = time.monotonic() - started\n        self.assertGreater(delta, 0.019)\n\n    def test_call_later_3(self):\n        # a memory leak regression test\n        waiter = self.loop.create_future()\n        waiter_r = weakref.ref(waiter)\n        self.loop.call_later(0.01, lambda f: f.set_result(None), waiter)\n        self.loop.run_until_complete(waiter)\n        del waiter\n        self.assertIsNone(waiter_r())\n\n    def test_call_later_4(self):\n        # a memory leak regression test\n        waiter = self.loop.create_future()\n        waiter_r = weakref.ref(waiter)\n        self.loop.call_later(0.01, lambda f=waiter: f.set_result(None))\n        self.loop.run_until_complete(waiter)\n        del waiter\n        self.assertIsNone(waiter_r())\n\n    def test_call_later_negative(self):\n        calls = []\n\n        def cb(arg):\n            calls.append(arg)\n            self.loop.stop()\n\n        self.loop.call_later(-1, cb, 'a')\n        self.loop.run_forever()\n        self.assertEqual(calls, ['a'])\n\n    def test_call_later_rounding(self):\n        # Refs #233, call_later() and call_at() shouldn't call cb early\n\n        def cb():\n            self.loop.stop()\n\n        for i in range(8):\n            self.loop.call_later(0.06 + 0.01, cb)  # 0.06999999999999999\n            started = int(round(self.loop.time() * 1000))\n            self.loop.run_forever()\n            finished = int(round(self.loop.time() * 1000))\n            self.assertGreaterEqual(finished - started, 69)\n\n    def test_call_at(self):\n        if (os.environ.get('TRAVIS_OS_NAME')\n                or os.environ.get('GITHUB_WORKFLOW')):\n            # Time seems to be really unpredictable on Travis.\n            raise unittest.SkipTest('time is not monotonic on CI')\n\n        i = 0\n\n        def cb(inc):\n            nonlocal i\n            i += inc\n            self.loop.stop()\n\n        at = self.loop.time() + 0.05\n\n        self.loop.call_at(at, cb, 100).cancel()\n        self.loop.call_at(at, cb, 10)\n\n        started = time.monotonic()\n        self.loop.run_forever()\n        finished = time.monotonic()\n\n        self.assertEqual(i, 10)\n\n        self.assertLess(finished - started, 0.07)\n        self.assertGreater(finished - started, 0.045)\n\n    def test_check_thread(self):\n        def check_thread(loop, debug):\n            def cb():\n                pass\n\n            loop.set_debug(debug)\n            if debug:\n                msg = (\"Non-thread-safe operation invoked on an \"\n                       \"event loop other than the current one\")\n                with self.assertRaisesRegex(RuntimeError, msg):\n                    loop.call_soon(cb)\n                with self.assertRaisesRegex(RuntimeError, msg):\n                    loop.call_later(60, cb)\n                with self.assertRaisesRegex(RuntimeError, msg):\n                    loop.call_at(loop.time() + 60, cb)\n            else:\n                loop.call_soon(cb)\n                loop.call_later(60, cb)\n                loop.call_at(loop.time() + 60, cb)\n\n        def check_in_thread(loop, event, debug, create_loop, fut):\n            # wait until the event loop is running\n            event.wait()\n\n            try:\n                if create_loop:\n                    loop2 = self.new_loop()\n                    try:\n                        asyncio.set_event_loop(loop2)\n                        check_thread(loop, debug)\n                    finally:\n                        asyncio.set_event_loop(None)\n                        loop2.close()\n                else:\n                    check_thread(loop, debug)\n            except Exception as exc:\n                loop.call_soon_threadsafe(fut.set_exception, exc)\n            else:\n                loop.call_soon_threadsafe(fut.set_result, None)\n\n        def test_thread(loop, debug, create_loop=False):\n            event = threading.Event()\n            fut = asyncio.Future(loop=loop)\n            loop.call_soon(event.set)\n            args = (loop, event, debug, create_loop, fut)\n            thread = threading.Thread(target=check_in_thread, args=args)\n            thread.start()\n            loop.run_until_complete(fut)\n            thread.join()\n\n        # raise RuntimeError if the thread has no event loop\n        test_thread(self.loop, True)\n\n        # check disabled if debug mode is disabled\n        test_thread(self.loop, False)\n\n        # raise RuntimeError if the event loop of the thread is not the called\n        # event loop\n        test_thread(self.loop, True, create_loop=True)\n\n        # check disabled if debug mode is disabled\n        test_thread(self.loop, False, create_loop=True)\n\n    def test_run_once_in_executor_plain(self):\n        called = []\n\n        def cb(arg):\n            called.append(arg)\n\n        async def runner():\n            await self.loop.run_in_executor(None, cb, 'a')\n\n        self.loop.run_until_complete(runner())\n\n        self.assertEqual(called, ['a'])\n\n    def test_set_debug(self):\n        self.loop.set_debug(True)\n        self.assertTrue(self.loop.get_debug())\n        self.loop.set_debug(False)\n        self.assertFalse(self.loop.get_debug())\n\n    def test_run_until_complete_type_error(self):\n        self.assertRaises(\n            TypeError, self.loop.run_until_complete, 'blah')\n\n    def test_run_until_complete_loop(self):\n        task = asyncio.Future()\n        other_loop = self.new_loop()\n        self.addCleanup(other_loop.close)\n        self.assertRaises(\n            ValueError, other_loop.run_until_complete, task)\n\n    def test_run_until_complete_error(self):\n        async def foo():\n            raise ValueError('aaa')\n        with self.assertRaisesRegex(ValueError, 'aaa'):\n            self.loop.run_until_complete(foo())\n\n    def test_run_until_complete_loop_orphan_future_close_loop(self):\n        async def foo(delay):\n            await asyncio.sleep(delay)\n\n        def throw():\n            raise KeyboardInterrupt\n\n        self.loop.call_soon(throw)\n        try:\n            self.loop.run_until_complete(foo(0.1))\n        except KeyboardInterrupt:\n            pass\n\n        # This call fails if run_until_complete does not clean up\n        # done-callback for the previous future.\n        self.loop.run_until_complete(foo(0.2))\n\n    def test_run_until_complete_keyboard_interrupt(self):\n        # Issue #336: run_until_complete() must not schedule a pending\n        # call to stop() if the future raised a KeyboardInterrupt\n        async def raise_keyboard_interrupt():\n            raise KeyboardInterrupt\n\n        self.loop._process_events = mock.Mock()\n\n        with self.assertRaises(KeyboardInterrupt):\n            self.loop.run_until_complete(raise_keyboard_interrupt())\n\n        def func():\n            self.loop.stop()\n            func.called = True\n\n        func.called = False\n        self.loop.call_later(0.01, func)\n        self.loop.run_forever()\n        self.assertTrue(func.called)\n\n    def test_debug_slow_callbacks(self):\n        logger = logging.getLogger('asyncio')\n        self.loop.set_debug(True)\n        self.loop.slow_callback_duration = 0.2\n        self.loop.call_soon(lambda: time.sleep(0.3))\n\n        with mock.patch.object(logger, 'warning') as log:\n            self.loop.run_until_complete(asyncio.sleep(0))\n\n        self.assertEqual(log.call_count, 1)\n        # format message\n        msg = log.call_args[0][0] % log.call_args[0][1:]\n\n        self.assertIn('Executing <Handle', msg)\n        self.assertIn('test_debug_slow_callbacks', msg)\n\n    def test_debug_slow_timer_callbacks(self):\n        logger = logging.getLogger('asyncio')\n        self.loop.set_debug(True)\n        self.loop.slow_callback_duration = 0.2\n        self.loop.call_later(0.01, lambda: time.sleep(0.3))\n\n        with mock.patch.object(logger, 'warning') as log:\n            self.loop.run_until_complete(asyncio.sleep(0.02))\n\n        self.assertEqual(log.call_count, 1)\n        # format message\n        msg = log.call_args[0][0] % log.call_args[0][1:]\n\n        self.assertIn('Executing <TimerHandle', msg)\n        self.assertIn('test_debug_slow_timer_callbacks', msg)\n\n    def test_debug_slow_task_callbacks(self):\n        logger = logging.getLogger('asyncio')\n        self.loop.set_debug(True)\n        self.loop.slow_callback_duration = 0.2\n\n        async def foo():\n            time.sleep(0.3)\n\n        with mock.patch.object(logger, 'warning') as log:\n            self.loop.run_until_complete(foo())\n\n        self.assertEqual(log.call_count, 1)\n        # format message\n        msg = log.call_args[0][0] % log.call_args[0][1:]\n\n        self.assertIn('Executing <Task finished', msg)\n        self.assertIn('test_debug_slow_task_callbacks', msg)\n\n    def test_default_exc_handler_callback(self):\n        self.loop.set_exception_handler(None)\n\n        self.loop._process_events = mock.Mock()\n\n        def zero_error(fut):\n            fut.set_result(True)\n            1 / 0\n\n        logger = logging.getLogger('asyncio')\n\n        # Test call_soon (events.Handle)\n        with mock.patch.object(logger, 'error') as log:\n            fut = asyncio.Future()\n            self.loop.call_soon(zero_error, fut)\n            fut.add_done_callback(lambda fut: self.loop.stop())\n            self.loop.run_forever()\n            log.assert_called_with(\n                self.mock_pattern('Exception in callback.*zero'),\n                exc_info=mock.ANY)\n\n        # Test call_later (events.TimerHandle)\n        with mock.patch.object(logger, 'error') as log:\n            fut = asyncio.Future()\n            self.loop.call_later(0.01, zero_error, fut)\n            fut.add_done_callback(lambda fut: self.loop.stop())\n            self.loop.run_forever()\n            log.assert_called_with(\n                self.mock_pattern('Exception in callback.*zero'),\n                exc_info=mock.ANY)\n\n    def test_set_exc_handler_custom(self):\n        self.loop.set_exception_handler(None)\n        logger = logging.getLogger('asyncio')\n\n        def run_loop():\n            def zero_error():\n                self.loop.stop()\n                1 / 0\n            self.loop.call_soon(zero_error)\n            self.loop.run_forever()\n\n        errors = []\n\n        def handler(loop, exc):\n            errors.append(exc)\n\n        self.loop.set_debug(True)\n\n        self.assertIsNone(self.loop.get_exception_handler())\n        self.loop.set_exception_handler(handler)\n        if hasattr(self.loop, 'get_exception_handler'):\n            self.assertIs(self.loop.get_exception_handler(), handler)\n        run_loop()\n        self.assertEqual(len(errors), 1)\n        self.assertRegex(errors[-1]['message'],\n                         'Exception in callback.*zero_error')\n\n        self.loop.set_exception_handler(None)\n        with mock.patch.object(logger, 'error') as log:\n            run_loop()\n            log.assert_called_with(\n                self.mock_pattern('Exception in callback.*zero'),\n                exc_info=mock.ANY)\n\n        self.assertEqual(len(errors), 1)\n\n    def test_set_exc_handler_broken(self):\n        logger = logging.getLogger('asyncio')\n\n        def run_loop():\n            def zero_error():\n                self.loop.stop()\n                1 / 0\n            self.loop.call_soon(zero_error)\n            self.loop.run_forever()\n\n        def handler(loop, context):\n            raise AttributeError('spam')\n\n        self.loop._process_events = mock.Mock()\n\n        self.loop.set_exception_handler(handler)\n\n        with mock.patch.object(logger, 'error') as log:\n            run_loop()\n            log.assert_called_with(\n                self.mock_pattern('Unhandled error in exception handler'),\n                exc_info=mock.ANY)\n\n    def test_set_task_factory_invalid(self):\n        with self.assertRaisesRegex(\n                TypeError,\n                'task factory must be a callable or None'):\n\n            self.loop.set_task_factory(1)\n\n        self.assertIsNone(self.loop.get_task_factory())\n\n    def test_set_task_factory(self):\n        self.loop._process_events = mock.Mock()\n\n        class MyTask(asyncio.Task):\n            pass\n\n        async def coro():\n            pass\n\n        factory = lambda loop, coro, **kwargs: MyTask(\n            coro, loop=loop, **kwargs\n        )\n\n        self.assertIsNone(self.loop.get_task_factory())\n        self.loop.set_task_factory(factory)\n        self.assertIs(self.loop.get_task_factory(), factory)\n\n        task = self.loop.create_task(coro())\n        self.assertTrue(isinstance(task, MyTask))\n        self.loop.run_until_complete(task)\n\n        self.loop.set_task_factory(None)\n        self.assertIsNone(self.loop.get_task_factory())\n\n        task = self.loop.create_task(coro())\n        self.assertTrue(isinstance(task, asyncio.Task))\n        self.assertFalse(isinstance(task, MyTask))\n        self.loop.run_until_complete(task)\n\n    def test_set_task_name(self):\n        self.loop._process_events = mock.Mock()\n\n        result = None\n\n        class MyTask(asyncio.Task):\n            def set_name(self, name):\n                nonlocal result\n                result = name + \"!\"\n\n            def get_name(self):\n                return result\n\n        async def coro():\n            pass\n\n        def factory(loop, coro, **kwargs):\n            task = MyTask(coro, loop=loop, **kwargs)\n            # Python moved the responsibility to set the name to the Task\n            # class constructor, so MyTask.set_name is never called by\n            # Python's create_task.  Compensate for that here.\n            if self.is_asyncio_loop() and \"name\" in kwargs:\n                task.set_name(kwargs[\"name\"])\n            return task\n\n        self.assertIsNone(self.loop.get_task_factory())\n        task = self.loop.create_task(coro(), name=\"mytask\")\n        self.assertFalse(isinstance(task, MyTask))\n        self.assertEqual(task.get_name(), \"mytask\")\n        self.loop.run_until_complete(task)\n\n        self.loop.set_task_factory(factory)\n        self.assertIs(self.loop.get_task_factory(), factory)\n\n        task = self.loop.create_task(coro(), name=\"mytask\")\n        self.assertTrue(isinstance(task, MyTask))\n        self.assertEqual(result, \"mytask!\")\n        self.assertEqual(task.get_name(), \"mytask!\")\n        self.loop.run_until_complete(task)\n\n        self.loop.set_task_factory(None)\n        self.assertIsNone(self.loop.get_task_factory())\n\n    def test_shutdown_asyncgens_01(self):\n        finalized = list()\n\n        if not hasattr(self.loop, 'shutdown_asyncgens'):\n            raise unittest.SkipTest()\n\n        async def waiter(timeout, finalized):\n            try:\n                await asyncio.sleep(timeout)\n                yield 1\n            finally:\n                await asyncio.sleep(0)\n                finalized.append(1)\n\n        async def wait():\n            async for _ in waiter(1, finalized):\n                pass\n\n        t1 = self.loop.create_task(wait())\n        t2 = self.loop.create_task(wait())\n\n        self.loop.run_until_complete(asyncio.sleep(0.1))\n\n        t1.cancel()\n        t2.cancel()\n        self.loop.run_until_complete(self.loop.shutdown_asyncgens())\n        self.assertEqual(finalized, [1, 1])\n\n        for t in {t1, t2}:\n            try:\n                self.loop.run_until_complete(t)\n            except asyncio.CancelledError:\n                pass\n\n    def test_shutdown_asyncgens_02(self):\n        if not hasattr(self.loop, 'shutdown_asyncgens'):\n            raise unittest.SkipTest()\n\n        logged = 0\n\n        def logger(loop, context):\n            nonlocal logged\n            expected = 'an error occurred during closing of asynchronous'\n            if expected in context['message']:\n                self.assertIn('asyncgen', context)\n                logged += 1\n\n        async def waiter(timeout):\n            try:\n                await asyncio.sleep(timeout)\n                yield 1\n            finally:\n                1 / 0\n\n        async def wait():\n            async for _ in waiter(1):\n                pass\n\n        t = self.loop.create_task(wait())\n        self.loop.run_until_complete(asyncio.sleep(0.1))\n\n        self.loop.set_exception_handler(logger)\n        self.loop.run_until_complete(self.loop.shutdown_asyncgens())\n\n        self.assertEqual(logged, 1)\n\n        # Silence warnings\n        t.cancel()\n        self.loop.run_until_complete(asyncio.sleep(0.1))\n\n    def test_shutdown_asyncgens_03(self):\n        if not hasattr(self.loop, 'shutdown_asyncgens'):\n            raise unittest.SkipTest()\n\n        async def waiter():\n            yield 1\n            yield 2\n\n        async def foo():\n            # We specifically want to hit _asyncgen_finalizer_hook\n            # method.\n            await waiter().asend(None)\n\n        self.loop.run_until_complete(foo())\n        self.loop.run_until_complete(asyncio.sleep(0.01))\n\n    def test_inf_wait_for(self):\n        async def foo():\n            await asyncio.sleep(0.1)\n            return 123\n        res = self.loop.run_until_complete(\n            asyncio.wait_for(foo(), timeout=float('inf')))\n        self.assertEqual(res, 123)\n\n    def test_shutdown_default_executor(self):\n        if not hasattr(self.loop, \"shutdown_default_executor\"):\n            raise unittest.SkipTest()\n\n        async def foo():\n            await self.loop.run_in_executor(None, time.sleep, .1)\n\n        self.loop.run_until_complete(foo())\n        self.loop.run_until_complete(\n            self.loop.shutdown_default_executor())\n\n    def test_call_soon_threadsafe_safety(self):\n        ITERATIONS = 4096\n        counter = [0]\n\n        def cb():\n            counter[0] += 1\n            if counter[0] < ITERATIONS - 512:\n                h = self.loop.call_later(0.01, lambda: None)\n                self.loop.call_later(\n                    0.0005 + random.random() * 0.0005, h.cancel\n                )\n\n        def scheduler():\n            loop = self.loop\n            for i in range(ITERATIONS):\n                if loop.is_running():\n                    loop.call_soon_threadsafe(cb)\n                time.sleep(0.001)\n            loop.call_soon_threadsafe(loop.stop)\n\n        thread = threading.Thread(target=scheduler)\n\n        self.loop.call_soon(thread.start)\n        self.loop.run_forever()\n        thread.join()\n        self.assertEqual(counter[0], ITERATIONS)\n\n    def test_freethreading(self):\n        if not hasattr(sys, \"_is_gil_enabled\"):\n            raise unittest.SkipTest(\"No sys._is_gil_enabled()\")\n        if os.cpu_count() < 2:\n            raise unittest.SkipTest(\"Flaky on single CPU machines\")\n        prog = \"\"\"\\\nimport asyncio\nimport os\nimport sys\nimport threading\nimport time\n\n\ncounter = 0\n\n\ndef job(barrier):\n    global counter\n    barrier.wait()\n    start_time = time.monotonic()\n    rv = 0\n    while time.monotonic() - start_time < 1:\n        for _i in range(10**4):\n            counter += 1\n            rv += 1\n    return rv\n\n\nasync def main():\n    if sys._is_gil_enabled():\n        print(\"{impl} turned on GIL\")\n        return False\n    loop = asyncio.get_running_loop()\n    n_jobs = os.cpu_count()\n    barrier = threading.Barrier(n_jobs)\n    fs = [loop.run_in_executor(None, job, barrier) for _ in range(n_jobs)]\n    result = sum(await asyncio.gather(*fs))\n    if counter == result:\n        print(\"Expected race condition did not happen\")\n        return False\n    return True\n\n\nif __name__ == \"__main__\":\n    if sys._is_gil_enabled():\n        print(\"Not running with GIL disabled\")\n        sys.exit(2)\n\n    import {impl}\n\n    if not {impl}.run(main()):\n        sys.exit(1)\n\"\"\"\n        result = subprocess.run(\n            [sys.executable, '-c', prog.format(impl=self.implementation)],\n            stdout=subprocess.PIPE,\n            text=True,\n        )\n        if result.returncode == 2:\n            raise unittest.SkipTest(result.stdout.strip())\n        elif result.returncode != 0:\n            self.fail(result.stdout.strip())\n\n\nclass TestBaseUV(_TestBase, UVTestCase):\n\n    def test_loop_create_future(self):\n        fut = self.loop.create_future()\n        self.assertTrue(isinstance(fut, asyncio.Future))\n        self.assertIs(fut._loop, self.loop)\n        fut.cancel()\n\n    def test_loop_call_soon_handle_cancelled(self):\n        cb = lambda: False  # NoQA\n        handle = self.loop.call_soon(cb)\n        self.assertFalse(handle.cancelled())\n        handle.cancel()\n        self.assertTrue(handle.cancelled())\n\n        handle = self.loop.call_soon(cb)\n        self.assertFalse(handle.cancelled())\n        self.run_loop_briefly()\n        self.assertFalse(handle.cancelled())\n\n    def test_loop_call_later_handle_cancelled(self):\n        cb = lambda: False  # NoQA\n        handle = self.loop.call_later(0.01, cb)\n        self.assertFalse(handle.cancelled())\n        handle.cancel()\n        self.assertTrue(handle.cancelled())\n\n        handle = self.loop.call_later(0.01, cb)\n        self.assertFalse(handle.cancelled())\n        self.run_loop_briefly(delay=0.05)\n        self.assertFalse(handle.cancelled())\n\n    def test_loop_std_files_cloexec(self):\n        # See https://github.com/MagicStack/uvloop/issues/40 for details.\n        for fd in {0, 1, 2}:\n            flags = fcntl.fcntl(fd, fcntl.F_GETFD)\n            self.assertFalse(flags & fcntl.FD_CLOEXEC)\n\n    def test_default_exc_handler_broken(self):\n        logger = logging.getLogger('asyncio')\n        _context = None\n\n        class Loop(uvloop.Loop):\n\n            _selector = mock.Mock()\n            _process_events = mock.Mock()\n\n            def default_exception_handler(self, context):\n                nonlocal _context\n                _context = context\n                # Simulates custom buggy \"default_exception_handler\"\n                raise ValueError('spam')\n\n        loop = Loop()\n        self.addCleanup(loop.close)\n        self.addCleanup(lambda: asyncio.set_event_loop(None))\n\n        asyncio.set_event_loop(loop)\n\n        def run_loop():\n            def zero_error():\n                loop.stop()\n                1 / 0\n            loop.call_soon(zero_error)\n            loop.run_forever()\n\n        with mock.patch.object(logger, 'error') as log:\n            run_loop()\n            log.assert_called_with(\n                'Exception in default exception handler',\n                exc_info=True)\n\n        def custom_handler(loop, context):\n            raise ValueError('ham')\n\n        _context = None\n        loop.set_exception_handler(custom_handler)\n        with mock.patch.object(logger, 'error') as log:\n            run_loop()\n            log.assert_called_with(\n                self.mock_pattern('Exception in default exception.*'\n                                  'while handling.*in custom'),\n                exc_info=True)\n\n            # Check that original context was passed to default\n            # exception handler.\n            self.assertIn('context', _context)\n            self.assertIs(type(_context['context']['exception']),\n                          ZeroDivisionError)\n\n    def test_big_call_later_timeout(self):\n        OK, NOT_OK = 0, 0\n\n        async def sleep(delay_name, delay):\n            nonlocal OK, NOT_OK\n            try:\n                await asyncio.sleep(delay)\n            except asyncio.CancelledError:\n                OK += 1\n            except Exception:\n                NOT_OK += 1\n\n        async def main():\n            tests = [\n                sleep(\"infinity\", float(\"inf\")),\n                sleep(\"sys.maxsize\", float(sys.maxsize)),\n                sleep(\"sys.maxsize\", sys.maxsize),\n                sleep(\"2**55\", 2**55),\n                sleep(\"2**54\", 2**54),\n            ]\n            tasks = [self.loop.create_task(test) for test in tests]\n            await asyncio.sleep(0.1)\n            for task in tasks:\n                task.cancel()\n                await task\n\n        self.loop.run_until_complete(main())\n\n        self.assertEqual(OK, 5)\n        self.assertEqual(NOT_OK, 0)\n\n    def test_loop_call_later_handle_when(self):\n        cb = lambda: False  # NoQA\n        delay = 1.0\n        loop_t = self.loop.time()\n        handle = self.loop.call_later(delay, cb)\n        self.assertAlmostEqual(handle.when(), loop_t + delay, places=2)\n        handle.cancel()\n        self.assertTrue(handle.cancelled())\n        self.assertAlmostEqual(handle.when(), loop_t + delay, places=2)\n\n    def test_loop_call_later_handle_when_after_fired(self):\n        fut = self.loop.create_future()\n        handle = self.loop.call_later(0.05, fut.set_result, None)\n        when = handle.when()\n        self.loop.run_until_complete(fut)\n        self.assertEqual(handle.when(), when)\n\n\nclass TestBaseAIO(_TestBase, AIOTestCase):\n    pass\n\n\nclass TestPolicy(unittest.TestCase):\n\n    def test_uvloop_policy(self):\n        try:\n            asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())\n            loop = asyncio.new_event_loop()\n            try:\n                self.assertIsInstance(loop, uvloop.Loop)\n            finally:\n                loop.close()\n        finally:\n            asyncio.set_event_loop_policy(None)\n\n    @unittest.skipUnless(hasattr(asyncio, '_get_running_loop'),\n                         'No asyncio._get_running_loop')\n    def test_running_loop_within_a_loop(self):\n        async def runner(loop):\n            loop.run_forever()\n\n        try:\n            asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())\n\n            loop = asyncio.new_event_loop()\n            outer_loop = asyncio.new_event_loop()\n\n            try:\n                with self.assertRaisesRegex(RuntimeError,\n                                            'while another loop is running'):\n                    outer_loop.run_until_complete(runner(loop))\n            finally:\n                loop.close()\n                outer_loop.close()\n\n        finally:\n            asyncio.set_event_loop_policy(None)\n\n    @unittest.skipUnless(hasattr(asyncio, '_get_running_loop'),\n                         'No asyncio._get_running_loop')\n    def test_get_event_loop_returns_running_loop(self):\n        class Policy(asyncio.DefaultEventLoopPolicy):\n            def get_event_loop(self):\n                raise NotImplementedError\n\n        loop = None\n\n        old_policy = asyncio.get_event_loop_policy()\n        try:\n            asyncio.set_event_loop_policy(Policy())\n            loop = uvloop.new_event_loop()\n            self.assertIs(asyncio._get_running_loop(), None)\n\n            async def func():\n                self.assertIs(asyncio.get_event_loop(), loop)\n                self.assertIs(asyncio._get_running_loop(), loop)\n\n            loop.run_until_complete(func())\n        finally:\n            asyncio.set_event_loop_policy(old_policy)\n            if loop is not None:\n                loop.close()\n\n        self.assertIs(asyncio._get_running_loop(), None)\n"
  },
  {
    "path": "tests/test_context.py",
    "content": "import asyncio\nimport contextvars\nimport decimal\nimport itertools\nimport random\nimport socket\nimport ssl\nimport sys\nimport tempfile\nimport unittest\nimport weakref\n\nfrom uvloop import _testbase as tb\n\n\nclass _BaseProtocol(asyncio.BaseProtocol):\n    def __init__(self, cvar, *, loop=None):\n        self.cvar = cvar\n        self.transport = None\n        self.connection_made_fut = asyncio.Future(loop=loop)\n        self.buffered_ctx = None\n        self.data_received_fut = asyncio.Future(loop=loop)\n        self.eof_received_fut = asyncio.Future(loop=loop)\n        self.pause_writing_fut = asyncio.Future(loop=loop)\n        self.resume_writing_fut = asyncio.Future(loop=loop)\n        self.pipe_ctx = {0, 1, 2}\n        self.pipe_connection_lost_fut = asyncio.Future(loop=loop)\n        self.process_exited_fut = asyncio.Future(loop=loop)\n        self.error_received_fut = asyncio.Future(loop=loop)\n        self.connection_lost_ctx = None\n        self.done = asyncio.Future(loop=loop)\n\n    def connection_made(self, transport):\n        self.transport = transport\n        self.connection_made_fut.set_result(self.cvar.get())\n\n    def connection_lost(self, exc):\n        self.connection_lost_ctx = self.cvar.get()\n        if exc is None:\n            self.done.set_result(None)\n        else:\n            self.done.set_exception(exc)\n\n    def eof_received(self):\n        self.eof_received_fut.set_result(self.cvar.get())\n\n    def pause_writing(self):\n        self.pause_writing_fut.set_result(self.cvar.get())\n\n    def resume_writing(self):\n        self.resume_writing_fut.set_result(self.cvar.get())\n\n\nclass _Protocol(_BaseProtocol, asyncio.Protocol):\n    def data_received(self, data):\n        self.data_received_fut.set_result(self.cvar.get())\n\n\nclass _BufferedProtocol(_BaseProtocol, asyncio.BufferedProtocol):\n    def get_buffer(self, sizehint):\n        if self.buffered_ctx is None:\n            self.buffered_ctx = self.cvar.get()\n        elif self.cvar.get() != self.buffered_ctx:\n            self.data_received_fut.set_exception(ValueError(\"{} != {}\".format(\n                self.buffered_ctx, self.cvar.get(),\n            )))\n        return bytearray(65536)\n\n    def buffer_updated(self, nbytes):\n        if not self.data_received_fut.done():\n            if self.cvar.get() == self.buffered_ctx:\n                self.data_received_fut.set_result(self.cvar.get())\n            else:\n                self.data_received_fut.set_exception(\n                    ValueError(\"{} != {}\".format(\n                        self.buffered_ctx, self.cvar.get(),\n                    ))\n                )\n\n\nclass _DatagramProtocol(_BaseProtocol, asyncio.DatagramProtocol):\n    def datagram_received(self, data, addr):\n        self.data_received_fut.set_result(self.cvar.get())\n\n    def error_received(self, exc):\n        self.error_received_fut.set_result(self.cvar.get())\n\n\nclass _SubprocessProtocol(_BaseProtocol, asyncio.SubprocessProtocol):\n    def pipe_data_received(self, fd, data):\n        self.data_received_fut.set_result(self.cvar.get())\n\n    def pipe_connection_lost(self, fd, exc):\n        self.pipe_ctx.remove(fd)\n        val = self.cvar.get()\n        self.pipe_ctx.add(val)\n        if not any(isinstance(x, int) for x in self.pipe_ctx):\n            if len(self.pipe_ctx) == 1:\n                self.pipe_connection_lost_fut.set_result(val)\n            else:\n                self.pipe_connection_lost_fut.set_exception(\n                    AssertionError(str(list(self.pipe_ctx))))\n\n    def process_exited(self):\n        self.process_exited_fut.set_result(self.cvar.get())\n\n\nclass _SSLSocketOverSSL:\n    # because wrap_socket() doesn't work correctly on\n    # SSLSocket, we have to do the 2nd level SSL manually\n\n    def __init__(self, ssl_sock, ctx, **kwargs):\n        self.sock = ssl_sock\n        self.incoming = ssl.MemoryBIO()\n        self.outgoing = ssl.MemoryBIO()\n        self.sslobj = ctx.wrap_bio(\n            self.incoming, self.outgoing, **kwargs)\n        self.do(self.sslobj.do_handshake)\n\n    def do(self, func, *args):\n        while True:\n            try:\n                rv = func(*args)\n                break\n            except ssl.SSLWantReadError:\n                if self.outgoing.pending:\n                    self.sock.send(self.outgoing.read())\n                self.incoming.write(self.sock.recv(65536))\n        if self.outgoing.pending:\n            self.sock.send(self.outgoing.read())\n        return rv\n\n    def send(self, data):\n        self.do(self.sslobj.write, data)\n\n    def unwrap(self):\n        self.do(self.sslobj.unwrap)\n\n    def close(self):\n        self.sock.unwrap()\n        self.sock.close()\n\n\nclass _ContextBaseTests(tb.SSLTestCase):\n\n    ONLYCERT = tb._cert_fullname(__file__, 'ssl_cert.pem')\n    ONLYKEY = tb._cert_fullname(__file__, 'ssl_key.pem')\n\n    def test_task_decimal_context(self):\n        async def fractions(t, precision, x, y):\n            with decimal.localcontext() as ctx:\n                ctx.prec = precision\n                a = decimal.Decimal(x) / decimal.Decimal(y)\n                await asyncio.sleep(t)\n                b = decimal.Decimal(x) / decimal.Decimal(y ** 2)\n                return a, b\n\n        async def main():\n            r1, r2 = await asyncio.gather(\n                fractions(0.1, 3, 1, 3), fractions(0.2, 6, 1, 3))\n\n            return r1, r2\n\n        r1, r2 = self.loop.run_until_complete(main())\n\n        self.assertEqual(str(r1[0]), '0.333')\n        self.assertEqual(str(r1[1]), '0.111')\n\n        self.assertEqual(str(r2[0]), '0.333333')\n        self.assertEqual(str(r2[1]), '0.111111')\n\n    def test_task_context_1(self):\n        cvar = contextvars.ContextVar('cvar', default='nope')\n\n        async def sub():\n            await asyncio.sleep(0.01)\n            self.assertEqual(cvar.get(), 'nope')\n            cvar.set('something else')\n\n        async def main():\n            self.assertEqual(cvar.get(), 'nope')\n            subtask = self.loop.create_task(sub())\n            cvar.set('yes')\n            self.assertEqual(cvar.get(), 'yes')\n            await subtask\n            self.assertEqual(cvar.get(), 'yes')\n\n        task = self.loop.create_task(main())\n        self.loop.run_until_complete(task)\n\n    def test_task_context_2(self):\n        cvar = contextvars.ContextVar('cvar', default='nope')\n\n        async def main():\n            def fut_on_done(fut):\n                # This change must not pollute the context\n                # of the \"main()\" task.\n                cvar.set('something else')\n\n            self.assertEqual(cvar.get(), 'nope')\n\n            for j in range(2):\n                fut = self.loop.create_future()\n                fut.add_done_callback(fut_on_done)\n                cvar.set('yes{}'.format(j))\n                self.loop.call_soon(fut.set_result, None)\n                await fut\n                self.assertEqual(cvar.get(), 'yes{}'.format(j))\n\n                for i in range(3):\n                    # Test that task passed its context to add_done_callback:\n                    cvar.set('yes{}-{}'.format(i, j))\n                    await asyncio.sleep(0.001)\n                    self.assertEqual(cvar.get(), 'yes{}-{}'.format(i, j))\n\n        task = self.loop.create_task(main())\n        self.loop.run_until_complete(task)\n\n        self.assertEqual(cvar.get(), 'nope')\n\n    def test_task_context_3(self):\n        cvar = contextvars.ContextVar('cvar', default=-1)\n\n        # Run 100 Tasks in parallel, each modifying cvar.\n\n        async def sub(num):\n            for i in range(10):\n                cvar.set(num + i)\n                await asyncio.sleep(random.uniform(0.001, 0.05))\n                self.assertEqual(cvar.get(), num + i)\n\n        async def main():\n            tasks = []\n            for i in range(100):\n                task = self.loop.create_task(sub(random.randint(0, 10)))\n                tasks.append(task)\n\n            await asyncio.gather(*tasks, return_exceptions=True)\n\n        self.loop.run_until_complete(main())\n\n        self.assertEqual(cvar.get(), -1)\n\n    def test_task_context_4(self):\n        cvar = contextvars.ContextVar('cvar', default='nope')\n\n        class TrackMe:\n            pass\n        tracked = TrackMe()\n        ref = weakref.ref(tracked)\n\n        async def sub():\n            cvar.set(tracked)  # NoQA\n            self.loop.call_soon(lambda: None)\n\n        async def main():\n            await self.loop.create_task(sub())\n            await asyncio.sleep(0.01)\n\n        task = self.loop.create_task(main())\n        self.loop.run_until_complete(task)\n\n        del tracked\n        self.assertIsNone(ref())\n\n    def _run_test(self, method, **switches):\n        switches.setdefault('use_tcp', 'both')\n        use_ssl = switches.setdefault('use_ssl', 'no') in {'yes', 'both'}\n        names = ['factory']\n        options = [(_Protocol, _BufferedProtocol)]\n        for k, v in switches.items():\n            if v == 'yes':\n                options.append((True,))\n            elif v == 'no':\n                options.append((False,))\n            elif v == 'both':\n                options.append((True, False))\n            else:\n                raise ValueError(f\"Illegal {k}={v}, can only be yes/no/both\")\n            names.append(k)\n\n        for combo in itertools.product(*options):\n            values = dict(zip(names, combo))\n            with self.subTest(**values):\n                cvar = contextvars.ContextVar('cvar', default='outer')\n                values['proto'] = values.pop('factory')(cvar, loop=self.loop)\n\n                async def test():\n                    self.assertEqual(cvar.get(), 'outer')\n                    cvar.set('inner')\n                    tmp_dir = tempfile.TemporaryDirectory()\n                    if use_ssl:\n                        values['sslctx'] = self._create_server_ssl_context(\n                            self.ONLYCERT, self.ONLYKEY)\n                        values['client_sslctx'] = \\\n                            self._create_client_ssl_context()\n                    else:\n                        values['sslctx'] = values['client_sslctx'] = None\n\n                    if values['use_tcp']:\n                        values['addr'] = ('127.0.0.1', tb.find_free_port())\n                        values['family'] = socket.AF_INET\n                    else:\n                        values['addr'] = tmp_dir.name + '/test.sock'\n                        values['family'] = socket.AF_UNIX\n\n                    try:\n                        await method(cvar=cvar, **values)\n                    finally:\n                        tmp_dir.cleanup()\n\n                self.loop.run_until_complete(test())\n\n    def _run_server_test(self, method, async_sock=False, **switches):\n        async def test(sslctx, client_sslctx, addr, family, **values):\n            if values['use_tcp']:\n                srv = await self.loop.create_server(\n                    lambda: values['proto'], *addr, ssl=sslctx)\n            else:\n                srv = await self.loop.create_unix_server(\n                    lambda: values['proto'], addr, ssl=sslctx)\n            s = socket.socket(family)\n\n            if async_sock:\n                s.setblocking(False)\n                await self.loop.sock_connect(s, addr)\n            else:\n                await self.loop.run_in_executor(\n                    None, s.connect, addr)\n                if values['use_ssl']:\n                    values['ssl_sock'] = await self.loop.run_in_executor(\n                        None, client_sslctx.wrap_socket, s)\n\n            try:\n                await method(s=s, **values)\n            finally:\n                if values['use_ssl']:\n                    values['ssl_sock'].close()\n                s.close()\n                srv.close()\n                await srv.wait_closed()\n        return self._run_test(test, **switches)\n\n    def test_create_server_protocol_factory_context(self):\n        async def test(cvar, proto, use_tcp, family, addr, **_):\n            factory_called_future = self.loop.create_future()\n\n            def factory():\n                try:\n                    self.assertEqual(cvar.get(), 'inner')\n                except Exception as e:\n                    factory_called_future.set_exception(e)\n                else:\n                    factory_called_future.set_result(None)\n\n                return proto\n\n            if use_tcp:\n                srv = await self.loop.create_server(factory, *addr)\n            else:\n                srv = await self.loop.create_unix_server(factory, addr)\n            s = socket.socket(family)\n            with s:\n                s.setblocking(False)\n                await self.loop.sock_connect(s, addr)\n\n            try:\n                await factory_called_future\n            finally:\n                srv.close()\n                await proto.done\n                await srv.wait_closed()\n\n        self._run_test(test)\n\n    def test_create_server_connection_protocol(self):\n        async def test(proto, s, **_):\n            inner = await proto.connection_made_fut\n            self.assertEqual(inner, \"inner\")\n\n            await self.loop.sock_sendall(s, b'data')\n            inner = await proto.data_received_fut\n            self.assertEqual(inner, \"inner\")\n\n            s.shutdown(socket.SHUT_WR)\n            inner = await proto.eof_received_fut\n            self.assertEqual(inner, \"inner\")\n\n            s.close()\n            await proto.done\n            self.assertEqual(proto.connection_lost_ctx, \"inner\")\n\n        self._run_server_test(test, async_sock=True)\n\n    def test_create_ssl_server_connection_protocol(self):\n        async def test(cvar, proto, ssl_sock, **_):\n            def resume_reading(transport):\n                cvar.set(\"resume_reading\")\n                transport.resume_reading()\n\n            try:\n                inner = await proto.connection_made_fut\n                self.assertEqual(inner, \"inner\")\n\n                await self.loop.run_in_executor(None, ssl_sock.send, b'data')\n                inner = await proto.data_received_fut\n                self.assertEqual(inner, \"inner\")\n\n                if self.implementation != 'asyncio':\n                    # this seems to be a bug in asyncio\n                    proto.data_received_fut = self.loop.create_future()\n                    proto.transport.pause_reading()\n                    await self.loop.run_in_executor(None,\n                                                    ssl_sock.send, b'data')\n                    self.loop.call_soon(resume_reading, proto.transport)\n                    inner = await proto.data_received_fut\n                    self.assertEqual(inner, \"inner\")\n\n                    await self.loop.run_in_executor(None, ssl_sock.unwrap)\n                else:\n                    ssl_sock.shutdown(socket.SHUT_WR)\n                inner = await proto.eof_received_fut\n                self.assertEqual(inner, \"inner\")\n\n                await self.loop.run_in_executor(None, ssl_sock.close)\n                await proto.done\n                self.assertEqual(proto.connection_lost_ctx, \"inner\")\n            finally:\n                if self.implementation == 'asyncio':\n                    # mute resource warning in asyncio\n                    proto.transport.close()\n\n        self._run_server_test(test, use_ssl='yes')\n\n    def test_create_server_manual_connection_lost(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest('this seems to be a bug in asyncio')\n\n        async def test(proto, cvar, **_):\n            def close():\n                cvar.set('closing')\n                proto.transport.close()\n\n            inner = await proto.connection_made_fut\n            self.assertEqual(inner, \"inner\")\n\n            self.loop.call_soon(close)\n\n            await proto.done\n            self.assertEqual(proto.connection_lost_ctx, \"inner\")\n\n        self._run_server_test(test, async_sock=True)\n\n    def test_create_ssl_server_manual_connection_lost(self):\n        if self.implementation == 'asyncio' and sys.version_info >= (3, 11, 0):\n            # TODO(fantix): fix for 3.11\n            raise unittest.SkipTest('should pass on 3.11')\n\n        async def test(proto, cvar, ssl_sock, **_):\n            def close():\n                cvar.set('closing')\n                proto.transport.close()\n\n            inner = await proto.connection_made_fut\n            self.assertEqual(inner, \"inner\")\n\n            if self.implementation == 'asyncio':\n                self.loop.call_soon(close)\n            else:\n                # asyncio doesn't have the flushing phase\n\n                # put the incoming data on-hold\n                proto.transport.pause_reading()\n                # send data\n                await self.loop.run_in_executor(None,\n                                                ssl_sock.send, b'hello')\n                # schedule a proactive transport close which will trigger\n                # the flushing process to retrieve the remaining data\n                self.loop.call_soon(close)\n                # turn off the reading lock now (this also schedules a\n                # resume operation after transport.close, therefore it\n                # won't affect our test)\n                proto.transport.resume_reading()\n\n            await asyncio.sleep(0)\n            await self.loop.run_in_executor(None, ssl_sock.unwrap)\n            await proto.done\n            self.assertEqual(proto.connection_lost_ctx, \"inner\")\n            self.assertFalse(proto.data_received_fut.done())\n\n        self._run_server_test(test, use_ssl='yes')\n\n    def test_create_connection_protocol(self):\n        async def test(cvar, proto, addr, sslctx, client_sslctx, family,\n                       use_sock, use_ssl, use_tcp):\n            ss = socket.socket(family)\n            ss.bind(addr)\n            ss.listen(1)\n\n            def accept():\n                sock, _ = ss.accept()\n                if use_ssl:\n                    sock = sslctx.wrap_socket(sock, server_side=True)\n                return sock\n\n            async def write_over():\n                cvar.set(\"write_over\")\n                count = 0\n                if use_ssl:\n                    proto.transport.set_write_buffer_limits(high=256, low=128)\n                    while not proto.transport.get_write_buffer_size():\n                        proto.transport.write(b'q' * 16384)\n                        count += 1\n                else:\n                    proto.transport.set_write_buffer_limits(high=256, low=128)\n                    while not proto.transport.get_write_buffer_size():\n                        proto.transport.write(b'q' * 16384)\n                        count += 1\n                return count\n\n            s = self.loop.run_in_executor(None, accept)\n\n            try:\n                method = ('create_connection' if use_tcp\n                          else 'create_unix_connection')\n                params = {}\n                if use_sock:\n                    cs = socket.socket(family)\n                    cs.connect(addr)\n                    params['sock'] = cs\n                    if use_ssl:\n                        params['server_hostname'] = '127.0.0.1'\n                elif use_tcp:\n                    params['host'] = addr[0]\n                    params['port'] = addr[1]\n                else:\n                    params['path'] = addr\n                    if use_ssl:\n                        params['server_hostname'] = '127.0.0.1'\n                if use_ssl:\n                    params['ssl'] = client_sslctx\n                await getattr(self.loop, method)(lambda: proto, **params)\n                s = await s\n\n                inner = await proto.connection_made_fut\n                self.assertEqual(inner, \"inner\")\n\n                await self.loop.run_in_executor(None, s.send, b'data')\n                inner = await proto.data_received_fut\n                self.assertEqual(inner, \"inner\")\n\n                if self.implementation != 'asyncio':\n                    # asyncio bug\n                    count = await self.loop.create_task(write_over())\n                    inner = await proto.pause_writing_fut\n                    self.assertEqual(inner, \"inner\")\n\n                    for i in range(count):\n                        await self.loop.run_in_executor(None, s.recv, 16384)\n                    inner = await proto.resume_writing_fut\n                    self.assertEqual(inner, \"inner\")\n\n                if use_ssl and self.implementation != 'asyncio':\n                    await self.loop.run_in_executor(None, s.unwrap)\n                else:\n                    s.shutdown(socket.SHUT_WR)\n                inner = await proto.eof_received_fut\n                self.assertEqual(inner, \"inner\")\n\n                s.close()\n                await proto.done\n                self.assertEqual(proto.connection_lost_ctx, \"inner\")\n            finally:\n                ss.close()\n                proto.transport.close()\n\n        self._run_test(test, use_sock='both', use_ssl='both')\n\n    def test_start_tls(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest('this seems to be a bug in asyncio')\n\n        async def test(cvar, proto, addr, sslctx, client_sslctx, family,\n                       ssl_over_ssl, use_tcp, **_):\n            ss = socket.socket(family)\n            ss.bind(addr)\n            ss.listen(1)\n\n            def accept():\n                sock, _ = ss.accept()\n                sock = sslctx.wrap_socket(sock, server_side=True)\n                if ssl_over_ssl:\n                    sock = _SSLSocketOverSSL(sock, sslctx, server_side=True)\n                return sock\n\n            s = self.loop.run_in_executor(None, accept)\n            transport = None\n\n            try:\n                if use_tcp:\n                    await self.loop.create_connection(lambda: proto, *addr)\n                else:\n                    await self.loop.create_unix_connection(lambda: proto, addr)\n                inner = await proto.connection_made_fut\n                self.assertEqual(inner, \"inner\")\n\n                cvar.set('start_tls')\n                transport = await self.loop.start_tls(\n                    proto.transport, proto, client_sslctx,\n                    server_hostname='127.0.0.1',\n                )\n\n                if ssl_over_ssl:\n                    cvar.set('start_tls_over_tls')\n                    transport = await self.loop.start_tls(\n                        transport, proto, client_sslctx,\n                        server_hostname='127.0.0.1',\n                    )\n\n                s = await s\n\n                await self.loop.run_in_executor(None, s.send, b'data')\n                inner = await proto.data_received_fut\n                self.assertEqual(inner, \"inner\")\n\n                await self.loop.run_in_executor(None, s.unwrap)\n                inner = await proto.eof_received_fut\n                self.assertEqual(inner, \"inner\")\n\n                s.close()\n                await proto.done\n                self.assertEqual(proto.connection_lost_ctx, \"inner\")\n            finally:\n                ss.close()\n                if transport:\n                    transport.close()\n\n        self._run_test(test, use_ssl='yes', ssl_over_ssl='both')\n\n    def test_connect_accepted_socket(self):\n        async def test(proto, addr, family, sslctx, client_sslctx,\n                       use_ssl, **_):\n            ss = socket.socket(family)\n            ss.bind(addr)\n            ss.listen(1)\n            s = self.loop.run_in_executor(None, ss.accept)\n            cs = socket.socket(family)\n            cs.connect(addr)\n            s, _ = await s\n\n            try:\n                if use_ssl:\n                    cs = self.loop.run_in_executor(\n                        None, client_sslctx.wrap_socket, cs)\n                    await self.loop.connect_accepted_socket(lambda: proto, s,\n                                                            ssl=sslctx)\n                    cs = await cs\n                else:\n                    await self.loop.connect_accepted_socket(lambda: proto, s)\n\n                inner = await proto.connection_made_fut\n                self.assertEqual(inner, \"inner\")\n\n                await self.loop.run_in_executor(None, cs.send, b'data')\n                inner = await proto.data_received_fut\n                self.assertEqual(inner, \"inner\")\n\n                if use_ssl and self.implementation != 'asyncio':\n                    await self.loop.run_in_executor(None, cs.unwrap)\n                else:\n                    cs.shutdown(socket.SHUT_WR)\n                inner = await proto.eof_received_fut\n                self.assertEqual(inner, \"inner\")\n\n                cs.close()\n                await proto.done\n                self.assertEqual(proto.connection_lost_ctx, \"inner\")\n            finally:\n                proto.transport.close()\n                ss.close()\n\n        self._run_test(test, use_ssl='both')\n\n    def test_subprocess_protocol(self):\n        cvar = contextvars.ContextVar('cvar', default='outer')\n        proto = _SubprocessProtocol(cvar, loop=self.loop)\n\n        async def test():\n            self.assertEqual(cvar.get(), 'outer')\n            cvar.set('inner')\n            await self.loop.subprocess_exec(\n                lambda: proto, sys.executable, b'-c',\n                b';'.join((b'import sys',\n                           b'data = sys.stdin.buffer.read()',\n                           b'sys.stdout.buffer.write(data)')))\n\n            try:\n                inner = await proto.connection_made_fut\n                self.assertEqual(inner, \"inner\")\n\n                proto.transport.get_pipe_transport(0).write(b'data')\n                proto.transport.get_pipe_transport(0).write_eof()\n                inner = await proto.data_received_fut\n                self.assertEqual(inner, \"inner\")\n\n                inner = await proto.pipe_connection_lost_fut\n                self.assertEqual(inner, \"inner\")\n\n                inner = await proto.process_exited_fut\n                if self.implementation != 'asyncio':\n                    # bug in asyncio\n                    self.assertEqual(inner, \"inner\")\n\n                await proto.done\n                if self.implementation != 'asyncio':\n                    # bug in asyncio\n                    self.assertEqual(proto.connection_lost_ctx, \"inner\")\n            finally:\n                proto.transport.close()\n\n        self.loop.run_until_complete(test())\n\n    def test_datagram_protocol(self):\n        cvar = contextvars.ContextVar('cvar', default='outer')\n        proto = _DatagramProtocol(cvar, loop=self.loop)\n        server_addr = ('127.0.0.1', 8888)\n        client_addr = ('127.0.0.1', 0)\n\n        async def run():\n            self.assertEqual(cvar.get(), 'outer')\n            cvar.set('inner')\n\n            def close():\n                cvar.set('closing')\n                proto.transport.close()\n\n            try:\n                await self.loop.create_datagram_endpoint(\n                    lambda: proto, local_addr=server_addr)\n                inner = await proto.connection_made_fut\n                self.assertEqual(inner, \"inner\")\n\n                s = socket.socket(socket.AF_INET, type=socket.SOCK_DGRAM)\n                s.bind(client_addr)\n                s.sendto(b'data', server_addr)\n                inner = await proto.data_received_fut\n                self.assertEqual(inner, \"inner\")\n\n                self.loop.call_soon(close)\n                await proto.done\n                if self.implementation != 'asyncio':\n                    # bug in asyncio\n                    self.assertEqual(proto.connection_lost_ctx, \"inner\")\n            finally:\n                proto.transport.close()\n                s.close()\n                # let transports close\n                await asyncio.sleep(0.1)\n\n        self.loop.run_until_complete(run())\n\n\nclass Test_UV_Context(_ContextBaseTests, tb.UVTestCase):\n    pass\n\n\nclass Test_AIO_Context(_ContextBaseTests, tb.AIOTestCase):\n    pass\n"
  },
  {
    "path": "tests/test_cython.py",
    "content": "import asyncio\n\nfrom uvloop._testbase import UVTestCase\n\n\nclass TestCythonIntegration(UVTestCase):\n\n    def test_cython_coro_is_coroutine(self):\n        from uvloop.loop import _test_coroutine_1\n        from asyncio.coroutines import _format_coroutine\n\n        coro = _test_coroutine_1()\n\n        coro_fmt = _format_coroutine(coro)\n        self.assertTrue(\n            coro_fmt.startswith('_test_coroutine_1() done')\n            or coro_fmt.startswith('_test_coroutine_1() running')\n        )\n        self.assertEqual(_test_coroutine_1.__qualname__, '_test_coroutine_1')\n        self.assertEqual(_test_coroutine_1.__name__, '_test_coroutine_1')\n        self.assertTrue(asyncio.iscoroutine(coro))\n        fut = asyncio.ensure_future(coro)\n        self.assertTrue(isinstance(fut, asyncio.Future))\n        self.assertTrue(isinstance(fut, asyncio.Task))\n        fut.cancel()\n\n        with self.assertRaises(asyncio.CancelledError):\n            self.loop.run_until_complete(fut)\n\n        try:\n            _format_coroutine(coro)  # This line checks against Cython segfault\n        except TypeError:\n            # TODO: Fix Cython to not reset __name__/__qualname__ to None\n            pass\n        coro.close()\n"
  },
  {
    "path": "tests/test_dealloc.py",
    "content": "import asyncio\nimport subprocess\nimport sys\n\nfrom uvloop import _testbase as tb\n\n\nclass TestDealloc(tb.UVTestCase):\n\n    def test_dealloc_1(self):\n        # Somewhere between Cython 0.25.2 and 0.26.0 uvloop programs\n        # started to trigger the following output:\n        #\n        #    $ python prog.py\n        #    Error in sys.excepthook:\n        #\n        #    Original exception was:\n        #\n        # Upon some debugging, it appeared that Handle.__dealloc__ was\n        # called at a time where some CPython objects become non-functional,\n        # and any exception in __dealloc__ caused CPython to output the\n        # above.\n        #\n        # This regression test starts an event loop in debug mode,\n        # lets it run for a brief period of time, and exits the program.\n        # This will trigger Handle.__dealloc__, CallbackHandle.__dealloc__,\n        # and Loop.__dealloc__ methods.  The test will fail if they produce\n        # any unwanted output.\n\n        async def test():\n            prog = '''\\\nimport uvloop\n\nasync def foo():\n    return 42\n\ndef main():\n    loop = uvloop.new_event_loop()\n    loop.set_debug(True)\n    loop.run_until_complete(foo())\n    # Do not close the loop on purpose: let __dealloc__ methods run.\n\nif __name__ == '__main__':\n    main()\n            '''\n\n            cmd = sys.executable\n            proc = await asyncio.create_subprocess_exec(\n                cmd, b'-W', b'ignore', b'-c', prog,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            await proc.wait()\n            out = await proc.stdout.read()\n            err = await proc.stderr.read()\n\n            return out, err\n\n        out, err = self.loop.run_until_complete(test())\n        self.assertEqual(out, b'', 'stdout is not empty')\n        self.assertEqual(err, b'', 'stderr is not empty')\n"
  },
  {
    "path": "tests/test_dns.py",
    "content": "import asyncio\nimport socket\nimport unittest\n\nfrom uvloop import _testbase as tb\n\n\ndef patched_getaddrinfo(*args, **kwargs):\n    # corrected socket.getaddrinfo() behavior: ai_canonname always follows the\n    # flag AI_CANONNAME, even if `host` is an IP\n    rv = []\n    result = socket.getaddrinfo(*args, **kwargs)\n    first = True\n    for af, sk, proto, canon_name, addr in result:\n        if kwargs.get('flags', 0) & socket.AI_CANONNAME:\n            if not canon_name and first:\n                first = False\n                canon_name = args[0]\n                if not isinstance(canon_name, str):\n                    canon_name = canon_name.decode('ascii')\n        elif canon_name:\n            canon_name = ''\n        rv.append((af, sk, proto, canon_name, addr))\n    return rv\n\n\nclass BaseTestDNS:\n\n    def _test_getaddrinfo(self, *args, _patch=False, _sorted=False, **kwargs):\n        err = None\n        try:\n            if _patch:\n                a1 = patched_getaddrinfo(*args, **kwargs)\n            else:\n                a1 = socket.getaddrinfo(*args, **kwargs)\n        except (socket.gaierror, UnicodeError) as ex:\n            err = ex\n\n        try:\n            a2 = self.loop.run_until_complete(\n                self.loop.getaddrinfo(*args, **kwargs))\n        except (socket.gaierror, UnicodeError) as ex:\n            if err is not None:\n                self.assertEqual(ex.args, err.args)\n            else:\n                ex.__context__ = err\n                raise ex\n        except OSError as ex:\n            ex.__context__ = err\n            raise ex\n        else:\n            if err is not None:\n                raise err\n\n            if _sorted:\n                if kwargs.get('flags', 0) & socket.AI_CANONNAME and a1 and a2:\n                    # The API doesn't guarantee the ai_canonname value if\n                    # multiple results are returned, but both implementations\n                    # must return the same value for the first result.\n                    self.assertEqual(a1[0][3], a2[0][3])\n                    a1 = [(af, sk, pr, addr) for af, sk, pr, _, addr in a1]\n                    a2 = [(af, sk, pr, addr) for af, sk, pr, _, addr in a2]\n\n                self.assertEqual(sorted(a1), sorted(a2))\n            else:\n                self.assertEqual(a1, a2)\n\n    def _test_getnameinfo(self, *args, **kwargs):\n        err = None\n        try:\n            a1 = socket.getnameinfo(*args, **kwargs)\n        except Exception as ex:\n            err = ex\n\n        try:\n            a2 = self.loop.run_until_complete(\n                self.loop.getnameinfo(*args, **kwargs))\n        except Exception as ex:\n            if err is not None:\n                if ex.__class__ is not err.__class__:\n                    print(ex, err)\n                self.assertIs(ex.__class__, err.__class__)\n                self.assertEqual(ex.args, err.args)\n            else:\n                raise\n        else:\n            if err is not None:\n                raise err\n\n            self.assertEqual(a1, a2)\n\n    def test_getaddrinfo_1(self):\n        self._test_getaddrinfo('example.com', 80, _sorted=True)\n        self._test_getaddrinfo('example.com', 80, type=socket.SOCK_STREAM,\n                               _sorted=True)\n\n    def test_getaddrinfo_2(self):\n        self._test_getaddrinfo('example.com', 80, flags=socket.AI_CANONNAME,\n                               _sorted=True)\n\n    def test_getaddrinfo_3(self):\n        self._test_getaddrinfo('a' + '1' * 50 + '.wat', 800)\n\n    def test_getaddrinfo_4(self):\n        self._test_getaddrinfo('example.com', 80, family=-1)\n        self._test_getaddrinfo('example.com', 80, type=socket.SOCK_STREAM,\n                               family=-1)\n\n    def test_getaddrinfo_5(self):\n        self._test_getaddrinfo('example.com', '80', _sorted=True)\n        self._test_getaddrinfo('example.com', '80', type=socket.SOCK_STREAM,\n                               _sorted=True)\n\n    def test_getaddrinfo_6(self):\n        self._test_getaddrinfo(b'example.com', b'80', _sorted=True)\n        self._test_getaddrinfo(b'example.com', b'80', type=socket.SOCK_STREAM,\n                               _sorted=True)\n\n    def test_getaddrinfo_7(self):\n        self._test_getaddrinfo(None, 0)\n        self._test_getaddrinfo(None, 0, type=socket.SOCK_STREAM)\n\n    def test_getaddrinfo_8(self):\n        self._test_getaddrinfo('', 0)\n        self._test_getaddrinfo('', 0, type=socket.SOCK_STREAM)\n\n    def test_getaddrinfo_9(self):\n        self._test_getaddrinfo(b'', 0)\n        self._test_getaddrinfo(b'', 0, type=socket.SOCK_STREAM)\n\n    def test_getaddrinfo_10(self):\n        self._test_getaddrinfo(None, None)\n        self._test_getaddrinfo(None, None, type=socket.SOCK_STREAM)\n\n    def test_getaddrinfo_11(self):\n        self._test_getaddrinfo(b'example.com', '80', _sorted=True)\n        self._test_getaddrinfo(b'example.com', '80', type=socket.SOCK_STREAM,\n                               _sorted=True)\n\n    def test_getaddrinfo_12(self):\n        # musl always returns ai_canonname but we don't\n        patch = self.implementation != 'asyncio'\n\n        self._test_getaddrinfo('127.0.0.1', '80')\n        self._test_getaddrinfo('127.0.0.1', '80', type=socket.SOCK_STREAM,\n                               _patch=patch)\n\n    def test_getaddrinfo_13(self):\n        # musl always returns ai_canonname but we don't\n        patch = self.implementation != 'asyncio'\n\n        self._test_getaddrinfo(b'127.0.0.1', b'80')\n        self._test_getaddrinfo(b'127.0.0.1', b'80', type=socket.SOCK_STREAM,\n                               _patch=patch)\n\n    def test_getaddrinfo_14(self):\n        # musl always returns ai_canonname but we don't\n        patch = self.implementation != 'asyncio'\n\n        self._test_getaddrinfo(b'127.0.0.1', b'http')\n        self._test_getaddrinfo(b'127.0.0.1', b'http', type=socket.SOCK_STREAM,\n                               _patch=patch)\n\n    def test_getaddrinfo_15(self):\n        # musl always returns ai_canonname but we don't\n        patch = self.implementation != 'asyncio'\n\n        self._test_getaddrinfo('127.0.0.1', 'http')\n        self._test_getaddrinfo('127.0.0.1', 'http', type=socket.SOCK_STREAM,\n                               _patch=patch)\n\n    def test_getaddrinfo_16(self):\n        self._test_getaddrinfo('localhost', 'http')\n        self._test_getaddrinfo('localhost', 'http', type=socket.SOCK_STREAM)\n\n    def test_getaddrinfo_17(self):\n        self._test_getaddrinfo(b'localhost', 'http')\n        self._test_getaddrinfo(b'localhost', 'http', type=socket.SOCK_STREAM)\n\n    def test_getaddrinfo_18(self):\n        self._test_getaddrinfo('localhost', b'http')\n        self._test_getaddrinfo('localhost', b'http', type=socket.SOCK_STREAM)\n\n    def test_getaddrinfo_19(self):\n        # musl always returns ai_canonname while macOS never return for IPs,\n        # but we strictly follow the docs to use the AI_CANONNAME flag in a\n        # shortcut __static_getaddrinfo_pyaddr()\n        patch = self.implementation != 'asyncio'\n\n        self._test_getaddrinfo('::1', 80)\n        self._test_getaddrinfo('::1', 80, type=socket.SOCK_STREAM,\n                               _patch=patch)\n        self._test_getaddrinfo('::1', 80, type=socket.SOCK_STREAM,\n                               flags=socket.AI_CANONNAME, _patch=patch)\n\n    def test_getaddrinfo_20(self):\n        # musl always returns ai_canonname while macOS never return for IPs,\n        # but we strictly follow the docs to use the AI_CANONNAME flag in a\n        # shortcut __static_getaddrinfo_pyaddr()\n        patch = self.implementation != 'asyncio'\n\n        self._test_getaddrinfo('127.0.0.1', 80)\n        self._test_getaddrinfo('127.0.0.1', 80, type=socket.SOCK_STREAM,\n                               _patch=patch)\n        self._test_getaddrinfo('127.0.0.1', 80, type=socket.SOCK_STREAM,\n                               flags=socket.AI_CANONNAME, _patch=patch)\n\n    # https://github.com/libuv/libuv/security/advisories/GHSA-f74f-cvh7-c6q6\n    # See also: https://github.com/MagicStack/uvloop/pull/600\n    def test_getaddrinfo_21(self):\n        payload = f'0x{\"0\" * 246}7f000001.example.com'.encode('ascii')\n        self._test_getaddrinfo(payload, 80)\n        self._test_getaddrinfo(payload, 80, type=socket.SOCK_STREAM)\n\n    def test_getaddrinfo_22(self):\n        payload = f'0x{\"0\" * 246}7f000001.example.com'\n        self._test_getaddrinfo(payload, 80)\n        self._test_getaddrinfo(payload, 80, type=socket.SOCK_STREAM)\n\n    def test_getaddrinfo_broadcast(self):\n        self._test_getaddrinfo('<broadcast>', 80)\n        self._test_getaddrinfo('<broadcast>', 80, type=socket.SOCK_STREAM)\n\n    ######\n\n    def test_getnameinfo_1(self):\n        self._test_getnameinfo(('127.0.0.1', 80), 0)\n\n    def test_getnameinfo_2(self):\n        self._test_getnameinfo(('127.0.0.1', 80, 1231231231213), 0)\n\n    def test_getnameinfo_3(self):\n        self._test_getnameinfo(('127.0.0.1', 80, 0, 0), 0)\n\n    def test_getnameinfo_4(self):\n        self._test_getnameinfo(('::1', 80), 0)\n\n    def test_getnameinfo_5(self):\n        self._test_getnameinfo(('localhost', 8080), 0)\n\n\nclass Test_UV_DNS(BaseTestDNS, tb.UVTestCase):\n\n    def test_getaddrinfo_close_loop(self):\n        # Test that we can close the loop with a running\n        # DNS query.\n\n        try:\n            # Check that we have internet connection\n            socket.getaddrinfo('example.com', 80)\n        except socket.error:\n            raise unittest.SkipTest\n\n        async def run():\n            fut = self.loop.create_task(\n                self.loop.getaddrinfo('example.com', 80))\n            await asyncio.sleep(0)\n            fut.cancel()\n            self.loop.stop()\n\n        try:\n            self.loop.run_until_complete(run())\n        finally:\n            self.loop.close()\n\n\nclass Test_AIO_DNS(BaseTestDNS, tb.AIOTestCase):\n    pass\n"
  },
  {
    "path": "tests/test_executors.py",
    "content": "import asyncio\nimport concurrent.futures\nimport multiprocessing\nimport unittest\n\nfrom uvloop import _testbase as tb\n\n\ndef fib(n):\n    if n < 2:\n        return 1\n    return fib(n - 2) + fib(n - 1)\n\n\nclass _TestExecutors:\n\n    def run_pool_test(self, pool_factory):\n        async def run():\n            pool = pool_factory()\n            with pool:\n                coros = []\n                for i in range(0, 10):\n                    coros.append(self.loop.run_in_executor(pool, fib, i))\n                res = await asyncio.gather(*coros)\n            self.assertEqual(res, fib10)\n            await asyncio.sleep(0.01)\n\n        fib10 = [fib(i) for i in range(10)]\n        self.loop.run_until_complete(run())\n\n    @unittest.skipIf(\n        multiprocessing.get_start_method(False) == 'spawn',\n        'no need to test on macOS where spawn is used instead of fork')\n    def test_executors_process_pool_01(self):\n        self.run_pool_test(concurrent.futures.ProcessPoolExecutor)\n\n    def test_executors_process_pool_02(self):\n        self.run_pool_test(concurrent.futures.ThreadPoolExecutor)\n\n\nclass TestUVExecutors(_TestExecutors, tb.UVTestCase):\n    pass\n\n\nclass TestAIOExecutors(_TestExecutors, tb.AIOTestCase):\n    pass\n"
  },
  {
    "path": "tests/test_fs_event.py",
    "content": "import asyncio\nimport contextlib\nimport os.path\nimport tempfile\n\nfrom uvloop import _testbase as tb\nfrom uvloop.loop import FileSystemEvent\n\n\nclass Test_UV_FS_Event(tb.UVTestCase):\n    def setUp(self):\n        super().setUp()\n        self.exit_stack = contextlib.ExitStack()\n        self.tmp_dir = self.exit_stack.enter_context(\n            tempfile.TemporaryDirectory()\n        )\n\n    def tearDown(self):\n        self.exit_stack.close()\n        super().tearDown()\n\n    def test_fs_event_change(self):\n        change_event_count = 0\n        filename = \"fs_event_change.txt\"\n        path = os.path.join(self.tmp_dir, filename)\n        q = asyncio.Queue()\n\n        with open(path, 'wt') as f:\n            async def file_writer():\n                while True:\n                    f.write('hello uvloop\\n')\n                    f.flush()\n                    x = await q.get()\n                    if x is None:\n                        return\n\n            def event_cb(ev_fname: bytes, evt: FileSystemEvent):\n                nonlocal change_event_count\n                self.assertEqual(ev_fname, filename.encode())\n                self.assertEqual(evt, FileSystemEvent.CHANGE)\n                change_event_count += 1\n                if change_event_count < 4:\n                    q.put_nowait(0)\n                else:\n                    q.put_nowait(None)\n\n            h = self.loop._monitor_fs(path, event_cb)\n            self.loop.run_until_complete(\n                asyncio.sleep(0.1)  # let monitor start\n            )\n            self.assertFalse(h.cancelled())\n\n            self.loop.run_until_complete(asyncio.wait_for(file_writer(), 4))\n            h.cancel()\n            self.assertTrue(h.cancelled())\n\n        self.assertEqual(change_event_count, 4)\n\n    def test_fs_event_rename(self):\n        orig_name = \"hello_fs_event.txt\"\n        new_name = \"hello_fs_event_rename.txt\"\n        changed_set = {orig_name, new_name}\n        event = asyncio.Event()\n\n        async def file_renamer():\n            os.rename(os.path.join(self.tmp_dir, orig_name),\n                      os.path.join(self.tmp_dir, new_name))\n            await event.wait()\n\n        def event_cb(ev_fname: bytes, evt: FileSystemEvent):\n            ev_fname = ev_fname.decode()\n            self.assertEqual(evt, FileSystemEvent.RENAME)\n            changed_set.discard(ev_fname)\n            if len(changed_set) == 0:\n                event.set()\n\n        with open(os.path.join(self.tmp_dir, orig_name), 'wt') as f:\n            f.write('hello!')\n        h = self.loop._monitor_fs(self.tmp_dir, event_cb)\n        self.loop.run_until_complete(asyncio.sleep(0.5))  # let monitor start\n        self.assertFalse(h.cancelled())\n\n        self.loop.run_until_complete(asyncio.wait_for(file_renamer(), 4))\n        h.cancel()\n        self.assertTrue(h.cancelled())\n\n        self.assertEqual(len(changed_set), 0)\n"
  },
  {
    "path": "tests/test_libuv_api.py",
    "content": "from uvloop import _testbase as tb\nfrom uvloop.loop import libuv_get_loop_t_ptr, libuv_get_version\nfrom uvloop.loop import _testhelper_unwrap_capsuled_pointer as unwrap\n\n\nclass Test_UV_libuv(tb.UVTestCase):\n    def test_libuv_get_loop_t_ptr(self):\n        loop1 = self.new_loop()\n        cap1 = libuv_get_loop_t_ptr(loop1)\n        cap2 = libuv_get_loop_t_ptr(loop1)\n\n        loop2 = self.new_loop()\n        cap3 = libuv_get_loop_t_ptr(loop2)\n\n        try:\n            self.assertEqual(unwrap(cap1), unwrap(cap2))\n            self.assertNotEqual(unwrap(cap1), unwrap(cap3))\n        finally:\n            loop1.close()\n            loop2.close()\n\n    def test_libuv_get_version(self):\n        self.assertGreater(libuv_get_version(), 0)\n"
  },
  {
    "path": "tests/test_pipes.py",
    "content": "import asyncio\nimport io\nimport os\nimport socket\n\nfrom uvloop import _testbase as tb\n\n\n# All tests are copied from asyncio (mostly as-is)\n\n\nclass MyReadPipeProto(asyncio.Protocol):\n    done = None\n\n    def __init__(self, loop=None):\n        self.state = ['INITIAL']\n        self.nbytes = 0\n        self.transport = None\n        if loop is not None:\n            self.done = asyncio.Future(loop=loop)\n\n    def connection_made(self, transport):\n        self.transport = transport\n        assert self.state == ['INITIAL'], self.state\n        self.state.append('CONNECTED')\n\n    def data_received(self, data):\n        assert self.state == ['INITIAL', 'CONNECTED'], self.state\n        self.nbytes += len(data)\n\n    def eof_received(self):\n        assert self.state == ['INITIAL', 'CONNECTED'], self.state\n        self.state.append('EOF')\n\n    def connection_lost(self, exc):\n        if 'EOF' not in self.state:\n            self.state.append('EOF')  # It is okay if EOF is missed.\n        assert self.state == ['INITIAL', 'CONNECTED', 'EOF'], self.state\n        self.state.append('CLOSED')\n        if self.done:\n            self.done.set_result(None)\n\n\nclass MyWritePipeProto(asyncio.BaseProtocol):\n    done = None\n    paused = False\n\n    def __init__(self, loop=None):\n        self.state = 'INITIAL'\n        self.transport = None\n        if loop is not None:\n            self.done = asyncio.Future(loop=loop)\n\n    def connection_made(self, transport):\n        self.transport = transport\n        assert self.state == 'INITIAL', self.state\n        self.state = 'CONNECTED'\n\n    def connection_lost(self, exc):\n        assert self.state == 'CONNECTED', self.state\n        self.state = 'CLOSED'\n        if self.done:\n            self.done.set_result(None)\n\n    def pause_writing(self):\n        self.paused = True\n\n    def resume_writing(self):\n        self.paused = False\n\n\nclass _BasePipeTest:\n    def test_read_pipe(self):\n        proto = MyReadPipeProto(loop=self.loop)\n\n        rpipe, wpipe = os.pipe()\n        pipeobj = io.open(rpipe, 'rb', 1024)\n\n        async def connect():\n            t, p = await self.loop.connect_read_pipe(\n                lambda: proto, pipeobj)\n            self.assertIs(p, proto)\n            self.assertIs(t, proto.transport)\n            self.assertEqual(['INITIAL', 'CONNECTED'], proto.state)\n            self.assertEqual(0, proto.nbytes)\n\n        self.loop.run_until_complete(connect())\n\n        os.write(wpipe, b'1')\n        tb.run_until(self.loop, lambda: proto.nbytes >= 1)\n        self.assertEqual(1, proto.nbytes)\n\n        os.write(wpipe, b'2345')\n        tb.run_until(self.loop, lambda: proto.nbytes >= 5)\n        self.assertEqual(['INITIAL', 'CONNECTED'], proto.state)\n        self.assertEqual(5, proto.nbytes)\n\n        os.close(wpipe)\n        self.loop.run_until_complete(proto.done)\n        self.assertEqual(\n            ['INITIAL', 'CONNECTED', 'EOF', 'CLOSED'], proto.state)\n        # extra info is available\n        self.assertIsNotNone(proto.transport.get_extra_info('pipe'))\n\n    def test_read_pty_output(self):\n        proto = MyReadPipeProto(loop=self.loop)\n\n        master, slave = os.openpty()\n        master_read_obj = io.open(master, 'rb', 0)\n\n        async def connect():\n            t, p = await self.loop.connect_read_pipe(\n                lambda: proto, master_read_obj)\n            self.assertIs(p, proto)\n            self.assertIs(t, proto.transport)\n            self.assertEqual(['INITIAL', 'CONNECTED'], proto.state)\n            self.assertEqual(0, proto.nbytes)\n\n        self.loop.run_until_complete(connect())\n\n        os.write(slave, b'1')\n        tb.run_until(self.loop, lambda: proto.nbytes)\n        self.assertEqual(1, proto.nbytes)\n\n        os.write(slave, b'2345')\n        tb.run_until(self.loop, lambda: proto.nbytes >= 5)\n        self.assertEqual(['INITIAL', 'CONNECTED'], proto.state)\n        self.assertEqual(5, proto.nbytes)\n\n        # On Linux, transport raises EIO when slave is closed --\n        # ignore it.\n        self.loop.set_exception_handler(lambda loop, ctx: None)\n        os.close(slave)\n        proto.transport.close()\n        self.loop.run_until_complete(proto.done)\n\n        self.assertEqual(\n            ['INITIAL', 'CONNECTED', 'EOF', 'CLOSED'], proto.state)\n        # extra info is available\n        self.assertIsNotNone(proto.transport.get_extra_info('pipe'))\n\n    def test_write_pipe(self):\n        rpipe, wpipe = os.pipe()\n        os.set_blocking(rpipe, False)\n        pipeobj = io.open(wpipe, 'wb', 1024)\n\n        proto = MyWritePipeProto(loop=self.loop)\n        connect = self.loop.connect_write_pipe(lambda: proto, pipeobj)\n        transport, p = self.loop.run_until_complete(connect)\n        self.assertIs(p, proto)\n        self.assertIs(transport, proto.transport)\n        self.assertEqual('CONNECTED', proto.state)\n\n        transport.write(b'1')\n\n        data = bytearray()\n\n        def reader(data):\n            try:\n                chunk = os.read(rpipe, 1024)\n            except BlockingIOError:\n                return len(data)\n            data += chunk\n            return len(data)\n\n        tb.run_until(self.loop, lambda: reader(data) >= 1)\n        self.assertEqual(b'1', data)\n\n        transport.write(b'2345')\n        tb.run_until(self.loop, lambda: reader(data) >= 5)\n        self.assertEqual(b'12345', data)\n        self.assertEqual('CONNECTED', proto.state)\n\n        os.close(rpipe)\n\n        # extra info is available\n        self.assertIsNotNone(proto.transport.get_extra_info('pipe'))\n\n        # close connection\n        proto.transport.close()\n        self.loop.run_until_complete(proto.done)\n        self.assertEqual('CLOSED', proto.state)\n\n    def test_write_pipe_disconnect_on_close(self):\n        rsock, wsock = socket.socketpair()\n        rsock.setblocking(False)\n\n        pipeobj = io.open(wsock.detach(), 'wb', 1024)\n\n        proto = MyWritePipeProto(loop=self.loop)\n        connect = self.loop.connect_write_pipe(lambda: proto, pipeobj)\n        transport, p = self.loop.run_until_complete(connect)\n        self.assertIs(p, proto)\n        self.assertIs(transport, proto.transport)\n        self.assertEqual('CONNECTED', proto.state)\n\n        transport.write(b'1')\n        data = self.loop.run_until_complete(self.loop.sock_recv(rsock, 1024))\n        self.assertEqual(b'1', data)\n\n        rsock.close()\n\n        self.loop.run_until_complete(proto.done)\n        self.assertEqual('CLOSED', proto.state)\n\n    def test_write_pty(self):\n        master, slave = os.openpty()\n        os.set_blocking(master, False)\n\n        slave_write_obj = io.open(slave, 'wb', 0)\n\n        proto = MyWritePipeProto(loop=self.loop)\n        connect = self.loop.connect_write_pipe(lambda: proto, slave_write_obj)\n        transport, p = self.loop.run_until_complete(connect)\n        self.assertIs(p, proto)\n        self.assertIs(transport, proto.transport)\n        self.assertEqual('CONNECTED', proto.state)\n\n        transport.write(b'1')\n\n        data = bytearray()\n\n        def reader(data):\n            try:\n                chunk = os.read(master, 1024)\n            except BlockingIOError:\n                return len(data)\n            data += chunk\n            return len(data)\n\n        tb.run_until(self.loop, lambda: reader(data) >= 1,\n                     timeout=10)\n        self.assertEqual(b'1', data)\n\n        transport.write(b'2345')\n        tb.run_until(self.loop, lambda: reader(data) >= 5,\n                     timeout=10)\n        self.assertEqual(b'12345', data)\n        self.assertEqual('CONNECTED', proto.state)\n\n        os.close(master)\n\n        # extra info is available\n        self.assertIsNotNone(proto.transport.get_extra_info('pipe'))\n\n        # close connection\n        proto.transport.close()\n        self.loop.run_until_complete(proto.done)\n        self.assertEqual('CLOSED', proto.state)\n\n    def test_write_buffer_full(self):\n        rpipe, wpipe = os.pipe()\n        pipeobj = io.open(wpipe, 'wb', 1024)\n\n        proto = MyWritePipeProto(loop=self.loop)\n        connect = self.loop.connect_write_pipe(lambda: proto, pipeobj)\n        transport, p = self.loop.run_until_complete(connect)\n        self.assertIs(p, proto)\n        self.assertIs(transport, proto.transport)\n        self.assertEqual('CONNECTED', proto.state)\n\n        for i in range(32):\n            transport.write(b'x' * 32768)\n            if proto.paused:\n                transport.write(b'x' * 32768)\n                break\n        else:\n            self.fail(\"Didn't reach a full buffer\")\n\n        os.close(rpipe)\n        self.loop.run_until_complete(asyncio.wait_for(proto.done, 1))\n        self.assertEqual('CLOSED', proto.state)\n\n\nclass Test_UV_Pipes(_BasePipeTest, tb.UVTestCase):\n    pass\n\n\nclass Test_AIO_Pipes(_BasePipeTest, tb.AIOTestCase):\n    pass\n"
  },
  {
    "path": "tests/test_process.py",
    "content": "import asyncio\nimport contextlib\nimport gc\nimport os\nimport pathlib\nimport signal\nimport subprocess\nimport sys\nimport tempfile\nimport textwrap\nimport time\nimport unittest\n\nimport psutil\n\nfrom uvloop import _testbase as tb\n\n\nclass _RedirectFD(contextlib.AbstractContextManager):\n    def __init__(self, old_file, new_file):\n        self._old_fd = old_file.fileno()\n        self._old_fd_save = os.dup(self._old_fd)\n        self._new_fd = new_file.fileno()\n\n    def __enter__(self):\n        os.dup2(self._new_fd, self._old_fd)\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        os.dup2(self._old_fd_save, self._old_fd)\n        os.close(self._old_fd_save)\n\n\nclass _TestProcess:\n    def get_num_fds(self):\n        return psutil.Process(os.getpid()).num_fds()\n\n    def test_process_env_1(self):\n        async def test():\n            cmd = 'echo $FOO$BAR'\n            env = {'FOO': 'sp', 'BAR': 'am'}\n            proc = await asyncio.create_subprocess_shell(\n                cmd,\n                env=env,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            out, _ = await proc.communicate()\n            self.assertEqual(out, b'spam\\n')\n            self.assertEqual(proc.returncode, 0)\n\n        self.loop.run_until_complete(test())\n\n    def test_process_env_2(self):\n        async def test():\n            cmd = 'env'\n            env = {}  # empty environment\n            proc = await asyncio.create_subprocess_exec(\n                cmd,\n                env=env,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            out, _ = await proc.communicate()\n            self.assertEqual(out, b'')\n            self.assertEqual(proc.returncode, 0)\n\n        self.loop.run_until_complete(test())\n\n    def test_process_cwd_1(self):\n        async def test():\n            cmd = 'pwd'\n            env = {}\n            cwd = '/'\n            proc = await asyncio.create_subprocess_shell(\n                cmd,\n                cwd=cwd,\n                env=env,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            out, _ = await proc.communicate()\n            self.assertEqual(out, b'/\\n')\n            self.assertEqual(proc.returncode, 0)\n\n        self.loop.run_until_complete(test())\n\n    @unittest.skipUnless(hasattr(os, 'fspath'), 'no os.fspath()')\n    def test_process_cwd_2(self):\n        async def test():\n            cmd = 'pwd'\n            env = {}\n            cwd = pathlib.Path('/')\n            proc = await asyncio.create_subprocess_shell(\n                cmd,\n                cwd=cwd,\n                env=env,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            out, _ = await proc.communicate()\n            self.assertEqual(out, b'/\\n')\n            self.assertEqual(proc.returncode, 0)\n\n        self.loop.run_until_complete(test())\n\n    def test_process_preexec_fn_1(self):\n        # Copied from CPython/test_suprocess.py\n\n        # DISCLAIMER: Setting environment variables is *not* a good use\n        # of a preexec_fn.  This is merely a test.\n\n        async def test():\n            cmd = sys.executable\n            proc = await asyncio.create_subprocess_exec(\n                cmd, b'-W', b'ignore', '-c',\n                'import os,sys;sys.stdout.write(os.getenv(\"FRUIT\"))',\n                stdout=subprocess.PIPE,\n                preexec_fn=lambda: os.putenv(\"FRUIT\", \"apple\"))\n\n            out, _ = await proc.communicate()\n            self.assertEqual(out, b'apple')\n            self.assertEqual(proc.returncode, 0)\n\n        self.loop.run_until_complete(test())\n\n    def test_process_preexec_fn_2(self):\n        # Copied from CPython/test_suprocess.py\n\n        def raise_it():\n            raise ValueError(\"spam\")\n\n        async def test():\n            cmd = sys.executable\n            proc = await asyncio.create_subprocess_exec(\n                cmd, b'-W', b'ignore', '-c', 'import time; time.sleep(10)',\n                preexec_fn=raise_it)\n\n            await proc.communicate()\n\n        started = time.time()\n        try:\n            self.loop.run_until_complete(test())\n        except subprocess.SubprocessError as ex:\n            self.assertIn('preexec_fn', ex.args[0])\n            if ex.__cause__ is not None:\n                # uvloop will set __cause__\n                self.assertIs(type(ex.__cause__), ValueError)\n                self.assertEqual(ex.__cause__.args[0], 'spam')\n        else:\n            self.fail(\n                'exception in preexec_fn did not propagate to the parent')\n\n        if time.time() - started > 5:\n            self.fail(\n                'exception in preexec_fn did not kill the child process')\n\n    def test_process_executable_1(self):\n        async def test():\n            proc = await asyncio.create_subprocess_exec(\n                b'doesnotexist', b'-W', b'ignore', b'-c', b'print(\"spam\")',\n                executable=sys.executable,\n                stdout=subprocess.PIPE)\n\n            out, err = await proc.communicate()\n            self.assertEqual(out, b'spam\\n')\n\n        self.loop.run_until_complete(test())\n\n    def test_process_executable_2(self):\n        async def test():\n            proc = await asyncio.create_subprocess_exec(\n                pathlib.Path(sys.executable),\n                b'-W', b'ignore', b'-c', b'print(\"spam\")',\n                stdout=subprocess.PIPE)\n\n            out, err = await proc.communicate()\n            self.assertEqual(out, b'spam\\n')\n\n        self.loop.run_until_complete(test())\n\n    def test_process_pid_1(self):\n        async def test():\n            prog = '''\\\nimport os\nprint(os.getpid())\n            '''\n\n            cmd = sys.executable\n            proc = await asyncio.create_subprocess_exec(\n                cmd, b'-W', b'ignore', b'-c', prog,\n                stdin=subprocess.PIPE,\n                stdout=subprocess.PIPE)\n\n            pid = proc.pid\n            expected_result = '{}\\n'.format(pid).encode()\n\n            out, err = await proc.communicate()\n            self.assertEqual(out, expected_result)\n\n        self.loop.run_until_complete(test())\n\n    def test_process_send_signal_1(self):\n        async def test():\n            prog = '''\\\nimport signal\n\ndef handler(signum, frame):\n    if signum == signal.SIGUSR1:\n        print('WORLD')\n\nsignal.signal(signal.SIGUSR1, handler)\na = input()\nprint(a)\na = input()\nprint(a)\nexit(11)\n            '''\n\n            cmd = sys.executable\n            proc = await asyncio.create_subprocess_exec(\n                cmd, b'-W', b'ignore', b'-c', prog,\n                stdin=subprocess.PIPE,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            proc.stdin.write(b'HELLO\\n')\n            await proc.stdin.drain()\n\n            self.assertEqual(await proc.stdout.readline(), b'HELLO\\n')\n\n            proc.send_signal(signal.SIGUSR1)\n\n            proc.stdin.write(b'!\\n')\n            await proc.stdin.drain()\n\n            self.assertEqual(await proc.stdout.readline(), b'WORLD\\n')\n            self.assertEqual(await proc.stdout.readline(), b'!\\n')\n            self.assertEqual(await proc.wait(), 11)\n\n        self.loop.run_until_complete(test())\n\n    def test_process_streams_basic_1(self):\n        async def test():\n\n            prog = '''\\\nimport sys\nwhile True:\n    a = input()\n    if a == 'stop':\n        exit(20)\n    elif a == 'stderr':\n        print('OUCH', file=sys.stderr)\n    else:\n        print('>' + a + '<')\n            '''\n\n            cmd = sys.executable\n            proc = await asyncio.create_subprocess_exec(\n                cmd, b'-W', b'ignore', b'-c', prog,\n                stdin=subprocess.PIPE,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            self.assertGreater(proc.pid, 0)\n            self.assertIs(proc.returncode, None)\n\n            transp = proc._transport\n            with self.assertRaises(NotImplementedError):\n                # stdin is WriteTransport\n                transp.get_pipe_transport(0).pause_reading()\n            with self.assertRaises((NotImplementedError, AttributeError)):\n                # stdout is ReadTransport\n                transp.get_pipe_transport(1).write(b'wat')\n\n            proc.stdin.write(b'foobar\\n')\n            await proc.stdin.drain()\n            out = await proc.stdout.readline()\n            self.assertEqual(out, b'>foobar<\\n')\n\n            proc.stdin.write(b'stderr\\n')\n            await proc.stdin.drain()\n            out = await proc.stderr.readline()\n            self.assertEqual(out, b'OUCH\\n')\n\n            proc.stdin.write(b'stop\\n')\n            await proc.stdin.drain()\n\n            exitcode = await proc.wait()\n            self.assertEqual(exitcode, 20)\n\n        self.loop.run_until_complete(test())\n\n    def test_process_streams_stderr_to_stdout(self):\n        async def test():\n            prog = '''\\\nimport sys\nprint('out', flush=True)\nprint('err', file=sys.stderr, flush=True)\n            '''\n\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', prog,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.STDOUT)\n\n            out, err = await proc.communicate()\n            self.assertIsNone(err)\n            self.assertEqual(out, b'out\\nerr\\n')\n\n        self.loop.run_until_complete(test())\n\n    def test_process_streams_devnull(self):\n        async def test():\n            prog = '''\\\nimport sys\nprint('out', flush=True)\nprint('err', file=sys.stderr, flush=True)\n            '''\n\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', prog,\n                stdin=subprocess.DEVNULL,\n                stdout=subprocess.DEVNULL,\n                stderr=subprocess.DEVNULL)\n\n            out, err = await proc.communicate()\n            self.assertIsNone(err)\n            self.assertIsNone(out)\n\n        self.loop.run_until_complete(test())\n\n    def test_process_streams_pass_fds(self):\n        async def test():\n            prog = '''\\\nimport sys, os\nassert sys.argv[1] == '--'\ninherited = int(sys.argv[2])\nnon_inherited = int(sys.argv[3])\n\nos.fstat(inherited)\n\ntry:\n    os.fstat(non_inherited)\nexcept:\n    pass\nelse:\n    raise RuntimeError()\n\nprint(\"OK\")\n            '''\n\n            with tempfile.TemporaryFile() as inherited, \\\n                    tempfile.TemporaryFile() as non_inherited:\n\n                proc = await asyncio.create_subprocess_exec(\n                    sys.executable, b'-W', b'ignore', b'-c', prog, '--',\n                    str(inherited.fileno()),\n                    str(non_inherited.fileno()),\n                    stdout=subprocess.PIPE,\n                    stderr=subprocess.PIPE,\n                    pass_fds=(inherited.fileno(),))\n\n                out, err = await proc.communicate()\n                self.assertEqual(err, b'')\n                self.assertEqual(out, b'OK\\n')\n\n        self.loop.run_until_complete(test())\n\n    def test_subprocess_fd_leak_1(self):\n        async def main(n):\n            for i in range(n):\n                try:\n                    await asyncio.create_subprocess_exec(\n                        'nonexistant',\n                        stdout=subprocess.DEVNULL,\n                        stderr=subprocess.DEVNULL)\n                except FileNotFoundError:\n                    pass\n                await asyncio.sleep(0)\n\n        self.loop.run_until_complete(main(10))\n        num_fd_1 = self.get_num_fds()\n        self.loop.run_until_complete(main(10))\n        num_fd_2 = self.get_num_fds()\n\n        self.assertEqual(num_fd_1, num_fd_2)\n\n    def test_subprocess_fd_leak_2(self):\n        async def main(n):\n            for i in range(n):\n                try:\n                    p = await asyncio.create_subprocess_exec(\n                        'ls',\n                        stdout=subprocess.DEVNULL,\n                        stderr=subprocess.DEVNULL)\n                finally:\n                    await p.wait()\n                await asyncio.sleep(0)\n\n        self.loop.run_until_complete(main(10))\n        num_fd_1 = self.get_num_fds()\n        self.loop.run_until_complete(main(10))\n        num_fd_2 = self.get_num_fds()\n\n        self.assertEqual(num_fd_1, num_fd_2)\n\n    def test_subprocess_invalid_stdin(self):\n        fd = None\n        for tryfd in range(10000, 1000, -1):\n            try:\n                tryfd = os.dup(tryfd)\n            except OSError:\n                fd = tryfd\n                break\n            else:\n                os.close(tryfd)\n        else:\n            self.fail('could not find a free FD')\n\n        async def main():\n            with self.assertRaises(OSError):\n                await asyncio.create_subprocess_exec(\n                    'ls',\n                    stdin=fd)\n\n            with self.assertRaises(OSError):\n                await asyncio.create_subprocess_exec(\n                    'ls',\n                    stdout=fd)\n\n            with self.assertRaises(OSError):\n                await asyncio.create_subprocess_exec(\n                    'ls',\n                    stderr=fd)\n\n        self.loop.run_until_complete(main())\n\n    def test_process_streams_redirect(self):\n        async def test():\n            prog = bR'''\nimport sys\nprint('out', flush=True)\nprint('err', file=sys.stderr, flush=True)\n            '''\n\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', prog)\n\n            out, err = await proc.communicate()\n            self.assertIsNone(out)\n            self.assertIsNone(err)\n\n        with tempfile.NamedTemporaryFile('w') as stdout:\n            with tempfile.NamedTemporaryFile('w') as stderr:\n                with _RedirectFD(sys.stdout, stdout):\n                    with _RedirectFD(sys.stderr, stderr):\n                        self.loop.run_until_complete(test())\n\n                stdout.flush()\n                stderr.flush()\n\n                with open(stdout.name, 'rb') as so:\n                    self.assertEqual(so.read(), b'out\\n')\n\n                with open(stderr.name, 'rb') as se:\n                    self.assertEqual(se.read(), b'err\\n')\n\n\nclass _AsyncioTests:\n\n    # Program blocking\n    PROGRAM_BLOCKED = [sys.executable, b'-W', b'ignore',\n                       b'-c', b'import time; time.sleep(3600)']\n\n    # Program copying input to output\n    PROGRAM_CAT = [\n        sys.executable, b'-c',\n        b';'.join((b'import sys',\n                   b'data = sys.stdin.buffer.read()',\n                   b'sys.stdout.buffer.write(data)'))]\n\n    PROGRAM_ERROR = [\n        sys.executable, b'-W', b'ignore', b'-c', b'1/0'\n    ]\n\n    def test_stdin_not_inheritable(self):\n        # asyncio issue #209: stdin must not be inheritable, otherwise\n        # the Process.communicate() hangs\n        async def len_message(message):\n            code = 'import sys; data = sys.stdin.read(); print(len(data))'\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', code,\n                stdin=asyncio.subprocess.PIPE,\n                stdout=asyncio.subprocess.PIPE,\n                stderr=asyncio.subprocess.PIPE,\n                close_fds=False)\n            stdout, stderr = await proc.communicate(message)\n            exitcode = await proc.wait()\n            return (stdout, exitcode)\n\n        output, exitcode = self.loop.run_until_complete(len_message(b'abc'))\n        self.assertEqual(output.rstrip(), b'3')\n        self.assertEqual(exitcode, 0)\n\n    def test_stdin_stdout_pipe(self):\n        args = self.PROGRAM_CAT\n\n        async def run(data):\n            proc = await asyncio.create_subprocess_exec(\n                *args,\n                stdin=subprocess.PIPE,\n                stdout=subprocess.PIPE)\n\n            # feed data\n            proc.stdin.write(data)\n            await proc.stdin.drain()\n            proc.stdin.close()\n\n            # get output and exitcode\n            data = await proc.stdout.read()\n            exitcode = await proc.wait()\n            return (exitcode, data)\n\n        task = run(b'some data')\n        task = asyncio.wait_for(task, 60.0)\n        exitcode, stdout = self.loop.run_until_complete(task)\n        self.assertEqual(exitcode, 0)\n        self.assertEqual(stdout, b'some data')\n\n    def test_stdin_stdout_file(self):\n        args = self.PROGRAM_CAT\n\n        async def run(data, stdout):\n            proc = await asyncio.create_subprocess_exec(\n                *args,\n                stdin=subprocess.PIPE,\n                stdout=stdout)\n\n            # feed data\n            proc.stdin.write(data)\n            await proc.stdin.drain()\n            proc.stdin.close()\n\n            exitcode = await proc.wait()\n            return exitcode\n\n        with tempfile.TemporaryFile('w+b') as new_stdout:\n            task = run(b'some data', new_stdout)\n            task = asyncio.wait_for(task, 60.0)\n            exitcode = self.loop.run_until_complete(task)\n            self.assertEqual(exitcode, 0)\n\n            new_stdout.seek(0)\n            self.assertEqual(new_stdout.read(), b'some data')\n\n    def test_stdin_stderr_file(self):\n        args = self.PROGRAM_ERROR\n\n        async def run(stderr):\n            proc = await asyncio.create_subprocess_exec(\n                *args,\n                stdin=subprocess.PIPE,\n                stderr=stderr)\n\n            exitcode = await proc.wait()\n            return exitcode\n\n        with tempfile.TemporaryFile('w+b') as new_stderr:\n            task = run(new_stderr)\n            task = asyncio.wait_for(task, 60.0)\n            exitcode = self.loop.run_until_complete(task)\n            self.assertEqual(exitcode, 1)\n\n            new_stderr.seek(0)\n            self.assertIn(b'ZeroDivisionError', new_stderr.read())\n\n    def test_communicate(self):\n        args = self.PROGRAM_CAT\n\n        async def run(data):\n            proc = await asyncio.create_subprocess_exec(\n                *args,\n                stdin=subprocess.PIPE,\n                stdout=subprocess.PIPE)\n            stdout, stderr = await proc.communicate(data)\n            return proc.returncode, stdout\n\n        task = run(b'some data')\n        task = asyncio.wait_for(task, 60.0)\n        exitcode, stdout = self.loop.run_until_complete(task)\n        self.assertEqual(exitcode, 0)\n        self.assertEqual(stdout, b'some data')\n\n    def test_start_new_session(self):\n        # start the new process in a new session\n        create = asyncio.create_subprocess_shell('exit 8',\n                                                 start_new_session=True)\n        proc = self.loop.run_until_complete(create)\n        exitcode = self.loop.run_until_complete(proc.wait())\n        self.assertEqual(exitcode, 8)\n\n    def test_shell(self):\n        create = asyncio.create_subprocess_shell('exit 7')\n        proc = self.loop.run_until_complete(create)\n        exitcode = self.loop.run_until_complete(proc.wait())\n        self.assertEqual(exitcode, 7)\n\n    def test_kill(self):\n        args = self.PROGRAM_BLOCKED\n        create = asyncio.create_subprocess_exec(*args)\n        proc = self.loop.run_until_complete(create)\n        proc.kill()\n        returncode = self.loop.run_until_complete(proc.wait())\n        self.assertEqual(-signal.SIGKILL, returncode)\n\n    def test_terminate(self):\n        args = self.PROGRAM_BLOCKED\n        create = asyncio.create_subprocess_exec(*args)\n        proc = self.loop.run_until_complete(create)\n        proc.terminate()\n        returncode = self.loop.run_until_complete(proc.wait())\n        self.assertEqual(-signal.SIGTERM, returncode)\n\n    def test_send_signal(self):\n        code = 'import time; print(\"sleeping\", flush=True); time.sleep(3600)'\n        args = [sys.executable, b'-W', b'ignore', b'-c', code]\n        create = asyncio.create_subprocess_exec(*args,\n                                                stdout=subprocess.PIPE)\n        proc = self.loop.run_until_complete(create)\n\n        async def send_signal(proc):\n            # basic synchronization to wait until the program is sleeping\n            line = await proc.stdout.readline()\n            self.assertEqual(line, b'sleeping\\n')\n\n            proc.send_signal(signal.SIGHUP)\n            returncode = (await proc.wait())\n            return returncode\n\n        returncode = self.loop.run_until_complete(send_signal(proc))\n        self.assertEqual(-signal.SIGHUP, returncode)\n\n    def test_cancel_process_wait(self):\n        # Issue #23140: cancel Process.wait()\n\n        async def cancel_wait():\n            proc = await asyncio.create_subprocess_exec(\n                *self.PROGRAM_BLOCKED)\n\n            # Create an internal future waiting on the process exit\n            task = self.loop.create_task(proc.wait())\n            self.loop.call_soon(task.cancel)\n            try:\n                await task\n            except asyncio.CancelledError:\n                pass\n\n            # Cancel the future\n            task.cancel()\n\n            # Kill the process and wait until it is done\n            proc.kill()\n            await proc.wait()\n\n        self.loop.run_until_complete(cancel_wait())\n\n    def test_cancel_make_subprocess_transport_exec(self):\n        async def cancel_make_transport():\n            coro = asyncio.create_subprocess_exec(*self.PROGRAM_BLOCKED)\n            task = self.loop.create_task(coro)\n\n            self.loop.call_soon(task.cancel)\n            try:\n                await task\n            except asyncio.CancelledError:\n                pass\n\n            # Give the process handler some time to close itself\n            await asyncio.sleep(0.3)\n            gc.collect()\n\n        # ignore the log:\n        # \"Exception during subprocess creation, kill the subprocess\"\n        with tb.disable_logger():\n            self.loop.run_until_complete(cancel_make_transport())\n\n    def test_cancel_post_init(self):\n        if sys.version_info >= (3, 13) and self.implementation == 'asyncio':\n            # https://github.com/python/cpython/issues/103847#issuecomment-3736561321\n            # This test started to flake on CPython 3.13 and later,\n            # so we skip it for asyncio tests until the issue is resolved.\n            self.skipTest('flaky test on CPython 3.13+')\n\n        async def cancel_make_transport():\n            coro = self.loop.subprocess_exec(asyncio.SubprocessProtocol,\n                                             *self.PROGRAM_BLOCKED)\n            task = self.loop.create_task(coro)\n\n            self.loop.call_soon(task.cancel)\n            try:\n                await task\n            except asyncio.CancelledError:\n                pass\n\n            # Give the process handler some time to close itself\n            await asyncio.sleep(0.3)\n            gc.collect()\n\n        # ignore the log:\n        # \"Exception during subprocess creation, kill the subprocess\"\n        with tb.disable_logger():\n            self.loop.run_until_complete(cancel_make_transport())\n            tb.run_briefly(self.loop)\n\n    def test_close_gets_process_closed(self):\n\n        loop = self.loop\n\n        class Protocol(asyncio.SubprocessProtocol):\n\n            def __init__(self):\n                self.closed = loop.create_future()\n\n            def connection_lost(self, exc):\n                self.closed.set_result(1)\n\n        async def test_subprocess():\n            transport, protocol = await loop.subprocess_exec(\n                Protocol, *self.PROGRAM_BLOCKED)\n            pid = transport.get_pid()\n            transport.close()\n            self.assertIsNone(transport.get_returncode())\n            await protocol.closed\n            self.assertIsNotNone(transport.get_returncode())\n            with self.assertRaises(ProcessLookupError):\n                os.kill(pid, 0)\n\n        loop.run_until_complete(test_subprocess())\n\n    def test_communicate_large_stdout_65536(self):\n        self._test_communicate_large_stdout(65536)\n\n    def test_communicate_large_stdout_65537(self):\n        self._test_communicate_large_stdout(65537)\n\n    def test_communicate_large_stdout_1000000(self):\n        self._test_communicate_large_stdout(1000000)\n\n    def _test_communicate_large_stdout(self, size):\n        async def copy_stdin_to_stdout(stdin):\n            # See https://github.com/MagicStack/uvloop/issues/363\n            # A program that copies stdin to stdout character by character\n            code = ('import sys, shutil; '\n                    'shutil.copyfileobj(sys.stdin, sys.stdout, 1)')\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', code,\n                stdin=asyncio.subprocess.PIPE,\n                stdout=asyncio.subprocess.PIPE,\n                stderr=asyncio.subprocess.PIPE)\n            stdout, _stderr = await asyncio.wait_for(proc.communicate(stdin),\n                                                     60.0)\n            return stdout\n\n        stdin = b'x' * size\n        stdout = self.loop.run_until_complete(copy_stdin_to_stdout(stdin))\n        self.assertEqual(stdout, stdin)\n\n    def test_write_huge_stdin_8192(self):\n        self._test_write_huge_stdin(8192)\n\n    def test_write_huge_stdin_8193(self):\n        self._test_write_huge_stdin(8193)\n\n    def test_write_huge_stdin_219263(self):\n        self._test_write_huge_stdin(219263)\n\n    def test_write_huge_stdin_219264(self):\n        self._test_write_huge_stdin(219264)\n\n    def _test_write_huge_stdin(self, buf_size):\n        code = '''\nimport sys\nn = 0\nwhile True:\n    line = sys.stdin.readline()\n    if not line:\n        print(\"unexpected EOF\", file=sys.stderr)\n        break\n    if line == \"END\\\\n\":\n        break\n    n+=1\nprint(n)'''\n        num_lines = buf_size - len(b\"END\\n\")\n        args = [sys.executable, b'-W', b'ignore', b'-c', code]\n\n        async def test():\n            proc = await asyncio.create_subprocess_exec(\n                *args,\n                stdout=asyncio.subprocess.PIPE,\n                stdin=asyncio.subprocess.PIPE)\n            data = b\"\\n\" * num_lines + b\"END\\n\"\n            self.assertEqual(len(data), buf_size)\n            proc.stdin.write(data)\n            await asyncio.wait_for(proc.stdin.drain(), timeout=5.0)\n            try:\n                await asyncio.wait_for(proc.wait(), timeout=5.0)\n            except asyncio.TimeoutError:\n                proc.kill()\n                proc.stdin.close()\n                await proc.wait()\n                raise\n            out = await proc.stdout.read()\n            self.assertEqual(int(out), num_lines)\n\n        self.loop.run_until_complete(test())\n\n\nclass Test_UV_Process(_TestProcess, tb.UVTestCase):\n    def test_process_double_close(self):\n        script = textwrap.dedent(\"\"\"\n            import os\n            import sys\n            from unittest import mock\n\n            import asyncio\n\n            pipes = []\n            original_os_pipe = os.pipe\n            def log_pipes():\n                pipe = original_os_pipe()\n                pipes.append(pipe)\n                return pipe\n\n            dups = []\n            original_os_dup = os.dup\n            def log_dups(*args, **kwargs):\n                dup = original_os_dup(*args, **kwargs)\n                dups.append(dup)\n                return dup\n\n            with mock.patch(\n                \"os.close\", wraps=os.close\n            ) as os_close, mock.patch(\n                \"os.pipe\", new=log_pipes\n            ), mock.patch(\n                \"os.dup\", new=log_dups\n            ):\n                import uvloop\n\n\n            async def test():\n                proc = await asyncio.create_subprocess_exec(\n                    sys.executable, \"-c\", \"pass\"\n                )\n                await proc.communicate()\n\n            uvloop.run(test())\n\n            stdin, stdout, stderr = dups\n            (r, w), = pipes\n            assert os_close.mock_calls == [\n                mock.call(w),\n                mock.call(r),\n                mock.call(stderr),\n                mock.call(stdout),\n                mock.call(stdin),\n            ]\n        \"\"\")\n        subprocess.run([sys.executable, '-c', script], check=True)\n\n\nclass Test_AIO_Process(_TestProcess, tb.AIOTestCase):\n    pass\n\n\nclass TestAsyncio_UV_Process(_AsyncioTests, tb.UVTestCase):\n    pass\n\n\nclass TestAsyncio_AIO_Process(_AsyncioTests, tb.AIOTestCase):\n    pass\n\n\nclass Test_UV_Process_Delayed(tb.UVTestCase):\n\n    class TestProto:\n        def __init__(self):\n            self.lost = 0\n            self.stages = []\n\n        def connection_made(self, transport):\n            self.stages.append(('CM', transport))\n\n        def pipe_data_received(self, fd, data):\n            if fd == 1:\n                self.stages.append(('STDOUT', data))\n\n        def pipe_connection_lost(self, fd, exc):\n            if fd == 1:\n                self.stages.append(('STDOUT', 'LOST'))\n\n        def process_exited(self):\n            self.stages.append('PROC_EXIT')\n\n        def connection_lost(self, exc):\n            self.stages.append(('CL', self.lost, exc))\n            self.lost += 1\n\n    async def run_sub(self, **kwargs):\n        return await self.loop.subprocess_shell(\n            lambda: self.TestProto(),\n            'echo 1',\n            **kwargs)\n\n    def test_process_delayed_stdio__paused__stdin_pipe(self):\n        transport, proto = self.loop.run_until_complete(\n            self.run_sub(\n                stdin=subprocess.PIPE,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE,\n                __uvloop_sleep_after_fork=True))\n        self.assertIsNot(transport, None)\n        self.assertEqual(transport.get_returncode(), 0)\n        self.assertEqual(\n            set(proto.stages),\n            {\n                ('CM', transport),\n                'PROC_EXIT',\n                ('STDOUT', b'1\\n'),\n                ('STDOUT', 'LOST'),\n                ('CL', 0, None)\n            })\n\n    def test_process_delayed_stdio__paused__no_stdin(self):\n        transport, proto = self.loop.run_until_complete(\n            self.run_sub(\n                stdin=None,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE,\n                __uvloop_sleep_after_fork=True))\n        self.assertIsNot(transport, None)\n        self.assertEqual(transport.get_returncode(), 0)\n        self.assertEqual(\n            set(proto.stages),\n            {\n                ('CM', transport),\n                'PROC_EXIT',\n                ('STDOUT', b'1\\n'),\n                ('STDOUT', 'LOST'),\n                ('CL', 0, None)\n            })\n\n    def test_process_delayed_stdio__not_paused__no_stdin(self):\n        if ((os.environ.get('TRAVIS_OS_NAME')\n                or os.environ.get('GITHUB_WORKFLOW'))\n                and sys.platform == 'darwin'):\n            # Randomly crashes on Travis, can't reproduce locally.\n            raise unittest.SkipTest()\n\n        transport, proto = self.loop.run_until_complete(\n            self.run_sub(\n                stdin=None,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE))\n        self.loop.run_until_complete(transport._wait())\n        self.assertEqual(transport.get_returncode(), 0)\n        self.assertIsNot(transport, None)\n        self.assertEqual(\n            set(proto.stages),\n            {\n                ('CM', transport),\n                'PROC_EXIT',\n                ('STDOUT', b'1\\n'),\n                ('STDOUT', 'LOST'),\n                ('CL', 0, None)\n            })\n"
  },
  {
    "path": "tests/test_process_spawning.py",
    "content": "import asyncio\nimport ctypes.util\nimport logging\nfrom concurrent.futures import ThreadPoolExecutor\nfrom threading import Thread\nfrom unittest import TestCase\n\nimport uvloop\n\n\nclass ProcessSpawningTestCollection(TestCase):\n\n    def test_spawning_external_process(self):\n        \"\"\"Test spawning external process (using `popen` system call) that\n        cause loop freeze.\"\"\"\n\n        async def run(loop):\n            event = asyncio.Event()\n\n            dummy_workers = [simulate_loop_activity(loop, event)\n                             for _ in range(5)]\n            spawn_worker = spawn_external_process(loop, event)\n            done, pending = await asyncio.wait([\n                asyncio.ensure_future(fut)\n                for fut in ([spawn_worker] + dummy_workers)\n            ])\n            exceptions = [result.exception()\n                          for result in done if result.exception()]\n            if exceptions:\n                raise exceptions[0]\n\n            return True\n\n        async def simulate_loop_activity(loop, done_event):\n            \"\"\"Simulate loop activity by busy waiting for event.\"\"\"\n            while True:\n                try:\n                    await asyncio.wait_for(done_event.wait(), timeout=0.1)\n                except asyncio.TimeoutError:\n                    pass\n\n                if done_event.is_set():\n                    return None\n\n        async def spawn_external_process(loop, event):\n            executor = ThreadPoolExecutor()\n            try:\n                call = loop.run_in_executor(executor, spawn_process)\n                await asyncio.wait_for(call, timeout=3600)\n            finally:\n                event.set()\n                executor.shutdown(wait=False)\n            return True\n\n        BUFFER_LENGTH = 1025\n        BufferType = ctypes.c_char * (BUFFER_LENGTH - 1)\n\n        def run_echo(popen, fread, pclose):\n            fd = popen('echo test'.encode('ASCII'), 'r'.encode('ASCII'))\n            try:\n                while True:\n                    buffer = BufferType()\n                    data = ctypes.c_void_p(ctypes.addressof(buffer))\n\n                    # -> this call will freeze whole loop in case of bug\n                    read = fread(data, 1, BUFFER_LENGTH, fd)\n                    if not read:\n                        break\n            except Exception:\n                logging.getLogger().exception('read error')\n                raise\n            finally:\n                pclose(fd)\n\n        def spawn_process():\n            \"\"\"Spawn external process via `popen` system call.\"\"\"\n\n            stdio = ctypes.CDLL(ctypes.util.find_library('c'))\n\n            # popen system call\n            popen = stdio.popen\n            popen.argtypes = (ctypes.c_char_p, ctypes.c_char_p)\n            popen.restype = ctypes.c_void_p\n\n            # pclose system call\n            pclose = stdio.pclose\n            pclose.argtypes = (ctypes.c_void_p,)\n            pclose.restype = ctypes.c_int\n\n            # fread system call\n            fread = stdio.fread\n            fread.argtypes = (ctypes.c_void_p, ctypes.c_size_t,\n                              ctypes.c_size_t, ctypes.c_void_p)\n            fread.restype = ctypes.c_size_t\n\n            for iteration in range(1000):\n                t = Thread(target=run_echo,\n                           args=(popen, fread, pclose),\n                           daemon=True)\n                t.start()\n                t.join(timeout=10.0)\n                if t.is_alive():\n                    raise Exception('process freeze detected at {}'\n                                    .format(iteration))\n\n            return True\n\n        loop = uvloop.new_event_loop()\n        proc = loop.run_until_complete(run(loop))\n        self.assertTrue(proc)\n"
  },
  {
    "path": "tests/test_regr1.py",
    "content": "import asyncio\nimport queue\nimport multiprocessing\nimport signal\nimport threading\nimport unittest\n\nimport uvloop\n\nfrom uvloop import _testbase as tb\n\n\nclass EchoServerProtocol(asyncio.Protocol):\n\n    def connection_made(self, transport):\n        transport.write(b'z')\n\n\nclass EchoClientProtocol(asyncio.Protocol):\n\n    def __init__(self, loop):\n        self.loop = loop\n\n    def connection_made(self, transport):\n        self.transport = transport\n\n    def data_received(self, data):\n        self.transport.close()\n\n    def connection_lost(self, exc):\n        self.loop.stop()\n\n\nclass FailedTestError(BaseException):\n    pass\n\n\ndef run_server(quin, qout):\n    server_loop = None\n\n    def server_thread():\n        nonlocal server_loop\n        loop = server_loop = uvloop.new_event_loop()\n        asyncio.set_event_loop(loop)\n        coro = loop.create_server(EchoServerProtocol, '127.0.0.1', 0)\n        server = loop.run_until_complete(coro)\n        addr = server.sockets[0].getsockname()\n        qout.put(addr)\n        loop.run_forever()\n        server.close()\n        loop.run_until_complete(server.wait_closed())\n        try:\n            loop.close()\n        except Exception as exc:\n            print(exc)\n        qout.put('stopped')\n\n    thread = threading.Thread(target=server_thread, daemon=True)\n    thread.start()\n\n    quin.get()\n    server_loop.call_soon_threadsafe(server_loop.stop)\n    thread.join(1)\n\n\nclass TestIssue39Regr(tb.UVTestCase):\n    \"\"\"See https://github.com/MagicStack/uvloop/issues/39 for details.\n\n    Original code to reproduce the bug is by Jim Fulton.\n    \"\"\"\n\n    def on_alarm(self, sig, fr):\n        if self.running:\n            raise FailedTestError\n\n    def run_test(self):\n        for i in range(10):\n            for threaded in [True, False]:\n                if threaded:\n                    qin, qout = queue.Queue(), queue.Queue()\n                    threading.Thread(\n                        target=run_server,\n                        args=(qin, qout),\n                        daemon=True).start()\n                else:\n                    qin = multiprocessing.Queue()\n                    qout = multiprocessing.Queue()\n                    multiprocessing.Process(\n                        target=run_server,\n                        args=(qin, qout),\n                        daemon=True).start()\n\n                addr = qout.get()\n                loop = self.new_loop()\n                asyncio.set_event_loop(loop)\n                loop.create_task(\n                    loop.create_connection(\n                        lambda: EchoClientProtocol(loop),\n                        host=addr[0], port=addr[1]))\n                loop.run_forever()\n                loop.close()\n                qin.put('stop')\n                qout.get()\n\n    @unittest.skipIf(\n        multiprocessing.get_start_method(False) == 'spawn',\n        'no need to test on macOS where spawn is used instead of fork')\n    def test_issue39_regression(self):\n        signal.signal(signal.SIGALRM, self.on_alarm)\n        signal.alarm(5)\n\n        try:\n            self.running = True\n            self.run_test()\n        except FailedTestError:\n            self.fail('deadlocked in libuv')\n        finally:\n            self.running = False\n            signal.signal(signal.SIGALRM, signal.SIG_IGN)\n"
  },
  {
    "path": "tests/test_runner.py",
    "content": "import asyncio\nimport unittest\nimport uvloop\n\n\nclass TestSourceCode(unittest.TestCase):\n\n    def test_uvloop_run_1(self):\n        CNT = 0\n\n        async def main():\n            nonlocal CNT\n            CNT += 1\n\n            loop = asyncio.get_running_loop()\n\n            self.assertTrue(isinstance(loop, uvloop.Loop))\n            self.assertTrue(loop.get_debug())\n\n            return 'done'\n\n        result = uvloop.run(main(), debug=True)\n\n        self.assertEqual(result, 'done')\n        self.assertEqual(CNT, 1)\n\n    def test_uvloop_run_2(self):\n\n        async def main():\n            pass\n\n        coro = main()\n        with self.assertRaisesRegex(TypeError, ' a non-uvloop event loop'):\n            uvloop.run(\n                coro,\n                loop_factory=asyncio.DefaultEventLoopPolicy().new_event_loop,\n            )\n\n        coro.close()\n"
  },
  {
    "path": "tests/test_signals.py",
    "content": "import asyncio\nimport signal\nimport subprocess\nimport sys\nimport time\n\nfrom uvloop import _testbase as tb\n\nDELAY = 0.1\n\n\nclass _TestSignal:\n    NEW_LOOP = None\n\n    @tb.silence_long_exec_warning()\n    def test_signals_sigint_pycode_stop(self):\n        async def runner():\n            PROG = R\"\"\"\\\nimport asyncio\nimport uvloop\nimport time\n\nfrom uvloop import _testbase as tb\n\nasync def worker():\n    print('READY', flush=True)\n    time.sleep(200)\n\n@tb.silence_long_exec_warning()\ndef run():\n    loop = \"\"\" + self.NEW_LOOP + \"\"\"\n    asyncio.set_event_loop(loop)\n    try:\n        loop.run_until_complete(worker())\n    finally:\n        loop.close()\n\nrun()\n\"\"\"\n\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', PROG,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            await proc.stdout.readline()\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGINT)\n            out, err = await proc.communicate()\n            self.assertIn(b'KeyboardInterrupt', err)\n            self.assertEqual(out, b'')\n\n        self.loop.run_until_complete(runner())\n\n    @tb.silence_long_exec_warning()\n    def test_signals_sigint_pycode_continue(self):\n        async def runner():\n            PROG = R\"\"\"\\\nimport asyncio\nimport uvloop\nimport time\n\nfrom uvloop import _testbase as tb\n\nasync def worker():\n    print('READY', flush=True)\n    try:\n        time.sleep(200)\n    except KeyboardInterrupt:\n        print(\"oups\")\n    await asyncio.sleep(0.5)\n    print('done')\n\n@tb.silence_long_exec_warning()\ndef run():\n    loop = \"\"\" + self.NEW_LOOP + \"\"\"\n    asyncio.set_event_loop(loop)\n    try:\n        loop.run_until_complete(worker())\n    finally:\n        loop.close()\n\nrun()\n\"\"\"\n\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', PROG,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            await proc.stdout.readline()\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGINT)\n            out, err = await proc.communicate()\n            self.assertEqual(err, b'')\n            self.assertEqual(out, b'oups\\ndone\\n')\n\n        self.loop.run_until_complete(runner())\n\n    @tb.silence_long_exec_warning()\n    def test_signals_sigint_uvcode(self):\n        async def runner():\n            PROG = R\"\"\"\\\nimport asyncio\nimport uvloop\n\nsrv = None\n\nasync def worker():\n    global srv\n    cb = lambda *args: None\n    srv = await asyncio.start_server(cb, '127.0.0.1', 0)\n    print('READY', flush=True)\n\nloop = \"\"\" + self.NEW_LOOP + \"\"\"\nasyncio.set_event_loop(loop)\nloop.create_task(worker())\ntry:\n    loop.run_forever()\nfinally:\n    srv.close()\n    loop.run_until_complete(srv.wait_closed())\n    loop.close()\n\"\"\"\n\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', PROG,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            await proc.stdout.readline()\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGINT)\n            out, err = await proc.communicate()\n            self.assertIn(b'KeyboardInterrupt', err)\n\n        self.loop.run_until_complete(runner())\n\n    @tb.silence_long_exec_warning()\n    def test_signals_sigint_uvcode_two_loop_runs(self):\n        async def runner():\n            PROG = R\"\"\"\\\nimport asyncio\nimport uvloop\n\nsrv = None\n\nasync def worker():\n    global srv\n    cb = lambda *args: None\n    srv = await asyncio.start_server(cb, '127.0.0.1', 0)\n\nloop = \"\"\" + self.NEW_LOOP + \"\"\"\nasyncio.set_event_loop(loop)\nloop.run_until_complete(worker())\nprint('READY', flush=True)\ntry:\n    loop.run_forever()\nfinally:\n    srv.close()\n    loop.run_until_complete(srv.wait_closed())\n    loop.close()\n\"\"\"\n\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', PROG,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            await proc.stdout.readline()\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGINT)\n            out, err = await proc.communicate()\n            self.assertIn(b'KeyboardInterrupt', err)\n\n        self.loop.run_until_complete(runner())\n\n    @tb.silence_long_exec_warning()\n    def test_signals_sigint_and_custom_handler(self):\n        async def runner():\n            PROG = R\"\"\"\\\nimport asyncio\nimport signal\nimport uvloop\n\nsrv = None\n\nasync def worker():\n    global srv\n    cb = lambda *args: None\n    srv = await asyncio.start_server(cb, '127.0.0.1', 0)\n    print('READY', flush=True)\n\ndef handler_sig(say):\n    print(say, flush=True)\n    exit()\n\ndef handler_hup(say):\n    print(say, flush=True)\n\nloop = \"\"\" + self.NEW_LOOP + \"\"\"\nloop.add_signal_handler(signal.SIGINT, handler_sig, '!s-int!')\nloop.add_signal_handler(signal.SIGHUP, handler_hup, '!s-hup!')\nasyncio.set_event_loop(loop)\nloop.create_task(worker())\ntry:\n    loop.run_forever()\nfinally:\n    srv.close()\n    loop.run_until_complete(srv.wait_closed())\n    loop.close()\n\"\"\"\n\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', PROG,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            await proc.stdout.readline()\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGHUP)\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGINT)\n            out, err = await proc.communicate()\n            self.assertEqual(err, b'')\n            self.assertIn(b'!s-hup!', out)\n            self.assertIn(b'!s-int!', out)\n\n        self.loop.run_until_complete(runner())\n\n    @tb.silence_long_exec_warning()\n    def test_signals_and_custom_handler_1(self):\n        async def runner():\n            PROG = R\"\"\"\\\nimport asyncio\nimport signal\nimport uvloop\n\nsrv = None\n\nasync def worker():\n    global srv\n    cb = lambda *args: None\n    srv = await asyncio.start_server(cb, '127.0.0.1', 0)\n    print('READY', flush=True)\n\ndef handler1():\n    print(\"GOTIT\", flush=True)\n\ndef handler2():\n    assert loop.remove_signal_handler(signal.SIGUSR1)\n    print(\"REMOVED\", flush=True)\n\ndef handler_hup():\n    exit()\n\nloop = \"\"\" + self.NEW_LOOP + \"\"\"\nasyncio.set_event_loop(loop)\nloop.add_signal_handler(signal.SIGUSR1, handler1)\nloop.add_signal_handler(signal.SIGUSR2, handler2)\nloop.add_signal_handler(signal.SIGHUP, handler_hup)\nloop.create_task(worker())\ntry:\n    loop.run_forever()\nfinally:\n    srv.close()\n    loop.run_until_complete(srv.wait_closed())\n    loop.close()\n\n\"\"\"\n\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', PROG,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            await proc.stdout.readline()\n\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGUSR1)\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGUSR1)\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGUSR2)\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGUSR1)\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGUSR1)\n            time.sleep(DELAY)\n            proc.send_signal(signal.SIGHUP)\n\n            out, err = await proc.communicate()\n            self.assertEqual(err, b'')\n            self.assertEqual(b'GOTIT\\nGOTIT\\nREMOVED\\n', out)\n\n        self.loop.run_until_complete(runner())\n\n    def test_signals_invalid_signal(self):\n        with self.assertRaisesRegex(RuntimeError,\n                                    'sig {} cannot be caught'.format(\n                                        signal.SIGKILL)):\n\n            self.loop.add_signal_handler(signal.SIGKILL, lambda *a: None)\n\n    def test_signals_coro_callback(self):\n        async def coro():\n            pass\n        with self.assertRaisesRegex(TypeError, 'coroutines cannot be used'):\n            self.loop.add_signal_handler(signal.SIGHUP, coro)\n\n    def test_signals_wakeup_fd_unchanged(self):\n        async def runner():\n            PROG = R\"\"\"\\\nimport uvloop\nimport signal\nimport asyncio\n\n\ndef get_wakeup_fd():\n    fd = signal.set_wakeup_fd(-1)\n    signal.set_wakeup_fd(fd)\n    return fd\n\nasync def f(): pass\n\nfd0 = get_wakeup_fd()\nloop = \"\"\" + self.NEW_LOOP + \"\"\"\ntry:\n    asyncio.set_event_loop(loop)\n    loop.run_until_complete(f())\n    fd1 = get_wakeup_fd()\nfinally:\n    loop.close()\n\nprint(fd0 == fd1, flush=True)\n\n\"\"\"\n\n            proc = await asyncio.create_subprocess_exec(\n                sys.executable, b'-W', b'ignore', b'-c', PROG,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n\n            out, err = await proc.communicate()\n            self.assertEqual(err, b'')\n            self.assertIn(b'True', out)\n\n        self.loop.run_until_complete(runner())\n\n    def test_signals_fork_in_thread(self):\n        # Refs #452, when forked from a thread, the main-thread-only signal\n        # operations failed thread ID checks because we didn't update\n        # MAIN_THREAD_ID after fork. It's now a lazy value set when needed and\n        # cleared after fork.\n        PROG = R\"\"\"\\\nimport asyncio\nimport multiprocessing\nimport signal\nimport sys\nimport threading\nimport uvloop\n\nmultiprocessing.set_start_method('fork')\n\ndef subprocess():\n    loop = \"\"\" + self.NEW_LOOP + \"\"\"\n    loop.add_signal_handler(signal.SIGINT, lambda *a: None)\n\ndef run():\n    loop = \"\"\" + self.NEW_LOOP + \"\"\"\n    loop.add_signal_handler(signal.SIGINT, lambda *a: None)\n    p = multiprocessing.Process(target=subprocess)\n    t = threading.Thread(target=p.start)\n    t.start()\n    t.join()\n    p.join()\n    sys.exit(p.exitcode)\n\nrun()\n\"\"\"\n\n        subprocess.check_call([\n            sys.executable, b'-W', b'ignore', b'-c', PROG,\n        ])\n\n\nclass Test_UV_Signals(_TestSignal, tb.UVTestCase):\n    NEW_LOOP = 'uvloop.new_event_loop()'\n\n    def test_signals_no_SIGCHLD(self):\n        with self.assertRaisesRegex(RuntimeError,\n                                    r\"cannot add.*handler.*SIGCHLD\"):\n\n            self.loop.add_signal_handler(signal.SIGCHLD, lambda *a: None)\n\n\nclass Test_AIO_Signals(_TestSignal, tb.AIOTestCase):\n    NEW_LOOP = 'asyncio.new_event_loop()'\n"
  },
  {
    "path": "tests/test_sockets.py",
    "content": "import asyncio\nimport pickle\nimport select\nimport socket\nimport sys\nimport time\nimport unittest\n\nfrom uvloop import _testbase as tb\n\n\n_SIZE = 1024 * 1024\n\n\nclass _TestSockets:\n\n    async def recv_all(self, sock, nbytes):\n        buf = b''\n        while len(buf) < nbytes:\n            buf += await self.loop.sock_recv(sock, nbytes - len(buf))\n        return buf\n\n    def test_socket_accept_recv_send(self):\n        async def server():\n            sock = socket.socket()\n            sock.setblocking(False)\n\n            with sock:\n                sock.bind(('127.0.0.1', 0))\n                sock.listen()\n\n                fut = self.loop.run_in_executor(None, client,\n                                                sock.getsockname())\n\n                client_sock, _ = await self.loop.sock_accept(sock)\n\n                with client_sock:\n                    data = await self.recv_all(client_sock, _SIZE)\n                    self.assertEqual(data, b'a' * _SIZE)\n\n                await fut\n\n        def client(addr):\n            sock = socket.socket()\n            with sock:\n                sock.connect(addr)\n                sock.sendall(b'a' * _SIZE)\n\n        self.loop.run_until_complete(server())\n\n    def test_socket_failed_connect(self):\n        sock = socket.socket()\n        with sock:\n            sock.bind(('127.0.0.1', 0))\n            addr = sock.getsockname()\n\n        async def run():\n            sock = socket.socket()\n            with sock:\n                sock.setblocking(False)\n                with self.assertRaises(ConnectionRefusedError):\n                    await self.loop.sock_connect(sock, addr)\n\n        self.loop.run_until_complete(run())\n\n    @unittest.skipUnless(tb.has_IPv6, 'no IPv6')\n    def test_socket_ipv6_addr(self):\n        server_sock = socket.socket(socket.AF_INET6)\n        with server_sock:\n            server_sock.bind(('::1', 0))\n\n            addr = server_sock.getsockname()  # tuple of 4 elements for IPv6\n\n            async def run():\n                sock = socket.socket(socket.AF_INET6)\n                with sock:\n                    sock.setblocking(False)\n                    # Check that sock_connect accepts 4-element address tuple\n                    # for IPv6 sockets.\n                    f = self.loop.sock_connect(sock, addr)\n                    try:\n                        await asyncio.wait_for(f, timeout=0.1)\n                    except (asyncio.TimeoutError, ConnectionRefusedError):\n                        # TimeoutError is expected.\n                        pass\n\n            self.loop.run_until_complete(run())\n\n    def test_socket_ipv4_nameaddr(self):\n        async def run():\n            sock = socket.socket(socket.AF_INET)\n            with sock:\n                sock.setblocking(False)\n                await self.loop.sock_connect(sock, ('localhost', 0))\n\n        with self.assertRaises(OSError):\n            # Regression test: sock_connect(sock) wasn't calling\n            # getaddrinfo() with `family=sock.family`, which resulted\n            # in `socket.connect()` being called with an IPv6 address\n            # for IPv4 sockets, which used to cause a TypeError.\n            # Here we expect that that is fixed so we should get an\n            # OSError instead.\n            self.loop.run_until_complete(run())\n\n    def test_socket_blocking_error(self):\n        self.loop.set_debug(True)\n        sock = socket.socket()\n\n        with sock:\n            with self.assertRaisesRegex(ValueError, 'must be non-blocking'):\n                self.loop.run_until_complete(\n                    self.loop.sock_recv(sock, 0))\n\n            with self.assertRaisesRegex(ValueError, 'must be non-blocking'):\n                self.loop.run_until_complete(\n                    self.loop.sock_sendall(sock, b''))\n\n            with self.assertRaisesRegex(ValueError, 'must be non-blocking'):\n                self.loop.run_until_complete(\n                    self.loop.sock_accept(sock))\n\n            with self.assertRaisesRegex(ValueError, 'must be non-blocking'):\n                self.loop.run_until_complete(\n                    self.loop.sock_connect(sock, (b'', 0)))\n\n    def test_socket_fileno(self):\n        rsock, wsock = socket.socketpair()\n        f = asyncio.Future(loop=self.loop)\n\n        def reader():\n            rsock.recv(100)\n            # We are done: unregister the file descriptor\n            self.loop.remove_reader(rsock)\n            f.set_result(None)\n\n        def writer():\n            wsock.send(b'abc')\n            self.loop.remove_writer(wsock)\n\n        with rsock, wsock:\n            self.loop.add_reader(rsock, reader)\n            self.loop.add_writer(wsock, writer)\n            self.loop.run_until_complete(f)\n\n    def test_socket_sync_remove_and_immediately_close(self):\n        # Test that it's OK to close the socket right after calling\n        # `remove_reader`.\n        sock = socket.socket()\n        with sock:\n            cb = lambda: None\n\n            sock.bind(('127.0.0.1', 0))\n            sock.listen(0)\n            fd = sock.fileno()\n            self.loop.add_reader(fd, cb)\n            self.loop.run_until_complete(asyncio.sleep(0.01))\n            self.loop.remove_reader(fd)\n            sock.close()\n            self.assertEqual(sock.fileno(), -1)\n            self.loop.run_until_complete(asyncio.sleep(0.01))\n\n    def test_sock_cancel_add_reader_race(self):\n        if self.is_asyncio_loop() and sys.version_info[:2] == (3, 8):\n            # asyncio 3.8.x has a regression; fixed in 3.9.0\n            # tracked in https://bugs.python.org/issue30064\n            raise unittest.SkipTest()\n\n        srv_sock_conn = None\n\n        async def server():\n            nonlocal srv_sock_conn\n            sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            sock_server.setblocking(False)\n            with sock_server:\n                sock_server.bind(('127.0.0.1', 0))\n                sock_server.listen()\n                fut = asyncio.ensure_future(\n                    client(sock_server.getsockname()))\n                srv_sock_conn, _ = await self.loop.sock_accept(sock_server)\n                srv_sock_conn.setsockopt(\n                    socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n                with srv_sock_conn:\n                    await fut\n\n        async def client(addr):\n            sock_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            sock_client.setblocking(False)\n            with sock_client:\n                await self.loop.sock_connect(sock_client, addr)\n                _, pending_read_futs = await asyncio.wait(\n                    [\n                        asyncio.ensure_future(\n                            self.loop.sock_recv(sock_client, 1)\n                        )\n                    ],\n                    timeout=1,\n                )\n\n                async def send_server_data():\n                    # Wait a little bit to let reader future cancel and\n                    # schedule the removal of the reader callback.  Right after\n                    # \"rfut.cancel()\" we will call \"loop.sock_recv()\", which\n                    # will add a reader.  This will make a race between\n                    # remove- and add-reader.\n                    await asyncio.sleep(0.1)\n                    await self.loop.sock_sendall(srv_sock_conn, b'1')\n                self.loop.create_task(send_server_data())\n\n                for rfut in pending_read_futs:\n                    rfut.cancel()\n\n                data = await self.loop.sock_recv(sock_client, 1)\n\n                self.assertEqual(data, b'1')\n\n        self.loop.run_until_complete(server())\n\n    def test_sock_send_before_cancel(self):\n        if self.is_asyncio_loop() and sys.version_info[:2] == (3, 8):\n            # asyncio 3.8.x has a regression; fixed in 3.9.0\n            # tracked in https://bugs.python.org/issue30064\n            raise unittest.SkipTest()\n\n        srv_sock_conn = None\n\n        async def server():\n            nonlocal srv_sock_conn\n            sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            sock_server.setblocking(False)\n            with sock_server:\n                sock_server.bind(('127.0.0.1', 0))\n                sock_server.listen()\n                fut = asyncio.ensure_future(\n                    client(sock_server.getsockname()))\n                srv_sock_conn, _ = await self.loop.sock_accept(sock_server)\n                with srv_sock_conn:\n                    await fut\n\n        async def client(addr):\n            await asyncio.sleep(0.01)\n            sock_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            sock_client.setblocking(False)\n            with sock_client:\n                await self.loop.sock_connect(sock_client, addr)\n                _, pending_read_futs = await asyncio.wait(\n                    [\n                        asyncio.ensure_future(\n                            self.loop.sock_recv(sock_client, 1)\n                        )\n                    ],\n                    timeout=1,\n                )\n\n                # server can send the data in a random time, even before\n                # the previous result future has cancelled.\n                await self.loop.sock_sendall(srv_sock_conn, b'1')\n\n                for rfut in pending_read_futs:\n                    rfut.cancel()\n\n                data = await self.loop.sock_recv(sock_client, 1)\n\n                self.assertEqual(data, b'1')\n\n        self.loop.run_until_complete(server())\n\n\nclass TestUVSockets(_TestSockets, tb.UVTestCase):\n\n    @unittest.skipUnless(hasattr(select, 'epoll'), 'Linux only test')\n    def test_socket_sync_remove(self):\n        # See https://github.com/MagicStack/uvloop/issues/61 for details\n\n        sock = socket.socket()\n        epoll = select.epoll.fromfd(self.loop._get_backend_id())\n\n        try:\n            cb = lambda: None\n\n            sock.bind(('127.0.0.1', 0))\n            sock.listen(0)\n            fd = sock.fileno()\n            self.loop.add_reader(fd, cb)\n            self.loop.run_until_complete(asyncio.sleep(0.01))\n            self.loop.remove_reader(fd)\n            with self.assertRaises(FileNotFoundError):\n                epoll.modify(fd, 0)\n\n        finally:\n            sock.close()\n            self.loop.close()\n            epoll.close()\n\n    def test_add_reader_or_writer_transport_fd(self):\n        def assert_raises():\n            return self.assertRaisesRegex(\n                RuntimeError,\n                r'File descriptor .* is used by transport')\n\n        async def runner():\n            tr, pr = await self.loop.create_connection(\n                lambda: asyncio.Protocol(), sock=rsock)\n\n            try:\n                cb = lambda: None\n                sock = tr.get_extra_info('socket')\n\n                with assert_raises():\n                    self.loop.add_reader(sock, cb)\n                with assert_raises():\n                    self.loop.add_reader(sock.fileno(), cb)\n\n                with assert_raises():\n                    self.loop.remove_reader(sock)\n                with assert_raises():\n                    self.loop.remove_reader(sock.fileno())\n\n                with assert_raises():\n                    self.loop.add_writer(sock, cb)\n                with assert_raises():\n                    self.loop.add_writer(sock.fileno(), cb)\n\n                with assert_raises():\n                    self.loop.remove_writer(sock)\n                with assert_raises():\n                    self.loop.remove_writer(sock.fileno())\n\n            finally:\n                tr.close()\n\n        rsock, wsock = socket.socketpair()\n        try:\n            self.loop.run_until_complete(runner())\n        finally:\n            rsock.close()\n            wsock.close()\n\n    def test_pseudosocket(self):\n        def assert_raises():\n            return self.assertRaisesRegex(\n                RuntimeError,\n                r'File descriptor .* is used by transport')\n\n        def test_pseudo(real_sock, pseudo_sock, *, is_dup=False):\n            self.assertIn('AF_UNIX', repr(pseudo_sock))\n\n            self.assertEqual(pseudo_sock.family, real_sock.family)\n            self.assertEqual(pseudo_sock.proto, real_sock.proto)\n\n            # Guard against SOCK_NONBLOCK bit in socket.type on Linux.\n            self.assertEqual(pseudo_sock.type & 0xf, real_sock.type & 0xf)\n\n            with self.assertRaises(TypeError):\n                pickle.dumps(pseudo_sock)\n\n            na_meths = {\n                'accept', 'connect', 'connect_ex', 'bind', 'listen',\n                'makefile', 'sendfile', 'close', 'detach', 'shutdown',\n                'sendmsg_afalg', 'sendmsg', 'sendto', 'send', 'sendall',\n                'recv_into', 'recvfrom_into', 'recvmsg_into', 'recvmsg',\n                'recvfrom', 'recv'\n            }\n            for methname in na_meths:\n                meth = getattr(pseudo_sock, methname)\n                with self.assertRaisesRegex(\n                        TypeError,\n                        r'.*not support ' + methname + r'\\(\\) method'):\n                    meth()\n\n            eq_meths = {\n                'getsockname', 'getpeername', 'get_inheritable', 'gettimeout'\n            }\n            for methname in eq_meths:\n                pmeth = getattr(pseudo_sock, methname)\n                rmeth = getattr(real_sock, methname)\n\n                # Call 2x to check caching paths\n                self.assertEqual(pmeth(), rmeth())\n                self.assertEqual(pmeth(), rmeth())\n\n            self.assertEqual(\n                pseudo_sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR),\n                0)\n\n            if not is_dup:\n                self.assertEqual(pseudo_sock.fileno(), real_sock.fileno())\n\n                duped = pseudo_sock.dup()\n                with duped:\n                    test_pseudo(duped, pseudo_sock, is_dup=True)\n\n            with self.assertRaises(TypeError):\n                with pseudo_sock:\n                    pass\n\n        async def runner():\n            tr, pr = await self.loop.create_connection(\n                lambda: asyncio.Protocol(), sock=rsock)\n\n            try:\n                sock = tr.get_extra_info('socket')\n                test_pseudo(rsock, sock)\n            finally:\n                tr.close()\n\n        rsock, wsock = socket.socketpair()\n        try:\n            self.loop.run_until_complete(runner())\n        finally:\n            rsock.close()\n            wsock.close()\n\n    def test_socket_connect_and_close(self):\n        def srv_gen(sock):\n            sock.send(b'helo')\n\n        async def client(sock, addr):\n            f = asyncio.ensure_future(self.loop.sock_connect(sock, addr),\n                                      loop=self.loop)\n            self.loop.call_soon(sock.close)\n            await f\n            return 'ok'\n\n        with self.tcp_server(srv_gen) as srv:\n\n            sock = socket.socket()\n            with sock:\n                sock.setblocking(False)\n                r = self.loop.run_until_complete(client(sock, srv.addr))\n                self.assertEqual(r, 'ok')\n\n    def test_socket_recv_and_close(self):\n        def srv_gen(sock):\n            time.sleep(1.2)\n            sock.send(b'helo')\n\n        async def kill(sock):\n            await asyncio.sleep(0.2)\n            sock.close()\n\n        async def client(sock, addr):\n            await self.loop.sock_connect(sock, addr)\n\n            f = asyncio.ensure_future(self.loop.sock_recv(sock, 10),\n                                      loop=self.loop)\n            self.loop.create_task(kill(sock))\n            res = await f\n            self.assertEqual(sock.fileno(), -1)\n            return res\n\n        with self.tcp_server(srv_gen) as srv:\n\n            sock = socket.socket()\n            with sock:\n                sock.setblocking(False)\n                c = client(sock, srv.addr)\n                w = asyncio.wait_for(c, timeout=5.0)\n                r = self.loop.run_until_complete(w)\n                self.assertEqual(r, b'helo')\n\n    def test_socket_recv_into_and_close(self):\n        def srv_gen(sock):\n            time.sleep(1.2)\n            sock.send(b'helo')\n\n        async def kill(sock):\n            await asyncio.sleep(0.2)\n            sock.close()\n\n        async def client(sock, addr):\n            await self.loop.sock_connect(sock, addr)\n\n            data = bytearray(10)\n            with memoryview(data) as buf:\n                f = asyncio.ensure_future(self.loop.sock_recv_into(sock, buf),\n                                          loop=self.loop)\n                self.loop.create_task(kill(sock))\n                rcvd = await f\n                data = data[:rcvd]\n            self.assertEqual(sock.fileno(), -1)\n            return bytes(data)\n\n        with self.tcp_server(srv_gen) as srv:\n\n            sock = socket.socket()\n            with sock:\n                sock.setblocking(False)\n                c = client(sock, srv.addr)\n                w = asyncio.wait_for(c, timeout=5.0)\n                r = self.loop.run_until_complete(w)\n                self.assertEqual(r, b'helo')\n\n    def test_socket_send_and_close(self):\n        ok = False\n\n        def srv_gen(sock):\n            nonlocal ok\n            b = sock.recv_all(2)\n            if b == b'hi':\n                ok = True\n            sock.send(b'ii')\n\n        async def client(sock, addr):\n            await self.loop.sock_connect(sock, addr)\n\n            s2 = sock.dup()  # Don't let it drop connection until `f` is done\n            with s2:\n                f = asyncio.ensure_future(self.loop.sock_sendall(sock, b'hi'),\n                                          loop=self.loop)\n                self.loop.call_soon(sock.close)\n                await f\n\n                return await self.loop.sock_recv(s2, 2)\n\n        with self.tcp_server(srv_gen) as srv:\n\n            sock = socket.socket()\n            with sock:\n                sock.setblocking(False)\n                r = self.loop.run_until_complete(client(sock, srv.addr))\n                self.assertEqual(r, b'ii')\n\n        self.assertTrue(ok)\n\n    def test_socket_close_loop_and_close(self):\n        class Abort(Exception):\n            pass\n\n        def srv_gen(sock):\n            time.sleep(1.2)\n\n        async def client(sock, addr):\n            await self.loop.sock_connect(sock, addr)\n\n            asyncio.ensure_future(self.loop.sock_recv(sock, 10),\n                                  loop=self.loop)\n            await asyncio.sleep(0.2)\n            raise Abort\n\n        with self.tcp_server(srv_gen) as srv:\n\n            sock = socket.socket()\n            with sock:\n                sock.setblocking(False)\n\n                c = client(sock, srv.addr)\n                w = asyncio.wait_for(c, timeout=5.0)\n                try:\n                    sock = self.loop.run_until_complete(w)\n                except Abort:\n                    pass\n\n                # `loop` still owns `sock`, so closing `sock` shouldn't\n                # do anything.\n                sock.close()\n                self.assertNotEqual(sock.fileno(), -1)\n\n                # `loop.close()` should io-decref all sockets that the\n                # loop owns, including our `sock`.\n                self.loop.close()\n                self.assertEqual(sock.fileno(), -1)\n\n    def test_socket_close_remove_reader(self):\n        s = socket.socket()\n        with s:\n            s.setblocking(False)\n            self.loop.add_reader(s, lambda: None)\n            self.loop.remove_reader(s.fileno())\n            s.close()\n            self.assertEqual(s.fileno(), -1)\n\n        s = socket.socket()\n        with s:\n            s.setblocking(False)\n            self.loop.add_reader(s.fileno(), lambda: None)\n            self.loop.remove_reader(s)\n            self.assertNotEqual(s.fileno(), -1)\n            s.close()\n            self.assertEqual(s.fileno(), -1)\n\n    def test_socket_close_remove_writer(self):\n        s = socket.socket()\n        with s:\n            s.setblocking(False)\n            self.loop.add_writer(s, lambda: None)\n            self.loop.remove_writer(s.fileno())\n            s.close()\n            self.assertEqual(s.fileno(), -1)\n\n        s = socket.socket()\n        with s:\n            s.setblocking(False)\n            self.loop.add_writer(s.fileno(), lambda: None)\n            self.loop.remove_writer(s)\n            self.assertNotEqual(s.fileno(), -1)\n            s.close()\n            self.assertEqual(s.fileno(), -1)\n\n    def test_socket_cancel_sock_recv_1(self):\n        def srv_gen(sock):\n            time.sleep(1.2)\n            sock.send(b'helo')\n\n        async def kill(fut):\n            await asyncio.sleep(0.2)\n            fut.cancel()\n\n        async def client(sock, addr):\n            await self.loop.sock_connect(sock, addr)\n\n            f = asyncio.ensure_future(self.loop.sock_recv(sock, 10),\n                                      loop=self.loop)\n            self.loop.create_task(kill(f))\n            with self.assertRaises(asyncio.CancelledError):\n                await f\n            sock.close()\n            self.assertEqual(sock.fileno(), -1)\n\n        with self.tcp_server(srv_gen) as srv:\n\n            sock = socket.socket()\n            with sock:\n                sock.setblocking(False)\n                c = client(sock, srv.addr)\n                w = asyncio.wait_for(c, timeout=5.0)\n                self.loop.run_until_complete(w)\n\n    def test_socket_cancel_sock_recv_2(self):\n        def srv_gen(sock):\n            time.sleep(1.2)\n            sock.send(b'helo')\n\n        async def kill(fut):\n            await asyncio.sleep(0.5)\n            fut.cancel()\n\n        async def recv(sock):\n            fut = self.loop.create_task(self.loop.sock_recv(sock, 10))\n            await asyncio.sleep(0.1)\n            self.loop.remove_reader(sock)\n            sock.close()\n            try:\n                await fut\n            except asyncio.CancelledError:\n                raise\n            finally:\n                sock.close()\n\n        async def client(sock, addr):\n            await self.loop.sock_connect(sock, addr)\n\n            f = asyncio.ensure_future(recv(sock))\n            self.loop.create_task(kill(f))\n            with self.assertRaises(asyncio.CancelledError):\n                await f\n            sock.close()\n            self.assertEqual(sock.fileno(), -1)\n\n        with self.tcp_server(srv_gen) as srv:\n\n            sock = socket.socket()\n            with sock:\n                sock.setblocking(False)\n                c = client(sock, srv.addr)\n                w = asyncio.wait_for(c, timeout=5.0)\n                self.loop.run_until_complete(w)\n\n    def test_socket_cancel_sock_sendall(self):\n        def srv_gen(sock):\n            time.sleep(1.2)\n            sock.recv_all(4)\n\n        async def kill(fut):\n            await asyncio.sleep(0.2)\n            fut.cancel()\n\n        async def client(sock, addr):\n            await self.loop.sock_connect(sock, addr)\n\n            f = asyncio.ensure_future(\n                self.loop.sock_sendall(sock, b'helo' * (1024 * 1024 * 50)),\n                loop=self.loop)\n            self.loop.create_task(kill(f))\n            with self.assertRaises(asyncio.CancelledError):\n                await f\n            sock.close()\n            self.assertEqual(sock.fileno(), -1)\n\n        # disable slow callback reporting for this test\n        self.loop.slow_callback_duration = 1000.0\n\n        with self.tcp_server(srv_gen) as srv:\n\n            sock = socket.socket()\n            with sock:\n                sock.setblocking(False)\n                c = client(sock, srv.addr)\n                w = asyncio.wait_for(c, timeout=5.0)\n                self.loop.run_until_complete(w)\n\n    def test_socket_close_many_add_readers(self):\n        s = socket.socket()\n        with s:\n            s.setblocking(False)\n            self.loop.add_reader(s, lambda: None)\n            self.loop.add_reader(s, lambda: None)\n            self.loop.add_reader(s, lambda: None)\n            self.loop.remove_reader(s.fileno())\n            s.close()\n            self.assertEqual(s.fileno(), -1)\n\n        s = socket.socket()\n        with s:\n            s.setblocking(False)\n            self.loop.add_reader(s, lambda: None)\n            self.loop.add_reader(s, lambda: None)\n            self.loop.add_reader(s, lambda: None)\n            self.loop.remove_reader(s)\n            s.close()\n            self.assertEqual(s.fileno(), -1)\n\n    def test_socket_close_many_remove_writers(self):\n        s = socket.socket()\n        with s:\n            s.setblocking(False)\n            self.loop.add_writer(s, lambda: None)\n            self.loop.add_writer(s, lambda: None)\n            self.loop.add_writer(s, lambda: None)\n            self.loop.remove_writer(s.fileno())\n            s.close()\n            self.assertEqual(s.fileno(), -1)\n\n        s = socket.socket()\n        with s:\n            s.setblocking(False)\n            self.loop.add_writer(s, lambda: None)\n            self.loop.add_writer(s, lambda: None)\n            self.loop.add_writer(s, lambda: None)\n            self.loop.remove_writer(s)\n            s.close()\n            self.assertEqual(s.fileno(), -1)\n\n\nclass TestAIOSockets(_TestSockets, tb.AIOTestCase):\n    pass\n"
  },
  {
    "path": "tests/test_sourcecode.py",
    "content": "import os\nimport subprocess\nimport sys\nimport unittest\n\n\ndef find_uvloop_root():\n    return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n\n\nclass TestSourceCode(unittest.TestCase):\n\n    def test_flake8(self):\n        edgepath = find_uvloop_root()\n        config_path = os.path.join(edgepath, '.flake8')\n        if not os.path.exists(config_path):\n            raise RuntimeError('could not locate .flake8 file')\n\n        try:\n            import flake8  # NoQA\n        except ImportError:\n            raise unittest.SkipTest('flake8 module is missing')\n\n        for subdir in ['examples', 'uvloop', 'tests']:\n            try:\n                subprocess.run(\n                    [sys.executable, '-m', 'flake8', '--config', config_path],\n                    check=True,\n                    stdout=subprocess.PIPE,\n                    stderr=subprocess.PIPE,\n                    cwd=os.path.join(edgepath, subdir))\n            except subprocess.CalledProcessError as ex:\n                output = ex.stdout.decode()\n                output += '\\n'\n                output += ex.stderr.decode()\n                raise AssertionError(\n                    'flake8 validation failed: {}\\n{}'.format(ex, output)\n                ) from None\n\n    def test_mypy(self):\n        edgepath = find_uvloop_root()\n        config_path = os.path.join(edgepath, 'mypy.ini')\n        if not os.path.exists(config_path):\n            raise RuntimeError('could not locate mypy.ini file')\n\n        try:\n            import mypy  # NoQA\n        except ImportError:\n            raise unittest.SkipTest('mypy module is missing')\n\n        try:\n            subprocess.run(\n                [\n                    sys.executable,\n                    '-m',\n                    'mypy',\n                    '--config-file',\n                    config_path,\n                    'uvloop'\n                ],\n                check=True,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE,\n                cwd=edgepath\n            )\n        except subprocess.CalledProcessError as ex:\n            output = ex.stdout.decode()\n            output += '\\n'\n            output += ex.stderr.decode()\n            raise AssertionError(\n                'mypy validation failed: {}\\n{}'.format(ex, output)\n            ) from None\n"
  },
  {
    "path": "tests/test_tcp.py",
    "content": "import asyncio\nimport asyncio.sslproto\nimport gc\nimport os\nimport select\nimport socket\nimport unittest.mock\nimport ssl\nimport sys\nimport threading\nimport time\nimport weakref\n\nfrom OpenSSL import SSL as openssl_ssl\nfrom uvloop import _testbase as tb\n\n\nSSL_HANDSHAKE_TIMEOUT = 15.0\n\n\nclass MyBaseProto(asyncio.Protocol):\n    connected = None\n    done = None\n\n    def __init__(self, loop=None):\n        self.transport = None\n        self.state = 'INITIAL'\n        self.nbytes = 0\n        if loop is not None:\n            self.connected = asyncio.Future(loop=loop)\n            self.done = asyncio.Future(loop=loop)\n\n    def connection_made(self, transport):\n        self.transport = transport\n        assert self.state == 'INITIAL', self.state\n        self.state = 'CONNECTED'\n        if self.connected:\n            self.connected.set_result(None)\n\n    def data_received(self, data):\n        assert self.state == 'CONNECTED', self.state\n        self.nbytes += len(data)\n\n    def eof_received(self):\n        assert self.state == 'CONNECTED', self.state\n        self.state = 'EOF'\n\n    def connection_lost(self, exc):\n        assert self.state in ('CONNECTED', 'EOF'), self.state\n        self.state = 'CLOSED'\n        if self.done:\n            self.done.set_result(None)\n\n\nclass _TestTCP:\n    def test_create_server_1(self):\n        CNT = 0           # number of clients that were successful\n        TOTAL_CNT = 25    # total number of clients that test will create\n        TIMEOUT = 5.0     # timeout for this test\n\n        A_DATA = b'A' * 1024 * 1024\n        B_DATA = b'B' * 1024 * 1024\n\n        async def handle_client(reader, writer):\n            nonlocal CNT\n\n            data = await reader.readexactly(len(A_DATA))\n            self.assertEqual(data, A_DATA)\n            writer.write(b'OK')\n\n            data = await reader.readexactly(len(B_DATA))\n            self.assertEqual(data, B_DATA)\n            writer.writelines([b'S', b'P'])\n            writer.write(bytearray(b'A'))\n            writer.write(memoryview(b'M'))\n\n            if self.implementation == 'uvloop':\n                tr = writer.transport\n                sock = tr.get_extra_info('socket')\n                self.assertTrue(\n                    sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY))\n\n            await writer.drain()\n            writer.close()\n\n            CNT += 1\n\n        async def test_client(addr):\n            sock = socket.socket()\n            with sock:\n                sock.setblocking(False)\n                await self.loop.sock_connect(sock, addr)\n\n                await self.loop.sock_sendall(sock, A_DATA)\n\n                buf = b''\n                while len(buf) != 2:\n                    buf += await self.loop.sock_recv(sock, 1)\n                self.assertEqual(buf, b'OK')\n\n                await self.loop.sock_sendall(sock, B_DATA)\n\n                buf = b''\n                while len(buf) != 4:\n                    buf += await self.loop.sock_recv(sock, 1)\n                self.assertEqual(buf, b'SPAM')\n\n            self.assertEqual(sock.fileno(), -1)\n            self.assertEqual(sock._io_refs, 0)\n            self.assertTrue(sock._closed)\n\n        async def start_server():\n            nonlocal CNT\n            CNT = 0\n\n            srv = await asyncio.start_server(\n                handle_client,\n                ('127.0.0.1', 'localhost'), 0,\n                family=socket.AF_INET)\n\n            srv_socks = srv.sockets\n            self.assertTrue(srv_socks)\n            self.assertTrue(srv.is_serving())\n\n            addr = srv_socks[0].getsockname()\n\n            tasks = []\n            for _ in range(TOTAL_CNT):\n                tasks.append(test_client(addr))\n\n            await asyncio.wait_for(asyncio.gather(*tasks), TIMEOUT)\n\n            self.loop.call_soon(srv.close)\n            await srv.wait_closed()\n\n            if (\n                self.implementation == 'asyncio'\n                and sys.version_info[:3] >= (3, 12, 0)\n            ):\n                # asyncio regression in 3.12 -- wait_closed()\n                # doesn't wait for `close()` to actually complete.\n                # https://github.com/python/cpython/issues/79033\n                await asyncio.sleep(1)\n\n            # Check that the server cleaned-up proxy-sockets\n            for srv_sock in srv_socks:\n                self.assertEqual(srv_sock.fileno(), -1)\n\n            self.assertFalse(srv.is_serving())\n\n        async def start_server_sock():\n            nonlocal CNT\n            CNT = 0\n\n            sock = socket.socket()\n            sock.bind(('127.0.0.1', 0))\n            addr = sock.getsockname()\n\n            srv = await asyncio.start_server(\n                handle_client,\n                None, None,\n                family=socket.AF_INET,\n                sock=sock)\n\n            self.assertIs(srv.get_loop(), self.loop)\n\n            srv_socks = srv.sockets\n            self.assertTrue(srv_socks)\n            self.assertTrue(srv.is_serving())\n\n            tasks = []\n            for _ in range(TOTAL_CNT):\n                tasks.append(test_client(addr))\n\n            await asyncio.wait_for(asyncio.gather(*tasks), TIMEOUT)\n\n            srv.close()\n            await srv.wait_closed()\n\n            if (\n                self.implementation == 'asyncio'\n                and sys.version_info[:3] >= (3, 12, 0)\n            ):\n                # asyncio regression in 3.12 -- wait_closed()\n                # doesn't wait for `close()` to actually complete.\n                # https://github.com/python/cpython/issues/79033\n                await asyncio.sleep(1)\n\n            # Check that the server cleaned-up proxy-sockets\n            for srv_sock in srv_socks:\n                self.assertEqual(srv_sock.fileno(), -1)\n\n            self.assertFalse(srv.is_serving())\n\n        self.loop.run_until_complete(start_server())\n        self.assertEqual(CNT, TOTAL_CNT)\n\n        self.loop.run_until_complete(start_server_sock())\n        self.assertEqual(CNT, TOTAL_CNT)\n\n    def test_create_server_2(self):\n        with self.assertRaisesRegex(ValueError, 'nor sock were specified'):\n            self.loop.run_until_complete(self.loop.create_server(object))\n\n    def test_create_server_3(self):\n        ''' check ephemeral port can be used '''\n\n        async def start_server_ephemeral_ports():\n\n            for port_sentinel in [0, None]:\n                srv = await self.loop.create_server(\n                    asyncio.Protocol,\n                    '127.0.0.1', port_sentinel,\n                    family=socket.AF_INET)\n\n                srv_socks = srv.sockets\n                self.assertTrue(srv_socks)\n                self.assertTrue(srv.is_serving())\n\n                host, port = srv_socks[0].getsockname()\n                self.assertNotEqual(0, port)\n\n                self.loop.call_soon(srv.close)\n                await srv.wait_closed()\n\n                if (\n                    self.implementation == 'asyncio'\n                    and sys.version_info[:3] >= (3, 12, 0)\n                ):\n                    # asyncio regression in 3.12 -- wait_closed()\n                    # doesn't wait for `close()` to actually complete.\n                    # https://github.com/python/cpython/issues/79033\n                    await asyncio.sleep(1)\n\n                # Check that the server cleaned-up proxy-sockets\n                for srv_sock in srv_socks:\n                    self.assertEqual(srv_sock.fileno(), -1)\n\n                self.assertFalse(srv.is_serving())\n\n        self.loop.run_until_complete(start_server_ephemeral_ports())\n\n    def test_create_server_4(self):\n        sock = socket.socket()\n        sock.bind(('127.0.0.1', 0))\n\n        with sock:\n            addr = sock.getsockname()\n\n            with self.assertRaisesRegex(OSError,\n                                        r\"error while attempting.*\\('127.*:\"\n                                        r\"( \\[errno \\d+\\])? address\"\n                                        r\"( already)? in use\"):\n\n                self.loop.run_until_complete(\n                    self.loop.create_server(object, *addr))\n\n    def test_create_server_5(self):\n        # Test that create_server sets the TCP_IPV6ONLY flag,\n        # so it can bind to ipv4 and ipv6 addresses\n        # simultaneously.\n\n        port = tb.find_free_port()\n\n        async def runner():\n            srv = await self.loop.create_server(\n                asyncio.Protocol,\n                None, port)\n\n            srv.close()\n            await srv.wait_closed()\n\n        self.loop.run_until_complete(runner())\n\n    def test_create_server_6(self):\n        if not hasattr(socket, 'SO_REUSEPORT'):\n            raise unittest.SkipTest(\n                'The system does not support SO_REUSEPORT')\n\n        port = tb.find_free_port()\n\n        async def runner():\n            srv1 = await self.loop.create_server(\n                asyncio.Protocol,\n                None, port,\n                reuse_port=True)\n\n            srv2 = await self.loop.create_server(\n                asyncio.Protocol,\n                None, port,\n                reuse_port=True)\n\n            srv1.close()\n            srv2.close()\n\n            await srv1.wait_closed()\n            await srv2.wait_closed()\n\n        self.loop.run_until_complete(runner())\n\n    def test_create_server_7(self):\n        # Test that create_server() stores a hard ref to the server object\n        # somewhere in the loop.  In asyncio it so happens that\n        # loop.sock_accept() has a reference to the server object so it\n        # never gets GCed.\n\n        class Proto(asyncio.Protocol):\n            def connection_made(self, tr):\n                self.tr = tr\n                self.tr.write(b'hello')\n\n        async def test():\n            port = tb.find_free_port()\n            srv = await self.loop.create_server(Proto, '127.0.0.1', port)\n            wsrv = weakref.ref(srv)\n            del srv\n\n            gc.collect()\n            gc.collect()\n            gc.collect()\n\n            s = socket.socket(socket.AF_INET)\n            with s:\n                s.setblocking(False)\n                await self.loop.sock_connect(s, ('127.0.0.1', port))\n                d = await self.loop.sock_recv(s, 100)\n                self.assertEqual(d, b'hello')\n\n            srv = wsrv()\n            srv.close()\n            await srv.wait_closed()\n            del srv\n\n            # Let all transports shutdown.\n            await asyncio.sleep(0.1)\n\n            gc.collect()\n            gc.collect()\n            gc.collect()\n\n            self.assertIsNone(wsrv())\n\n        self.loop.run_until_complete(test())\n\n    def test_create_server_8(self):\n        with self.assertRaisesRegex(\n                ValueError, 'ssl_handshake_timeout is only meaningful'):\n            self.loop.run_until_complete(\n                self.loop.create_server(\n                    lambda: None, host='::', port=0,\n                    ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT))\n\n    def test_create_server_9(self):\n        async def handle_client(reader, writer):\n            pass\n\n        async def start_server():\n            srv = await asyncio.start_server(\n                handle_client,\n                '127.0.0.1', 0,\n                family=socket.AF_INET,\n                start_serving=False)\n\n            await srv.start_serving()\n            self.assertTrue(srv.is_serving())\n\n            # call start_serving again\n            await srv.start_serving()\n            self.assertTrue(srv.is_serving())\n\n            srv.close()\n            await srv.wait_closed()\n            self.assertFalse(srv.is_serving())\n\n        self.loop.run_until_complete(start_server())\n\n    def test_create_server_10(self):\n        async def handle_client(reader, writer):\n            pass\n\n        async def start_server():\n            srv = await asyncio.start_server(\n                handle_client,\n                '127.0.0.1', 0,\n                family=socket.AF_INET,\n                start_serving=False)\n\n            async with srv:\n                fut = asyncio.ensure_future(srv.serve_forever())\n                await asyncio.sleep(0)\n                self.assertTrue(srv.is_serving())\n\n                fut.cancel()\n                with self.assertRaises(asyncio.CancelledError):\n                    await fut\n                self.assertFalse(srv.is_serving())\n\n        self.loop.run_until_complete(start_server())\n\n    def test_create_connection_open_con_addr(self):\n        async def client(addr):\n            reader, writer = await asyncio.open_connection(*addr)\n\n            writer.write(b'AAAA')\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            re = r'(a bytes-like object)|(must be byte-ish)'\n            if sys.version_info >= (3, 13, 9):\n                re += r'|(must be a bytes, bytearray, or memoryview object)'\n            with self.assertRaisesRegex(TypeError, re):\n                writer.write('AAAA')\n\n            writer.write(b'BBBB')\n            self.assertEqual(await reader.readexactly(4), b'SPAM')\n\n            if self.implementation == 'uvloop':\n                tr = writer.transport\n                sock = tr.get_extra_info('socket')\n                self.assertTrue(\n                    sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY))\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        self._test_create_connection_1(client)\n\n    def test_create_connection_open_con_sock(self):\n        async def client(addr):\n            sock = socket.socket()\n            sock.connect(addr)\n            reader, writer = await asyncio.open_connection(sock=sock)\n\n            writer.write(b'AAAA')\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            writer.write(b'BBBB')\n            self.assertEqual(await reader.readexactly(4), b'SPAM')\n\n            if self.implementation == 'uvloop':\n                tr = writer.transport\n                sock = tr.get_extra_info('socket')\n                self.assertTrue(\n                    sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY))\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        self._test_create_connection_1(client)\n\n    def _test_create_connection_1(self, client):\n        CNT = 0\n        TOTAL_CNT = 100\n\n        def server(sock):\n            data = sock.recv_all(4)\n            self.assertEqual(data, b'AAAA')\n            sock.send(b'OK')\n\n            data = sock.recv_all(4)\n            self.assertEqual(data, b'BBBB')\n            sock.send(b'SPAM')\n\n        async def client_wrapper(addr):\n            await client(addr)\n            nonlocal CNT\n            CNT += 1\n\n        def run(coro):\n            nonlocal CNT\n            CNT = 0\n\n            with self.tcp_server(server,\n                                 max_clients=TOTAL_CNT,\n                                 backlog=TOTAL_CNT) as srv:\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(coro(srv.addr))\n\n                self.loop.run_until_complete(asyncio.gather(*tasks))\n\n            self.assertEqual(CNT, TOTAL_CNT)\n\n        run(client_wrapper)\n\n    def test_create_connection_2(self):\n        sock = socket.socket()\n        with sock:\n            sock.bind(('127.0.0.1', 0))\n            addr = sock.getsockname()\n\n        async def client():\n            reader, writer = await asyncio.open_connection(*addr)\n            writer.close()\n            await self.wait_closed(writer)\n\n        async def runner():\n            with self.assertRaises(ConnectionRefusedError):\n                await client()\n\n        self.loop.run_until_complete(runner())\n\n    def test_create_connection_3(self):\n        CNT = 0\n        TOTAL_CNT = 100\n\n        def server(sock):\n            data = sock.recv_all(4)\n            self.assertEqual(data, b'AAAA')\n            sock.close()\n\n        async def client(addr):\n            reader, writer = await asyncio.open_connection(*addr)\n\n            writer.write(b'AAAA')\n\n            with self.assertRaises(asyncio.IncompleteReadError):\n                await reader.readexactly(10)\n\n            writer.close()\n            await self.wait_closed(writer)\n\n            nonlocal CNT\n            CNT += 1\n\n        def run(coro):\n            nonlocal CNT\n            CNT = 0\n\n            with self.tcp_server(server,\n                                 max_clients=TOTAL_CNT,\n                                 backlog=TOTAL_CNT) as srv:\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(coro(srv.addr))\n\n                self.loop.run_until_complete(asyncio.gather(*tasks))\n\n            self.assertEqual(CNT, TOTAL_CNT)\n\n        run(client)\n\n    def test_create_connection_4(self):\n        sock = socket.socket()\n        sock.close()\n\n        async def client():\n            reader, writer = await asyncio.open_connection(sock=sock)\n            writer.close()\n            await self.wait_closed(writer)\n\n        async def runner():\n            with self.assertRaisesRegex(OSError, 'Bad file'):\n                await client()\n\n        self.loop.run_until_complete(runner())\n\n    def test_create_connection_5(self):\n        def server(sock):\n            try:\n                data = sock.recv_all(4)\n            except ConnectionError:\n                return\n            self.assertEqual(data, b'AAAA')\n            sock.send(b'OK')\n\n        async def client(addr):\n            fut = asyncio.ensure_future(\n                self.loop.create_connection(asyncio.Protocol, *addr))\n            await asyncio.sleep(0)\n            fut.cancel()\n            with self.assertRaises(asyncio.CancelledError):\n                await fut\n\n        with self.tcp_server(server,\n                             max_clients=1,\n                             backlog=1) as srv:\n            self.loop.run_until_complete(client(srv.addr))\n\n    def test_create_connection_6(self):\n        with self.assertRaisesRegex(\n                ValueError, 'ssl_handshake_timeout is only meaningful'):\n            self.loop.run_until_complete(\n                self.loop.create_connection(\n                    lambda: None, host='::', port=0,\n                    ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT))\n\n    def test_transport_shutdown(self):\n        CNT = 0           # number of clients that were successful\n        TOTAL_CNT = 100   # total number of clients that test will create\n        TIMEOUT = 5.0     # timeout for this test\n\n        async def handle_client(reader, writer):\n            nonlocal CNT\n\n            data = await reader.readexactly(4)\n            self.assertEqual(data, b'AAAA')\n\n            writer.write(b'OK')\n            writer.write_eof()\n            writer.write_eof()\n\n            await writer.drain()\n            writer.close()\n\n            CNT += 1\n\n        async def test_client(addr):\n            reader, writer = await asyncio.open_connection(*addr)\n\n            writer.write(b'AAAA')\n            data = await reader.readexactly(2)\n            self.assertEqual(data, b'OK')\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        async def start_server():\n            nonlocal CNT\n            CNT = 0\n\n            srv = await asyncio.start_server(\n                handle_client,\n                '127.0.0.1', 0,\n                family=socket.AF_INET)\n\n            srv_socks = srv.sockets\n            self.assertTrue(srv_socks)\n\n            addr = srv_socks[0].getsockname()\n\n            tasks = []\n            for _ in range(TOTAL_CNT):\n                tasks.append(test_client(addr))\n\n            await asyncio.wait_for(asyncio.gather(*tasks), TIMEOUT)\n\n            srv.close()\n            await srv.wait_closed()\n\n        self.loop.run_until_complete(start_server())\n        self.assertEqual(CNT, TOTAL_CNT)\n\n    def test_tcp_handle_exception_in_connection_made(self):\n        # Test that if connection_made raises an exception,\n        # 'create_connection' still returns.\n\n        # Silence error logging\n        self.loop.set_exception_handler(lambda *args: None)\n\n        fut = asyncio.Future()\n        connection_lost_called = asyncio.Future()\n\n        async def server(reader, writer):\n            try:\n                await reader.read()\n            finally:\n                writer.close()\n\n        class Proto(asyncio.Protocol):\n            def connection_made(self, tr):\n                1 / 0\n\n            def connection_lost(self, exc):\n                connection_lost_called.set_result(exc)\n\n        srv = self.loop.run_until_complete(asyncio.start_server(\n            server,\n            '127.0.0.1', 0,\n            family=socket.AF_INET))\n\n        async def runner():\n            tr, pr = await asyncio.wait_for(\n                self.loop.create_connection(\n                    Proto, *srv.sockets[0].getsockname()),\n                timeout=1.0)\n            fut.set_result(None)\n            tr.close()\n\n        self.loop.run_until_complete(runner())\n        srv.close()\n        self.loop.run_until_complete(srv.wait_closed())\n        self.loop.run_until_complete(fut)\n\n        self.assertIsNone(\n            self.loop.run_until_complete(connection_lost_called))\n\n    def test_resume_writing_write_different_transport(self):\n        loop = self.loop\n\n        class P1(asyncio.Protocol):\n            def __init__(self, t2):\n                self.t2 = t2\n                self.paused = False\n                self.waiter = loop.create_future()\n\n            def data_received(self, data):\n                self.waiter.set_result(data)\n\n            def pause_writing(self):\n                self.paused = True\n\n            def resume_writing(self):\n                self.paused = False\n                self.t2.write(b'hello')\n\n        s1, s2 = socket.socketpair()\n        s1.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1024)\n        s2.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1024)\n\n        async def _test(t1, p1, t2):\n            t1.set_write_buffer_limits(1024, 1023)\n\n            # fill s1 up first\n            t2.pause_reading()\n            while not p1.paused:\n                t1.write(b' ' * 1024)\n\n            # trigger resume_writing() in _exec_queued_writes() with tight loop\n            t2.resume_reading()\n            while p1.paused:\n                t1.write(b' ')\n                await asyncio.sleep(0)\n\n            # t2.write() in p1.resume_writing() should work fine\n            data = await asyncio.wait_for(p1.waiter, 5)\n            self.assertEqual(data, b'hello')\n\n        async def test():\n            t2, _ = await loop.create_connection(asyncio.Protocol, sock=s2)\n            t1, p1 = await loop.create_connection(lambda: P1(t2), sock=s1)\n            try:\n                await _test(t1, p1, t2)\n            finally:\n                t1.close()\n                t2.close()\n\n        with s1, s2:\n            loop.run_until_complete(test())\n\n\nclass Test_UV_TCP(_TestTCP, tb.UVTestCase):\n\n    def test_create_server_buffered_1(self):\n        SIZE = 123123\n        eof = False\n        fut = asyncio.Future()\n\n        class Proto(asyncio.BaseProtocol):\n            def connection_made(self, tr):\n                self.tr = tr\n                self.recvd = b''\n                self.data = bytearray(50)\n                self.buf = memoryview(self.data)\n\n            def get_buffer(self, sizehint):\n                return self.buf\n\n            def buffer_updated(self, nbytes):\n                self.recvd += self.buf[:nbytes]\n                if self.recvd == b'a' * SIZE:\n                    self.tr.write(b'hello')\n\n            def eof_received(self):\n                nonlocal eof\n                eof = True\n\n            def connection_lost(self, exc):\n                fut.set_result(exc)\n\n        async def test():\n            port = tb.find_free_port()\n            srv = await self.loop.create_server(Proto, '127.0.0.1', port)\n\n            s = socket.socket(socket.AF_INET)\n            with s:\n                s.setblocking(False)\n                await self.loop.sock_connect(s, ('127.0.0.1', port))\n                await self.loop.sock_sendall(s, b'a' * SIZE)\n                d = await self.loop.sock_recv(s, 100)\n                self.assertEqual(d, b'hello')\n\n            srv.close()\n            await srv.wait_closed()\n\n        self.loop.run_until_complete(test())\n        self.loop.run_until_complete(fut)\n        self.assertTrue(eof)\n        self.assertIsNone(fut.result())\n\n    def test_create_server_buffered_2(self):\n        class ProtoExc(asyncio.BaseProtocol):\n            def __init__(self):\n                self._lost_exc = None\n\n            def get_buffer(self, sizehint):\n                1 / 0\n\n            def buffer_updated(self, nbytes):\n                pass\n\n            def connection_lost(self, exc):\n                self._lost_exc = exc\n\n            def eof_received(self):\n                pass\n\n        class ProtoZeroBuf1(asyncio.BaseProtocol):\n            def __init__(self):\n                self._lost_exc = None\n\n            def get_buffer(self, sizehint):\n                return bytearray(0)\n\n            def buffer_updated(self, nbytes):\n                pass\n\n            def connection_lost(self, exc):\n                self._lost_exc = exc\n\n            def eof_received(self):\n                pass\n\n        class ProtoZeroBuf2(asyncio.BaseProtocol):\n            def __init__(self):\n                self._lost_exc = None\n\n            def get_buffer(self, sizehint):\n                return memoryview(bytearray(0))\n\n            def buffer_updated(self, nbytes):\n                pass\n\n            def connection_lost(self, exc):\n                self._lost_exc = exc\n\n            def eof_received(self):\n                pass\n\n        class ProtoUpdatedError(asyncio.BaseProtocol):\n            def __init__(self):\n                self._lost_exc = None\n\n            def get_buffer(self, sizehint):\n                return memoryview(bytearray(100))\n\n            def buffer_updated(self, nbytes):\n                raise RuntimeError('oups')\n\n            def connection_lost(self, exc):\n                self._lost_exc = exc\n\n            def eof_received(self):\n                pass\n\n        async def test(proto_factory, exc_type, exc_re):\n            port = tb.find_free_port()\n            proto = proto_factory()\n            srv = await self.loop.create_server(\n                lambda: proto, '127.0.0.1', port)\n\n            try:\n                s = socket.socket(socket.AF_INET)\n                with s:\n                    s.setblocking(False)\n                    await self.loop.sock_connect(s, ('127.0.0.1', port))\n                    await self.loop.sock_sendall(s, b'a')\n                    d = await self.loop.sock_recv(s, 100)\n                    if not d:\n                        raise ConnectionResetError\n            except ConnectionResetError:\n                pass\n            else:\n                self.fail(\"server didn't abort the connection\")\n                return\n            finally:\n                srv.close()\n                await srv.wait_closed()\n\n            if proto._lost_exc is None:\n                self.fail(\"connection_lost() was not called\")\n                return\n\n            with self.assertRaisesRegex(exc_type, exc_re):\n                raise proto._lost_exc\n\n        self.loop.set_exception_handler(lambda loop, ctx: None)\n\n        self.loop.run_until_complete(\n            test(ProtoExc, RuntimeError, 'unhandled error .* get_buffer'))\n\n        self.loop.run_until_complete(\n            test(ProtoZeroBuf1, RuntimeError, 'unhandled error .* get_buffer'))\n\n        self.loop.run_until_complete(\n            test(ProtoZeroBuf2, RuntimeError, 'unhandled error .* get_buffer'))\n\n        self.loop.run_until_complete(\n            test(ProtoUpdatedError, RuntimeError, r'^oups$'))\n\n    def test_transport_get_extra_info(self):\n        # This tests is only for uvloop.  asyncio should pass it\n        # too in Python 3.6.\n\n        fut = asyncio.Future()\n\n        async def handle_client(reader, writer):\n            with self.assertRaises(asyncio.IncompleteReadError):\n                await reader.readexactly(4)\n            writer.close()\n\n            # Previously, when we used socket.fromfd to create a socket\n            # for UVTransports (to make get_extra_info() work), a duplicate\n            # of the socket was created, preventing UVTransport from being\n            # properly closed.\n            # This test ensures that server handle will receive an EOF\n            # and finish the request.\n            fut.set_result(None)\n\n        async def test_client(addr):\n            t, p = await self.loop.create_connection(\n                lambda: asyncio.Protocol(), *addr)\n\n            if hasattr(t, 'get_protocol'):\n                p2 = asyncio.Protocol()\n                self.assertIs(t.get_protocol(), p)\n                t.set_protocol(p2)\n                self.assertIs(t.get_protocol(), p2)\n                t.set_protocol(p)\n\n            self.assertFalse(t._paused)\n            self.assertTrue(t.is_reading())\n            t.pause_reading()\n            t.pause_reading()  # Check that it's OK to call it 2nd time.\n            self.assertTrue(t._paused)\n            self.assertFalse(t.is_reading())\n            t.resume_reading()\n            t.resume_reading()  # Check that it's OK to call it 2nd time.\n            self.assertFalse(t._paused)\n            self.assertTrue(t.is_reading())\n\n            sock = t.get_extra_info('socket')\n            self.assertIs(sock, t.get_extra_info('socket'))\n            sockname = sock.getsockname()\n            peername = sock.getpeername()\n\n            with self.assertRaisesRegex(RuntimeError, 'is used by transport'):\n                self.loop.add_writer(sock.fileno(), lambda: None)\n            with self.assertRaisesRegex(RuntimeError, 'is used by transport'):\n                self.loop.remove_writer(sock.fileno())\n            with self.assertRaisesRegex(RuntimeError, 'is used by transport'):\n                self.loop.add_reader(sock.fileno(), lambda: None)\n            with self.assertRaisesRegex(RuntimeError, 'is used by transport'):\n                self.loop.remove_reader(sock.fileno())\n\n            self.assertEqual(t.get_extra_info('sockname'),\n                             sockname)\n            self.assertEqual(t.get_extra_info('peername'),\n                             peername)\n\n            t.write(b'OK')  # We want server to fail.\n\n            self.assertFalse(t._closing)\n            t.abort()\n            self.assertTrue(t._closing)\n\n            self.assertFalse(t.is_reading())\n            # Check that pause_reading and resume_reading don't raise\n            # errors if called after the transport is closed.\n            t.pause_reading()\n            t.resume_reading()\n\n            await fut\n\n            # Test that peername and sockname are available after\n            # the transport is closed.\n            self.assertEqual(t.get_extra_info('peername'),\n                             peername)\n            self.assertEqual(t.get_extra_info('sockname'),\n                             sockname)\n\n        async def start_server():\n            srv = await asyncio.start_server(\n                handle_client,\n                '127.0.0.1', 0,\n                family=socket.AF_INET)\n\n            addr = srv.sockets[0].getsockname()\n            await test_client(addr)\n\n            srv.close()\n            await srv.wait_closed()\n\n        self.loop.run_until_complete(start_server())\n\n    def test_create_server_float_backlog(self):\n        # asyncio spits out a warning we cannot suppress\n\n        async def runner(bl):\n            await self.loop.create_server(\n                asyncio.Protocol,\n                None, 0, backlog=bl)\n\n        for bl in (1.1, '1'):\n            with self.subTest(backlog=bl):\n                with self.assertRaisesRegex(TypeError, 'integer'):\n                    self.loop.run_until_complete(runner(bl))\n\n    def test_many_small_writes(self):\n        N = 10000\n        TOTAL = 0\n\n        fut = self.loop.create_future()\n\n        async def server(reader, writer):\n            nonlocal TOTAL\n            while True:\n                d = await reader.read(10000)\n                if not d:\n                    break\n                TOTAL += len(d)\n            fut.set_result(True)\n            writer.close()\n\n        async def run():\n            srv = await asyncio.start_server(\n                server,\n                '127.0.0.1', 0,\n                family=socket.AF_INET)\n\n            addr = srv.sockets[0].getsockname()\n            r, w = await asyncio.open_connection(*addr)\n\n            DATA = b'x' * 102400\n\n            # Test _StreamWriteContext with short sequences of writes\n            w.write(DATA)\n            await w.drain()\n            for _ in range(3):\n                w.write(DATA)\n            await w.drain()\n            for _ in range(10):\n                w.write(DATA)\n            await w.drain()\n\n            for _ in range(N):\n                w.write(DATA)\n\n                try:\n                    w.write('a')\n                except TypeError:\n                    pass\n\n            await w.drain()\n            for _ in range(N):\n                w.write(DATA)\n                await w.drain()\n\n            w.close()\n            await fut\n            await self.wait_closed(w)\n\n            srv.close()\n            await srv.wait_closed()\n\n            self.assertEqual(TOTAL, N * 2 * len(DATA) + 14 * len(DATA))\n\n        self.loop.run_until_complete(run())\n\n    def test_tcp_handle_abort_in_connection_made(self):\n        async def server(reader, writer):\n            try:\n                await reader.read()\n            finally:\n                writer.close()\n\n        class Proto(asyncio.Protocol):\n            def connection_made(self, tr):\n                tr.abort()\n\n        srv = self.loop.run_until_complete(asyncio.start_server(\n            server,\n            '127.0.0.1', 0,\n            family=socket.AF_INET))\n\n        async def runner():\n            tr, pr = await asyncio.wait_for(\n                self.loop.create_connection(\n                    Proto, *srv.sockets[0].getsockname()),\n                timeout=1.0)\n\n            # Asyncio would return a closed socket, which we\n            # can't do: the transport was aborted, hence there\n            # is no FD to attach a socket to (to make\n            # get_extra_info() work).\n            self.assertIsNone(tr.get_extra_info('socket'))\n            tr.close()\n\n        self.loop.run_until_complete(runner())\n        srv.close()\n        self.loop.run_until_complete(srv.wait_closed())\n\n    def test_connect_accepted_socket_ssl_args(self):\n        with self.assertRaisesRegex(\n                ValueError, 'ssl_handshake_timeout is only meaningful'):\n            with socket.socket() as s:\n                self.loop.run_until_complete(\n                    self.loop.connect_accepted_socket(\n                        (lambda: None),\n                        s,\n                        ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT\n                    )\n                )\n\n    def test_connect_accepted_socket(self, server_ssl=None, client_ssl=None):\n        loop = self.loop\n\n        class MyProto(MyBaseProto):\n\n            def connection_lost(self, exc):\n                super().connection_lost(exc)\n                loop.call_soon(loop.stop)\n\n            def data_received(self, data):\n                super().data_received(data)\n                self.transport.write(expected_response)\n\n        lsock = socket.socket(socket.AF_INET)\n        lsock.bind(('127.0.0.1', 0))\n        lsock.listen(1)\n        addr = lsock.getsockname()\n\n        message = b'test data'\n        response = None\n        expected_response = b'roger'\n\n        def client():\n            nonlocal response\n            try:\n                csock = socket.socket(socket.AF_INET)\n                if client_ssl is not None:\n                    csock = client_ssl.wrap_socket(csock)\n                csock.connect(addr)\n                csock.sendall(message)\n                response = csock.recv(99)\n                csock.close()\n            except Exception as exc:\n                print(\n                    \"Failure in client thread in test_connect_accepted_socket\",\n                    exc)\n\n        thread = threading.Thread(target=client, daemon=True)\n        thread.start()\n\n        conn, _ = lsock.accept()\n        proto = MyProto(loop=loop)\n        proto.loop = loop\n\n        extras = {}\n        if server_ssl:\n            extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)\n\n        f = loop.create_task(\n            loop.connect_accepted_socket(\n                (lambda: proto), conn, ssl=server_ssl,\n                **extras))\n        loop.run_forever()\n        conn.close()\n        lsock.close()\n\n        thread.join(1)\n        self.assertFalse(thread.is_alive())\n        self.assertEqual(proto.state, 'CLOSED')\n        self.assertEqual(proto.nbytes, len(message))\n        self.assertEqual(response, expected_response)\n        tr, _ = f.result()\n\n        if server_ssl:\n            self.assertIn('SSL', tr.__class__.__name__)\n\n        tr.close()\n        # let it close\n        self.loop.run_until_complete(asyncio.sleep(0.1))\n\n    @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'no Unix sockets')\n    def test_create_connection_wrong_sock(self):\n        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n        with sock:\n            coro = self.loop.create_connection(MyBaseProto, sock=sock)\n            with self.assertRaisesRegex(ValueError,\n                                        'A Stream Socket was expected'):\n                self.loop.run_until_complete(coro)\n\n    @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'no Unix sockets')\n    def test_create_server_wrong_sock(self):\n        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n        with sock:\n            coro = self.loop.create_server(MyBaseProto, sock=sock)\n            with self.assertRaisesRegex(ValueError,\n                                        'A Stream Socket was expected'):\n                self.loop.run_until_complete(coro)\n\n    @unittest.skipUnless(hasattr(socket, 'SOCK_NONBLOCK'),\n                         'no socket.SOCK_NONBLOCK (linux only)')\n    def test_create_server_stream_bittype(self):\n        sock = socket.socket(\n            socket.AF_INET, socket.SOCK_STREAM | socket.SOCK_NONBLOCK)\n        with sock:\n            coro = self.loop.create_server(lambda: None, sock=sock)\n            srv = self.loop.run_until_complete(coro)\n            srv.close()\n            self.loop.run_until_complete(srv.wait_closed())\n\n    def test_flowcontrol_mixin_set_write_limits(self):\n        async def client(addr):\n            paused = False\n\n            class Protocol(asyncio.Protocol):\n                def pause_writing(self):\n                    nonlocal paused\n                    paused = True\n\n                def resume_writing(self):\n                    nonlocal paused\n                    paused = False\n\n            t, p = await self.loop.create_connection(Protocol, *addr)\n\n            t.write(b'q' * 512)\n            t.set_write_buffer_limits(low=16385)\n            self.assertEqual(t.get_write_buffer_limits(), (16385, 65540))\n\n            with self.assertRaisesRegex(ValueError, 'high.*must be >= low'):\n                t.set_write_buffer_limits(high=0, low=1)\n\n            t.set_write_buffer_limits(high=1024, low=128)\n            self.assertEqual(t.get_write_buffer_limits(), (128, 1024))\n\n            t.set_write_buffer_limits(high=256, low=128)\n            self.assertEqual(t.get_write_buffer_limits(), (128, 256))\n\n            t.close()\n\n        with self.tcp_server(lambda sock: sock.recv_all(1),\n                             max_clients=1,\n                             backlog=1) as srv:\n            self.loop.run_until_complete(client(srv.addr))\n\n\nclass Test_AIO_TCP(_TestTCP, tb.AIOTestCase):\n    pass\n\n\nclass _TestSSL(tb.SSLTestCase):\n\n    ONLYCERT = tb._cert_fullname(__file__, 'ssl_cert.pem')\n    ONLYKEY = tb._cert_fullname(__file__, 'ssl_key.pem')\n\n    PAYLOAD_SIZE = 1024 * 100\n    TIMEOUT = 60\n\n    def test_create_server_ssl_1(self):\n        CNT = 0           # number of clients that were successful\n        TOTAL_CNT = 25    # total number of clients that test will create\n        TIMEOUT = 20.0    # timeout for this test\n\n        A_DATA = b'A' * 1024 * 1024\n        B_DATA = b'B' * 1024 * 1024\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context()\n\n        clients = []\n\n        async def handle_client(reader, writer):\n            nonlocal CNT\n\n            data = await reader.readexactly(len(A_DATA))\n            self.assertEqual(data, A_DATA)\n            writer.write(b'OK')\n\n            data = await reader.readexactly(len(B_DATA))\n            self.assertEqual(data, B_DATA)\n            writer.writelines([b'SP', bytearray(b'A'), memoryview(b'M')])\n\n            await writer.drain()\n            writer.close()\n\n            CNT += 1\n\n        async def test_client(addr):\n            fut = asyncio.Future()\n\n            def prog(sock):\n                try:\n                    sock.starttls(client_sslctx)\n                    sock.connect(addr)\n                    sock.send(A_DATA)\n\n                    data = sock.recv_all(2)\n                    self.assertEqual(data, b'OK')\n\n                    sock.send(B_DATA)\n                    data = sock.recv_all(4)\n                    self.assertEqual(data, b'SPAM')\n\n                    sock.close()\n\n                except Exception as ex:\n                    self.loop.call_soon_threadsafe(fut.set_exception, ex)\n                else:\n                    self.loop.call_soon_threadsafe(fut.set_result, None)\n\n            client = self.tcp_client(prog)\n            client.start()\n            clients.append(client)\n\n            await fut\n\n        async def start_server():\n            extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)\n\n            srv = await asyncio.start_server(\n                handle_client,\n                '127.0.0.1', 0,\n                family=socket.AF_INET,\n                ssl=sslctx,\n                **extras)\n\n            try:\n                srv_socks = srv.sockets\n                self.assertTrue(srv_socks)\n\n                addr = srv_socks[0].getsockname()\n\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(test_client(addr))\n\n                await asyncio.wait_for(asyncio.gather(*tasks), TIMEOUT)\n\n            finally:\n                self.loop.call_soon(srv.close)\n                await srv.wait_closed()\n\n        with self._silence_eof_received_warning():\n            self.loop.run_until_complete(start_server())\n\n        self.assertEqual(CNT, TOTAL_CNT)\n\n        for client in clients:\n            client.stop()\n\n    def test_create_connection_ssl_1(self):\n        if self.implementation == 'asyncio':\n            # Don't crash on asyncio errors\n            self.loop.set_exception_handler(None)\n\n        CNT = 0\n        TOTAL_CNT = 25\n\n        A_DATA = b'A' * 1024 * 1024\n        B_DATA = b'B' * 1024 * 1024\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context()\n\n        def server(sock):\n            sock.starttls(\n                sslctx,\n                server_side=True)\n\n            data = sock.recv_all(len(A_DATA))\n            self.assertEqual(data, A_DATA)\n            sock.send(b'OK')\n\n            data = sock.recv_all(len(B_DATA))\n            self.assertEqual(data, B_DATA)\n            sock.send(b'SPAM')\n\n            sock.close()\n\n        async def client(addr):\n            extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)\n\n            reader, writer = await asyncio.open_connection(\n                *addr,\n                ssl=client_sslctx,\n                server_hostname='',\n                **extras)\n\n            writer.write(A_DATA)\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            writer.write(B_DATA)\n            self.assertEqual(await reader.readexactly(4), b'SPAM')\n\n            nonlocal CNT\n            CNT += 1\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        async def client_sock(addr):\n            sock = socket.socket()\n            sock.connect(addr)\n            reader, writer = await asyncio.open_connection(\n                sock=sock,\n                ssl=client_sslctx,\n                server_hostname='')\n\n            writer.write(A_DATA)\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            writer.write(B_DATA)\n            self.assertEqual(await reader.readexactly(4), b'SPAM')\n\n            nonlocal CNT\n            CNT += 1\n\n            writer.close()\n            await self.wait_closed(writer)\n            sock.close()\n\n        def run(coro):\n            nonlocal CNT\n            CNT = 0\n\n            with self.tcp_server(server,\n                                 max_clients=TOTAL_CNT,\n                                 backlog=TOTAL_CNT) as srv:\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(coro(srv.addr))\n\n                self.loop.run_until_complete(asyncio.gather(*tasks))\n\n            self.assertEqual(CNT, TOTAL_CNT)\n\n        with self._silence_eof_received_warning():\n            run(client)\n\n        with self._silence_eof_received_warning():\n            run(client_sock)\n\n    def test_create_connection_ssl_slow_handshake(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        client_sslctx = self._create_client_ssl_context()\n\n        # silence error logger\n        self.loop.set_exception_handler(lambda *args: None)\n\n        def server(sock):\n            try:\n                sock.recv_all(1024 * 1024)\n            except ConnectionAbortedError:\n                pass\n            finally:\n                sock.close()\n\n        async def client(addr):\n            reader, writer = await asyncio.open_connection(\n                *addr,\n                ssl=client_sslctx,\n                server_hostname='',\n                ssl_handshake_timeout=1.0)\n            writer.close()\n            await self.wait_closed(writer)\n\n        with self.tcp_server(server,\n                             max_clients=1,\n                             backlog=1) as srv:\n\n            with self.assertRaisesRegex(\n                    ConnectionAbortedError,\n                    r'SSL handshake.*is taking longer'):\n\n                self.loop.run_until_complete(client(srv.addr))\n\n    def test_create_connection_ssl_failed_certificate(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        # silence error logger\n        self.loop.set_exception_handler(lambda *args: None)\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context(disable_verify=False)\n\n        def server(sock):\n            try:\n                sock.starttls(\n                    sslctx,\n                    server_side=True)\n                sock.connect()\n            except (ssl.SSLError, OSError):\n                pass\n            finally:\n                sock.close()\n\n        async def client(addr):\n            reader, writer = await asyncio.open_connection(\n                *addr,\n                ssl=client_sslctx,\n                server_hostname='',\n                ssl_handshake_timeout=1.0)\n            writer.close()\n            await self.wait_closed(writer)\n\n        with self.tcp_server(server,\n                             max_clients=1,\n                             backlog=1) as srv:\n\n            with self.assertRaises(ssl.SSLCertVerificationError):\n                self.loop.run_until_complete(client(srv.addr))\n\n    def test_start_tls_wrong_args(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        async def main():\n            with self.assertRaisesRegex(TypeError, 'SSLContext, got'):\n                await self.loop.start_tls(None, None, None)\n\n            sslctx = self._create_server_ssl_context(\n                self.ONLYCERT, self.ONLYKEY)\n            with self.assertRaisesRegex(TypeError, 'is not supported'):\n                await self.loop.start_tls(None, None, sslctx)\n\n        self.loop.run_until_complete(main())\n\n    def test_ssl_handshake_timeout(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        # bpo-29970: Check that a connection is aborted if handshake is not\n        # completed in timeout period, instead of remaining open indefinitely\n        client_sslctx = self._create_client_ssl_context()\n\n        # silence error logger\n        messages = []\n        self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx))\n\n        server_side_aborted = False\n\n        def server(sock):\n            nonlocal server_side_aborted\n            try:\n                sock.recv_all(1024 * 1024)\n            except ConnectionAbortedError:\n                server_side_aborted = True\n            finally:\n                sock.close()\n\n        async def client(addr):\n            await asyncio.wait_for(\n                self.loop.create_connection(\n                    asyncio.Protocol,\n                    *addr,\n                    ssl=client_sslctx,\n                    server_hostname='',\n                    ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT\n                ),\n                0.5\n            )\n\n        with self.tcp_server(server,\n                             max_clients=1,\n                             backlog=1) as srv:\n\n            with self.assertRaises(asyncio.TimeoutError):\n                self.loop.run_until_complete(client(srv.addr))\n\n        self.assertTrue(server_side_aborted)\n\n        # Python issue #23197: cancelling a handshake must not raise an\n        # exception or log an error, even if the handshake failed\n        self.assertEqual(messages, [])\n\n    def test_ssl_handshake_connection_lost(self):\n        # #246: make sure that no connection_lost() is called before\n        # connection_made() is called first\n\n        client_sslctx = self._create_client_ssl_context()\n\n        # silence error logger\n        self.loop.set_exception_handler(lambda loop, ctx: None)\n\n        connection_made_called = False\n        connection_lost_called = False\n\n        def server(sock):\n            sock.recv(1024)\n            # break the connection during handshake\n            sock.close()\n\n        class ClientProto(asyncio.Protocol):\n            def connection_made(self, transport):\n                nonlocal connection_made_called\n                connection_made_called = True\n\n            def connection_lost(self, exc):\n                nonlocal connection_lost_called\n                connection_lost_called = True\n\n        async def client(addr):\n            await self.loop.create_connection(\n                ClientProto,\n                *addr,\n                ssl=client_sslctx,\n                server_hostname=''),\n\n        with self.tcp_server(server,\n                             max_clients=1,\n                             backlog=1) as srv:\n\n            with self.assertRaises(ConnectionResetError):\n                self.loop.run_until_complete(client(srv.addr))\n\n        if connection_lost_called:\n            if connection_made_called:\n                self.fail(\"unexpected call to connection_lost()\")\n            else:\n                self.fail(\"unexpected call to connection_lost() without\"\n                          \"calling connection_made()\")\n        elif connection_made_called:\n            self.fail(\"unexpected call to connection_made()\")\n\n    def test_ssl_connect_accepted_socket(self):\n        if hasattr(ssl, 'PROTOCOL_TLS_SERVER'):\n            server_proto = ssl.PROTOCOL_TLS_SERVER\n            client_proto = ssl.PROTOCOL_TLS_CLIENT\n        else:\n            if hasattr(ssl, 'PROTOCOL_TLS'):\n                client_proto = server_proto = ssl.PROTOCOL_TLS\n            else:\n                client_proto = server_proto = ssl.PROTOCOL_SSLv23\n\n        server_context = ssl.SSLContext(server_proto)\n        server_context.load_cert_chain(self.ONLYCERT, self.ONLYKEY)\n        if hasattr(server_context, 'check_hostname'):\n            server_context.check_hostname = False\n        server_context.verify_mode = ssl.CERT_NONE\n\n        client_context = ssl.SSLContext(client_proto)\n        if hasattr(server_context, 'check_hostname'):\n            client_context.check_hostname = False\n        client_context.verify_mode = ssl.CERT_NONE\n\n        Test_UV_TCP.test_connect_accepted_socket(\n            self, server_context, client_context)\n\n    def test_start_tls_client_corrupted_ssl(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        self.loop.set_exception_handler(lambda loop, ctx: None)\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context()\n\n        def server(sock):\n            orig_sock = sock.dup()\n            try:\n                sock.starttls(\n                    sslctx,\n                    server_side=True)\n                sock.sendall(b'A\\n')\n                sock.recv_all(1)\n                orig_sock.send(b'please corrupt the SSL connection')\n            except ssl.SSLError:\n                pass\n            finally:\n                sock.close()\n                orig_sock.close()\n\n        async def client(addr):\n            reader, writer = await asyncio.open_connection(\n                *addr,\n                ssl=client_sslctx,\n                server_hostname='')\n\n            self.assertEqual(await reader.readline(), b'A\\n')\n            writer.write(b'B')\n            with self.assertRaises(ssl.SSLError):\n                await reader.readline()\n            writer.close()\n            try:\n                await self.wait_closed(writer)\n            except ssl.SSLError:\n                pass\n            return 'OK'\n\n        with self.tcp_server(server,\n                             max_clients=1,\n                             backlog=1) as srv:\n\n            res = self.loop.run_until_complete(client(srv.addr))\n\n        self.assertEqual(res, 'OK')\n\n    def test_start_tls_client_reg_proto_1(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        HELLO_MSG = b'1' * self.PAYLOAD_SIZE\n\n        server_context = self._create_server_ssl_context(\n            self.ONLYCERT, self.ONLYKEY)\n        client_context = self._create_client_ssl_context()\n\n        def serve(sock):\n            sock.settimeout(self.TIMEOUT)\n\n            data = sock.recv_all(len(HELLO_MSG))\n            self.assertEqual(len(data), len(HELLO_MSG))\n\n            sock.starttls(server_context, server_side=True)\n\n            sock.sendall(b'O')\n            data = sock.recv_all(len(HELLO_MSG))\n            self.assertEqual(len(data), len(HELLO_MSG))\n\n            sock.unwrap()\n            sock.close()\n\n        class ClientProto(asyncio.Protocol):\n            def __init__(self, on_data, on_eof):\n                self.on_data = on_data\n                self.on_eof = on_eof\n                self.con_made_cnt = 0\n\n            def connection_made(proto, tr):\n                proto.con_made_cnt += 1\n                # Ensure connection_made gets called only once.\n                self.assertEqual(proto.con_made_cnt, 1)\n\n            def data_received(self, data):\n                self.on_data.set_result(data)\n\n            def eof_received(self):\n                self.on_eof.set_result(True)\n\n        async def client(addr):\n            await asyncio.sleep(0.5)\n\n            on_data = self.loop.create_future()\n            on_eof = self.loop.create_future()\n\n            tr, proto = await self.loop.create_connection(\n                lambda: ClientProto(on_data, on_eof), *addr)\n\n            tr.write(HELLO_MSG)\n            new_tr = await self.loop.start_tls(tr, proto, client_context)\n\n            self.assertEqual(await on_data, b'O')\n            new_tr.write(HELLO_MSG)\n            await on_eof\n\n            new_tr.close()\n\n        with self.tcp_server(serve, timeout=self.TIMEOUT) as srv:\n            self.loop.run_until_complete(\n                asyncio.wait_for(client(srv.addr), timeout=10))\n\n    def test_create_connection_memory_leak(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        HELLO_MSG = b'1' * self.PAYLOAD_SIZE\n\n        server_context = self._create_server_ssl_context(\n            self.ONLYCERT, self.ONLYKEY)\n        client_context = self._create_client_ssl_context()\n\n        def serve(sock):\n            sock.settimeout(self.TIMEOUT)\n\n            sock.starttls(server_context, server_side=True)\n\n            sock.sendall(b'O')\n            data = sock.recv_all(len(HELLO_MSG))\n            self.assertEqual(len(data), len(HELLO_MSG))\n\n            sock.unwrap()\n            sock.close()\n\n        class ClientProto(asyncio.Protocol):\n            def __init__(self, on_data, on_eof):\n                self.on_data = on_data\n                self.on_eof = on_eof\n                self.con_made_cnt = 0\n\n            def connection_made(proto, tr):\n                # XXX: We assume user stores the transport in protocol\n                proto.tr = tr\n                proto.con_made_cnt += 1\n                # Ensure connection_made gets called only once.\n                self.assertEqual(proto.con_made_cnt, 1)\n\n            def data_received(self, data):\n                self.on_data.set_result(data)\n\n            def eof_received(self):\n                self.on_eof.set_result(True)\n\n        async def client(addr):\n            await asyncio.sleep(0.5)\n\n            on_data = self.loop.create_future()\n            on_eof = self.loop.create_future()\n\n            tr, proto = await self.loop.create_connection(\n                lambda: ClientProto(on_data, on_eof), *addr,\n                ssl=client_context)\n\n            self.assertEqual(await on_data, b'O')\n            tr.write(HELLO_MSG)\n            await on_eof\n\n            tr.close()\n\n        with self.tcp_server(serve, timeout=self.TIMEOUT) as srv:\n            self.loop.run_until_complete(\n                asyncio.wait_for(client(srv.addr), timeout=10))\n\n        # No garbage is left for SSL client from loop.create_connection, even\n        # if user stores the SSLTransport in corresponding protocol instance\n        client_context = weakref.ref(client_context)\n        self.assertIsNone(client_context())\n\n    def test_start_tls_client_buf_proto_1(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        HELLO_MSG = b'1' * self.PAYLOAD_SIZE\n\n        server_context = self._create_server_ssl_context(\n            self.ONLYCERT, self.ONLYKEY)\n        client_context = self._create_client_ssl_context()\n\n        client_con_made_calls = 0\n\n        def serve(sock):\n            sock.settimeout(self.TIMEOUT)\n\n            data = sock.recv_all(len(HELLO_MSG))\n            self.assertEqual(len(data), len(HELLO_MSG))\n\n            sock.starttls(server_context, server_side=True)\n\n            sock.sendall(b'O')\n            data = sock.recv_all(len(HELLO_MSG))\n            self.assertEqual(len(data), len(HELLO_MSG))\n\n            sock.sendall(b'2')\n            data = sock.recv_all(len(HELLO_MSG))\n            self.assertEqual(len(data), len(HELLO_MSG))\n\n            sock.unwrap()\n            sock.close()\n\n        class ClientProtoFirst(asyncio.BaseProtocol):\n            def __init__(self, on_data):\n                self.on_data = on_data\n                self.buf = bytearray(1)\n\n            def connection_made(self, tr):\n                nonlocal client_con_made_calls\n                client_con_made_calls += 1\n\n            def get_buffer(self, sizehint):\n                return self.buf\n\n            def buffer_updated(self, nsize):\n                assert nsize == 1\n                self.on_data.set_result(bytes(self.buf[:nsize]))\n\n            def eof_received(self):\n                pass\n\n        class ClientProtoSecond(asyncio.Protocol):\n            def __init__(self, on_data, on_eof):\n                self.on_data = on_data\n                self.on_eof = on_eof\n                self.con_made_cnt = 0\n\n            def connection_made(self, tr):\n                nonlocal client_con_made_calls\n                client_con_made_calls += 1\n\n            def data_received(self, data):\n                self.on_data.set_result(data)\n\n            def eof_received(self):\n                self.on_eof.set_result(True)\n\n        async def client(addr):\n            await asyncio.sleep(0.5)\n\n            on_data1 = self.loop.create_future()\n            on_data2 = self.loop.create_future()\n            on_eof = self.loop.create_future()\n\n            tr, proto = await self.loop.create_connection(\n                lambda: ClientProtoFirst(on_data1), *addr)\n\n            tr.write(HELLO_MSG)\n            new_tr = await self.loop.start_tls(tr, proto, client_context)\n\n            self.assertEqual(await on_data1, b'O')\n            new_tr.write(HELLO_MSG)\n\n            new_tr.set_protocol(ClientProtoSecond(on_data2, on_eof))\n            self.assertEqual(await on_data2, b'2')\n            new_tr.write(HELLO_MSG)\n            await on_eof\n\n            new_tr.close()\n\n            # connection_made() should be called only once -- when\n            # we establish connection for the first time. Start TLS\n            # doesn't call connection_made() on application protocols.\n            self.assertEqual(client_con_made_calls, 1)\n\n        with self.tcp_server(serve, timeout=self.TIMEOUT) as srv:\n            self.loop.run_until_complete(\n                asyncio.wait_for(client(srv.addr),\n                                 timeout=self.TIMEOUT))\n\n    def test_start_tls_slow_client_cancel(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        HELLO_MSG = b'1' * self.PAYLOAD_SIZE\n\n        client_context = self._create_client_ssl_context()\n        server_waits_on_handshake = self.loop.create_future()\n\n        def serve(sock):\n            sock.settimeout(self.TIMEOUT)\n\n            data = sock.recv_all(len(HELLO_MSG))\n            self.assertEqual(len(data), len(HELLO_MSG))\n\n            try:\n                self.loop.call_soon_threadsafe(\n                    server_waits_on_handshake.set_result, None)\n                data = sock.recv_all(1024 * 1024)\n            except ConnectionAbortedError:\n                pass\n            finally:\n                sock.close()\n\n        class ClientProto(asyncio.Protocol):\n            def __init__(self, on_data, on_eof):\n                self.on_data = on_data\n                self.on_eof = on_eof\n                self.con_made_cnt = 0\n\n            def connection_made(proto, tr):\n                proto.con_made_cnt += 1\n                # Ensure connection_made gets called only once.\n                self.assertEqual(proto.con_made_cnt, 1)\n\n            def data_received(self, data):\n                self.on_data.set_result(data)\n\n            def eof_received(self):\n                self.on_eof.set_result(True)\n\n        async def client(addr):\n            await asyncio.sleep(0.5)\n\n            on_data = self.loop.create_future()\n            on_eof = self.loop.create_future()\n\n            tr, proto = await self.loop.create_connection(\n                lambda: ClientProto(on_data, on_eof), *addr)\n\n            tr.write(HELLO_MSG)\n\n            await server_waits_on_handshake\n\n            with self.assertRaises(asyncio.TimeoutError):\n                await asyncio.wait_for(\n                    self.loop.start_tls(tr, proto, client_context),\n                    0.5)\n\n        with self.tcp_server(serve, timeout=self.TIMEOUT) as srv:\n            self.loop.run_until_complete(\n                asyncio.wait_for(client(srv.addr), timeout=10))\n\n    def test_start_tls_server_1(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        HELLO_MSG = b'1' * self.PAYLOAD_SIZE\n\n        server_context = self._create_server_ssl_context(\n            self.ONLYCERT, self.ONLYKEY)\n        client_context = self._create_client_ssl_context()\n\n        def client(sock, addr):\n            sock.settimeout(self.TIMEOUT)\n\n            sock.connect(addr)\n            data = sock.recv_all(len(HELLO_MSG))\n            self.assertEqual(len(data), len(HELLO_MSG))\n\n            sock.starttls(client_context)\n            sock.sendall(HELLO_MSG)\n\n            sock.unwrap()\n            sock.close()\n\n        class ServerProto(asyncio.Protocol):\n            def __init__(self, on_con, on_eof, on_con_lost):\n                self.on_con = on_con\n                self.on_eof = on_eof\n                self.on_con_lost = on_con_lost\n                self.data = b''\n\n            def connection_made(self, tr):\n                self.on_con.set_result(tr)\n\n            def data_received(self, data):\n                self.data += data\n\n            def eof_received(self):\n                self.on_eof.set_result(1)\n\n            def connection_lost(self, exc):\n                if exc is None:\n                    self.on_con_lost.set_result(None)\n                else:\n                    self.on_con_lost.set_exception(exc)\n\n        async def main(proto, on_con, on_eof, on_con_lost):\n            tr = await on_con\n            tr.write(HELLO_MSG)\n\n            self.assertEqual(proto.data, b'')\n\n            new_tr = await self.loop.start_tls(\n                tr, proto, server_context,\n                server_side=True,\n                ssl_handshake_timeout=self.TIMEOUT)\n\n            await on_eof\n            await on_con_lost\n            self.assertEqual(proto.data, HELLO_MSG)\n            new_tr.close()\n\n        async def run_main():\n            on_con = self.loop.create_future()\n            on_eof = self.loop.create_future()\n            on_con_lost = self.loop.create_future()\n            proto = ServerProto(on_con, on_eof, on_con_lost)\n\n            server = await self.loop.create_server(\n                lambda: proto, '127.0.0.1', 0)\n            addr = server.sockets[0].getsockname()\n\n            with self.tcp_client(lambda sock: client(sock, addr),\n                                 timeout=self.TIMEOUT):\n                await asyncio.wait_for(\n                    main(proto, on_con, on_eof, on_con_lost),\n                    timeout=self.TIMEOUT)\n\n            server.close()\n            await server.wait_closed()\n\n        self.loop.run_until_complete(run_main())\n\n    def test_create_server_ssl_over_ssl(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest('asyncio does not support SSL over SSL')\n\n        CNT = 0           # number of clients that were successful\n        TOTAL_CNT = 25    # total number of clients that test will create\n        TIMEOUT = 60.0    # timeout for this test\n\n        A_DATA = b'A' * 1024 * 1024\n        B_DATA = b'B' * 1024 * 1024\n\n        sslctx_1 = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx_1 = self._create_client_ssl_context()\n        sslctx_2 = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx_2 = self._create_client_ssl_context()\n\n        clients = []\n\n        async def handle_client(reader, writer):\n            nonlocal CNT\n\n            data = await reader.readexactly(len(A_DATA))\n            self.assertEqual(data, A_DATA)\n            writer.write(b'OK')\n\n            data = await reader.readexactly(len(B_DATA))\n            self.assertEqual(data, B_DATA)\n            writer.writelines([b'SP', bytearray(b'A'), memoryview(b'M')])\n\n            await writer.drain()\n            writer.close()\n\n            CNT += 1\n\n        class ServerProtocol(asyncio.StreamReaderProtocol):\n            def connection_made(self, transport):\n                super_ = super()\n                transport.pause_reading()\n                fut = self._loop.create_task(self._loop.start_tls(\n                    transport, self, sslctx_2, server_side=True))\n\n                def cb(_):\n                    try:\n                        tr = fut.result()\n                    except Exception as ex:\n                        super_.connection_lost(ex)\n                    else:\n                        super_.connection_made(tr)\n                fut.add_done_callback(cb)\n\n        def server_protocol_factory():\n            reader = asyncio.StreamReader()\n            protocol = ServerProtocol(reader, handle_client)\n            return protocol\n\n        async def test_client(addr):\n            fut = asyncio.Future()\n\n            def prog(sock):\n                try:\n                    sock.connect(addr)\n                    sock.starttls(client_sslctx_1)\n\n                    # because wrap_socket() doesn't work correctly on\n                    # SSLSocket, we have to do the 2nd level SSL manually\n                    incoming = ssl.MemoryBIO()\n                    outgoing = ssl.MemoryBIO()\n                    sslobj = client_sslctx_2.wrap_bio(incoming, outgoing)\n\n                    def do(func, *args):\n                        while True:\n                            try:\n                                rv = func(*args)\n                                break\n                            except ssl.SSLWantReadError:\n                                if outgoing.pending:\n                                    sock.send(outgoing.read())\n                                incoming.write(sock.recv(65536))\n                        if outgoing.pending:\n                            sock.send(outgoing.read())\n                        return rv\n\n                    do(sslobj.do_handshake)\n\n                    do(sslobj.write, A_DATA)\n                    data = do(sslobj.read, 2)\n                    self.assertEqual(data, b'OK')\n\n                    do(sslobj.write, B_DATA)\n                    data = b''\n                    while True:\n                        chunk = do(sslobj.read, 4)\n                        if not chunk:\n                            break\n                        data += chunk\n                    self.assertEqual(data, b'SPAM')\n\n                    do(sslobj.unwrap)\n                    sock.close()\n\n                except Exception as ex:\n                    self.loop.call_soon_threadsafe(fut.set_exception, ex)\n                    sock.close()\n                else:\n                    self.loop.call_soon_threadsafe(fut.set_result, None)\n\n            client = self.tcp_client(prog)\n            client.start()\n            clients.append(client)\n\n            await fut\n\n        async def start_server():\n            extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)\n\n            srv = await self.loop.create_server(\n                server_protocol_factory,\n                '127.0.0.1', 0,\n                family=socket.AF_INET,\n                ssl=sslctx_1,\n                **extras)\n\n            try:\n                srv_socks = srv.sockets\n                self.assertTrue(srv_socks)\n\n                addr = srv_socks[0].getsockname()\n\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(test_client(addr))\n\n                await asyncio.wait_for(asyncio.gather(*tasks), TIMEOUT)\n\n            finally:\n                self.loop.call_soon(srv.close)\n                await srv.wait_closed()\n\n        with self._silence_eof_received_warning():\n            self.loop.run_until_complete(start_server())\n\n        self.assertEqual(CNT, TOTAL_CNT)\n\n        for client in clients:\n            client.stop()\n\n    def test_renegotiation(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest('asyncio does not support renegotiation')\n\n        CNT = 0\n        TOTAL_CNT = 25\n\n        A_DATA = b'A' * 1024 * 1024\n        B_DATA = b'B' * 1024 * 1024\n\n        sslctx = openssl_ssl.Context(openssl_ssl.TLSv1_2_METHOD)\n        if hasattr(openssl_ssl, 'OP_NO_SSLV2'):\n            sslctx.set_options(openssl_ssl.OP_NO_SSLV2)\n        sslctx.use_privatekey_file(self.ONLYKEY)\n        sslctx.use_certificate_chain_file(self.ONLYCERT)\n        client_sslctx = self._create_client_ssl_context()\n        client_sslctx.maximum_version = ssl.TLSVersion.TLSv1_2\n\n        def server(sock):\n            conn = openssl_ssl.Connection(sslctx, sock)\n            conn.set_accept_state()\n\n            data = b''\n            while len(data) < len(A_DATA):\n                try:\n                    chunk = conn.recv(len(A_DATA) - len(data))\n                    if not chunk:\n                        break\n                    data += chunk\n                except openssl_ssl.WantReadError:\n                    pass\n            self.assertEqual(data, A_DATA)\n            conn.renegotiate()\n            if conn.renegotiate_pending():\n                conn.send(b'OK')\n            else:\n                conn.send(b'ER')\n\n            data = b''\n            while len(data) < len(B_DATA):\n                try:\n                    chunk = conn.recv(len(B_DATA) - len(data))\n                    if not chunk:\n                        break\n                    data += chunk\n                except openssl_ssl.WantReadError:\n                    pass\n            self.assertEqual(data, B_DATA)\n            if conn.renegotiate_pending():\n                conn.send(b'ERRO')\n            else:\n                conn.send(b'SPAM')\n\n            conn.shutdown()\n\n        async def client(addr):\n            extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)\n\n            reader, writer = await asyncio.open_connection(\n                *addr,\n                ssl=client_sslctx,\n                server_hostname='',\n                **extras)\n\n            writer.write(A_DATA)\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            writer.write(B_DATA)\n            self.assertEqual(await reader.readexactly(4), b'SPAM')\n\n            nonlocal CNT\n            CNT += 1\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        async def client_sock(addr):\n            sock = socket.socket()\n            sock.connect(addr)\n            reader, writer = await asyncio.open_connection(\n                sock=sock,\n                ssl=client_sslctx,\n                server_hostname='')\n\n            writer.write(A_DATA)\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            writer.write(B_DATA)\n            self.assertEqual(await reader.readexactly(4), b'SPAM')\n\n            nonlocal CNT\n            CNT += 1\n\n            writer.close()\n            await self.wait_closed(writer)\n            sock.close()\n\n        def run(coro):\n            nonlocal CNT\n            CNT = 0\n\n            with self.tcp_server(server,\n                                 max_clients=TOTAL_CNT,\n                                 backlog=TOTAL_CNT) as srv:\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(coro(srv.addr))\n\n                self.loop.run_until_complete(\n                    asyncio.gather(*tasks))\n\n            self.assertEqual(CNT, TOTAL_CNT)\n\n        with self._silence_eof_received_warning():\n            run(client)\n\n        with self._silence_eof_received_warning():\n            run(client_sock)\n\n    def test_shutdown_timeout(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        CNT = 0           # number of clients that were successful\n        TOTAL_CNT = 25    # total number of clients that test will create\n        TIMEOUT = 10.0    # timeout for this test\n\n        A_DATA = b'A' * 1024 * 1024\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context()\n\n        clients = []\n\n        async def handle_client(reader, writer):\n            nonlocal CNT\n\n            data = await reader.readexactly(len(A_DATA))\n            self.assertEqual(data, A_DATA)\n            writer.write(b'OK')\n            await writer.drain()\n            writer.close()\n            with self.assertRaisesRegex(asyncio.TimeoutError,\n                                        'SSL shutdown timed out'):\n                await reader.read()\n            CNT += 1\n\n        async def test_client(addr):\n            fut = asyncio.Future()\n\n            def prog(sock):\n                try:\n                    sock.starttls(client_sslctx)\n                    sock.connect(addr)\n                    sock.send(A_DATA)\n\n                    data = sock.recv_all(2)\n                    self.assertEqual(data, b'OK')\n\n                    data = sock.recv(1024)\n                    self.assertEqual(data, b'')\n\n                    fd = sock.detach()\n                    try:\n                        select.select([fd], [], [], 3)\n                    finally:\n                        os.close(fd)\n\n                except Exception as ex:\n                    self.loop.call_soon_threadsafe(fut.set_exception, ex)\n                else:\n                    self.loop.call_soon_threadsafe(fut.set_result, None)\n\n            client = self.tcp_client(prog)\n            client.start()\n            clients.append(client)\n\n            await fut\n\n        async def start_server():\n            extras = {'ssl_handshake_timeout': SSL_HANDSHAKE_TIMEOUT}\n            if self.implementation != 'asyncio':  # or self.PY38\n                extras['ssl_shutdown_timeout'] = 0.5\n\n            srv = await asyncio.start_server(\n                handle_client,\n                '127.0.0.1', 0,\n                family=socket.AF_INET,\n                ssl=sslctx,\n                **extras)\n\n            try:\n                srv_socks = srv.sockets\n                self.assertTrue(srv_socks)\n\n                addr = srv_socks[0].getsockname()\n\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(test_client(addr))\n\n                await asyncio.wait_for(\n                    asyncio.gather(*tasks),\n                    TIMEOUT)\n\n            finally:\n                self.loop.call_soon(srv.close)\n                await srv.wait_closed()\n\n        with self._silence_eof_received_warning():\n            self.loop.run_until_complete(start_server())\n\n        self.assertEqual(CNT, TOTAL_CNT)\n\n        for client in clients:\n            client.stop()\n\n    def test_shutdown_cleanly(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        CNT = 0\n        TOTAL_CNT = 25\n\n        A_DATA = b'A' * 1024 * 1024\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context()\n\n        def server(sock):\n            sock.starttls(\n                sslctx,\n                server_side=True)\n\n            data = sock.recv_all(len(A_DATA))\n            self.assertEqual(data, A_DATA)\n            sock.send(b'OK')\n\n            sock.unwrap()\n\n            sock.close()\n\n        async def client(addr):\n            extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)\n\n            reader, writer = await asyncio.open_connection(\n                *addr,\n                ssl=client_sslctx,\n                server_hostname='',\n                **extras)\n\n            writer.write(A_DATA)\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            self.assertEqual(await reader.read(), b'')\n\n            nonlocal CNT\n            CNT += 1\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        def run(coro):\n            nonlocal CNT\n            CNT = 0\n\n            with self.tcp_server(server,\n                                 max_clients=TOTAL_CNT,\n                                 backlog=TOTAL_CNT) as srv:\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(coro(srv.addr))\n\n                self.loop.run_until_complete(\n                    asyncio.gather(*tasks))\n\n            self.assertEqual(CNT, TOTAL_CNT)\n\n        with self._silence_eof_received_warning():\n            run(client)\n\n    def test_write_to_closed_transport(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context()\n        future = None\n\n        def server(sock):\n            sock.starttls(sslctx, server_side=True)\n            sock.shutdown(socket.SHUT_RDWR)\n            sock.close()\n\n        def unwrap_server(sock):\n            sock.starttls(sslctx, server_side=True)\n            while True:\n                try:\n                    sock.unwrap()\n                    break\n                except ssl.SSLError as ex:\n                    # Since OpenSSL 1.1.1, it raises \"application data after\n                    # close notify\"\n                    # Python < 3.8:\n                    if ex.reason == 'KRB5_S_INIT':\n                        break\n                    # Python >= 3.8:\n                    if ex.reason == 'APPLICATION_DATA_AFTER_CLOSE_NOTIFY':\n                        break\n                    raise ex\n                except OSError as ex:\n                    # OpenSSL < 1.1.1\n                    if ex.errno != 0:\n                        raise\n            sock.close()\n\n        async def client(addr):\n            nonlocal future\n            future = self.loop.create_future()\n\n            reader, writer = await asyncio.open_connection(\n                *addr,\n                ssl=client_sslctx,\n                server_hostname='')\n            writer.write(b'I AM WRITING NOWHERE1' * 100)\n\n            try:\n                data = await reader.read()\n                self.assertEqual(data, b'')\n            except (ConnectionResetError, BrokenPipeError):\n                pass\n\n            for i in range(25):\n                writer.write(b'I AM WRITING NOWHERE2' * 100)\n\n            self.assertEqual(\n                writer.transport.get_write_buffer_size(), 0)\n\n            await future\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        def run(meth):\n            def wrapper(sock):\n                try:\n                    meth(sock)\n                except Exception as ex:\n                    self.loop.call_soon_threadsafe(future.set_exception, ex)\n                else:\n                    self.loop.call_soon_threadsafe(future.set_result, None)\n            return wrapper\n\n        with self._silence_eof_received_warning():\n            with self.tcp_server(run(server)) as srv:\n                self.loop.run_until_complete(client(srv.addr))\n\n            with self.tcp_server(run(unwrap_server)) as srv:\n                self.loop.run_until_complete(client(srv.addr))\n\n    def test_flush_before_shutdown(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        CHUNK = 1024 * 128\n        SIZE = 32\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        sslctx_openssl = openssl_ssl.Context(openssl_ssl.TLSv1_2_METHOD)\n        if hasattr(openssl_ssl, 'OP_NO_SSLV2'):\n            sslctx_openssl.set_options(openssl_ssl.OP_NO_SSLV2)\n        sslctx_openssl.use_privatekey_file(self.ONLYKEY)\n        sslctx_openssl.use_certificate_chain_file(self.ONLYCERT)\n        client_sslctx = self._create_client_ssl_context()\n        client_sslctx.maximum_version = ssl.TLSVersion.TLSv1_2\n\n        future = None\n\n        def server(sock):\n            sock.starttls(sslctx, server_side=True)\n            self.assertEqual(sock.recv_all(4), b'ping')\n            sock.send(b'pong')\n            time.sleep(0.5)  # hopefully stuck the TCP buffer\n            data = sock.recv_all(CHUNK * SIZE)\n            self.assertEqual(len(data), CHUNK * SIZE)\n            sock.close()\n\n        def run(meth):\n            def wrapper(sock):\n                try:\n                    meth(sock)\n                except Exception as ex:\n                    self.loop.call_soon_threadsafe(future.set_exception, ex)\n                else:\n                    self.loop.call_soon_threadsafe(future.set_result, None)\n            return wrapper\n\n        async def client(addr):\n            nonlocal future\n            future = self.loop.create_future()\n            reader, writer = await asyncio.open_connection(\n                *addr,\n                ssl=client_sslctx,\n                server_hostname='')\n            sslprotocol = writer.get_extra_info('uvloop.sslproto')\n            writer.write(b'ping')\n            data = await reader.readexactly(4)\n            self.assertEqual(data, b'pong')\n\n            sslprotocol.pause_writing()\n            for _ in range(SIZE):\n                writer.write(b'x' * CHUNK)\n\n            writer.close()\n            sslprotocol.resume_writing()\n\n            await self.wait_closed(writer)\n            try:\n                data = await reader.read()\n                self.assertEqual(data, b'')\n            except ConnectionResetError:\n                pass\n            await future\n\n        with self.tcp_server(run(server)) as srv:\n            self.loop.run_until_complete(client(srv.addr))\n\n    def test_remote_shutdown_receives_trailing_data(self):\n        if sys.platform == 'linux' and sys.version_info < (3, 11):\n            # TODO: started hanging and needs to be diagnosed.\n            raise unittest.SkipTest()\n\n        CHUNK = 1024 * 16\n        SIZE = 8\n        count = 0\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context()\n        future = None\n        filled = threading.Lock()\n        eof_received = threading.Lock()\n\n        def server(sock):\n            incoming = ssl.MemoryBIO()\n            outgoing = ssl.MemoryBIO()\n            sslobj = sslctx.wrap_bio(incoming, outgoing, server_side=True)\n\n            while True:\n                try:\n                    sslobj.do_handshake()\n                except ssl.SSLWantReadError:\n                    if outgoing.pending:\n                        sock.send(outgoing.read())\n                    incoming.write(sock.recv(16384))\n                else:\n                    if outgoing.pending:\n                        sock.send(outgoing.read())\n                    break\n\n            while True:\n                try:\n                    data = sslobj.read(4)\n                except ssl.SSLWantReadError:\n                    incoming.write(sock.recv(16384))\n                else:\n                    break\n\n            self.assertEqual(data, b'ping')\n            sslobj.write(b'pong')\n            sock.send(outgoing.read())\n\n            data_len = 0\n\n            with filled:\n                # trigger peer's resume_writing()\n                incoming.write(sock.recv(65536 * 4))\n                while True:\n                    try:\n                        chunk = len(sslobj.read(16384))\n                        data_len += chunk\n                    except ssl.SSLWantReadError:\n                        break\n\n                # send close_notify but don't wait for response\n                with self.assertRaises(ssl.SSLWantReadError):\n                    sslobj.unwrap()\n                sock.send(outgoing.read())\n\n            with eof_received:\n                # should receive all data\n                while True:\n                    try:\n                        chunk = len(sslobj.read(16384))\n                        data_len += chunk\n                    except ssl.SSLWantReadError:\n                        incoming.write(sock.recv(16384))\n                        if not incoming.pending:\n                            # EOF received\n                            break\n                    except ssl.SSLZeroReturnError:\n                        break\n\n            self.assertEqual(data_len, CHUNK * count)\n\n            if self.implementation == 'uvloop':\n                # Verify that close_notify is received. asyncio is currently\n                # not guaranteed to send close_notify before dropping off\n                sslobj.unwrap()\n\n            sock.close()\n\n        async def client(addr):\n            nonlocal future, count\n            future = self.loop.create_future()\n\n            with eof_received:\n                with filled:\n                    reader, writer = await asyncio.open_connection(\n                        *addr,\n                        ssl=client_sslctx,\n                        server_hostname='')\n                    writer.write(b'ping')\n                    data = await reader.readexactly(4)\n                    self.assertEqual(data, b'pong')\n\n                    count = 0\n                    try:\n                        while True:\n                            writer.write(b'x' * CHUNK)\n                            count += 1\n                            await asyncio.wait_for(\n                                asyncio.ensure_future(writer.drain()), 0.5)\n                    except asyncio.TimeoutError:\n                        # fill write backlog in a hacky way for uvloop\n                        if self.implementation == 'uvloop':\n                            for _ in range(SIZE):\n                                writer.transport._test__append_write_backlog(\n                                    b'x' * CHUNK)\n                                count += 1\n\n                data = await reader.read()\n                self.assertEqual(data, b'')\n\n            await future\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        def run(meth):\n            def wrapper(sock):\n                try:\n                    meth(sock)\n                except Exception as ex:\n                    self.loop.call_soon_threadsafe(future.set_exception, ex)\n                else:\n                    self.loop.call_soon_threadsafe(future.set_result, None)\n            return wrapper\n\n        with self.tcp_server(run(server)) as srv:\n            self.loop.run_until_complete(client(srv.addr))\n\n    def test_connect_timeout_warning(self):\n        s = socket.socket(socket.AF_INET)\n        s.bind(('127.0.0.1', 0))\n        addr = s.getsockname()\n\n        async def test():\n            try:\n                await asyncio.wait_for(\n                    self.loop.create_connection(asyncio.Protocol,\n                                                *addr, ssl=True),\n                    0.1)\n            except (ConnectionRefusedError, asyncio.TimeoutError):\n                pass\n            else:\n                self.fail('TimeoutError is not raised')\n\n        with s:\n            try:\n                with self.assertWarns(ResourceWarning) as cm:\n                    self.loop.run_until_complete(test())\n                    gc.collect()\n                    gc.collect()\n                    gc.collect()\n            except AssertionError as e:\n                self.assertEqual(str(e), 'ResourceWarning not triggered')\n            else:\n                self.fail('Unexpected ResourceWarning: {}'.format(cm.warning))\n\n    def test_handshake_timeout_handler_leak(self):\n        if self.implementation == 'asyncio':\n            # Okay this turns out to be an issue for asyncio.sslproto too\n            raise unittest.SkipTest()\n\n        s = socket.socket(socket.AF_INET)\n        s.bind(('127.0.0.1', 0))\n        s.listen(1)\n        addr = s.getsockname()\n\n        async def test(ctx):\n            try:\n                await asyncio.wait_for(\n                    self.loop.create_connection(asyncio.Protocol, *addr,\n                                                ssl=ctx),\n                    0.1)\n            except (ConnectionRefusedError, asyncio.TimeoutError):\n                pass\n            else:\n                self.fail('TimeoutError is not raised')\n\n        with s:\n            ctx = ssl.create_default_context()\n            self.loop.run_until_complete(test(ctx))\n            ctx = weakref.ref(ctx)\n\n        # SSLProtocol should be DECREF to 0\n        self.assertIsNone(ctx())\n\n    def test_shutdown_timeout_handler_leak(self):\n        loop = self.loop\n\n        def server(sock):\n            sslctx = self._create_server_ssl_context(self.ONLYCERT,\n                                                     self.ONLYKEY)\n            sock = sslctx.wrap_socket(sock, server_side=True)\n            sock.recv(32)\n            sock.close()\n\n        class Protocol(asyncio.Protocol):\n            def __init__(self):\n                self.fut = asyncio.Future(loop=loop)\n\n            def connection_lost(self, exc):\n                self.fut.set_result(None)\n\n        async def client(addr, ctx):\n            tr, pr = await loop.create_connection(Protocol, *addr, ssl=ctx)\n            tr.close()\n            await pr.fut\n\n        with self.tcp_server(server) as srv:\n            ctx = self._create_client_ssl_context()\n            loop.run_until_complete(client(srv.addr, ctx))\n            ctx = weakref.ref(ctx)\n\n        if self.implementation == 'asyncio':\n            # asyncio has no shutdown timeout, but it ends up with a circular\n            # reference loop - not ideal (introduces gc glitches), but at least\n            # not leaking\n            gc.collect()\n            gc.collect()\n            gc.collect()\n\n        # SSLProtocol should be DECREF to 0\n        self.assertIsNone(ctx())\n\n    def test_shutdown_timeout_handler_not_set(self):\n        if self.implementation == 'asyncio':\n            # asyncio doesn't call SSL eof_received() so we can't run this test\n            raise unittest.SkipTest()\n\n        loop = self.loop\n        extra = None\n\n        def server(sock):\n            sslctx = self._create_server_ssl_context(self.ONLYCERT,\n                                                     self.ONLYKEY)\n            sock = sslctx.wrap_socket(sock, server_side=True)\n            sock.send(b'hello')\n            assert sock.recv(1024) == b'world'\n            sock.send(b'extra bytes')\n            # sending EOF here\n            sock.shutdown(socket.SHUT_WR)\n            # make sure we have enough time to reproduce the issue\n            self.assertEqual(sock.recv(1024), b'')\n            sock.close()\n\n        class Protocol(asyncio.Protocol):\n            def __init__(self):\n                self.fut = asyncio.Future(loop=loop)\n                self.transport = None\n\n            def connection_made(self, transport):\n                self.transport = transport\n\n            def data_received(self, data):\n                if data == b'hello':\n                    self.transport.write(b'world')\n                    # pause reading would make incoming data stay in the sslobj\n                    self.transport.pause_reading()\n                else:\n                    nonlocal extra\n                    extra = data\n\n            def connection_lost(self, exc):\n                if exc is None:\n                    self.fut.set_result(None)\n                else:\n                    self.fut.set_exception(exc)\n\n            def eof_received(self):\n                self.transport.resume_reading()\n\n        async def client(addr):\n            ctx = self._create_client_ssl_context()\n            tr, pr = await loop.create_connection(Protocol, *addr, ssl=ctx)\n            await pr.fut\n            tr.close()\n            # extra data received after transport.close() should be ignored\n            self.assertIsNone(extra)\n\n        with self.tcp_server(server) as srv:\n            loop.run_until_complete(client(srv.addr))\n\n    def test_shutdown_while_pause_reading(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        loop = self.loop\n        conn_made = loop.create_future()\n        eof_recvd = loop.create_future()\n        conn_lost = loop.create_future()\n        data_recv = False\n\n        def server(sock):\n            sslctx = self._create_server_ssl_context(self.ONLYCERT,\n                                                     self.ONLYKEY)\n            incoming = ssl.MemoryBIO()\n            outgoing = ssl.MemoryBIO()\n            sslobj = sslctx.wrap_bio(incoming, outgoing, server_side=True)\n\n            while True:\n                try:\n                    sslobj.do_handshake()\n                    sslobj.write(b'trailing data')\n                    break\n                except ssl.SSLWantReadError:\n                    if outgoing.pending:\n                        sock.send(outgoing.read())\n                    incoming.write(sock.recv(16384))\n            if outgoing.pending:\n                sock.send(outgoing.read())\n\n            while True:\n                try:\n                    self.assertEqual(sslobj.read(), b'')  # close_notify\n                    break\n                except ssl.SSLWantReadError:\n                    incoming.write(sock.recv(16384))\n\n            while True:\n                try:\n                    sslobj.unwrap()\n                except ssl.SSLWantReadError:\n                    if outgoing.pending:\n                        sock.send(outgoing.read())\n                    incoming.write(sock.recv(16384))\n                else:\n                    if outgoing.pending:\n                        sock.send(outgoing.read())\n                    break\n\n            self.assertEqual(sock.recv(16384), b'')  # socket closed\n\n        class Protocol(asyncio.Protocol):\n            def connection_made(self, transport):\n                conn_made.set_result(None)\n\n            def data_received(self, data):\n                nonlocal data_recv\n                data_recv = True\n\n            def eof_received(self):\n                eof_recvd.set_result(None)\n\n            def connection_lost(self, exc):\n                if exc is None:\n                    conn_lost.set_result(None)\n                else:\n                    conn_lost.set_exception(exc)\n\n        async def client(addr):\n            ctx = self._create_client_ssl_context()\n            tr, _ = await loop.create_connection(Protocol, *addr, ssl=ctx)\n            await conn_made\n            self.assertFalse(data_recv)\n\n            tr.pause_reading()\n            tr.close()\n\n            await asyncio.wait_for(eof_recvd, 10)\n            await asyncio.wait_for(conn_lost, 10)\n\n        with self.tcp_server(server) as srv:\n            loop.run_until_complete(client(srv.addr))\n\n    def test_bpo_39951_discard_trailing_data(self):\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context()\n        future = None\n        close_notify = threading.Lock()\n\n        def server(sock):\n            incoming = ssl.MemoryBIO()\n            outgoing = ssl.MemoryBIO()\n            sslobj = sslctx.wrap_bio(incoming, outgoing, server_side=True)\n\n            while True:\n                try:\n                    sslobj.do_handshake()\n                except ssl.SSLWantReadError:\n                    if outgoing.pending:\n                        sock.send(outgoing.read())\n                    incoming.write(sock.recv(16384))\n                else:\n                    if outgoing.pending:\n                        sock.send(outgoing.read())\n                    break\n\n            while True:\n                try:\n                    data = sslobj.read(4)\n                except ssl.SSLWantReadError:\n                    incoming.write(sock.recv(16384))\n                else:\n                    break\n\n            self.assertEqual(data, b'ping')\n            sslobj.write(b'pong')\n            sock.send(outgoing.read())\n\n            with close_notify:\n                sslobj.write(b'trailing')\n                sock.send(outgoing.read())\n                time.sleep(0.5)  # allow time for the client to receive\n\n            incoming.write(sock.recv(16384))\n            sslobj.unwrap()\n            sock.send(outgoing.read())\n            sock.close()\n\n        async def client(addr):\n            nonlocal future\n            future = self.loop.create_future()\n\n            with close_notify:\n                reader, writer = await asyncio.open_connection(\n                    *addr,\n                    ssl=client_sslctx,\n                    server_hostname='')\n                writer.write(b'ping')\n                data = await reader.readexactly(4)\n                self.assertEqual(data, b'pong')\n\n                writer.close()\n\n            try:\n                await self.wait_closed(writer)\n            except ssl.SSLError as e:\n                if self.implementation == 'asyncio' and \\\n                        'application data after close notify' in str(e):\n                    raise unittest.SkipTest('bpo-39951')\n                raise\n            await future\n\n        def run(meth):\n            def wrapper(sock):\n                try:\n                    meth(sock)\n                except Exception as ex:\n                    self.loop.call_soon_threadsafe(future.set_exception, ex)\n                else:\n                    self.loop.call_soon_threadsafe(future.set_result, None)\n            return wrapper\n\n        with self.tcp_server(run(server)) as srv:\n            self.loop.run_until_complete(client(srv.addr))\n\n    def test_first_data_after_wakeup(self):\n        if self.implementation == 'asyncio':\n            raise unittest.SkipTest()\n\n        server_context = self._create_server_ssl_context(\n            self.ONLYCERT, self.ONLYKEY)\n        client_context = self._create_client_ssl_context()\n        loop = self.loop\n        this = self\n        fut = self.loop.create_future()\n\n        def client(sock, addr):\n            try:\n                sock.connect(addr)\n\n                incoming = ssl.MemoryBIO()\n                outgoing = ssl.MemoryBIO()\n                sslobj = client_context.wrap_bio(incoming, outgoing)\n\n                # Do handshake manually so that we could collect the last piece\n                while True:\n                    try:\n                        sslobj.do_handshake()\n                        break\n                    except ssl.SSLWantReadError:\n                        if outgoing.pending:\n                            sock.send(outgoing.read())\n                        incoming.write(sock.recv(65536))\n\n                # Send the first data together with the last handshake payload\n                sslobj.write(b'hello')\n                sock.send(outgoing.read())\n\n                while True:\n                    try:\n                        incoming.write(sock.recv(65536))\n                        self.assertEqual(sslobj.read(1024), b'hello')\n                        break\n                    except ssl.SSLWantReadError:\n                        pass\n\n                sock.close()\n\n            except Exception as ex:\n                loop.call_soon_threadsafe(fut.set_exception, ex)\n                sock.close()\n            else:\n                loop.call_soon_threadsafe(fut.set_result, None)\n\n        class EchoProto(asyncio.Protocol):\n            def connection_made(self, tr):\n                self.tr = tr\n                # manually run the coroutine, in order to avoid accidental data\n                coro = loop.start_tls(\n                    tr, self, server_context,\n                    server_side=True,\n                    ssl_handshake_timeout=this.TIMEOUT,\n                )\n                waiter = coro.send(None)\n\n                def tls_started(_):\n                    try:\n                        coro.send(None)\n                    except StopIteration as e:\n                        # update self.tr to SSL transport as soon as we know it\n                        self.tr = e.value\n\n                waiter.add_done_callback(tls_started)\n\n            def data_received(self, data):\n                # This is a dumb protocol that writes back whatever it receives\n                # regardless of whether self.tr is SSL or not\n                self.tr.write(data)\n\n        async def run_main():\n            proto = EchoProto()\n\n            server = await self.loop.create_server(\n                lambda: proto, '127.0.0.1', 0)\n            addr = server.sockets[0].getsockname()\n\n            with self.tcp_client(lambda sock: client(sock, addr),\n                                 timeout=self.TIMEOUT):\n                await asyncio.wait_for(fut, timeout=self.TIMEOUT)\n                proto.tr.close()\n\n            server.close()\n            await server.wait_closed()\n\n        self.loop.run_until_complete(run_main())\n\n\nclass Test_UV_TCPSSL(_TestSSL, tb.UVTestCase):\n    pass\n\n\nclass Test_AIO_TCPSSL(_TestSSL, tb.AIOTestCase):\n    pass\n"
  },
  {
    "path": "tests/test_testbase.py",
    "content": "import unittest\n\nfrom uvloop import _testbase as tb\n\n\nclass TestBaseTest(unittest.TestCase):\n\n    def test_duplicate_methods(self):\n        with self.assertRaisesRegex(RuntimeError, 'duplicate test Foo.test_a'):\n\n            class Foo(tb.BaseTestCase):\n                def test_a(self):\n                    pass\n\n                def test_b(self):\n                    pass\n\n                def test_a(self):  # NOQA\n                    pass\n\n    def test_duplicate_methods_parent_1(self):\n        class FooBase:\n            def test_a(self):\n                pass\n\n        with self.assertRaisesRegex(RuntimeError,\n                                    'duplicate test Foo.test_a.*'\n                                    'defined in FooBase'):\n\n            class Foo(FooBase, tb.BaseTestCase):\n                def test_b(self):\n                    pass\n\n                def test_a(self):\n                    pass\n\n    def test_duplicate_methods_parent_2(self):\n        class FooBase(tb.BaseTestCase):\n            def test_a(self):\n                pass\n\n        with self.assertRaisesRegex(RuntimeError,\n                                    'duplicate test Foo.test_a.*'\n                                    'defined in FooBase'):\n\n            class Foo(FooBase):\n                def test_b(self):\n                    pass\n\n                def test_a(self):\n                    pass\n"
  },
  {
    "path": "tests/test_udp.py",
    "content": "import asyncio\nimport os\nimport socket\nimport sys\nimport tempfile\nimport unittest\nimport uuid\n\nfrom uvloop import _testbase as tb\n\n\nclass MyDatagramProto(asyncio.DatagramProtocol):\n    done = None\n\n    def __init__(self, loop=None):\n        self.state = 'INITIAL'\n        self.nbytes = 0\n        if loop is not None:\n            self.done = asyncio.Future(loop=loop)\n\n    def connection_made(self, transport):\n        self.transport = transport\n        assert self.state == 'INITIAL', self.state\n        self.state = 'INITIALIZED'\n\n    def datagram_received(self, data, addr):\n        assert self.state == 'INITIALIZED', self.state\n        self.nbytes += len(data)\n\n    def error_received(self, exc):\n        assert self.state == 'INITIALIZED', self.state\n        raise exc\n\n    def connection_lost(self, exc):\n        assert self.state == 'INITIALIZED', self.state\n        self.state = 'CLOSED'\n        if self.done:\n            self.done.set_result(None)\n\n\nclass _TestUDP:\n\n    def _test_create_datagram_endpoint_addrs(self, family, lc_addr):\n        class TestMyDatagramProto(MyDatagramProto):\n            def __init__(inner_self):\n                super().__init__(loop=self.loop)\n\n            def datagram_received(self, data, addr):\n                super().datagram_received(data, addr)\n                self.transport.sendto(b'resp:' + data, addr)\n\n        coro = self.loop.create_datagram_endpoint(\n            TestMyDatagramProto,\n            local_addr=lc_addr,\n            family=family)\n\n        s_transport, server = self.loop.run_until_complete(coro)\n\n        remote_addr = s_transport.get_extra_info('sockname')\n        host, port, *_ = remote_addr\n\n        self.assertIsInstance(server, TestMyDatagramProto)\n        self.assertEqual('INITIALIZED', server.state)\n        self.assertIs(server.transport, s_transport)\n\n        extra = {}\n        if hasattr(socket, 'SO_REUSEPORT'):\n            extra['reuse_port'] = True\n\n        coro = self.loop.create_datagram_endpoint(\n            lambda: MyDatagramProto(loop=self.loop),\n            family=family,\n            remote_addr=(host, port),\n            **extra)\n        transport, client = self.loop.run_until_complete(coro)\n\n        self.assertIsInstance(client, MyDatagramProto)\n        self.assertEqual('INITIALIZED', client.state)\n        self.assertIs(client.transport, transport)\n\n        transport.sendto(b'xxx')\n        tb.run_until(self.loop, lambda: server.nbytes)\n        self.assertEqual(3, server.nbytes)\n        tb.run_until(self.loop, lambda: client.nbytes)\n\n        # received\n        self.assertEqual(8, client.nbytes)\n\n        # https://github.com/MagicStack/uvloop/issues/319\n        # uvloop should behave the same as asyncio when given remote_addr\n        transport.sendto(b'xxx', remote_addr)\n        tb.run_until(\n            self.loop, lambda: server.nbytes > 3 or client.done.done())\n        self.assertEqual(6, server.nbytes)\n        tb.run_until(self.loop, lambda: client.nbytes > 8)\n\n        # received\n        self.assertEqual(16, client.nbytes)\n\n        # reject sendto with a different port\n        with self.assertRaisesRegex(\n            ValueError, \"Invalid address.*\" + repr(remote_addr)\n        ):\n            bad_addr = list(remote_addr)\n            bad_addr[1] += 1\n            bad_addr = tuple(bad_addr)\n            transport.sendto(b\"xxx\", bad_addr)\n\n        # reject sento with unresolved hostname\n        if remote_addr[0] != lc_addr[0]:\n            with self.assertRaisesRegex(\n                ValueError, \"Invalid address.*\" + repr(remote_addr)\n            ):\n                bad_addr = list(remote_addr)\n                bad_addr[0] = lc_addr[0]\n                bad_addr = tuple(bad_addr)\n                transport.sendto(b\"xxx\", bad_addr)\n\n        # extra info is available\n        self.assertIsNotNone(transport.get_extra_info('sockname'))\n\n        # close connection\n        transport.close()\n        self.loop.run_until_complete(client.done)\n        self.assertEqual('CLOSED', client.state)\n        server.transport.close()\n        self.loop.run_until_complete(server.done)\n\n    def test_create_datagram_endpoint_addrs_ipv4(self):\n        self._test_create_datagram_endpoint_addrs(\n            socket.AF_INET, ('127.0.0.1', 0))\n\n    def test_create_datagram_endpoint_addrs_ipv4_nameaddr(self):\n        self._test_create_datagram_endpoint_addrs(\n            socket.AF_INET, ('localhost', 0))\n\n    def _test_create_datagram_endpoint_addrs_ipv6(self):\n        self._test_create_datagram_endpoint_addrs(\n            socket.AF_INET6, ('::1', 0))\n\n    def test_create_datagram_endpoint_ipv6_family(self):\n        class TestMyDatagramProto(MyDatagramProto):\n            def __init__(inner_self):\n                super().__init__(loop=self.loop)\n\n            def datagram_received(self, data, addr):\n                super().datagram_received(data, addr)\n                self.transport.sendto(b'resp:' + data, addr)\n\n        coro = self.loop.create_datagram_endpoint(\n            TestMyDatagramProto, local_addr=None, family=socket.AF_INET6)\n        s_transport = None\n        try:\n            s_transport, server = self.loop.run_until_complete(coro)\n        finally:\n            if s_transport:\n                s_transport.close()\n                # let it close\n                self.loop.run_until_complete(\n                    asyncio.sleep(0.1))\n\n    def test_create_datagram_endpoint_sock(self):\n        sock = None\n        local_address = ('127.0.0.1', 0)\n        infos = self.loop.run_until_complete(\n            self.loop.getaddrinfo(\n                *local_address, type=socket.SOCK_DGRAM))\n        for family, type, proto, cname, address in infos:\n            try:\n                sock = socket.socket(family=family, type=type, proto=proto)\n                sock.setblocking(False)\n                sock.bind(address)\n            except Exception:\n                pass\n            else:\n                break\n        else:\n            assert False, 'Can not create socket.'\n\n        with sock:\n            f = self.loop.create_datagram_endpoint(\n                lambda: MyDatagramProto(loop=self.loop), sock=sock)\n            tr, pr = self.loop.run_until_complete(f)\n            self.assertIsInstance(pr, MyDatagramProto)\n            tr.close()\n            self.loop.run_until_complete(pr.done)\n\n    def test_create_datagram_endpoint_sock_unix_domain(self):\n\n        class Proto(asyncio.DatagramProtocol):\n            done = None\n\n            def __init__(self, loop):\n                self.state = 'INITIAL'\n                self.addrs = set()\n                self.done = asyncio.Future(loop=loop)\n                self.data = b''\n\n            def connection_made(self, transport):\n                self.transport = transport\n                assert self.state == 'INITIAL', self.state\n                self.state = 'INITIALIZED'\n\n            def datagram_received(self, data, addr):\n                assert self.state == 'INITIALIZED', self.state\n                self.addrs.add(addr)\n                self.data += data\n                if self.data == b'STOP' and not self.done.done():\n                    self.done.set_result(True)\n\n            def error_received(self, exc):\n                assert self.state == 'INITIALIZED', self.state\n                if not self.done.done():\n                    self.done.set_exception(exc or RuntimeError())\n\n            def connection_lost(self, exc):\n                assert self.state == 'INITIALIZED', self.state\n                self.state = 'CLOSED'\n                if self.done and not self.done.done():\n                    self.done.set_result(None)\n\n        tmp_file = os.path.join(tempfile.gettempdir(), str(uuid.uuid4()))\n        sock = socket.socket(socket.AF_UNIX, type=socket.SOCK_DGRAM)\n        sock.bind(tmp_file)\n\n        with sock:\n            pr = Proto(loop=self.loop)\n            f = self.loop.create_datagram_endpoint(\n                lambda: pr, sock=sock)\n            tr, pr_prime = self.loop.run_until_complete(f)\n            self.assertIs(pr, pr_prime)\n\n            tmp_file2 = os.path.join(tempfile.gettempdir(), str(uuid.uuid4()))\n            sock2 = socket.socket(socket.AF_UNIX, type=socket.SOCK_DGRAM)\n            sock2.bind(tmp_file2)\n\n            with sock2:\n                f2 = self.loop.create_datagram_endpoint(\n                    asyncio.DatagramProtocol, sock=sock2)\n                tr2, pr2 = self.loop.run_until_complete(f2)\n\n                tr2.sendto(b'STOP', tmp_file)\n\n                self.loop.run_until_complete(pr.done)\n\n                tr.close()\n                tr2.close()\n\n                # Let transports close\n                self.loop.run_until_complete(asyncio.sleep(0.2))\n\n                self.assertIn(tmp_file2, pr.addrs)\n\n    def test_create_datagram_1(self):\n        server_addr = ('127.0.0.1', 8888)\n        client_addr = ('127.0.0.1', 0)\n\n        async def run():\n            server_transport, client_protocol = \\\n                await self.loop.create_datagram_endpoint(\n                    asyncio.DatagramProtocol,\n                    local_addr=server_addr)\n\n            client_transport, client_conn = \\\n                await self.loop.create_datagram_endpoint(\n                    asyncio.DatagramProtocol,\n                    remote_addr=server_addr,\n                    local_addr=client_addr)\n\n            client_transport.close()\n            server_transport.close()\n\n            # let transports close\n            await asyncio.sleep(0.1)\n\n        self.loop.run_until_complete(run())\n\n    def test_socketpair(self):\n        peername = asyncio.Future(loop=self.loop)\n\n        class Proto(MyDatagramProto):\n            def datagram_received(self, data, addr):\n                super().datagram_received(data, addr)\n                peername.set_result(addr)\n\n        s1, s2 = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM, 0)\n\n        with s1, s2:\n            f = self.loop.create_datagram_endpoint(\n                lambda: Proto(loop=self.loop), sock=s1)\n            tr, pr = self.loop.run_until_complete(f)\n            self.assertIsInstance(pr, Proto)\n\n            s2.send(b'hello, socketpair')\n            addr = self.loop.run_until_complete(\n                asyncio.wait_for(peername, 1))\n            if sys.platform.startswith('linux'):\n                self.assertEqual(addr, None)\n            else:\n                self.assertEqual(addr, '')\n            self.assertEqual(pr.nbytes, 17)\n\n            if not self.is_asyncio_loop():\n                # asyncio doesn't support sendto(xx) on UDP sockets\n                # https://git.io/Jfqbw\n                data = b'from uvloop'\n                tr.sendto(data)\n                result = self.loop.run_until_complete(asyncio.wait_for(\n                    self.loop.run_in_executor(None, s2.recv, 1024),\n                    1))\n                self.assertEqual(data, result)\n\n            tr.close()\n            self.loop.run_until_complete(pr.done)\n\n    def _skip_create_datagram_endpoint_reuse_addr(self):\n        if self.implementation == 'asyncio':\n            if sys.version_info[:2] >= (3, 11):\n                raise unittest.SkipTest()\n            if (3, 8, 0) <= sys.version_info < (3, 8, 1):\n                raise unittest.SkipTest()\n\n    def test_create_datagram_endpoint_reuse_address_error(self):\n        # bpo-37228: Ensure that explicit passing of `reuse_address=True`\n        # raises an error, as it is not safe to use SO_REUSEADDR when using UDP\n\n        self._skip_create_datagram_endpoint_reuse_addr()\n\n        coro = self.loop.create_datagram_endpoint(\n            lambda: MyDatagramProto(loop=self.loop),\n            local_addr=('127.0.0.1', 0),\n            reuse_address=True)\n\n        with self.assertRaises(ValueError):\n            self.loop.run_until_complete(coro)\n\n    def test_create_datagram_endpoint_reuse_address_warning(self):\n        # bpo-37228: Deprecate *reuse_address* parameter\n\n        self._skip_create_datagram_endpoint_reuse_addr()\n\n        coro = self.loop.create_datagram_endpoint(\n            lambda: MyDatagramProto(loop=self.loop),\n            local_addr=('127.0.0.1', 0),\n            reuse_address=False)\n\n        with self.assertWarns(DeprecationWarning):\n            tr, pr = self.loop.run_until_complete(coro)\n\n        tr.close()\n        self.loop.run_until_complete(pr.done)\n\n\nclass Test_UV_UDP(_TestUDP, tb.UVTestCase):\n\n    def test_create_datagram_endpoint_wrong_sock(self):\n        sock = socket.socket(socket.AF_INET)\n        with sock:\n            coro = self.loop.create_datagram_endpoint(lambda: None, sock=sock)\n            with self.assertRaisesRegex(ValueError,\n                                        'A UDP Socket was expected'):\n                self.loop.run_until_complete(coro)\n\n    def test_udp_sendto_dns(self):\n        coro = self.loop.create_datagram_endpoint(\n            asyncio.DatagramProtocol,\n            local_addr=('127.0.0.1', 0),\n            family=socket.AF_INET)\n\n        s_transport, server = self.loop.run_until_complete(coro)\n\n        with self.assertRaisesRegex(ValueError, 'DNS lookup'):\n            s_transport.sendto(b'aaaa', ('example.com', 80))\n\n        with self.assertRaisesRegex(ValueError, 'socket family mismatch'):\n            s_transport.sendto(b'aaaa', ('::1', 80))\n\n        s_transport.close()\n        self.loop.run_until_complete(asyncio.sleep(0.01))\n\n    def test_udp_sendto_broadcast(self):\n        coro = self.loop.create_datagram_endpoint(\n            asyncio.DatagramProtocol,\n            local_addr=('127.0.0.1', 0),\n            family=socket.AF_INET)\n\n        s_transport, server = self.loop.run_until_complete(coro)\n\n        try:\n            s_transport.sendto(b'aaaa', ('<broadcast>', 80))\n        except ValueError as exc:\n            raise AssertionError('sendto raises {}.'.format(exc))\n\n        s_transport.close()\n        self.loop.run_until_complete(asyncio.sleep(0.01))\n\n    def test_send_after_close(self):\n        coro = self.loop.create_datagram_endpoint(\n            asyncio.DatagramProtocol,\n            local_addr=('127.0.0.1', 0),\n            family=socket.AF_INET)\n\n        s_transport, _ = self.loop.run_until_complete(coro)\n\n        s_transport.close()\n        s_transport.sendto(b'aaaa', ('127.0.0.1', 80))\n        self.loop.run_until_complete(asyncio.sleep(0.01))\n        s_transport.sendto(b'aaaa', ('127.0.0.1', 80))\n\n    @unittest.skipUnless(tb.has_IPv6, 'no IPv6')\n    def test_create_datagram_endpoint_addrs_ipv6(self):\n        self._test_create_datagram_endpoint_addrs_ipv6()\n\n\nclass Test_AIO_UDP(_TestUDP, tb.AIOTestCase):\n    @unittest.skipUnless(tb.has_IPv6, 'no IPv6')\n    def test_create_datagram_endpoint_addrs_ipv6(self):\n        self._test_create_datagram_endpoint_addrs_ipv6()\n"
  },
  {
    "path": "tests/test_unix.py",
    "content": "import asyncio\nimport os\nimport pathlib\nimport socket\nimport tempfile\nimport time\nimport unittest\nimport sys\n\nfrom uvloop import _testbase as tb\n\n\nSSL_HANDSHAKE_TIMEOUT = 15.0\n\n\nclass _TestUnix:\n    def test_create_unix_server_1(self):\n        CNT = 0           # number of clients that were successful\n        TOTAL_CNT = 100   # total number of clients that test will create\n        TIMEOUT = 5.0     # timeout for this test\n\n        async def handle_client(reader, writer):\n            nonlocal CNT\n\n            data = await reader.readexactly(4)\n            self.assertEqual(data, b'AAAA')\n            writer.write(b'OK')\n\n            data = await reader.readexactly(4)\n            self.assertEqual(data, b'BBBB')\n            writer.write(b'SPAM')\n\n            await writer.drain()\n            writer.close()\n            await self.wait_closed(writer)\n\n            CNT += 1\n\n        async def test_client(addr):\n            sock = socket.socket(socket.AF_UNIX)\n            with sock:\n                sock.setblocking(False)\n                await self.loop.sock_connect(sock, addr)\n\n                await self.loop.sock_sendall(sock, b'AAAA')\n\n                buf = b''\n                while len(buf) != 2:\n                    buf += await self.loop.sock_recv(sock, 1)\n                self.assertEqual(buf, b'OK')\n\n                await self.loop.sock_sendall(sock, b'BBBB')\n\n                buf = b''\n                while len(buf) != 4:\n                    buf += await self.loop.sock_recv(sock, 1)\n                self.assertEqual(buf, b'SPAM')\n\n        async def start_server():\n            nonlocal CNT\n            CNT = 0\n\n            with tempfile.TemporaryDirectory() as td:\n                sock_name = os.path.join(td, 'sock')\n                srv = await asyncio.start_unix_server(\n                    handle_client,\n                    sock_name)\n\n                try:\n                    srv_socks = srv.sockets\n                    self.assertTrue(srv_socks)\n                    self.assertTrue(srv.is_serving())\n\n                    tasks = []\n                    for _ in range(TOTAL_CNT):\n                        tasks.append(test_client(sock_name))\n\n                    await asyncio.wait_for(asyncio.gather(*tasks), TIMEOUT)\n\n                finally:\n                    self.loop.call_soon(srv.close)\n                    await srv.wait_closed()\n\n                    if (\n                        self.implementation == 'asyncio'\n                        and sys.version_info[:3] >= (3, 12, 0)\n                    ):\n                        # asyncio regression in 3.12 -- wait_closed()\n                        # doesn't wait for `close()` to actually complete.\n                        # https://github.com/python/cpython/issues/79033\n                        await asyncio.sleep(1)\n\n                    # Check that the server cleaned-up proxy-sockets\n                    for srv_sock in srv_socks:\n                        self.assertEqual(srv_sock.fileno(), -1)\n\n                    self.assertFalse(srv.is_serving())\n\n                if sys.version_info < (3, 13):\n                    # asyncio doesn't cleanup the sock file under Python 3.13\n                    self.assertTrue(os.path.exists(sock_name))\n                else:\n                    self.assertFalse(os.path.exists(sock_name))\n\n        async def start_server_sock(start_server, is_unix_api=True):\n            # is_unix_api indicates whether `start_server` is calling\n            # `loop.create_unix_server()` or `loop.create_server()`,\n            # because asyncio `loop.create_server()` doesn't cleanup\n            # the socket file even if it's a UNIX socket.\n\n            nonlocal CNT\n            CNT = 0\n\n            with tempfile.TemporaryDirectory() as td:\n                sock_name = os.path.join(td, 'sock')\n                sock = socket.socket(socket.AF_UNIX)\n                sock.bind(sock_name)\n\n                srv = await start_server(sock)\n\n                try:\n                    srv_socks = srv.sockets\n                    self.assertTrue(srv_socks)\n                    self.assertTrue(srv.is_serving())\n\n                    tasks = []\n                    for _ in range(TOTAL_CNT):\n                        tasks.append(test_client(sock_name))\n\n                    await asyncio.wait_for(asyncio.gather(*tasks), TIMEOUT)\n\n                finally:\n                    self.loop.call_soon(srv.close)\n                    await srv.wait_closed()\n\n                    if (\n                        self.implementation == 'asyncio'\n                        and sys.version_info[:3] >= (3, 12, 0)\n                    ):\n                        # asyncio regression in 3.12 -- wait_closed()\n                        # doesn't wait for `close()` to actually complete.\n                        # https://github.com/python/cpython/issues/79033\n                        await asyncio.sleep(1)\n\n                    # Check that the server cleaned-up proxy-sockets\n                    for srv_sock in srv_socks:\n                        self.assertEqual(srv_sock.fileno(), -1)\n\n                    self.assertFalse(srv.is_serving())\n\n                if sys.version_info < (3, 13) or not is_unix_api:\n                    # asyncio doesn't cleanup the sock file under Python 3.13\n                    self.assertTrue(os.path.exists(sock_name))\n                else:\n                    self.assertFalse(os.path.exists(sock_name))\n\n        with self.subTest(func='start_unix_server(host, port)'):\n            self.loop.run_until_complete(start_server())\n            self.assertEqual(CNT, TOTAL_CNT)\n\n        with self.subTest(func='start_unix_server(sock)'):\n            self.loop.run_until_complete(start_server_sock(\n                lambda sock: asyncio.start_unix_server(\n                    handle_client,\n                    None,\n                    sock=sock)))\n            self.assertEqual(CNT, TOTAL_CNT)\n\n        with self.subTest(func='start_server(sock)'):\n            self.loop.run_until_complete(start_server_sock(\n                lambda sock: asyncio.start_server(\n                    handle_client,\n                    None, None,\n                    sock=sock), is_unix_api=False))\n            self.assertEqual(CNT, TOTAL_CNT)\n\n    def test_create_unix_server_2(self):\n        with tempfile.TemporaryDirectory() as td:\n            sock_name = os.path.join(td, 'sock')\n            with open(sock_name, 'wt') as f:\n                f.write('x')\n\n            with self.assertRaisesRegex(\n                    OSError, \"Address '{}' is already in use\".format(\n                        sock_name)):\n\n                self.loop.run_until_complete(\n                    self.loop.create_unix_server(object, sock_name))\n\n    def test_create_unix_server_3(self):\n        with self.assertRaisesRegex(\n                ValueError, 'ssl_handshake_timeout is only meaningful'):\n            self.loop.run_until_complete(\n                self.loop.create_unix_server(\n                    lambda: None, path='/tmp/a',\n                    ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT))\n\n    def test_create_unix_server_existing_path_sock(self):\n        with self.unix_sock_name() as path:\n            sock = socket.socket(socket.AF_UNIX)\n            with sock:\n                sock.bind(path)\n                sock.listen(1)\n\n            # Check that no error is raised -- `path` is removed.\n            coro = self.loop.create_unix_server(lambda: None, path)\n            srv = self.loop.run_until_complete(coro)\n            srv.close()\n            self.loop.run_until_complete(srv.wait_closed())\n\n    def test_create_unix_connection_open_unix_con_addr(self):\n        async def client(addr):\n            reader, writer = await asyncio.open_unix_connection(addr)\n\n            writer.write(b'AAAA')\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            writer.write(b'BBBB')\n            self.assertEqual(await reader.readexactly(4), b'SPAM')\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        self._test_create_unix_connection_1(client)\n\n    def test_create_unix_connection_open_unix_con_sock(self):\n        async def client(addr):\n            sock = socket.socket(socket.AF_UNIX)\n            sock.connect(addr)\n            reader, writer = await asyncio.open_unix_connection(sock=sock)\n\n            writer.write(b'AAAA')\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            writer.write(b'BBBB')\n            self.assertEqual(await reader.readexactly(4), b'SPAM')\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        self._test_create_unix_connection_1(client)\n\n    def test_create_unix_connection_open_con_sock(self):\n        async def client(addr):\n            sock = socket.socket(socket.AF_UNIX)\n            sock.connect(addr)\n            reader, writer = await asyncio.open_connection(sock=sock)\n\n            writer.write(b'AAAA')\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            writer.write(b'BBBB')\n            self.assertEqual(await reader.readexactly(4), b'SPAM')\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        self._test_create_unix_connection_1(client)\n\n    def _test_create_unix_connection_1(self, client):\n        CNT = 0\n        TOTAL_CNT = 100\n\n        def server(sock):\n            data = sock.recv_all(4)\n            self.assertEqual(data, b'AAAA')\n            sock.send(b'OK')\n\n            data = sock.recv_all(4)\n            self.assertEqual(data, b'BBBB')\n            sock.send(b'SPAM')\n\n        async def client_wrapper(addr):\n            await client(addr)\n            nonlocal CNT\n            CNT += 1\n\n        def run(coro):\n            nonlocal CNT\n            CNT = 0\n\n            with self.unix_server(server,\n                                  max_clients=TOTAL_CNT,\n                                  backlog=TOTAL_CNT) as srv:\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(coro(srv.addr))\n\n                self.loop.run_until_complete(asyncio.gather(*tasks))\n\n                # Give time for all transports to close.\n                self.loop.run_until_complete(asyncio.sleep(0.1))\n\n            self.assertEqual(CNT, TOTAL_CNT)\n\n        run(client_wrapper)\n\n    def test_create_unix_connection_2(self):\n        with tempfile.NamedTemporaryFile() as tmp:\n            path = tmp.name\n\n        async def client():\n            reader, writer = await asyncio.open_unix_connection(path)\n            writer.close()\n            await self.wait_closed(writer)\n\n        async def runner():\n            with self.assertRaises(FileNotFoundError):\n                await client()\n\n        self.loop.run_until_complete(runner())\n\n    def test_create_unix_connection_3(self):\n        CNT = 0\n        TOTAL_CNT = 100\n\n        def server(sock):\n            data = sock.recv_all(4)\n            self.assertEqual(data, b'AAAA')\n            sock.close()\n\n        async def client(addr):\n            reader, writer = await asyncio.open_unix_connection(addr)\n\n            sock = writer._transport.get_extra_info('socket')\n            self.assertEqual(sock.family, socket.AF_UNIX)\n\n            writer.write(b'AAAA')\n\n            with self.assertRaises(asyncio.IncompleteReadError):\n                await reader.readexactly(10)\n\n            writer.close()\n            await self.wait_closed(writer)\n\n            nonlocal CNT\n            CNT += 1\n\n        def run(coro):\n            nonlocal CNT\n            CNT = 0\n\n            with self.unix_server(server,\n                                  max_clients=TOTAL_CNT,\n                                  backlog=TOTAL_CNT) as srv:\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(coro(srv.addr))\n\n                self.loop.run_until_complete(asyncio.gather(*tasks))\n\n            self.assertEqual(CNT, TOTAL_CNT)\n\n        run(client)\n\n    def test_create_unix_connection_4(self):\n        sock = socket.socket(socket.AF_UNIX)\n        sock.close()\n\n        async def client():\n            reader, writer = await asyncio.open_unix_connection(sock=sock)\n            writer.close()\n            await self.wait_closed(writer)\n\n        async def runner():\n            with self.assertRaisesRegex(OSError, 'Bad file'):\n                await client()\n\n        self.loop.run_until_complete(runner())\n\n    def test_create_unix_connection_5(self):\n        s1, s2 = socket.socketpair(socket.AF_UNIX)\n\n        excs = []\n\n        class Proto(asyncio.Protocol):\n            def connection_lost(self, exc):\n                excs.append(exc)\n\n        proto = Proto()\n\n        async def client():\n            t, _ = await self.loop.create_unix_connection(\n                lambda: proto,\n                None,\n                sock=s2)\n\n            t.write(b'AAAAA')\n            s1.close()\n            t.write(b'AAAAA')\n            await asyncio.sleep(0.1)\n\n        self.loop.run_until_complete(client())\n\n        self.assertEqual(len(excs), 1)\n        self.assertIn(excs[0].__class__,\n                      (BrokenPipeError, ConnectionResetError))\n\n    def test_create_unix_connection_6(self):\n        with self.assertRaisesRegex(\n                ValueError, 'ssl_handshake_timeout is only meaningful'):\n            self.loop.run_until_complete(\n                self.loop.create_unix_connection(\n                    lambda: None, path='/tmp/a',\n                    ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT))\n\n\nclass Test_UV_Unix(_TestUnix, tb.UVTestCase):\n\n    @unittest.skipUnless(hasattr(os, 'fspath'), 'no os.fspath()')\n    def test_create_unix_connection_pathlib(self):\n        async def run(addr):\n            t, _ = await self.loop.create_unix_connection(\n                asyncio.Protocol, addr)\n            t.close()\n\n        with self.unix_server(lambda sock: time.sleep(0.01)) as srv:\n            addr = pathlib.Path(srv.addr)\n            self.loop.run_until_complete(run(addr))\n\n    @unittest.skipUnless(hasattr(os, 'fspath'), 'no os.fspath()')\n    def test_create_unix_server_pathlib(self):\n        with self.unix_sock_name() as srv_path:\n            srv_path = pathlib.Path(srv_path)\n            srv = self.loop.run_until_complete(\n                self.loop.create_unix_server(asyncio.Protocol, srv_path))\n            srv.close()\n            self.loop.run_until_complete(srv.wait_closed())\n\n    def test_transport_fromsock_get_extra_info(self):\n        # This tests is only for uvloop.  asyncio should pass it\n        # too in Python 3.6.\n\n        async def test(sock):\n            t, _ = await self.loop.create_unix_connection(\n                asyncio.Protocol,\n                sock=sock)\n\n            sock = t.get_extra_info('socket')\n            self.assertIs(t.get_extra_info('socket'), sock)\n\n            with self.assertRaisesRegex(RuntimeError, 'is used by transport'):\n                self.loop.add_writer(sock.fileno(), lambda: None)\n            with self.assertRaisesRegex(RuntimeError, 'is used by transport'):\n                self.loop.remove_writer(sock.fileno())\n\n            t.close()\n\n        s1, s2 = socket.socketpair(socket.AF_UNIX)\n        with s1, s2:\n            self.loop.run_until_complete(test(s1))\n\n    def test_create_unix_server_path_dgram(self):\n        sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)\n        with sock:\n            coro = self.loop.create_unix_server(lambda: None,\n                                                sock=sock)\n            with self.assertRaisesRegex(ValueError,\n                                        'A UNIX Domain Stream.*was expected'):\n                self.loop.run_until_complete(coro)\n\n    @unittest.skipUnless(hasattr(socket, 'SOCK_NONBLOCK'),\n                         'no socket.SOCK_NONBLOCK (linux only)')\n    def test_create_unix_server_path_stream_bittype(self):\n        sock = socket.socket(\n            socket.AF_UNIX, socket.SOCK_STREAM | socket.SOCK_NONBLOCK)\n        with tempfile.NamedTemporaryFile() as file:\n            fn = file.name\n        with sock:\n            sock.bind(fn)\n            coro = self.loop.create_unix_server(lambda: None, path=None,\n                                                sock=sock, cleanup_socket=True)\n            srv = self.loop.run_until_complete(coro)\n            srv.close()\n            self.loop.run_until_complete(srv.wait_closed())\n\n    @unittest.skipUnless(sys.platform.startswith('linux'), 'requires epoll')\n    def test_epollhup(self):\n        SIZE = 50\n        eof = False\n        done = False\n        recvd = b''\n\n        class Proto(asyncio.BaseProtocol):\n            def connection_made(self, tr):\n                tr.write(b'hello')\n                self.data = bytearray(SIZE)\n                self.buf = memoryview(self.data)\n\n            def get_buffer(self, sizehint):\n                return self.buf\n\n            def buffer_updated(self, nbytes):\n                nonlocal recvd\n                recvd += self.buf[:nbytes]\n\n            def eof_received(self):\n                nonlocal eof\n                eof = True\n\n            def connection_lost(self, exc):\n                nonlocal done\n                done = exc\n\n        async def test():\n            with tempfile.TemporaryDirectory() as td:\n                sock_name = os.path.join(td, 'sock')\n                srv = await self.loop.create_unix_server(Proto, sock_name)\n\n                s = socket.socket(socket.AF_UNIX)\n                with s:\n                    s.setblocking(False)\n                    await self.loop.sock_connect(s, sock_name)\n                    d = await self.loop.sock_recv(s, 100)\n                    self.assertEqual(d, b'hello')\n\n                    # IMPORTANT: overflow recv buffer and close immediately\n                    await self.loop.sock_sendall(s, b'a' * (SIZE + 1))\n\n                srv.close()\n                await srv.wait_closed()\n\n        self.loop.run_until_complete(test())\n        self.assertTrue(eof)\n        self.assertIsNone(done)\n        self.assertEqual(recvd, b'a' * (SIZE + 1))\n\n\nclass Test_AIO_Unix(_TestUnix, tb.AIOTestCase):\n    pass\n\n\nclass _TestSSL(tb.SSLTestCase):\n\n    ONLYCERT = tb._cert_fullname(__file__, 'ssl_cert.pem')\n    ONLYKEY = tb._cert_fullname(__file__, 'ssl_key.pem')\n\n    def test_create_unix_server_ssl_1(self):\n        CNT = 0           # number of clients that were successful\n        TOTAL_CNT = 25    # total number of clients that test will create\n        TIMEOUT = 10.0    # timeout for this test\n\n        A_DATA = b'A' * 1024 * 1024\n        B_DATA = b'B' * 1024 * 1024\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context()\n\n        clients = []\n\n        async def handle_client(reader, writer):\n            nonlocal CNT\n\n            data = await reader.readexactly(len(A_DATA))\n            self.assertEqual(data, A_DATA)\n            writer.write(b'OK')\n\n            data = await reader.readexactly(len(B_DATA))\n            self.assertEqual(data, B_DATA)\n            writer.writelines([b'SP', bytearray(b'A'), memoryview(b'M')])\n\n            await writer.drain()\n            writer.close()\n\n            CNT += 1\n\n        async def test_client(addr):\n            fut = asyncio.Future(loop=self.loop)\n\n            def prog(sock):\n                try:\n                    sock.starttls(client_sslctx)\n\n                    sock.connect(addr)\n                    sock.send(A_DATA)\n\n                    data = sock.recv_all(2)\n                    self.assertEqual(data, b'OK')\n\n                    sock.send(B_DATA)\n                    data = sock.recv_all(4)\n                    self.assertEqual(data, b'SPAM')\n\n                    sock.close()\n\n                except Exception as ex:\n                    self.loop.call_soon_threadsafe(\n                        lambda ex=ex:\n                            (fut.cancelled() or fut.set_exception(ex)))\n                else:\n                    self.loop.call_soon_threadsafe(\n                        lambda: (fut.cancelled() or fut.set_result(None)))\n\n            client = self.unix_client(prog)\n            client.start()\n            clients.append(client)\n\n            await fut\n\n        async def start_server():\n            extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)\n\n            with tempfile.TemporaryDirectory() as td:\n                sock_name = os.path.join(td, 'sock')\n\n                srv = await asyncio.start_unix_server(\n                    handle_client,\n                    sock_name,\n                    ssl=sslctx,\n                    **extras)\n\n                try:\n                    tasks = []\n                    for _ in range(TOTAL_CNT):\n                        tasks.append(test_client(sock_name))\n\n                    await asyncio.wait_for(asyncio.gather(*tasks), TIMEOUT)\n\n                finally:\n                    self.loop.call_soon(srv.close)\n                    await srv.wait_closed()\n\n        try:\n            with self._silence_eof_received_warning():\n                self.loop.run_until_complete(start_server())\n        except asyncio.TimeoutError:\n            if os.environ.get('TRAVIS_OS_NAME') == 'osx':\n                # XXX: figure out why this fails on macOS on Travis\n                raise unittest.SkipTest('unexplained error on Travis macOS')\n            else:\n                raise\n\n        self.assertEqual(CNT, TOTAL_CNT)\n\n        for client in clients:\n            client.stop()\n\n    def test_create_unix_connection_ssl_1(self):\n        CNT = 0\n        TOTAL_CNT = 25\n\n        A_DATA = b'A' * 1024 * 1024\n        B_DATA = b'B' * 1024 * 1024\n\n        sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY)\n        client_sslctx = self._create_client_ssl_context()\n\n        def server(sock):\n            sock.starttls(sslctx, server_side=True)\n\n            data = sock.recv_all(len(A_DATA))\n            self.assertEqual(data, A_DATA)\n            sock.send(b'OK')\n\n            data = sock.recv_all(len(B_DATA))\n            self.assertEqual(data, B_DATA)\n            sock.send(b'SPAM')\n\n            sock.close()\n\n        async def client(addr):\n            extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)\n\n            reader, writer = await asyncio.open_unix_connection(\n                addr,\n                ssl=client_sslctx,\n                server_hostname='',\n                **extras)\n\n            writer.write(A_DATA)\n            self.assertEqual(await reader.readexactly(2), b'OK')\n\n            writer.write(B_DATA)\n            self.assertEqual(await reader.readexactly(4), b'SPAM')\n\n            nonlocal CNT\n            CNT += 1\n\n            writer.close()\n            await self.wait_closed(writer)\n\n        def run(coro):\n            nonlocal CNT\n            CNT = 0\n\n            with self.unix_server(server,\n                                  max_clients=TOTAL_CNT,\n                                  backlog=TOTAL_CNT) as srv:\n                tasks = []\n                for _ in range(TOTAL_CNT):\n                    tasks.append(coro(srv.addr))\n\n                self.loop.run_until_complete(asyncio.gather(*tasks))\n\n            self.assertEqual(CNT, TOTAL_CNT)\n\n        with self._silence_eof_received_warning():\n            run(client)\n\n\nclass Test_UV_UnixSSL(_TestSSL, tb.UVTestCase):\n    pass\n\n\nclass Test_AIO_UnixSSL(_TestSSL, tb.AIOTestCase):\n    pass\n"
  },
  {
    "path": "uvloop/.gitignore",
    "content": "*.c\n*.html\n"
  },
  {
    "path": "uvloop/__init__.py",
    "content": "import asyncio as __asyncio\nimport typing as _typing\nimport sys as _sys\nimport warnings as _warnings\n\nfrom . import includes as __includes  # NOQA\nfrom .loop import Loop as __BaseLoop  # NOQA\nfrom ._version import __version__  # NOQA\n\n\n__all__: _typing.Tuple[str, ...] = ('new_event_loop', 'run')\n_AbstractEventLoop = __asyncio.AbstractEventLoop\n\n\n_T = _typing.TypeVar(\"_T\")\n\n\nclass Loop(__BaseLoop, _AbstractEventLoop):  # type: ignore[misc]\n    pass\n\n\ndef new_event_loop() -> Loop:\n    \"\"\"Return a new event loop.\"\"\"\n    return Loop()\n\n\nif _typing.TYPE_CHECKING:\n    def run(\n        main: _typing.Coroutine[_typing.Any, _typing.Any, _T],\n        *,\n        loop_factory: _typing.Optional[\n            _typing.Callable[[], Loop]\n        ] = new_event_loop,\n        debug: _typing.Optional[bool]=None,\n    ) -> _T:\n        \"\"\"The preferred way of running a coroutine with uvloop.\"\"\"\nelse:\n    def run(main, *, loop_factory=new_event_loop, debug=None, **run_kwargs):\n        \"\"\"The preferred way of running a coroutine with uvloop.\"\"\"\n\n        async def wrapper():\n            # If `loop_factory` is provided we want it to return\n            # either uvloop.Loop or a subtype of it, assuming the user\n            # is using `uvloop.run()` intentionally.\n            loop = __asyncio._get_running_loop()\n            if not isinstance(loop, Loop):\n                raise TypeError('uvloop.run() uses a non-uvloop event loop')\n            return await main\n\n        vi = _sys.version_info[:2]\n\n        if vi <= (3, 10):\n            # Copied from python/cpython\n\n            if __asyncio._get_running_loop() is not None:\n                raise RuntimeError(\n                    \"asyncio.run() cannot be called from a running event loop\")\n\n            if not __asyncio.iscoroutine(main):\n                raise ValueError(\n                    \"a coroutine was expected, got {!r}\".format(main)\n                )\n\n            loop = loop_factory()\n            try:\n                __asyncio.set_event_loop(loop)\n                if debug is not None:\n                    loop.set_debug(debug)\n                return loop.run_until_complete(wrapper())\n            finally:\n                try:\n                    _cancel_all_tasks(loop)\n                    loop.run_until_complete(loop.shutdown_asyncgens())\n                    if hasattr(loop, 'shutdown_default_executor'):\n                        loop.run_until_complete(\n                            loop.shutdown_default_executor()\n                        )\n                finally:\n                    __asyncio.set_event_loop(None)\n                    loop.close()\n\n        elif vi == (3, 11):\n            if __asyncio._get_running_loop() is not None:\n                raise RuntimeError(\n                    \"asyncio.run() cannot be called from a running event loop\")\n\n            with __asyncio.Runner(\n                loop_factory=loop_factory,\n                debug=debug,\n                **run_kwargs\n            ) as runner:\n                return runner.run(wrapper())\n\n        else:\n            assert vi >= (3, 12)\n            return __asyncio.run(\n                wrapper(),\n                loop_factory=loop_factory,\n                debug=debug,\n                **run_kwargs\n            )\n\n\ndef _cancel_all_tasks(loop: _AbstractEventLoop) -> None:\n    # Copied from python/cpython\n\n    to_cancel = __asyncio.all_tasks(loop)\n    if not to_cancel:\n        return\n\n    for task in to_cancel:\n        task.cancel()\n\n    loop.run_until_complete(\n        __asyncio.gather(*to_cancel, return_exceptions=True)\n    )\n\n    for task in to_cancel:\n        if task.cancelled():\n            continue\n        if task.exception() is not None:\n            loop.call_exception_handler({\n                'message': 'unhandled exception during asyncio.run() shutdown',\n                'exception': task.exception(),\n                'task': task,\n            })\n\n\n_deprecated_names = ('install', 'EventLoopPolicy')\n\n\nif _sys.version_info[:2] < (3, 16):\n    __all__ += _deprecated_names\n\n\ndef __getattr__(name: str) -> _typing.Any:\n    if name not in _deprecated_names:\n        raise AttributeError(f\"module 'uvloop' has no attribute '{name}'\")\n    elif _sys.version_info[:2] >= (3, 16):\n        raise AttributeError(\n            f\"module 'uvloop' has no attribute '{name}' \"\n            f\"(it was removed in Python 3.16, use uvloop.run() instead)\"\n        )\n\n    import threading\n\n    def install() -> None:\n        \"\"\"A helper function to install uvloop policy.\n\n        This function is deprecated and will be removed in Python 3.16.\n        Use `uvloop.run()` instead.\n        \"\"\"\n        if _sys.version_info[:2] >= (3, 12):\n            _warnings.warn(\n                'uvloop.install() is deprecated in favor of uvloop.run() '\n                'starting with Python 3.12.',\n                DeprecationWarning,\n                stacklevel=1,\n            )\n        __asyncio.set_event_loop_policy(EventLoopPolicy())\n\n    class EventLoopPolicy(\n        # This is to avoid a mypy error about AbstractEventLoopPolicy\n        getattr(__asyncio, 'AbstractEventLoopPolicy')  # type: ignore[misc]\n    ):\n        \"\"\"Event loop policy for uvloop.\n\n        This class is deprecated and will be removed in Python 3.16.\n        Use `uvloop.run()` instead.\n\n        >>> import asyncio\n        >>> import uvloop\n        >>> asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())\n        >>> asyncio.get_event_loop()\n        <uvloop.Loop running=False closed=False debug=False>\n        \"\"\"\n\n        def _loop_factory(self) -> Loop:\n            return new_event_loop()\n\n        if _typing.TYPE_CHECKING:\n            # EventLoopPolicy doesn't implement these, but since they are\n            # marked as abstract in typeshed, we have to put them in so mypy\n            # thinks the base methods are overridden. This is the same approach\n            # taken for the Windows event loop policy classes in typeshed.\n            def get_child_watcher(self) -> _typing.NoReturn:\n                ...\n\n            def set_child_watcher(\n                self, watcher: _typing.Any\n            ) -> _typing.NoReturn:\n                ...\n\n        class _Local(threading.local):\n            _loop: _typing.Optional[_AbstractEventLoop] = None\n\n        def __init__(self) -> None:\n            self._local = self._Local()\n\n        def get_event_loop(self) -> _AbstractEventLoop:\n            \"\"\"Get the event loop for the current context.\n\n            Returns an instance of EventLoop or raises an exception.\n            \"\"\"\n            if self._local._loop is None:\n                raise RuntimeError(\n                    'There is no current event loop in thread %r.'\n                    % threading.current_thread().name\n                )\n\n            return self._local._loop\n\n        def set_event_loop(\n            self, loop: _typing.Optional[_AbstractEventLoop]\n        ) -> None:\n            \"\"\"Set the event loop.\"\"\"\n            if loop is not None and not isinstance(loop, _AbstractEventLoop):\n                raise TypeError(\n                    f\"loop must be an instance of AbstractEventLoop or None, \"\n                    f\"not '{type(loop).__name__}'\"\n                )\n            self._local._loop = loop\n\n        def new_event_loop(self) -> Loop:\n            \"\"\"Create a new event loop.\n\n            You must call set_event_loop() to make this the current event loop.\n            \"\"\"\n            return self._loop_factory()\n\n    globals()['install'] = install\n    globals()['EventLoopPolicy'] = EventLoopPolicy\n    return globals()[name]\n"
  },
  {
    "path": "uvloop/_noop.py",
    "content": "def noop() -> None:\n    \"\"\"Empty function to invoke CPython ceval loop.\"\"\"\n    return\n"
  },
  {
    "path": "uvloop/_testbase.py",
    "content": "\"\"\"Test utilities. Don't use outside of the uvloop project.\"\"\"\n\n\nimport asyncio\nimport asyncio.events\nimport collections\nimport contextlib\nimport gc\nimport logging\nimport os\nimport pprint\nimport re\nimport select\nimport socket\nimport ssl\nimport sys\nimport tempfile\nimport threading\nimport time\nimport unittest\nimport uvloop\n\n\nclass MockPattern(str):\n    def __eq__(self, other):\n        return bool(re.search(str(self), other, re.S))\n\n\nclass TestCaseDict(collections.UserDict):\n\n    def __init__(self, name):\n        super().__init__()\n        self.name = name\n\n    def __setitem__(self, key, value):\n        if key in self.data:\n            raise RuntimeError('duplicate test {}.{}'.format(\n                self.name, key))\n        super().__setitem__(key, value)\n\n\nclass BaseTestCaseMeta(type):\n\n    @classmethod\n    def __prepare__(mcls, name, bases):\n        return TestCaseDict(name)\n\n    def __new__(mcls, name, bases, dct):\n        for test_name in dct:\n            if not test_name.startswith('test_'):\n                continue\n            for base in bases:\n                if hasattr(base, test_name):\n                    raise RuntimeError(\n                        'duplicate test {}.{} (also defined in {} '\n                        'parent class)'.format(\n                            name, test_name, base.__name__))\n\n        return super().__new__(mcls, name, bases, dict(dct))\n\n\nclass BaseTestCase(unittest.TestCase, metaclass=BaseTestCaseMeta):\n\n    def new_loop(self):\n        raise NotImplementedError\n\n    def new_policy(self):\n        raise NotImplementedError\n\n    def mock_pattern(self, str):\n        return MockPattern(str)\n\n    async def wait_closed(self, obj):\n        if not isinstance(obj, asyncio.StreamWriter):\n            return\n        try:\n            await obj.wait_closed()\n        except (BrokenPipeError, ConnectionError):\n            pass\n\n    def is_asyncio_loop(self):\n        return type(self.loop).__module__.startswith('asyncio.')\n\n    def run_loop_briefly(self, *, delay=0.01):\n        self.loop.run_until_complete(asyncio.sleep(delay))\n\n    def loop_exception_handler(self, loop, context):\n        self.__unhandled_exceptions.append(context)\n        self.loop.default_exception_handler(context)\n\n    def setUp(self):\n        self.loop = self.new_loop()\n        asyncio.set_event_loop_policy(self.new_policy())\n        asyncio.set_event_loop(self.loop)\n        self._check_unclosed_resources_in_debug = True\n\n        self.loop.set_exception_handler(self.loop_exception_handler)\n        self.__unhandled_exceptions = []\n\n    def tearDown(self):\n        self.loop.close()\n\n        if self.__unhandled_exceptions:\n            print('Unexpected calls to loop.call_exception_handler():')\n            pprint.pprint(self.__unhandled_exceptions)\n            self.fail('unexpected calls to loop.call_exception_handler()')\n            return\n\n        if not self._check_unclosed_resources_in_debug:\n            return\n\n        # GC to show any resource warnings as the test completes\n        gc.collect()\n        gc.collect()\n        gc.collect()\n\n        if getattr(self.loop, '_debug_cc', False):\n            gc.collect()\n            gc.collect()\n            gc.collect()\n\n            self.assertEqual(\n                self.loop._debug_uv_handles_total,\n                self.loop._debug_uv_handles_freed,\n                'not all uv_handle_t handles were freed')\n\n            self.assertEqual(\n                self.loop._debug_cb_handles_count, 0,\n                'not all callbacks (call_soon) are GCed')\n\n            self.assertEqual(\n                self.loop._debug_cb_timer_handles_count, 0,\n                'not all timer callbacks (call_later) are GCed')\n\n            self.assertEqual(\n                self.loop._debug_stream_write_ctx_cnt, 0,\n                'not all stream write contexts are GCed')\n\n            for h_name, h_cnt in self.loop._debug_handles_current.items():\n                with self.subTest('Alive handle after test',\n                                  handle_name=h_name):\n                    self.assertEqual(\n                        h_cnt, 0,\n                        'alive {} after test'.format(h_name))\n\n            for h_name, h_cnt in self.loop._debug_handles_total.items():\n                with self.subTest('Total/closed handles',\n                                  handle_name=h_name):\n                    self.assertEqual(\n                        h_cnt, self.loop._debug_handles_closed[h_name],\n                        'total != closed for {}'.format(h_name))\n\n        asyncio.set_event_loop(None)\n        asyncio.set_event_loop_policy(None)\n        self.loop = None\n\n    def skip_unclosed_handles_check(self):\n        self._check_unclosed_resources_in_debug = False\n\n    def tcp_server(self, server_prog, *,\n                   family=socket.AF_INET,\n                   addr=None,\n                   timeout=5,\n                   backlog=1,\n                   max_clients=10):\n\n        if addr is None:\n            if family == socket.AF_UNIX:\n                with tempfile.NamedTemporaryFile() as tmp:\n                    addr = tmp.name\n            else:\n                addr = ('127.0.0.1', 0)\n\n        sock = socket.socket(family, socket.SOCK_STREAM)\n\n        if timeout is None:\n            raise RuntimeError('timeout is required')\n        if timeout <= 0:\n            raise RuntimeError('only blocking sockets are supported')\n        sock.settimeout(timeout)\n\n        try:\n            sock.bind(addr)\n            sock.listen(backlog)\n        except OSError as ex:\n            sock.close()\n            raise ex\n\n        return TestThreadedServer(\n            self, sock, server_prog, timeout, max_clients)\n\n    def tcp_client(self, client_prog,\n                   family=socket.AF_INET,\n                   timeout=10):\n\n        sock = socket.socket(family, socket.SOCK_STREAM)\n\n        if timeout is None:\n            raise RuntimeError('timeout is required')\n        if timeout <= 0:\n            raise RuntimeError('only blocking sockets are supported')\n        sock.settimeout(timeout)\n\n        return TestThreadedClient(\n            self, sock, client_prog, timeout)\n\n    def unix_server(self, *args, **kwargs):\n        return self.tcp_server(*args, family=socket.AF_UNIX, **kwargs)\n\n    def unix_client(self, *args, **kwargs):\n        return self.tcp_client(*args, family=socket.AF_UNIX, **kwargs)\n\n    @contextlib.contextmanager\n    def unix_sock_name(self):\n        with tempfile.TemporaryDirectory() as td:\n            fn = os.path.join(td, 'sock')\n            try:\n                yield fn\n            finally:\n                try:\n                    os.unlink(fn)\n                except OSError:\n                    pass\n\n    def _abort_socket_test(self, ex):\n        try:\n            self.loop.stop()\n        finally:\n            self.fail(ex)\n\n\ndef _cert_fullname(test_file_name, cert_file_name):\n    fullname = os.path.abspath(os.path.join(\n        os.path.dirname(test_file_name), 'certs', cert_file_name))\n    assert os.path.isfile(fullname)\n    return fullname\n\n\n@contextlib.contextmanager\ndef silence_long_exec_warning():\n\n    class Filter(logging.Filter):\n        def filter(self, record):\n            return not (record.msg.startswith('Executing') and\n                        record.msg.endswith('seconds'))\n\n    logger = logging.getLogger('asyncio')\n    filter = Filter()\n    logger.addFilter(filter)\n    try:\n        yield\n    finally:\n        logger.removeFilter(filter)\n\n\ndef find_free_port(start_from=50000):\n    for port in range(start_from, start_from + 500):\n        sock = socket.socket()\n        with sock:\n            try:\n                sock.bind(('', port))\n            except socket.error:\n                continue\n            else:\n                return port\n    raise RuntimeError('could not find a free port')\n\n\nclass SSLTestCase:\n\n    def _create_server_ssl_context(self, certfile, keyfile=None):\n        if hasattr(ssl, 'PROTOCOL_TLS_SERVER'):\n            sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)\n        elif hasattr(ssl, 'PROTOCOL_TLS'):\n            sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS)\n        else:\n            sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        sslcontext.options |= ssl.OP_NO_SSLv2\n        sslcontext.load_cert_chain(certfile, keyfile)\n        return sslcontext\n\n    def _create_client_ssl_context(self, *, disable_verify=True):\n        sslcontext = ssl.create_default_context()\n        sslcontext.check_hostname = False\n        if disable_verify:\n            sslcontext.verify_mode = ssl.CERT_NONE\n        return sslcontext\n\n    @contextlib.contextmanager\n    def _silence_eof_received_warning(self):\n        # TODO This warning has to be fixed in asyncio.\n        logger = logging.getLogger('asyncio')\n        filter = logging.Filter('has no effect when using ssl')\n        logger.addFilter(filter)\n        try:\n            yield\n        finally:\n            logger.removeFilter(filter)\n\n\nclass UVTestCase(BaseTestCase):\n\n    implementation = 'uvloop'\n\n    def new_loop(self):\n        return uvloop.new_event_loop()\n\n    def new_policy(self):\n        return uvloop.EventLoopPolicy()\n\n\nclass AIOTestCase(BaseTestCase):\n\n    implementation = 'asyncio'\n\n    def setUp(self):\n        super().setUp()\n\n        if sys.version_info < (3, 12):\n            watcher = asyncio.SafeChildWatcher()\n            watcher.attach_loop(self.loop)\n            asyncio.set_child_watcher(watcher)\n\n    def tearDown(self):\n        if sys.version_info < (3, 12):\n            asyncio.set_child_watcher(None)\n        super().tearDown()\n\n    def new_loop(self):\n        return asyncio.new_event_loop()\n\n    def new_policy(self):\n        return asyncio.DefaultEventLoopPolicy()\n\n\ndef has_IPv6():\n    server_sock = socket.socket(socket.AF_INET6)\n    with server_sock:\n        try:\n            server_sock.bind(('::1', 0))\n        except OSError:\n            return False\n        else:\n            return True\n\n\nhas_IPv6 = has_IPv6()\n\n\n###############################################################################\n# Socket Testing Utilities\n###############################################################################\n\n\nclass TestSocketWrapper:\n\n    def __init__(self, sock):\n        self.__sock = sock\n\n    def recv_all(self, n):\n        buf = b''\n        while len(buf) < n:\n            data = self.recv(n - len(buf))\n            if data == b'':\n                raise ConnectionAbortedError\n            buf += data\n        return buf\n\n    def starttls(self, ssl_context, *,\n                 server_side=False,\n                 server_hostname=None,\n                 do_handshake_on_connect=True):\n\n        assert isinstance(ssl_context, ssl.SSLContext)\n\n        ssl_sock = ssl_context.wrap_socket(\n            self.__sock, server_side=server_side,\n            server_hostname=server_hostname,\n            do_handshake_on_connect=do_handshake_on_connect)\n\n        if server_side:\n            ssl_sock.do_handshake()\n\n        self.__sock.close()\n        self.__sock = ssl_sock\n\n    def __getattr__(self, name):\n        return getattr(self.__sock, name)\n\n    def __repr__(self):\n        return '<{} {!r}>'.format(type(self).__name__, self.__sock)\n\n\nclass SocketThread(threading.Thread):\n\n    def stop(self):\n        self._active = False\n        self.join()\n\n    def __enter__(self):\n        self.start()\n        return self\n\n    def __exit__(self, *exc):\n        self.stop()\n\n\nclass TestThreadedClient(SocketThread):\n\n    def __init__(self, test, sock, prog, timeout):\n        threading.Thread.__init__(self, None, None, 'test-client')\n        self.daemon = True\n\n        self._timeout = timeout\n        self._sock = sock\n        self._active = True\n        self._prog = prog\n        self._test = test\n\n    def run(self):\n        try:\n            self._prog(TestSocketWrapper(self._sock))\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException as ex:\n            self._test._abort_socket_test(ex)\n\n\nclass TestThreadedServer(SocketThread):\n\n    def __init__(self, test, sock, prog, timeout, max_clients):\n        threading.Thread.__init__(self, None, None, 'test-server')\n        self.daemon = True\n\n        self._clients = 0\n        self._finished_clients = 0\n        self._max_clients = max_clients\n        self._timeout = timeout\n        self._sock = sock\n        self._active = True\n\n        self._prog = prog\n\n        self._s1, self._s2 = socket.socketpair()\n        self._s1.setblocking(False)\n\n        self._test = test\n\n    def stop(self):\n        try:\n            if self._s2 and self._s2.fileno() != -1:\n                try:\n                    self._s2.send(b'stop')\n                except OSError:\n                    pass\n        finally:\n            super().stop()\n\n    def run(self):\n        try:\n            with self._sock:\n                self._sock.setblocking(0)\n                self._run()\n        finally:\n            self._s1.close()\n            self._s2.close()\n\n    def _run(self):\n        while self._active:\n            if self._clients >= self._max_clients:\n                return\n\n            r, w, x = select.select(\n                [self._sock, self._s1], [], [], self._timeout)\n\n            if self._s1 in r:\n                return\n\n            if self._sock in r:\n                try:\n                    conn, addr = self._sock.accept()\n                except BlockingIOError:\n                    continue\n                except socket.timeout:\n                    if not self._active:\n                        return\n                    else:\n                        raise\n                else:\n                    self._clients += 1\n                    conn.settimeout(self._timeout)\n                    try:\n                        with conn:\n                            self._handle_client(conn)\n                    except (KeyboardInterrupt, SystemExit):\n                        raise\n                    except BaseException as ex:\n                        self._active = False\n                        try:\n                            raise\n                        finally:\n                            self._test._abort_socket_test(ex)\n\n    def _handle_client(self, sock):\n        self._prog(TestSocketWrapper(sock))\n\n    @property\n    def addr(self):\n        return self._sock.getsockname()\n\n\n###############################################################################\n# A few helpers from asyncio/tests/testutils.py\n###############################################################################\n\n\ndef run_briefly(loop):\n    async def once():\n        pass\n    gen = once()\n    t = loop.create_task(gen)\n    # Don't log a warning if the task is not done after run_until_complete().\n    # It occurs if the loop is stopped or if a task raises a BaseException.\n    t._log_destroy_pending = False\n    try:\n        loop.run_until_complete(t)\n    finally:\n        gen.close()\n\n\ndef run_until(loop, pred, timeout=30):\n    deadline = time.time() + timeout\n    while not pred():\n        if timeout is not None:\n            timeout = deadline - time.time()\n            if timeout <= 0:\n                raise asyncio.futures.TimeoutError()\n        loop.run_until_complete(asyncio.tasks.sleep(0.001))\n\n\n@contextlib.contextmanager\ndef disable_logger():\n    \"\"\"Context manager to disable asyncio logger.\n\n    For example, it can be used to ignore warnings in debug mode.\n    \"\"\"\n    old_level = asyncio.log.logger.level\n    try:\n        asyncio.log.logger.setLevel(logging.CRITICAL + 1)\n        yield\n    finally:\n        asyncio.log.logger.setLevel(old_level)\n"
  },
  {
    "path": "uvloop/_version.py",
    "content": "# This file MUST NOT contain anything but the __version__ assignment.\n#\n# When making a release, change the value of __version__\n# to an appropriate value, and open a pull request against\n# the correct branch (master if making a new feature release).\n# The commit message MUST contain a properly formatted release\n# log, and the commit must be signed.\n#\n# The release automation will: build and test the packages for the\n# supported platforms, publish the packages on PyPI, merge the PR\n# to the target branch, create a Git tag pointing to the commit.\n\n__version__ = '0.22.1'\n"
  },
  {
    "path": "uvloop/cbhandles.pxd",
    "content": "cdef class Handle:\n    cdef:\n        Loop loop\n        object context\n        bint _cancelled\n\n        str meth_name\n        int cb_type\n        void *callback\n        object arg1, arg2, arg3, arg4\n\n        object __weakref__\n\n        readonly _source_traceback\n\n    cdef inline _set_loop(self, Loop loop)\n    cdef inline _set_context(self, object context)\n\n    cdef inline _run(self)\n    cdef _cancel(self)\n\n    cdef _format_handle(self)\n\n\ncdef class TimerHandle:\n    cdef:\n        object callback\n        tuple args\n        bint _cancelled\n        UVTimer timer\n        Loop loop\n        object context\n        tuple _debug_info\n        object __weakref__\n        object _when\n\n    cdef _run(self)\n    cdef _cancel(self)\n    cdef inline _clear(self)\n"
  },
  {
    "path": "uvloop/cbhandles.pyx",
    "content": "@cython.no_gc_clear\n@cython.freelist(DEFAULT_FREELIST_SIZE)\ncdef class Handle:\n    def __cinit__(self):\n        self._cancelled = 0\n        self.cb_type = 0\n        self._source_traceback = None\n\n    cdef inline _set_loop(self, Loop loop):\n        self.loop = loop\n        if UVLOOP_DEBUG:\n            system.__atomic_fetch_add(\n                &loop._debug_cb_handles_total, 1, system.__ATOMIC_RELAXED)\n            system.__atomic_fetch_add(\n                &loop._debug_cb_handles_count, 1, system.__ATOMIC_RELAXED)\n        if loop._debug:\n            self._source_traceback = extract_stack()\n\n    cdef inline _set_context(self, object context):\n        if context is None:\n            context = Context_CopyCurrent()\n        self.context = context\n\n    def __dealloc__(self):\n        if UVLOOP_DEBUG and self.loop is not None:\n            system.__atomic_fetch_sub(\n                &self.loop._debug_cb_handles_count, 1, system.__ATOMIC_RELAXED)\n        if self.loop is None:\n            raise RuntimeError('Handle.loop is None in Handle.__dealloc__')\n\n    def __init__(self):\n        raise TypeError(\n            '{} is not supposed to be instantiated from Python'.format(\n                self.__class__.__name__))\n\n    cdef inline _run(self):\n        cdef:\n            int cb_type\n            object callback\n\n        if self._cancelled:\n            return\n\n        cb_type = self.cb_type\n\n        # Since _run is a cdef and there's no BoundMethod,\n        # we guard 'self' manually (since the callback\n        # might cause GC of the handle.)\n        Py_INCREF(self)\n\n        try:\n            assert self.context is not None\n            Context_Enter(self.context)\n\n            if cb_type == 1:\n                callback = self.arg1\n                if callback is None:\n                    raise RuntimeError(\n                        'cannot run Handle; callback is not set')\n\n                args = self.arg2\n\n                if args is None:\n                    callback()\n                else:\n                    callback(*args)\n\n            elif cb_type == 2:\n                (<method_t>self.callback)(self.arg1)\n\n            elif cb_type == 3:\n                (<method1_t>self.callback)(self.arg1, self.arg2)\n\n            elif cb_type == 4:\n                (<method2_t>self.callback)(self.arg1, self.arg2, self.arg3)\n\n            elif cb_type == 5:\n                (<method3_t>self.callback)(\n                    self.arg1, self.arg2, self.arg3, self.arg4)\n\n            else:\n                raise RuntimeError('invalid Handle.cb_type: {}'.format(\n                    cb_type))\n\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException as ex:\n            if cb_type == 1:\n                msg = 'Exception in callback {}'.format(callback)\n            else:\n                msg = 'Exception in callback {}'.format(self.meth_name)\n\n            context = {\n                'message': msg,\n                'exception': ex,\n                'handle': self,\n            }\n\n            if self._source_traceback is not None:\n                context['source_traceback'] = self._source_traceback\n\n            self.loop.call_exception_handler(context)\n\n        finally:\n            context = self.context\n            Py_DECREF(self)\n            Context_Exit(context)\n\n    cdef _cancel(self):\n        self._cancelled = 1\n        self.callback = NULL\n        self.arg1 = self.arg2 = self.arg3 = self.arg4 = None\n\n    cdef _format_handle(self):\n        # Mirrors `asyncio.base_events._format_handle`.\n        if self.cb_type == 1 and self.arg1 is not None:\n            cb = self.arg1\n            if isinstance(getattr(cb, '__self__', None), aio_Task):\n                try:\n                    return repr(cb.__self__)\n                except (AttributeError, TypeError, ValueError) as ex:\n                    # Cython generates empty __code__ objects for coroutines\n                    # that can crash asyncio.Task.__repr__ with an\n                    # AttributeError etc.  Guard against that.\n                    self.loop.call_exception_handler({\n                        'message': 'exception in Task.__repr__',\n                        'task': cb.__self__,\n                        'exception': ex,\n                        'handle': self,\n                    })\n        return repr(self)\n\n    # Public API\n\n    def __repr__(self):\n        info = [self.__class__.__name__]\n\n        if self._cancelled:\n            info.append('cancelled')\n\n        if self.cb_type == 1 and self.arg1 is not None:\n            func = self.arg1\n            # Cython can unset func.__qualname__/__name__, hence the checks.\n            if hasattr(func, '__qualname__') and func.__qualname__:\n                cb_name = func.__qualname__\n            elif hasattr(func, '__name__') and func.__name__:\n                cb_name = func.__name__\n            else:\n                cb_name = repr(func)\n\n            info.append(cb_name)\n        elif self.meth_name is not None:\n            info.append(self.meth_name)\n\n        if self._source_traceback is not None:\n            frame = self._source_traceback[-1]\n            info.append('created at {}:{}'.format(frame[0], frame[1]))\n\n        return '<' + ' '.join(info) + '>'\n\n    def cancel(self):\n        self._cancel()\n\n    def cancelled(self):\n        return self._cancelled\n\n\n@cython.no_gc_clear\n@cython.freelist(DEFAULT_FREELIST_SIZE)\ncdef class TimerHandle:\n    def __cinit__(self, Loop loop, object callback, object args,\n                  uint64_t delay, object context):\n\n        self.loop = loop\n        self.callback = callback\n        self.args = args\n        self._cancelled = 0\n\n        if UVLOOP_DEBUG:\n            system.__atomic_fetch_add(\n                &self.loop._debug_cb_timer_handles_total, 1, system.__ATOMIC_RELAXED)\n            system.__atomic_fetch_add(\n                &self.loop._debug_cb_timer_handles_count, 1, system.__ATOMIC_RELAXED)\n\n        if context is None:\n            context = Context_CopyCurrent()\n        self.context = context\n\n        if loop._debug:\n            self._debug_info = (\n                format_callback_name(callback),\n                extract_stack()\n            )\n        else:\n            self._debug_info = None\n\n        self.timer = UVTimer.new(\n            loop, <method_t>self._run, self, delay)\n\n        self.timer.start()\n        self._when = self.timer.get_when() * 1e-3\n\n        # Only add to loop._timers when `self.timer` is successfully created\n        loop._timers.add(self)\n\n    property _source_traceback:\n        def __get__(self):\n            if self._debug_info is not None:\n                return self._debug_info[1]\n\n    def __dealloc__(self):\n        if UVLOOP_DEBUG:\n            system.__atomic_fetch_sub(\n                &self.loop._debug_cb_timer_handles_count, 1, system.__ATOMIC_RELAXED)\n        if self.timer is not None:\n            raise RuntimeError('active TimerHandle is deallacating')\n\n    cdef _cancel(self):\n        if self._cancelled == 1:\n            return\n        self._cancelled = 1\n        self._clear()\n\n    cdef inline _clear(self):\n        if self.timer is None:\n            return\n\n        self.callback = None\n        self.args = None\n\n        try:\n            self.loop._timers.remove(self)\n        finally:\n            self.timer._close()\n            self.timer = None  # let the UVTimer handle GC\n\n    cdef _run(self):\n        if self._cancelled == 1:\n            return\n        if self.callback is None:\n            raise RuntimeError('cannot run TimerHandle; callback is not set')\n\n        callback = self.callback\n        args = self.args\n\n        # Since _run is a cdef and there's no BoundMethod,\n        # we guard 'self' manually.\n        Py_INCREF(self)\n\n        if self.loop._debug:\n            started = time_monotonic()\n        try:\n            assert self.context is not None\n            Context_Enter(self.context)\n\n            if args is not None:\n                callback(*args)\n            else:\n                callback()\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException as ex:\n            context = {\n                'message': 'Exception in callback {}'.format(callback),\n                'exception': ex,\n                'handle': self,\n            }\n\n            if self._debug_info is not None:\n                context['source_traceback'] = self._debug_info[1]\n\n            self.loop.call_exception_handler(context)\n        else:\n            if self.loop._debug:\n                delta = time_monotonic() - started\n                if delta > self.loop.slow_callback_duration:\n                    aio_logger.warning(\n                        'Executing %r took %.3f seconds',\n                        self, delta)\n        finally:\n            context = self.context\n            Py_DECREF(self)\n            Context_Exit(context)\n            self._clear()\n\n    # Public API\n\n    def __repr__(self):\n        info = [self.__class__.__name__]\n\n        if self._cancelled:\n            info.append('cancelled')\n\n        if self._debug_info is not None:\n            callback_name = self._debug_info[0]\n            source_traceback = self._debug_info[1]\n        else:\n            callback_name = None\n            source_traceback = None\n\n        if callback_name is not None:\n            info.append(callback_name)\n        elif self.callback is not None:\n            info.append(format_callback_name(self.callback))\n\n        if source_traceback is not None:\n            frame = source_traceback[-1]\n            info.append('created at {}:{}'.format(frame[0], frame[1]))\n\n        return '<' + ' '.join(info) + '>'\n\n    def cancelled(self):\n        return self._cancelled\n\n    def cancel(self):\n        self._cancel()\n\n    def when(self):\n        return self._when\n\n\ncdef format_callback_name(func):\n    if hasattr(func, '__qualname__'):\n        cb_name = getattr(func, '__qualname__')\n    elif hasattr(func, '__name__'):\n        cb_name = getattr(func, '__name__')\n    else:\n        cb_name = repr(func)\n    return cb_name\n\n\ncdef new_Handle(Loop loop, object callback, object args, object context):\n    cdef Handle handle\n    handle = Handle.__new__(Handle)\n    handle._set_loop(loop)\n    handle._set_context(context)\n\n    handle.cb_type = 1\n\n    handle.arg1 = callback\n    handle.arg2 = args\n\n    return handle\n\n\ncdef new_MethodHandle(Loop loop, str name, method_t callback, object context,\n                      object bound_to):\n    cdef Handle handle\n    handle = Handle.__new__(Handle)\n    handle._set_loop(loop)\n    handle._set_context(context)\n\n    handle.cb_type = 2\n    handle.meth_name = name\n\n    handle.callback = <void*> callback\n    handle.arg1 = bound_to\n\n    return handle\n\n\ncdef new_MethodHandle1(Loop loop, str name, method1_t callback, object context,\n                       object bound_to, object arg):\n\n    cdef Handle handle\n    handle = Handle.__new__(Handle)\n    handle._set_loop(loop)\n    handle._set_context(context)\n\n    handle.cb_type = 3\n    handle.meth_name = name\n\n    handle.callback = <void*> callback\n    handle.arg1 = bound_to\n    handle.arg2 = arg\n\n    return handle\n\n\ncdef new_MethodHandle2(Loop loop, str name, method2_t callback, object context,\n                       object bound_to, object arg1, object arg2):\n\n    cdef Handle handle\n    handle = Handle.__new__(Handle)\n    handle._set_loop(loop)\n    handle._set_context(context)\n\n    handle.cb_type = 4\n    handle.meth_name = name\n\n    handle.callback = <void*> callback\n    handle.arg1 = bound_to\n    handle.arg2 = arg1\n    handle.arg3 = arg2\n\n    return handle\n\n\ncdef new_MethodHandle3(Loop loop, str name, method3_t callback, object context,\n                       object bound_to, object arg1, object arg2, object arg3):\n\n    cdef Handle handle\n    handle = Handle.__new__(Handle)\n    handle._set_loop(loop)\n    handle._set_context(context)\n\n    handle.cb_type = 5\n    handle.meth_name = name\n\n    handle.callback = <void*> callback\n    handle.arg1 = bound_to\n    handle.arg2 = arg1\n    handle.arg3 = arg2\n    handle.arg4 = arg3\n\n    return handle\n\n\ncdef extract_stack():\n    \"\"\"Replacement for traceback.extract_stack() that only does the\n    necessary work for asyncio debug mode.\n    \"\"\"\n    try:\n        f = sys_getframe()\n    # sys._getframe() might raise ValueError if being called without a frame, e.g.\n    # from Cython or similar C extensions.\n    except ValueError:\n        return None\n    if f is None:\n        return\n\n    try:\n        stack = tb_StackSummary.extract(tb_walk_stack(f),\n                                        limit=DEBUG_STACK_DEPTH,\n                                        lookup_lines=False)\n    finally:\n        f = None\n\n    stack.reverse()\n    return stack\n"
  },
  {
    "path": "uvloop/dns.pyx",
    "content": "cdef __port_to_int(port, proto):\n    if type(port) is int:\n        return port\n\n    if port is None or port == '' or port == b'':\n        return 0\n\n    try:\n        return int(port)\n    except (ValueError, TypeError):\n        pass\n\n    if isinstance(port, bytes):\n        port = port.decode()\n\n    if isinstance(port, str) and proto is not None:\n        if proto == uv.IPPROTO_TCP:\n            return socket_getservbyname(port, 'tcp')\n        elif proto == uv.IPPROTO_UDP:\n            return socket_getservbyname(port, 'udp')\n\n    raise OSError('service/proto not found')\n\n\ncdef __convert_sockaddr_to_pyaddr(const system.sockaddr* addr):\n    # Converts sockaddr structs into what Python socket\n    # module can understand:\n    #   - for IPv4 a tuple of (host, port)\n    #   - for IPv6 a tuple of (host, port, flowinfo, scope_id)\n\n    cdef:\n        char buf[128]  # INET6_ADDRSTRLEN is usually 46\n        int err\n        system.sockaddr_in *addr4\n        system.sockaddr_in6 *addr6\n        system.sockaddr_un *addr_un\n\n    if addr.sa_family == uv.AF_INET:\n        addr4 = <system.sockaddr_in*>addr\n\n        err = uv.uv_ip4_name(addr4, buf, sizeof(buf))\n        if err < 0:\n            raise convert_error(err)\n\n        return (\n            PyUnicode_FromString(buf),\n            system.ntohs(addr4.sin_port)\n        )\n\n    elif addr.sa_family == uv.AF_INET6:\n        addr6 = <system.sockaddr_in6*>addr\n\n        err = uv.uv_ip6_name(addr6, buf, sizeof(buf))\n        if err < 0:\n            raise convert_error(err)\n\n        return (\n            PyUnicode_FromString(buf),\n            system.ntohs(addr6.sin6_port),\n            system.ntohl(addr6.sin6_flowinfo),\n            addr6.sin6_scope_id\n        )\n\n    elif addr.sa_family == uv.AF_UNIX:\n        addr_un = <system.sockaddr_un*>addr\n        return system.MakeUnixSockPyAddr(addr_un)\n\n    raise RuntimeError(\"cannot convert sockaddr into Python object\")\n\n\n@cython.freelist(DEFAULT_FREELIST_SIZE)\ncdef class SockAddrHolder:\n    cdef:\n        int family\n        system.sockaddr_storage addr\n        Py_ssize_t addr_size\n\n\ncdef LruCache sockaddrs = LruCache(maxsize=DNS_PYADDR_TO_SOCKADDR_CACHE_SIZE)\n\n\ncdef __convert_pyaddr_to_sockaddr(int family, object addr,\n                                  system.sockaddr* res):\n    cdef:\n        int err\n        int addr_len\n        int scope_id = 0\n        int flowinfo = 0\n        char *buf\n        Py_ssize_t buflen\n        SockAddrHolder ret\n\n    ret = sockaddrs.get(addr, None)\n    if ret is not None and ret.family == family:\n        memcpy(res, &ret.addr, ret.addr_size)\n        return\n\n    ret = SockAddrHolder.__new__(SockAddrHolder)\n    if family == uv.AF_INET:\n        if not isinstance(addr, tuple):\n            raise TypeError('AF_INET address must be tuple')\n        if len(addr) != 2:\n            raise ValueError('AF_INET address must be tuple of (host, port)')\n        host, port = addr\n        if isinstance(host, str):\n            try:\n                # idna codec is rather slow, so we try ascii first.\n                host = host.encode('ascii')\n            except UnicodeEncodeError:\n                host = host.encode('idna')\n        if not isinstance(host, (bytes, bytearray)):\n            raise TypeError('host must be a string or bytes object')\n\n        port = __port_to_int(port, None)\n\n        ret.addr_size = sizeof(system.sockaddr_in)\n        err = uv.uv_ip4_addr(host, <int>port, <system.sockaddr_in*>&ret.addr)\n        if err < 0:\n            raise convert_error(err)\n\n    elif family == uv.AF_INET6:\n        if not isinstance(addr, tuple):\n            raise TypeError('AF_INET6 address must be tuple')\n\n        addr_len = len(addr)\n        if addr_len < 2 or addr_len > 4:\n            raise ValueError(\n                'AF_INET6 must be a tuple of 2-4 parameters: '\n                '(host, port, flowinfo?, scope_id?)')\n\n        host = addr[0]\n        if isinstance(host, str):\n            try:\n                # idna codec is rather slow, so we try ascii first.\n                host = host.encode('ascii')\n            except UnicodeEncodeError:\n                host = host.encode('idna')\n        if not isinstance(host, (bytes, bytearray)):\n            raise TypeError('host must be a string or bytes object')\n\n        port = __port_to_int(addr[1], None)\n\n        if addr_len > 2:\n            flowinfo = addr[2]\n        if addr_len > 3:\n            scope_id = addr[3]\n\n        ret.addr_size = sizeof(system.sockaddr_in6)\n\n        err = uv.uv_ip6_addr(host, port, <system.sockaddr_in6*>&ret.addr)\n        if err < 0:\n            raise convert_error(err)\n\n        (<system.sockaddr_in6*>&ret.addr).sin6_flowinfo = flowinfo\n        (<system.sockaddr_in6*>&ret.addr).sin6_scope_id = scope_id\n\n    elif family == uv.AF_UNIX:\n        if isinstance(addr, str):\n            addr = addr.encode(sys_getfilesystemencoding())\n        elif not isinstance(addr, bytes):\n            raise TypeError('AF_UNIX address must be a str or a bytes object')\n\n        PyBytes_AsStringAndSize(addr, &buf, &buflen)\n        if buflen > 107:\n            raise ValueError(\n                f'unix socket path {addr!r} is longer than 107 characters')\n\n        ret.addr_size = sizeof(system.sockaddr_un)\n        memset(&ret.addr, 0, sizeof(system.sockaddr_un))\n        (<system.sockaddr_un*>&ret.addr).sun_family = uv.AF_UNIX\n        memcpy((<system.sockaddr_un*>&ret.addr).sun_path, buf, buflen)\n\n    else:\n        raise ValueError(\n            f'expected AF_INET, AF_INET6, or AF_UNIX family, got {family}')\n\n    ret.family = family\n    sockaddrs[addr] = ret\n    memcpy(res, &ret.addr, ret.addr_size)\n\n\ncdef __static_getaddrinfo(object host, object port,\n                          int family, int type,\n                          int proto,\n                          system.sockaddr *addr):\n\n    if proto not in {0, uv.IPPROTO_TCP, uv.IPPROTO_UDP}:\n        return\n\n    if _is_sock_stream(type):\n        proto = uv.IPPROTO_TCP\n    elif _is_sock_dgram(type):\n        proto = uv.IPPROTO_UDP\n    else:\n        return\n\n    try:\n        port = __port_to_int(port, proto)\n    except Exception:\n        return\n\n    hp = (host, port)\n    if family == uv.AF_UNSPEC:\n        try:\n            __convert_pyaddr_to_sockaddr(uv.AF_INET, hp, addr)\n        except Exception:\n            pass\n        else:\n            return (uv.AF_INET, type, proto)\n\n        try:\n            __convert_pyaddr_to_sockaddr(uv.AF_INET6, hp, addr)\n        except Exception:\n            pass\n        else:\n            return (uv.AF_INET6, type, proto)\n\n    else:\n        try:\n            __convert_pyaddr_to_sockaddr(family, hp, addr)\n        except Exception:\n            pass\n        else:\n            return (family, type, proto)\n\n\ncdef __static_getaddrinfo_pyaddr(object host, object port,\n                                 int family, int type,\n                                 int proto, int flags):\n\n    cdef:\n        system.sockaddr_storage addr\n        object triplet\n\n    triplet = __static_getaddrinfo(\n        host, port, family, type,\n        proto, <system.sockaddr*>&addr)\n    if triplet is None:\n        return\n\n    af, type, proto = triplet\n\n    try:\n        pyaddr = __convert_sockaddr_to_pyaddr(<system.sockaddr*>&addr)\n    except Exception:\n        return\n\n    # When the host is an IP while type is one of TCP or UDP, different libc\n    # implementations of getaddrinfo() behave differently:\n    # 1. When AI_CANONNAME is set:\n    #    * glibc: returns ai_canonname\n    #    * musl: returns ai_canonname\n    #    * macOS: returns an empty string for ai_canonname\n    # 2. When AI_CANONNAME is NOT set:\n    #    * glibc: returns an empty string for ai_canonname\n    #    * musl: returns ai_canonname\n    #    * macOS: returns an empty string for ai_canonname\n    # At the same time, libuv and CPython both uses libc directly, even though\n    # this different behavior is violating what is in the documentation.\n    #\n    # uvloop potentially should be a 100% drop-in replacement for asyncio,\n    # doing whatever asyncio does, especially when the libc implementations are\n    # also different in the same way. However, making our implementation to be\n    # consistent with libc/CPython would be complex and hard to maintain\n    # (including caching libc behaviors when flag is/not set), therefore we\n    # decided to simply normalize the behavior in uvloop for this very marginal\n    # case following the documentation, even though uvloop would behave\n    # differently to asyncio on macOS and musl platforms, when again the host\n    # is an IP and type is one of TCP or UDP.\n    # All other cases are still asyncio-compatible.\n    if flags & socket_AI_CANONNAME:\n        if isinstance(host, str):\n            canon_name = host\n        else:\n            canon_name = host.decode('ascii')\n    else:\n        canon_name = ''\n\n    return (\n        _intenum_converter(af, socket_AddressFamily),\n        _intenum_converter(type, socket_SocketKind),\n        proto,\n        canon_name,\n        pyaddr,\n    )\n\n\n@cython.freelist(DEFAULT_FREELIST_SIZE)\ncdef class AddrInfo:\n    cdef:\n        system.addrinfo *data\n\n    def __cinit__(self):\n        self.data = NULL\n\n    def __dealloc__(self):\n        if self.data is not NULL:\n            uv.uv_freeaddrinfo(self.data)  # returns void\n            self.data = NULL\n\n    cdef void set_data(self, system.addrinfo *data) noexcept:\n        self.data = data\n\n    cdef unpack(self):\n        cdef:\n            list result = []\n            system.addrinfo *ptr\n\n        if self.data is NULL:\n            raise RuntimeError('AddrInfo.data is NULL')\n\n        ptr = self.data\n        while ptr != NULL:\n            if ptr.ai_addr.sa_family in (uv.AF_INET, uv.AF_INET6):\n                result.append((\n                    _intenum_converter(ptr.ai_family, socket_AddressFamily),\n                    _intenum_converter(ptr.ai_socktype, socket_SocketKind),\n                    ptr.ai_protocol,\n                    ('' if ptr.ai_canonname is NULL else\n                        (<bytes>ptr.ai_canonname).decode()),\n                    __convert_sockaddr_to_pyaddr(ptr.ai_addr)\n                ))\n\n            ptr = ptr.ai_next\n\n        return result\n\n    @staticmethod\n    cdef int isinstance(object other):\n        return type(other) is AddrInfo\n\n\ncdef class AddrInfoRequest(UVRequest):\n    cdef:\n        system.addrinfo hints\n        object callback\n        uv.uv_getaddrinfo_t _req_data\n\n    def __cinit__(self, Loop loop,\n                  bytes host, bytes port,\n                  int family, int type, int proto, int flags,\n                  object callback):\n\n        cdef:\n            int err\n            char *chost\n            char *cport\n\n        if host is None:\n            chost = NULL\n        elif host == b'' and sys.platform == 'darwin':\n            # It seems `getaddrinfo(\"\", ...)` on macOS is equivalent to\n            # `getaddrinfo(\"localhost\", ...)`. This is inconsistent with\n            # libuv 1.48 which treats empty nodename as EINVAL.\n            chost = <char*>'localhost'\n        else:\n            chost = <char*>host\n\n        if port is None:\n            cport = NULL\n        else:\n            cport = <char*>port\n\n        memset(&self.hints, 0, sizeof(system.addrinfo))\n        self.hints.ai_flags = flags\n        self.hints.ai_family = family\n        self.hints.ai_socktype = type\n        self.hints.ai_protocol = proto\n\n        self.request = <uv.uv_req_t*> &self._req_data\n        self.callback = callback\n        self.request.data = <void*>self\n\n        err = uv.uv_getaddrinfo(loop.uvloop,\n                                <uv.uv_getaddrinfo_t*>self.request,\n                                __on_addrinfo_resolved,\n                                chost,\n                                cport,\n                                &self.hints)\n\n        if err < 0:\n            self.on_done()\n            try:\n                if err == uv.UV_EINVAL:\n                    # Convert UV_EINVAL to EAI_NONAME to match libc behavior\n                    msg = system.gai_strerror(socket_EAI_NONAME).decode('utf-8')\n                    ex = socket_gaierror(socket_EAI_NONAME, msg)\n                else:\n                    ex = convert_error(err)\n            except Exception as ex:\n                callback(ex)\n            else:\n                callback(ex)\n\n\ncdef class NameInfoRequest(UVRequest):\n    cdef:\n        object callback\n        uv.uv_getnameinfo_t _req_data\n\n    def __cinit__(self, Loop loop, callback):\n        self.request = <uv.uv_req_t*> &self._req_data\n        self.callback = callback\n        self.request.data = <void*>self\n\n    cdef query(self, system.sockaddr *addr, int flags):\n        cdef int err\n        err = uv.uv_getnameinfo(self.loop.uvloop,\n                                <uv.uv_getnameinfo_t*>self.request,\n                                __on_nameinfo_resolved,\n                                addr,\n                                flags)\n        if err < 0:\n            self.on_done()\n            self.callback(convert_error(err))\n\n\ncdef _intenum_converter(value, enum_klass):\n    try:\n        return enum_klass(value)\n    except ValueError:\n        return value\n\n\ncdef void __on_addrinfo_resolved(\n    uv.uv_getaddrinfo_t *resolver,\n    int status,\n    system.addrinfo *res,\n) noexcept with gil:\n\n    if resolver.data is NULL:\n        aio_logger.error(\n            'AddrInfoRequest callback called with NULL resolver.data')\n        return\n\n    cdef:\n        AddrInfoRequest request = <AddrInfoRequest> resolver.data\n        Loop loop = request.loop\n        object callback = request.callback\n        AddrInfo ai\n\n    try:\n        if status < 0:\n            callback(convert_error(status))\n        else:\n            ai = AddrInfo()\n            ai.set_data(res)\n            callback(ai)\n    except (KeyboardInterrupt, SystemExit):\n        raise\n    except BaseException as ex:\n        loop._handle_exception(ex)\n    finally:\n        request.on_done()\n\n\ncdef void __on_nameinfo_resolved(\n    uv.uv_getnameinfo_t* req,\n    int status,\n    const char* hostname,\n    const char* service,\n) noexcept with gil:\n    cdef:\n        NameInfoRequest request = <NameInfoRequest> req.data\n        Loop loop = request.loop\n        object callback = request.callback\n\n    try:\n        if status < 0:\n            callback(convert_error(status))\n        else:\n            callback(((<bytes>hostname).decode(),\n                      (<bytes>service).decode()))\n    except (KeyboardInterrupt, SystemExit):\n        raise\n    except BaseException as ex:\n        loop._handle_exception(ex)\n    finally:\n        request.on_done()\n"
  },
  {
    "path": "uvloop/errors.pyx",
    "content": "cdef str __strerr(int errno):\n    return strerror(errno).decode()\n\n\ncdef __convert_python_error(int uverr):\n    # XXX Won't work for Windows:\n    # From libuv docs:\n    #      Implementation detail: on Unix error codes are the\n    #      negated errno (or -errno), while on Windows they\n    #      are defined by libuv to arbitrary negative numbers.\n    cdef int oserr = -uverr\n\n    exc = OSError\n\n    if uverr in (uv.UV_EACCES, uv.UV_EPERM):\n        exc = PermissionError\n\n    elif uverr in (uv.UV_EAGAIN, uv.UV_EALREADY):\n        exc = BlockingIOError\n\n    elif uverr in (uv.UV_EPIPE, uv.UV_ESHUTDOWN):\n        exc = BrokenPipeError\n\n    elif uverr == uv.UV_ECONNABORTED:\n        exc = ConnectionAbortedError\n\n    elif uverr == uv.UV_ECONNREFUSED:\n        exc = ConnectionRefusedError\n\n    elif uverr == uv.UV_ECONNRESET:\n        exc = ConnectionResetError\n\n    elif uverr == uv.UV_EEXIST:\n        exc = FileExistsError\n\n    elif uverr == uv.UV_ENOENT:\n        exc = FileNotFoundError\n\n    elif uverr == uv.UV_EINTR:\n        exc = InterruptedError\n\n    elif uverr == uv.UV_EISDIR:\n        exc = IsADirectoryError\n\n    elif uverr == uv.UV_ESRCH:\n        exc = ProcessLookupError\n\n    elif uverr == uv.UV_ETIMEDOUT:\n        exc = TimeoutError\n\n    return exc(oserr, __strerr(oserr))\n\n\ncdef int __convert_socket_error(int uverr):\n    cdef int sock_err = 0\n\n    if uverr == uv.UV_EAI_ADDRFAMILY:\n        sock_err = socket_EAI_ADDRFAMILY\n\n    elif uverr == uv.UV_EAI_AGAIN:\n        sock_err = socket_EAI_AGAIN\n\n    elif uverr == uv.UV_EAI_BADFLAGS:\n        sock_err = socket_EAI_BADFLAGS\n\n    elif uverr == uv.UV_EAI_BADHINTS:\n        sock_err = socket_EAI_BADHINTS\n\n    elif uverr == uv.UV_EAI_CANCELED:\n        sock_err = socket_EAI_CANCELED\n\n    elif uverr == uv.UV_EAI_FAIL:\n        sock_err = socket_EAI_FAIL\n\n    elif uverr == uv.UV_EAI_FAMILY:\n        sock_err = socket_EAI_FAMILY\n\n    elif uverr == uv.UV_EAI_MEMORY:\n        sock_err = socket_EAI_MEMORY\n\n    elif uverr == uv.UV_EAI_NODATA:\n        sock_err = socket_EAI_NODATA\n\n    elif uverr == uv.UV_EAI_NONAME:\n        sock_err = socket_EAI_NONAME\n\n    elif uverr == uv.UV_EAI_OVERFLOW:\n        sock_err = socket_EAI_OVERFLOW\n\n    elif uverr == uv.UV_EAI_PROTOCOL:\n        sock_err = socket_EAI_PROTOCOL\n\n    elif uverr == uv.UV_EAI_SERVICE:\n        sock_err = socket_EAI_SERVICE\n\n    elif uverr == uv.UV_EAI_SOCKTYPE:\n        sock_err = socket_EAI_SOCKTYPE\n\n    return sock_err\n\n\ncdef convert_error(int uverr):\n    cdef int sock_err\n\n    if uverr == uv.UV_ECANCELED:\n        return aio_CancelledError()\n\n    sock_err = __convert_socket_error(uverr)\n    if sock_err:\n        msg = system.gai_strerror(sock_err).decode('utf-8')\n        return socket_gaierror(sock_err, msg)\n\n    return __convert_python_error(uverr)\n"
  },
  {
    "path": "uvloop/handles/async_.pxd",
    "content": "cdef class UVAsync(UVHandle):\n    cdef:\n        method_t callback\n        object ctx\n\n    cdef _init(self, Loop loop, method_t callback, object ctx)\n\n    cdef send(self)\n\n    @staticmethod\n    cdef UVAsync new(Loop loop, method_t callback, object ctx)\n"
  },
  {
    "path": "uvloop/handles/async_.pyx",
    "content": "@cython.no_gc_clear\ncdef class UVAsync(UVHandle):\n    cdef _init(self, Loop loop, method_t callback, object ctx):\n        cdef int err\n\n        self._start_init(loop)\n\n        self._handle = <uv.uv_handle_t*>PyMem_RawMalloc(sizeof(uv.uv_async_t))\n        if self._handle is NULL:\n            self._abort_init()\n            raise MemoryError()\n\n        err = uv.uv_async_init(self._loop.uvloop,\n                               <uv.uv_async_t*>self._handle,\n                               __uvasync_callback)\n        if err < 0:\n            self._abort_init()\n            raise convert_error(err)\n\n        self._finish_init()\n\n        self.callback = callback\n        self.ctx = ctx\n\n    cdef send(self):\n        cdef int err\n\n        self._ensure_alive()\n\n        err = uv.uv_async_send(<uv.uv_async_t*>self._handle)\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n\n    @staticmethod\n    cdef UVAsync new(Loop loop, method_t callback, object ctx):\n        cdef UVAsync handle\n        handle = UVAsync.__new__(UVAsync)\n        handle._init(loop, callback, ctx)\n        return handle\n\n\ncdef void __uvasync_callback(\n    uv.uv_async_t* handle,\n) noexcept with gil:\n    if __ensure_handle_data(<uv.uv_handle_t*>handle, \"UVAsync callback\") == 0:\n        return\n\n    cdef:\n        UVAsync async_ = <UVAsync> handle.data\n        method_t cb = async_.callback\n    try:\n        cb(async_.ctx)\n    except BaseException as ex:\n        async_._error(ex, False)\n"
  },
  {
    "path": "uvloop/handles/basetransport.pxd",
    "content": "cdef class UVBaseTransport(UVSocketHandle):\n\n    cdef:\n        readonly bint _closing\n\n        bint _protocol_connected\n        bint _protocol_paused\n        object _protocol_data_received\n        size_t _high_water\n        size_t _low_water\n\n        object _protocol\n        Server _server\n        object _waiter\n\n        dict _extra_info\n\n        uint32_t _conn_lost\n\n        object __weakref__\n\n    # All \"inline\" methods are final\n\n    cdef inline _maybe_pause_protocol(self)\n    cdef inline _maybe_resume_protocol(self)\n\n    cdef inline _schedule_call_connection_made(self)\n    cdef inline _schedule_call_connection_lost(self, exc)\n\n    cdef _wakeup_waiter(self)\n    cdef _call_connection_made(self)\n    cdef _call_connection_lost(self, exc)\n\n    # Overloads of UVHandle methods:\n    cdef _fatal_error(self, exc, throw, reason=?)\n    cdef _close(self)\n\n    cdef inline _set_server(self, Server server)\n    cdef inline _set_waiter(self, object waiter)\n\n    cdef _set_protocol(self, object protocol)\n    cdef _clear_protocol(self)\n\n    cdef inline _init_protocol(self)\n    cdef inline _add_extra_info(self, str name, object obj)\n\n    # === overloads ===\n\n    cdef _new_socket(self)\n    cdef size_t _get_write_buffer_size(self)\n\n    cdef bint _is_reading(self)\n    cdef _start_reading(self)\n    cdef _stop_reading(self)\n"
  },
  {
    "path": "uvloop/handles/basetransport.pyx",
    "content": "cdef class UVBaseTransport(UVSocketHandle):\n\n    def __cinit__(self):\n        # Flow control\n        self._high_water = FLOW_CONTROL_HIGH_WATER * 1024\n        self._low_water = FLOW_CONTROL_HIGH_WATER // 4\n\n        self._protocol = None\n        self._protocol_connected = 0\n        self._protocol_paused = 0\n        self._protocol_data_received = None\n\n        self._server = None\n        self._waiter = None\n        self._extra_info = None\n\n        self._conn_lost = 0\n\n        self._closing = 0\n\n    cdef size_t _get_write_buffer_size(self):\n        return 0\n\n    cdef inline _schedule_call_connection_made(self):\n        self._loop._call_soon_handle(\n            new_MethodHandle(self._loop,\n                             \"UVTransport._call_connection_made\",\n                             <method_t>self._call_connection_made,\n                             self.context,\n                             self))\n\n    cdef inline _schedule_call_connection_lost(self, exc):\n        self._loop._call_soon_handle(\n            new_MethodHandle1(self._loop,\n                              \"UVTransport._call_connection_lost\",\n                              <method1_t>self._call_connection_lost,\n                              self.context,\n                              self, exc))\n\n    cdef _fatal_error(self, exc, throw, reason=None):\n        # Overload UVHandle._fatal_error\n\n        self._force_close(exc)\n\n        if not isinstance(exc, OSError):\n\n            if throw or self._loop is None:\n                raise exc\n\n            msg = f'Fatal error on transport {self.__class__.__name__}'\n            if reason is not None:\n                msg = f'{msg} ({reason})'\n\n            self._loop.call_exception_handler({\n                'message': msg,\n                'exception': exc,\n                'transport': self,\n                'protocol': self._protocol,\n            })\n\n    cdef inline _maybe_pause_protocol(self):\n        cdef:\n            size_t size = self._get_write_buffer_size()\n\n        if size <= self._high_water:\n            return\n\n        if not self._protocol_paused:\n            self._protocol_paused = 1\n            try:\n                # _maybe_pause_protocol() is always triggered from user-calls,\n                # so we must copy the context to avoid entering context twice\n                run_in_context(\n                    self.context.copy(), self._protocol.pause_writing,\n                )\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException as exc:\n                self._loop.call_exception_handler({\n                    'message': 'protocol.pause_writing() failed',\n                    'exception': exc,\n                    'transport': self,\n                    'protocol': self._protocol,\n                })\n\n    cdef inline _maybe_resume_protocol(self):\n        cdef:\n            size_t size = self._get_write_buffer_size()\n\n        if self._protocol_paused and size <= self._low_water:\n            self._protocol_paused = 0\n            try:\n                # We're copying the context to avoid entering context twice,\n                # even though it's not always necessary to copy - it's easier\n                # to copy here than passing down a copied context.\n                run_in_context(\n                    self.context.copy(), self._protocol.resume_writing,\n                )\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException as exc:\n                self._loop.call_exception_handler({\n                    'message': 'protocol.resume_writing() failed',\n                    'exception': exc,\n                    'transport': self,\n                    'protocol': self._protocol,\n                })\n\n    cdef _wakeup_waiter(self):\n        if self._waiter is not None:\n            if not self._waiter.cancelled():\n                if not self._is_alive():\n                    self._waiter.set_exception(\n                        RuntimeError(\n                            'closed Transport handle and unset waiter'))\n                else:\n                    self._waiter.set_result(True)\n            self._waiter = None\n\n    cdef _call_connection_made(self):\n        if self._protocol is None:\n            raise RuntimeError(\n                'protocol is not set, cannot call connection_made()')\n\n        # We use `_is_alive()` and not `_closing`, because we call\n        # `transport._close()` in `loop.create_connection()` if an\n        # exception happens during `await waiter`.\n        if not self._is_alive():\n            # A connection waiter can be cancelled between\n            # 'await loop.create_connection()' and\n            # `_schedule_call_connection_made` and\n            # the actual `_call_connection_made`.\n            self._wakeup_waiter()\n            return\n\n        # Set _protocol_connected to 1 before calling \"connection_made\":\n        # if transport is aborted or closed, \"connection_lost\" will\n        # still be scheduled.\n        self._protocol_connected = 1\n\n        try:\n            self._protocol.connection_made(self)\n        except BaseException:\n            self._wakeup_waiter()\n            raise\n\n        if not self._is_alive():\n            # This might happen when \"transport.abort()\" is called\n            # from \"Protocol.connection_made\".\n            self._wakeup_waiter()\n            return\n\n        self._start_reading()\n        self._wakeup_waiter()\n\n    cdef _call_connection_lost(self, exc):\n        if self._waiter is not None:\n            if not self._waiter.done():\n                self._waiter.set_exception(exc)\n            self._waiter = None\n\n        if self._closed:\n            # The handle is closed -- likely, _call_connection_lost\n            # was already called before.\n            return\n\n        try:\n            if self._protocol_connected:\n                self._protocol.connection_lost(exc)\n        finally:\n            self._clear_protocol()\n\n            self._close()\n\n            server = self._server\n            if server is not None:\n                (<Server>server)._detach()\n                self._server = None\n\n    cdef inline _set_server(self, Server server):\n        self._server = server\n        (<Server>server)._attach()\n\n    cdef inline _set_waiter(self, object waiter):\n        if waiter is not None and not isfuture(waiter):\n            raise TypeError(\n                f'invalid waiter object {waiter!r}, expected asyncio.Future')\n\n        self._waiter = waiter\n\n    cdef _set_protocol(self, object protocol):\n        self._protocol = protocol\n        # Store a reference to the bound method directly\n        try:\n            self._protocol_data_received = protocol.data_received\n        except AttributeError:\n            pass\n\n    cdef _clear_protocol(self):\n        self._protocol = None\n        self._protocol_data_received = None\n\n    cdef inline _init_protocol(self):\n        self._loop._track_transport(self)\n        if self._protocol is None:\n            raise RuntimeError('invalid _init_protocol call')\n        self._schedule_call_connection_made()\n\n    cdef inline _add_extra_info(self, str name, object obj):\n        if self._extra_info is None:\n            self._extra_info = {}\n        self._extra_info[name] = obj\n\n    cdef bint _is_reading(self):\n        raise NotImplementedError\n\n    cdef _start_reading(self):\n        raise NotImplementedError\n\n    cdef _stop_reading(self):\n        raise NotImplementedError\n\n    # === Public API ===\n\n    property _paused:\n        # Used by SSLProto.  Might be removed in the future.\n        def __get__(self):\n            return bool(not self._is_reading())\n\n    def get_protocol(self):\n        return self._protocol\n\n    def set_protocol(self, protocol):\n        self._set_protocol(protocol)\n        if self._is_reading():\n            self._stop_reading()\n            self._start_reading()\n\n    def _force_close(self, exc):\n        # Used by SSLProto.  Might be removed in the future.\n        if self._conn_lost or self._closed:\n            return\n        if not self._closing:\n            self._closing = 1\n            self._stop_reading()\n        self._conn_lost += 1\n        self._schedule_call_connection_lost(exc)\n\n    def abort(self):\n        self._force_close(None)\n\n    def close(self):\n        if self._closing or self._closed:\n            return\n\n        self._closing = 1\n        self._stop_reading()\n\n        if not self._get_write_buffer_size():\n            # The write buffer is empty\n            self._conn_lost += 1\n            self._schedule_call_connection_lost(None)\n\n    def is_closing(self):\n        return self._closing\n\n    def get_write_buffer_size(self):\n        return self._get_write_buffer_size()\n\n    def set_write_buffer_limits(self, high=None, low=None):\n        self._ensure_alive()\n\n        self._high_water, self._low_water = add_flowcontrol_defaults(\n            high, low, FLOW_CONTROL_HIGH_WATER)\n\n        self._maybe_pause_protocol()\n\n    def get_write_buffer_limits(self):\n        return (self._low_water, self._high_water)\n\n    def get_extra_info(self, name, default=None):\n        if self._extra_info is not None and name in self._extra_info:\n            return self._extra_info[name]\n        if name == 'socket':\n            return self._get_socket()\n        if name == 'sockname':\n            return self._get_socket().getsockname()\n        if name == 'peername':\n            try:\n                return self._get_socket().getpeername()\n            except socket_error:\n                return default\n        return default\n"
  },
  {
    "path": "uvloop/handles/check.pxd",
    "content": "cdef class UVCheck(UVHandle):\n    cdef:\n        Handle h\n        bint running\n\n    # All \"inline\" methods are final\n\n    cdef _init(self, Loop loop, Handle h)\n\n    cdef inline stop(self)\n    cdef inline start(self)\n\n    @staticmethod\n    cdef UVCheck new(Loop loop, Handle h)\n"
  },
  {
    "path": "uvloop/handles/check.pyx",
    "content": "@cython.no_gc_clear\ncdef class UVCheck(UVHandle):\n    cdef _init(self, Loop loop, Handle h):\n        cdef int err\n\n        self._start_init(loop)\n\n        self._handle = <uv.uv_handle_t*>PyMem_RawMalloc(sizeof(uv.uv_check_t))\n        if self._handle is NULL:\n            self._abort_init()\n            raise MemoryError()\n\n        err = uv.uv_check_init(self._loop.uvloop, <uv.uv_check_t*>self._handle)\n        if err < 0:\n            self._abort_init()\n            raise convert_error(err)\n\n        self._finish_init()\n\n        self.h = h\n        self.running = 0\n\n    cdef inline stop(self):\n        cdef int err\n\n        if not self._is_alive():\n            self.running = 0\n            return\n\n        if self.running == 1:\n            err = uv.uv_check_stop(<uv.uv_check_t*>self._handle)\n            self.running = 0\n            if err < 0:\n                exc = convert_error(err)\n                self._fatal_error(exc, True)\n                return\n\n    cdef inline start(self):\n        cdef int err\n\n        self._ensure_alive()\n\n        if self.running == 0:\n            err = uv.uv_check_start(<uv.uv_check_t*>self._handle,\n                                    cb_check_callback)\n            if err < 0:\n                exc = convert_error(err)\n                self._fatal_error(exc, True)\n                return\n            self.running = 1\n\n    @staticmethod\n    cdef UVCheck new(Loop loop, Handle h):\n        cdef UVCheck handle\n        handle = UVCheck.__new__(UVCheck)\n        handle._init(loop, h)\n        return handle\n\n\ncdef void cb_check_callback(\n    uv.uv_check_t* handle,\n) noexcept with gil:\n    if __ensure_handle_data(<uv.uv_handle_t*>handle, \"UVCheck callback\") == 0:\n        return\n\n    cdef:\n        UVCheck check = <UVCheck> handle.data\n        Handle h = check.h\n    try:\n        h._run()\n    except BaseException as ex:\n        check._error(ex, False)\n"
  },
  {
    "path": "uvloop/handles/fsevent.pxd",
    "content": "cdef class UVFSEvent(UVHandle):\n    cdef:\n        object callback\n        bint running\n\n    cdef _init(self, Loop loop, object callback, object context)\n    cdef _close(self)\n    cdef start(self, char* path, int flags)\n    cdef stop(self)\n\n    @staticmethod\n    cdef UVFSEvent new(Loop loop, object callback, object context)\n"
  },
  {
    "path": "uvloop/handles/fsevent.pyx",
    "content": "import enum\n\n\nclass FileSystemEvent(enum.IntEnum):\n    RENAME = uv.UV_RENAME\n    CHANGE = uv.UV_CHANGE\n    RENAME_CHANGE = RENAME | CHANGE\n\n\n@cython.no_gc_clear\ncdef class UVFSEvent(UVHandle):\n    cdef _init(self, Loop loop, object callback, object context):\n        cdef int err\n\n        self._start_init(loop)\n\n        self._handle = <uv.uv_handle_t*>PyMem_RawMalloc(\n            sizeof(uv.uv_fs_event_t)\n        )\n        if self._handle is NULL:\n            self._abort_init()\n            raise MemoryError()\n\n        err = uv.uv_fs_event_init(\n            self._loop.uvloop, <uv.uv_fs_event_t*>self._handle\n        )\n        if err < 0:\n            self._abort_init()\n            raise convert_error(err)\n\n        self._finish_init()\n\n        self.running = 0\n        self.callback = callback\n        if context is None:\n            context = Context_CopyCurrent()\n        self.context = context\n\n    cdef start(self, char* path, int flags):\n        cdef int err\n\n        self._ensure_alive()\n\n        if self.running == 0:\n            err = uv.uv_fs_event_start(\n                <uv.uv_fs_event_t*>self._handle,\n                __uvfsevent_callback,\n                path,\n                flags,\n            )\n            if err < 0:\n                exc = convert_error(err)\n                self._fatal_error(exc, True)\n                return\n            self.running = 1\n\n    cdef stop(self):\n        cdef int err\n\n        if not self._is_alive():\n            self.running = 0\n            return\n\n        if self.running == 1:\n            err = uv.uv_fs_event_stop(<uv.uv_fs_event_t*>self._handle)\n            self.running = 0\n            if err < 0:\n                exc = convert_error(err)\n                self._fatal_error(exc, True)\n                return\n\n    cdef _close(self):\n        try:\n            self.stop()\n        finally:\n            UVHandle._close(<UVHandle>self)\n\n    def cancel(self):\n        self._close()\n\n    def cancelled(self):\n        return self.running == 0\n\n    @staticmethod\n    cdef UVFSEvent new(Loop loop, object callback, object context):\n        cdef UVFSEvent handle\n        handle = UVFSEvent.__new__(UVFSEvent)\n        handle._init(loop, callback, context)\n        return handle\n\n\ncdef void __uvfsevent_callback(\n    uv.uv_fs_event_t* handle,\n    const char *filename,\n    int events,\n    int status,\n) noexcept with gil:\n    if __ensure_handle_data(\n        <uv.uv_handle_t*>handle, \"UVFSEvent callback\"\n    ) == 0:\n        return\n\n    cdef:\n        UVFSEvent fs_event = <UVFSEvent> handle.data\n        Handle h\n\n    try:\n        h = new_Handle(\n            fs_event._loop,\n            fs_event.callback,\n            (filename, FileSystemEvent(events)),\n            fs_event.context,\n        )\n        h._run()\n    except BaseException as ex:\n        fs_event._error(ex, False)\n"
  },
  {
    "path": "uvloop/handles/handle.pxd",
    "content": "cdef class UVHandle:\n    cdef:\n        uv.uv_handle_t *_handle\n        Loop _loop\n        readonly _source_traceback\n        bint _closed\n        bint _inited\n        object context\n\n        # Added to enable current UDPTransport implementation,\n        # which doesn't use libuv handles.\n        bint _has_handle\n\n    # All \"inline\" methods are final\n\n    cdef inline _start_init(self, Loop loop)\n    cdef inline _abort_init(self)\n    cdef inline _finish_init(self)\n\n    cdef inline bint _is_alive(self)\n    cdef inline _ensure_alive(self)\n\n    cdef _error(self, exc, throw)\n    cdef _fatal_error(self, exc, throw, reason=?)\n\n    cdef _warn_unclosed(self)\n\n    cdef _free(self)\n    cdef _close(self)\n\n\ncdef class UVSocketHandle(UVHandle):\n    cdef:\n        # Points to a Python file-object that should be closed\n        # when the transport is closing.  Used by pipes.  This\n        # should probably be refactored somehow.\n        object _fileobj\n        object __cached_socket\n\n    # All \"inline\" methods are final\n\n    cdef _fileno(self)\n\n    cdef _new_socket(self)\n    cdef inline _get_socket(self)\n    cdef inline _attach_fileobj(self, object file)\n\n    cdef _open(self, int sockfd)\n"
  },
  {
    "path": "uvloop/handles/handle.pyx",
    "content": "cdef class UVHandle:\n    \"\"\"A base class for all libuv handles.\n\n    Automatically manages memory deallocation and closing.\n\n    Important:\n\n       1. call \"_ensure_alive()\" before calling any libuv functions on\n          your handles.\n\n       2. call \"__ensure_handle_data\" in *all* libuv handle callbacks.\n    \"\"\"\n\n    def __cinit__(self):\n        self._closed = 0\n        self._inited = 0\n        self._has_handle = 1\n        self._handle = NULL\n        self._loop = None\n        self._source_traceback = None\n\n    def __init__(self):\n        raise TypeError(\n            '{} is not supposed to be instantiated from Python'.format(\n                self.__class__.__name__))\n\n    def __dealloc__(self):\n        if UVLOOP_DEBUG:\n            if self._loop is not None:\n                if self._inited:\n                    self._loop._debug_handles_current.subtract([\n                        self.__class__.__name__])\n            else:\n                # No \"@cython.no_gc_clear\" decorator on this UVHandle\n                raise RuntimeError(\n                    '{} without @no_gc_clear; loop was set to None by GC'\n                    .format(self.__class__.__name__))\n\n        if self._handle is NULL:\n            return\n\n        # -> When we're at this point, something is wrong <-\n\n        if self._handle.loop is NULL:\n            # The handle wasn't initialized with \"uv_{handle}_init\"\n            self._closed = 1\n            self._free()\n            raise RuntimeError(\n                '{} is open in __dealloc__ with loop set to NULL'\n                .format(self.__class__.__name__))\n\n        if self._closed:\n            # So _handle is not NULL and self._closed == 1?\n            raise RuntimeError(\n                '{}.__dealloc__: _handle is NULL, _closed == 1'.format(\n                    self.__class__.__name__))\n\n        # The handle is dealloced while open.  Let's try to close it.\n        # Situations when this is possible include unhandled exceptions,\n        # errors during Handle.__cinit__/__init__ etc.\n        if self._inited:\n            self._handle.data = NULL\n            uv.uv_close(self._handle, __uv_close_handle_cb)  # void; no errors\n            self._handle = NULL\n            self._warn_unclosed()\n        else:\n            # The handle was allocated, but not initialized\n            self._closed = 1\n            self._free()\n\n    cdef _free(self):\n        if self._handle == NULL:\n            return\n\n        if UVLOOP_DEBUG and self._inited:\n            self._loop._debug_uv_handles_freed += 1\n\n        PyMem_RawFree(self._handle)\n        self._handle = NULL\n\n    cdef _warn_unclosed(self):\n        if self._source_traceback is not None:\n            try:\n                tb = ''.join(tb_format_list(self._source_traceback))\n                tb = 'object created at (most recent call last):\\n{}'.format(\n                    tb.rstrip())\n            except Exception as ex:\n                msg = (\n                    'unclosed resource {!r}; could not serialize '\n                    'debug traceback: {}: {}'\n                ).format(self, type(ex).__name__, ex)\n            else:\n                msg = 'unclosed resource {!r}; {}'.format(self, tb)\n        else:\n            msg = 'unclosed resource {!r}'.format(self)\n        warnings_warn(msg, ResourceWarning)\n\n    cdef inline _abort_init(self):\n        if self._handle is not NULL:\n            self._free()\n\n        try:\n            if UVLOOP_DEBUG:\n                name = self.__class__.__name__\n                if self._inited:\n                    raise RuntimeError(\n                        '_abort_init: {}._inited is set'.format(name))\n                if self._closed:\n                    raise RuntimeError(\n                        '_abort_init: {}._closed is set'.format(name))\n        finally:\n            self._closed = 1\n\n    cdef inline _finish_init(self):\n        self._inited = 1\n        if self._has_handle == 1:\n            self._handle.data = <void*>self\n        if self._loop._debug:\n            self._source_traceback = extract_stack()\n        if UVLOOP_DEBUG:\n            cls_name = self.__class__.__name__\n            self._loop._debug_uv_handles_total += 1\n            self._loop._debug_handles_total.update([cls_name])\n            self._loop._debug_handles_current.update([cls_name])\n\n    cdef inline _start_init(self, Loop loop):\n        if UVLOOP_DEBUG:\n            if self._loop is not None:\n                raise RuntimeError(\n                    '{}._start_init can only be called once'.format(\n                        self.__class__.__name__))\n\n        self._loop = loop\n\n    cdef inline bint _is_alive(self):\n        cdef bint res\n        res = self._closed != 1 and self._inited == 1\n        if UVLOOP_DEBUG:\n            if res and self._has_handle == 1:\n                name = self.__class__.__name__\n                if self._handle is NULL:\n                    raise RuntimeError(\n                        '{} is alive, but _handle is NULL'.format(name))\n                if self._loop is None:\n                    raise RuntimeError(\n                        '{} is alive, but _loop is None'.format(name))\n                if self._handle.loop is not self._loop.uvloop:\n                    raise RuntimeError(\n                        '{} is alive, but _handle.loop is not '\n                        'initialized'.format(name))\n                if self._handle.data is not <void*>self:\n                    raise RuntimeError(\n                        '{} is alive, but _handle.data is not '\n                        'initialized'.format(name))\n        return res\n\n    cdef inline _ensure_alive(self):\n        if not self._is_alive():\n            raise RuntimeError(\n                'unable to perform operation on {!r}; '\n                'the handler is closed'.format(self))\n\n    cdef _fatal_error(self, exc, throw, reason=None):\n        # Fatal error means an error that was returned by the\n        # underlying libuv handle function.  We usually can't\n        # recover from that, hence we just close the handle.\n        self._close()\n\n        if throw or self._loop is None:\n            raise exc\n        else:\n            self._loop._handle_exception(exc)\n\n    cdef _error(self, exc, throw):\n        # A non-fatal error is usually an error that was caught\n        # by the handler, but was originated in the client code\n        # (not in libuv).  In this case we either want to simply\n        # raise or log it.\n        if throw or self._loop is None:\n            raise exc\n        else:\n            self._loop._handle_exception(exc)\n\n    cdef _close(self):\n        if self._closed == 1:\n            return\n\n        self._closed = 1\n\n        if self._handle is NULL:\n            return\n\n        if UVLOOP_DEBUG:\n            if self._handle.data is NULL:\n                raise RuntimeError(\n                    '{}._close: _handle.data is NULL'.format(\n                        self.__class__.__name__))\n\n            if <object>self._handle.data is not self:\n                raise RuntimeError(\n                    '{}._close: _handle.data is not UVHandle/self'.format(\n                        self.__class__.__name__))\n\n            if uv.uv_is_closing(self._handle):\n                raise RuntimeError(\n                    '{}._close: uv_is_closing() is true'.format(\n                        self.__class__.__name__))\n\n        # We want the handle wrapper (UVHandle) to stay alive until\n        # the closing callback fires.\n        Py_INCREF(self)\n        uv.uv_close(self._handle, __uv_close_handle_cb)  # void; no errors\n\n    def __repr__(self):\n        return '<{} closed={} {:#x}>'.format(\n            self.__class__.__name__,\n            self._closed,\n            id(self))\n\n\ncdef class UVSocketHandle(UVHandle):\n\n    def __cinit__(self):\n        self._fileobj = None\n        self.__cached_socket = None\n\n    cdef _fileno(self):\n        cdef:\n            int fd\n            int err\n\n        self._ensure_alive()\n        err = uv.uv_fileno(self._handle, <uv.uv_os_fd_t*>&fd)\n        if err < 0:\n            raise convert_error(err)\n\n        return fd\n\n    cdef _new_socket(self):\n        raise NotImplementedError\n\n    cdef inline _get_socket(self):\n        if self.__cached_socket is not None:\n            return self.__cached_socket\n\n        if not self._is_alive():\n            return None\n\n        self.__cached_socket = self._new_socket()\n        if UVLOOP_DEBUG:\n            # We don't \"dup\" for the \"__cached_socket\".\n            assert self.__cached_socket.fileno() == self._fileno()\n        return self.__cached_socket\n\n    cdef inline _attach_fileobj(self, object file):\n        # When we create a TCP/PIPE/etc connection/server based on\n        # a Python file object, we need to close the file object when\n        # the uv handle is closed.\n        socket_inc_io_ref(file)\n        self._fileobj = file\n\n    cdef _close(self):\n        if self.__cached_socket is not None:\n            (<PseudoSocket>self.__cached_socket)._fd = -1\n\n        UVHandle._close(self)\n\n        try:\n            # This code will only run for transports created from\n            # Python sockets, i.e. with `loop.create_server(sock=sock)` etc.\n            if self._fileobj is not None:\n                if isinstance(self._fileobj, socket_socket):\n                    # Detaching the socket object is the ideal solution:\n                    # * libuv will actually close the FD;\n                    # * detach() call will reset FD for the Python socket\n                    #   object, which means that it won't be closed 2nd time\n                    #   when the socket object is GCed.\n                    #\n                    # No need to call `socket_dec_io_ref()`, as\n                    # `socket.detach()` ignores `socket._io_refs`.\n                    self._fileobj.detach()\n                else:\n                    try:\n                        # `socket.close()` will raise an EBADF because libuv\n                        # has already closed the underlying FD.\n                        self._fileobj.close()\n                    except OSError as ex:\n                        if ex.errno != errno_EBADF:\n                            raise\n        except Exception as ex:\n            self._loop.call_exception_handler({\n                'exception': ex,\n                'transport': self,\n                'message': f'could not close attached file object '\n                           f'{self._fileobj!r}',\n            })\n        finally:\n            self._fileobj = None\n\n    cdef _open(self, int sockfd):\n        raise NotImplementedError\n\n\ncdef inline bint __ensure_handle_data(uv.uv_handle_t* handle,\n                                      const char* handle_ctx):\n\n    cdef Loop loop\n\n    if UVLOOP_DEBUG:\n        if handle.loop is NULL:\n            raise RuntimeError(\n                'handle.loop is NULL in __ensure_handle_data')\n\n        if handle.loop.data is NULL:\n            raise RuntimeError(\n                'handle.loop.data is NULL in __ensure_handle_data')\n\n    if handle.data is NULL:\n        loop = <Loop>handle.loop.data\n        loop.call_exception_handler({\n            'message': '{} called with handle.data == NULL'.format(\n                handle_ctx.decode('latin-1'))\n        })\n        return 0\n\n    if handle.data is NULL:\n        # The underlying UVHandle object was GCed with an open uv_handle_t.\n        loop = <Loop>handle.loop.data\n        loop.call_exception_handler({\n            'message': '{} called after destroying the UVHandle'.format(\n                handle_ctx.decode('latin-1'))\n        })\n        return 0\n\n    return 1\n\n\ncdef void __uv_close_handle_cb(uv.uv_handle_t* handle) noexcept with gil:\n    cdef UVHandle h\n\n    if handle.data is NULL:\n        # The original UVHandle is long dead. Just free the mem of\n        # the uv_handle_t* handler.\n\n        if UVLOOP_DEBUG:\n            if handle.loop == NULL or handle.loop.data == NULL:\n                raise RuntimeError(\n                    '__uv_close_handle_cb: handle.loop is invalid')\n            (<Loop>handle.loop.data)._debug_uv_handles_freed += 1\n\n        PyMem_RawFree(handle)\n    else:\n        h = <UVHandle>handle.data\n        try:\n            if UVLOOP_DEBUG:\n                if not h._has_handle:\n                    raise RuntimeError(\n                        'has_handle=0 in __uv_close_handle_cb')\n                h._loop._debug_handles_closed.update([\n                    h.__class__.__name__])\n            h._free()\n        finally:\n            Py_DECREF(h)  # Was INCREFed in UVHandle._close\n\n\ncdef void __close_all_handles(Loop loop) noexcept:\n    uv.uv_walk(loop.uvloop,\n               __uv_walk_close_all_handles_cb,\n               <void*>loop)  # void\n\n\ncdef void __uv_walk_close_all_handles_cb(\n    uv.uv_handle_t* handle,\n    void* arg,\n) noexcept with gil:\n\n    cdef:\n        Loop loop = <Loop>arg\n        UVHandle h\n\n    if uv.uv_is_closing(handle):\n        # The handle is closed or is closing.\n        return\n\n    if handle.data is NULL:\n        # This shouldn't happen. Ever.\n        loop.call_exception_handler({\n            'message': 'handle.data is NULL in __close_all_handles_cb'\n        })\n        return\n\n    h = <UVHandle>handle.data\n    if not h._closed:\n        h._warn_unclosed()\n        h._close()\n"
  },
  {
    "path": "uvloop/handles/idle.pxd",
    "content": "cdef class UVIdle(UVHandle):\n    cdef:\n        Handle h\n        bint running\n\n    # All \"inline\" methods are final\n\n    cdef _init(self, Loop loop, Handle h)\n\n    cdef inline stop(self)\n    cdef inline start(self)\n\n    @staticmethod\n    cdef UVIdle new(Loop loop, Handle h)\n"
  },
  {
    "path": "uvloop/handles/idle.pyx",
    "content": "@cython.no_gc_clear\ncdef class UVIdle(UVHandle):\n    cdef _init(self, Loop loop, Handle h):\n        cdef int err\n\n        self._start_init(loop)\n\n        self._handle = <uv.uv_handle_t*>PyMem_RawMalloc(sizeof(uv.uv_idle_t))\n        if self._handle is NULL:\n            self._abort_init()\n            raise MemoryError()\n\n        err = uv.uv_idle_init(self._loop.uvloop, <uv.uv_idle_t*>self._handle)\n        if err < 0:\n            self._abort_init()\n            raise convert_error(err)\n\n        self._finish_init()\n\n        self.h = h\n        self.running = 0\n\n    cdef inline stop(self):\n        cdef int err\n\n        if not self._is_alive():\n            self.running = 0\n            return\n\n        if self.running == 1:\n            err = uv.uv_idle_stop(<uv.uv_idle_t*>self._handle)\n            self.running = 0\n            if err < 0:\n                exc = convert_error(err)\n                self._fatal_error(exc, True)\n                return\n\n    cdef inline start(self):\n        cdef int err\n\n        self._ensure_alive()\n\n        if self.running == 0:\n            err = uv.uv_idle_start(<uv.uv_idle_t*>self._handle,\n                                   cb_idle_callback)\n            if err < 0:\n                exc = convert_error(err)\n                self._fatal_error(exc, True)\n                return\n            self.running = 1\n\n    @staticmethod\n    cdef UVIdle new(Loop loop, Handle h):\n        cdef UVIdle handle\n        handle = UVIdle.__new__(UVIdle)\n        handle._init(loop, h)\n        return handle\n\n\ncdef void cb_idle_callback(\n    uv.uv_idle_t* handle,\n) noexcept with gil:\n    if __ensure_handle_data(<uv.uv_handle_t*>handle, \"UVIdle callback\") == 0:\n        return\n\n    cdef:\n        UVIdle idle = <UVIdle> handle.data\n        Handle h = idle.h\n    try:\n        h._run()\n    except BaseException as ex:\n        idle._error(ex, False)\n"
  },
  {
    "path": "uvloop/handles/pipe.pxd",
    "content": "cdef class UnixServer(UVStreamServer):\n\n    cdef bind(self, str path)\n\n    @staticmethod\n    cdef UnixServer new(Loop loop, object protocol_factory, Server server,\n                        object backlog,\n                        object ssl,\n                        object ssl_handshake_timeout,\n                        object ssl_shutdown_timeout)\n\n\ncdef class UnixTransport(UVStream):\n\n    @staticmethod\n    cdef UnixTransport new(Loop loop, object protocol, Server server,\n                           object waiter, object context)\n\n    cdef connect(self, char* addr)\n\n\ncdef class ReadUnixTransport(UVStream):\n\n    @staticmethod\n    cdef ReadUnixTransport new(Loop loop, object protocol, Server server,\n                               object waiter)\n\n\ncdef class WriteUnixTransport(UVStream):\n\n    @staticmethod\n    cdef WriteUnixTransport new(Loop loop, object protocol, Server server,\n                                object waiter)\n"
  },
  {
    "path": "uvloop/handles/pipe.pyx",
    "content": "cdef __pipe_init_uv_handle(UVStream handle, Loop loop):\n    cdef int err\n\n    handle._handle = <uv.uv_handle_t*>PyMem_RawMalloc(sizeof(uv.uv_pipe_t))\n    if handle._handle is NULL:\n        handle._abort_init()\n        raise MemoryError()\n\n    # Initialize pipe handle with ipc=0.\n    # ipc=1 means that libuv will use recvmsg/sendmsg\n    # instead of recv/send.\n    err = uv.uv_pipe_init(handle._loop.uvloop,\n                          <uv.uv_pipe_t*>handle._handle,\n                          0)\n    # UV_HANDLE_READABLE allows calling uv_read_start() on this pipe\n    # even if it is O_WRONLY, see also #317, libuv/libuv#2058\n    handle._handle.flags |= uv.UV_INTERNAL_HANDLE_READABLE\n    if err < 0:\n        handle._abort_init()\n        raise convert_error(err)\n\n    handle._finish_init()\n\n\ncdef __pipe_open(UVStream handle, int fd):\n    cdef int err\n    err = uv.uv_pipe_open(<uv.uv_pipe_t *>handle._handle,\n                          <uv.uv_os_fd_t>fd)\n    if err < 0:\n        exc = convert_error(err)\n        raise exc\n\n\ncdef __pipe_get_socket(UVSocketHandle handle):\n    fileno = handle._fileno()\n    return PseudoSocket(uv.AF_UNIX, uv.SOCK_STREAM, 0, fileno)\n\n\n@cython.no_gc_clear\ncdef class UnixServer(UVStreamServer):\n\n    @staticmethod\n    cdef UnixServer new(Loop loop, object protocol_factory, Server server,\n                        object backlog,\n                        object ssl,\n                        object ssl_handshake_timeout,\n                        object ssl_shutdown_timeout):\n\n        cdef UnixServer handle\n        handle = UnixServer.__new__(UnixServer)\n        handle._init(loop, protocol_factory, server, backlog,\n                     ssl, ssl_handshake_timeout, ssl_shutdown_timeout)\n        __pipe_init_uv_handle(<UVStream>handle, loop)\n        return handle\n\n    cdef _new_socket(self):\n        return __pipe_get_socket(<UVSocketHandle>self)\n\n    cdef _open(self, int sockfd):\n        self._ensure_alive()\n        __pipe_open(<UVStream>self, sockfd)\n        self._mark_as_open()\n\n    cdef bind(self, str path):\n        cdef int err\n        self._ensure_alive()\n        err = uv.uv_pipe_bind(<uv.uv_pipe_t *>self._handle,\n                              path.encode())\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n\n        self._mark_as_open()\n\n    cdef UVStream _make_new_transport(self, object protocol, object waiter,\n                                      object context):\n        cdef UnixTransport tr\n        tr = UnixTransport.new(self._loop, protocol, self._server, waiter,\n                               context)\n        return <UVStream>tr\n\n    cdef _close(self):\n        sock = self._fileobj\n        if sock is not None and sock in self._loop._unix_server_sockets:\n            path = sock.getsockname()\n        else:\n            path = None\n\n        UVStreamServer._close(self)\n\n        if path is not None:\n            prev_ino = self._loop._unix_server_sockets[sock]\n            del self._loop._unix_server_sockets[sock]\n            try:\n                if os_stat(path).st_ino == prev_ino:\n                    os_unlink(path)\n            except FileNotFoundError:\n                pass\n            except OSError as err:\n                aio_logger.error('Unable to clean up listening UNIX socket '\n                                 '%r: %r', path, err)\n\n\n@cython.no_gc_clear\ncdef class UnixTransport(UVStream):\n\n    @staticmethod\n    cdef UnixTransport new(Loop loop, object protocol, Server server,\n                           object waiter, object context):\n\n        cdef UnixTransport handle\n        handle = UnixTransport.__new__(UnixTransport)\n        handle._init(loop, protocol, server, waiter, context)\n        __pipe_init_uv_handle(<UVStream>handle, loop)\n        return handle\n\n    cdef _new_socket(self):\n        return __pipe_get_socket(<UVSocketHandle>self)\n\n    cdef _open(self, int sockfd):\n        __pipe_open(<UVStream>self, sockfd)\n\n    cdef connect(self, char* addr):\n        cdef _PipeConnectRequest req\n        req = _PipeConnectRequest(self._loop, self)\n        req.connect(addr)\n\n\n@cython.no_gc_clear\ncdef class ReadUnixTransport(UVStream):\n\n    @staticmethod\n    cdef ReadUnixTransport new(Loop loop, object protocol, Server server,\n                               object waiter):\n        cdef ReadUnixTransport handle\n        handle = ReadUnixTransport.__new__(ReadUnixTransport)\n        # This is only used in connect_read_pipe() and subprocess_shell/exec()\n        # directly, we could simply copy the current context.\n        handle._init(loop, protocol, server, waiter, Context_CopyCurrent())\n        __pipe_init_uv_handle(<UVStream>handle, loop)\n        return handle\n\n    cdef _new_socket(self):\n        return __pipe_get_socket(<UVSocketHandle>self)\n\n    cdef _open(self, int sockfd):\n        __pipe_open(<UVStream>self, sockfd)\n\n    def get_write_buffer_limits(self):\n        raise NotImplementedError\n\n    def set_write_buffer_limits(self, high=None, low=None):\n        raise NotImplementedError\n\n    def get_write_buffer_size(self):\n        raise NotImplementedError\n\n    def write(self, data):\n        raise NotImplementedError\n\n    def writelines(self, list_of_data):\n        raise NotImplementedError\n\n    def write_eof(self):\n        raise NotImplementedError\n\n    def can_write_eof(self):\n        raise NotImplementedError\n\n    def abort(self):\n        raise NotImplementedError\n\n\n@cython.no_gc_clear\ncdef class WriteUnixTransport(UVStream):\n\n    @staticmethod\n    cdef WriteUnixTransport new(Loop loop, object protocol, Server server,\n                                object waiter):\n        cdef WriteUnixTransport handle\n        handle = WriteUnixTransport.__new__(WriteUnixTransport)\n\n        # We listen for read events on write-end of the pipe. When\n        # the read-end is close, the uv_stream_t.read callback will\n        # receive an error -- we want to silence that error, and just\n        # close the transport.\n        handle._close_on_read_error()\n\n        # This is only used in connect_write_pipe() and subprocess_shell/exec()\n        # directly, we could simply copy the current context.\n        handle._init(loop, protocol, server, waiter, Context_CopyCurrent())\n        __pipe_init_uv_handle(<UVStream>handle, loop)\n        return handle\n\n    cdef _new_socket(self):\n        return __pipe_get_socket(<UVSocketHandle>self)\n\n    cdef _open(self, int sockfd):\n        __pipe_open(<UVStream>self, sockfd)\n\n    def pause_reading(self):\n        raise NotImplementedError\n\n    def resume_reading(self):\n        raise NotImplementedError\n\n\ncdef class _PipeConnectRequest(UVRequest):\n    cdef:\n        UnixTransport transport\n        uv.uv_connect_t _req_data\n\n    def __cinit__(self, loop, transport):\n        self.request = <uv.uv_req_t*> &self._req_data\n        self.request.data = <void*>self\n        self.transport = transport\n\n    cdef connect(self, char* addr):\n        # uv_pipe_connect returns void\n        uv.uv_pipe_connect(<uv.uv_connect_t*>self.request,\n                           <uv.uv_pipe_t*>self.transport._handle,\n                           addr,\n                           __pipe_connect_callback)\n\ncdef void __pipe_connect_callback(\n    uv.uv_connect_t* req,\n    int status,\n) noexcept with gil:\n    cdef:\n        _PipeConnectRequest wrapper\n        UnixTransport transport\n\n    wrapper = <_PipeConnectRequest> req.data\n    transport = wrapper.transport\n\n    if status < 0:\n        exc = convert_error(status)\n    else:\n        exc = None\n\n    try:\n        transport._on_connect(exc)\n    except BaseException as ex:\n        wrapper.transport._fatal_error(ex, False)\n    finally:\n        wrapper.on_done()\n"
  },
  {
    "path": "uvloop/handles/poll.pxd",
    "content": "cdef class UVPoll(UVHandle):\n    cdef:\n        int fd\n        Handle reading_handle\n        Handle writing_handle\n\n    cdef _init(self, Loop loop, int fd)\n    cdef _close(self)\n\n    cdef inline _poll_start(self, int flags)\n    cdef inline _poll_stop(self)\n\n    cdef int is_active(self) noexcept\n\n    cdef is_reading(self)\n    cdef is_writing(self)\n\n    cdef start_reading(self, Handle callback)\n    cdef start_writing(self, Handle callback)\n    cdef stop_reading(self)\n    cdef stop_writing(self)\n    cdef stop(self)\n\n    @staticmethod\n    cdef UVPoll new(Loop loop, int fd)\n"
  },
  {
    "path": "uvloop/handles/poll.pyx",
    "content": "@cython.no_gc_clear\ncdef class UVPoll(UVHandle):\n    cdef _init(self, Loop loop, int fd):\n        cdef int err\n\n        self._start_init(loop)\n\n        self._handle = <uv.uv_handle_t*>PyMem_RawMalloc(sizeof(uv.uv_poll_t))\n        if self._handle is NULL:\n            self._abort_init()\n            raise MemoryError()\n\n        err = uv.uv_poll_init(self._loop.uvloop,\n                              <uv.uv_poll_t *>self._handle, fd)\n        if err < 0:\n            self._abort_init()\n            raise convert_error(err)\n\n        self._finish_init()\n\n        self.fd = fd\n        self.reading_handle = None\n        self.writing_handle = None\n\n    @staticmethod\n    cdef UVPoll new(Loop loop, int fd):\n        cdef UVPoll handle\n        handle = UVPoll.__new__(UVPoll)\n        handle._init(loop, fd)\n        return handle\n\n    cdef int is_active(self) noexcept:\n        return (self.reading_handle is not None or\n                self.writing_handle is not None)\n\n    cdef inline _poll_start(self, int flags):\n        cdef int err\n\n        self._ensure_alive()\n\n        err = uv.uv_poll_start(\n            <uv.uv_poll_t*>self._handle,\n            flags,\n            __on_uvpoll_event)\n\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n\n    cdef inline _poll_stop(self):\n        cdef int err\n\n        if not self._is_alive():\n            return\n\n        err = uv.uv_poll_stop(<uv.uv_poll_t*>self._handle)\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n\n        cdef:\n            int backend_id\n            system.epoll_event dummy_event\n\n        if system.PLATFORM_IS_LINUX:\n            # libuv doesn't remove the FD from epoll immediately\n            # after uv_poll_stop or uv_poll_close, causing hard\n            # to debug issue with dup-ed file descriptors causing\n            # CPU burn in epoll/epoll_ctl:\n            #    https://github.com/MagicStack/uvloop/issues/61\n            #\n            # It's safe though to manually call epoll_ctl here,\n            # after calling uv_poll_stop.\n\n            backend_id = uv.uv_backend_fd(self._loop.uvloop)\n            if backend_id != -1:\n                memset(&dummy_event, 0, sizeof(dummy_event))\n                system.epoll_ctl(\n                    backend_id,\n                    system.EPOLL_CTL_DEL,\n                    self.fd,\n                    &dummy_event)  # ignore errors\n\n    cdef is_reading(self):\n        return self._is_alive() and self.reading_handle is not None\n\n    cdef is_writing(self):\n        return self._is_alive() and self.writing_handle is not None\n\n    cdef start_reading(self, Handle callback):\n        cdef:\n            int mask = 0\n\n        if self.reading_handle is None:\n            # not reading right now, setup the handle\n\n            mask = uv.UV_READABLE\n            if self.writing_handle is not None:\n                # are we writing right now?\n                mask |= uv.UV_WRITABLE\n\n            self._poll_start(mask)\n        else:\n            self.reading_handle._cancel()\n\n        self.reading_handle = callback\n\n    cdef start_writing(self, Handle callback):\n        cdef:\n            int mask = 0\n\n        if self.writing_handle is None:\n            # not writing right now, setup the handle\n\n            mask = uv.UV_WRITABLE\n            if self.reading_handle is not None:\n                # are we reading right now?\n                mask |= uv.UV_READABLE\n\n            self._poll_start(mask)\n        else:\n            self.writing_handle._cancel()\n\n        self.writing_handle = callback\n\n    cdef stop_reading(self):\n        if self.reading_handle is None:\n            return False\n\n        self.reading_handle._cancel()\n        self.reading_handle = None\n\n        if self.writing_handle is None:\n            self.stop()\n        else:\n            self._poll_start(uv.UV_WRITABLE)\n\n        return True\n\n    cdef stop_writing(self):\n        if self.writing_handle is None:\n            return False\n\n        self.writing_handle._cancel()\n        self.writing_handle = None\n\n        if self.reading_handle is None:\n            self.stop()\n        else:\n            self._poll_start(uv.UV_READABLE)\n\n        return True\n\n    cdef stop(self):\n        if self.reading_handle is not None:\n            self.reading_handle._cancel()\n            self.reading_handle = None\n\n        if self.writing_handle is not None:\n            self.writing_handle._cancel()\n            self.writing_handle = None\n\n        self._poll_stop()\n\n    cdef _close(self):\n        if self.is_active():\n            self.stop()\n\n        UVHandle._close(<UVHandle>self)\n\n    cdef _fatal_error(self, exc, throw, reason=None):\n        try:\n            if self.reading_handle is not None:\n                try:\n                    self.reading_handle._run()\n                except BaseException as ex:\n                    self._loop._handle_exception(ex)\n                self.reading_handle = None\n\n            if self.writing_handle is not None:\n                try:\n                    self.writing_handle._run()\n                except BaseException as ex:\n                    self._loop._handle_exception(ex)\n                self.writing_handle = None\n\n        finally:\n            self._close()\n\n\ncdef void __on_uvpoll_event(\n    uv.uv_poll_t* handle,\n    int status,\n    int events,\n) noexcept with gil:\n\n    if __ensure_handle_data(<uv.uv_handle_t*>handle, \"UVPoll callback\") == 0:\n        return\n\n    cdef:\n        UVPoll poll = <UVPoll> handle.data\n\n    if status < 0:\n        exc = convert_error(status)\n        poll._fatal_error(exc, False)\n        return\n\n    if ((events & (uv.UV_READABLE | uv.UV_DISCONNECT)) and\n            poll.reading_handle is not None):\n\n        try:\n            if UVLOOP_DEBUG:\n                poll._loop._poll_read_events_total += 1\n            poll.reading_handle._run()\n        except BaseException as ex:\n            if UVLOOP_DEBUG:\n                poll._loop._poll_read_cb_errors_total += 1\n            poll._error(ex, False)\n            # continue code execution\n\n    if ((events & (uv.UV_WRITABLE | uv.UV_DISCONNECT)) and\n            poll.writing_handle is not None):\n\n        try:\n            if UVLOOP_DEBUG:\n                poll._loop._poll_write_events_total += 1\n            poll.writing_handle._run()\n        except BaseException as ex:\n            if UVLOOP_DEBUG:\n                poll._loop._poll_write_cb_errors_total += 1\n            poll._error(ex, False)\n"
  },
  {
    "path": "uvloop/handles/process.pxd",
    "content": "cdef class UVProcess(UVHandle):\n    cdef:\n        object _returncode\n        object _pid\n\n        object _errpipe_read\n        object _errpipe_write\n        object _preexec_fn\n        bint _restore_signals\n\n        list _fds_to_close\n\n        # Attributes used to compose uv_process_options_t:\n        uv.uv_process_options_t options\n        uv.uv_stdio_container_t[3] iocnt\n        list __env\n        char **uv_opt_env\n        list __args\n        char **uv_opt_args\n        char *uv_opt_file\n        bytes __cwd\n\n    cdef _close_process_handle(self)\n\n    cdef _init(self, Loop loop, list args, dict env, cwd,\n               start_new_session,\n               _stdin, _stdout, _stderr, pass_fds,\n               debug_flags, preexec_fn, restore_signals)\n\n    cdef _after_fork(self)\n\n    cdef char** __to_cstring_array(self, list arr)\n    cdef _init_args(self, list args)\n    cdef _init_env(self, dict env)\n    cdef _init_files(self, _stdin, _stdout, _stderr)\n    cdef _init_options(self, list args, dict env, cwd, start_new_session,\n                       _stdin, _stdout, _stderr, bint force_fork)\n\n    cdef _close_after_spawn(self, int fd)\n\n    cdef _on_exit(self, int64_t exit_status, int term_signal)\n    cdef _kill(self, int signum)\n\n\ncdef class UVProcessTransport(UVProcess):\n    cdef:\n        list _exit_waiters\n        list _init_futs\n        bint _stdio_ready\n        list _pending_calls\n        object _protocol\n        bint _finished\n\n        WriteUnixTransport _stdin\n        ReadUnixTransport _stdout\n        ReadUnixTransport _stderr\n\n        object stdin_proto\n        object stdout_proto\n        object stderr_proto\n\n    cdef _file_redirect_stdio(self, int fd)\n    cdef _file_devnull(self)\n    cdef _file_inpipe(self)\n    cdef _file_outpipe(self)\n\n    cdef _check_proc(self)\n    cdef _pipe_connection_lost(self, int fd, exc)\n    cdef _pipe_data_received(self, int fd, data)\n\n    cdef _call_connection_made(self, waiter)\n    cdef _try_finish(self)\n\n    @staticmethod\n    cdef UVProcessTransport new(Loop loop, protocol, args, env, cwd,\n                                start_new_session,\n                                _stdin, _stdout, _stderr, pass_fds,\n                                waiter,\n                                debug_flags,\n                                preexec_fn, restore_signals)\n"
  },
  {
    "path": "uvloop/handles/process.pyx",
    "content": "@cython.no_gc_clear\ncdef class UVProcess(UVHandle):\n    \"\"\"Abstract class; wrapper over uv_process_t handle.\"\"\"\n\n    def __cinit__(self):\n        self.uv_opt_env = NULL\n        self.uv_opt_args = NULL\n        self._returncode = None\n        self._pid = None\n        self._fds_to_close = list()\n        self._preexec_fn = None\n        self._restore_signals = True\n        self.context = Context_CopyCurrent()\n\n    cdef _close_process_handle(self):\n        # XXX: This is a workaround for a libuv bug:\n        # - https://github.com/libuv/libuv/issues/1933\n        # - https://github.com/libuv/libuv/pull/551\n        if self._handle is NULL:\n            return\n        self._handle.data = NULL\n        uv.uv_close(self._handle, __uv_close_process_handle_cb)\n        self._handle = NULL  # close callback will free() the memory\n\n    cdef _init(self, Loop loop, list args, dict env,\n               cwd, start_new_session,\n               _stdin, _stdout, _stderr,  # std* can be defined as macros in C\n               pass_fds, debug_flags, preexec_fn, restore_signals):\n\n        global __forking\n        global __forking_loop\n        global __forkHandler\n\n        cdef int err\n\n        self._start_init(loop)\n\n        self._handle = <uv.uv_handle_t*>PyMem_RawMalloc(\n            sizeof(uv.uv_process_t))\n        if self._handle is NULL:\n            self._abort_init()\n            raise MemoryError()\n\n        # Too early to call _finish_init, but still a lot of work to do.\n        # Let's set handle.data to NULL, so in case something goes wrong,\n        # callbacks have a chance to avoid casting *something* into UVHandle.\n        self._handle.data = NULL\n\n        force_fork = False\n        if system.PLATFORM_IS_APPLE and not (\n            preexec_fn is None\n            and not pass_fds\n        ):\n            # see _execute_child() in CPython/subprocess.py\n            force_fork = True\n\n        try:\n            self._init_options(args, env, cwd, start_new_session,\n                               _stdin, _stdout, _stderr, force_fork)\n\n            restore_inheritable = set()\n            if pass_fds:\n                for fd in pass_fds:\n                    if not os_get_inheritable(fd):\n                        restore_inheritable.add(fd)\n                        os_set_inheritable(fd, True)\n        except Exception:\n            self._abort_init()\n            raise\n\n        if __forking or loop.active_process_handler is not None:\n            # Our pthread_atfork handlers won't work correctly when\n            # another loop is forking in another thread (even though\n            # GIL should help us to avoid that.)\n            self._abort_init()\n            raise RuntimeError(\n                'Racing with another loop to spawn a process.')\n\n        self._errpipe_read, self._errpipe_write = os_pipe()\n        fds_to_close = self._fds_to_close\n        self._fds_to_close = None\n        fds_to_close.append(self._errpipe_read)\n        # add the write pipe last so we can close it early\n        fds_to_close.append(self._errpipe_write)\n        try:\n            os_set_inheritable(self._errpipe_write, True)\n\n            self._preexec_fn = preexec_fn\n            self._restore_signals = restore_signals\n\n            loop.active_process_handler = self\n            __forking = 1\n            __forking_loop = loop\n            system.setForkHandler(<system.OnForkHandler>&__get_fork_handler)\n\n            PyOS_BeforeFork()\n\n            err = uv.uv_spawn(loop.uvloop,\n                              <uv.uv_process_t*>self._handle,\n                              &self.options)\n\n            __forking = 0\n            __forking_loop = None\n            system.resetForkHandler()\n            loop.active_process_handler = None\n\n            PyOS_AfterFork_Parent()\n\n            if err < 0:\n                self._close_process_handle()\n                self._abort_init()\n                raise convert_error(err)\n\n            self._finish_init()\n\n            # close the write pipe early\n            os_close(fds_to_close.pop())\n\n            if preexec_fn is not None:\n                errpipe_data = bytearray()\n                while True:\n                    # XXX: This is a blocking code that has to be\n                    # rewritten (using loop.connect_read_pipe() or\n                    # otherwise.)\n                    part = os_read(self._errpipe_read, 50000)\n                    errpipe_data += part\n                    if not part or len(errpipe_data) > 50000:\n                        break\n\n        finally:\n            while fds_to_close:\n                os_close(fds_to_close.pop())\n\n            for fd in restore_inheritable:\n                os_set_inheritable(fd, False)\n\n        # asyncio caches the PID in BaseSubprocessTransport,\n        # so that the transport knows what the PID was even\n        # after the process is finished.\n        self._pid = (<uv.uv_process_t*>self._handle).pid\n\n        # Track the process handle (create a strong ref to it)\n        # to guarantee that __dealloc__ doesn't happen in an\n        # uncontrolled fashion.  We want to wait until the process\n        # exits and libuv calls __uvprocess_on_exit_callback,\n        # which will call `UVProcess._close()`, which will, in turn,\n        # untrack this handle.\n        self._loop._track_process(self)\n\n        if debug_flags & __PROCESS_DEBUG_SLEEP_AFTER_FORK:\n            time_sleep(1)\n\n        if preexec_fn is not None and errpipe_data:\n            # preexec_fn has raised an exception.  The child\n            # process must be dead now.\n            try:\n                exc_name, exc_msg = errpipe_data.split(b':', 1)\n                exc_name = exc_name.decode()\n                exc_msg = exc_msg.decode()\n            except Exception:\n                self._close()\n                raise subprocess_SubprocessError(\n                    'Bad exception data from child: {!r}'.format(\n                        errpipe_data))\n            exc_cls = getattr(__builtins__, exc_name,\n                              subprocess_SubprocessError)\n\n            exc = subprocess_SubprocessError(\n                'Exception occurred in preexec_fn.')\n            exc.__cause__ = exc_cls(exc_msg)\n            self._close()\n            raise exc\n\n    cdef _after_fork(self):\n        # See CPython/_posixsubprocess.c for details\n        cdef int err\n\n        if self._restore_signals:\n            _Py_RestoreSignals()\n\n        PyOS_AfterFork_Child()\n\n        err = uv.uv_loop_fork(self._loop.uvloop)\n        if err < 0:\n            raise convert_error(err)\n\n        if self._preexec_fn is not None:\n            try:\n                gc_disable()\n                self._preexec_fn()\n            except BaseException as ex:\n                try:\n                    with open(self._errpipe_write, 'wb') as f:\n                        f.write(str(ex.__class__.__name__).encode())\n                        f.write(b':')\n                        f.write(str(ex.args[0]).encode())\n                finally:\n                    system._exit(255)\n                    return\n            else:\n                os_close(self._errpipe_write)\n        else:\n            os_close(self._errpipe_write)\n\n    cdef _close_after_spawn(self, int fd):\n        if self._fds_to_close is None:\n            raise RuntimeError(\n                'UVProcess._close_after_spawn called after uv_spawn')\n        self._fds_to_close.append(fd)\n\n    def __dealloc__(self):\n        if self.uv_opt_env is not NULL:\n            PyMem_RawFree(self.uv_opt_env)\n            self.uv_opt_env = NULL\n\n        if self.uv_opt_args is not NULL:\n            PyMem_RawFree(self.uv_opt_args)\n            self.uv_opt_args = NULL\n\n    cdef char** __to_cstring_array(self, list arr):\n        cdef:\n            int i\n            ssize_t arr_len = len(arr)\n            bytes el\n\n            char **ret\n\n        ret = <char **>PyMem_RawMalloc((arr_len + 1) * sizeof(char *))\n        if ret is NULL:\n            raise MemoryError()\n\n        for i in range(arr_len):\n            el = arr[i]\n            # NB: PyBytes_AsString doesn't copy the data;\n            # we have to be careful when the \"arr\" is GCed,\n            # and it shouldn't be ever mutated.\n            ret[i] = PyBytes_AsString(el)\n\n        ret[arr_len] = NULL\n        return ret\n\n    cdef _init_options(self, list args, dict env, cwd, start_new_session,\n                       _stdin, _stdout, _stderr, bint force_fork):\n\n        memset(&self.options, 0, sizeof(uv.uv_process_options_t))\n\n        self._init_env(env)\n        self.options.env = self.uv_opt_env\n\n        self._init_args(args)\n        self.options.file = self.uv_opt_file\n        self.options.args = self.uv_opt_args\n\n        if start_new_session:\n            self.options.flags |= uv.UV_PROCESS_DETACHED\n\n        if force_fork:\n            # This is a hack to work around the change in libuv 1.44:\n            #    > macos: use posix_spawn instead of fork\n            # where Python subprocess options like preexec_fn are\n            # crippled. CPython only uses posix_spawn under a pretty\n            # strict list of conditions (see subprocess.py), and falls\n            # back to using fork() otherwise. We'd like to simulate such\n            # behavior with libuv, but unfortunately libuv doesn't\n            # provide explicit API to choose such implementation detail.\n            # Based on current (libuv 1.46) behavior, setting\n            # UV_PROCESS_SETUID or UV_PROCESS_SETGID would reliably make\n            # libuv fallback to use fork, so let's just use it for now.\n            self.options.flags |= uv.UV_PROCESS_SETUID\n            self.options.uid = uv.getuid()\n\n        if cwd is not None:\n            cwd = os_fspath(cwd)\n\n            if isinstance(cwd, str):\n                cwd = PyUnicode_EncodeFSDefault(cwd)\n            if not isinstance(cwd, bytes):\n                raise ValueError('cwd must be a str or bytes object')\n\n            self.__cwd = cwd\n            self.options.cwd = PyBytes_AsString(self.__cwd)\n\n        self.options.exit_cb = &__uvprocess_on_exit_callback\n\n        self._init_files(_stdin, _stdout, _stderr)\n\n    cdef _init_args(self, list args):\n        cdef:\n            bytes path\n            int an = len(args)\n\n        if an < 1:\n            raise ValueError('cannot spawn a process: args are empty')\n\n        self.__args = args.copy()\n        for i in range(an):\n            arg = os_fspath(args[i])\n            if isinstance(arg, str):\n                self.__args[i] = PyUnicode_EncodeFSDefault(arg)\n            elif not isinstance(arg, bytes):\n                raise TypeError('all args must be str or bytes')\n\n        path = self.__args[0]\n        self.uv_opt_file = PyBytes_AsString(path)\n        self.uv_opt_args = self.__to_cstring_array(self.__args)\n\n    cdef _init_env(self, dict env):\n        if env is not None:\n            self.__env = list()\n            for key in env:\n                val = env[key]\n\n                if isinstance(key, str):\n                    key = PyUnicode_EncodeFSDefault(key)\n                elif not isinstance(key, bytes):\n                    raise TypeError(\n                        'all environment vars must be bytes or str')\n\n                if isinstance(val, str):\n                    val = PyUnicode_EncodeFSDefault(val)\n                elif not isinstance(val, bytes):\n                    raise TypeError(\n                        'all environment values must be bytes or str')\n\n                self.__env.append(key + b'=' + val)\n\n            self.uv_opt_env = self.__to_cstring_array(self.__env)\n        else:\n            self.__env = None\n\n    cdef _init_files(self, _stdin, _stdout, _stderr):\n        self.options.stdio_count = 0\n\n    cdef _kill(self, int signum):\n        cdef int err\n        self._ensure_alive()\n        err = uv.uv_process_kill(<uv.uv_process_t*>self._handle, signum)\n        if err < 0:\n            raise convert_error(err)\n\n    cdef _on_exit(self, int64_t exit_status, int term_signal):\n        if term_signal:\n            # From Python docs:\n            #    A negative value -N indicates that the child was\n            #    terminated by signal N (POSIX only).\n            self._returncode = -term_signal\n        else:\n            self._returncode = exit_status\n\n        self._close()\n\n    cdef _close(self):\n        try:\n            if self._loop is not None:\n                self._loop._untrack_process(self)\n        finally:\n            UVHandle._close(self)\n\n\nDEF _CALL_PIPE_DATA_RECEIVED = 0\nDEF _CALL_PIPE_CONNECTION_LOST = 1\nDEF _CALL_PROCESS_EXITED = 2\nDEF _CALL_CONNECTION_LOST = 3\n\n\n@cython.no_gc_clear\ncdef class UVProcessTransport(UVProcess):\n    def __cinit__(self):\n        self._exit_waiters = []\n        self._protocol = None\n\n        self._init_futs = []\n        self._pending_calls = []\n        self._stdio_ready = 0\n\n        self._stdin = self._stdout = self._stderr = None\n        self.stdin_proto = self.stdout_proto = self.stderr_proto = None\n\n        self._finished = 0\n\n    cdef _on_exit(self, int64_t exit_status, int term_signal):\n        UVProcess._on_exit(self, exit_status, term_signal)\n\n        if self._stdio_ready:\n            self._loop.call_soon(self._protocol.process_exited,\n                                 context=self.context)\n        else:\n            self._pending_calls.append((_CALL_PROCESS_EXITED, None, None))\n\n        self._try_finish()\n\n        for waiter in self._exit_waiters:\n            if not waiter.cancelled():\n                waiter.set_result(self._returncode)\n        self._exit_waiters.clear()\n\n        self._close()\n\n    cdef _check_proc(self):\n        if not self._is_alive() or self._returncode is not None:\n            raise ProcessLookupError()\n\n    cdef _pipe_connection_lost(self, int fd, exc):\n        if self._stdio_ready:\n            self._loop.call_soon(self._protocol.pipe_connection_lost, fd, exc,\n                                 context=self.context)\n            self._try_finish()\n        else:\n            self._pending_calls.append((_CALL_PIPE_CONNECTION_LOST, fd, exc))\n\n    cdef _pipe_data_received(self, int fd, data):\n        if self._stdio_ready:\n            self._loop.call_soon(self._protocol.pipe_data_received, fd, data,\n                                 context=self.context)\n        else:\n            self._pending_calls.append((_CALL_PIPE_DATA_RECEIVED, fd, data))\n\n    cdef _file_redirect_stdio(self, int fd):\n        fd = os_dup(fd)\n        os_set_inheritable(fd, True)\n        self._close_after_spawn(fd)\n        return fd\n\n    cdef _file_devnull(self):\n        dn = os_open(os_devnull, os_O_RDWR)\n        os_set_inheritable(dn, True)\n        self._close_after_spawn(dn)\n        return dn\n\n    cdef _file_outpipe(self):\n        r, w = __socketpair()\n        os_set_inheritable(w, True)\n        self._close_after_spawn(w)\n        return r, w\n\n    cdef _file_inpipe(self):\n        r, w = __socketpair()\n        os_set_inheritable(r, True)\n        self._close_after_spawn(r)\n        return r, w\n\n    cdef _init_files(self, _stdin, _stdout, _stderr):\n        cdef uv.uv_stdio_container_t *iocnt\n\n        UVProcess._init_files(self, _stdin, _stdout, _stderr)\n\n        io = [None, None, None]\n\n        self.options.stdio_count = 3\n        self.options.stdio = self.iocnt\n\n        if _stdin is not None:\n            if _stdin == subprocess_PIPE:\n                r, w = self._file_inpipe()\n                io[0] = r\n\n                self.stdin_proto = WriteSubprocessPipeProto(self, 0)\n                waiter = self._loop._new_future()\n                self._stdin = WriteUnixTransport.new(\n                    self._loop, self.stdin_proto, None, waiter)\n                self._init_futs.append(waiter)\n                self._stdin._open(w)\n                self._stdin._init_protocol()\n            elif _stdin == subprocess_DEVNULL:\n                io[0] = self._file_devnull()\n            elif _stdout == subprocess_STDOUT:\n                raise ValueError(\n                    'subprocess.STDOUT is supported only by stderr parameter')\n            else:\n                io[0] = self._file_redirect_stdio(_stdin)\n        else:\n            io[0] = self._file_redirect_stdio(0)\n\n        if _stdout is not None:\n            if _stdout == subprocess_PIPE:\n                # We can't use UV_CREATE_PIPE here, since 'stderr' might be\n                # set to 'subprocess.STDOUT', and there is no way to\n                # emulate that functionality with libuv high-level\n                # streams API. Therefore, we create pipes for stdout and\n                # stderr manually.\n\n                r, w = self._file_outpipe()\n                io[1] = w\n\n                self.stdout_proto = ReadSubprocessPipeProto(self, 1)\n                waiter = self._loop._new_future()\n                self._stdout = ReadUnixTransport.new(\n                    self._loop, self.stdout_proto, None, waiter)\n                self._init_futs.append(waiter)\n                self._stdout._open(r)\n                self._stdout._init_protocol()\n            elif _stdout == subprocess_DEVNULL:\n                io[1] = self._file_devnull()\n            elif _stdout == subprocess_STDOUT:\n                raise ValueError(\n                    'subprocess.STDOUT is supported only by stderr parameter')\n            else:\n                io[1] = self._file_redirect_stdio(_stdout)\n        else:\n            io[1] = self._file_redirect_stdio(1)\n\n        if _stderr is not None:\n            if _stderr == subprocess_PIPE:\n                r, w = self._file_outpipe()\n                io[2] = w\n\n                self.stderr_proto = ReadSubprocessPipeProto(self, 2)\n                waiter = self._loop._new_future()\n                self._stderr = ReadUnixTransport.new(\n                    self._loop, self.stderr_proto, None, waiter)\n                self._init_futs.append(waiter)\n                self._stderr._open(r)\n                self._stderr._init_protocol()\n            elif _stderr == subprocess_STDOUT:\n                if io[1] is None:\n                    # shouldn't ever happen\n                    raise RuntimeError('cannot apply subprocess.STDOUT')\n\n                io[2] = self._file_redirect_stdio(io[1])\n            elif _stderr == subprocess_DEVNULL:\n                io[2] = self._file_devnull()\n            else:\n                io[2] = self._file_redirect_stdio(_stderr)\n        else:\n            io[2] = self._file_redirect_stdio(2)\n\n        assert len(io) == 3\n        for idx in range(3):\n            iocnt = &self.iocnt[idx]\n            if io[idx] is not None:\n                iocnt.flags = uv.UV_INHERIT_FD\n                iocnt.data.fd = io[idx]\n            else:\n                iocnt.flags = uv.UV_IGNORE\n\n    cdef _call_connection_made(self, waiter):\n        try:\n            # we're always called in the right context, so just call the user's\n            self._protocol.connection_made(self)\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException as ex:\n            if waiter is not None and not waiter.cancelled():\n                waiter.set_exception(ex)\n            else:\n                raise\n        else:\n            if waiter is not None and not waiter.cancelled():\n                waiter.set_result(True)\n\n        self._stdio_ready = 1\n        if self._pending_calls:\n            pending_calls = self._pending_calls.copy()\n            self._pending_calls.clear()\n            for (type, fd, arg) in pending_calls:\n                if type == _CALL_PIPE_CONNECTION_LOST:\n                    self._pipe_connection_lost(fd, arg)\n                elif type == _CALL_PIPE_DATA_RECEIVED:\n                    self._pipe_data_received(fd, arg)\n                elif type == _CALL_PROCESS_EXITED:\n                    self._loop.call_soon(self._protocol.process_exited)\n                elif type == _CALL_CONNECTION_LOST:\n                    self._loop.call_soon(self._protocol.connection_lost, None)\n\n    cdef _try_finish(self):\n        if self._returncode is None or self._finished:\n            return\n\n        if ((self.stdin_proto is None or self.stdin_proto.disconnected) and\n                (self.stdout_proto is None or\n                    self.stdout_proto.disconnected) and\n                (self.stderr_proto is None or\n                    self.stderr_proto.disconnected)):\n\n            self._finished = 1\n\n            if self._stdio_ready:\n                # copy self.context for simplicity\n                self._loop.call_soon(self._protocol.connection_lost, None,\n                                     context=self.context)\n            else:\n                self._pending_calls.append((_CALL_CONNECTION_LOST, None, None))\n\n    def __stdio_inited(self, waiter, stdio_fut):\n        exc = stdio_fut.exception()\n        if exc is not None:\n            if waiter is None:\n                raise exc\n            else:\n                waiter.set_exception(exc)\n        else:\n            self._loop._call_soon_handle(\n                new_MethodHandle1(self._loop,\n                                  \"UVProcessTransport._call_connection_made\",\n                                  <method1_t>self._call_connection_made,\n                                  None,  # means to copy the current context\n                                  self, waiter))\n\n    @staticmethod\n    cdef UVProcessTransport new(Loop loop, protocol, args, env,\n                                cwd, start_new_session,\n                                _stdin, _stdout, _stderr, pass_fds,\n                                waiter,\n                                debug_flags,\n                                preexec_fn,\n                                restore_signals):\n\n        cdef UVProcessTransport handle\n        handle = UVProcessTransport.__new__(UVProcessTransport)\n        handle._protocol = protocol\n        handle._init(loop, args, env, cwd, start_new_session,\n                     __process_convert_fileno(_stdin),\n                     __process_convert_fileno(_stdout),\n                     __process_convert_fileno(_stderr),\n                     pass_fds,\n                     debug_flags,\n                     preexec_fn,\n                     restore_signals)\n\n        if handle._init_futs:\n            handle._stdio_ready = 0\n            init_fut = aio_gather(*handle._init_futs)\n            # add_done_callback will copy the current context and run the\n            # callback within the context\n            init_fut.add_done_callback(\n                ft_partial(handle.__stdio_inited, waiter))\n        else:\n            handle._stdio_ready = 1\n            loop._call_soon_handle(\n                new_MethodHandle1(loop,\n                                  \"UVProcessTransport._call_connection_made\",\n                                  <method1_t>handle._call_connection_made,\n                                  None,  # means to copy the current context\n                                  handle, waiter))\n\n        return handle\n\n    def get_protocol(self):\n        return self._protocol\n\n    def set_protocol(self, protocol):\n        self._protocol = protocol\n\n    def get_pid(self):\n        return self._pid\n\n    def get_returncode(self):\n        return self._returncode\n\n    def get_pipe_transport(self, fd):\n        if fd == 0:\n            return self._stdin\n        elif fd == 1:\n            return self._stdout\n        elif fd == 2:\n            return self._stderr\n\n    def terminate(self):\n        self._check_proc()\n        self._kill(uv.SIGTERM)\n\n    def kill(self):\n        self._check_proc()\n        self._kill(uv.SIGKILL)\n\n    def send_signal(self, int signal):\n        self._check_proc()\n        self._kill(signal)\n\n    def is_closing(self):\n        return self._closed\n\n    def close(self):\n        if self._returncode is None:\n            self._kill(uv.SIGKILL)\n\n        if self._stdin is not None:\n            self._stdin.close()\n        if self._stdout is not None:\n            self._stdout.close()\n        if self._stderr is not None:\n            self._stderr.close()\n\n        if self._returncode is not None:\n            # The process is dead, just close the UV handle.\n            #\n            # (If \"self._returncode is None\", the process should have been\n            # killed already and we're just waiting for a SIGCHLD; after\n            # which the transport will be GC'ed and the uvhandle will be\n            # closed in UVHandle.__dealloc__.)\n            self._close()\n\n    def get_extra_info(self, name, default=None):\n        return default\n\n    def _wait(self):\n        fut = self._loop._new_future()\n        if self._returncode is not None:\n            fut.set_result(self._returncode)\n            return fut\n\n        self._exit_waiters.append(fut)\n        return fut\n\n\nclass WriteSubprocessPipeProto(aio_BaseProtocol):\n\n    def __init__(self, proc, fd):\n        if UVLOOP_DEBUG:\n            if type(proc) is not UVProcessTransport:\n                raise TypeError\n            if not isinstance(fd, int):\n                raise TypeError\n        self.proc = proc\n        self.fd = fd\n        self.pipe = None\n        self.disconnected = False\n\n    def connection_made(self, transport):\n        self.pipe = transport\n\n    def __repr__(self):\n        return ('<%s fd=%s pipe=%r>'\n                % (self.__class__.__name__, self.fd, self.pipe))\n\n    def connection_lost(self, exc):\n        self.disconnected = True\n        (<UVProcessTransport>self.proc)._pipe_connection_lost(self.fd, exc)\n        self.proc = None\n\n    def pause_writing(self):\n        (<UVProcessTransport>self.proc)._protocol.pause_writing()\n\n    def resume_writing(self):\n        (<UVProcessTransport>self.proc)._protocol.resume_writing()\n\n\nclass ReadSubprocessPipeProto(WriteSubprocessPipeProto,\n                              aio_Protocol):\n\n    def data_received(self, data):\n        (<UVProcessTransport>self.proc)._pipe_data_received(self.fd, data)\n\n\ncdef __process_convert_fileno(object obj):\n    if obj is None or isinstance(obj, int):\n        return obj\n\n    fileno = obj.fileno()\n    if not isinstance(fileno, int):\n        raise TypeError(\n            '{!r}.fileno() returned non-integer'.format(obj))\n    return fileno\n\n\ncdef void __uvprocess_on_exit_callback(\n    uv.uv_process_t *handle,\n    int64_t exit_status,\n    int term_signal,\n) noexcept with gil:\n\n    if __ensure_handle_data(<uv.uv_handle_t*>handle,\n                            \"UVProcess exit callback\") == 0:\n        return\n\n    cdef UVProcess proc = <UVProcess> handle.data\n    try:\n        proc._on_exit(exit_status, term_signal)\n    except BaseException as ex:\n        proc._error(ex, False)\n\n\ncdef __socketpair():\n    cdef:\n        int fds[2]\n        int err\n\n    err = system.socketpair(uv.AF_UNIX, uv.SOCK_STREAM, 0, fds)\n    if err:\n        exc = convert_error(-err)\n        raise exc\n\n    os_set_inheritable(fds[0], False)\n    os_set_inheritable(fds[1], False)\n\n    return fds[0], fds[1]\n\n\ncdef void __uv_close_process_handle_cb(\n    uv.uv_handle_t* handle\n) noexcept with gil:\n    PyMem_RawFree(handle)\n"
  },
  {
    "path": "uvloop/handles/stream.pxd",
    "content": "cdef enum ProtocolType:\n    SIMPLE = 0          # User Protocol doesn't support asyncio.BufferedProtocol\n    BUFFERED = 1        # User Protocol supports asyncio.BufferedProtocol\n    SSL_PROTOCOL = 2    # Our own SSLProtocol\n\n\ncdef class UVStream(UVBaseTransport):\n    cdef:\n        uv.uv_shutdown_t _shutdown_req\n        bint __shutting_down\n        bint __reading\n        bint __read_error_close\n\n        ProtocolType __protocol_type\n        object _protocol_get_buffer\n        object _protocol_buffer_updated\n\n        bint _eof\n        list _buffer\n        size_t _buffer_size\n\n        Py_buffer _read_pybuf\n        bint _read_pybuf_acquired\n\n    cpdef write(self, object buf)\n\n    # All \"inline\" methods are final\n\n    cdef inline _init(self, Loop loop, object protocol, Server server,\n                      object waiter, object context)\n\n\n    cdef inline _shutdown(self)\n    cdef inline _accept(self, UVStream server)\n\n    cdef inline _close_on_read_error(self)\n\n    cdef inline __reading_started(self)\n    cdef inline __reading_stopped(self)\n\n    # The user API write() and writelines() firstly call _buffer_write() to\n    # buffer up user data chunks, potentially multiple times in writelines(),\n    # and then call _initiate_write() to start writing either immediately or in\n    # the next iteration (loop._queue_write()).\n    cdef inline _buffer_write(self, object data)\n    cdef inline _initiate_write(self)\n\n    # _exec_write() is the method that does the actual send, and _try_write()\n    # is a fast-path used in _exec_write() to send a single chunk.\n    cdef inline bint _exec_write(self) except -1\n    cdef inline Py_ssize_t _try_write(self, object data) except -2\n\n    cdef _close(self)\n\n    cdef inline _on_accept(self)\n    cdef inline _on_eof(self)\n    cdef inline _on_write(self)\n    cdef inline _on_connect(self, object exc)\n"
  },
  {
    "path": "uvloop/handles/stream.pyx",
    "content": "cdef enum:\n    __PREALLOCED_BUFS = 4\n\n\n@cython.no_gc_clear\n@cython.freelist(DEFAULT_FREELIST_SIZE)\ncdef class _StreamWriteContext:\n    # used to hold additional write request information for uv_write\n\n    cdef:\n        uv.uv_write_t   req\n\n        list            buffers\n\n        uv.uv_buf_t     uv_bufs_sml[__PREALLOCED_BUFS]\n        Py_buffer       py_bufs_sml[__PREALLOCED_BUFS]\n        bint            py_bufs_sml_inuse\n\n        uv.uv_buf_t*    uv_bufs\n        Py_buffer*      py_bufs\n        size_t          py_bufs_len\n\n        uv.uv_buf_t*    uv_bufs_start\n        size_t          uv_bufs_len\n\n        UVStream        stream\n\n        bint            closed\n\n    cdef free_bufs(self):\n        cdef size_t i\n\n        if self.uv_bufs is not NULL:\n            PyMem_RawFree(self.uv_bufs)\n            self.uv_bufs = NULL\n            if UVLOOP_DEBUG:\n                if self.py_bufs_sml_inuse:\n                    raise RuntimeError(\n                        '_StreamWriteContext.close: uv_bufs != NULL and '\n                        'py_bufs_sml_inuse is True')\n\n        if self.py_bufs is not NULL:\n            for i from 0 <= i < self.py_bufs_len:\n                PyBuffer_Release(&self.py_bufs[i])\n            PyMem_RawFree(self.py_bufs)\n            self.py_bufs = NULL\n            if UVLOOP_DEBUG:\n                if self.py_bufs_sml_inuse:\n                    raise RuntimeError(\n                        '_StreamWriteContext.close: py_bufs != NULL and '\n                        'py_bufs_sml_inuse is True')\n\n        if self.py_bufs_sml_inuse:\n            for i from 0 <= i < self.py_bufs_len:\n                PyBuffer_Release(&self.py_bufs_sml[i])\n            self.py_bufs_sml_inuse = 0\n\n        self.py_bufs_len = 0\n        self.buffers = None\n\n    cdef close(self):\n        if self.closed:\n            return\n        self.closed = 1\n        self.free_bufs()\n        Py_DECREF(self)\n\n    cdef advance_uv_buf(self, size_t sent):\n        # Advance the pointer to first uv_buf and the\n        # pointer to first byte in that buffer.\n        #\n        # We do this after a \"uv_try_write\" call, which\n        # sometimes sends only a portion of data.\n        # We then call \"advance_uv_buf\" on the write\n        # context, and reuse it in a \"uv_write\" call.\n\n        cdef:\n            uv.uv_buf_t* buf\n            size_t idx\n\n        for idx from 0 <= idx < self.uv_bufs_len:\n            buf = &self.uv_bufs_start[idx]\n            if buf.len > sent:\n                buf.len -= sent\n                buf.base = buf.base + sent\n                self.uv_bufs_start = buf\n                self.uv_bufs_len -= idx\n                return\n            else:\n                sent -= self.uv_bufs_start[idx].len\n\n            if UVLOOP_DEBUG:\n                if sent < 0:\n                    raise RuntimeError('fatal: sent < 0 in advance_uv_buf')\n\n        raise RuntimeError('fatal: Could not advance _StreamWriteContext')\n\n    @staticmethod\n    cdef _StreamWriteContext new(UVStream stream, list buffers):\n        cdef:\n            _StreamWriteContext ctx\n            int uv_bufs_idx = 0\n            size_t py_bufs_len = 0\n            int i\n\n            Py_buffer* p_pybufs\n            uv.uv_buf_t* p_uvbufs\n\n        ctx = _StreamWriteContext.__new__(_StreamWriteContext)\n        ctx.stream = None\n        ctx.closed = 1\n        ctx.py_bufs_len = 0\n        ctx.py_bufs_sml_inuse = 0\n        ctx.uv_bufs = NULL\n        ctx.py_bufs = NULL\n        ctx.buffers = buffers\n        ctx.stream = stream\n\n        if len(buffers) <= __PREALLOCED_BUFS:\n            # We've got a small number of buffers to write, don't\n            # need to use malloc.\n            ctx.py_bufs_sml_inuse = 1\n            p_pybufs = <Py_buffer*>&ctx.py_bufs_sml\n            p_uvbufs = <uv.uv_buf_t*>&ctx.uv_bufs_sml\n\n        else:\n            for buf in buffers:\n                if UVLOOP_DEBUG:\n                    if not isinstance(buf, (bytes, bytearray, memoryview)):\n                        raise RuntimeError(\n                            'invalid data in writebuf: an instance of '\n                            'bytes, bytearray or memoryview was expected, '\n                            'got {}'.format(type(buf)))\n\n                if not PyBytes_CheckExact(buf):\n                    py_bufs_len += 1\n\n            if py_bufs_len > 0:\n                ctx.py_bufs = <Py_buffer*>PyMem_RawMalloc(\n                    py_bufs_len * sizeof(Py_buffer))\n                if ctx.py_bufs is NULL:\n                    raise MemoryError()\n\n            ctx.uv_bufs = <uv.uv_buf_t*>PyMem_RawMalloc(\n                len(buffers) * sizeof(uv.uv_buf_t))\n            if ctx.uv_bufs is NULL:\n                raise MemoryError()\n\n            p_pybufs = ctx.py_bufs\n            p_uvbufs = ctx.uv_bufs\n\n        py_bufs_len = 0\n        for buf in buffers:\n            if PyBytes_CheckExact(buf):\n                # We can only use this hack for bytes since it's\n                # immutable.  For everything else it is only safe to\n                # use buffer protocol.\n                p_uvbufs[uv_bufs_idx].base = PyBytes_AS_STRING(buf)\n                p_uvbufs[uv_bufs_idx].len = Py_SIZE(buf)\n\n            else:\n                try:\n                    PyObject_GetBuffer(\n                        buf, &p_pybufs[py_bufs_len], PyBUF_SIMPLE)\n                except Exception:\n                    # This shouldn't ever happen, as `UVStream._buffer_write`\n                    # casts non-bytes objects to `memoryviews`.\n                    ctx.py_bufs_len = py_bufs_len\n                    ctx.free_bufs()\n                    raise\n\n                p_uvbufs[uv_bufs_idx].base = <char*>p_pybufs[py_bufs_len].buf\n                p_uvbufs[uv_bufs_idx].len = p_pybufs[py_bufs_len].len\n\n                py_bufs_len += 1\n\n            uv_bufs_idx += 1\n\n        ctx.uv_bufs_start = p_uvbufs\n        ctx.uv_bufs_len = uv_bufs_idx\n\n        ctx.py_bufs_len = py_bufs_len\n        ctx.req.data = <void*> ctx\n\n        if UVLOOP_DEBUG:\n            stream._loop._debug_stream_write_ctx_total += 1\n            stream._loop._debug_stream_write_ctx_cnt += 1\n\n        # Do incref after everything else is done.\n        # Under no circumstances we want `ctx` to be GCed while\n        # libuv is still working with `ctx.uv_bufs`.\n        Py_INCREF(ctx)\n        ctx.closed = 0\n        return ctx\n\n    def __dealloc__(self):\n        if not self.closed:\n            # Because we do an INCREF in _StreamWriteContext.new,\n            # __dealloc__ shouldn't ever happen with `self.closed == 1`\n            raise RuntimeError(\n                'open _StreamWriteContext is being deallocated')\n\n        if UVLOOP_DEBUG:\n            if self.stream is not None:\n                self.stream._loop._debug_stream_write_ctx_cnt -= 1\n                self.stream = None\n\n\n@cython.no_gc_clear\ncdef class UVStream(UVBaseTransport):\n\n    def __cinit__(self):\n        self.__shutting_down = 0\n        self.__reading = 0\n        self.__read_error_close = 0\n\n        self.__protocol_type = ProtocolType.SIMPLE\n        self._protocol_get_buffer = None\n        self._protocol_buffer_updated = None\n\n        self._eof = 0\n        self._buffer = []\n        self._buffer_size = 0\n\n        self._read_pybuf_acquired = False\n\n    cdef _set_protocol(self, object protocol):\n        if protocol is None:\n            raise TypeError('protocol is required')\n\n        UVBaseTransport._set_protocol(self, protocol)\n\n        if isinstance(protocol, SSLProtocol):\n            self.__protocol_type = ProtocolType.SSL_PROTOCOL\n        elif (hasattr(protocol, 'get_buffer') and\n                not isinstance(protocol, aio_Protocol)):\n            try:\n                self._protocol_get_buffer = protocol.get_buffer\n                self._protocol_buffer_updated = protocol.buffer_updated\n                self.__protocol_type = ProtocolType.BUFFERED\n            except AttributeError:\n                pass\n        else:\n            self.__protocol_type = ProtocolType.SIMPLE\n\n    cdef _clear_protocol(self):\n        UVBaseTransport._clear_protocol(self)\n        self._protocol_get_buffer = None\n        self._protocol_buffer_updated = None\n        self.__protocol_type = ProtocolType.SIMPLE\n\n    cdef inline _shutdown(self):\n        cdef int err\n\n        if self.__shutting_down:\n            return\n        self.__shutting_down = 1\n\n        self._ensure_alive()\n\n        self._shutdown_req.data = <void*> self\n        err = uv.uv_shutdown(&self._shutdown_req,\n                             <uv.uv_stream_t*> self._handle,\n                             __uv_stream_on_shutdown)\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n\n    cdef inline _accept(self, UVStream server):\n        cdef int err\n        self._ensure_alive()\n\n        err = uv.uv_accept(<uv.uv_stream_t*>server._handle,\n                           <uv.uv_stream_t*>self._handle)\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n\n        self._on_accept()\n\n    cdef inline _close_on_read_error(self):\n        self.__read_error_close = 1\n\n    cdef bint _is_reading(self):\n        return self.__reading\n\n    cdef _start_reading(self):\n        cdef int err\n\n        if self._closing:\n            return\n\n        self._ensure_alive()\n\n        if self.__reading:\n            return\n\n        if self.__protocol_type == ProtocolType.SIMPLE:\n            err = uv.uv_read_start(<uv.uv_stream_t*>self._handle,\n                                   __loop_alloc_buffer,\n                                   __uv_stream_on_read)\n        else:\n            err = uv.uv_read_start(<uv.uv_stream_t *> self._handle,\n                                   __uv_stream_buffered_alloc,\n                                   __uv_stream_buffered_on_read)\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n        else:\n            # UVStream must live until the read callback is called\n            self.__reading_started()\n\n    cdef inline __reading_started(self):\n        if self.__reading:\n            return\n        self.__reading = 1\n        Py_INCREF(self)\n\n    cdef inline __reading_stopped(self):\n        if not self.__reading:\n            return\n        self.__reading = 0\n        Py_DECREF(self)\n\n    cdef _stop_reading(self):\n        cdef int err\n\n        if not self.__reading:\n            return\n\n        self._ensure_alive()\n\n        # From libuv docs:\n        #    This function is idempotent and may be safely\n        #    called on a stopped stream.\n        err = uv.uv_read_stop(<uv.uv_stream_t*>self._handle)\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n        else:\n            self.__reading_stopped()\n\n    cdef inline Py_ssize_t _try_write(self, object data) except -2:\n        # Returns number of bytes written.\n        # -1 - in case of fatal errors\n        cdef:\n            Py_ssize_t written\n            bint used_buf = 0\n            Py_buffer py_buf\n            void* buf\n            Py_ssize_t blen\n            int saved_errno\n            int fd\n\n        if (<uv.uv_stream_t*>self._handle).write_queue_size != 0:\n            raise RuntimeError(\n                'UVStream._try_write called with data in uv buffers')\n\n        if PyBytes_CheckExact(data):\n            # We can only use this hack for bytes since it's\n            # immutable.  For everything else it is only safe to\n            # use buffer protocol.\n            buf = <void*>PyBytes_AS_STRING(data)\n            blen = Py_SIZE(data)\n        else:\n            PyObject_GetBuffer(data, &py_buf, PyBUF_SIMPLE)\n            used_buf = 1\n            buf = py_buf.buf\n            blen = py_buf.len\n\n        if blen == 0:\n            if used_buf:\n                PyBuffer_Release(&py_buf)\n            # Empty data, do nothing.\n            return 0\n\n        fd = self._fileno()\n        # Use `unistd.h/write` directly, it's faster than\n        # uv_try_write -- less layers of code.  The error\n        # checking logic is copied from libuv.\n        written = system.write(fd, buf, blen)\n        while written == -1 and (\n                errno.errno == errno.EINTR or\n                (system.PLATFORM_IS_APPLE and\n                    errno.errno == errno.EPROTOTYPE)):\n            # From libuv code (unix/stream.c):\n            #   Due to a possible kernel bug at least in OS X 10.10 \"Yosemite\",\n            #   EPROTOTYPE can be returned while trying to write to a socket\n            #   that is shutting down. If we retry the write, we should get\n            #   the expected EPIPE instead.\n            written = system.write(fd, buf, blen)\n        saved_errno = errno.errno\n\n        if used_buf:\n            PyBuffer_Release(&py_buf)\n\n        if written < 0:\n            if saved_errno in (errno.EAGAIN, system.EWOULDBLOCK):\n                return 0\n            else:\n                exc = convert_error(-saved_errno)\n                self._fatal_error(exc, True)\n                return -1\n\n        if UVLOOP_DEBUG:\n            self._loop._debug_stream_write_tries += 1\n\n        return written\n\n    cdef inline _buffer_write(self, object data):\n        cdef Py_ssize_t dlen\n\n        if not PyBytes_CheckExact(data):\n            data = memoryview(data).cast('b')\n\n        dlen = len(data)\n        if not dlen:\n            return\n\n        self._buffer_size += dlen\n        self._buffer.append(data)\n\n    cdef inline _initiate_write(self):\n        cdef bint all_sent\n\n        if (not self._protocol_paused and\n            (<uv.uv_stream_t*>self._handle).write_queue_size == 0):\n            # Fast-path.  If:\n            #   - the protocol isn't yet paused,\n            #   - there is no data in libuv buffers for this stream,\n            #\n            # Then:\n            #   - Try to write all buffered data right now.\n            all_sent = self._exec_write()\n            if UVLOOP_DEBUG:\n                if self._buffer_size != 0 or self._buffer:\n                    raise RuntimeError(\n                        '_buffer_size is not 0 after a successful _exec_write')\n\n            # There is no need to call `_queue_write` anymore,\n            # as `uv_write` should be called already.\n\n            if not all_sent:\n                # If not all of the data was sent successfully,\n                # we might need to pause the protocol.\n                self._maybe_pause_protocol()\n\n        elif self._buffer_size > 0:\n            self._maybe_pause_protocol()\n            self._loop._queue_write(self)\n\n    cdef inline bint _exec_write(self) except -1:\n        # Returns True if all data from self._buffers has been sent,\n        # False - otherwise\n        cdef:\n            int err\n            Py_ssize_t buf_len\n            Py_ssize_t sent\n            _StreamWriteContext ctx = None\n\n        if self._closed:\n            # If the handle is closed, just return, it's too\n            # late to do anything.\n            return False\n\n        buf_len = len(self._buffer)\n        if not buf_len:\n            return True\n\n        if (<uv.uv_stream_t*>self._handle).write_queue_size == 0:\n            # libuv internal write buffers for this stream are empty.\n            if buf_len == 1:\n                # If we only have one piece of data to send, let's\n                # use our fast implementation of try_write.\n                data = self._buffer[0]\n                sent = self._try_write(data)\n\n                if sent == len(data):\n                    # The most likely and latency sensitive outcome goes first,\n                    # all data was successfully written.\n                    self._buffer_size = 0\n                    self._buffer.clear()\n                    # on_write will call \"maybe_resume_protocol\".\n                    self._on_write()\n                    return True\n\n                elif sent > 0:\n                    if PyBytes_CheckExact(data):\n                        # Cast bytes to memoryview to avoid copying\n                        # data that wasn't sent.\n                        data = memoryview(data)\n                    data = data[sent:]\n\n                    self._buffer_size -= sent\n                    self._buffer[0] = data\n\n                elif sent == -1:\n                    # A `self._fatal_error` was called.\n                    # It might not raise an exception under some\n                    # conditions.\n                    self._buffer_size = 0\n                    self._buffer.clear()\n                    if not self._closing:\n                        # This should never happen.\n                        raise RuntimeError(\n                            'stream is open after UVStream._try_write '\n                            'returned None')\n                    return False\n\n                # At this point it's either data was sent partially,\n                # or an EAGAIN has happened.\n\n            else:\n                ctx = _StreamWriteContext.new(self, self._buffer)\n\n                err = uv.uv_try_write(<uv.uv_stream_t*>self._handle,\n                                      ctx.uv_bufs_start,\n                                      ctx.uv_bufs_len)\n\n                if err > 0:\n                    # Some data was successfully sent.\n\n                    if <size_t>err == self._buffer_size:\n                        # Everything was sent.\n                        ctx.close()\n                        self._buffer.clear()\n                        self._buffer_size = 0\n                        # on_write will call \"maybe_resume_protocol\".\n                        self._on_write()\n                        return True\n\n                    try:\n                        # Advance pointers to uv_bufs in `ctx`,\n                        # we will reuse it soon for a uv_write\n                        # call.\n                        ctx.advance_uv_buf(<ssize_t>err)\n                    except Exception as ex:  # This should never happen.\n                        # Let's try to close the `ctx` anyways.\n                        ctx.close()\n                        self._fatal_error(ex, True)\n                        self._buffer.clear()\n                        self._buffer_size = 0\n                        return False\n\n                elif err != uv.UV_EAGAIN:\n                    ctx.close()\n                    exc = convert_error(err)\n                    self._fatal_error(exc, True)\n                    self._buffer.clear()\n                    self._buffer_size = 0\n                    return False\n\n                # fall through\n\n        if ctx is None:\n            ctx = _StreamWriteContext.new(self, self._buffer)\n\n        err = uv.uv_write(&ctx.req,\n                          <uv.uv_stream_t*>self._handle,\n                          ctx.uv_bufs_start,\n                          ctx.uv_bufs_len,\n                          __uv_stream_on_write)\n\n        self._buffer_size = 0\n        # Can't use `_buffer.clear()` here: `ctx` holds a reference to\n        # the `_buffer`.\n        self._buffer = []\n\n        if err < 0:\n            # close write context\n            ctx.close()\n\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return False\n\n        self._maybe_resume_protocol()\n        return False\n\n    cdef size_t _get_write_buffer_size(self):\n        if self._handle is NULL:\n            return 0\n        return ((<uv.uv_stream_t*>self._handle).write_queue_size +\n                self._buffer_size)\n\n    cdef _close(self):\n        try:\n            if self._read_pybuf_acquired:\n                # Should never happen. libuv always calls uv_alloc/uv_read\n                # in pairs.\n                self._loop.call_exception_handler({\n                    'transport': self,\n                    'message': 'XXX: an allocated buffer in transport._close()'\n                })\n                self._read_pybuf_acquired = 0\n                PyBuffer_Release(&self._read_pybuf)\n\n            self._stop_reading()\n        finally:\n            UVSocketHandle._close(<UVHandle>self)\n\n    cdef inline _on_accept(self):\n        # Ultimately called by __uv_stream_on_listen.\n        self._init_protocol()\n\n    cdef inline _on_eof(self):\n        # Any exception raised here will be caught in\n        # __uv_stream_on_read.\n\n        try:\n            meth = self._protocol.eof_received\n        except AttributeError:\n            keep_open = False\n        else:\n            keep_open = run_in_context(self.context, meth)\n\n        if keep_open:\n            # We're keeping the connection open so the\n            # protocol can write more, but we still can't\n            # receive more, so remove the reader callback.\n            self._stop_reading()\n        else:\n            self.close()\n\n    cdef inline _on_write(self):\n        self._maybe_resume_protocol()\n        if not self._get_write_buffer_size():\n            if self._closing:\n                self._schedule_call_connection_lost(None)\n            elif self._eof:\n                self._shutdown()\n\n    cdef inline _init(self, Loop loop, object protocol, Server server,\n                      object waiter, object context):\n        self.context = context\n        self._set_protocol(protocol)\n        self._start_init(loop)\n\n        if server is not None:\n            self._set_server(server)\n\n        if waiter is not None:\n            self._set_waiter(waiter)\n\n    cdef inline _on_connect(self, object exc):\n        # Called from __tcp_connect_callback (tcp.pyx) and\n        # __pipe_connect_callback (pipe.pyx).\n        if exc is None:\n            self._init_protocol()\n        else:\n            if self._waiter is None:\n                self._fatal_error(exc, False, \"connect failed\")\n            elif self._waiter.cancelled():\n                # Connect call was cancelled; just close the transport\n                # silently.\n                self._close()\n            elif self._waiter.done():\n                self._fatal_error(exc, False, \"connect failed\")\n            else:\n                self._waiter.set_exception(exc)\n                self._close()\n\n    # === Public API ===\n\n    def __repr__(self):\n        return '<{} closed={} reading={} {:#x}>'.format(\n            self.__class__.__name__,\n            self._closed,\n            self.__reading,\n            id(self))\n\n    cpdef write(self, object buf):\n        self._ensure_alive()\n\n        if self._eof:\n            raise RuntimeError('Cannot call write() after write_eof()')\n        if not buf:\n            return\n        if self._conn_lost:\n            self._conn_lost += 1\n            return\n        self._buffer_write(buf)\n        self._initiate_write()\n\n    def writelines(self, bufs):\n        self._ensure_alive()\n\n        if self._eof:\n            raise RuntimeError('Cannot call writelines() after write_eof()')\n        if self._conn_lost:\n            self._conn_lost += 1\n            return\n        for buf in bufs:\n            self._buffer_write(buf)\n        self._initiate_write()\n\n    def write_eof(self):\n        self._ensure_alive()\n\n        if self._eof:\n            return\n\n        self._eof = 1\n        if not self._get_write_buffer_size():\n            self._shutdown()\n\n    def can_write_eof(self):\n        return True\n\n    def is_reading(self):\n        return self._is_reading()\n\n    def pause_reading(self):\n        if self._closing or not self._is_reading():\n            return\n        self._stop_reading()\n\n    def resume_reading(self):\n        if self._is_reading() or self._closing:\n            return\n        self._start_reading()\n\n\ncdef void __uv_stream_on_shutdown(uv.uv_shutdown_t* req,\n                                  int status) noexcept with gil:\n\n    # callback for uv_shutdown\n\n    if req.data is NULL:\n        aio_logger.error(\n            'UVStream.shutdown callback called with NULL req.data, status=%r',\n            status)\n        return\n\n    cdef UVStream stream = <UVStream> req.data\n\n    if status < 0 and status != uv.UV_ECANCELED:\n        # From libuv source code:\n        #     The ECANCELED error code is a lie, the shutdown(2) syscall is a\n        #     fait accompli at this point. Maybe we should revisit this in\n        #     v0.11.  A possible reason for leaving it unchanged is that it\n        #     informs the callee that the handle has been destroyed.\n\n        if UVLOOP_DEBUG:\n            stream._loop._debug_stream_shutdown_errors_total += 1\n\n        exc = convert_error(status)\n        stream._fatal_error(\n            exc, False, \"error status in uv_stream_t.shutdown callback\")\n        return\n\n\ncdef inline bint __uv_stream_on_read_common(\n    UVStream sc,\n    Loop loop,\n    ssize_t nread,\n):\n    if sc._closed:\n        # The stream was closed, there is no reason to\n        # do any work now.\n        sc.__reading_stopped()  # Just in case.\n        return True\n\n    if nread == uv.UV_EOF:\n        # From libuv docs:\n        #     The callee is responsible for stopping closing the stream\n        #     when an error happens by calling uv_read_stop() or uv_close().\n        #     Trying to read from the stream again is undefined.\n        try:\n            if UVLOOP_DEBUG:\n                loop._debug_stream_read_eof_total += 1\n\n            sc._stop_reading()\n            sc._on_eof()\n        except BaseException as ex:\n            if UVLOOP_DEBUG:\n                loop._debug_stream_read_eof_cb_errors_total += 1\n\n            sc._fatal_error(ex, False)\n        finally:\n            return True\n\n    if nread == 0:\n        # From libuv docs:\n        #     nread might be 0, which does not indicate an error or EOF.\n        #     This is equivalent to EAGAIN or EWOULDBLOCK under read(2).\n        return True\n\n    if nread < 0:\n        # From libuv docs:\n        #     The callee is responsible for stopping closing the stream\n        #     when an error happens by calling uv_read_stop() or uv_close().\n        #     Trying to read from the stream again is undefined.\n        #\n        # Therefore, we're closing the stream.  Since \"UVHandle._close()\"\n        # doesn't raise exceptions unless uvloop is built with DEBUG=1,\n        # we don't need try...finally here.\n\n        if UVLOOP_DEBUG:\n            loop._debug_stream_read_errors_total += 1\n\n        if sc.__read_error_close:\n            # Used for getting notified when a pipe is closed.\n            # See WriteUnixTransport for the explanation.\n            sc._on_eof()\n            return True\n\n        exc = convert_error(nread)\n        sc._fatal_error(\n            exc, False, \"error status in uv_stream_t.read callback\")\n        return True\n\n    return False\n\n\ncdef inline void __uv_stream_on_read_impl(\n    uv.uv_stream_t* stream,\n    ssize_t nread,\n    const uv.uv_buf_t* buf,\n):\n    cdef:\n        UVStream sc = <UVStream>stream.data\n        Loop loop = sc._loop\n\n    # It's OK to free the buffer early, since nothing will\n    # be able to touch it until this method is done.\n    __loop_free_buffer(loop)\n\n    if __uv_stream_on_read_common(sc, loop, nread):\n        return\n\n    try:\n        if UVLOOP_DEBUG:\n            loop._debug_stream_read_cb_total += 1\n\n        run_in_context1(\n            sc.context,\n            sc._protocol_data_received,\n            loop._recv_buffer[:nread],\n        )\n    except BaseException as exc:\n        if UVLOOP_DEBUG:\n            loop._debug_stream_read_cb_errors_total += 1\n\n        sc._fatal_error(exc, False)\n\n\ncdef inline void __uv_stream_on_write_impl(\n    uv.uv_write_t* req,\n    int status,\n):\n    cdef:\n        _StreamWriteContext ctx = <_StreamWriteContext> req.data\n        UVStream stream = <UVStream>ctx.stream\n\n    ctx.close()\n\n    if stream._closed:\n        # The stream was closed, there is nothing to do.\n        # Even if there is an error, like EPIPE, there\n        # is no reason to report it.\n        return\n\n    if status < 0:\n        if UVLOOP_DEBUG:\n            stream._loop._debug_stream_write_errors_total += 1\n\n        exc = convert_error(status)\n        stream._fatal_error(\n            exc, False, \"error status in uv_stream_t.write callback\")\n        return\n\n    try:\n        stream._on_write()\n    except BaseException as exc:\n        if UVLOOP_DEBUG:\n            stream._loop._debug_stream_write_cb_errors_total += 1\n\n        stream._fatal_error(exc, False)\n\n\ncdef void __uv_stream_on_read(\n    uv.uv_stream_t* stream,\n    ssize_t nread,\n    const uv.uv_buf_t* buf,\n) noexcept with gil:\n\n    if __ensure_handle_data(<uv.uv_handle_t*>stream,\n                            \"UVStream read callback\") == 0:\n        return\n\n    # Don't need try-finally, __uv_stream_on_read_impl is void\n    __uv_stream_on_read_impl(stream, nread, buf)\n\n\ncdef void __uv_stream_on_write(\n    uv.uv_write_t* req,\n    int status,\n) noexcept with gil:\n\n    if UVLOOP_DEBUG:\n        if req.data is NULL:\n            aio_logger.error(\n                'UVStream.write callback called with NULL req.data, status=%r',\n                status)\n            return\n\n    # Don't need try-finally, __uv_stream_on_write_impl is void\n    __uv_stream_on_write_impl(req, status)\n\n\ncdef void __uv_stream_buffered_alloc(\n    uv.uv_handle_t* stream,\n    size_t suggested_size,\n    uv.uv_buf_t* uvbuf,\n) noexcept with gil:\n\n    if __ensure_handle_data(<uv.uv_handle_t*>stream,\n                            \"UVStream alloc buffer callback\") == 0:\n        return\n\n    cdef UVStream sc = <UVStream>stream.data\n\n    # Fast pass for our own SSLProtocol\n    # avoid python calls, memoryviews, context enter/exit, etc\n    if sc.__protocol_type == ProtocolType.SSL_PROTOCOL:\n        try:\n            (<SSLProtocol>sc._protocol).get_buffer_impl(\n                suggested_size, &uvbuf.base, &uvbuf.len)\n            return\n        except BaseException as exc:\n            # Can't call 'sc._fatal_error' or 'sc._close', libuv will SF.\n            # We'll do it later in __uv_stream_buffered_on_read when we\n            # receive UV_ENOBUFS.\n            uvbuf.len = 0\n            uvbuf.base = NULL\n            return\n\n    cdef:\n        Py_buffer* pybuf = &sc._read_pybuf\n        int got_buf = 0\n\n    if sc._read_pybuf_acquired:\n        uvbuf.len = 0\n        uvbuf.base = NULL\n        return\n\n    sc._read_pybuf_acquired = 0\n    try:\n        buf = run_in_context1(\n            sc.context,\n            sc._protocol_get_buffer,\n            suggested_size,\n        )\n        PyObject_GetBuffer(buf, pybuf, PyBUF_WRITABLE)\n        got_buf = 1\n    except BaseException as exc:\n        # Can't call 'sc._fatal_error' or 'sc._close', libuv will SF.\n        # We'll do it later in __uv_stream_buffered_on_read when we\n        # receive UV_ENOBUFS.\n        uvbuf.len = 0\n        uvbuf.base = NULL\n        return\n\n    if not pybuf.len:\n        uvbuf.len = 0\n        uvbuf.base = NULL\n        if got_buf:\n            PyBuffer_Release(pybuf)\n        return\n\n    sc._read_pybuf_acquired = 1\n    uvbuf.base = <char*>pybuf.buf\n    uvbuf.len = pybuf.len\n\n\ncdef void __uv_stream_buffered_on_read(\n    uv.uv_stream_t* stream,\n    ssize_t nread,\n    const uv.uv_buf_t* buf,\n) noexcept with gil:\n\n    if __ensure_handle_data(<uv.uv_handle_t*>stream,\n                            \"UVStream buffered read callback\") == 0:\n        return\n\n    cdef:\n        UVStream sc = <UVStream>stream.data\n        Loop loop = sc._loop\n        Py_buffer* pybuf = &sc._read_pybuf\n\n    if nread == uv.UV_ENOBUFS:\n        sc._fatal_error(\n            RuntimeError(\n                'unhandled error (or an empty buffer) in get_buffer()'),\n            False)\n        return\n\n    try:\n        # When our own SSLProtocol is used, we get buffer pointer directly,\n        # through SSLProtocol.get_buffer_impl, not through Py_Buffer interface.\n        # Therefore sc._read_pybuf_acquired is always False for SSLProtocol.\n        if (nread > 0 and\n            sc.__protocol_type == ProtocolType.BUFFERED and\n            not sc._read_pybuf_acquired):\n            # From libuv docs:\n            #     nread is > 0 if there is data available or < 0 on error. When\n            #     we’ve reached EOF, nread will be set to UV_EOF. When\n            #     nread < 0, the buf parameter might not point to a valid\n            #     buffer; in that case buf.len and buf.base are both set to 0.\n            raise RuntimeError(\n                f'no python buffer is allocated in on_read; nread={nread}')\n\n        if nread == 0:\n            # From libuv docs:\n            #     nread might be 0, which does not indicate an error or EOF.\n            #     This is equivalent to EAGAIN or EWOULDBLOCK under read(2).\n            return\n\n        if __uv_stream_on_read_common(sc, loop, nread):\n            return\n\n        if UVLOOP_DEBUG:\n            loop._debug_stream_read_cb_total += 1\n\n        if sc.__protocol_type == ProtocolType.SSL_PROTOCOL:\n            Context_Enter(sc.context)\n            try:\n                (<SSLProtocol>sc._protocol).buffer_updated_impl(nread)\n            finally:\n                Context_Exit(sc.context)\n        else:\n            run_in_context1(sc.context, sc._protocol_buffer_updated, nread)\n    except BaseException as exc:\n        if UVLOOP_DEBUG:\n            loop._debug_stream_read_cb_errors_total += 1\n\n        sc._fatal_error(exc, False)\n    finally:\n        if sc._read_pybuf_acquired:\n            sc._read_pybuf_acquired = 0\n            PyBuffer_Release(pybuf)\n"
  },
  {
    "path": "uvloop/handles/streamserver.pxd",
    "content": "cdef class UVStreamServer(UVSocketHandle):\n    cdef:\n        int backlog\n        object ssl\n        object ssl_handshake_timeout\n        object ssl_shutdown_timeout\n        object protocol_factory\n        bint opened\n        Server _server\n\n    # All \"inline\" methods are final\n\n    cdef inline _init(self, Loop loop, object protocol_factory,\n                      Server server,\n                      object backlog,\n                      object ssl,\n                      object ssl_handshake_timeout,\n                      object ssl_shutdown_timeout)\n\n    cdef inline _mark_as_open(self)\n\n    cdef inline listen(self)\n    cdef inline _on_listen(self)\n\n    cdef UVStream _make_new_transport(self, object protocol, object waiter,\n                                      object context)\n"
  },
  {
    "path": "uvloop/handles/streamserver.pyx",
    "content": "@cython.no_gc_clear\ncdef class UVStreamServer(UVSocketHandle):\n\n    def __cinit__(self):\n        self.opened = 0\n        self._server = None\n        self.ssl = None\n        self.ssl_handshake_timeout = None\n        self.ssl_shutdown_timeout = None\n        self.protocol_factory = None\n\n    cdef inline _init(self, Loop loop, object protocol_factory,\n                      Server server,\n                      object backlog,\n                      object ssl,\n                      object ssl_handshake_timeout,\n                      object ssl_shutdown_timeout):\n\n        if not isinstance(backlog, int):\n            # Don't allow floats\n            raise TypeError('integer argument expected, got {}'.format(\n                type(backlog).__name__))\n\n        if ssl is not None:\n            if not isinstance(ssl, ssl_SSLContext):\n                raise TypeError(\n                    'ssl is expected to be None or an instance of '\n                    'ssl.SSLContext, got {!r}'.format(ssl))\n        else:\n            if ssl_handshake_timeout is not None:\n                raise ValueError(\n                    'ssl_handshake_timeout is only meaningful with ssl')\n            if ssl_shutdown_timeout is not None:\n                raise ValueError(\n                    'ssl_shutdown_timeout is only meaningful with ssl')\n\n        self.backlog = backlog\n        self.ssl = ssl\n        self.ssl_handshake_timeout = ssl_handshake_timeout\n        self.ssl_shutdown_timeout = ssl_shutdown_timeout\n\n        self._start_init(loop)\n        self.protocol_factory = protocol_factory\n        self._server = server\n\n    cdef inline listen(self):\n        cdef int err\n        self._ensure_alive()\n\n        if self.protocol_factory is None:\n            raise RuntimeError('unable to listen(); no protocol_factory')\n\n        if self.opened != 1:\n            raise RuntimeError('unopened TCPServer')\n\n        self.context = Context_CopyCurrent()\n\n        err = uv.uv_listen(<uv.uv_stream_t*> self._handle,\n                           self.backlog,\n                           __uv_streamserver_on_listen)\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n\n    cdef inline _on_listen(self):\n        cdef UVStream client\n\n        protocol = run_in_context(self.context, self.protocol_factory)\n\n        if self.ssl is None:\n            client = self._make_new_transport(protocol, None, self.context)\n\n        else:\n            waiter = self._loop._new_future()\n\n            ssl_protocol = SSLProtocol(\n                self._loop, protocol, self.ssl,\n                waiter,\n                server_side=True,\n                server_hostname=None,\n                ssl_handshake_timeout=self.ssl_handshake_timeout,\n                ssl_shutdown_timeout=self.ssl_shutdown_timeout)\n\n            client = self._make_new_transport(ssl_protocol, None, self.context)\n\n            waiter.add_done_callback(\n                ft_partial(self.__on_ssl_connected, client))\n\n        client._accept(<UVStream>self)\n\n    cdef _fatal_error(self, exc, throw, reason=None):\n        # Overload UVHandle._fatal_error\n\n        self._close()\n\n        if not isinstance(exc, OSError):\n\n            if throw or self._loop is None:\n                raise exc\n\n            msg = f'Fatal error on server {self.__class__.__name__}'\n            if reason is not None:\n                msg = f'{msg} ({reason})'\n\n            self._loop.call_exception_handler({\n                'message': msg,\n                'exception': exc,\n            })\n\n    cdef inline _mark_as_open(self):\n        self.opened = 1\n\n    cdef UVStream _make_new_transport(self, object protocol, object waiter,\n                                      object context):\n        raise NotImplementedError\n\n    def __on_ssl_connected(self, transport, fut):\n        exc = fut.exception()\n        if exc is not None:\n            transport._force_close(exc)\n\n\ncdef void __uv_streamserver_on_listen(\n    uv.uv_stream_t* handle,\n    int status,\n) noexcept with gil:\n\n    # callback for uv_listen\n\n    if __ensure_handle_data(<uv.uv_handle_t*>handle,\n                            \"UVStream listen callback\") == 0:\n        return\n\n    cdef:\n        UVStreamServer stream = <UVStreamServer> handle.data\n\n    if status < 0:\n        if UVLOOP_DEBUG:\n            stream._loop._debug_stream_listen_errors_total += 1\n\n        exc = convert_error(status)\n        stream._fatal_error(\n            exc, False, \"error status in uv_stream_t.listen callback\")\n        return\n\n    try:\n        stream._on_listen()\n    except BaseException as exc:\n        stream._error(exc, False)\n"
  },
  {
    "path": "uvloop/handles/tcp.pxd",
    "content": "cdef class TCPServer(UVStreamServer):\n    cdef bind(self, system.sockaddr* addr, unsigned int flags=*)\n\n    @staticmethod\n    cdef TCPServer new(Loop loop, object protocol_factory, Server server,\n                       unsigned int flags,\n                       object backlog,\n                       object ssl,\n                       object ssl_handshake_timeout,\n                       object ssl_shutdown_timeout)\n\n\ncdef class TCPTransport(UVStream):\n    cdef:\n        bint __peername_set\n        bint __sockname_set\n        system.sockaddr_storage __peername\n        system.sockaddr_storage __sockname\n\n    cdef bind(self, system.sockaddr* addr, unsigned int flags=*)\n    cdef connect(self, system.sockaddr* addr)\n    cdef _set_nodelay(self)\n\n    @staticmethod\n    cdef TCPTransport new(Loop loop, object protocol, Server server,\n                          object waiter, object context)\n"
  },
  {
    "path": "uvloop/handles/tcp.pyx",
    "content": "cdef __tcp_init_uv_handle(UVStream handle, Loop loop, unsigned int flags):\n    cdef int err\n\n    handle._handle = <uv.uv_handle_t*>PyMem_RawMalloc(sizeof(uv.uv_tcp_t))\n    if handle._handle is NULL:\n        handle._abort_init()\n        raise MemoryError()\n\n    err = uv.uv_tcp_init_ex(handle._loop.uvloop,\n                            <uv.uv_tcp_t*>handle._handle,\n                            flags)\n    if err < 0:\n        handle._abort_init()\n        raise convert_error(err)\n\n    handle._finish_init()\n\n\ncdef __tcp_bind(UVStream handle, system.sockaddr* addr, unsigned int flags):\n    cdef int err\n    err = uv.uv_tcp_bind(<uv.uv_tcp_t *>handle._handle,\n                         addr, flags)\n    if err < 0:\n        exc = convert_error(err)\n        raise exc\n\n\ncdef __tcp_open(UVStream handle, int sockfd):\n    cdef int err\n    err = uv.uv_tcp_open(<uv.uv_tcp_t *>handle._handle,\n                         <uv.uv_os_sock_t>sockfd)\n    if err < 0:\n        exc = convert_error(err)\n        raise exc\n\n\ncdef __tcp_get_socket(UVSocketHandle handle):\n    cdef:\n        int buf_len = sizeof(system.sockaddr_storage)\n        int fileno\n        int err\n        system.sockaddr_storage buf\n\n    fileno = handle._fileno()\n\n    err = uv.uv_tcp_getsockname(<uv.uv_tcp_t*>handle._handle,\n                                <system.sockaddr*>&buf,\n                                &buf_len)\n    if err < 0:\n        raise convert_error(err)\n\n    return PseudoSocket(buf.ss_family, uv.SOCK_STREAM, 0, fileno)\n\n\n@cython.no_gc_clear\ncdef class TCPServer(UVStreamServer):\n\n    @staticmethod\n    cdef TCPServer new(Loop loop, object protocol_factory, Server server,\n                       unsigned int flags,\n                       object backlog,\n                       object ssl,\n                       object ssl_handshake_timeout,\n                       object ssl_shutdown_timeout):\n\n        cdef TCPServer handle\n        handle = TCPServer.__new__(TCPServer)\n        handle._init(loop, protocol_factory, server, backlog,\n                     ssl, ssl_handshake_timeout, ssl_shutdown_timeout)\n        __tcp_init_uv_handle(<UVStream>handle, loop, flags)\n        return handle\n\n    cdef _new_socket(self):\n        return __tcp_get_socket(<UVSocketHandle>self)\n\n    cdef _open(self, int sockfd):\n        self._ensure_alive()\n        try:\n            __tcp_open(<UVStream>self, sockfd)\n        except Exception as exc:\n            self._fatal_error(exc, True)\n        else:\n            self._mark_as_open()\n\n    cdef bind(self, system.sockaddr* addr, unsigned int flags=0):\n        self._ensure_alive()\n        try:\n            __tcp_bind(<UVStream>self, addr, flags)\n        except Exception as exc:\n            self._fatal_error(exc, True)\n        else:\n            self._mark_as_open()\n\n    cdef UVStream _make_new_transport(self, object protocol, object waiter,\n                                      object context):\n        cdef TCPTransport tr\n        tr = TCPTransport.new(self._loop, protocol, self._server, waiter,\n                              context)\n        return <UVStream>tr\n\n\n@cython.no_gc_clear\ncdef class TCPTransport(UVStream):\n\n    @staticmethod\n    cdef TCPTransport new(Loop loop, object protocol, Server server,\n                          object waiter, object context):\n\n        cdef TCPTransport handle\n        handle = TCPTransport.__new__(TCPTransport)\n        handle._init(loop, protocol, server, waiter, context)\n        __tcp_init_uv_handle(<UVStream>handle, loop, uv.AF_UNSPEC)\n        handle.__peername_set = 0\n        handle.__sockname_set = 0\n        handle._set_nodelay()\n        return handle\n\n    cdef _set_nodelay(self):\n        cdef int err\n        self._ensure_alive()\n        err = uv.uv_tcp_nodelay(<uv.uv_tcp_t*>self._handle, 1)\n        if err < 0:\n            raise convert_error(err)\n\n    cdef _call_connection_made(self):\n        # asyncio saves peername & sockname when transports are instantiated,\n        # so that they're accessible even after the transport is closed.\n        # We are doing the same thing here, except that we create Python\n        # objects lazily, on request in get_extra_info()\n\n        cdef:\n            int err\n            int buf_len\n\n        buf_len = sizeof(system.sockaddr_storage)\n        err = uv.uv_tcp_getsockname(<uv.uv_tcp_t*>self._handle,\n                                    <system.sockaddr*>&self.__sockname,\n                                    &buf_len)\n        if err >= 0:\n            # Ignore errors, this is an optional thing.\n            # If something serious is going on, the transport\n            # will crash later (in roughly the same way how\n            # an asyncio transport would.)\n            self.__sockname_set = 1\n\n        buf_len = sizeof(system.sockaddr_storage)\n        err = uv.uv_tcp_getpeername(<uv.uv_tcp_t*>self._handle,\n                                    <system.sockaddr*>&self.__peername,\n                                    &buf_len)\n        if err >= 0:\n            # Same as few lines above -- we don't really care\n            # about error case here.\n            self.__peername_set = 1\n\n        UVBaseTransport._call_connection_made(self)\n\n    def get_extra_info(self, name, default=None):\n        if name == 'sockname':\n            if self.__sockname_set:\n                return __convert_sockaddr_to_pyaddr(\n                    <system.sockaddr*>&self.__sockname)\n        elif name == 'peername':\n            if self.__peername_set:\n                return __convert_sockaddr_to_pyaddr(\n                    <system.sockaddr*>&self.__peername)\n        return super().get_extra_info(name, default)\n\n    cdef _new_socket(self):\n        return __tcp_get_socket(<UVSocketHandle>self)\n\n    cdef bind(self, system.sockaddr* addr, unsigned int flags=0):\n        self._ensure_alive()\n        __tcp_bind(<UVStream>self, addr, flags)\n\n    cdef _open(self, int sockfd):\n        self._ensure_alive()\n        __tcp_open(<UVStream>self, sockfd)\n\n    cdef connect(self, system.sockaddr* addr):\n        cdef _TCPConnectRequest req\n        req = _TCPConnectRequest(self._loop, self)\n        req.connect(addr)\n\n\ncdef class _TCPConnectRequest(UVRequest):\n    cdef:\n        TCPTransport transport\n        uv.uv_connect_t _req_data\n\n    def __cinit__(self, loop, transport):\n        self.request = <uv.uv_req_t*>&self._req_data\n        self.request.data = <void*>self\n        self.transport = transport\n\n    cdef connect(self, system.sockaddr* addr):\n        cdef int err\n        err = uv.uv_tcp_connect(<uv.uv_connect_t*>self.request,\n                                <uv.uv_tcp_t*>self.transport._handle,\n                                addr,\n                                __tcp_connect_callback)\n        if err < 0:\n            exc = convert_error(err)\n            self.on_done()\n            raise exc\n\n\ncdef void __tcp_connect_callback(\n    uv.uv_connect_t* req,\n    int status,\n) noexcept with gil:\n    cdef:\n        _TCPConnectRequest wrapper\n        TCPTransport transport\n\n    wrapper = <_TCPConnectRequest> req.data\n    transport = wrapper.transport\n\n    if status < 0:\n        exc = convert_error(status)\n    else:\n        exc = None\n\n    try:\n        transport._on_connect(exc)\n    except BaseException as ex:\n        wrapper.transport._fatal_error(ex, False)\n    finally:\n        wrapper.on_done()\n"
  },
  {
    "path": "uvloop/handles/timer.pxd",
    "content": "cdef class UVTimer(UVHandle):\n    cdef:\n        method_t callback\n        object ctx\n        bint running\n        uint64_t timeout\n        uint64_t start_t\n\n    cdef _init(self, Loop loop, method_t callback, object ctx,\n               uint64_t timeout)\n\n    cdef stop(self)\n    cdef start(self)\n    cdef get_when(self)\n\n    @staticmethod\n    cdef UVTimer new(Loop loop, method_t callback, object ctx,\n                     uint64_t timeout)\n"
  },
  {
    "path": "uvloop/handles/timer.pyx",
    "content": "@cython.no_gc_clear\ncdef class UVTimer(UVHandle):\n    cdef _init(self, Loop loop, method_t callback, object ctx,\n               uint64_t timeout):\n\n        cdef int err\n\n        self._start_init(loop)\n\n        self._handle = <uv.uv_handle_t*> PyMem_RawMalloc(sizeof(uv.uv_timer_t))\n        if self._handle is NULL:\n            self._abort_init()\n            raise MemoryError()\n\n        err = uv.uv_timer_init(self._loop.uvloop, <uv.uv_timer_t*>self._handle)\n        if err < 0:\n            self._abort_init()\n            raise convert_error(err)\n\n        self._finish_init()\n\n        self.callback = callback\n        self.ctx = ctx\n        self.running = 0\n        self.timeout = timeout\n        self.start_t = 0\n\n    cdef stop(self):\n        cdef int err\n\n        if not self._is_alive():\n            self.running = 0\n            return\n\n        if self.running == 1:\n            err = uv.uv_timer_stop(<uv.uv_timer_t*>self._handle)\n            self.running = 0\n            if err < 0:\n                exc = convert_error(err)\n                self._fatal_error(exc, True)\n                return\n\n    cdef start(self):\n        cdef int err\n\n        self._ensure_alive()\n\n        if self.running == 0:\n            # Update libuv internal time.\n            uv.uv_update_time(self._loop.uvloop)  # void\n            self.start_t = uv.uv_now(self._loop.uvloop)\n\n            err = uv.uv_timer_start(<uv.uv_timer_t*>self._handle,\n                                    __uvtimer_callback,\n                                    self.timeout, 0)\n            if err < 0:\n                exc = convert_error(err)\n                self._fatal_error(exc, True)\n                return\n            self.running = 1\n\n    cdef get_when(self):\n        return self.start_t + self.timeout\n\n    @staticmethod\n    cdef UVTimer new(Loop loop, method_t callback, object ctx,\n                     uint64_t timeout):\n\n        cdef UVTimer handle\n        handle = UVTimer.__new__(UVTimer)\n        handle._init(loop, callback, ctx, timeout)\n        return handle\n\n\ncdef void __uvtimer_callback(\n    uv.uv_timer_t* handle,\n) noexcept with gil:\n    if __ensure_handle_data(<uv.uv_handle_t*>handle, \"UVTimer callback\") == 0:\n        return\n\n    cdef:\n        UVTimer timer = <UVTimer> handle.data\n        method_t cb = timer.callback\n\n    timer.running = 0\n    try:\n        cb(timer.ctx)\n    except BaseException as ex:\n        timer._error(ex, False)\n"
  },
  {
    "path": "uvloop/handles/udp.pxd",
    "content": "cdef class UDPTransport(UVBaseTransport):\n    cdef:\n        bint __receiving\n        int _family\n        object _address\n\n    cdef _init(self, Loop loop, unsigned int family)\n    cdef _set_address(self, system.addrinfo *addr)\n\n    cdef _connect(self, system.sockaddr* addr, size_t addr_len)\n\n    cdef _bind(self, system.sockaddr* addr)\n    cdef open(self, int family, int sockfd)\n    cdef _set_broadcast(self, bint on)\n\n    cdef inline __receiving_started(self)\n    cdef inline __receiving_stopped(self)\n\n    cdef _send(self, object data, object addr)\n\n    cdef _on_receive(self, bytes data, object exc, object addr)\n    cdef _on_sent(self, object exc, object context=*)\n"
  },
  {
    "path": "uvloop/handles/udp.pyx",
    "content": "@cython.no_gc_clear\n@cython.freelist(DEFAULT_FREELIST_SIZE)\ncdef class _UDPSendContext:\n    # used to hold additional write request information for uv_write\n\n    cdef:\n        uv.uv_udp_send_t   req\n\n        uv.uv_buf_t     uv_buf\n        Py_buffer       py_buf\n\n        UDPTransport    udp\n\n        bint            closed\n\n    cdef close(self):\n        if self.closed:\n            return\n\n        self.closed = 1\n        PyBuffer_Release(&self.py_buf)  # void\n        self.req.data = NULL\n        self.uv_buf.base = NULL\n        Py_DECREF(self)\n        self.udp = None\n\n    @staticmethod\n    cdef _UDPSendContext new(UDPTransport udp, object data):\n        cdef _UDPSendContext ctx\n        ctx = _UDPSendContext.__new__(_UDPSendContext)\n        ctx.udp = None\n        ctx.closed = 1\n\n        ctx.req.data = <void*> ctx\n        Py_INCREF(ctx)\n\n        PyObject_GetBuffer(data, &ctx.py_buf, PyBUF_SIMPLE)\n        ctx.uv_buf.base = <char*>ctx.py_buf.buf\n        ctx.uv_buf.len = ctx.py_buf.len\n        ctx.udp = udp\n\n        ctx.closed = 0\n        return ctx\n\n    def __dealloc__(self):\n        if UVLOOP_DEBUG:\n            if not self.closed:\n                raise RuntimeError(\n                    'open _UDPSendContext is being deallocated')\n        self.udp = None\n\n\n@cython.no_gc_clear\ncdef class UDPTransport(UVBaseTransport):\n    def __cinit__(self):\n        self._family = uv.AF_UNSPEC\n        self.__receiving = 0\n        self._address = None\n        self.context = Context_CopyCurrent()\n\n    cdef _init(self, Loop loop, unsigned int family):\n        cdef int err\n\n        self._start_init(loop)\n\n        self._handle = <uv.uv_handle_t*>PyMem_RawMalloc(sizeof(uv.uv_udp_t))\n        if self._handle is NULL:\n            self._abort_init()\n            raise MemoryError()\n\n        err = uv.uv_udp_init_ex(loop.uvloop,\n                                <uv.uv_udp_t*>self._handle,\n                                family)\n        if err < 0:\n            self._abort_init()\n            raise convert_error(err)\n\n        if family in (uv.AF_INET, uv.AF_INET6):\n            self._family = family\n\n        self._finish_init()\n\n    cdef _set_address(self, system.addrinfo *addr):\n        self._address = __convert_sockaddr_to_pyaddr(addr.ai_addr)\n\n    cdef _connect(self, system.sockaddr* addr, size_t addr_len):\n        cdef int err\n        err = uv.uv_udp_connect(<uv.uv_udp_t*>self._handle, addr)\n        if err < 0:\n            exc = convert_error(err)\n            raise exc\n\n    cdef open(self, int family, int sockfd):\n        if family in (uv.AF_INET, uv.AF_INET6, uv.AF_UNIX):\n            self._family = family\n        else:\n            raise ValueError(\n                'cannot open a UDP handle, invalid family {}'.format(family))\n\n        cdef int err\n        err = uv.uv_udp_open(<uv.uv_udp_t*>self._handle,\n                             <uv.uv_os_sock_t>sockfd)\n\n        if err < 0:\n            exc = convert_error(err)\n            raise exc\n\n    cdef _bind(self, system.sockaddr* addr):\n        cdef:\n            int err\n            int flags = 0\n\n        self._ensure_alive()\n\n        err = uv.uv_udp_bind(<uv.uv_udp_t*>self._handle, addr, flags)\n        if err < 0:\n            exc = convert_error(err)\n            raise exc\n\n    cdef _set_broadcast(self, bint on):\n        cdef int err\n\n        self._ensure_alive()\n\n        err = uv.uv_udp_set_broadcast(<uv.uv_udp_t*>self._handle, on)\n        if err < 0:\n            exc = convert_error(err)\n            raise exc\n\n    cdef size_t _get_write_buffer_size(self):\n        if self._handle is NULL:\n            return 0\n        return (<uv.uv_udp_t*>self._handle).send_queue_size\n\n    cdef bint _is_reading(self):\n        return self.__receiving\n\n    cdef _start_reading(self):\n        cdef int err\n\n        if self.__receiving:\n            return\n\n        self._ensure_alive()\n\n        err = uv.uv_udp_recv_start(<uv.uv_udp_t*>self._handle,\n                                   __loop_alloc_buffer,\n                                   __uv_udp_on_receive)\n\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n        else:\n            # UDPTransport must live until the read callback is called\n            self.__receiving_started()\n\n    cdef _stop_reading(self):\n        cdef int err\n\n        if not self.__receiving:\n            return\n\n        self._ensure_alive()\n\n        err = uv.uv_udp_recv_stop(<uv.uv_udp_t*>self._handle)\n        if err < 0:\n            exc = convert_error(err)\n            self._fatal_error(exc, True)\n            return\n        else:\n            self.__receiving_stopped()\n\n    cdef inline __receiving_started(self):\n        if self.__receiving:\n            return\n        self.__receiving = 1\n        Py_INCREF(self)\n\n    cdef inline __receiving_stopped(self):\n        if not self.__receiving:\n            return\n        self.__receiving = 0\n        Py_DECREF(self)\n\n    cdef _new_socket(self):\n        if self._family not in (uv.AF_INET, uv.AF_INET6, uv.AF_UNIX):\n            raise RuntimeError(\n                'UDPTransport.family is undefined; '\n                'cannot create python socket')\n\n        fileno = self._fileno()\n        return PseudoSocket(self._family, uv.SOCK_DGRAM, 0, fileno)\n\n    cdef _send(self, object data, object addr):\n        cdef:\n            _UDPSendContext ctx\n            system.sockaddr_storage saddr_st\n            system.sockaddr *saddr\n            Py_buffer       try_pybuf\n            uv.uv_buf_t     try_uvbuf\n\n        self._ensure_alive()\n\n        if self._family not in (uv.AF_INET, uv.AF_INET6, uv.AF_UNIX):\n            raise RuntimeError('UDPTransport.family is undefined; cannot send')\n\n        if addr is None:\n            saddr = NULL\n        else:\n            # resolve special hostname <broadcast> to the broadcast address before use\n            if self._family == uv.AF_INET and addr[0] == '<broadcast>':\n                addr = (b'255.255.255.255', addr[1])\n\n            try:\n                __convert_pyaddr_to_sockaddr(self._family, addr,\n                                             <system.sockaddr*>&saddr_st)\n            except (ValueError, TypeError):\n                raise\n            except Exception:\n                raise ValueError(\n                    f'{addr!r}: socket family mismatch or '\n                    f'a DNS lookup is required')\n            saddr = <system.sockaddr*>(&saddr_st)\n\n        if self._get_write_buffer_size() == 0:\n            PyObject_GetBuffer(data, &try_pybuf, PyBUF_SIMPLE)\n            try_uvbuf.base = <char*>try_pybuf.buf\n            try_uvbuf.len = try_pybuf.len\n            err = uv.uv_udp_try_send(<uv.uv_udp_t*>self._handle,\n                                     &try_uvbuf,\n                                     1,\n                                     saddr)\n            PyBuffer_Release(&try_pybuf)\n        else:\n            err = uv.UV_EAGAIN\n\n        if err == uv.UV_EAGAIN:\n            ctx = _UDPSendContext.new(self, data)\n            err = uv.uv_udp_send(&ctx.req,\n                                 <uv.uv_udp_t*>self._handle,\n                                 &ctx.uv_buf,\n                                 1,\n                                 saddr,\n                                 __uv_udp_on_send)\n\n            if err < 0:\n                ctx.close()\n\n                exc = convert_error(err)\n                if isinstance(exc, OSError):\n                    run_in_context1(self.context.copy(), self._protocol.error_received, exc)\n                else:\n                    self._fatal_error(exc, True)\n            else:\n                self._maybe_pause_protocol()\n\n        else:\n            self._on_sent(convert_error(err) if err < 0 else None, self.context.copy())\n\n    cdef _on_receive(self, bytes data, object exc, object addr):\n        if exc is None:\n            run_in_context2(\n                self.context, self._protocol.datagram_received, data, addr,\n            )\n        else:\n            run_in_context1(self.context, self._protocol.error_received, exc)\n\n    cdef _on_sent(self, object exc, object context=None):\n        if exc is not None:\n            if isinstance(exc, OSError):\n                if context is None:\n                    context = self.context\n                run_in_context1(context, self._protocol.error_received, exc)\n            else:\n                self._fatal_error(\n                    exc, False, 'Fatal write error on datagram transport')\n\n        self._maybe_resume_protocol()\n        if not self._get_write_buffer_size():\n            if self._closing:\n                self._schedule_call_connection_lost(None)\n\n    # === Public API ===\n\n    def sendto(self, data, addr=None):\n        if not data:\n            # Replicating asyncio logic here.\n            return\n\n        if self._address:\n            if addr not in (None, self._address):\n                # Replicating asyncio logic here.\n                raise ValueError(\n                    'Invalid address: must be None or %s' % (self._address,))\n\n            # Instead of setting addr to self._address below like what asyncio\n            # does, we depend on previous uv_udp_connect() to set the address\n            addr = None\n\n        if self._conn_lost:\n            # Replicating asyncio logic here.\n            if self._conn_lost >= LOG_THRESHOLD_FOR_CONNLOST_WRITES:\n                aio_logger.warning('socket.send() raised exception.')\n            self._conn_lost += 1\n            return\n\n        self._send(data, addr)\n\n\ncdef void __uv_udp_on_receive(\n    uv.uv_udp_t* handle,\n    ssize_t nread,\n    const uv.uv_buf_t* buf,\n    const system.sockaddr* addr,\n    unsigned flags\n) noexcept with gil:\n\n    if __ensure_handle_data(<uv.uv_handle_t*>handle,\n                            \"UDPTransport receive callback\") == 0:\n        return\n\n    cdef:\n        UDPTransport udp = <UDPTransport>handle.data\n        Loop loop = udp._loop\n        bytes data\n        object pyaddr\n\n    # It's OK to free the buffer early, since nothing will\n    # be able to touch it until this method is done.\n    __loop_free_buffer(loop)\n\n    if udp._closed:\n        # The handle was closed, there is no reason to\n        # do any work now.\n        udp.__receiving_stopped()  # Just in case.\n        return\n\n    if addr is NULL and nread == 0:\n        # From libuv docs:\n        #      addr: struct sockaddr* containing the address\n        #      of the sender. Can be NULL. Valid for the duration\n        #      of the callback only.\n        #      [...]\n        #      The receive callback will be called with\n        #      nread == 0 and addr == NULL when there is\n        #      nothing to read, and with nread == 0 and\n        #      addr != NULL when an empty UDP packet is\n        #      received.\n        return\n\n    if addr is NULL:\n        pyaddr = None\n    elif addr.sa_family == uv.AF_UNSPEC:\n        # https://github.com/MagicStack/uvloop/issues/304\n        if system.PLATFORM_IS_LINUX:\n            pyaddr = None\n        else:\n            pyaddr = ''\n    else:\n        try:\n            pyaddr = __convert_sockaddr_to_pyaddr(addr)\n        except BaseException as exc:\n            udp._error(exc, False)\n            return\n\n    if nread < 0:\n        exc = convert_error(nread)\n        udp._on_receive(None, exc, pyaddr)\n        return\n\n    if nread == 0:\n        data = b''\n    else:\n        data = loop._recv_buffer[:nread]\n\n    try:\n        udp._on_receive(data, None, pyaddr)\n    except BaseException as exc:\n        udp._error(exc, False)\n\n\ncdef void __uv_udp_on_send(\n    uv.uv_udp_send_t* req,\n    int status,\n) noexcept with gil:\n\n    if req.data is NULL:\n        # Shouldn't happen as:\n        #    - _UDPSendContext does an extra INCREF in its 'init()'\n        #    - _UDPSendContext holds a ref to the relevant UDPTransport\n        aio_logger.error(\n            'UVStream.write callback called with NULL req.data, status=%r',\n            status)\n        return\n\n    cdef:\n        _UDPSendContext ctx = <_UDPSendContext> req.data\n        UDPTransport udp = <UDPTransport>ctx.udp\n\n    ctx.close()\n\n    if status < 0:\n        exc = convert_error(status)\n        print(exc)\n    else:\n        exc = None\n\n    try:\n        udp._on_sent(exc)\n    except BaseException as exc:\n        udp._error(exc, False)\n"
  },
  {
    "path": "uvloop/includes/__init__.py",
    "content": "# flake8: noqa\n\n# These have to be synced with the stdlib.pxi\nimport asyncio\nimport collections\nimport concurrent.futures\nimport errno\nimport functools\nimport gc\nimport inspect\nimport itertools\nimport os\nimport signal\nimport socket\nimport subprocess\nimport ssl\nimport stat\nimport sys\nimport threading\nimport traceback\nimport time\nimport warnings\nimport weakref\n"
  },
  {
    "path": "uvloop/includes/compat.h",
    "content": "#include <errno.h>\n#include <stddef.h>\n#include <signal.h>\n#include <sys/socket.h>\n#include <sys/un.h>\n#include \"Python.h\"\n#include \"uv.h\"\n\n\n#ifndef EWOULDBLOCK\n#define EWOULDBLOCK EAGAIN\n#endif\n\n#ifdef __APPLE__\n#define PLATFORM_IS_APPLE 1\n#else\n#define PLATFORM_IS_APPLE 0\n#endif\n\n\n#ifdef __linux__\n#  define PLATFORM_IS_LINUX 1\n#  include <sys/epoll.h>\n#else\n#  define PLATFORM_IS_LINUX 0\n#  define EPOLL_CTL_DEL 2\nstruct epoll_event {};\nint epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) {\n    return 0;\n};\n#endif\n\n\nPyObject *\nMakeUnixSockPyAddr(struct sockaddr_un *addr)\n{\n    if (addr->sun_family != AF_UNIX) {\n        PyErr_SetString(\n            PyExc_ValueError, \"a UNIX socket addr was expected\");\n        return NULL;\n    }\n\n#ifdef __linux__\n    int addrlen = sizeof (struct sockaddr_un);\n    size_t linuxaddrlen = addrlen - offsetof(struct sockaddr_un, sun_path);\n    if (linuxaddrlen > 0 && addr->sun_path[0] == 0) {\n        return PyBytes_FromStringAndSize(addr->sun_path, linuxaddrlen);\n    }\n    else\n#endif /* linux */\n    {\n        /* regular NULL-terminated string */\n        return PyUnicode_DecodeFSDefault(addr->sun_path);\n    }\n}\n\n\n#if PY_VERSION_HEX < 0x03070100\n\nPyObject * Context_CopyCurrent(void) {\n    return (PyObject *)PyContext_CopyCurrent();\n};\n\nint Context_Enter(PyObject *ctx) {\n    return PyContext_Enter((PyContext *)ctx);\n}\n\nint Context_Exit(PyObject *ctx) {\n    return PyContext_Exit((PyContext *)ctx);\n}\n\n#else\n\nPyObject * Context_CopyCurrent(void) {\n    return PyContext_CopyCurrent();\n};\n\nint Context_Enter(PyObject *ctx) {\n    return PyContext_Enter(ctx);\n}\n\nint Context_Exit(PyObject *ctx) {\n    return PyContext_Exit(ctx);\n}\n\n#endif\n\n/* inlined from cpython/Modules/signalmodule.c\n * https://github.com/python/cpython/blob/v3.13.0a6/Modules/signalmodule.c#L1931-L1951\n * private _Py_RestoreSignals has been moved to CPython internals in Python 3.13\n * https://github.com/python/cpython/pull/106400 */\n\nvoid\n_Py_RestoreSignals(void)\n{\n#ifdef SIGPIPE\n    PyOS_setsig(SIGPIPE, SIG_DFL);\n#endif\n#ifdef SIGXFZ\n    PyOS_setsig(SIGXFZ, SIG_DFL);\n#endif\n#ifdef SIGXFSZ\n    PyOS_setsig(SIGXFSZ, SIG_DFL);\n#endif\n}\n"
  },
  {
    "path": "uvloop/includes/consts.pxi",
    "content": "cdef enum:\n    UV_STREAM_RECV_BUF_SIZE = 256000  # 250kb\n\n    FLOW_CONTROL_HIGH_WATER = 64  # KiB\n    FLOW_CONTROL_HIGH_WATER_SSL_READ = 256  # KiB\n    FLOW_CONTROL_HIGH_WATER_SSL_WRITE = 512  # KiB\n\n    DEFAULT_FREELIST_SIZE = 250\n    DNS_PYADDR_TO_SOCKADDR_CACHE_SIZE = 2048\n\n    DEBUG_STACK_DEPTH = 10\n\n\n    __PROCESS_DEBUG_SLEEP_AFTER_FORK = 1\n\n\n    LOG_THRESHOLD_FOR_CONNLOST_WRITES = 5\n    SSL_READ_MAX_SIZE = 256 * 1024\n\n\ncdef extern from *:\n    '''\n    // Number of seconds to wait for SSL handshake to complete\n    // The default timeout matches that of Nginx.\n    #define SSL_HANDSHAKE_TIMEOUT 60.0\n\n    // Number of seconds to wait for SSL shutdown to complete\n    // The default timeout mimics lingering_time\n    #define SSL_SHUTDOWN_TIMEOUT 30.0\n    '''\n\n    const float SSL_HANDSHAKE_TIMEOUT\n    const float SSL_SHUTDOWN_TIMEOUT\n"
  },
  {
    "path": "uvloop/includes/debug.h",
    "content": "#ifndef UVLOOP_DEBUG\n#define UVLOOP_DEBUG 0\n#endif\n"
  },
  {
    "path": "uvloop/includes/debug.pxd",
    "content": "cdef extern from \"includes/debug.h\":\n\n    cdef int UVLOOP_DEBUG\n"
  },
  {
    "path": "uvloop/includes/flowcontrol.pxd",
    "content": "# flake8: noqa\n\n\ncdef inline add_flowcontrol_defaults(high, low, int kb):\n    cdef int h, l\n    if high is None:\n        if low is None:\n            h = kb * 1024\n        else:\n            l = low\n            h = 4 * l\n    else:\n        h = high\n    if low is None:\n        l = h // 4\n    else:\n        l = low\n\n    if not h >= l >= 0:\n        raise ValueError('high (%r) must be >= low (%r) must be >= 0' %\n                         (h, l))\n\n    return h, l\n"
  },
  {
    "path": "uvloop/includes/fork_handler.h",
    "content": "#ifndef UVLOOP_FORK_HANDLER_H_\n#define UVLOOP_FORK_HANDLER_H_\n\nvolatile uint64_t MAIN_THREAD_ID = 0;\nvolatile int8_t MAIN_THREAD_ID_SET = 0;\n\ntypedef void (*OnForkHandler)(void);\n\nOnForkHandler __forkHandler = NULL;\n\n/* Auxiliary function to call global fork handler if defined.\n\nNote: Fork handler needs to be in C (not cython) otherwise it would require\nGIL to be present, but some forks can exec non-python processes.\n*/\nvoid handleAtFork(void) {\n    // Reset the MAIN_THREAD_ID on fork, because the main thread ID is not\n    // always the same after fork, especially when forked from within a thread.\n    MAIN_THREAD_ID_SET = 0;\n\n    if (__forkHandler != NULL) {\n        __forkHandler();\n    }\n}\n\n\nvoid setForkHandler(OnForkHandler handler)\n{\n    __forkHandler = handler;\n}\n\n\nvoid resetForkHandler(void)\n{\n    __forkHandler = NULL;\n}\n\nvoid setMainThreadID(uint64_t id) {\n    MAIN_THREAD_ID = id;\n    MAIN_THREAD_ID_SET = 1;\n}\n#endif\n"
  },
  {
    "path": "uvloop/includes/python.pxd",
    "content": "cdef extern from \"Python.h\":\n    int PY_VERSION_HEX\n\n    unicode PyUnicode_FromString(const char *)\n\n    void* PyMem_RawMalloc(size_t n) nogil\n    void* PyMem_RawRealloc(void *p, size_t n) nogil\n    void* PyMem_RawCalloc(size_t nelem, size_t elsize) nogil\n    void PyMem_RawFree(void *p) nogil\n\n    object PyUnicode_EncodeFSDefault(object)\n    void PyErr_SetInterrupt() nogil\n\n    object PyMemoryView_FromMemory(char *mem, ssize_t size, int flags)\n    object PyMemoryView_FromObject(object obj)\n    int PyMemoryView_Check(object obj)\n\n    cdef enum:\n        PyBUF_WRITE\n\n\ncdef extern from \"includes/compat.h\":\n    object Context_CopyCurrent()\n    int Context_Enter(object) except -1\n    int Context_Exit(object) except -1\n\n    void PyOS_BeforeFork()\n    void PyOS_AfterFork_Parent()\n    void PyOS_AfterFork_Child()\n\n    void _Py_RestoreSignals()\n"
  },
  {
    "path": "uvloop/includes/stdlib.pxi",
    "content": "# flake8: noqa\n\n\nimport asyncio, asyncio.log, asyncio.base_events, \\\n       asyncio.sslproto, asyncio.coroutines, \\\n       asyncio.futures, asyncio.transports\nimport collections.abc\nimport concurrent.futures\nimport errno\nimport functools\nimport gc\nimport inspect\nimport itertools\nimport os\nimport signal\nimport socket\nimport subprocess\nimport ssl\nimport stat\nimport sys\nimport threading\nimport traceback\nimport time\nimport warnings\nimport weakref\n\n\ncdef aio_get_event_loop = asyncio.get_event_loop\ncdef aio_CancelledError = asyncio.CancelledError\ncdef aio_InvalidStateError = asyncio.InvalidStateError\ncdef aio_TimeoutError = asyncio.TimeoutError\ncdef aio_Future = asyncio.Future\ncdef aio_Task = asyncio.Task\ncdef aio_ensure_future = asyncio.ensure_future\ncdef aio_gather = asyncio.gather\ncdef aio_wait = asyncio.wait\ncdef aio_wrap_future = asyncio.wrap_future\ncdef aio_logger = asyncio.log.logger\ncdef aio_iscoroutine = asyncio.iscoroutine\ncdef aio_BaseProtocol = asyncio.BaseProtocol\ncdef aio_Protocol = asyncio.Protocol\ncdef aio_isfuture = getattr(asyncio, 'isfuture', None)\ncdef aio_get_running_loop = getattr(asyncio, '_get_running_loop', None)\ncdef aio_set_running_loop = getattr(asyncio, '_set_running_loop', None)\ncdef aio_debug_wrapper = getattr(asyncio.coroutines, 'debug_wrapper', None)\ncdef aio_AbstractChildWatcher = getattr(asyncio, \"AbstractChildWatcher\", ())\ncdef aio_Transport = asyncio.Transport\ncdef aio_FlowControlMixin = asyncio.transports._FlowControlMixin\n\ncdef col_deque = collections.deque\ncdef col_Iterable = collections.abc.Iterable\ncdef col_Counter = collections.Counter\ncdef col_OrderedDict = collections.OrderedDict\n\ncdef cc_ThreadPoolExecutor = concurrent.futures.ThreadPoolExecutor\ncdef cc_Future = concurrent.futures.Future\n\ncdef errno_EBADF = errno.EBADF\ncdef errno_EINVAL = errno.EINVAL\n\ncdef ft_partial = functools.partial\n\ncdef gc_disable = gc.disable\n\ncdef iter_chain = itertools.chain\ncdef inspect_isgenerator = inspect.isgenerator\ncdef inspect_iscoroutinefunction = inspect.iscoroutinefunction\n\ncdef int has_IPV6_V6ONLY = hasattr(socket, 'IPV6_V6ONLY')\ncdef int IPV6_V6ONLY = getattr(socket, 'IPV6_V6ONLY', -1)\ncdef int has_SO_REUSEPORT = hasattr(socket, 'SO_REUSEPORT')\ncdef int SO_REUSEPORT = getattr(socket, 'SO_REUSEPORT', 0)\ncdef int SO_BROADCAST = getattr(socket, 'SO_BROADCAST')\ncdef int SOCK_NONBLOCK = getattr(socket, 'SOCK_NONBLOCK', -1)\ncdef int socket_AI_CANONNAME = getattr(socket, 'AI_CANONNAME')\n\ncdef socket_gaierror = socket.gaierror\ncdef socket_error = socket.error\ncdef socket_timeout = socket.timeout\ncdef socket_socket = socket.socket\ncdef socket_socketpair = socket.socketpair\ncdef socket_getservbyname = socket.getservbyname\ncdef socket_AddressFamily = socket.AddressFamily\ncdef socket_SocketKind = socket.SocketKind\n\ncdef int socket_EAI_ADDRFAMILY = getattr(socket, 'EAI_ADDRFAMILY', -1)\ncdef int socket_EAI_AGAIN      = getattr(socket, 'EAI_AGAIN', -1)\ncdef int socket_EAI_BADFLAGS   = getattr(socket, 'EAI_BADFLAGS', -1)\ncdef int socket_EAI_BADHINTS   = getattr(socket, 'EAI_BADHINTS', -1)\ncdef int socket_EAI_CANCELED   = getattr(socket, 'EAI_CANCELED', -1)\ncdef int socket_EAI_FAIL       = getattr(socket, 'EAI_FAIL', -1)\ncdef int socket_EAI_FAMILY     = getattr(socket, 'EAI_FAMILY', -1)\ncdef int socket_EAI_MEMORY     = getattr(socket, 'EAI_MEMORY', -1)\ncdef int socket_EAI_NODATA     = getattr(socket, 'EAI_NODATA', -1)\ncdef int socket_EAI_NONAME     = getattr(socket, 'EAI_NONAME', -1)\ncdef int socket_EAI_OVERFLOW   = getattr(socket, 'EAI_OVERFLOW', -1)\ncdef int socket_EAI_PROTOCOL   = getattr(socket, 'EAI_PROTOCOL', -1)\ncdef int socket_EAI_SERVICE    = getattr(socket, 'EAI_SERVICE', -1)\ncdef int socket_EAI_SOCKTYPE   = getattr(socket, 'EAI_SOCKTYPE', -1)\n\n\ncdef str os_name = os.name\ncdef os_environ = os.environ\ncdef os_dup = os.dup\ncdef os_set_inheritable = os.set_inheritable\ncdef os_get_inheritable = os.get_inheritable\ncdef os_close = os.close\ncdef os_open = os.open\ncdef os_devnull = os.devnull\ncdef os_O_RDWR = os.O_RDWR\ncdef os_pipe = os.pipe\ncdef os_read = os.read\ncdef os_remove = os.remove\ncdef os_stat = os.stat\ncdef os_unlink = os.unlink\ncdef os_fspath = os.fspath\n\ncdef stat_S_ISSOCK = stat.S_ISSOCK\n\ncdef sys_ignore_environment = sys.flags.ignore_environment\ncdef sys_dev_mode = sys.flags.dev_mode\ncdef sys_exc_info = sys.exc_info\ncdef sys_set_coroutine_wrapper = getattr(sys, 'set_coroutine_wrapper', None)\ncdef sys_get_coroutine_wrapper = getattr(sys, 'get_coroutine_wrapper', None)\ncdef sys_getframe = sys._getframe\ncdef sys_version_info = sys.version_info\ncdef sys_getfilesystemencoding = sys.getfilesystemencoding\ncdef str sys_platform = sys.platform\n\ncdef ssl_SSLContext = ssl.SSLContext\ncdef ssl_MemoryBIO = ssl.MemoryBIO\ncdef ssl_create_default_context = ssl.create_default_context\ncdef ssl_SSLError = ssl.SSLError\ncdef ssl_SSLAgainErrors = (ssl.SSLWantReadError, ssl.SSLSyscallError)\ncdef ssl_SSLZeroReturnError = ssl.SSLZeroReturnError\ncdef ssl_CertificateError = ssl.CertificateError\ncdef int ssl_SSL_ERROR_WANT_READ = ssl.SSL_ERROR_WANT_READ\ncdef int ssl_SSL_ERROR_WANT_WRITE = ssl.SSL_ERROR_WANT_WRITE\ncdef int ssl_SSL_ERROR_SYSCALL = ssl.SSL_ERROR_SYSCALL\n\ncdef threading_Thread = threading.Thread\ncdef threading_main_thread = threading.main_thread\n\ncdef int subprocess_PIPE = subprocess.PIPE\ncdef int subprocess_STDOUT = subprocess.STDOUT\ncdef int subprocess_DEVNULL = subprocess.DEVNULL\ncdef subprocess_SubprocessError = subprocess.SubprocessError\n\ncdef int signal_NSIG = signal.NSIG\ncdef signal_signal = signal.signal\ncdef signal_siginterrupt = signal.siginterrupt\ncdef signal_set_wakeup_fd = signal.set_wakeup_fd\ncdef signal_default_int_handler = signal.default_int_handler\ncdef signal_SIG_DFL = signal.SIG_DFL\n\ncdef time_sleep = time.sleep\ncdef time_monotonic = time.monotonic\n\ncdef tb_StackSummary = traceback.StackSummary\ncdef tb_walk_stack = traceback.walk_stack\ncdef tb_format_list = traceback.format_list\n\ncdef warnings_warn = warnings.warn\n\ncdef weakref_WeakValueDictionary = weakref.WeakValueDictionary\ncdef weakref_WeakSet = weakref.WeakSet\n\ncdef py_inf = float('inf')\n\n\n# Cython doesn't clean-up imported objects properly in Py3 mode,\n# so we delete refs to all modules manually (except sys)\ndel asyncio, concurrent, collections, errno\ndel functools, inspect, itertools, socket, os, threading\ndel signal, subprocess, ssl\ndel time, traceback, warnings, weakref\n"
  },
  {
    "path": "uvloop/includes/system.pxd",
    "content": "from libc.stdint cimport int8_t, uint64_t\n\ncdef extern from \"arpa/inet.h\" nogil:\n\n    int ntohl(int)\n    int htonl(int)\n    int ntohs(int)\n\n\ncdef extern from \"sys/socket.h\" nogil:\n\n    struct sockaddr:\n        unsigned short sa_family\n        char           sa_data[14]\n\n    struct addrinfo:\n        int            ai_flags\n        int            ai_family\n        int            ai_socktype\n        int            ai_protocol\n        size_t         ai_addrlen\n        sockaddr*      ai_addr\n        char*          ai_canonname\n        addrinfo*      ai_next\n\n    struct sockaddr_in:\n        unsigned short sin_family\n        unsigned short sin_port\n        # ...\n\n    struct sockaddr_in6:\n        unsigned short sin6_family\n        unsigned short sin6_port\n        unsigned long  sin6_flowinfo\n        # ...\n        unsigned long  sin6_scope_id\n\n    struct sockaddr_storage:\n        unsigned short ss_family\n        # ...\n\n    const char *gai_strerror(int errcode)\n\n    int socketpair(int domain, int type, int protocol, int socket_vector[2])\n\n    int setsockopt(int socket, int level, int option_name,\n                   const void *option_value, int option_len)\n\n\ncdef extern from \"sys/un.h\" nogil:\n\n    struct sockaddr_un:\n        unsigned short sun_family\n        char*          sun_path\n        # ...\n\n\ncdef extern from \"unistd.h\" nogil:\n\n    ssize_t write(int fd, const void *buf, size_t count)\n    void _exit(int status)\n\n\ncdef extern from \"pthread.h\":\n\n    int pthread_atfork(\n        void (*prepare)(),\n        void (*parent)(),\n        void (*child)())\n\n\ncdef extern from \"includes/compat.h\" nogil:\n\n    cdef int EWOULDBLOCK\n\n    cdef int PLATFORM_IS_APPLE\n    cdef int PLATFORM_IS_LINUX\n\n    struct epoll_event:\n        # We don't use the fields\n        pass\n\n    int EPOLL_CTL_DEL\n    int epoll_ctl(int epfd, int op, int fd, epoll_event *event)\n    object MakeUnixSockPyAddr(sockaddr_un *addr)\n\n\ncdef extern from \"includes/fork_handler.h\":\n\n    uint64_t MAIN_THREAD_ID\n    int8_t MAIN_THREAD_ID_SET\n    ctypedef void (*OnForkHandler)()\n    void handleAtFork()\n    void setForkHandler(OnForkHandler handler)\n    void resetForkHandler()\n    void setMainThreadID(uint64_t id)\n\n\ncdef extern from * nogil:\n    uint64_t __atomic_fetch_add(uint64_t *ptr, uint64_t val, int memorder)\n    uint64_t __atomic_fetch_sub(uint64_t *ptr, uint64_t val, int memorder)\n\n    cdef enum:\n        __ATOMIC_RELAXED\n"
  },
  {
    "path": "uvloop/includes/uv.pxd",
    "content": "from libc.stdint cimport uint16_t, uint32_t, uint64_t, int64_t\nfrom posix.types cimport gid_t, uid_t\nfrom posix.unistd cimport getuid\n\nfrom . cimport system\n\n# This is an internal enum UV_HANDLE_READABLE from uv-common.h, used only by\n# handles/pipe.pyx to temporarily workaround a libuv issue libuv/libuv#2058,\n# before there is a proper fix in libuv. In short, libuv disallowed feeding a\n# write-only pipe to uv_read_start(), which was needed by uvloop to detect a\n# broken pipe without having to send anything on the write-only end. We're\n# setting UV_HANDLE_READABLE on pipe_t to workaround this limitation\n# temporarily, please see also #317.\ncdef enum:\n    UV_INTERNAL_HANDLE_READABLE = 0x00004000\n\ncdef extern from \"uv.h\" nogil:\n    cdef int UV_TCP_IPV6ONLY\n\n    cdef int UV_EACCES\n    cdef int UV_EAGAIN\n    cdef int UV_EALREADY\n    cdef int UV_EBUSY\n    cdef int UV_ECONNABORTED\n    cdef int UV_ECONNREFUSED\n    cdef int UV_ECONNRESET\n    cdef int UV_ECANCELED\n    cdef int UV_EEXIST\n    cdef int UV_EINTR\n    cdef int UV_EINVAL\n    cdef int UV_EISDIR\n    cdef int UV_ENOENT\n    cdef int UV_EOF\n    cdef int UV_EPERM\n    cdef int UV_EPIPE\n    cdef int UV_ESHUTDOWN\n    cdef int UV_ESRCH\n    cdef int UV_ETIMEDOUT\n    cdef int UV_EBADF\n    cdef int UV_ENOBUFS\n\n    cdef int UV_EAI_ADDRFAMILY\n    cdef int UV_EAI_AGAIN\n    cdef int UV_EAI_BADFLAGS\n    cdef int UV_EAI_BADHINTS\n    cdef int UV_EAI_CANCELED\n    cdef int UV_EAI_FAIL\n    cdef int UV_EAI_FAMILY\n    cdef int UV_EAI_MEMORY\n    cdef int UV_EAI_NODATA\n    cdef int UV_EAI_NONAME\n    cdef int UV_EAI_OVERFLOW\n    cdef int UV_EAI_PROTOCOL\n    cdef int UV_EAI_SERVICE\n    cdef int UV_EAI_SOCKTYPE\n\n    cdef int SOL_SOCKET\n    cdef int SO_ERROR\n    cdef int SO_REUSEADDR\n    # use has_SO_REUSEPORT and SO_REUSEPORT in stdlib.pxi instead\n    cdef int AF_INET\n    cdef int AF_INET6\n    cdef int AF_UNIX\n    cdef int AF_UNSPEC\n    cdef int AI_PASSIVE\n    cdef int AI_NUMERICHOST\n    cdef int INET6_ADDRSTRLEN\n    cdef int IPPROTO_IPV6\n    cdef int SOCK_STREAM\n    cdef int SOCK_DGRAM\n    cdef int IPPROTO_TCP\n    cdef int IPPROTO_UDP\n\n    cdef int SIGINT\n    cdef int SIGHUP\n    cdef int SIGCHLD\n    cdef int SIGKILL\n    cdef int SIGTERM\n\n    ctypedef int uv_os_sock_t\n    ctypedef int uv_file\n    ctypedef int uv_os_fd_t\n\n    ctypedef struct uv_buf_t:\n        char* base\n        size_t len\n\n    ctypedef struct uv_loop_t:\n        void* data\n        # ...\n\n    ctypedef struct uv_handle_t:\n        void* data\n        uv_loop_t* loop\n        unsigned int flags\n        # ...\n\n    ctypedef struct uv_idle_t:\n        void* data\n        uv_loop_t* loop\n        # ...\n\n    ctypedef struct uv_check_t:\n        void* data\n        uv_loop_t* loop\n        # ...\n\n    ctypedef struct uv_signal_t:\n        void* data\n        uv_loop_t* loop\n        # ...\n\n    ctypedef struct uv_async_t:\n        void* data\n        uv_loop_t* loop\n        # ...\n\n    ctypedef struct uv_timer_t:\n        void* data\n        uv_loop_t* loop\n        # ...\n\n    ctypedef struct uv_stream_t:\n        void* data\n        size_t write_queue_size\n        uv_loop_t* loop\n        # ...\n\n    ctypedef struct uv_tcp_t:\n        void* data\n        uv_loop_t* loop\n        # ...\n\n    ctypedef struct uv_pipe_t:\n        void* data\n        uv_loop_t* loop\n        # ...\n\n    ctypedef struct uv_udp_t:\n        void* data\n        uv_loop_t* loop\n        size_t send_queue_size\n        size_t send_queue_count\n        # ...\n\n    ctypedef struct uv_udp_send_t:\n        void* data\n        uv_udp_t* handle\n\n    ctypedef struct uv_poll_t:\n        void* data\n        uv_loop_t* loop\n        # ...\n\n    ctypedef struct uv_req_t:\n        # Only cancellation of uv_fs_t, uv_getaddrinfo_t,\n        # uv_getnameinfo_t and uv_work_t requests is\n        # currently supported.\n        void* data\n        uv_req_type type\n        # ...\n\n    ctypedef struct uv_connect_t:\n        void* data\n\n    ctypedef struct uv_getaddrinfo_t:\n        void* data\n        # ...\n\n    ctypedef struct uv_getnameinfo_t:\n        void* data\n        # ...\n\n    ctypedef struct uv_write_t:\n        void* data\n        # ...\n\n    ctypedef struct uv_shutdown_t:\n        void* data\n        # ...\n\n    ctypedef struct uv_process_t:\n        void* data\n        int pid\n        # ...\n\n    ctypedef struct uv_fs_event_t:\n        void* data\n        # ...\n\n    ctypedef enum uv_req_type:\n        UV_UNKNOWN_REQ = 0,\n        UV_REQ,\n        UV_CONNECT,\n        UV_WRITE,\n        UV_SHUTDOWN,\n        UV_UDP_SEND,\n        UV_FS,\n        UV_WORK,\n        UV_GETADDRINFO,\n        UV_GETNAMEINFO,\n        UV_REQ_TYPE_PRIVATE,\n        UV_REQ_TYPE_MAX\n\n    ctypedef enum uv_run_mode:\n        UV_RUN_DEFAULT = 0,\n        UV_RUN_ONCE,\n        UV_RUN_NOWAIT\n\n    ctypedef enum uv_poll_event:\n        UV_READABLE = 1,\n        UV_WRITABLE = 2,\n        UV_DISCONNECT = 4\n\n    ctypedef enum uv_udp_flags:\n        UV_UDP_IPV6ONLY = 1,\n        UV_UDP_PARTIAL = 2\n\n    ctypedef enum uv_membership:\n        UV_LEAVE_GROUP = 0,\n        UV_JOIN_GROUP\n\n    cdef enum uv_fs_event:\n        UV_RENAME = 1,\n        UV_CHANGE = 2\n\n    const char* uv_strerror(int err)\n    const char* uv_err_name(int err)\n\n    ctypedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg) with gil\n\n    ctypedef void (*uv_close_cb)(uv_handle_t* handle) with gil\n    ctypedef void (*uv_idle_cb)(uv_idle_t* handle) with gil\n    ctypedef void (*uv_check_cb)(uv_check_t* handle) with gil\n    ctypedef void (*uv_signal_cb)(uv_signal_t* handle, int signum) with gil\n    ctypedef void (*uv_async_cb)(uv_async_t* handle) with gil\n    ctypedef void (*uv_timer_cb)(uv_timer_t* handle) with gil\n    ctypedef void (*uv_connection_cb)(uv_stream_t* server, int status) with gil\n    ctypedef void (*uv_alloc_cb)(uv_handle_t* handle,\n                                 size_t suggested_size,\n                                 uv_buf_t* buf) with gil\n    ctypedef void (*uv_read_cb)(uv_stream_t* stream,\n                                ssize_t nread,\n                                const uv_buf_t* buf) with gil\n    ctypedef void (*uv_write_cb)(uv_write_t* req, int status) with gil\n    ctypedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req,\n                                       int status,\n                                       system.addrinfo* res) with gil\n    ctypedef void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req,\n                                       int status,\n                                       const char* hostname,\n                                       const char* service) with gil\n    ctypedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status) with gil\n    ctypedef void (*uv_poll_cb)(uv_poll_t* handle,\n                                int status, int events) with gil\n\n    ctypedef void (*uv_connect_cb)(uv_connect_t* req, int status) with gil\n\n    ctypedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status) with gil\n    ctypedef void (*uv_udp_recv_cb)(uv_udp_t* handle,\n                                    ssize_t nread,\n                                    const uv_buf_t* buf,\n                                    const system.sockaddr* addr,\n                                    unsigned flags) with gil\n    ctypedef void (*uv_fs_event_cb)(uv_fs_event_t* handle,\n                                    const char *filename,\n                                    int events,\n                                    int status) with gil\n\n    # Generic request functions\n    int uv_cancel(uv_req_t* req)\n\n    # Generic handler functions\n    int uv_is_active(const uv_handle_t* handle)\n    void uv_close(uv_handle_t* handle, uv_close_cb close_cb)\n    int uv_is_closing(const uv_handle_t* handle)\n    int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd)\n    void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg)\n\n    # Loop functions\n    int uv_loop_init(uv_loop_t* loop)\n    int uv_loop_close(uv_loop_t* loop)\n    int uv_loop_alive(uv_loop_t* loop)\n    int uv_loop_fork(uv_loop_t* loop)\n    uv_os_fd_t uv_backend_fd(uv_loop_t* loop)\n\n    void uv_update_time(uv_loop_t* loop)\n    uint64_t uv_now(const uv_loop_t*)\n\n    int uv_run(uv_loop_t*, uv_run_mode mode) nogil\n    void uv_stop(uv_loop_t*)\n\n    # Idle handler\n    int uv_idle_init(uv_loop_t*, uv_idle_t* idle)\n    int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb)\n    int uv_idle_stop(uv_idle_t* idle)\n\n    # Check handler\n    int uv_check_init(uv_loop_t*, uv_check_t* idle)\n    int uv_check_start(uv_check_t* check, uv_check_cb cb)\n    int uv_check_stop(uv_check_t* check)\n\n    # Signal handler\n    int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle)\n    int uv_signal_start(uv_signal_t* handle,\n                        uv_signal_cb signal_cb,\n                        int signum)\n    int uv_signal_stop(uv_signal_t* handle)\n\n    # Async handler\n    int uv_async_init(uv_loop_t*,\n                      uv_async_t* async_,\n                      uv_async_cb async_cb)\n    int uv_async_send(uv_async_t* async_)\n\n    # Timer handler\n    int uv_timer_init(uv_loop_t*, uv_timer_t* handle)\n    int uv_timer_start(uv_timer_t* handle,\n                       uv_timer_cb cb,\n                       uint64_t timeout,\n                       uint64_t repeat)\n    int uv_timer_stop(uv_timer_t* handle)\n\n    # DNS\n    int uv_getaddrinfo(uv_loop_t* loop,\n                       uv_getaddrinfo_t* req,\n                       uv_getaddrinfo_cb getaddrinfo_cb,\n                       const char* node,\n                       const char* service,\n                       const system.addrinfo* hints)\n\n    void uv_freeaddrinfo(system.addrinfo* ai)\n\n    int uv_getnameinfo(uv_loop_t* loop,\n                       uv_getnameinfo_t* req,\n                       uv_getnameinfo_cb getnameinfo_cb,\n                       const system.sockaddr* addr,\n                       int flags)\n\n    int uv_ip4_name(const system.sockaddr_in* src, char* dst, size_t size)\n    int uv_ip6_name(const system.sockaddr_in6* src, char* dst, size_t size)\n\n    # Streams\n\n    int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb)\n    int uv_accept(uv_stream_t* server, uv_stream_t* client)\n    int uv_read_start(uv_stream_t* stream,\n                      uv_alloc_cb alloc_cb,\n                      uv_read_cb read_cb)\n    int uv_read_stop(uv_stream_t*)\n    int uv_write(uv_write_t* req, uv_stream_t* handle,\n                 uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb)\n\n    int uv_try_write(uv_stream_t* handle, uv_buf_t bufs[], unsigned int nbufs)\n\n    int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb)\n\n    int uv_is_readable(const uv_stream_t* handle)\n    int uv_is_writable(const uv_stream_t* handle)\n\n    # TCP\n\n    int uv_tcp_init_ex(uv_loop_t*, uv_tcp_t* handle, unsigned int flags)\n    int uv_tcp_nodelay(uv_tcp_t* handle, int enable)\n    int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay)\n    int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock)\n    int uv_tcp_bind(uv_tcp_t* handle, system.sockaddr* addr,\n                    unsigned int flags)\n\n    int uv_tcp_getsockname(const uv_tcp_t* handle, system.sockaddr* name,\n                           int* namelen)\n    int uv_tcp_getpeername(const uv_tcp_t* handle, system.sockaddr* name,\n                           int* namelen)\n\n    int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,\n                       const system.sockaddr* addr, uv_connect_cb cb)\n\n    # Pipes\n\n    int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc)\n    int uv_pipe_open(uv_pipe_t* handle, uv_os_fd_t file)\n    int uv_pipe_bind(uv_pipe_t* handle, const char* name)\n\n    void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,\n                         const char* name, uv_connect_cb cb)\n\n    # UDP\n\n    int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags)\n    int uv_udp_connect(uv_udp_t* handle, const system.sockaddr* addr)\n    int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock)\n    int uv_udp_bind(uv_udp_t* handle, const system.sockaddr* addr,\n                    unsigned int flags)\n    int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle,\n                    const uv_buf_t bufs[], unsigned int nbufs,\n                    const system.sockaddr* addr, uv_udp_send_cb send_cb)\n    int uv_udp_try_send(uv_udp_t* handle,\n                        const uv_buf_t bufs[], unsigned int nbufs,\n                        const system.sockaddr* addr)\n    int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,\n                          uv_udp_recv_cb recv_cb)\n    int uv_udp_recv_stop(uv_udp_t* handle)\n    int uv_udp_set_broadcast(uv_udp_t* handle, int on)\n\n    # Polling\n\n    int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd)\n    int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,\n                            uv_os_sock_t socket)\n    int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb)\n    int uv_poll_stop(uv_poll_t* poll)\n\n    # FS Event\n\n    int uv_fs_event_init(uv_loop_t *loop, uv_fs_event_t *handle)\n    int uv_fs_event_start(uv_fs_event_t *handle, uv_fs_event_cb cb,\n                          const char *path, unsigned int flags)\n    int uv_fs_event_stop(uv_fs_event_t *handle)\n\n    # Misc\n\n    ctypedef struct uv_timeval_t:\n        long tv_sec\n        long tv_usec\n\n    ctypedef struct uv_rusage_t:\n        uv_timeval_t ru_utime   # user CPU time used\n        uv_timeval_t ru_stime   # system CPU time used\n        uint64_t ru_maxrss      # maximum resident set size\n        uint64_t ru_ixrss       # integral shared memory size\n        uint64_t ru_idrss       # integral unshared data size\n        uint64_t ru_isrss       # integral unshared stack size\n        uint64_t ru_minflt      # page reclaims (soft page faults)\n        uint64_t ru_majflt      # page faults (hard page faults)\n        uint64_t ru_nswap       # swaps\n        uint64_t ru_inblock     # block input operations\n        uint64_t ru_oublock     # block output operations\n        uint64_t ru_msgsnd      # IPC messages sent\n        uint64_t ru_msgrcv      # IPC messages received\n        uint64_t ru_nsignals    # signals received\n        uint64_t ru_nvcsw       # voluntary context switches\n        uint64_t ru_nivcsw      # involuntary context switches\n\n    int uv_getrusage(uv_rusage_t* rusage)\n\n    int uv_ip4_addr(const char* ip, int port, system.sockaddr_in* addr)\n    int uv_ip6_addr(const char* ip, int port, system.sockaddr_in6* addr)\n\n    # Memory Allocation\n\n    ctypedef void* (*uv_malloc_func)(size_t size)\n    ctypedef void* (*uv_realloc_func)(void* ptr, size_t size)\n    ctypedef void* (*uv_calloc_func)(size_t count, size_t size)\n    ctypedef void (*uv_free_func)(void* ptr)\n\n    int uv_replace_allocator(uv_malloc_func malloc_func,\n                             uv_realloc_func realloc_func,\n                             uv_calloc_func calloc_func,\n                             uv_free_func free_func)\n\n    # Process\n\n    ctypedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status,\n                                int term_signal) with gil\n\n    ctypedef enum uv_process_flags:\n        UV_PROCESS_SETUID = 1,\n        UV_PROCESS_SETGID = 2,\n        UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = 4,\n        UV_PROCESS_DETACHED = 8,\n        UV_PROCESS_WINDOWS_HIDE = 16\n\n    ctypedef enum uv_stdio_flags:\n        UV_IGNORE = 0x00,\n        UV_CREATE_PIPE = 0x01,\n        UV_INHERIT_FD = 0x02,\n        UV_INHERIT_STREAM = 0x04,\n        UV_READABLE_PIPE = 0x10,\n        UV_WRITABLE_PIPE = 0x20\n\n    ctypedef union uv_stdio_container_data_u:\n        uv_stream_t* stream\n        int fd\n\n    ctypedef struct uv_stdio_container_t:\n        uv_stdio_flags flags\n        uv_stdio_container_data_u data\n\n    ctypedef struct uv_process_options_t:\n        uv_exit_cb exit_cb\n        char* file\n        char** args\n        char** env\n        char* cwd\n        unsigned int flags\n        int stdio_count\n        uv_stdio_container_t* stdio\n        uid_t uid\n        gid_t gid\n\n    int uv_spawn(uv_loop_t* loop, uv_process_t* handle,\n                 const uv_process_options_t* options)\n\n    int uv_process_kill(uv_process_t* handle, int signum)\n\n    unsigned int uv_version()\n"
  },
  {
    "path": "uvloop/loop.pxd",
    "content": "# cython: language_level=3\n\n\nfrom .includes cimport uv\nfrom .includes cimport system\n\nfrom libc.stdint cimport uint64_t, uint32_t, int64_t\n\n\ninclude \"includes/consts.pxi\"\n\n\ncdef extern from *:\n    ctypedef int vint \"volatile int\"\n\n\ncdef class UVHandle\ncdef class UVSocketHandle(UVHandle)\n\ncdef class UVAsync(UVHandle)\ncdef class UVTimer(UVHandle)\ncdef class UVIdle(UVHandle)\n\ncdef class UVBaseTransport(UVSocketHandle)\n\nctypedef object (*method_t)(object)\nctypedef object (*method1_t)(object, object)\nctypedef object (*method2_t)(object, object, object)\nctypedef object (*method3_t)(object, object, object, object)\n\n\ncdef class Loop:\n    cdef:\n        uv.uv_loop_t *uvloop\n\n        bint _coroutine_debug_set\n        int _coroutine_origin_tracking_saved_depth\n\n        public slow_callback_duration\n\n        readonly bint _closed\n        bint _debug\n        bint _running\n        bint _stopping\n\n        uint64_t _thread_id\n\n        object _task_factory\n        object _exception_handler\n        object _default_executor\n        object _ready\n        set _queued_streams, _executing_streams\n\n        set _servers\n\n        object _transports\n        set _processes\n        dict _fd_to_reader_fileobj\n        dict _fd_to_writer_fileobj\n        dict _unix_server_sockets\n\n        set _signals\n        dict _signal_handlers\n        object _ssock\n        object _csock\n        bint _listening_signals\n        int _old_signal_wakeup_id\n\n        set _timers\n        dict _polls\n\n        UVProcess active_process_handler\n\n        UVAsync handler_async\n        UVIdle handler_idle\n        UVCheck handler_check__exec_writes\n\n        object _last_error\n\n        cdef object __weakref__\n\n        object _asyncgens\n        bint _asyncgens_shutdown_called\n\n        bint _executor_shutdown_called\n\n        char _recv_buffer[UV_STREAM_RECV_BUF_SIZE]\n        bint _recv_buffer_in_use\n\n        # DEBUG fields\n        # True when compiled with DEBUG.\n        # Used only in unittests.\n        readonly bint _debug_cc\n\n        readonly object _debug_handles_total\n        readonly object _debug_handles_closed\n        readonly object _debug_handles_current\n\n        readonly uint64_t _debug_uv_handles_total\n        readonly uint64_t _debug_uv_handles_freed\n\n        readonly uint64_t _debug_cb_handles_total\n        readonly uint64_t _debug_cb_handles_count\n        readonly uint64_t _debug_cb_timer_handles_total\n        readonly uint64_t _debug_cb_timer_handles_count\n\n        readonly uint64_t _debug_stream_shutdown_errors_total\n        readonly uint64_t _debug_stream_listen_errors_total\n\n        readonly uint64_t _debug_stream_read_cb_total\n        readonly uint64_t _debug_stream_read_cb_errors_total\n        readonly uint64_t _debug_stream_read_eof_total\n        readonly uint64_t _debug_stream_read_eof_cb_errors_total\n        readonly uint64_t _debug_stream_read_errors_total\n\n        readonly uint64_t _debug_stream_write_tries\n        readonly uint64_t _debug_stream_write_errors_total\n        readonly uint64_t _debug_stream_write_ctx_total\n        readonly uint64_t _debug_stream_write_ctx_cnt\n        readonly uint64_t _debug_stream_write_cb_errors_total\n\n        readonly uint64_t _poll_read_events_total\n        readonly uint64_t _poll_read_cb_errors_total\n        readonly uint64_t _poll_write_events_total\n        readonly uint64_t _poll_write_cb_errors_total\n\n        readonly uint64_t _sock_try_write_total\n\n        readonly uint64_t _debug_exception_handler_cnt\n\n    cdef _init_debug_fields(self)\n\n    cdef _on_wake(self)\n    cdef _on_idle(self)\n\n    cdef __run(self, uv.uv_run_mode)\n    cdef _run(self, uv.uv_run_mode)\n\n    cdef _close(self)\n    cdef _stop(self, exc)\n    cdef uint64_t _time(self)\n\n    cdef inline _queue_write(self, UVStream stream)\n    cdef _exec_queued_writes(self)\n\n    cdef inline _call_soon(self, object callback, object args, object context)\n    cdef inline _append_ready_handle(self, Handle handle)\n    cdef inline _call_soon_handle(self, Handle handle)\n\n    cdef _call_later(self, uint64_t delay, object callback, object args,\n                     object context)\n\n    cdef void _handle_exception(self, object ex)\n\n    cdef inline _is_main_thread(self)\n\n    cdef inline _new_future(self)\n    cdef inline _check_signal(self, sig)\n    cdef inline _check_closed(self)\n    cdef inline _check_thread(self)\n\n    cdef _getaddrinfo(self, object host, object port,\n                      int family, int type,\n                      int proto, int flags,\n                      int unpack)\n\n    cdef _getnameinfo(self, system.sockaddr *addr, int flags)\n\n    cdef _track_transport(self, UVBaseTransport transport)\n    cdef _fileobj_to_fd(self, fileobj)\n    cdef _ensure_fd_no_transport(self, fd)\n\n    cdef _track_process(self, UVProcess proc)\n    cdef _untrack_process(self, UVProcess proc)\n\n    cdef _add_reader(self, fd, Handle handle)\n    cdef _has_reader(self, fd)\n    cdef _remove_reader(self, fd)\n\n    cdef _add_writer(self, fd, Handle handle)\n    cdef _has_writer(self, fd)\n    cdef _remove_writer(self, fd)\n\n    cdef _sock_recv(self, fut, sock, n)\n    cdef _sock_recv_into(self, fut, sock, buf)\n    cdef _sock_sendall(self, fut, sock, data)\n    cdef _sock_accept(self, fut, sock)\n\n    cdef _sock_connect(self, sock, address)\n    cdef _sock_connect_cb(self, fut, sock, address)\n\n    cdef _sock_set_reuseport(self, int fd)\n\n    cdef _setup_or_resume_signals(self)\n    cdef _shutdown_signals(self)\n    cdef _pause_signals(self)\n\n    cdef _handle_signal(self, sig)\n    cdef _read_from_self(self)\n    cdef inline _ceval_process_signals(self)\n    cdef _invoke_signals(self, bytes data)\n\n    cdef _set_coroutine_debug(self, bint enabled)\n\n    cdef _print_debug_info(self)\n\n\ninclude \"cbhandles.pxd\"\n\ninclude \"handles/handle.pxd\"\ninclude \"handles/async_.pxd\"\ninclude \"handles/idle.pxd\"\ninclude \"handles/check.pxd\"\ninclude \"handles/timer.pxd\"\ninclude \"handles/poll.pxd\"\ninclude \"handles/basetransport.pxd\"\ninclude \"handles/stream.pxd\"\ninclude \"handles/streamserver.pxd\"\ninclude \"handles/tcp.pxd\"\ninclude \"handles/pipe.pxd\"\ninclude \"handles/process.pxd\"\ninclude \"handles/fsevent.pxd\"\n\ninclude \"request.pxd\"\ninclude \"sslproto.pxd\"\n\ninclude \"handles/udp.pxd\"\n\ninclude \"server.pxd\"\n"
  },
  {
    "path": "uvloop/loop.pyi",
    "content": "import asyncio\nimport ssl\nimport sys\nfrom socket import AddressFamily, SocketKind, _Address, _RetAddress, socket\nfrom typing import (\n    IO,\n    Any,\n    Awaitable,\n    Callable,\n    Dict,\n    Generator,\n    List,\n    Optional,\n    Sequence,\n    Tuple,\n    TypeVar,\n    Union,\n    overload,\n)\n\n_T = TypeVar('_T')\n_Context = Dict[str, Any]\n_ExceptionHandler = Callable[[asyncio.AbstractEventLoop, _Context], Any]\n_SSLContext = Union[bool, None, ssl.SSLContext]\n_ProtocolT = TypeVar(\"_ProtocolT\", bound=asyncio.BaseProtocol)\n\nclass Loop:\n    def call_soon(\n        self, callback: Callable[..., Any], *args: Any, context: Optional[Any] = ...\n    ) -> asyncio.Handle: ...\n    def call_soon_threadsafe(\n        self, callback: Callable[..., Any], *args: Any, context: Optional[Any] = ...\n    ) -> asyncio.Handle: ...\n    def call_later(\n        self, delay: float, callback: Callable[..., Any], *args: Any, context: Optional[Any] = ...\n    ) -> asyncio.TimerHandle: ...\n    def call_at(\n        self, when: float, callback: Callable[..., Any], *args: Any, context: Optional[Any] = ...\n    ) -> asyncio.TimerHandle: ...\n    def time(self) -> float: ...\n    def stop(self) -> None: ...\n    def run_forever(self) -> None: ...\n    def close(self) -> None: ...\n    def get_debug(self) -> bool: ...\n    def set_debug(self, enabled: bool) -> None: ...\n    def is_running(self) -> bool: ...\n    def is_closed(self) -> bool: ...\n    def create_future(self) -> asyncio.Future[Any]: ...\n    def create_task(\n        self,\n        coro: Union[Awaitable[_T], Generator[Any, None, _T]],\n        *,\n        name: Optional[str] = ...,\n    ) -> asyncio.Task[_T]: ...\n    def set_task_factory(\n        self,\n        factory: Optional[\n            Callable[[asyncio.AbstractEventLoop, Generator[Any, None, _T]], asyncio.Future[_T]]\n        ],\n    ) -> None: ...\n    def get_task_factory(\n        self,\n    ) -> Optional[\n        Callable[[asyncio.AbstractEventLoop, Generator[Any, None, _T]], asyncio.Future[_T]]\n    ]: ...\n    @overload\n    def run_until_complete(self, future: Generator[Any, None, _T]) -> _T: ...\n    @overload\n    def run_until_complete(self, future: Awaitable[_T]) -> _T: ...\n    async def getaddrinfo(\n        self,\n        host: Optional[Union[str, bytes]],\n        port: Optional[Union[str, bytes, int]],\n        *,\n        family: int = ...,\n        type: int = ...,\n        proto: int = ...,\n        flags: int = ...,\n    ) -> List[\n        Tuple[\n            AddressFamily,\n            SocketKind,\n            int,\n            str,\n            Union[Tuple[str, int], Tuple[str, int, int, int]],\n        ]\n    ]: ...\n    async def getnameinfo(\n        self,\n        sockaddr: Union[\n            Tuple[str, int],\n            Tuple[str, int, int],\n            Tuple[str, int, int, int]\n        ],\n        flags: int = ...,\n    ) -> Tuple[str, str]: ...\n    async def start_tls(\n        self,\n        transport: asyncio.BaseTransport,\n        protocol: asyncio.BaseProtocol,\n        sslcontext: ssl.SSLContext,\n        *,\n        server_side: bool = ...,\n        server_hostname: Optional[str] = ...,\n        ssl_handshake_timeout: Optional[float] = ...,\n        ssl_shutdown_timeout: Optional[float] = ...,\n    ) -> asyncio.BaseTransport: ...\n    @overload\n    async def create_server(\n        self,\n        protocol_factory: asyncio.events._ProtocolFactory,\n        host: Optional[Union[str, Sequence[str]]] = ...,\n        port: int = ...,\n        *,\n        family: int = ...,\n        flags: int = ...,\n        sock: None = ...,\n        backlog: int = ...,\n        ssl: _SSLContext = ...,\n        reuse_address: Optional[bool] = ...,\n        reuse_port: Optional[bool] = ...,\n        ssl_handshake_timeout: Optional[float] = ...,\n        ssl_shutdown_timeout: Optional[float] = ...,\n        start_serving: bool = ...,\n    ) -> asyncio.AbstractServer: ...\n    @overload\n    async def create_server(\n        self,\n        protocol_factory: asyncio.events._ProtocolFactory,\n        host: None = ...,\n        port: None = ...,\n        *,\n        family: int = ...,\n        flags: int = ...,\n        sock: socket = ...,\n        backlog: int = ...,\n        ssl: _SSLContext = ...,\n        reuse_address: Optional[bool] = ...,\n        reuse_port: Optional[bool] = ...,\n        ssl_handshake_timeout: Optional[float] = ...,\n        ssl_shutdown_timeout: Optional[float] = ...,\n        start_serving: bool = ...,\n    ) -> asyncio.AbstractServer: ...\n    @overload\n    async def create_connection(\n        self,\n        protocol_factory: Callable[[], _ProtocolT],\n        host: str = ...,\n        port: int = ...,\n        *,\n        ssl: _SSLContext = ...,\n        family: int = ...,\n        proto: int = ...,\n        flags: int = ...,\n        sock: None = ...,\n        local_addr: Optional[Tuple[str, int]] = ...,\n        server_hostname: Optional[str] = ...,\n        ssl_handshake_timeout: Optional[float] = ...,\n        ssl_shutdown_timeout: Optional[float] = ...,\n    ) -> tuple[asyncio.BaseProtocol, _ProtocolT]: ...\n    @overload\n    async def create_connection(\n        self,\n        protocol_factory: Callable[[], _ProtocolT],\n        host: None = ...,\n        port: None = ...,\n        *,\n        ssl: _SSLContext = ...,\n        family: int = ...,\n        proto: int = ...,\n        flags: int = ...,\n        sock: socket,\n        local_addr: None = ...,\n        server_hostname: Optional[str] = ...,\n        ssl_handshake_timeout: Optional[float] = ...,\n        ssl_shutdown_timeout: Optional[float] = ...,\n    ) -> tuple[asyncio.BaseProtocol, _ProtocolT]: ...\n    async def create_unix_server(\n        self,\n        protocol_factory: asyncio.events._ProtocolFactory,\n        path: Optional[str] = ...,\n        *,\n        backlog: int = ...,\n        sock: Optional[socket] = ...,\n        ssl: _SSLContext = ...,\n        ssl_handshake_timeout: Optional[float] = ...,\n        ssl_shutdown_timeout: Optional[float] = ...,\n        start_serving: bool = ...,\n    ) -> asyncio.AbstractServer: ...\n    async def create_unix_connection(\n        self,\n        protocol_factory: Callable[[], _ProtocolT],\n        path: Optional[str] = ...,\n        *,\n        ssl: _SSLContext = ...,\n        sock: Optional[socket] = ...,\n        server_hostname: Optional[str] = ...,\n        ssl_handshake_timeout: Optional[float] = ...,\n        ssl_shutdown_timeout: Optional[float] = ...,\n    ) -> tuple[asyncio.BaseProtocol, _ProtocolT]: ...\n    def default_exception_handler(self, context: _Context) -> None: ...\n    def get_exception_handler(self) -> Optional[_ExceptionHandler]: ...\n    def set_exception_handler(self, handler: Optional[_ExceptionHandler]) -> None: ...\n    def call_exception_handler(self, context: _Context) -> None: ...\n    def add_reader(self, fd: Any, callback: Callable[..., Any], *args: Any) -> None: ...\n    def remove_reader(self, fd: Any) -> None: ...\n    def add_writer(self, fd: Any, callback: Callable[..., Any], *args: Any) -> None: ...\n    def remove_writer(self, fd: Any) -> None: ...\n    async def sock_recv(self, sock: socket, nbytes: int) -> bytes: ...\n    async def sock_recv_into(self, sock: socket, buf: bytearray) -> int: ...\n    async def sock_sendall(self, sock: socket, data: bytes) -> None: ...\n    async def sock_accept(self, sock: socket) -> Tuple[socket, _RetAddress]: ...\n    async def sock_connect(self, sock: socket, address: _Address) -> None: ...\n    async def sock_recvfrom(self, sock: socket, bufsize: int) -> bytes: ...\n    async def sock_recvfrom_into(self, sock: socket, buf: bytearray, nbytes: int = ...) -> int: ...\n    async def sock_sendto(self, sock: socket, data: bytes, address: _Address) -> None: ...\n    async def connect_accepted_socket(\n        self,\n        protocol_factory: Callable[[], _ProtocolT],\n        sock: socket,\n        *,\n        ssl: _SSLContext = ...,\n        ssl_handshake_timeout: Optional[float] = ...,\n        ssl_shutdown_timeout: Optional[float] = ...,\n    ) -> tuple[asyncio.BaseProtocol, _ProtocolT]: ...\n    async def run_in_executor(\n        self, executor: Any, func: Callable[..., _T], *args: Any\n    ) -> _T: ...\n    def set_default_executor(self, executor: Any) -> None: ...\n    async def subprocess_shell(\n        self,\n        protocol_factory: Callable[[], _ProtocolT],\n        cmd: Union[bytes, str],\n        *,\n        stdin: Any = ...,\n        stdout: Any = ...,\n        stderr: Any = ...,\n        **kwargs: Any,\n    ) -> tuple[asyncio.BaseProtocol, _ProtocolT]: ...\n    async def subprocess_exec(\n        self,\n        protocol_factory: Callable[[], _ProtocolT],\n        *args: Any,\n        stdin: Any = ...,\n        stdout: Any = ...,\n        stderr: Any = ...,\n        **kwargs: Any,\n    ) -> tuple[asyncio.BaseProtocol, _ProtocolT]: ...\n    async def connect_read_pipe(\n        self, protocol_factory: Callable[[], _ProtocolT], pipe: Any\n    ) -> tuple[asyncio.BaseProtocol, _ProtocolT]: ...\n    async def connect_write_pipe(\n        self, protocol_factory: Callable[[], _ProtocolT], pipe: Any\n    ) -> tuple[asyncio.BaseProtocol, _ProtocolT]: ...\n    def add_signal_handler(\n        self, sig: int, callback: Callable[..., Any], *args: Any\n    ) -> None: ...\n    def remove_signal_handler(self, sig: int) -> bool: ...\n    async def create_datagram_endpoint(\n        self,\n        protocol_factory: Callable[[], _ProtocolT],\n        local_addr: Optional[Tuple[str, int]] = ...,\n        remote_addr: Optional[Tuple[str, int]] = ...,\n        *,\n        family: int = ...,\n        proto: int = ...,\n        flags: int = ...,\n        reuse_address: Optional[bool] = ...,\n        reuse_port: Optional[bool] = ...,\n        allow_broadcast: Optional[bool] = ...,\n        sock: Optional[socket] = ...,\n    ) -> tuple[asyncio.BaseProtocol, _ProtocolT]: ...\n    async def shutdown_asyncgens(self) -> None: ...\n    async def shutdown_default_executor(\n        self,\n        timeout: Optional[float] = ...,\n    ) -> None: ...\n    # Loop doesn't implement these, but since they are marked as abstract in typeshed,\n    # we have to put them in so mypy thinks the base methods are overridden\n    async def sendfile(\n        self,\n        transport: asyncio.BaseTransport,\n        file: IO[bytes],\n        offset: int = ...,\n        count: Optional[int] = ...,\n        *,\n        fallback: bool = ...,\n    ) -> int: ...\n    async def sock_sendfile(\n        self,\n        sock: socket,\n        file: IO[bytes],\n        offset: int = ...,\n        count: Optional[int] = ...,\n        *,\n        fallback: bool = ...\n    ) -> int: ...\n"
  },
  {
    "path": "uvloop/loop.pyx",
    "content": "# cython: language_level=3, embedsignature=True, freethreading_compatible=True\n\nimport asyncio\ncimport cython\n\nfrom .includes.debug cimport UVLOOP_DEBUG\nfrom .includes cimport uv\nfrom .includes cimport system\nfrom .includes.python cimport (\n    PY_VERSION_HEX,\n    PyMem_RawMalloc, PyMem_RawFree,\n    PyMem_RawCalloc, PyMem_RawRealloc,\n    PyUnicode_EncodeFSDefault,\n    PyErr_SetInterrupt,\n    _Py_RestoreSignals,\n    Context_CopyCurrent,\n    Context_Enter,\n    Context_Exit,\n    PyMemoryView_FromMemory, PyBUF_WRITE,\n    PyMemoryView_FromObject, PyMemoryView_Check,\n    PyOS_AfterFork_Parent, PyOS_AfterFork_Child,\n    PyOS_BeforeFork,\n    PyUnicode_FromString\n)\nfrom .includes.flowcontrol cimport add_flowcontrol_defaults\n\nfrom libc.stdint cimport uint64_t\nfrom libc.string cimport memset, strerror, memcpy\nfrom libc cimport errno\n\nfrom cpython cimport PyObject\nfrom cpython cimport PyErr_CheckSignals, PyErr_Occurred\nfrom cpython cimport PyThread_get_thread_ident\nfrom cpython cimport Py_INCREF, Py_DECREF, Py_XDECREF, Py_XINCREF\nfrom cpython cimport (\n    PyObject_GetBuffer, PyBuffer_Release, PyBUF_SIMPLE,\n    Py_buffer, PyBytes_AsString, PyBytes_CheckExact,\n    PyBytes_AsStringAndSize,\n    Py_SIZE, PyBytes_AS_STRING, PyBUF_WRITABLE\n)\nfrom cpython.pycapsule cimport PyCapsule_New, PyCapsule_GetPointer\n\nfrom . import _noop\n\n\ninclude \"includes/stdlib.pxi\"\n\ninclude \"errors.pyx\"\n\ncdef:\n    int PY39 = PY_VERSION_HEX >= 0x03090000\n    int PY311 = PY_VERSION_HEX >= 0x030b0000\n    int PY313 = PY_VERSION_HEX >= 0x030d0000\n    uint64_t MAX_SLEEP = 3600 * 24 * 365 * 100\n\n\ncdef _is_sock_stream(sock_type):\n    if SOCK_NONBLOCK == -1:\n        return sock_type == uv.SOCK_STREAM\n    else:\n        # Linux's socket.type is a bitmask that can include extra info\n        # about socket (like SOCK_NONBLOCK bit), therefore we can't do simple\n        # `sock_type == socket.SOCK_STREAM`, see\n        # https://github.com/torvalds/linux/blob/v4.13/include/linux/net.h#L77\n        # for more details.\n        return (sock_type & 0xF) == uv.SOCK_STREAM\n\n\ncdef _is_sock_dgram(sock_type):\n    if SOCK_NONBLOCK == -1:\n        return sock_type == uv.SOCK_DGRAM\n    else:\n        # Read the comment in `_is_sock_stream`.\n        return (sock_type & 0xF) == uv.SOCK_DGRAM\n\n\ncdef isfuture(obj):\n    if aio_isfuture is None:\n        return isinstance(obj, aio_Future)\n    else:\n        return aio_isfuture(obj)\n\n\ncdef inline socket_inc_io_ref(sock):\n    if isinstance(sock, socket_socket):\n        sock._io_refs += 1\n\n\ncdef inline socket_dec_io_ref(sock):\n    if isinstance(sock, socket_socket):\n        sock._decref_socketios()\n\n\ncdef inline run_in_context(context, method):\n    Context_Enter(context)\n    try:\n        return method()\n    finally:\n        Context_Exit(context)\n\n\ncdef inline run_in_context1(context, method, arg):\n    Context_Enter(context)\n    try:\n        return method(arg)\n    finally:\n        Context_Exit(context)\n\n\ncdef inline run_in_context2(context, method, arg1, arg2):\n    Context_Enter(context)\n    try:\n        return method(arg1, arg2)\n    finally:\n        Context_Exit(context)\n\n\n# Used for deprecation and removal of `loop.create_datagram_endpoint()`'s\n# *reuse_address* parameter\n_unset = object()\n\n\n@cython.no_gc_clear\ncdef class Loop:\n    def __cinit__(self):\n        cdef int err\n\n        # Install PyMem* memory allocators if they aren't installed yet.\n        __install_pymem()\n\n        # Install pthread_atfork handlers\n        __install_atfork()\n\n        self.uvloop = <uv.uv_loop_t*>PyMem_RawMalloc(sizeof(uv.uv_loop_t))\n        if self.uvloop is NULL:\n            raise MemoryError()\n\n        self.slow_callback_duration = 0.1\n\n        self._closed = 0\n        self._debug = 0\n        self._thread_id = 0\n        self._running = 0\n        self._stopping = 0\n\n        self._transports = weakref_WeakValueDictionary()\n        self._processes = set()\n\n        # Used to keep a reference (and hence keep the fileobj alive)\n        # for as long as its registered by add_reader or add_writer.\n        # This is how the selector module and hence asyncio behaves.\n        self._fd_to_reader_fileobj = {}\n        self._fd_to_writer_fileobj = {}\n\n        self._unix_server_sockets = {}\n\n        self._timers = set()\n        self._polls = {}\n\n        self._recv_buffer_in_use = 0\n\n        err = uv.uv_loop_init(self.uvloop)\n        if err < 0:\n            raise convert_error(err)\n        self.uvloop.data = <void*> self\n\n        self._init_debug_fields()\n\n        self.active_process_handler = None\n\n        self._last_error = None\n\n        self._task_factory = None\n        self._exception_handler = None\n        self._default_executor = None\n\n        self._queued_streams = set()\n        self._executing_streams = set()\n        self._ready = col_deque()\n\n        self.handler_async = UVAsync.new(\n            self, <method_t>self._on_wake, self)\n\n        self.handler_idle = UVIdle.new(\n            self,\n            new_MethodHandle(\n                self, \"loop._on_idle\", <method_t>self._on_idle, None, self))\n\n        # Needed to call `UVStream._exec_write` for writes scheduled\n        # during `Protocol.data_received`.\n        self.handler_check__exec_writes = UVCheck.new(\n            self,\n            new_MethodHandle(\n                self, \"loop._exec_queued_writes\",\n                <method_t>self._exec_queued_writes, None, self))\n\n        self._signals = set()\n        self._ssock = self._csock = None\n        self._signal_handlers = {}\n        self._listening_signals = False\n        self._old_signal_wakeup_id = -1\n\n        self._coroutine_debug_set = False\n\n        # A weak set of all asynchronous generators that are\n        # being iterated by the loop.\n        self._asyncgens = weakref_WeakSet()\n\n        # Set to True when `loop.shutdown_asyncgens` is called.\n        self._asyncgens_shutdown_called = False\n        # Set to True when `loop.shutdown_default_executor` is called.\n        self._executor_shutdown_called = False\n\n        self._servers = set()\n\n    cdef inline _is_main_thread(self):\n        cdef uint64_t main_thread_id = system.MAIN_THREAD_ID\n        if system.MAIN_THREAD_ID_SET == 0:\n            main_thread_id = <uint64_t>threading_main_thread().ident\n            system.setMainThreadID(main_thread_id)\n        return main_thread_id == PyThread_get_thread_ident()\n\n    def __init__(self):\n        self.set_debug(\n            sys_dev_mode or (not sys_ignore_environment\n                             and bool(os_environ.get('PYTHONASYNCIODEBUG'))))\n\n    def __dealloc__(self):\n        if self._running == 1:\n            raise RuntimeError('deallocating a running event loop!')\n        if self._closed == 0:\n            aio_logger.error(\"deallocating an open event loop\")\n            return\n        PyMem_RawFree(self.uvloop)\n        self.uvloop = NULL\n\n    cdef _init_debug_fields(self):\n        self._debug_cc = bool(UVLOOP_DEBUG)\n\n        if UVLOOP_DEBUG:\n            self._debug_handles_current = col_Counter()\n            self._debug_handles_closed = col_Counter()\n            self._debug_handles_total = col_Counter()\n        else:\n            self._debug_handles_current = None\n            self._debug_handles_closed = None\n            self._debug_handles_total = None\n\n        self._debug_uv_handles_total = 0\n        self._debug_uv_handles_freed = 0\n\n        self._debug_stream_read_cb_total = 0\n        self._debug_stream_read_eof_total = 0\n        self._debug_stream_read_errors_total = 0\n        self._debug_stream_read_cb_errors_total = 0\n        self._debug_stream_read_eof_cb_errors_total = 0\n\n        self._debug_stream_shutdown_errors_total = 0\n        self._debug_stream_listen_errors_total = 0\n\n        self._debug_stream_write_tries = 0\n        self._debug_stream_write_errors_total = 0\n        self._debug_stream_write_ctx_total = 0\n        self._debug_stream_write_ctx_cnt = 0\n        self._debug_stream_write_cb_errors_total = 0\n\n        self._debug_cb_handles_total = 0\n        self._debug_cb_handles_count = 0\n\n        self._debug_cb_timer_handles_total = 0\n        self._debug_cb_timer_handles_count = 0\n\n        self._poll_read_events_total = 0\n        self._poll_read_cb_errors_total = 0\n        self._poll_write_events_total = 0\n        self._poll_write_cb_errors_total = 0\n\n        self._sock_try_write_total = 0\n\n        self._debug_exception_handler_cnt = 0\n\n    cdef _setup_or_resume_signals(self):\n        if not self._is_main_thread():\n            return\n\n        if self._listening_signals:\n            raise RuntimeError('signals handling has been already setup')\n\n        if self._ssock is not None:\n            raise RuntimeError('self-pipe exists before loop run')\n\n        # Create a self-pipe and call set_signal_wakeup_fd() with one\n        # of its ends.  This is needed so that libuv knows that it needs\n        # to wakeup on ^C (no matter if the SIGINT handler is still the\n        # standard Python's one or or user set their own.)\n\n        self._ssock, self._csock = socket_socketpair()\n        try:\n            self._ssock.setblocking(False)\n            self._csock.setblocking(False)\n\n            fileno = self._csock.fileno()\n\n            self._old_signal_wakeup_id = _set_signal_wakeup_fd(fileno)\n        except Exception:\n            # Out of all statements in the try block, only the\n            # \"_set_signal_wakeup_fd()\" call can fail, but it shouldn't,\n            # as we ensure that the current thread is the main thread.\n            # Still, if something goes horribly wrong we want to clean up\n            # the socket pair.\n            self._ssock.close()\n            self._csock.close()\n            self._ssock = None\n            self._csock = None\n            raise\n\n        self._add_reader(\n            self._ssock,\n            new_MethodHandle(\n                self,\n                \"Loop._read_from_self\",\n                <method_t>self._read_from_self,\n                None,\n                self))\n\n        self._listening_signals = True\n\n    cdef _pause_signals(self):\n        if not self._is_main_thread():\n            if self._listening_signals:\n                raise RuntimeError(\n                    'cannot pause signals handling; no longer running in '\n                    'the main thread')\n            else:\n                return\n\n        if not self._listening_signals:\n            raise RuntimeError('signals handling has not been setup')\n\n        self._listening_signals = False\n\n        _set_signal_wakeup_fd(self._old_signal_wakeup_id)\n\n        self._remove_reader(self._ssock)\n        self._ssock.close()\n        self._csock.close()\n        self._ssock = None\n        self._csock = None\n\n    cdef _shutdown_signals(self):\n        if not self._is_main_thread():\n            if self._signal_handlers:\n                aio_logger.warning(\n                    'cannot cleanup signal handlers: closing the event loop '\n                    'in a non-main OS thread')\n            return\n\n        if self._listening_signals:\n            raise RuntimeError(\n                'cannot shutdown signals handling as it has not been paused')\n\n        if self._ssock:\n            raise RuntimeError(\n                'self-pipe was not cleaned up after loop was run')\n\n        for sig in list(self._signal_handlers):\n            self.remove_signal_handler(sig)\n\n    def __sighandler(self, signum, frame):\n        self._signals.add(signum)\n\n    cdef inline _ceval_process_signals(self):\n        # Invoke CPython eval loop to let process signals.\n        PyErr_CheckSignals()\n        # Calling a pure-Python function will invoke\n        # _PyEval_EvalFrameDefault which will process\n        # pending signal callbacks.\n        _noop.noop()  # Might raise ^C\n\n    cdef _read_from_self(self):\n        cdef bytes sigdata\n        sigdata = b''\n        while True:\n            try:\n                data = self._ssock.recv(65536)\n                if not data:\n                    break\n                sigdata += data\n            except InterruptedError:\n                continue\n            except BlockingIOError:\n                break\n        if sigdata:\n            self._invoke_signals(sigdata)\n\n    cdef _invoke_signals(self, bytes data):\n        cdef set sigs\n\n        self._ceval_process_signals()\n\n        sigs = self._signals.copy()\n        self._signals.clear()\n        for signum in data:\n            if not signum:\n                # ignore null bytes written by set_wakeup_fd()\n                continue\n            sigs.discard(signum)\n            self._handle_signal(signum)\n\n        for signum in sigs:\n            # Since not all signals are registered by add_signal_handler()\n            # (for instance, we use the default SIGINT handler) not all\n            # signals will trigger loop.__sighandler() callback.  Therefore\n            # we combine two datasources: one is self-pipe, one is data\n            # from __sighandler; this ensures that signals shouldn't be\n            # lost even if set_wakeup_fd() couldn't write to the self-pipe.\n            self._handle_signal(signum)\n\n    cdef _handle_signal(self, sig):\n        cdef Handle handle\n\n        try:\n            handle = <Handle>(self._signal_handlers[sig])\n        except KeyError:\n            handle = None\n\n        if handle is None:\n            self._ceval_process_signals()\n            return\n\n        if handle._cancelled:\n            self.remove_signal_handler(sig)  # Remove it properly.\n        else:\n            self._append_ready_handle(handle)\n            self.handler_async.send()\n\n    cdef _on_wake(self):\n        if ((len(self._ready) > 0 or self._stopping) and\n                not self.handler_idle.running):\n            self.handler_idle.start()\n\n    cdef _on_idle(self):\n        cdef:\n            int i, ntodo\n            object popleft = self._ready.popleft\n            Handle handler\n\n        ntodo = len(self._ready)\n        if self._debug:\n            for i from 0 <= i < ntodo:\n                handler = <Handle> popleft()\n                if handler._cancelled == 0:\n                    try:\n                        started = time_monotonic()\n                        handler._run()\n                    except BaseException as ex:\n                        self._stop(ex)\n                        return\n                    else:\n                        delta = time_monotonic() - started\n                        if delta > self.slow_callback_duration:\n                            aio_logger.warning(\n                                'Executing %s took %.3f seconds',\n                                handler._format_handle(), delta)\n\n        else:\n            for i from 0 <= i < ntodo:\n                handler = <Handle> popleft()\n                if handler._cancelled == 0:\n                    try:\n                        handler._run()\n                    except BaseException as ex:\n                        self._stop(ex)\n                        return\n\n        if len(self._queued_streams):\n            self._exec_queued_writes()\n\n        if len(self._ready) == 0 and self.handler_idle.running:\n            self.handler_idle.stop()\n\n        if self._stopping:\n            uv.uv_stop(self.uvloop)  # void\n\n    cdef _stop(self, exc):\n        if exc is not None:\n            self._last_error = exc\n        if self._stopping == 1:\n            return\n        self._stopping = 1\n        if not self.handler_idle.running:\n            self.handler_idle.start()\n\n    cdef __run(self, uv.uv_run_mode mode):\n        # Although every UVHandle holds a reference to the loop,\n        # we want to do everything to ensure that the loop will\n        # never deallocate during the run -- so we do some\n        # manual refs management.\n        Py_INCREF(self)\n        with nogil:\n            err = uv.uv_run(self.uvloop, mode)\n        Py_DECREF(self)\n\n        if err < 0:\n            raise convert_error(err)\n\n    cdef _run(self, uv.uv_run_mode mode):\n        cdef int err\n\n        if self._closed == 1:\n            raise RuntimeError('unable to start the loop; it was closed')\n\n        if self._running == 1:\n            raise RuntimeError('this event loop is already running.')\n\n        if (aio_get_running_loop is not None and\n                aio_get_running_loop() is not None):\n            raise RuntimeError(\n                'Cannot run the event loop while another loop is running')\n\n        # reset _last_error\n        self._last_error = None\n\n        self._thread_id = PyThread_get_thread_ident()\n        self._running = 1\n\n        self.handler_check__exec_writes.start()\n        self.handler_idle.start()\n\n        self._setup_or_resume_signals()\n\n        if aio_set_running_loop is not None:\n            aio_set_running_loop(self)\n        try:\n            self.__run(mode)\n        finally:\n            if aio_set_running_loop is not None:\n                aio_set_running_loop(None)\n\n            self.handler_check__exec_writes.stop()\n            self.handler_idle.stop()\n\n            self._pause_signals()\n\n            self._thread_id = 0\n            self._running = 0\n            self._stopping = 0\n\n        if self._last_error is not None:\n            # The loop was stopped with an error with 'loop._stop(error)' call\n            raise self._last_error\n\n    cdef _close(self):\n        cdef int err\n\n        if self._running == 1:\n            raise RuntimeError(\"Cannot close a running event loop\")\n\n        if self._closed == 1:\n            return\n\n        self._closed = 1\n\n        for cb_handle in self._ready:\n            cb_handle.cancel()\n        self._ready.clear()\n\n        if self._polls:\n            for poll_handle in self._polls.values():\n                (<UVHandle>poll_handle)._close()\n\n            self._polls.clear()\n\n        if self._timers:\n            for timer_cbhandle in tuple(self._timers):\n                timer_cbhandle.cancel()\n\n        # Close all remaining handles\n        self.handler_async._close()\n        self.handler_idle._close()\n        self.handler_check__exec_writes._close()\n        __close_all_handles(self)\n        self._shutdown_signals()\n        # During this run there should be no open handles,\n        # so it should finish right away\n        self.__run(uv.UV_RUN_DEFAULT)\n\n        if self._fd_to_writer_fileobj:\n            for fileobj in self._fd_to_writer_fileobj.values():\n                socket_dec_io_ref(fileobj)\n            self._fd_to_writer_fileobj.clear()\n\n        if self._fd_to_reader_fileobj:\n            for fileobj in self._fd_to_reader_fileobj.values():\n                socket_dec_io_ref(fileobj)\n            self._fd_to_reader_fileobj.clear()\n\n        if self._timers:\n            raise RuntimeError(\n                f\"new timers were queued during loop closing: {self._timers}\")\n\n        if self._polls:\n            raise RuntimeError(\n                f\"new poll handles were queued during loop closing: \"\n                f\"{self._polls}\")\n\n        if self._ready:\n            raise RuntimeError(\n                f\"new callbacks were queued during loop closing: \"\n                f\"{self._ready}\")\n\n        err = uv.uv_loop_close(self.uvloop)\n        if err < 0:\n            raise convert_error(err)\n\n        self.handler_async = None\n        self.handler_idle = None\n        self.handler_check__exec_writes = None\n\n        self._executor_shutdown_called = True\n        executor = self._default_executor\n        if executor is not None:\n            self._default_executor = None\n            executor.shutdown(wait=False)\n\n    cdef uint64_t _time(self):\n        # asyncio doesn't have a time cache, neither should uvloop.\n        uv.uv_update_time(self.uvloop)  # void\n        return uv.uv_now(self.uvloop)\n\n    cdef inline _queue_write(self, UVStream stream):\n        self._queued_streams.add(stream)\n        if not self.handler_check__exec_writes.running:\n            self.handler_check__exec_writes.start()\n\n    cdef _exec_queued_writes(self):\n        if len(self._queued_streams) == 0:\n            if self.handler_check__exec_writes.running:\n                self.handler_check__exec_writes.stop()\n            return\n\n        cdef:\n            UVStream stream\n\n        streams = self._queued_streams\n        self._queued_streams = self._executing_streams\n        self._executing_streams = streams\n        try:\n            for pystream in streams:\n                stream = <UVStream>pystream\n                stream._exec_write()\n        finally:\n            streams.clear()\n\n        if self.handler_check__exec_writes.running:\n            if len(self._queued_streams) == 0:\n                self.handler_check__exec_writes.stop()\n\n    cdef inline _call_soon(self, object callback, object args, object context):\n        cdef Handle handle\n        handle = new_Handle(self, callback, args, context)\n        self._call_soon_handle(handle)\n        return handle\n\n    cdef inline _append_ready_handle(self, Handle handle):\n        self._check_closed()\n        self._ready.append(handle)\n\n    cdef inline _call_soon_handle(self, Handle handle):\n        self._append_ready_handle(handle)\n        if not self.handler_idle.running:\n            self.handler_idle.start()\n\n    cdef _call_later(self, uint64_t delay, object callback, object args,\n                     object context):\n        return TimerHandle(self, callback, args, delay, context)\n\n    cdef void _handle_exception(self, object ex):\n        if isinstance(ex, Exception):\n            self.call_exception_handler({'exception': ex})\n        else:\n            # BaseException\n            self._last_error = ex\n            # Exit ASAP\n            self._stop(None)\n\n    cdef inline _check_signal(self, sig):\n        if not isinstance(sig, int):\n            raise TypeError('sig must be an int, not {!r}'.format(sig))\n\n        if not (1 <= sig < signal_NSIG):\n            raise ValueError(\n                'sig {} out of range(1, {})'.format(sig, signal_NSIG))\n\n    cdef inline _check_closed(self):\n        if self._closed == 1:\n            raise RuntimeError('Event loop is closed')\n\n    cdef inline _check_thread(self):\n        if self._thread_id == 0:\n            return\n\n        cdef uint64_t thread_id\n        thread_id = <uint64_t>PyThread_get_thread_ident()\n\n        if thread_id != self._thread_id:\n            raise RuntimeError(\n                \"Non-thread-safe operation invoked on an event loop other \"\n                \"than the current one\")\n\n    cdef inline _new_future(self):\n        return aio_Future(loop=self)\n\n    cdef _track_transport(self, UVBaseTransport transport):\n        self._transports[transport._fileno()] = transport\n\n    cdef _track_process(self, UVProcess proc):\n        self._processes.add(proc)\n\n    cdef _untrack_process(self, UVProcess proc):\n        self._processes.discard(proc)\n\n    cdef _fileobj_to_fd(self, fileobj):\n        \"\"\"Return a file descriptor from a file object.\n\n        Parameters:\n        fileobj -- file object or file descriptor\n\n        Returns:\n        corresponding file descriptor\n\n        Raises:\n        ValueError if the object is invalid\n        \"\"\"\n        # Copy of the `selectors._fileobj_to_fd()` function.\n        if isinstance(fileobj, int):\n            fd = fileobj\n        else:\n            try:\n                fd = int(fileobj.fileno())\n            except (AttributeError, TypeError, ValueError):\n                raise ValueError(\"Invalid file object: \"\n                                 \"{!r}\".format(fileobj)) from None\n        if fd < 0:\n            raise ValueError(\"Invalid file descriptor: {}\".format(fd))\n        return fd\n\n    cdef _ensure_fd_no_transport(self, fd):\n        cdef UVBaseTransport tr\n        try:\n            tr = <UVBaseTransport>(self._transports[fd])\n        except KeyError:\n            pass\n        else:\n            if tr._is_alive():\n                raise RuntimeError(\n                    'File descriptor {!r} is used by transport {!r}'.format(\n                        fd, tr))\n\n    cdef _add_reader(self, fileobj, Handle handle):\n        cdef:\n            UVPoll poll\n\n        self._check_closed()\n        fd = self._fileobj_to_fd(fileobj)\n        self._ensure_fd_no_transport(fd)\n\n        try:\n            poll = <UVPoll>(self._polls[fd])\n        except KeyError:\n            poll = UVPoll.new(self, fd)\n            self._polls[fd] = poll\n\n        poll.start_reading(handle)\n\n        old_fileobj = self._fd_to_reader_fileobj.pop(fd, None)\n        if old_fileobj is not None:\n            socket_dec_io_ref(old_fileobj)\n\n        self._fd_to_reader_fileobj[fd] = fileobj\n        socket_inc_io_ref(fileobj)\n\n    cdef _remove_reader(self, fileobj):\n        cdef:\n            UVPoll poll\n\n        fd = self._fileobj_to_fd(fileobj)\n        self._ensure_fd_no_transport(fd)\n\n        mapped_fileobj = self._fd_to_reader_fileobj.pop(fd, None)\n        if mapped_fileobj is not None:\n            socket_dec_io_ref(mapped_fileobj)\n\n        if self._closed == 1:\n            return False\n\n        try:\n            poll = <UVPoll>(self._polls[fd])\n        except KeyError:\n            return False\n\n        result = poll.stop_reading()\n        if not poll.is_active():\n            del self._polls[fd]\n            poll._close()\n\n        return result\n\n    cdef _has_reader(self, fileobj):\n        cdef:\n            UVPoll poll\n\n        self._check_closed()\n        fd = self._fileobj_to_fd(fileobj)\n\n        try:\n            poll = <UVPoll>(self._polls[fd])\n        except KeyError:\n            return False\n\n        return poll.is_reading()\n\n    cdef _add_writer(self, fileobj, Handle handle):\n        cdef:\n            UVPoll poll\n\n        self._check_closed()\n        fd = self._fileobj_to_fd(fileobj)\n        self._ensure_fd_no_transport(fd)\n\n        try:\n            poll = <UVPoll>(self._polls[fd])\n        except KeyError:\n            poll = UVPoll.new(self, fd)\n            self._polls[fd] = poll\n\n        poll.start_writing(handle)\n\n        old_fileobj = self._fd_to_writer_fileobj.pop(fd, None)\n        if old_fileobj is not None:\n            socket_dec_io_ref(old_fileobj)\n\n        self._fd_to_writer_fileobj[fd] = fileobj\n        socket_inc_io_ref(fileobj)\n\n    cdef _remove_writer(self, fileobj):\n        cdef:\n            UVPoll poll\n\n        fd = self._fileobj_to_fd(fileobj)\n        self._ensure_fd_no_transport(fd)\n\n        mapped_fileobj = self._fd_to_writer_fileobj.pop(fd, None)\n        if mapped_fileobj is not None:\n            socket_dec_io_ref(mapped_fileobj)\n\n        if self._closed == 1:\n            return False\n\n        try:\n            poll = <UVPoll>(self._polls[fd])\n        except KeyError:\n            return False\n\n        result = poll.stop_writing()\n        if not poll.is_active():\n            del self._polls[fd]\n            poll._close()\n\n        return result\n\n    cdef _has_writer(self, fileobj):\n        cdef:\n            UVPoll poll\n\n        self._check_closed()\n        fd = self._fileobj_to_fd(fileobj)\n\n        try:\n            poll = <UVPoll>(self._polls[fd])\n        except KeyError:\n            return False\n\n        return poll.is_writing()\n\n    cdef _getaddrinfo(self, object host, object port,\n                      int family, int type,\n                      int proto, int flags,\n                      int unpack):\n\n        if isinstance(port, str):\n            port = port.encode()\n        elif isinstance(port, int):\n            port = str(port).encode()\n        if port is not None and not isinstance(port, bytes):\n            raise TypeError('port must be a str, bytes or int')\n\n        if isinstance(host, str):\n            host = host.encode('idna')\n        if host is not None:\n            if not isinstance(host, bytes):\n                raise TypeError('host must be a str or bytes')\n\n        fut = self._new_future()\n\n        def callback(result):\n            if AddrInfo.isinstance(result):\n                try:\n                    if unpack == 0:\n                        data = result\n                    else:\n                        data = (<AddrInfo>result).unpack()\n                except (KeyboardInterrupt, SystemExit):\n                    raise\n                except BaseException as ex:\n                    if not fut.cancelled():\n                        fut.set_exception(ex)\n                else:\n                    if not fut.cancelled():\n                        fut.set_result(data)\n            else:\n                if not fut.cancelled():\n                    fut.set_exception(result)\n\n        AddrInfoRequest(self, host, port, family, type, proto, flags, callback)\n        return fut\n\n    cdef _getnameinfo(self, system.sockaddr *addr, int flags):\n        cdef NameInfoRequest nr\n        fut = self._new_future()\n\n        def callback(result):\n            if isinstance(result, tuple):\n                fut.set_result(result)\n            else:\n                fut.set_exception(result)\n\n        nr = NameInfoRequest(self, callback)\n        nr.query(addr, flags)\n        return fut\n\n    cdef _sock_recv(self, fut, sock, n):\n        if UVLOOP_DEBUG:\n            if fut.cancelled():\n                # Shouldn't happen with _SyncSocketReaderFuture.\n                raise RuntimeError(\n                    f'_sock_recv is called on a cancelled Future')\n\n            if not self._has_reader(sock):\n                raise RuntimeError(\n                    f'socket {sock!r} does not have a reader '\n                    f'in the _sock_recv callback')\n\n        try:\n            data = sock.recv(n)\n        except (BlockingIOError, InterruptedError):\n            # No need to re-add the reader, let's just wait until\n            # the poll handler calls this callback again.\n            pass\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException as exc:\n            fut.set_exception(exc)\n            self._remove_reader(sock)\n        else:\n            fut.set_result(data)\n            self._remove_reader(sock)\n\n    cdef _sock_recv_into(self, fut, sock, buf):\n        if UVLOOP_DEBUG:\n            if fut.cancelled():\n                # Shouldn't happen with _SyncSocketReaderFuture.\n                raise RuntimeError(\n                    f'_sock_recv_into is called on a cancelled Future')\n\n            if not self._has_reader(sock):\n                raise RuntimeError(\n                    f'socket {sock!r} does not have a reader '\n                    f'in the _sock_recv_into callback')\n\n        try:\n            data = sock.recv_into(buf)\n        except (BlockingIOError, InterruptedError):\n            # No need to re-add the reader, let's just wait until\n            # the poll handler calls this callback again.\n            pass\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException as exc:\n            fut.set_exception(exc)\n            self._remove_reader(sock)\n        else:\n            fut.set_result(data)\n            self._remove_reader(sock)\n\n    cdef _sock_sendall(self, fut, sock, data):\n        cdef:\n            Handle handle\n            int n\n\n        if UVLOOP_DEBUG:\n            if fut.cancelled():\n                # Shouldn't happen with _SyncSocketWriterFuture.\n                raise RuntimeError(\n                    f'_sock_sendall is called on a cancelled Future')\n\n            if not self._has_writer(sock):\n                raise RuntimeError(\n                    f'socket {sock!r} does not have a writer '\n                    f'in the _sock_sendall callback')\n\n        try:\n            n = sock.send(data)\n        except (BlockingIOError, InterruptedError):\n            # Try next time.\n            return\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException as exc:\n            fut.set_exception(exc)\n            self._remove_writer(sock)\n            return\n\n        self._remove_writer(sock)\n\n        if n == len(data):\n            fut.set_result(None)\n        else:\n            if n:\n                if not isinstance(data, memoryview):\n                    data = memoryview(data)\n                data = data[n:]\n\n            handle = new_MethodHandle3(\n                self,\n                \"Loop._sock_sendall\",\n                <method3_t>self._sock_sendall,\n                None,\n                self,\n                fut, sock, data)\n\n            self._add_writer(sock, handle)\n\n    cdef _sock_accept(self, fut, sock):\n        try:\n            conn, address = sock.accept()\n            conn.setblocking(False)\n        except (BlockingIOError, InterruptedError):\n            # There is an active reader for _sock_accept, so\n            # do nothing, it will be called again.\n            pass\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException as exc:\n            fut.set_exception(exc)\n            self._remove_reader(sock)\n        else:\n            fut.set_result((conn, address))\n            self._remove_reader(sock)\n\n    cdef _sock_connect(self, sock, address):\n        cdef:\n            Handle handle\n\n        try:\n            sock.connect(address)\n        except (BlockingIOError, InterruptedError):\n            pass\n        else:\n            return\n\n        fut = _SyncSocketWriterFuture(sock, self)\n        handle = new_MethodHandle3(\n            self,\n            \"Loop._sock_connect\",\n            <method3_t>self._sock_connect_cb,\n            None,\n            self,\n            fut, sock, address)\n\n        self._add_writer(sock, handle)\n        return fut\n\n    cdef _sock_connect_cb(self, fut, sock, address):\n        if UVLOOP_DEBUG:\n            if fut.cancelled():\n                # Shouldn't happen with _SyncSocketWriterFuture.\n                raise RuntimeError(\n                    f'_sock_connect_cb is called on a cancelled Future')\n\n            if not self._has_writer(sock):\n                raise RuntimeError(\n                    f'socket {sock!r} does not have a writer '\n                    f'in the _sock_connect_cb callback')\n\n        try:\n            err = sock.getsockopt(uv.SOL_SOCKET, uv.SO_ERROR)\n            if err != 0:\n                # Jump to any except clause below.\n                raise OSError(err, 'Connect call failed %s' % (address,))\n        except (BlockingIOError, InterruptedError):\n            # socket is still registered, the callback will be retried later\n            pass\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException as exc:\n            fut.set_exception(exc)\n            self._remove_writer(sock)\n        else:\n            fut.set_result(None)\n            self._remove_writer(sock)\n\n    cdef _sock_set_reuseport(self, int fd):\n        cdef:\n            int err = 0\n            int reuseport_flag = 1\n\n        err = system.setsockopt(\n            fd,\n            uv.SOL_SOCKET,\n            SO_REUSEPORT,\n            <char*>&reuseport_flag,\n            sizeof(reuseport_flag))\n\n        if err < 0:\n            raise convert_error(-errno.errno)\n\n    cdef _set_coroutine_debug(self, bint enabled):\n        enabled = bool(enabled)\n        if self._coroutine_debug_set == enabled:\n            return\n\n        if enabled:\n            self._coroutine_origin_tracking_saved_depth = (\n                sys.get_coroutine_origin_tracking_depth())\n            sys.set_coroutine_origin_tracking_depth(\n                DEBUG_STACK_DEPTH)\n        else:\n            sys.set_coroutine_origin_tracking_depth(\n                self._coroutine_origin_tracking_saved_depth)\n\n        self._coroutine_debug_set = enabled\n\n    def _get_backend_id(self):\n        \"\"\"This method is used by uvloop tests and is not part of the API.\"\"\"\n        return uv.uv_backend_fd(self.uvloop)\n\n    cdef _print_debug_info(self):\n        cdef:\n            int err\n            uv.uv_rusage_t rusage\n\n        err = uv.uv_getrusage(&rusage)\n        if err < 0:\n            raise convert_error(err)\n\n        # OS\n\n        print('---- Process info: -----')\n        print('Process memory:            {}'.format(rusage.ru_maxrss))\n        print('Number of signals:         {}'.format(rusage.ru_nsignals))\n        print('')\n\n        # Loop\n\n        print('--- Loop debug info: ---')\n        print('Loop time:                 {}'.format(self.time()))\n        print('Errors logged:             {}'.format(\n            self._debug_exception_handler_cnt))\n        print()\n        print('Callback handles:          {: <8} | {}'.format(\n            self._debug_cb_handles_count,\n            self._debug_cb_handles_total))\n        print('Timer handles:             {: <8} | {}'.format(\n            self._debug_cb_timer_handles_count,\n            self._debug_cb_timer_handles_total))\n        print()\n\n        print('                        alive  | closed  |')\n        print('UVHandles               python | libuv   | total')\n        print('                        objs   | handles |')\n        print('-------------------------------+---------+---------')\n        for name in sorted(self._debug_handles_total):\n            print('    {: <18} {: >7} | {: >7} | {: >7}'.format(\n                name,\n                self._debug_handles_current[name],\n                self._debug_handles_closed[name],\n                self._debug_handles_total[name]))\n        print()\n\n        print('uv_handle_t (current: {}; freed: {}; total: {})'.format(\n            self._debug_uv_handles_total - self._debug_uv_handles_freed,\n            self._debug_uv_handles_freed,\n            self._debug_uv_handles_total))\n        print()\n\n        print('--- Streams debug info: ---')\n        print('Write errors:              {}'.format(\n            self._debug_stream_write_errors_total))\n        print('Write without poll:        {}'.format(\n            self._debug_stream_write_tries))\n        print('Write contexts:            {: <8} | {}'.format(\n            self._debug_stream_write_ctx_cnt,\n            self._debug_stream_write_ctx_total))\n        print('Write failed callbacks:    {}'.format(\n            self._debug_stream_write_cb_errors_total))\n        print()\n        print('Read errors:               {}'.format(\n            self._debug_stream_read_errors_total))\n        print('Read callbacks:            {}'.format(\n            self._debug_stream_read_cb_total))\n        print('Read failed callbacks:     {}'.format(\n            self._debug_stream_read_cb_errors_total))\n        print('Read EOFs:                 {}'.format(\n            self._debug_stream_read_eof_total))\n        print('Read EOF failed callbacks: {}'.format(\n            self._debug_stream_read_eof_cb_errors_total))\n        print()\n        print('Listen errors:             {}'.format(\n            self._debug_stream_listen_errors_total))\n        print('Shutdown errors            {}'.format(\n            self._debug_stream_shutdown_errors_total))\n        print()\n\n        print('--- Polls debug info: ---')\n        print('Read events:               {}'.format(\n            self._poll_read_events_total))\n        print('Read callbacks failed:     {}'.format(\n            self._poll_read_cb_errors_total))\n        print('Write events:              {}'.format(\n            self._poll_write_events_total))\n        print('Write callbacks failed:    {}'.format(\n            self._poll_write_cb_errors_total))\n        print()\n\n        print('--- Sock ops successful on 1st try: ---')\n        print('Socket try-writes:         {}'.format(\n            self._sock_try_write_total))\n\n        print(flush=True)\n\n    property print_debug_info:\n        def __get__(self):\n            if UVLOOP_DEBUG:\n                return lambda: self._print_debug_info()\n            else:\n                raise AttributeError('print_debug_info')\n\n    # Public API\n\n    def __repr__(self):\n        return '<{}.{} running={} closed={} debug={}>'.format(\n            self.__class__.__module__,\n            self.__class__.__name__,\n            self.is_running(),\n            self.is_closed(),\n            self.get_debug()\n        )\n\n    def call_soon(self, callback, *args, context=None):\n        \"\"\"Arrange for a callback to be called as soon as possible.\n\n        This operates as a FIFO queue: callbacks are called in the\n        order in which they are registered.  Each callback will be\n        called exactly once.\n\n        Any positional arguments after the callback will be passed to\n        the callback when it is called.\n        \"\"\"\n        if self._debug == 1:\n            self._check_thread()\n        if args:\n            return self._call_soon(callback, args, context)\n        else:\n            return self._call_soon(callback, None, context)\n\n    def call_soon_threadsafe(self, callback, *args, context=None):\n        \"\"\"Like call_soon(), but thread-safe.\"\"\"\n        if not args:\n            args = None\n        cdef Handle handle = new_Handle(self, callback, args, context)\n        self._append_ready_handle(handle)  # deque append is atomic\n        # libuv async handler is thread-safe while the idle handler is not -\n        # we only set the async handler here, which will start the idle handler\n        # in _on_wake() from the loop and eventually call the callback.\n        self.handler_async.send()\n        return handle\n\n    def call_later(self, delay, callback, *args, context=None):\n        \"\"\"Arrange for a callback to be called at a given time.\n\n        Return a Handle: an opaque object with a cancel() method that\n        can be used to cancel the call.\n\n        The delay can be an int or float, expressed in seconds.  It is\n        always relative to the current time.\n\n        Each callback will be called exactly once.  If two callbacks\n        are scheduled for exactly the same time, it undefined which\n        will be called first.\n\n        Any positional arguments after the callback will be passed to\n        the callback when it is called.\n        \"\"\"\n        cdef uint64_t when\n\n        self._check_closed()\n        if self._debug == 1:\n            self._check_thread()\n\n        if delay < 0:\n            delay = 0\n        elif delay == py_inf or delay > MAX_SLEEP:\n            # ~100 years sounds like a good approximation of\n            # infinity for a Python application.\n            delay = MAX_SLEEP\n\n        when = <uint64_t>round(delay * 1000)\n        if not args:\n            args = None\n        if when == 0:\n            return self._call_soon(callback, args, context)\n        else:\n            return self._call_later(when, callback, args, context)\n\n    def call_at(self, when, callback, *args, context=None):\n        \"\"\"Like call_later(), but uses an absolute time.\n\n        Absolute time corresponds to the event loop's time() method.\n        \"\"\"\n        return self.call_later(\n            when - self.time(), callback, *args, context=context)\n\n    def time(self):\n        \"\"\"Return the time according to the event loop's clock.\n\n        This is a float expressed in seconds since an epoch, but the\n        epoch, precision, accuracy and drift are unspecified and may\n        differ per event loop.\n        \"\"\"\n        return self._time() / 1000\n\n    def stop(self):\n        \"\"\"Stop running the event loop.\n\n        Every callback already scheduled will still run.  This simply informs\n        run_forever to stop looping after a complete iteration.\n        \"\"\"\n        self._call_soon_handle(\n            new_MethodHandle1(\n                self,\n                \"Loop._stop\",\n                <method1_t>self._stop,\n                None,\n                self,\n                None))\n\n    def run_forever(self):\n        \"\"\"Run the event loop until stop() is called.\"\"\"\n        self._check_closed()\n        mode = uv.UV_RUN_DEFAULT\n        if self._stopping:\n            # loop.stop() was called right before loop.run_forever().\n            # This is how asyncio loop behaves.\n            mode = uv.UV_RUN_NOWAIT\n        self._set_coroutine_debug(self._debug)\n        old_agen_hooks = sys.get_asyncgen_hooks()\n        sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook,\n                               finalizer=self._asyncgen_finalizer_hook)\n        try:\n            self._run(mode)\n        finally:\n            self._set_coroutine_debug(False)\n            sys.set_asyncgen_hooks(*old_agen_hooks)\n\n    def close(self):\n        \"\"\"Close the event loop.\n\n        The event loop must not be running.\n\n        This is idempotent and irreversible.\n\n        No other methods should be called after this one.\n        \"\"\"\n        self._close()\n\n    def get_debug(self):\n        return bool(self._debug)\n\n    def set_debug(self, enabled):\n        self._debug = bool(enabled)\n        if self.is_running():\n             self.call_soon_threadsafe(self._set_coroutine_debug, self._debug)\n\n    def is_running(self):\n        \"\"\"Return whether the event loop is currently running.\"\"\"\n        return bool(self._running)\n\n    def is_closed(self):\n        \"\"\"Returns True if the event loop was closed.\"\"\"\n        return bool(self._closed)\n\n    def create_future(self):\n        \"\"\"Create a Future object attached to the loop.\"\"\"\n        return self._new_future()\n\n    def create_task(self, coro, *, name=None, context=None):\n        \"\"\"Schedule a coroutine object.\n\n        Return a task object.\n\n        If name is not None, task.set_name(name) will be called if the task\n        object has the set_name attribute, true for default Task in CPython.\n\n        An optional keyword-only context argument allows specifying a custom\n        contextvars.Context for the coro to run in. The current context copy is\n        created when no context is provided.\n        \"\"\"\n        self._check_closed()\n        if PY311:\n            if self._task_factory is None:\n                task = aio_Task(coro, loop=self, context=context)\n            else:\n                task = self._task_factory(self, coro, context=context)\n        else:\n            if context is None:\n                if self._task_factory is None:\n                    task = aio_Task(coro, loop=self)\n                else:\n                    task = self._task_factory(self, coro)\n            else:\n                if self._task_factory is None:\n                    task = context.run(aio_Task, coro, self)\n                else:\n                    task = context.run(self._task_factory, self, coro)\n\n        # copied from asyncio.tasks._set_task_name (bpo-34270)\n        if name is not None:\n            try:\n                set_name = task.set_name\n            except AttributeError:\n                pass\n            else:\n                set_name(name)\n\n        return task\n\n    def set_task_factory(self, factory):\n        \"\"\"Set a task factory that will be used by loop.create_task().\n\n        If factory is None the default task factory will be set.\n\n        If factory is a callable, it should have a signature matching\n        '(loop, coro)', where 'loop' will be a reference to the active\n        event loop, 'coro' will be a coroutine object.  The callable\n        must return a Future.\n        \"\"\"\n        if factory is not None and not callable(factory):\n            raise TypeError('task factory must be a callable or None')\n        self._task_factory = factory\n\n    def get_task_factory(self):\n        \"\"\"Return a task factory, or None if the default one is in use.\"\"\"\n        return self._task_factory\n\n    def run_until_complete(self, future):\n        \"\"\"Run until the Future is done.\n\n        If the argument is a coroutine, it is wrapped in a Task.\n\n        WARNING: It would be disastrous to call run_until_complete()\n        with the same coroutine twice -- it would wrap it in two\n        different Tasks and that can't be good.\n\n        Return the Future's result, or raise its exception.\n        \"\"\"\n        self._check_closed()\n\n        new_task = not isfuture(future)\n        future = aio_ensure_future(future, loop=self)\n        if new_task:\n            # An exception is raised if the future didn't complete, so there\n            # is no need to log the \"destroy pending task\" message\n            future._log_destroy_pending = False\n\n        def done_cb(fut):\n            if not fut.cancelled():\n                exc = fut.exception()\n                if isinstance(exc, (SystemExit, KeyboardInterrupt)):\n                    # Issue #336: run_forever() already finished,\n                    # no need to stop it.\n                    return\n            self.stop()\n\n        future.add_done_callback(done_cb)\n        try:\n            self.run_forever()\n        except BaseException:\n            if new_task and future.done() and not future.cancelled():\n                # The coroutine raised a BaseException. Consume the exception\n                # to not log a warning, the caller doesn't have access to the\n                # local task.\n                future.exception()\n            raise\n        finally:\n            future.remove_done_callback(done_cb)\n        if not future.done():\n            raise RuntimeError('Event loop stopped before Future completed.')\n\n        return future.result()\n\n    @cython.iterable_coroutine\n    async def getaddrinfo(self, object host, object port, *,\n                          int family=0, int type=0, int proto=0, int flags=0):\n\n        addr = __static_getaddrinfo_pyaddr(host, port, family,\n                                           type, proto, flags)\n        if addr is not None:\n            return [addr]\n\n        return await self._getaddrinfo(\n            host, port, family, type, proto, flags, 1)\n\n    @cython.iterable_coroutine\n    async def getnameinfo(self, sockaddr, int flags=0):\n        cdef:\n            AddrInfo ai_cnt\n            system.addrinfo *ai\n            system.sockaddr_in6 *sin6\n\n        if not isinstance(sockaddr, tuple):\n            raise TypeError('getnameinfo() argument 1 must be a tuple')\n\n        sl = len(sockaddr)\n\n        if sl < 2 or sl > 4:\n            raise ValueError('sockaddr must be a tuple of 2, 3 or 4 values')\n\n        if sl > 2:\n            flowinfo = sockaddr[2]\n            if flowinfo < 0 or flowinfo > 0xfffff:\n                raise OverflowError(\n                    'getnameinfo(): flowinfo must be 0-1048575.')\n        else:\n            flowinfo = 0\n\n        if sl > 3:\n            scope_id = sockaddr[3]\n            if scope_id < 0 or scope_id > 2 ** 32:\n                raise OverflowError(\n                    'getsockaddrarg: scope_id must be unsigned 32 bit integer')\n        else:\n            scope_id = 0\n\n        ai_cnt = await self._getaddrinfo(\n            sockaddr[0], sockaddr[1],\n            uv.AF_UNSPEC,         # family\n            uv.SOCK_DGRAM,        # type\n            0,                    # proto\n            uv.AI_NUMERICHOST,    # flags\n            0)                    # unpack\n\n        ai = ai_cnt.data\n\n        if ai.ai_next:\n            raise OSError(\"sockaddr resolved to multiple addresses\")\n\n        if ai.ai_family == uv.AF_INET:\n            if sl > 2:\n                raise OSError(\"IPv4 sockaddr must be 2 tuple\")\n        elif ai.ai_family == uv.AF_INET6:\n            # Modify some fields in `ai`\n            sin6 = <system.sockaddr_in6*> ai.ai_addr\n            sin6.sin6_flowinfo = system.htonl(flowinfo)\n            sin6.sin6_scope_id = scope_id\n\n        return await self._getnameinfo(ai.ai_addr, flags)\n\n    @cython.iterable_coroutine\n    async def start_tls(self, transport, protocol, sslcontext, *,\n                        server_side=False,\n                        server_hostname=None,\n                        ssl_handshake_timeout=None,\n                        ssl_shutdown_timeout=None):\n        \"\"\"Upgrade transport to TLS.\n\n        Return a new transport that *protocol* should start using\n        immediately.\n        \"\"\"\n        if not isinstance(sslcontext, ssl_SSLContext):\n            raise TypeError(\n                f'sslcontext is expected to be an instance of ssl.SSLContext, '\n                f'got {sslcontext!r}')\n\n        if isinstance(transport, (TCPTransport, UnixTransport)):\n            context = (<UVStream>transport).context\n        elif isinstance(transport, _SSLProtocolTransport):\n            context = (<_SSLProtocolTransport>transport).context\n        else:\n            raise TypeError(\n                f'transport {transport!r} is not supported by start_tls()')\n\n        waiter = self._new_future()\n        ssl_protocol = SSLProtocol(\n            self, protocol, sslcontext, waiter,\n            server_side, server_hostname,\n            ssl_handshake_timeout=ssl_handshake_timeout,\n            ssl_shutdown_timeout=ssl_shutdown_timeout,\n            call_connection_made=False)\n\n        # Pause early so that \"ssl_protocol.data_received()\" doesn't\n        # have a chance to get called before \"ssl_protocol.connection_made()\".\n        transport.pause_reading()\n\n        transport.set_protocol(ssl_protocol)\n        conmade_cb = self.call_soon(ssl_protocol.connection_made, transport,\n                                    context=context)\n        # transport.resume_reading() will use the right context\n        # (transport.context) to call e.g. data_received()\n        resume_cb = self.call_soon(transport.resume_reading)\n        app_transport = ssl_protocol._get_app_transport(context)\n\n        try:\n            await waiter\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException:\n            app_transport.close()\n            conmade_cb.cancel()\n            resume_cb.cancel()\n            raise\n\n        return app_transport\n\n    @cython.iterable_coroutine\n    async def create_server(self, protocol_factory, host=None, port=None,\n                            *,\n                            int family=uv.AF_UNSPEC,\n                            int flags=uv.AI_PASSIVE,\n                            sock=None,\n                            backlog=100,\n                            ssl=None,\n                            reuse_address=None,\n                            reuse_port=None,\n                            ssl_handshake_timeout=None,\n                            ssl_shutdown_timeout=None,\n                            start_serving=True):\n        \"\"\"A coroutine which creates a TCP server bound to host and port.\n\n        The return value is a Server object which can be used to stop\n        the service.\n\n        If host is an empty string or None all interfaces are assumed\n        and a list of multiple sockets will be returned (most likely\n        one for IPv4 and another one for IPv6). The host parameter can also be\n        a sequence (e.g. list) of hosts to bind to.\n\n        family can be set to either AF_INET or AF_INET6 to force the\n        socket to use IPv4 or IPv6. If not set it will be determined\n        from host (defaults to AF_UNSPEC).\n\n        flags is a bitmask for getaddrinfo().\n\n        sock can optionally be specified in order to use a preexisting\n        socket object.\n\n        backlog is the maximum number of queued connections passed to\n        listen() (defaults to 100).\n\n        ssl can be set to an SSLContext to enable SSL over the\n        accepted connections.\n\n        reuse_address tells the kernel to reuse a local socket in\n        TIME_WAIT state, without waiting for its natural timeout to\n        expire. If not specified will automatically be set to True on\n        UNIX.\n\n        reuse_port tells the kernel to allow this endpoint to be bound to\n        the same port as other existing endpoints are bound to, so long as\n        they all set this flag when being created. This option is not\n        supported on Windows.\n\n        ssl_handshake_timeout is the time in seconds that an SSL server\n        will wait for completion of the SSL handshake before aborting the\n        connection. Default is 60s.\n\n        ssl_shutdown_timeout is the time in seconds that an SSL server\n        will wait for completion of the SSL shutdown before aborting the\n        connection. Default is 30s.\n        \"\"\"\n        cdef:\n            TCPServer tcp\n            system.addrinfo *addrinfo\n            Server server\n\n        if sock is not None and sock.family == uv.AF_UNIX:\n            if host is not None or port is not None:\n                raise ValueError(\n                    'host/port and sock can not be specified at the same time')\n            return await self.create_unix_server(\n                protocol_factory, sock=sock, backlog=backlog, ssl=ssl,\n                start_serving=start_serving,\n                # asyncio won't clean up socket file using create_server() API\n                cleanup_socket=False,\n            )\n\n        server = Server(self)\n\n        if ssl is not None:\n            if not isinstance(ssl, ssl_SSLContext):\n                raise TypeError('ssl argument must be an SSLContext or None')\n        else:\n            if ssl_handshake_timeout is not None:\n                raise ValueError(\n                    'ssl_handshake_timeout is only meaningful with ssl')\n            if ssl_shutdown_timeout is not None:\n                raise ValueError(\n                    'ssl_shutdown_timeout is only meaningful with ssl')\n\n        if host is not None or port is not None:\n            if sock is not None:\n                raise ValueError(\n                    'host/port and sock can not be specified at the same time')\n\n            if reuse_address is None:\n                reuse_address = os_name == 'posix' and sys_platform != 'cygwin'\n            reuse_port = bool(reuse_port)\n            if reuse_port and not has_SO_REUSEPORT:\n                raise ValueError(\n                    'reuse_port not supported by socket module')\n\n            if host == '':\n                hosts = [None]\n            elif (isinstance(host, str) or not isinstance(host, col_Iterable)):\n                hosts = [host]\n            else:\n                hosts = host\n\n            fs = [self._getaddrinfo(host, port, family,\n                                    uv.SOCK_STREAM, 0, flags,\n                                    0) for host in hosts]\n\n            infos = await aio_gather(*fs)\n\n            completed = False\n            sock = None\n            try:\n                for info in infos:\n                    addrinfo = (<AddrInfo>info).data\n                    while addrinfo != NULL:\n                        if addrinfo.ai_family == uv.AF_UNSPEC:\n                            raise RuntimeError('AF_UNSPEC in DNS results')\n\n                        try:\n                            sock = socket_socket(addrinfo.ai_family,\n                                                 addrinfo.ai_socktype,\n                                                 addrinfo.ai_protocol)\n                        except socket_error:\n                            # Assume it's a bad family/type/protocol\n                            # combination.\n                            if self._debug:\n                                aio_logger.warning(\n                                    'create_server() failed to create '\n                                    'socket.socket(%r, %r, %r)',\n                                    addrinfo.ai_family,\n                                    addrinfo.ai_socktype,\n                                    addrinfo.ai_protocol, exc_info=True)\n                            addrinfo = addrinfo.ai_next\n                            continue\n\n                        if reuse_address:\n                            sock.setsockopt(uv.SOL_SOCKET, uv.SO_REUSEADDR, 1)\n                        if reuse_port:\n                            sock.setsockopt(uv.SOL_SOCKET, SO_REUSEPORT, 1)\n                        # Disable IPv4/IPv6 dual stack support (enabled by\n                        # default on Linux) which makes a single socket\n                        # listen on both address families.\n                        if (addrinfo.ai_family == uv.AF_INET6 and\n                                has_IPV6_V6ONLY):\n                            sock.setsockopt(uv.IPPROTO_IPV6, IPV6_V6ONLY, 1)\n\n                        pyaddr = __convert_sockaddr_to_pyaddr(addrinfo.ai_addr)\n                        try:\n                            sock.bind(pyaddr)\n                        except OSError as err:\n                            raise OSError(\n                                err.errno, 'error while attempting '\n                                'to bind on address %r: %s'\n                                % (pyaddr, err.strerror.lower())) from None\n\n                        tcp = TCPServer.new(self, protocol_factory, server,\n                                            uv.AF_UNSPEC, backlog,\n                                            ssl, ssl_handshake_timeout,\n                                            ssl_shutdown_timeout)\n\n                        try:\n                            tcp._open(sock.fileno())\n                        except (KeyboardInterrupt, SystemExit):\n                            raise\n                        except BaseException:\n                            tcp._close()\n                            raise\n\n                        server._add_server(tcp)\n                        sock.detach()\n                        sock = None\n\n                        addrinfo = addrinfo.ai_next\n\n                completed = True\n            finally:\n                if not completed:\n                    if sock is not None:\n                        sock.close()\n                    server.close()\n        else:\n            if sock is None:\n                raise ValueError('Neither host/port nor sock were specified')\n            if not _is_sock_stream(sock.type):\n                raise ValueError(\n                    'A Stream Socket was expected, got {!r}'.format(sock))\n\n            # libuv will set the socket to non-blocking mode, but\n            # we want Python socket object to notice that.\n            sock.setblocking(False)\n\n            tcp = TCPServer.new(self, protocol_factory, server,\n                                uv.AF_UNSPEC, backlog,\n                                ssl, ssl_handshake_timeout,\n                                ssl_shutdown_timeout)\n\n            try:\n                tcp._open(sock.fileno())\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException:\n                tcp._close()\n                raise\n\n            tcp._attach_fileobj(sock)\n            server._add_server(tcp)\n\n        if start_serving:\n            server._start_serving()\n\n        server._ref()\n        return server\n\n    @cython.iterable_coroutine\n    async def create_connection(self, protocol_factory, host=None, port=None,\n                                *,\n                                ssl=None,\n                                family=0, proto=0, flags=0, sock=None,\n                                local_addr=None, server_hostname=None,\n                                ssl_handshake_timeout=None,\n                                ssl_shutdown_timeout=None):\n        \"\"\"Connect to a TCP server.\n\n        Create a streaming transport connection to a given Internet host and\n        port: socket family AF_INET or socket.AF_INET6 depending on host (or\n        family if specified), socket type SOCK_STREAM. protocol_factory must be\n        a callable returning a protocol instance.\n\n        This method is a coroutine which will try to establish the connection\n        in the background.  When successful, the coroutine returns a\n        (transport, protocol) pair.\n        \"\"\"\n        cdef:\n            AddrInfo ai_local = None\n            AddrInfo ai_remote\n            TCPTransport tr\n\n            system.addrinfo *rai = NULL\n            system.addrinfo *lai = NULL\n\n            system.addrinfo *rai_iter = NULL\n            system.addrinfo *lai_iter = NULL\n\n            system.addrinfo rai_static\n            system.sockaddr_storage rai_addr_static\n            system.addrinfo lai_static\n            system.sockaddr_storage lai_addr_static\n\n            object app_protocol\n            object app_transport\n            object protocol\n            object ssl_waiter\n\n        if sock is not None and sock.family == uv.AF_UNIX:\n            if host is not None or port is not None:\n                raise ValueError(\n                    'host/port and sock can not be specified at the same time')\n            return await self.create_unix_connection(\n                protocol_factory, None,\n                sock=sock, ssl=ssl, server_hostname=server_hostname)\n\n        app_protocol = protocol = protocol_factory()\n        ssl_waiter = None\n        context = Context_CopyCurrent()\n        if ssl:\n            if server_hostname is None:\n                if not host:\n                    raise ValueError('You must set server_hostname '\n                                     'when using ssl without a host')\n                server_hostname = host\n\n            ssl_waiter = self._new_future()\n            sslcontext = None if isinstance(ssl, bool) else ssl\n            protocol = SSLProtocol(\n                self, app_protocol, sslcontext, ssl_waiter,\n                False, server_hostname,\n                ssl_handshake_timeout=ssl_handshake_timeout,\n                ssl_shutdown_timeout=ssl_shutdown_timeout)\n        else:\n            if server_hostname is not None:\n                raise ValueError('server_hostname is only meaningful with ssl')\n            if ssl_handshake_timeout is not None:\n                raise ValueError(\n                    'ssl_handshake_timeout is only meaningful with ssl')\n            if ssl_shutdown_timeout is not None:\n                raise ValueError(\n                    'ssl_shutdown_timeout is only meaningful with ssl')\n\n        if host is not None or port is not None:\n            if sock is not None:\n                raise ValueError(\n                    'host/port and sock can not be specified at the same time')\n\n            fs = []\n            f1 = f2 = None\n\n            addr = __static_getaddrinfo(\n                host, port, family, uv.SOCK_STREAM,\n                proto, <system.sockaddr*>&rai_addr_static)\n\n            if addr is None:\n                f1 = self._getaddrinfo(\n                    host, port, family,\n                    uv.SOCK_STREAM, proto, flags,\n                    0)  # 0 == don't unpack\n\n                fs.append(f1)\n            else:\n                rai_static.ai_addr = <system.sockaddr*>&rai_addr_static\n                rai_static.ai_next = NULL\n                rai = &rai_static\n\n            if local_addr is not None:\n                if not isinstance(local_addr, (tuple, list)) or \\\n                        len(local_addr) != 2:\n                    raise ValueError(\n                        'local_addr must be a tuple of host and port')\n\n                addr = __static_getaddrinfo(\n                    local_addr[0], local_addr[1],\n                    family, uv.SOCK_STREAM,\n                    proto, <system.sockaddr*>&lai_addr_static)\n                if addr is None:\n                    f2 = self._getaddrinfo(\n                        local_addr[0], local_addr[1], family,\n                        uv.SOCK_STREAM, proto, flags,\n                        0)  # 0 == don't unpack\n\n                    fs.append(f2)\n                else:\n                    lai_static.ai_addr = <system.sockaddr*>&lai_addr_static\n                    lai_static.ai_next = NULL\n                    lai = &lai_static\n\n            if len(fs):\n                await aio_wait(fs)\n\n            if rai is NULL:\n                ai_remote = f1.result()\n                if ai_remote.data is NULL:\n                    raise OSError('getaddrinfo() returned empty list')\n                rai = ai_remote.data\n\n            if lai is NULL and f2 is not None:\n                ai_local = f2.result()\n                if ai_local.data is NULL:\n                    raise OSError(\n                        'getaddrinfo() returned empty list for local_addr')\n                lai = ai_local.data\n\n            exceptions = []\n            rai_iter = rai\n            while rai_iter is not NULL:\n                tr = None\n                try:\n                    waiter = self._new_future()\n                    tr = TCPTransport.new(self, protocol, None, waiter,\n                                          context)\n\n                    if lai is not NULL:\n                        lai_iter = lai\n                        while lai_iter is not NULL:\n                            try:\n                                tr.bind(lai_iter.ai_addr)\n                                break\n                            except OSError as exc:\n                                exceptions.append(exc)\n                            lai_iter = lai_iter.ai_next\n                        else:\n                            tr._close()\n                            tr = None\n\n                            rai_iter = rai_iter.ai_next\n                            continue\n\n                    tr.connect(rai_iter.ai_addr)\n                    await waiter\n\n                except OSError as exc:\n                    if tr is not None:\n                        tr._close()\n                        tr = None\n                    exceptions.append(exc)\n                except (KeyboardInterrupt, SystemExit):\n                    raise\n                except BaseException:\n                    if tr is not None:\n                        tr._close()\n                        tr = None\n                    raise\n                else:\n                    break\n\n                rai_iter = rai_iter.ai_next\n\n            else:\n                # If they all have the same str(), raise one.\n                model = str(exceptions[0])\n                if all(str(exc) == model for exc in exceptions):\n                    raise exceptions[0]\n                # Raise a combined exception so the user can see all\n                # the various error messages.\n                raise OSError('Multiple exceptions: {}'.format(\n                    ', '.join(str(exc) for exc in exceptions)))\n        else:\n            if sock is None:\n                raise ValueError(\n                    'host and port was not specified and no sock specified')\n            if not _is_sock_stream(sock.type):\n                raise ValueError(\n                    'A Stream Socket was expected, got {!r}'.format(sock))\n\n            # libuv will set the socket to non-blocking mode, but\n            # we want Python socket object to notice that.\n            sock.setblocking(False)\n\n            waiter = self._new_future()\n            tr = TCPTransport.new(self, protocol, None, waiter, context)\n            try:\n                # libuv will make socket non-blocking\n                tr._open(sock.fileno())\n                tr._init_protocol()\n                await waiter\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException:\n                # It's OK to call `_close()` here, as opposed to\n                # `_force_close()` or `close()` as we want to terminate the\n                # transport immediately.  The `waiter` can only be waken\n                # up in `Transport._call_connection_made()`, and calling\n                # `_close()` before it is fine.\n                tr._close()\n                raise\n\n            tr._attach_fileobj(sock)\n\n        if ssl:\n            app_transport = protocol._get_app_transport(context)\n            try:\n                await ssl_waiter\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException:\n                app_transport.close()\n                raise\n            return app_transport, app_protocol\n        else:\n            return tr, protocol\n\n    @cython.iterable_coroutine\n    async def create_unix_server(self, protocol_factory, path=None,\n                                 *, backlog=100, sock=None, ssl=None,\n                                 ssl_handshake_timeout=None,\n                                 ssl_shutdown_timeout=None,\n                                 start_serving=True, cleanup_socket=PY313):\n        \"\"\"A coroutine which creates a UNIX Domain Socket server.\n\n        The return value is a Server object, which can be used to stop\n        the service.\n\n        path is a str, representing a file systsem path to bind the\n        server socket to.\n\n        sock can optionally be specified in order to use a preexisting\n        socket object.\n\n        backlog is the maximum number of queued connections passed to\n        listen() (defaults to 100).\n\n        ssl can be set to an SSLContext to enable SSL over the\n        accepted connections.\n\n        ssl_handshake_timeout is the time in seconds that an SSL server\n        will wait for completion of the SSL handshake before aborting the\n        connection. Default is 60s.\n\n        ssl_shutdown_timeout is the time in seconds that an SSL server\n        will wait for completion of the SSL shutdown before aborting the\n        connection. Default is 30s.\n\n        If *cleanup_socket* is true then the Unix socket will automatically\n        be removed from the filesystem when the server is closed, unless the\n        socket has been replaced after the server has been created.\n        This defaults to True on Python 3.13 and above, or False otherwise.\n        \"\"\"\n        cdef:\n            UnixServer pipe\n            Server server = Server(self)\n\n        if ssl is not None:\n            if not isinstance(ssl, ssl_SSLContext):\n                raise TypeError('ssl argument must be an SSLContext or None')\n        else:\n            if ssl_handshake_timeout is not None:\n                raise ValueError(\n                    'ssl_handshake_timeout is only meaningful with ssl')\n            if ssl_shutdown_timeout is not None:\n                raise ValueError(\n                    'ssl_shutdown_timeout is only meaningful with ssl')\n\n        if path is not None:\n            if sock is not None:\n                raise ValueError(\n                    'path and sock can not be specified at the same time')\n            orig_path = path\n\n            path = os_fspath(path)\n\n            if isinstance(path, str):\n                path = PyUnicode_EncodeFSDefault(path)\n\n            # Check for abstract socket.\n            if path[0] != 0:\n                try:\n                    if stat_S_ISSOCK(os_stat(path).st_mode):\n                        os_remove(path)\n                except FileNotFoundError:\n                    pass\n                except OSError as err:\n                    # Directory may have permissions only to create socket.\n                    aio_logger.error(\n                        'Unable to check or remove stale UNIX socket %r: %r',\n                        orig_path, err)\n\n            # We use Python sockets to create a UNIX server socket because\n            # when UNIX sockets are created by libuv, libuv removes the path\n            # they were bound to.  This is different from asyncio, which\n            # doesn't cleanup the socket path.\n            sock = socket_socket(uv.AF_UNIX)\n\n            try:\n                sock.bind(path)\n            except OSError as exc:\n                sock.close()\n                if exc.errno == errno.EADDRINUSE:\n                    # Let's improve the error message by adding\n                    # with what exact address it occurs.\n                    msg = 'Address {!r} is already in use'.format(orig_path)\n                    raise OSError(errno.EADDRINUSE, msg) from None\n                else:\n                    raise\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException:\n                sock.close()\n                raise\n\n        else:\n            if sock is None:\n                raise ValueError(\n                    'path was not specified, and no sock specified')\n\n            if sock.family != uv.AF_UNIX or not _is_sock_stream(sock.type):\n                raise ValueError(\n                    'A UNIX Domain Stream Socket was expected, got {!r}'\n                    .format(sock))\n\n            # libuv will set the socket to non-blocking mode, but\n            # we want Python socket object to notice that.\n            sock.setblocking(False)\n\n        if cleanup_socket:\n            path = sock.getsockname()\n            # Check for abstract socket. `str` and `bytes` paths are supported.\n            if path[0] not in (0, '\\x00'):\n                try:\n                    self._unix_server_sockets[sock] = os_stat(path).st_ino\n                except FileNotFoundError:\n                    pass\n\n        pipe = UnixServer.new(\n            self, protocol_factory, server, backlog,\n            ssl, ssl_handshake_timeout, ssl_shutdown_timeout)\n\n        try:\n            pipe._open(sock.fileno())\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException:\n            pipe._close()\n            sock.close()\n            raise\n\n        pipe._attach_fileobj(sock)\n        server._add_server(pipe)\n\n        if start_serving:\n            server._start_serving()\n\n        return server\n\n    @cython.iterable_coroutine\n    async def create_unix_connection(self, protocol_factory, path=None, *,\n                                     ssl=None, sock=None,\n                                     server_hostname=None,\n                                     ssl_handshake_timeout=None,\n                                     ssl_shutdown_timeout=None):\n\n        cdef:\n            UnixTransport tr\n            object app_protocol\n            object app_transport\n            object protocol\n            object ssl_waiter\n\n        app_protocol = protocol = protocol_factory()\n        ssl_waiter = None\n        context = Context_CopyCurrent()\n        if ssl:\n            if server_hostname is None:\n                raise ValueError('You must set server_hostname '\n                                 'when using ssl without a host')\n\n            ssl_waiter = self._new_future()\n            sslcontext = None if isinstance(ssl, bool) else ssl\n            protocol = SSLProtocol(\n                self, app_protocol, sslcontext, ssl_waiter,\n                False, server_hostname,\n                ssl_handshake_timeout=ssl_handshake_timeout,\n                ssl_shutdown_timeout=ssl_shutdown_timeout)\n        else:\n            if server_hostname is not None:\n                raise ValueError('server_hostname is only meaningful with ssl')\n            if ssl_handshake_timeout is not None:\n                raise ValueError(\n                    'ssl_handshake_timeout is only meaningful with ssl')\n            if ssl_shutdown_timeout is not None:\n                raise ValueError(\n                    'ssl_shutdown_timeout is only meaningful with ssl')\n\n        if path is not None:\n            if sock is not None:\n                raise ValueError(\n                    'path and sock can not be specified at the same time')\n\n            path = os_fspath(path)\n\n            if isinstance(path, str):\n                path = PyUnicode_EncodeFSDefault(path)\n\n            waiter = self._new_future()\n            tr = UnixTransport.new(self, protocol, None, waiter, context)\n            tr.connect(path)\n            try:\n                await waiter\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException:\n                tr._close()\n                raise\n\n        else:\n            if sock is None:\n                raise ValueError('no path and sock were specified')\n\n            if sock.family != uv.AF_UNIX or not _is_sock_stream(sock.type):\n                raise ValueError(\n                    'A UNIX Domain Stream Socket was expected, got {!r}'\n                    .format(sock))\n\n            # libuv will set the socket to non-blocking mode, but\n            # we want Python socket object to notice that.\n            sock.setblocking(False)\n\n            waiter = self._new_future()\n            tr = UnixTransport.new(self, protocol, None, waiter, context)\n            try:\n                tr._open(sock.fileno())\n                tr._init_protocol()\n                await waiter\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException:\n                tr._close()\n                raise\n\n            tr._attach_fileobj(sock)\n\n        if ssl:\n            app_transport = protocol._get_app_transport(Context_CopyCurrent())\n            try:\n                await ssl_waiter\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException:\n                app_transport.close()\n                raise\n            return app_transport, app_protocol\n        else:\n            return tr, protocol\n\n    def default_exception_handler(self, context):\n        \"\"\"Default exception handler.\n\n        This is called when an exception occurs and no exception\n        handler is set, and can be called by a custom exception\n        handler that wants to defer to the default behavior.\n\n        The context parameter has the same meaning as in\n        `call_exception_handler()`.\n        \"\"\"\n        message = context.get('message')\n        if not message:\n            message = 'Unhandled exception in event loop'\n\n        exception = context.get('exception')\n        if exception is not None:\n            exc_info = (type(exception), exception, exception.__traceback__)\n        else:\n            exc_info = False\n\n        log_lines = [message]\n        for key in sorted(context):\n            if key in {'message', 'exception'}:\n                continue\n            value = context[key]\n            if key == 'source_traceback':\n                tb = ''.join(tb_format_list(value))\n                value = 'Object created at (most recent call last):\\n'\n                value += tb.rstrip()\n            else:\n                try:\n                    value = repr(value)\n                except (KeyboardInterrupt, SystemExit):\n                    raise\n                except BaseException as ex:\n                    value = ('Exception in __repr__ {!r}; '\n                             'value type: {!r}'.format(ex, type(value)))\n            log_lines.append('{}: {}'.format(key, value))\n\n        aio_logger.error('\\n'.join(log_lines), exc_info=exc_info)\n\n    def get_exception_handler(self):\n        \"\"\"Return an exception handler, or None if the default one is in use.\n        \"\"\"\n        return self._exception_handler\n\n    def set_exception_handler(self, handler):\n        \"\"\"Set handler as the new event loop exception handler.\n\n        If handler is None, the default exception handler will\n        be set.\n\n        If handler is a callable object, it should have a\n        signature matching '(loop, context)', where 'loop'\n        will be a reference to the active event loop, 'context'\n        will be a dict object (see `call_exception_handler()`\n        documentation for details about context).\n        \"\"\"\n        if handler is not None and not callable(handler):\n            raise TypeError('A callable object or None is expected, '\n                            'got {!r}'.format(handler))\n        self._exception_handler = handler\n\n    def call_exception_handler(self, context):\n        \"\"\"Call the current event loop's exception handler.\n\n        The context argument is a dict containing the following keys:\n\n        - 'message': Error message;\n        - 'exception' (optional): Exception object;\n        - 'future' (optional): Future instance;\n        - 'handle' (optional): Handle instance;\n        - 'protocol' (optional): Protocol instance;\n        - 'transport' (optional): Transport instance;\n        - 'socket' (optional): Socket instance.\n\n        New keys maybe introduced in the future.\n\n        Note: do not overload this method in an event loop subclass.\n        For custom exception handling, use the\n        `set_exception_handler()` method.\n        \"\"\"\n        if UVLOOP_DEBUG:\n            self._debug_exception_handler_cnt += 1\n\n        if self._exception_handler is None:\n            try:\n                self.default_exception_handler(context)\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException:\n                # Second protection layer for unexpected errors\n                # in the default implementation, as well as for subclassed\n                # event loops with overloaded \"default_exception_handler\".\n                aio_logger.error('Exception in default exception handler',\n                                 exc_info=True)\n        else:\n            try:\n                self._exception_handler(self, context)\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException as exc:\n                # Exception in the user set custom exception handler.\n                try:\n                    # Let's try default handler.\n                    self.default_exception_handler({\n                        'message': 'Unhandled error in exception handler',\n                        'exception': exc,\n                        'context': context,\n                    })\n                except (KeyboardInterrupt, SystemExit):\n                    raise\n                except BaseException:\n                    # Guard 'default_exception_handler' in case it is\n                    # overloaded.\n                    aio_logger.error('Exception in default exception handler '\n                                     'while handling an unexpected error '\n                                     'in custom exception handler',\n                                     exc_info=True)\n\n    def add_reader(self, fileobj, callback, *args):\n        \"\"\"Add a reader callback.\"\"\"\n        if len(args) == 0:\n            args = None\n        self._add_reader(fileobj, new_Handle(self, callback, args, None))\n\n    def remove_reader(self, fileobj):\n        \"\"\"Remove a reader callback.\"\"\"\n        self._remove_reader(fileobj)\n\n    def add_writer(self, fileobj, callback, *args):\n        \"\"\"Add a writer callback..\"\"\"\n        if len(args) == 0:\n            args = None\n        self._add_writer(fileobj, new_Handle(self, callback, args, None))\n\n    def remove_writer(self, fileobj):\n        \"\"\"Remove a writer callback.\"\"\"\n        self._remove_writer(fileobj)\n\n    @cython.iterable_coroutine\n    async def sock_recv(self, sock, n):\n        \"\"\"Receive data from the socket.\n\n        The return value is a bytes object representing the data received.\n        The maximum amount of data to be received at once is specified by\n        nbytes.\n\n        This method is a coroutine.\n        \"\"\"\n        cdef:\n            Handle handle\n\n        if self._debug and sock.gettimeout() != 0:\n            raise ValueError(\"the socket must be non-blocking\")\n\n        fut = _SyncSocketReaderFuture(sock, self)\n        handle = new_MethodHandle3(\n            self,\n            \"Loop._sock_recv\",\n            <method3_t>self._sock_recv,\n            None,\n            self,\n            fut, sock, n)\n\n        self._add_reader(sock, handle)\n        return await fut\n\n    @cython.iterable_coroutine\n    async def sock_recv_into(self, sock, buf):\n        \"\"\"Receive data from the socket.\n\n        The received data is written into *buf* (a writable buffer).\n        The return value is the number of bytes written.\n\n        This method is a coroutine.\n        \"\"\"\n        cdef:\n            Handle handle\n\n        if self._debug and sock.gettimeout() != 0:\n            raise ValueError(\"the socket must be non-blocking\")\n\n        fut = _SyncSocketReaderFuture(sock, self)\n        handle = new_MethodHandle3(\n            self,\n            \"Loop._sock_recv_into\",\n            <method3_t>self._sock_recv_into,\n            None,\n            self,\n            fut, sock, buf)\n\n        self._add_reader(sock, handle)\n        return await fut\n\n    @cython.iterable_coroutine\n    async def sock_sendall(self, sock, data):\n        \"\"\"Send data to the socket.\n\n        The socket must be connected to a remote socket. This method continues\n        to send data from data until either all data has been sent or an\n        error occurs. None is returned on success. On error, an exception is\n        raised, and there is no way to determine how much data, if any, was\n        successfully processed by the receiving end of the connection.\n\n        This method is a coroutine.\n        \"\"\"\n        cdef:\n            Handle handle\n            ssize_t n\n\n        if self._debug and sock.gettimeout() != 0:\n            raise ValueError(\"the socket must be non-blocking\")\n\n        if not data:\n            return\n\n        socket_inc_io_ref(sock)\n        try:\n            try:\n                n = sock.send(data)\n            except (BlockingIOError, InterruptedError):\n                pass\n            else:\n                if UVLOOP_DEBUG:\n                    # This can be a partial success, i.e. only part\n                    # of the data was sent\n                    self._sock_try_write_total += 1\n\n                if n == len(data):\n                    return\n                if not isinstance(data, memoryview):\n                    data = memoryview(data)\n                data = data[n:]\n\n            fut = _SyncSocketWriterFuture(sock, self)\n            handle = new_MethodHandle3(\n                self,\n                \"Loop._sock_sendall\",\n                <method3_t>self._sock_sendall,\n                None,\n                self,\n                fut, sock, data)\n\n            self._add_writer(sock, handle)\n            return await fut\n        finally:\n            socket_dec_io_ref(sock)\n\n    @cython.iterable_coroutine\n    async def sock_accept(self, sock):\n        \"\"\"Accept a connection.\n\n        The socket must be bound to an address and listening for connections.\n        The return value is a pair (conn, address) where conn is a new socket\n        object usable to send and receive data on the connection, and address\n        is the address bound to the socket on the other end of the connection.\n\n        This method is a coroutine.\n        \"\"\"\n        cdef:\n            Handle handle\n\n        if self._debug and sock.gettimeout() != 0:\n            raise ValueError(\"the socket must be non-blocking\")\n\n        fut = _SyncSocketReaderFuture(sock, self)\n        handle = new_MethodHandle2(\n            self,\n            \"Loop._sock_accept\",\n            <method2_t>self._sock_accept,\n            None,\n            self,\n            fut, sock)\n\n        self._add_reader(sock, handle)\n        return await fut\n\n    @cython.iterable_coroutine\n    async def sock_connect(self, sock, address):\n        \"\"\"Connect to a remote socket at address.\n\n        This method is a coroutine.\n        \"\"\"\n        if self._debug and sock.gettimeout() != 0:\n            raise ValueError(\"the socket must be non-blocking\")\n\n        socket_inc_io_ref(sock)\n        try:\n            if sock.family == uv.AF_UNIX:\n                fut = self._sock_connect(sock, address)\n            else:\n                addrs = await self.getaddrinfo(\n                    *address[:2], family=sock.family)\n\n                _, _, _, _, address = addrs[0]\n                fut = self._sock_connect(sock, address)\n            if fut is not None:\n                await fut\n        finally:\n            socket_dec_io_ref(sock)\n\n    @cython.iterable_coroutine\n    async def sock_recvfrom(self, sock, bufsize):\n        raise NotImplementedError\n\n    @cython.iterable_coroutine\n    async def sock_recvfrom_into(self, sock, buf, nbytes=0):\n        raise NotImplementedError\n\n    @cython.iterable_coroutine\n    async def sock_sendto(self, sock, data, address):\n        raise NotImplementedError\n\n    @cython.iterable_coroutine\n    async def connect_accepted_socket(self, protocol_factory, sock, *,\n                                      ssl=None,\n                                      ssl_handshake_timeout=None,\n                                      ssl_shutdown_timeout=None):\n        \"\"\"Handle an accepted connection.\n\n        This is used by servers that accept connections outside of\n        asyncio but that use asyncio to handle connections.\n\n        This method is a coroutine.  When completed, the coroutine\n        returns a (transport, protocol) pair.\n        \"\"\"\n\n        cdef:\n            UVStream transport = None\n\n        if ssl is not None:\n            if not isinstance(ssl, ssl_SSLContext):\n                raise TypeError('ssl argument must be an SSLContext or None')\n        else:\n            if ssl_handshake_timeout is not None:\n                raise ValueError(\n                    'ssl_handshake_timeout is only meaningful with ssl')\n            if ssl_shutdown_timeout is not None:\n                raise ValueError(\n                    'ssl_shutdown_timeout is only meaningful with ssl')\n\n        if not _is_sock_stream(sock.type):\n            raise ValueError(\n                'A Stream Socket was expected, got {!r}'.format(sock))\n\n        app_protocol = protocol_factory()\n        waiter = self._new_future()\n        transport_waiter = None\n        context = Context_CopyCurrent()\n\n        if ssl is None:\n            protocol = app_protocol\n            transport_waiter = waiter\n        else:\n            protocol = SSLProtocol(\n                self, app_protocol, ssl, waiter,\n                server_side=True,\n                server_hostname=None,\n                ssl_handshake_timeout=ssl_handshake_timeout,\n                ssl_shutdown_timeout=ssl_shutdown_timeout)\n            transport_waiter = None\n\n        if sock.family == uv.AF_UNIX:\n            transport = <UVStream>UnixTransport.new(\n                self, protocol, None, transport_waiter, context)\n        elif sock.family in (uv.AF_INET, uv.AF_INET6):\n            transport = <UVStream>TCPTransport.new(\n                self, protocol, None, transport_waiter, context)\n\n        if transport is None:\n            raise ValueError(\n                'invalid socket family, expected AF_UNIX, AF_INET or AF_INET6')\n\n        transport._open(sock.fileno())\n        transport._init_protocol()\n        transport._attach_fileobj(sock)\n\n        if ssl:\n            app_transport = protocol._get_app_transport(context)\n            try:\n                await waiter\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException:\n                app_transport.close()\n                raise\n            return app_transport, protocol\n        else:\n            try:\n                await waiter\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException:\n                transport._close()\n                raise\n            return transport, protocol\n\n    def run_in_executor(self, executor, func, *args):\n        if aio_iscoroutine(func) or inspect_iscoroutinefunction(func):\n            raise TypeError(\"coroutines cannot be used with run_in_executor()\")\n\n        self._check_closed()\n\n        if executor is None:\n            executor = self._default_executor\n            # Only check when the default executor is being used\n            self._check_default_executor()\n            if executor is None:\n                executor = cc_ThreadPoolExecutor()\n                self._default_executor = executor\n\n        return aio_wrap_future(executor.submit(func, *args), loop=self)\n\n    def set_default_executor(self, executor):\n        self._default_executor = executor\n\n    @cython.iterable_coroutine\n    async def __subprocess_run(self, protocol_factory, args,\n                               stdin=subprocess_PIPE,\n                               stdout=subprocess_PIPE,\n                               stderr=subprocess_PIPE,\n                               universal_newlines=False,\n                               shell=True,\n                               bufsize=0,\n                               preexec_fn=None,\n                               close_fds=None,\n                               cwd=None,\n                               env=None,\n                               startupinfo=None,\n                               creationflags=0,\n                               restore_signals=True,\n                               start_new_session=False,\n                               executable=None,\n                               pass_fds=(),\n                               **kwargs):\n\n        # TODO: Implement close_fds (might not be very important in\n        # Python 3.5, since all FDs aren't inheritable by default.)\n\n        cdef:\n            int debug_flags = 0\n\n        if universal_newlines:\n            raise ValueError(\"universal_newlines must be False\")\n        if bufsize != 0:\n            raise ValueError(\"bufsize must be 0\")\n        if startupinfo is not None:\n            raise ValueError('startupinfo is not supported')\n        if creationflags != 0:\n            raise ValueError('creationflags is not supported')\n\n        if executable is not None:\n            args[0] = executable\n\n        # For tests only! Do not use in your code. Ever.\n        if kwargs.pop(\"__uvloop_sleep_after_fork\", False):\n            debug_flags |= __PROCESS_DEBUG_SLEEP_AFTER_FORK\n        if kwargs:\n            raise ValueError(\n                'unexpected kwargs: {}'.format(', '.join(kwargs.keys())))\n\n        waiter = self._new_future()\n        protocol = protocol_factory()\n        proc = UVProcessTransport.new(self, protocol,\n                                      args, env, cwd, start_new_session,\n                                      stdin, stdout, stderr, pass_fds,\n                                      waiter,\n                                      debug_flags,\n                                      preexec_fn,\n                                      restore_signals)\n\n        try:\n            await waiter\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException:\n            proc.close()\n            raise\n\n        return proc, protocol\n\n    @cython.iterable_coroutine\n    async def subprocess_shell(self, protocol_factory, cmd, *,\n                               shell=True,\n                               **kwargs):\n\n        if not shell:\n            raise ValueError(\"shell must be True\")\n\n        args = [cmd]\n        if shell:\n            args = [b'/bin/sh', b'-c'] + args\n\n        return await self.__subprocess_run(protocol_factory, args, shell=True,\n                                           **kwargs)\n\n    @cython.iterable_coroutine\n    async def subprocess_exec(self, protocol_factory, program, *args,\n                              shell=False, **kwargs):\n\n        if shell:\n            raise ValueError(\"shell must be False\")\n\n        args = list((program,) + args)\n\n        return await self.__subprocess_run(protocol_factory, args, shell=False,\n                                           **kwargs)\n\n    @cython.iterable_coroutine\n    async def connect_read_pipe(self, proto_factory, pipe):\n        \"\"\"Register read pipe in event loop. Set the pipe to non-blocking mode.\n\n        protocol_factory should instantiate object with Protocol interface.\n        pipe is a file-like object.\n        Return pair (transport, protocol), where transport supports the\n        ReadTransport interface.\"\"\"\n        cdef:\n            ReadUnixTransport transp\n\n        waiter = self._new_future()\n        proto = proto_factory()\n        transp = ReadUnixTransport.new(self, proto, None, waiter)\n        transp._add_extra_info('pipe', pipe)\n        try:\n            transp._open(pipe.fileno())\n            transp._init_protocol()\n            await waiter\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException:\n            transp._close()\n            raise\n        transp._attach_fileobj(pipe)\n        return transp, proto\n\n    @cython.iterable_coroutine\n    async def connect_write_pipe(self, proto_factory, pipe):\n        \"\"\"Register write pipe in event loop.\n\n        protocol_factory should instantiate object with BaseProtocol interface.\n        Pipe is file-like object already switched to nonblocking.\n        Return pair (transport, protocol), where transport support\n        WriteTransport interface.\"\"\"\n        cdef:\n            WriteUnixTransport transp\n\n        waiter = self._new_future()\n        proto = proto_factory()\n        transp = WriteUnixTransport.new(self, proto, None, waiter)\n        transp._add_extra_info('pipe', pipe)\n        try:\n            transp._open(pipe.fileno())\n            transp._init_protocol()\n            await waiter\n        except (KeyboardInterrupt, SystemExit):\n            raise\n        except BaseException:\n            transp._close()\n            raise\n        transp._attach_fileobj(pipe)\n        return transp, proto\n\n    def add_signal_handler(self, sig, callback, *args):\n        \"\"\"Add a handler for a signal.  UNIX only.\n\n        Raise ValueError if the signal number is invalid or uncatchable.\n        Raise RuntimeError if there is a problem setting up the handler.\n        \"\"\"\n        cdef:\n            Handle h\n\n        if not self._is_main_thread():\n            raise ValueError(\n                'add_signal_handler() can only be called from '\n                'the main thread')\n\n        if (aio_iscoroutine(callback)\n                or inspect_iscoroutinefunction(callback)):\n            raise TypeError(\n                \"coroutines cannot be used with add_signal_handler()\")\n\n        if sig == uv.SIGCHLD:\n            if (hasattr(callback, '__self__') and\n                    isinstance(callback.__self__, aio_AbstractChildWatcher)):\n\n                warnings_warn(\n                    \"!!! asyncio is trying to install its ChildWatcher for \"\n                    \"SIGCHLD signal !!!\\n\\nThis is probably because a uvloop \"\n                    \"instance is used with asyncio.set_event_loop(). \"\n                    \"The correct way to use uvloop is to install its policy: \"\n                    \"`asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())`\"\n                    \"\\n\\n\", RuntimeWarning, source=self)\n\n                # TODO: ideally we should always raise an error here,\n                # but that would be a backwards incompatible change,\n                # because we recommended using \"asyncio.set_event_loop()\"\n                # in our README.  Need to start a deprecation period\n                # at some point to turn this warning into an error.\n                return\n\n            raise RuntimeError(\n                'cannot add a signal handler for SIGCHLD: it is used '\n                'by the event loop to track subprocesses')\n\n        self._check_signal(sig)\n        self._check_closed()\n\n        h = new_Handle(self, callback, args or None, None)\n        self._signal_handlers[sig] = h\n\n        try:\n            # Register a dummy signal handler to ask Python to write the signal\n            # number in the wakeup file descriptor.\n            signal_signal(sig, self.__sighandler)\n\n            # Set SA_RESTART to limit EINTR occurrences.\n            signal_siginterrupt(sig, False)\n        except OSError as exc:\n            del self._signal_handlers[sig]\n            if not self._signal_handlers:\n                try:\n                    signal_set_wakeup_fd(-1)\n                except (ValueError, OSError) as nexc:\n                    aio_logger.info('set_wakeup_fd(-1) failed: %s', nexc)\n\n            if exc.errno == errno_EINVAL:\n                raise RuntimeError('sig {} cannot be caught'.format(sig))\n            else:\n                raise\n\n    def remove_signal_handler(self, sig):\n        \"\"\"Remove a handler for a signal.  UNIX only.\n\n        Return True if a signal handler was removed, False if not.\n        \"\"\"\n\n        if not self._is_main_thread():\n            raise ValueError(\n                'remove_signal_handler() can only be called from '\n                'the main thread')\n\n        self._check_signal(sig)\n\n        if not self._listening_signals:\n            return False\n\n        try:\n            del self._signal_handlers[sig]\n        except KeyError:\n            return False\n\n        if sig == uv.SIGINT:\n            handler = signal_default_int_handler\n        else:\n            handler = signal_SIG_DFL\n\n        try:\n            signal_signal(sig, handler)\n        except OSError as exc:\n            if exc.errno == errno_EINVAL:\n                raise RuntimeError('sig {} cannot be caught'.format(sig))\n            else:\n                raise\n\n        return True\n\n    @cython.iterable_coroutine\n    async def create_datagram_endpoint(self, protocol_factory,\n                                       local_addr=None, remote_addr=None, *,\n                                       family=0, proto=0, flags=0,\n                                       reuse_address=_unset, reuse_port=None,\n                                       allow_broadcast=None, sock=None):\n        \"\"\"A coroutine which creates a datagram endpoint.\n\n        This method will try to establish the endpoint in the background.\n        When successful, the coroutine returns a (transport, protocol) pair.\n\n        protocol_factory must be a callable returning a protocol instance.\n\n        socket family AF_INET or socket.AF_INET6 depending on host (or\n        family if specified), socket type SOCK_DGRAM.\n\n        reuse_port tells the kernel to allow this endpoint to be bound to\n        the same port as other existing endpoints are bound to, so long as\n        they all set this flag when being created. This option is not\n        supported on Windows and some UNIX's. If the\n        :py:data:`~socket.SO_REUSEPORT` constant is not defined then this\n        capability is unsupported.\n\n        allow_broadcast tells the kernel to allow this endpoint to send\n        messages to the broadcast address.\n\n        sock can optionally be specified in order to use a preexisting\n        socket object.\n        \"\"\"\n        cdef:\n            UDPTransport udp = None\n            system.addrinfo * lai\n            system.addrinfo * rai\n\n        if sock is not None:\n            if not _is_sock_dgram(sock.type):\n                raise ValueError(\n                    'A UDP Socket was expected, got {!r}'.format(sock))\n            if (local_addr or remote_addr or\n                    family or proto or flags or\n                    reuse_port or allow_broadcast):\n                # show the problematic kwargs in exception msg\n                opts = dict(local_addr=local_addr, remote_addr=remote_addr,\n                            family=family, proto=proto, flags=flags,\n                            reuse_address=reuse_address, reuse_port=reuse_port,\n                            allow_broadcast=allow_broadcast)\n                problems = ', '.join(\n                    '{}={}'.format(k, v) for k, v in opts.items() if v)\n                raise ValueError(\n                    'socket modifier keyword arguments can not be used '\n                    'when sock is specified. ({})'.format(problems))\n            sock.setblocking(False)\n            udp = UDPTransport.__new__(UDPTransport)\n            udp._init(self, uv.AF_UNSPEC)\n            udp.open(sock.family, sock.fileno())\n            udp._attach_fileobj(sock)\n        else:\n            if reuse_address is not _unset:\n                if reuse_address:\n                    raise ValueError(\"Passing `reuse_address=True` is no \"\n                                     \"longer supported, as the usage of \"\n                                     \"SO_REUSEPORT in UDP poses a significant \"\n                                     \"security concern.\")\n                else:\n                    warnings_warn(\"The *reuse_address* parameter has been \"\n                                  \"deprecated as of 0.15.\", DeprecationWarning,\n                                  stacklevel=2)\n            reuse_port = bool(reuse_port)\n            if reuse_port and not has_SO_REUSEPORT:\n                raise ValueError(\n                    'reuse_port not supported by socket module')\n\n            lads = None\n            if local_addr is not None:\n                if (not isinstance(local_addr, (tuple, list)) or\n                        len(local_addr) != 2):\n                    raise TypeError(\n                        'local_addr must be a tuple of (host, port)')\n                lads = await self._getaddrinfo(\n                    local_addr[0], local_addr[1],\n                    family, uv.SOCK_DGRAM, proto, flags,\n                    0)\n\n            rads = None\n            if remote_addr is not None:\n                if (not isinstance(remote_addr, (tuple, list)) or\n                        len(remote_addr) != 2):\n                    raise TypeError(\n                        'remote_addr must be a tuple of (host, port)')\n                rads = await self._getaddrinfo(\n                    remote_addr[0], remote_addr[1],\n                    family, uv.SOCK_DGRAM, proto, flags,\n                    0)\n\n            excs = []\n            if lads is None:\n                if rads is not None:\n                    udp = UDPTransport.__new__(UDPTransport)\n                    rai = (<AddrInfo>rads).data\n                    udp._init(self, rai.ai_family)\n                    udp._connect(rai.ai_addr, rai.ai_addrlen)\n                    udp._set_address(rai)\n                else:\n                    if family not in (uv.AF_INET, uv.AF_INET6):\n                        raise ValueError('unexpected address family')\n                    udp = UDPTransport.__new__(UDPTransport)\n                    udp._init(self, family)\n\n                if reuse_port:\n                    self._sock_set_reuseport(udp._fileno())\n\n            else:\n                lai = (<AddrInfo>lads).data\n                while lai is not NULL:\n                    try:\n                        udp = UDPTransport.__new__(UDPTransport)\n                        udp._init(self, lai.ai_family)\n                        if reuse_port:\n                            self._sock_set_reuseport(udp._fileno())\n                        udp._bind(lai.ai_addr)\n                    except (KeyboardInterrupt, SystemExit):\n                        raise\n                    except BaseException as ex:\n                        lai = lai.ai_next\n                        excs.append(ex)\n                        continue\n                    else:\n                        break\n                else:\n                    ctx = None\n                    if len(excs):\n                        ctx = excs[0]\n                    raise OSError('could not bind to local_addr {}'.format(\n                        local_addr)) from ctx\n\n                if rads is not None:\n                    rai = (<AddrInfo>rads).data\n                    while rai is not NULL:\n                        if rai.ai_family != lai.ai_family:\n                            rai = rai.ai_next\n                            continue\n                        if rai.ai_protocol != lai.ai_protocol:\n                            rai = rai.ai_next\n                            continue\n                        udp._connect(rai.ai_addr, rai.ai_addrlen)\n                        udp._set_address(rai)\n                        break\n                    else:\n                        raise OSError(\n                            'could not bind to remote_addr {}'.format(\n                                remote_addr))\n\n        if allow_broadcast:\n            udp._set_broadcast(1)\n\n        protocol = protocol_factory()\n        waiter = self._new_future()\n        assert udp is not None\n        udp._set_protocol(protocol)\n        udp._set_waiter(waiter)\n        udp._init_protocol()\n\n        await waiter\n        return udp, protocol\n\n    def _monitor_fs(self, path: str, callback) -> asyncio.Handle:\n        cdef:\n            UVFSEvent fs_handle\n            char* c_str_path\n\n        self._check_closed()\n        fs_handle = UVFSEvent.new(self, callback, None)\n        p_bytes = path.encode('UTF-8')\n        c_str_path = p_bytes\n        flags = 0\n        fs_handle.start(c_str_path, flags)\n        return fs_handle\n\n    def _check_default_executor(self):\n        if self._executor_shutdown_called:\n            raise RuntimeError('Executor shutdown has been called')\n\n    def _asyncgen_finalizer_hook(self, agen):\n        self._asyncgens.discard(agen)\n        if not self.is_closed():\n            self.call_soon_threadsafe(self.create_task, agen.aclose())\n\n    def _asyncgen_firstiter_hook(self, agen):\n        if self._asyncgens_shutdown_called:\n            warnings_warn(\n                \"asynchronous generator {!r} was scheduled after \"\n                \"loop.shutdown_asyncgens() call\".format(agen),\n                ResourceWarning, source=self)\n\n        self._asyncgens.add(agen)\n\n    @cython.iterable_coroutine\n    async def shutdown_asyncgens(self):\n        \"\"\"Shutdown all active asynchronous generators.\"\"\"\n        self._asyncgens_shutdown_called = True\n\n        if not len(self._asyncgens):\n            return\n\n        closing_agens = list(self._asyncgens)\n        self._asyncgens.clear()\n\n        shutdown_coro = aio_gather(\n            *[ag.aclose() for ag in closing_agens],\n            return_exceptions=True)\n\n        results = await shutdown_coro\n        for result, agen in zip(results, closing_agens):\n            if isinstance(result, Exception):\n                self.call_exception_handler({\n                    'message': 'an error occurred during closing of '\n                               'asynchronous generator {!r}'.format(agen),\n                    'exception': result,\n                    'asyncgen': agen\n                })\n\n    @cython.iterable_coroutine\n    async def shutdown_default_executor(self, timeout=None):\n        \"\"\"Schedule the shutdown of the default executor.\n\n        The timeout parameter specifies the amount of time the executor will\n        be given to finish joining. The default value is None, which means\n        that the executor will be given an unlimited amount of time.\n        \"\"\"\n        self._executor_shutdown_called = True\n        if self._default_executor is None:\n            return\n        future = self.create_future()\n        thread = threading_Thread(target=self._do_shutdown, args=(future,))\n        thread.start()\n        try:\n            await future\n        finally:\n            thread.join(timeout)\n\n        if thread.is_alive():\n            warnings_warn(\n                \"The executor did not finishing joining \"\n                f\"its threads within {timeout} seconds.\",\n                RuntimeWarning,\n                stacklevel=2\n            )\n            self._default_executor.shutdown(wait=False)\n\n    def _do_shutdown(self, future):\n        try:\n            self._default_executor.shutdown(wait=True)\n            self.call_soon_threadsafe(future.set_result, None)\n        except Exception as ex:\n            self.call_soon_threadsafe(future.set_exception, ex)\n\n\n# Expose pointer for integration with other C-extensions\ndef libuv_get_loop_t_ptr(loop):\n    return PyCapsule_New(<void *>(<Loop>loop).uvloop, NULL, NULL)\n\n\ndef libuv_get_version():\n    return uv.uv_version()\n\n\ndef _testhelper_unwrap_capsuled_pointer(obj):\n    return <uint64_t>PyCapsule_GetPointer(obj, NULL)\n\n\ncdef void __loop_alloc_buffer(\n    uv.uv_handle_t* uvhandle,\n    size_t suggested_size,\n    uv.uv_buf_t* buf\n) noexcept with gil:\n    cdef:\n        Loop loop = (<UVHandle>uvhandle.data)._loop\n\n    if loop._recv_buffer_in_use == 1:\n        buf.len = 0\n        exc = RuntimeError('concurrent allocations')\n        loop._handle_exception(exc)\n        return\n\n    loop._recv_buffer_in_use = 1\n    buf.base = loop._recv_buffer\n    buf.len = sizeof(loop._recv_buffer)\n\n\ncdef inline void __loop_free_buffer(Loop loop):\n    loop._recv_buffer_in_use = 0\n\n\nclass _SyncSocketReaderFuture(aio_Future):\n\n    def __init__(self, sock, loop):\n        aio_Future.__init__(self, loop=loop)\n        self.__sock = sock\n        self.__loop = loop\n\n    def __remove_reader(self):\n        if self.__sock is not None and self.__sock.fileno() != -1:\n            self.__loop.remove_reader(self.__sock)\n            self.__sock = None\n\n    if PY39:\n        def cancel(self, msg=None):\n            self.__remove_reader()\n            aio_Future.cancel(self, msg=msg)\n\n    else:\n        def cancel(self):\n            self.__remove_reader()\n            aio_Future.cancel(self)\n\n\nclass _SyncSocketWriterFuture(aio_Future):\n\n    def __init__(self, sock, loop):\n        aio_Future.__init__(self, loop=loop)\n        self.__sock = sock\n        self.__loop = loop\n\n    def __remove_writer(self):\n        if self.__sock is not None and self.__sock.fileno() != -1:\n            self.__loop.remove_writer(self.__sock)\n            self.__sock = None\n\n    if PY39:\n        def cancel(self, msg=None):\n            self.__remove_writer()\n            aio_Future.cancel(self, msg=msg)\n\n    else:\n        def cancel(self):\n            self.__remove_writer()\n            aio_Future.cancel(self)\n\n\ninclude \"cbhandles.pyx\"\ninclude \"pseudosock.pyx\"\ninclude \"lru.pyx\"\n\ninclude \"handles/handle.pyx\"\ninclude \"handles/async_.pyx\"\ninclude \"handles/idle.pyx\"\ninclude \"handles/check.pyx\"\ninclude \"handles/timer.pyx\"\ninclude \"handles/poll.pyx\"\ninclude \"handles/basetransport.pyx\"\ninclude \"handles/stream.pyx\"\ninclude \"handles/streamserver.pyx\"\ninclude \"handles/tcp.pyx\"\ninclude \"handles/pipe.pyx\"\ninclude \"handles/process.pyx\"\ninclude \"handles/fsevent.pyx\"\n\ninclude \"request.pyx\"\ninclude \"dns.pyx\"\ninclude \"sslproto.pyx\"\n\ninclude \"handles/udp.pyx\"\n\ninclude \"server.pyx\"\n\n\n# Used in UVProcess\ncdef vint __atfork_installed = 0\ncdef vint __forking = 0\ncdef Loop __forking_loop = None\n\n\ncdef void __get_fork_handler() noexcept nogil:\n    with gil:\n        if (__forking and __forking_loop is not None and\n                __forking_loop.active_process_handler is not None):\n            __forking_loop.active_process_handler._after_fork()\n\ncdef __install_atfork():\n    global __atfork_installed\n\n    if __atfork_installed:\n        return\n    __atfork_installed = 1\n\n    cdef int err\n\n    err = system.pthread_atfork(NULL, NULL, &system.handleAtFork)\n    if err:\n        __atfork_installed = 0\n        raise convert_error(-err)\n\n\n# Install PyMem* memory allocators\ncdef vint __mem_installed = 0\ncdef __install_pymem():\n    global __mem_installed\n    if __mem_installed:\n        return\n    __mem_installed = 1\n\n    cdef int err\n    err = uv.uv_replace_allocator(<uv.uv_malloc_func>PyMem_RawMalloc,\n                                  <uv.uv_realloc_func>PyMem_RawRealloc,\n                                  <uv.uv_calloc_func>PyMem_RawCalloc,\n                                  <uv.uv_free_func>PyMem_RawFree)\n    if err < 0:\n        __mem_installed = 0\n        raise convert_error(err)\n\n\ncdef _set_signal_wakeup_fd(fd):\n    if fd >= 0:\n        return signal_set_wakeup_fd(fd, warn_on_full_buffer=False)\n    else:\n        return signal_set_wakeup_fd(fd)\n\n\n# Helpers for tests\n\n@cython.iterable_coroutine\nasync def _test_coroutine_1():\n    return 42\n"
  },
  {
    "path": "uvloop/lru.pyx",
    "content": "cdef object _LRU_MARKER = object()\n\n\n@cython.final\ncdef class LruCache:\n\n    cdef:\n        object _dict\n        int _maxsize\n        object _dict_move_to_end\n        object _dict_get\n\n    # We use an OrderedDict for LRU implementation.  Operations:\n    #\n    # * We use a simple `__setitem__` to push a new entry:\n    #       `entries[key] = new_entry`\n    #   That will push `new_entry` to the *end* of the entries dict.\n    #\n    # * When we have a cache hit, we call\n    #       `entries.move_to_end(key, last=True)`\n    #   to move the entry to the *end* of the entries dict.\n    #\n    # * When we need to remove entries to maintain `max_size`, we call\n    #       `entries.popitem(last=False)`\n    #   to remove an entry from the *beginning* of the entries dict.\n    #\n    # So new entries and hits are always promoted to the end of the\n    # entries dict, whereas the unused one will group in the\n    # beginning of it.\n\n    def __init__(self, *, maxsize):\n        if maxsize <= 0:\n            raise ValueError(\n                f'maxsize is expected to be greater than 0, got {maxsize}')\n\n        self._dict = col_OrderedDict()\n        self._dict_move_to_end = self._dict.move_to_end\n        self._dict_get = self._dict.get\n        self._maxsize = maxsize\n\n    cdef get(self, key, default):\n        o = self._dict_get(key, _LRU_MARKER)\n        if o is _LRU_MARKER:\n            return default\n        self._dict_move_to_end(key)  # last=True\n        return o\n\n    cdef inline needs_cleanup(self):\n        return len(self._dict) > self._maxsize\n\n    cdef inline cleanup_one(self):\n        k, _ = self._dict.popitem(last=False)\n        return k\n\n    def __getitem__(self, key):\n        o = self._dict[key]\n        self._dict_move_to_end(key)  # last=True\n        return o\n\n    def __setitem__(self, key, o):\n        if key in self._dict:\n            self._dict[key] = o\n            self._dict_move_to_end(key)  # last=True\n        else:\n            self._dict[key] = o\n        while self.needs_cleanup():\n            self.cleanup_one()\n\n    def __delitem__(self, key):\n        del self._dict[key]\n\n    def __contains__(self, key):\n        return key in self._dict\n\n    def __len__(self):\n        return len(self._dict)\n\n    def __iter__(self):\n        return iter(self._dict)\n"
  },
  {
    "path": "uvloop/pseudosock.pyx",
    "content": "cdef class PseudoSocket:\n    cdef:\n        int _family\n        int _type\n        int _proto\n        int _fd\n        object _peername\n        object _sockname\n\n    def __init__(self, int family, int type, int proto, int fd):\n        self._family = family\n        self._type = type\n        self._proto = proto\n        self._fd = fd\n        self._peername = None\n        self._sockname = None\n\n    cdef _na(self, what):\n        raise TypeError('transport sockets do not support {}'.format(what))\n\n    cdef _make_sock(self):\n        return socket_socket(self._family, self._type, self._proto, self._fd)\n\n    property family:\n        def __get__(self):\n            try:\n                return socket_AddressFamily(self._family)\n            except ValueError:\n                return self._family\n\n    property type:\n        def __get__(self):\n            try:\n                return socket_SocketKind(self._type)\n            except ValueError:\n                return self._type\n\n    property proto:\n        def __get__(self):\n            return self._proto\n\n    def __repr__(self):\n        s = (\"<uvloop.PseudoSocket fd={}, family={!s}, \"\n             \"type={!s}, proto={}\").format(self.fileno(), self.family.name,\n                                           self.type.name, self.proto)\n\n        if self._fd != -1:\n            try:\n                laddr = self.getsockname()\n                if laddr:\n                    s += \", laddr=%s\" % str(laddr)\n            except socket_error:\n                pass\n            try:\n                raddr = self.getpeername()\n                if raddr:\n                    s += \", raddr=%s\" % str(raddr)\n            except socket_error:\n                pass\n        s += '>'\n        return s\n\n    def __getstate__(self):\n        raise TypeError(\"Cannot serialize socket object\")\n\n    def fileno(self):\n        return self._fd\n\n    def dup(self):\n        fd = os_dup(self._fd)\n        sock = socket_socket(self._family, self._type, self._proto, fileno=fd)\n        sock.settimeout(0)\n        return sock\n\n    def get_inheritable(self):\n        return os_get_inheritable(self._fd)\n\n    def set_inheritable(self):\n        os_set_inheritable(self._fd)\n\n    def ioctl(self, *args, **kwargs):\n        pass\n\n    def getsockopt(self, *args, **kwargs):\n        sock = self._make_sock()\n        try:\n            return sock.getsockopt(*args, **kwargs)\n        finally:\n            sock.detach()\n\n    def setsockopt(self, *args, **kwargs):\n        sock = self._make_sock()\n        try:\n            return sock.setsockopt(*args, **kwargs)\n        finally:\n            sock.detach()\n\n    def getpeername(self):\n        if self._peername is not None:\n            return self._peername\n\n        sock = self._make_sock()\n        try:\n            self._peername = sock.getpeername()\n            return self._peername\n        finally:\n            sock.detach()\n\n    def getsockname(self):\n        if self._sockname is not None:\n            return self._sockname\n\n        sock = self._make_sock()\n        try:\n            self._sockname = sock.getsockname()\n            return self._sockname\n        finally:\n            sock.detach()\n\n    def share(self, process_id):\n        sock = self._make_sock()\n        try:\n            return sock.share(process_id)\n        finally:\n            sock.detach()\n\n    def accept(self):\n        self._na('accept() method')\n\n    def connect(self, *args):\n        self._na('connect() method')\n\n    def connect_ex(self, *args):\n        self._na('connect_ex() method')\n\n    def bind(self, *args):\n        self._na('bind() method')\n\n    def listen(self, *args, **kwargs):\n        self._na('listen() method')\n\n    def makefile(self):\n        self._na('makefile() method')\n\n    def sendfile(self, *args, **kwargs):\n        self._na('sendfile() method')\n\n    def close(self):\n        self._na('close() method')\n\n    def detach(self):\n        self._na('detach() method')\n\n    def shutdown(self, *args):\n        self._na('shutdown() method')\n\n    def sendmsg_afalg(self, *args, **kwargs):\n        self._na('sendmsg_afalg() method')\n\n    def sendmsg(self):\n        self._na('sendmsg() method')\n\n    def sendto(self, *args, **kwargs):\n        self._na('sendto() method')\n\n    def send(self, *args, **kwargs):\n        self._na('send() method')\n\n    def sendall(self, *args, **kwargs):\n        self._na('sendall() method')\n\n    def recv_into(self, *args, **kwargs):\n        self._na('recv_into() method')\n\n    def recvfrom_into(self, *args, **kwargs):\n        self._na('recvfrom_into() method')\n\n    def recvmsg_into(self, *args, **kwargs):\n        self._na('recvmsg_into() method')\n\n    def recvmsg(self, *args, **kwargs):\n        self._na('recvmsg() method')\n\n    def recvfrom(self, *args, **kwargs):\n        self._na('recvfrom() method')\n\n    def recv(self, *args, **kwargs):\n        self._na('recv() method')\n\n    def settimeout(self, value):\n        if value == 0:\n            return\n        raise ValueError(\n            'settimeout(): only 0 timeout is allowed on transport sockets')\n\n    def gettimeout(self):\n        return 0\n\n    def setblocking(self, flag):\n        if not flag:\n            return\n        raise ValueError(\n            'setblocking(): transport sockets cannot be blocking')\n\n    def __enter__(self):\n        self._na('context manager protocol')\n\n    def __exit__(self, *err):\n        self._na('context manager protocol')\n"
  },
  {
    "path": "uvloop/py.typed",
    "content": ""
  },
  {
    "path": "uvloop/request.pxd",
    "content": "cdef class UVRequest:\n    cdef:\n        uv.uv_req_t *request\n        bint done\n        Loop loop\n\n    cdef on_done(self)\n    cdef cancel(self)\n"
  },
  {
    "path": "uvloop/request.pyx",
    "content": "cdef class UVRequest:\n    \"\"\"A base class for all libuv requests (uv_getaddrinfo_t, etc).\n\n    Important: it's a responsibility of the subclass to call the\n    \"on_done\" method in the request's callback.\n\n    If \"on_done\" isn't called, the request object will never die.\n    \"\"\"\n\n    def __cinit__(self, Loop loop, *_):\n        self.request = NULL\n        self.loop = loop\n        self.done = 0\n        Py_INCREF(self)\n\n    cdef on_done(self):\n        self.done = 1\n        Py_DECREF(self)\n\n    cdef cancel(self):\n        # Most requests are implemented using a threadpool.  It's only\n        # possible to cancel a request when it's still in a threadpool's\n        # queue.  Once it's started to execute, we have to wait until\n        # it finishes and calls its callback (and callback *must* call\n        # UVRequest.on_done).\n\n        cdef int err\n\n        if self.done == 1:\n            return\n\n        if UVLOOP_DEBUG:\n            if self.request is NULL:\n                raise RuntimeError(\n                    '{}.cancel: .request is NULL'.format(\n                        self.__class__.__name__))\n\n            if self.request.data is NULL:\n                raise RuntimeError(\n                    '{}.cancel: .request.data is NULL'.format(\n                        self.__class__.__name__))\n\n            if <UVRequest>self.request.data is not self:\n                raise RuntimeError(\n                    '{}.cancel: .request.data is not UVRequest'.format(\n                        self.__class__.__name__))\n\n        # We only can cancel pending requests.  Let's try.\n        err = uv.uv_cancel(self.request)\n        if err < 0:\n            if err == uv.UV_EBUSY:\n                # Can't close the request -- it's executing (see the first\n                # comment).  Loop will have to wait until the callback\n                # fires.\n                pass\n            elif err == uv.UV_EINVAL:\n                # From libuv docs:\n                #\n                #     Only cancellation of uv_fs_t, uv_getaddrinfo_t,\n                #     uv_getnameinfo_t and uv_work_t requests is currently\n                #     supported.\n                return\n            else:\n                ex = convert_error(err)\n                self.loop._handle_exception(ex)\n"
  },
  {
    "path": "uvloop/server.pxd",
    "content": "cdef class Server:\n    cdef:\n        list _servers\n        list _waiters\n        int _active_count\n        Loop _loop\n        bint _serving\n        object _serving_forever_fut\n        object __weakref__\n\n    cdef _add_server(self, UVStreamServer srv)\n    cdef _start_serving(self)\n    cdef _wakeup(self)\n\n    cdef _attach(self)\n    cdef _detach(self)\n\n    cdef _ref(self)\n    cdef _unref(self)\n"
  },
  {
    "path": "uvloop/server.pyx",
    "content": "import asyncio\n\n\ncdef class Server:\n    def __cinit__(self, Loop loop):\n        self._loop = loop\n        self._servers = []\n        self._waiters = []\n        self._active_count = 0\n        self._serving_forever_fut = None\n\n    cdef _add_server(self, UVStreamServer srv):\n        self._servers.append(srv)\n\n    cdef _start_serving(self):\n        if self._serving:\n            return\n\n        self._serving = 1\n        for server in self._servers:\n            (<UVStreamServer>server).listen()\n\n    cdef _wakeup(self):\n        cdef list waiters\n\n        waiters = self._waiters\n        self._waiters = None\n        for waiter in waiters:\n            if not waiter.done():\n                waiter.set_result(waiter)\n\n    cdef _attach(self):\n        assert self._servers is not None\n        self._active_count += 1\n\n    cdef _detach(self):\n        assert self._active_count > 0\n        self._active_count -= 1\n        if self._active_count == 0 and self._servers is None:\n            self._wakeup()\n\n    cdef _ref(self):\n        # Keep the server object alive while it's not explicitly closed.\n        self._loop._servers.add(self)\n\n    cdef _unref(self):\n        self._loop._servers.discard(self)\n\n    # Public API\n\n    @cython.iterable_coroutine\n    async def __aenter__(self):\n        return self\n\n    @cython.iterable_coroutine\n    async def __aexit__(self, *exc):\n        self.close()\n        await self.wait_closed()\n\n    def __repr__(self):\n        return '<%s sockets=%r>' % (self.__class__.__name__, self.sockets)\n\n    def get_loop(self):\n        return self._loop\n\n    @cython.iterable_coroutine\n    async def wait_closed(self):\n        # Do not remove `self._servers is None` below\n        # because close() method only closes server sockets\n        # and existing client connections are left open.\n        if self._servers is None or self._waiters is None:\n            return\n        waiter = self._loop._new_future()\n        self._waiters.append(waiter)\n        await waiter\n\n    def close(self):\n        cdef list servers\n\n        if self._servers is None:\n            return\n\n        try:\n            servers = self._servers\n            self._servers = None\n            self._serving = 0\n\n            for server in servers:\n                (<UVStreamServer>server)._close()\n\n            if self._active_count == 0:\n                self._wakeup()\n        finally:\n            self._unref()\n\n    def is_serving(self):\n        return self._serving\n\n    @cython.iterable_coroutine\n    async def start_serving(self):\n        self._start_serving()\n\n    @cython.iterable_coroutine\n    async def serve_forever(self):\n        if self._serving_forever_fut is not None:\n            raise RuntimeError(\n                f'server {self!r} is already being awaited on serve_forever()')\n        if self._servers is None:\n            raise RuntimeError(f'server {self!r} is closed')\n\n        self._start_serving()\n        self._serving_forever_fut = self._loop.create_future()\n\n        try:\n            await self._serving_forever_fut\n        except asyncio.CancelledError:\n            try:\n                self.close()\n                await self.wait_closed()\n            finally:\n                raise\n        finally:\n            self._serving_forever_fut = None\n\n    property sockets:\n        def __get__(self):\n            cdef list sockets = []\n\n            # Guard against `self._servers is None`\n            if self._servers:\n                for server in self._servers:\n                    sockets.append(\n                        (<UVStreamServer>server)._get_socket()\n                    )\n\n            return sockets\n"
  },
  {
    "path": "uvloop/sslproto.pxd",
    "content": "cdef enum SSLProtocolState:\n    UNWRAPPED = 0\n    DO_HANDSHAKE = 1\n    WRAPPED = 2\n    FLUSHING = 3\n    SHUTDOWN = 4\n\n\ncdef enum AppProtocolState:\n    # This tracks the state of app protocol (https://git.io/fj59P):\n    #\n    #     INIT -cm-> CON_MADE [-dr*->] [-er-> EOF?] -cl-> CON_LOST\n    #\n    # * cm: connection_made()\n    # * dr: data_received()\n    # * er: eof_received()\n    # * cl: connection_lost()\n\n    STATE_INIT = 0\n    STATE_CON_MADE = 1\n    STATE_EOF = 2\n    STATE_CON_LOST = 3\n\n\ncdef class _SSLProtocolTransport:\n    cdef:\n        Loop _loop\n        SSLProtocol _ssl_protocol\n        bint _closed\n        object context\n\n\ncdef class SSLProtocol:\n    cdef:\n        bint _server_side\n        str _server_hostname\n        object _sslcontext\n\n        object _extra\n\n        object _write_backlog\n        size_t _write_buffer_size\n\n        object _waiter\n        Loop _loop\n        _SSLProtocolTransport _app_transport\n        bint _app_transport_created\n\n        object _transport\n        object _ssl_handshake_timeout\n        object _ssl_shutdown_timeout\n\n        object _sslobj\n        object _sslobj_read\n        object _sslobj_write\n        object _sslobj_pending\n        object _incoming\n        object _incoming_write\n        object _outgoing\n        object _outgoing_read\n        char* _ssl_buffer\n        size_t _ssl_buffer_len\n        SSLProtocolState _state\n        size_t _conn_lost\n        AppProtocolState _app_state\n\n        bint _ssl_writing_paused\n        bint _app_reading_paused\n\n        size_t _incoming_high_water\n        size_t _incoming_low_water\n        bint _ssl_reading_paused\n\n        bint _app_writing_paused\n        size_t _outgoing_high_water\n        size_t _outgoing_low_water\n\n        object _app_protocol\n        bint _app_protocol_is_buffer\n        object _app_protocol_get_buffer\n        object _app_protocol_buffer_updated\n\n        object _handshake_start_time\n        object _handshake_timeout_handle\n        object _shutdown_timeout_handle\n\n    # Instead of doing python calls, c methods *_impl are called directly\n    # from stream.pyx\n\n    cdef inline get_buffer_impl(self, size_t n, char** buf, size_t* buf_size)\n    cdef inline buffer_updated_impl(self, size_t nbytes)\n\n    cdef inline _set_app_protocol(self, app_protocol)\n    cdef inline _wakeup_waiter(self, exc=*)\n    cdef inline _get_extra_info(self, name, default=*)\n    cdef inline _set_state(self, SSLProtocolState new_state)\n\n    # Handshake flow\n\n    cdef inline _start_handshake(self)\n    cdef inline _check_handshake_timeout(self)\n    cdef inline _do_handshake(self)\n    cdef inline _on_handshake_complete(self, handshake_exc)\n\n    # Shutdown flow\n\n    cdef inline _start_shutdown(self, object context=*)\n    cdef inline _check_shutdown_timeout(self)\n    cdef inline _do_read_into_void(self, object context)\n    cdef inline _do_flush(self, object context=*)\n    cdef inline _do_shutdown(self, object context=*)\n    cdef inline _on_shutdown_complete(self, shutdown_exc)\n    cdef inline _abort(self, exc)\n\n    # Outgoing flow\n\n    cdef inline _write_appdata(self, list_of_data, object context)\n    cdef inline _do_write(self)\n    cdef inline _process_outgoing(self)\n\n    # Incoming flow\n\n    cdef inline _do_read(self)\n    cdef inline _do_read__buffered(self)\n    cdef inline _do_read__copied(self)\n    cdef inline _call_eof_received(self, object context=*)\n\n    # Flow control for writes from APP socket\n\n    cdef inline _control_app_writing(self, object context=*)\n    cdef inline size_t _get_write_buffer_size(self)\n    cdef inline _set_write_buffer_limits(self, high=*, low=*)\n\n    # Flow control for reads to APP socket\n\n    cdef inline _pause_reading(self)\n    cdef inline _resume_reading(self, object context)\n\n    # Flow control for reads from SSL socket\n\n    cdef inline _control_ssl_reading(self)\n    cdef inline _set_read_buffer_limits(self, high=*, low=*)\n    cdef inline size_t _get_read_buffer_size(self)\n    cdef inline _fatal_error(self, exc, message=*)\n"
  },
  {
    "path": "uvloop/sslproto.pyx",
    "content": "cdef _create_transport_context(server_side, server_hostname):\n    if server_side:\n        raise ValueError('Server side SSL needs a valid SSLContext')\n\n    # Client side may pass ssl=True to use a default\n    # context; in that case the sslcontext passed is None.\n    # The default is secure for client connections.\n    # Python 3.4+: use up-to-date strong settings.\n    sslcontext = ssl_create_default_context()\n    if not server_hostname:\n        sslcontext.check_hostname = False\n    return sslcontext\n\n\ncdef class _SSLProtocolTransport:\n\n    # TODO:\n    # _sendfile_compatible = constants._SendfileMode.FALLBACK\n\n    def __cinit__(self, Loop loop, ssl_protocol, context):\n        self._loop = loop\n        # SSLProtocol instance\n        self._ssl_protocol = ssl_protocol\n        self._closed = False\n        if context is None:\n            context = Context_CopyCurrent()\n        self.context = context\n\n    def get_extra_info(self, name, default=None):\n        \"\"\"Get optional transport information.\"\"\"\n        return self._ssl_protocol._get_extra_info(name, default)\n\n    def set_protocol(self, protocol):\n        self._ssl_protocol._set_app_protocol(protocol)\n\n    def get_protocol(self):\n        return self._ssl_protocol._app_protocol\n\n    def is_closing(self):\n        return self._closed\n\n    def close(self):\n        \"\"\"Close the transport.\n\n        Buffered data will be flushed asynchronously.  No more data\n        will be received.  After all buffered data is flushed, the\n        protocol's connection_lost() method will (eventually) called\n        with None as its argument.\n        \"\"\"\n        self._closed = True\n        self._ssl_protocol._start_shutdown(self.context.copy())\n\n    def __dealloc__(self):\n        if not self._closed:\n            self._closed = True\n            warnings_warn(\n                \"unclosed transport <uvloop.loop._SSLProtocolTransport \"\n                \"object>\", ResourceWarning)\n\n    def is_reading(self):\n        return not self._ssl_protocol._app_reading_paused\n\n    def pause_reading(self):\n        \"\"\"Pause the receiving end.\n\n        No data will be passed to the protocol's data_received()\n        method until resume_reading() is called.\n        \"\"\"\n        self._ssl_protocol._pause_reading()\n\n    def resume_reading(self):\n        \"\"\"Resume the receiving end.\n\n        Data received will once again be passed to the protocol's\n        data_received() method.\n        \"\"\"\n        self._ssl_protocol._resume_reading(self.context.copy())\n\n    def set_write_buffer_limits(self, high=None, low=None):\n        \"\"\"Set the high- and low-water limits for write flow control.\n\n        These two values control when to call the protocol's\n        pause_writing() and resume_writing() methods.  If specified,\n        the low-water limit must be less than or equal to the\n        high-water limit.  Neither value can be negative.\n\n        The defaults are implementation-specific.  If only the\n        high-water limit is given, the low-water limit defaults to an\n        implementation-specific value less than or equal to the\n        high-water limit.  Setting high to zero forces low to zero as\n        well, and causes pause_writing() to be called whenever the\n        buffer becomes non-empty.  Setting low to zero causes\n        resume_writing() to be called only once the buffer is empty.\n        Use of zero for either limit is generally sub-optimal as it\n        reduces opportunities for doing I/O and computation\n        concurrently.\n        \"\"\"\n        self._ssl_protocol._set_write_buffer_limits(high, low)\n        self._ssl_protocol._control_app_writing(self.context.copy())\n\n    def get_write_buffer_limits(self):\n        return (self._ssl_protocol._outgoing_low_water,\n                self._ssl_protocol._outgoing_high_water)\n\n    def get_write_buffer_size(self):\n        \"\"\"Return the current size of the write buffers.\"\"\"\n        return self._ssl_protocol._get_write_buffer_size()\n\n    def set_read_buffer_limits(self, high=None, low=None):\n        \"\"\"Set the high- and low-water limits for read flow control.\n\n        These two values control when to call the upstream transport's\n        pause_reading() and resume_reading() methods.  If specified,\n        the low-water limit must be less than or equal to the\n        high-water limit.  Neither value can be negative.\n\n        The defaults are implementation-specific.  If only the\n        high-water limit is given, the low-water limit defaults to an\n        implementation-specific value less than or equal to the\n        high-water limit.  Setting high to zero forces low to zero as\n        well, and causes pause_reading() to be called whenever the\n        buffer becomes non-empty.  Setting low to zero causes\n        resume_reading() to be called only once the buffer is empty.\n        Use of zero for either limit is generally sub-optimal as it\n        reduces opportunities for doing I/O and computation\n        concurrently.\n        \"\"\"\n        self._ssl_protocol._set_read_buffer_limits(high, low)\n        self._ssl_protocol._control_ssl_reading()\n\n    def get_read_buffer_limits(self):\n        return (self._ssl_protocol._incoming_low_water,\n                self._ssl_protocol._incoming_high_water)\n\n    def get_read_buffer_size(self):\n        \"\"\"Return the current size of the read buffer.\"\"\"\n        return self._ssl_protocol._get_read_buffer_size()\n\n    @property\n    def _protocol_paused(self):\n        # Required for sendfile fallback pause_writing/resume_writing logic\n        return self._ssl_protocol._app_writing_paused\n\n    def write(self, data):\n        \"\"\"Write some data bytes to the transport.\n\n        This does not block; it buffers the data and arranges for it\n        to be sent out asynchronously.\n        \"\"\"\n        if not isinstance(data, (bytes, bytearray, memoryview)):\n            raise TypeError(f\"data: expecting a bytes-like instance, \"\n                            f\"got {type(data).__name__}\")\n        if not data:\n            return\n        self._ssl_protocol._write_appdata((data,), self.context.copy())\n\n    def writelines(self, list_of_data):\n        \"\"\"Write a list (or any iterable) of data bytes to the transport.\n\n        The default implementation concatenates the arguments and\n        calls write() on the result.\n        \"\"\"\n        self._ssl_protocol._write_appdata(list_of_data, self.context.copy())\n\n    def write_eof(self):\n        \"\"\"Close the write end after flushing buffered data.\n\n        This raises :exc:`NotImplementedError` right now.\n        \"\"\"\n        raise NotImplementedError\n\n    def can_write_eof(self):\n        \"\"\"Return True if this transport supports write_eof(), False if not.\"\"\"\n        return False\n\n    def abort(self):\n        \"\"\"Close the transport immediately.\n\n        Buffered data will be lost.  No more data will be received.\n        The protocol's connection_lost() method will (eventually) be\n        called with None as its argument.\n        \"\"\"\n        self._force_close(None)\n\n    def _force_close(self, exc):\n        self._closed = True\n        self._ssl_protocol._abort(exc)\n\n    def _test__append_write_backlog(self, data):\n        # for test only\n        self._ssl_protocol._write_backlog.append(data)\n        self._ssl_protocol._write_buffer_size += len(data)\n\n\ncdef class SSLProtocol:\n    \"\"\"SSL protocol.\n\n    Implementation of SSL on top of a socket using incoming and outgoing\n    buffers which are ssl.MemoryBIO objects.\n    \"\"\"\n\n    def __cinit__(self, *args, **kwargs):\n        self._ssl_buffer_len = SSL_READ_MAX_SIZE\n        self._ssl_buffer = <char*>PyMem_RawMalloc(self._ssl_buffer_len)\n        if not self._ssl_buffer:\n            raise MemoryError()\n\n    def __dealloc__(self):\n        PyMem_RawFree(self._ssl_buffer)\n        self._ssl_buffer = NULL\n        self._ssl_buffer_len = 0\n\n    def __init__(self, loop, app_protocol, sslcontext, waiter,\n                 server_side=False, server_hostname=None,\n                 call_connection_made=True,\n                 ssl_handshake_timeout=None,\n                 ssl_shutdown_timeout=None):\n        if ssl_handshake_timeout is None:\n            ssl_handshake_timeout = SSL_HANDSHAKE_TIMEOUT\n        elif ssl_handshake_timeout <= 0:\n            raise ValueError(\n                f\"ssl_handshake_timeout should be a positive number, \"\n                f\"got {ssl_handshake_timeout}\")\n        if ssl_shutdown_timeout is None:\n            ssl_shutdown_timeout = SSL_SHUTDOWN_TIMEOUT\n        elif ssl_shutdown_timeout <= 0:\n            raise ValueError(\n                f\"ssl_shutdown_timeout should be a positive number, \"\n                f\"got {ssl_shutdown_timeout}\")\n\n        if not sslcontext:\n            sslcontext = _create_transport_context(\n                server_side, server_hostname)\n\n        self._server_side = server_side\n        if server_hostname and not server_side:\n            self._server_hostname = server_hostname\n        else:\n            self._server_hostname = None\n        self._sslcontext = sslcontext\n        # SSL-specific extra info. More info are set when the handshake\n        # completes.\n        self._extra = dict(sslcontext=sslcontext)\n\n        # App data write buffering\n        self._write_backlog = col_deque()\n        self._write_buffer_size = 0\n\n        self._waiter = waiter\n        self._loop = loop\n        self._set_app_protocol(app_protocol)\n        self._app_transport = None\n        self._app_transport_created = False\n        # transport, ex: SelectorSocketTransport\n        self._transport = None\n        self._ssl_handshake_timeout = ssl_handshake_timeout\n        self._ssl_shutdown_timeout = ssl_shutdown_timeout\n        # SSL and state machine\n        self._sslobj = None\n        self._incoming = ssl_MemoryBIO()\n        self._incoming_write = self._incoming.write\n        self._outgoing = ssl_MemoryBIO()\n        self._outgoing_read = self._outgoing.read\n        self._state = UNWRAPPED\n        self._conn_lost = 0  # Set when connection_lost called\n        if call_connection_made:\n            self._app_state = STATE_INIT\n        else:\n            self._app_state = STATE_CON_MADE\n\n        # Flow Control\n\n        self._ssl_writing_paused = False\n\n        self._app_reading_paused = False\n\n        self._ssl_reading_paused = False\n        self._incoming_high_water = 0\n        self._incoming_low_water = 0\n        self._set_read_buffer_limits()\n\n        self._app_writing_paused = False\n        self._outgoing_high_water = 0\n        self._outgoing_low_water = 0\n        self._set_write_buffer_limits()\n\n    cdef _set_app_protocol(self, app_protocol):\n        self._app_protocol = app_protocol\n        if (hasattr(app_protocol, 'get_buffer') and\n                not isinstance(app_protocol, aio_Protocol)):\n            self._app_protocol_get_buffer = app_protocol.get_buffer\n            self._app_protocol_buffer_updated = app_protocol.buffer_updated\n            self._app_protocol_is_buffer = True\n        else:\n            self._app_protocol_is_buffer = False\n\n    cdef _wakeup_waiter(self, exc=None):\n        if self._waiter is None:\n            return\n        if not self._waiter.cancelled():\n            if exc is not None:\n                self._waiter.set_exception(exc)\n            else:\n                self._waiter.set_result(None)\n        self._waiter = None\n\n    def _get_app_transport(self, context=None):\n        if self._app_transport is None:\n            if self._app_transport_created:\n                raise RuntimeError('Creating _SSLProtocolTransport twice')\n            self._app_transport = _SSLProtocolTransport(self._loop, self,\n                                                        context)\n            self._app_transport_created = True\n        return self._app_transport\n\n    def connection_made(self, transport):\n        \"\"\"Called when the low-level connection is made.\n\n        Start the SSL handshake.\n        \"\"\"\n        self._transport = transport\n        self._start_handshake()\n\n    def connection_lost(self, exc):\n        \"\"\"Called when the low-level connection is lost or closed.\n\n        The argument is an exception object or None (the latter\n        meaning a regular EOF is received or the connection was\n        aborted or closed).\n        \"\"\"\n        self._write_backlog.clear()\n        self._outgoing_read()\n        self._conn_lost += 1\n\n        # Just mark the app transport as closed so that its __dealloc__\n        # doesn't complain.\n        if self._app_transport is not None:\n            self._app_transport._closed = True\n\n        if self._state != DO_HANDSHAKE:\n            if self._app_state == STATE_CON_MADE or \\\n                    self._app_state == STATE_EOF:\n                self._app_state = STATE_CON_LOST\n                self._loop.call_soon(self._app_protocol.connection_lost, exc)\n        self._set_state(UNWRAPPED)\n        self._transport = None\n        self._app_transport = None\n        self._app_protocol = None\n        self._wakeup_waiter(exc)\n\n        if self._shutdown_timeout_handle:\n            self._shutdown_timeout_handle.cancel()\n            self._shutdown_timeout_handle = None\n        if self._handshake_timeout_handle:\n            self._handshake_timeout_handle.cancel()\n            self._handshake_timeout_handle = None\n\n    cdef get_buffer_impl(self, size_t n, char** buf, size_t* buf_size):\n        cdef size_t want = n\n        if want > SSL_READ_MAX_SIZE:\n            want = SSL_READ_MAX_SIZE\n        if self._ssl_buffer_len < want:\n            self._ssl_buffer = <char*>PyMem_RawRealloc(self._ssl_buffer, want)\n            if not self._ssl_buffer:\n                raise MemoryError()\n            self._ssl_buffer_len = want\n\n        buf[0] = self._ssl_buffer\n        buf_size[0] = self._ssl_buffer_len\n\n    cdef buffer_updated_impl(self, size_t nbytes):\n        self._incoming_write(PyMemoryView_FromMemory(\n            self._ssl_buffer, nbytes, PyBUF_WRITE))\n\n        if self._state == DO_HANDSHAKE:\n            self._do_handshake()\n\n        elif self._state == WRAPPED:\n            self._do_read()\n\n        elif self._state == FLUSHING:\n            self._do_flush()\n\n        elif self._state == SHUTDOWN:\n            self._do_shutdown()\n\n    def get_buffer(self, size_t n):\n        # This pure python call is still used by some very peculiar test cases\n        cdef:\n            char* buf\n            size_t buf_size\n\n        self.get_buffer_impl(n, &buf, &buf_size)\n        return PyMemoryView_FromMemory(buf, buf_size, PyBUF_WRITE)\n\n    def buffer_updated(self, size_t nbytes):\n        self.buffer_updated_impl(nbytes)\n\n    def eof_received(self):\n        \"\"\"Called when the other end of the low-level stream\n        is half-closed.\n\n        If this returns a false value (including None), the transport\n        will close itself.  If it returns a true value, closing the\n        transport is up to the protocol.\n        \"\"\"\n        try:\n            if self._loop.get_debug():\n                aio_logger.debug(\"%r received EOF\", self)\n\n            if self._state == DO_HANDSHAKE:\n                self._on_handshake_complete(ConnectionResetError)\n\n            elif self._state == WRAPPED or self._state == FLUSHING:\n                # We treat a low-level EOF as a critical situation similar to a\n                # broken connection - just send whatever is in the buffer and\n                # close. No application level eof_received() is called -\n                # because we don't want the user to think that this is a\n                # graceful shutdown triggered by SSL \"close_notify\".\n                self._set_state(SHUTDOWN)\n                self._on_shutdown_complete(None)\n\n            elif self._state == SHUTDOWN:\n                self._on_shutdown_complete(None)\n\n        except Exception:\n            self._transport.close()\n            raise\n\n    cdef _get_extra_info(self, name, default=None):\n        if name == 'uvloop.sslproto':\n            return self\n        elif name in self._extra:\n            return self._extra[name]\n        elif self._transport is not None:\n            return self._transport.get_extra_info(name, default)\n        else:\n            return default\n\n    cdef _set_state(self, SSLProtocolState new_state):\n        cdef bint allowed = False\n\n        if new_state == UNWRAPPED:\n            allowed = True\n\n        elif self._state == UNWRAPPED and new_state == DO_HANDSHAKE:\n            allowed = True\n\n        elif self._state == DO_HANDSHAKE and new_state == WRAPPED:\n            allowed = True\n\n        elif self._state == WRAPPED and new_state == FLUSHING:\n            allowed = True\n\n        elif self._state == WRAPPED and new_state == SHUTDOWN:\n            allowed = True\n\n        elif self._state == FLUSHING and new_state == SHUTDOWN:\n            allowed = True\n\n        if allowed:\n            self._state = new_state\n\n        else:\n            raise RuntimeError(\n                'cannot switch state from {} to {}'.format(\n                    self._state, new_state))\n\n    # Handshake flow\n\n    cdef _start_handshake(self):\n        if self._loop.get_debug():\n            aio_logger.debug(\"%r starts SSL handshake\", self)\n            self._handshake_start_time = self._loop.time()\n        else:\n            self._handshake_start_time = None\n\n        self._set_state(DO_HANDSHAKE)\n\n        # start handshake timeout count down\n        self._handshake_timeout_handle = \\\n            self._loop.call_later(self._ssl_handshake_timeout,\n                                  lambda: self._check_handshake_timeout())\n\n        try:\n            self._sslobj = self._sslcontext.wrap_bio(\n                self._incoming, self._outgoing,\n                server_side=self._server_side,\n                server_hostname=self._server_hostname)\n            self._sslobj_read = self._sslobj.read\n            self._sslobj_write = self._sslobj.write\n            self._sslobj_pending = self._sslobj.pending\n        except Exception as ex:\n            self._on_handshake_complete(ex)\n        else:\n            self._do_handshake()\n\n    cdef _check_handshake_timeout(self):\n        if self._state == DO_HANDSHAKE:\n            msg = (\n                f\"SSL handshake is taking longer than \"\n                f\"{self._ssl_handshake_timeout} seconds: \"\n                f\"aborting the connection\"\n            )\n            self._fatal_error(ConnectionAbortedError(msg))\n\n    cdef _do_handshake(self):\n        try:\n            self._sslobj.do_handshake()\n        except ssl_SSLAgainErrors as exc:\n            self._process_outgoing()\n        except ssl_SSLError as exc:\n            self._on_handshake_complete(exc)\n        else:\n            self._on_handshake_complete(None)\n\n    cdef _on_handshake_complete(self, handshake_exc):\n        if self._handshake_timeout_handle is not None:\n            self._handshake_timeout_handle.cancel()\n            self._handshake_timeout_handle = None\n\n        sslobj = self._sslobj\n        try:\n            if handshake_exc is None:\n                self._set_state(WRAPPED)\n            else:\n                raise handshake_exc\n\n            peercert = sslobj.getpeercert()\n        except Exception as exc:\n            self._set_state(UNWRAPPED)\n            if isinstance(exc, ssl_CertificateError):\n                msg = 'SSL handshake failed on verifying the certificate'\n            else:\n                msg = 'SSL handshake failed'\n            self._fatal_error(exc, msg)\n            self._wakeup_waiter(exc)\n            return\n\n        if self._loop.get_debug():\n            dt = self._loop.time() - self._handshake_start_time\n            aio_logger.debug(\"%r: SSL handshake took %.1f ms\", self, dt * 1e3)\n\n        # Add extra info that becomes available after handshake.\n        self._extra.update(peercert=peercert,\n                           cipher=sslobj.cipher(),\n                           compression=sslobj.compression(),\n                           ssl_object=sslobj)\n        if self._app_state == STATE_INIT:\n            self._app_state = STATE_CON_MADE\n            self._app_protocol.connection_made(self._get_app_transport())\n        self._wakeup_waiter()\n\n        # We should wakeup user code before sending the first data below. In\n        # case of `start_tls()`, the user can only get the SSLTransport in the\n        # wakeup callback, because `connection_made()` is not called again.\n        # We should schedule the first data later than the wakeup callback so\n        # that the user get a chance to e.g. check ALPN with the transport\n        # before having to handle the first data.\n        self._loop._call_soon_handle(\n            new_MethodHandle(self._loop,\n                             \"SSLProtocol._do_read\",\n                             <method_t> self._do_read,\n                             None,  # current context is good\n                             self))\n\n    # Shutdown flow\n\n    cdef _start_shutdown(self, object context=None):\n        if self._state in (FLUSHING, SHUTDOWN, UNWRAPPED):\n            return\n        # we don't need the context for _abort or the timeout, because\n        # TCP transport._force_close() should be able to call\n        # connection_lost() in the right context\n        if self._app_transport is not None:\n            self._app_transport._closed = True\n        if self._state == DO_HANDSHAKE:\n            self._abort(None)\n        else:\n            self._set_state(FLUSHING)\n            self._shutdown_timeout_handle = \\\n                self._loop.call_later(self._ssl_shutdown_timeout,\n                                      lambda: self._check_shutdown_timeout())\n            self._do_flush(context)\n\n    cdef _check_shutdown_timeout(self):\n        if self._state in (FLUSHING, SHUTDOWN):\n            self._transport._force_close(\n                aio_TimeoutError('SSL shutdown timed out'))\n\n    cdef _do_read_into_void(self, object context):\n        \"\"\"Consume and discard incoming application data.\n\n        If close_notify is received for the first time, call eof_received.\n        \"\"\"\n        cdef:\n            bint close_notify = False\n        try:\n            while True:\n                if not self._sslobj_read(SSL_READ_MAX_SIZE):\n                    close_notify = True\n                    break\n        except ssl_SSLAgainErrors as exc:\n            pass\n        except ssl_SSLZeroReturnError:\n            close_notify = True\n        if close_notify:\n            self._call_eof_received(context)\n\n    cdef _do_flush(self, object context=None):\n        \"\"\"Flush the write backlog, discarding new data received.\n\n        We don't send close_notify in FLUSHING because we still want to send\n        the remaining data over SSL, even if we received a close_notify. Also,\n        no application-level resume_writing() or pause_writing() will be called\n        in FLUSHING, as we could fully manage the flow control internally.\n        \"\"\"\n        try:\n            self._do_read_into_void(context)\n            self._do_write()\n            self._process_outgoing()\n            self._control_ssl_reading()\n        except Exception as ex:\n            self._on_shutdown_complete(ex)\n        else:\n            if not self._get_write_buffer_size():\n                self._set_state(SHUTDOWN)\n                self._do_shutdown(context)\n\n    cdef _do_shutdown(self, object context=None):\n        \"\"\"Send close_notify and wait for the same from the peer.\"\"\"\n        try:\n            # we must skip all application data (if any) before unwrap\n            self._do_read_into_void(context)\n            try:\n                self._sslobj.unwrap()\n            except ssl_SSLAgainErrors as exc:\n                self._process_outgoing()\n            else:\n                self._process_outgoing()\n                if not self._get_write_buffer_size():\n                    self._on_shutdown_complete(None)\n        except Exception as ex:\n            self._on_shutdown_complete(ex)\n\n    cdef _on_shutdown_complete(self, shutdown_exc):\n        if self._shutdown_timeout_handle is not None:\n            self._shutdown_timeout_handle.cancel()\n            self._shutdown_timeout_handle = None\n\n        # we don't need the context here because TCP transport.close() should\n        # be able to call connection_made() in the right context\n        if shutdown_exc:\n            self._fatal_error(shutdown_exc, 'Error occurred during shutdown')\n        else:\n            self._transport.close()\n\n    cdef _abort(self, exc):\n        self._set_state(UNWRAPPED)\n        if self._transport is not None:\n            self._transport._force_close(exc)\n\n    # Outgoing flow\n\n    cdef _write_appdata(self, list_of_data, object context):\n        if self._state in (FLUSHING, SHUTDOWN, UNWRAPPED):\n            if self._conn_lost >= LOG_THRESHOLD_FOR_CONNLOST_WRITES:\n                aio_logger.warning('SSL connection is closed')\n            self._conn_lost += 1\n            return\n\n        for data in list_of_data:\n            self._write_backlog.append(data)\n            self._write_buffer_size += len(data)\n\n        try:\n            if self._state == WRAPPED:\n                self._do_write()\n                self._process_outgoing()\n                self._control_app_writing(context)\n\n        except Exception as ex:\n            self._fatal_error(ex, 'Fatal error on SSL protocol')\n\n    cdef _do_write(self):\n        \"\"\"Do SSL write, consumes write backlog and fills outgoing BIO.\"\"\"\n        cdef size_t data_len, count\n        try:\n            while self._write_backlog:\n                data = self._write_backlog[0]\n                count = self._sslobj_write(data)\n                data_len = len(data)\n                if count < data_len:\n                    if not PyMemoryView_Check(data):\n                        data = PyMemoryView_FromObject(data)\n                    self._write_backlog[0] = data[count:]\n                    self._write_buffer_size -= count\n                else:\n                    del self._write_backlog[0]\n                    self._write_buffer_size -= data_len\n        except ssl_SSLAgainErrors as exc:\n            pass\n\n    cdef _process_outgoing(self):\n        \"\"\"Send bytes from the outgoing BIO.\"\"\"\n        if not self._ssl_writing_paused:\n            data = self._outgoing_read()\n            if len(data):\n                if isinstance(self._transport, UVStream):\n                    (<UVStream>self._transport).write(data)\n                else:\n                    self._transport.write(data)\n\n    # Incoming flow\n\n    cdef _do_read(self):\n        if self._state != WRAPPED:\n            return\n        try:\n            if not self._app_reading_paused:\n                if self._app_protocol_is_buffer:\n                    self._do_read__buffered()\n                else:\n                    self._do_read__copied()\n                if self._write_backlog:\n                    self._do_write()\n                self._process_outgoing()\n                self._control_app_writing()\n            self._control_ssl_reading()\n        except Exception as ex:\n            self._fatal_error(ex, 'Fatal error on SSL protocol')\n\n    cdef _do_read__buffered(self):\n        cdef:\n            Py_ssize_t total_pending = (<Py_ssize_t>self._incoming.pending\n                                        + <Py_ssize_t>self._sslobj_pending())\n            # Ask for a little extra in case when decrypted data is bigger\n            # than original\n            object app_buffer = self._app_protocol_get_buffer(\n                total_pending + 256)\n            Py_ssize_t app_buffer_size = len(app_buffer)\n\n        if app_buffer_size == 0:\n            return\n\n        cdef:\n            Py_ssize_t last_bytes_read = -1\n            Py_ssize_t total_bytes_read = 0\n            Py_buffer pybuf\n            bint pybuf_initialized = False\n\n        try:\n            # SSLObject.read may not return all available data in one go.\n            # We have to keep calling read until it throw SSLWantReadError.\n            # However, throwing SSLWantReadError is very expensive even in\n            # the master trunk of cpython.\n            # See https://github.com/python/cpython/issues/123954\n\n            # One way to reduce reliance on SSLWantReadError is to check\n            # self._incoming.pending > 0 and SSLObject.pending() > 0.\n            # SSLObject.read may still throw SSLWantReadError even when\n            # self._incoming.pending > 0 and SSLObject.pending() == 0,\n            # but this should happen relatively rarely, only when ssl frame\n            # is partially received.\n\n            # This optimization works really well especially for peers\n            # exchanging small messages and wanting to have minimal latency.\n\n            # self._incoming.pending means how much data hasn't\n            # been processed by ssl yet (read: \"still encrypted\"). The final\n            # unencrypted data size maybe different.\n\n            # self._sslobj.pending() means how much data has been already\n            # decrypted and can be directly read with SSLObject.read.\n\n            # Run test_create_server_ssl_over_ssl to reproduce different cases\n            # for this method.\n            while total_pending > 0:\n                if total_bytes_read > 0:\n                    if not pybuf_initialized:\n                        PyObject_GetBuffer(app_buffer, &pybuf, PyBUF_WRITABLE)\n                        pybuf_initialized = True\n\n                    app_buffer = PyMemoryView_FromMemory(\n                        (<char*>pybuf.buf) + total_bytes_read,\n                        app_buffer_size - total_bytes_read,\n                        PyBUF_WRITE)\n\n                last_bytes_read = <Py_ssize_t>self._sslobj_read(\n                    app_buffer_size - total_bytes_read, app_buffer)\n                total_bytes_read += last_bytes_read\n\n                if last_bytes_read == 0:\n                    break\n\n                # User buffer may not fit all available data.\n                if total_bytes_read == app_buffer_size:\n                    self._loop._call_soon_handle(\n                        new_MethodHandle(self._loop,\n                                         \"SSLProtocol._do_read\",\n                                         <method_t> self._do_read,\n                                         None,  # current context is good\n                                         self))\n                    break\n\n                total_pending = (<Py_ssize_t>self._incoming.pending +\n                                 <Py_ssize_t>self._sslobj_pending())\n        except ssl_SSLAgainErrors as exc:\n            pass\n        finally:\n            if pybuf_initialized:\n                PyBuffer_Release(&pybuf)\n\n        if total_bytes_read > 0:\n            self._app_protocol_buffer_updated(total_bytes_read)\n\n        # SSLObject.read() may return 0 instead of throwing SSLWantReadError\n        # This indicates that we reached EOF\n        if last_bytes_read == 0:\n            # close_notify\n            self._call_eof_received()\n            self._start_shutdown()\n\n    cdef _do_read__copied(self):\n        cdef:\n            list data\n            bytes first, chunk = b'1'\n            bint zero = True, one = False\n\n        try:\n            while (<Py_ssize_t>self._incoming.pending > 0 or\n                   <Py_ssize_t>self._sslobj_pending() > 0):\n                chunk = self._sslobj_read(SSL_READ_MAX_SIZE)\n                if not chunk:\n                    break\n                if zero:\n                    zero = False\n                    one = True\n                    first = chunk\n                elif one:\n                    one = False\n                    data = [first, chunk]\n                else:\n                    data.append(chunk)\n        except ssl_SSLAgainErrors as exc:\n            pass\n        if one:\n            self._app_protocol.data_received(first)\n        elif not zero:\n            self._app_protocol.data_received(b''.join(data))\n        if not chunk:\n            # close_notify\n            self._call_eof_received()\n            self._start_shutdown()\n\n    cdef _call_eof_received(self, object context=None):\n        if self._app_state == STATE_CON_MADE:\n            self._app_state = STATE_EOF\n            try:\n                if context is None:\n                    # If the caller didn't provide a context, we assume the\n                    # caller is already in the right context, which is usually\n                    # inside the upstream callbacks like buffer_updated()\n                    keep_open = self._app_protocol.eof_received()\n                else:\n                    keep_open = run_in_context(\n                        context, self._app_protocol.eof_received,\n                    )\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException as ex:\n                self._fatal_error(ex, 'Error calling eof_received()')\n            else:\n                if keep_open:\n                    aio_logger.warning('returning true from eof_received() '\n                                       'has no effect when using ssl')\n\n    # Flow control for writes from APP socket\n\n    cdef _control_app_writing(self, object context=None):\n        cdef size_t size = self._get_write_buffer_size()\n        if size >= self._outgoing_high_water and not self._app_writing_paused:\n            self._app_writing_paused = True\n            try:\n                if context is None:\n                    # If the caller didn't provide a context, we assume the\n                    # caller is already in the right context, which is usually\n                    # inside the upstream callbacks like buffer_updated()\n                    self._app_protocol.pause_writing()\n                else:\n                    run_in_context(context, self._app_protocol.pause_writing)\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException as exc:\n                self._loop.call_exception_handler({\n                    'message': 'protocol.pause_writing() failed',\n                    'exception': exc,\n                    'transport': self._app_transport,\n                    'protocol': self,\n                })\n        elif size <= self._outgoing_low_water and self._app_writing_paused:\n            self._app_writing_paused = False\n            try:\n                if context is None:\n                    # If the caller didn't provide a context, we assume the\n                    # caller is already in the right context, which is usually\n                    # inside the upstream callbacks like resume_writing()\n                    self._app_protocol.resume_writing()\n                else:\n                    run_in_context(context, self._app_protocol.resume_writing)\n            except (KeyboardInterrupt, SystemExit):\n                raise\n            except BaseException as exc:\n                self._loop.call_exception_handler({\n                    'message': 'protocol.resume_writing() failed',\n                    'exception': exc,\n                    'transport': self._app_transport,\n                    'protocol': self,\n                })\n\n    cdef size_t _get_write_buffer_size(self):\n        return self._outgoing.pending + self._write_buffer_size\n\n    cdef _set_write_buffer_limits(self, high=None, low=None):\n        high, low = add_flowcontrol_defaults(\n            high, low, FLOW_CONTROL_HIGH_WATER_SSL_WRITE)\n        self._outgoing_high_water = high\n        self._outgoing_low_water = low\n\n    # Flow control for reads to APP socket\n\n    cdef _pause_reading(self):\n        self._app_reading_paused = True\n\n    cdef _resume_reading(self, object context):\n        if self._app_reading_paused:\n            self._app_reading_paused = False\n            if self._state == WRAPPED:\n                self._loop._call_soon_handle(\n                    new_MethodHandle(self._loop,\n                                     \"SSLProtocol._do_read\",\n                                     <method_t>self._do_read,\n                                     context,\n                                     self))\n\n    # Flow control for reads from SSL socket\n\n    cdef _control_ssl_reading(self):\n        cdef size_t size = self._get_read_buffer_size()\n        if size >= self._incoming_high_water and not self._ssl_reading_paused:\n            self._ssl_reading_paused = True\n            self._transport.pause_reading()\n        elif size <= self._incoming_low_water and self._ssl_reading_paused:\n            self._ssl_reading_paused = False\n            self._transport.resume_reading()\n\n    cdef _set_read_buffer_limits(self, high=None, low=None):\n        high, low = add_flowcontrol_defaults(\n            high, low, FLOW_CONTROL_HIGH_WATER_SSL_READ)\n        self._incoming_high_water = high\n        self._incoming_low_water = low\n\n    cdef size_t _get_read_buffer_size(self):\n        return self._incoming.pending\n\n    # Flow control for writes to SSL socket\n\n    def pause_writing(self):\n        \"\"\"Called when the low-level transport's buffer goes over\n        the high-water mark.\n        \"\"\"\n        assert not self._ssl_writing_paused\n        self._ssl_writing_paused = True\n\n    def resume_writing(self):\n        \"\"\"Called when the low-level transport's buffer drains below\n        the low-water mark.\n        \"\"\"\n        assert self._ssl_writing_paused\n        self._ssl_writing_paused = False\n\n        if self._state == WRAPPED:\n            self._process_outgoing()\n            self._control_app_writing()\n\n        elif self._state == FLUSHING:\n            self._do_flush()\n\n        elif self._state == SHUTDOWN:\n            self._do_shutdown()\n\n    cdef _fatal_error(self, exc, message='Fatal error on transport'):\n        if self._app_transport:\n            self._app_transport._force_close(exc)\n        elif self._transport:\n            self._transport._force_close(exc)\n\n        if isinstance(exc, OSError):\n            if self._loop.get_debug():\n                aio_logger.debug(\"%r: %s\", self, message, exc_info=True)\n        elif not isinstance(exc, aio_CancelledError):\n            self._loop.call_exception_handler({\n                'message': message,\n                'exception': exc,\n                'transport': self._transport,\n                'protocol': self,\n            })\n"
  }
]