diff options
| author | Piotr Ożarowski <piotr@debian.org> | 2018-12-31 18:15:56 +0100 |
|---|---|---|
| committer | git-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com> | 2018-12-31 22:37:36 +0000 |
| commit | c0cd50fda931c94280c4d509fe77398d21c0b424 (patch) | |
| tree | 16a41263e70985c030d877368cd29cf7da2c0d5b | |
| parent | 0ea2cd99ce6fd962409f68c75e41671f63f468f4 (diff) | |
3.5.1-1 (patches unapplied)import/3.5.1-1ubuntu/disco-proposedubuntu/disco-develubuntu/disco
Imported using git-ubuntu import.
Notes
Notes:
* New upstream release
* Remove idna_ssl patch - no longer needed in Python >= 3.7
* Standards-Version bumped to 4.3.0 (no changes needed)
163 files changed, 12024 insertions, 8924 deletions
diff --git a/.appveyor.yml b/.appveyor.yml index 7d79701..c83b66c 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -17,13 +17,14 @@ install: - "tools/build.cmd %PYTHON%\\python.exe -m pip install -r requirements/cython.txt" - "tools/build.cmd %PYTHON%\\python.exe -m pip install -r requirements/ci.txt" -build: false +build_script: + - "tools/build.cmd %PYTHON%\\python.exe -m setup sdist bdist_wheel" test_script: - - "tools/build.cmd %PYTHON%\\python.exe -m pytest tests" + - "tools/build.cmd %PYTHON%\\python.exe -m pytest -c pytest.ci.ini --cov-report xml" after_test: - - "tools/build.cmd %PYTHON%\\python.exe setup.py sdist bdist_wheel" + - "tools/build.cmd %PYTHON%\\python.exe -m codecov -f coverage.xml -X gcov" artifacts: - path: dist\* diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..9cf15d0 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,22 @@ +* @asvetlov +/.github/* @webknjaz @asvetlov +/.circleci/* @webknjaz @asvetlov +/CHANGES/* @asvetlov +/docs/* @asvetlov +/examples/* @asvetlov +/requirements/* @webknjaz @asvetlov +/tests/* @asvetlov +/tools/* @webknjaz @asvetlov +/vendor/* @webknjaz @asvetlov +*.ini @webknjaz @asvetlov +*.md @webknjaz @asvetlov +*.rst @webknjaz @asvetlov +*.toml @webknjaz @asvetlov +*.txt @webknjaz @asvetlov +*.yml @webknjaz @asvetlov +*.yaml @webknjaz @asvetlov +.editorconfig @webknjaz @asvetlov +.git* @webknjaz +Makefile @webknjaz @asvetlov +setup.py @webknjaz @asvetlov +setup.cfg @webknjaz @asvetlov diff --git a/.travis.yml b/.travis.yml index 0206c84..2666be5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,17 @@ +conditions: v1 version: "= 0" +if: > # Forbid running non-PR pushes from pyup bot + not (type != pull_request AND branch =~ ^pyup\-scheduled\-update\-) -sudo: false +dist: xenial +sudo: required language: python python: - 3.5 -- &mainstream_python 3.6 -- 3.7-dev +- 3.6 +- &mainstream_python 3.7 - nightly - &pypy3 pypy3.5 @@ -17,8 +21,6 @@ install: - pip install -r requirements/ci.txt script: -- make cov-ci-no-ext -- make cov-ci-aio-debug - make cov-ci-run after_success: @@ -80,7 +82,7 @@ _helpers: skip_cleanup: true # `skip-existing: true` is required to skip uploading dists, already # present in PYPI instead of failing the whole process. - # This happenes when other CI (AppVeyor etc.) has already uploaded + # This happens when other CI (AppVeyor etc.) has already uploaded # the very same dist (usually sdist). skip-existing: true user: aio-libs-bot @@ -136,23 +138,21 @@ os: linux jobs: fast_finish: true allow_failures: - - python: 3.7-dev - python: nightly include: - - python: 3.7 - dist: xenial - sudo: required + - name: 3.7 without extensions + python: 3.7 + env: + AIOHTTP_NO_EXTENSIONS: 1 - <<: *_doc_base - env: - - TARGET=docs + name: Checking docs spelling script: - make doc-spelling - <<: *_doc_base - env: - - TARGET=towncrier + name: Checking Towncrier fragments install: - *upgrade_python_toolset - pip install -r requirements/cython.txt @@ -162,8 +162,7 @@ jobs: - towncrier --yes - <<: *_lint_base - env: - - TARGET=flake8 + name: Linting source code with flake8 install: - *upgrade_python_toolset - pip install -r requirements/flake.txt @@ -171,14 +170,31 @@ jobs: - flake8 aiohttp examples tests - <<: *_lint_base - env: - - TARGET="'dist setup check'" + name: Linting source code with mypy + install: + - *upgrade_python_toolset + - pip install -r requirements/cython.txt + - pip install -r requirements/ci.txt + script: + - mypy aiohttp + + - <<: *_lint_base + name: Verifying distribution package metadata install: - *upgrade_python_toolset - pip install -r requirements/cython.txt - pip install -r requirements/ci.txt -r requirements/doc.txt script: - - python setup.py check --metadata --restructuredtext --strict --verbose + - python setup.py check --metadata --restructuredtext --strict --verbose sdist bdist_wheel + - twine check dist/* + + - <<: *_lint_base + name: Making sure that CONTRIBUTORS.txt remains sorted + language: minimal + install: + - skip + script: + - LC_ALL=C sort -c CONTRIBUTORS.txt - <<: *osx_python_base python: 3.5.3 @@ -210,8 +226,6 @@ jobs: - <<: *generic_deploy_base <<: *_reset_steps env: Build and deploy to PYPI of manylinux1 binary wheels for all supported Pythons and source distribution= - dist: trusty - group: edge services: - docker script: diff --git a/CHANGES.rst b/CHANGES.rst index 46a4d91..e93c0ac 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,83 +14,92 @@ Changelog .. towncrier release notes start -3.4.4 (2018-09-05) -================== +3.5.1 (2018-12-24) +==================== -- Fix installation from sources when compiling toolkit is not available (`#3241 <https://github.com/aio-libs/aiohttp/pull/3241>`_) +- Fix a regression about ``ClientSession._requote_redirect_url`` modification in debug + mode. -3.4.3 (2018-09-04) -================== +3.5.0 (2018-12-22) +==================== -- Add ``app.pre_frozen`` state to properly handle startup signals in sub-applications. (`#3237 <https://github.com/aio-libs/aiohttp/pull/3237>`_) - - -3.4.2 (2018-09-01) -================== - -- Fix ``iter_chunks`` type annotation (`#3230 <https://github.com/aio-libs/aiohttp/pull/3230>`_) - -3.4.1 (2018-08-28) -================== - -- Fix empty header parsing regression. (`#3218 <https://github.com/aio-libs/aiohttp/pull/3218>`_) -- Fix BaseRequest.raw_headers doc. (`#3215 <https://github.com/aio-libs/aiohttp/pull/3215>`_) -- Fix documentation building on ReadTheDocs (`#3221 <https://github.com/aio-libs/aiohttp/pull/3221>`_) +Features +-------- +- The library type annotations are checked in strict mode now. +- Add support for setting cookies for individual request (`#2387 <https://github.com/aio-libs/aiohttp/pull/2387>`_) +- Application.add_domain implementation (`#2809 <https://github.com/aio-libs/aiohttp/pull/2809>`_) +- The default ``app`` in the request returned by ``test_utils.make_mocked_request`` + can now have objects assigned to it and retrieved using the ``[]`` operator. (`#3174 <https://github.com/aio-libs/aiohttp/pull/3174>`_) +- Make ``request.url`` accessible when transport is closed. (`#3177 <https://github.com/aio-libs/aiohttp/pull/3177>`_) +- Add ``zlib_executor_size`` argument to ``Response`` constructor to allow compression to run in a background executor to avoid blocking the main thread and potentially triggering health check failures. (`#3205 <https://github.com/aio-libs/aiohttp/pull/3205>`_) +- Enable users to set `ClientTimeout` in `aiohttp.request` (`#3213 <https://github.com/aio-libs/aiohttp/pull/3213>`_) +- Don't raise a warning if ``NETRC`` environment variable is not set and ``~/.netrc`` file + doesn't exist. (`#3267 <https://github.com/aio-libs/aiohttp/pull/3267>`_) +- Add default logging handler to web.run_app -3.4.0 (2018-08-25) -================== + If the `Application.debug` flag is set and the default logger `aiohttp.access` is used, access logs will now be output using a `stderr` `StreamHandler` if no handlers are attached. Furthermore, if the default logger has no log level set, the log level will be set to `DEBUG`. (`#3324 <https://github.com/aio-libs/aiohttp/pull/3324>`_) +- Add method argument to ``session.ws_connect()``. -Features --------- + Sometimes server API requires a different HTTP method for WebSocket connection establishment. -- Add type hints (`#3049 <https://github.com/aio-libs/aiohttp/pull/3049>`_) -- Add ``raise_for_status`` request parameter (`#3073 <https://github.com/aio-libs/aiohttp/pull/3073>`_) -- Add type hints to HTTP client (`#3092 <https://github.com/aio-libs/aiohttp/pull/3092>`_) -- Minor server optimizations (`#3095 <https://github.com/aio-libs/aiohttp/pull/3095>`_) -- Preserve the cause when `HTTPException` is raised from another exception. (`#3096 <https://github.com/aio-libs/aiohttp/pull/3096>`_) -- Add `close_boundary` option in `MultipartWriter.write` method. Support streaming (`#3104 <https://github.com/aio-libs/aiohttp/pull/3104>`_) -- Added a ``remove_slash`` option to the ``normalize_path_middleware`` factory. (`#3173 <https://github.com/aio-libs/aiohttp/pull/3173>`_) -- The class `AbstractRouteDef` is importable from `aiohttp.web`. (`#3183 <https://github.com/aio-libs/aiohttp/pull/3183>`_) + For example, ``Docker exec`` needs POST. (`#3378 <https://github.com/aio-libs/aiohttp/pull/3378>`_) +- Create a task per request handling. (`#3406 <https://github.com/aio-libs/aiohttp/pull/3406>`_) Bugfixes -------- -- Prevent double closing when client connection is released before the - last ``data_received()`` callback. (`#3031 <https://github.com/aio-libs/aiohttp/pull/3031>`_) -- Make redirect with `normalize_path_middleware` work when using url encoded paths. (`#3051 <https://github.com/aio-libs/aiohttp/pull/3051>`_) -- Postpone web task creation to connection establishment. (`#3052 <https://github.com/aio-libs/aiohttp/pull/3052>`_) -- Fix ``sock_read`` timeout. (`#3053 <https://github.com/aio-libs/aiohttp/pull/3053>`_) -- When using a server-request body as the `data=` argument of a client request, iterate over the content with `readany` instead of `readline` to avoid `Line too long` errors. (`#3054 <https://github.com/aio-libs/aiohttp/pull/3054>`_) -- fix `UrlDispatcher` has no attribute `add_options`, add `web.options` (`#3062 <https://github.com/aio-libs/aiohttp/pull/3062>`_) -- correct filename in content-disposition with multipart body (`#3064 <https://github.com/aio-libs/aiohttp/pull/3064>`_) -- Many HTTP proxies has buggy keepalive support. - Let's not reuse connection but close it after processing every response. (`#3070 <https://github.com/aio-libs/aiohttp/pull/3070>`_) -- raise 413 "Payload Too Large" rather than raising ValueError in request.post() - Add helpful debug message to 413 responses (`#3087 <https://github.com/aio-libs/aiohttp/pull/3087>`_) -- Fix `StreamResponse` equality, now that they are `MutableMapping` objects. (`#3100 <https://github.com/aio-libs/aiohttp/pull/3100>`_) -- Fix server request objects comparison (`#3116 <https://github.com/aio-libs/aiohttp/pull/3116>`_) -- Do not hang on `206 Partial Content` response with `Content-Encoding: gzip` (`#3123 <https://github.com/aio-libs/aiohttp/pull/3123>`_) -- Fix timeout precondition checkers (`#3145 <https://github.com/aio-libs/aiohttp/pull/3145>`_) +- Enable passing `access_log_class` via `handler_args` (`#3158 <https://github.com/aio-libs/aiohttp/pull/3158>`_) +- Return empty bytes with end-of-chunk marker in empty stream reader. (`#3186 <https://github.com/aio-libs/aiohttp/pull/3186>`_) +- Accept ``CIMultiDictProxy`` instances for ``headers`` argument in ``web.Response`` + constructor. (`#3207 <https://github.com/aio-libs/aiohttp/pull/3207>`_) +- Don't uppercase HTTP method in parser (`#3233 <https://github.com/aio-libs/aiohttp/pull/3233>`_) +- Make method match regexp RFC-7230 compliant (`#3235 <https://github.com/aio-libs/aiohttp/pull/3235>`_) +- Add ``app.pre_frozen`` state to properly handle startup signals in sub-applications. (`#3237 <https://github.com/aio-libs/aiohttp/pull/3237>`_) +- Enhanced parsing and validation of helpers.BasicAuth.decode. (`#3239 <https://github.com/aio-libs/aiohttp/pull/3239>`_) +- Change imports from collections module in preparation for 3.8. (`#3258 <https://github.com/aio-libs/aiohttp/pull/3258>`_) +- Ensure Host header is added first to ClientRequest to better replicate browser (`#3265 <https://github.com/aio-libs/aiohttp/pull/3265>`_) +- Fix forward compatibility with Python 3.8: importing ABCs directly from the collections module will not be supported anymore. (`#3273 <https://github.com/aio-libs/aiohttp/pull/3273>`_) +- Keep the query string by `normalize_path_middleware`. (`#3278 <https://github.com/aio-libs/aiohttp/pull/3278>`_) +- Fix missing parameter ``raise_for_status`` for aiohttp.request() (`#3290 <https://github.com/aio-libs/aiohttp/pull/3290>`_) +- Bracket IPv6 addresses in the HOST header (`#3304 <https://github.com/aio-libs/aiohttp/pull/3304>`_) +- Fix default message for server ping and pong frames. (`#3308 <https://github.com/aio-libs/aiohttp/pull/3308>`_) +- Fix tests/test_connector.py typo and tests/autobahn/server.py duplicate loop def. (`#3337 <https://github.com/aio-libs/aiohttp/pull/3337>`_) +- Fix false-negative indicator end_of_HTTP_chunk in StreamReader.readchunk function (`#3361 <https://github.com/aio-libs/aiohttp/pull/3361>`_) +- Release HTTP response before raising status exception (`#3364 <https://github.com/aio-libs/aiohttp/pull/3364>`_) +- Fix task cancellation when ``sendfile()`` syscall is used by static file handling. (`#3383 <https://github.com/aio-libs/aiohttp/pull/3383>`_) +- Fix stack trace for ``asyncio.TimeoutError`` which was not logged, when it is caught + in the handler. (`#3414 <https://github.com/aio-libs/aiohttp/pull/3414>`_) Improved Documentation ---------------------- -- Add a new FAQ entry that clarifies that you should not reuse response - objects in middleware functions. (`#3020 <https://github.com/aio-libs/aiohttp/pull/3020>`_) -- Add FAQ section "Why is creating a ClientSession outside of an event loop dangerous?" (`#3072 <https://github.com/aio-libs/aiohttp/pull/3072>`_) -- Fix link to Rambler (`#3115 <https://github.com/aio-libs/aiohttp/pull/3115>`_) -- Fix TCPSite documentation on the Server Reference page. (`#3146 <https://github.com/aio-libs/aiohttp/pull/3146>`_) -- Fix documentation build configuration file for Windows. (`#3147 <https://github.com/aio-libs/aiohttp/pull/3147>`_) -- Remove no longer existing lingering_timeout parameter of Application.make_handler from documentation. (`#3151 <https://github.com/aio-libs/aiohttp/pull/3151>`_) -- Mention that ``app.make_handler`` is deprecated, recommend to use runners - API instead. (`#3157 <https://github.com/aio-libs/aiohttp/pull/3157>`_) +- Improve documentation of ``Application.make_handler`` parameters. (`#3152 <https://github.com/aio-libs/aiohttp/pull/3152>`_) +- Fix BaseRequest.raw_headers doc. (`#3215 <https://github.com/aio-libs/aiohttp/pull/3215>`_) +- Fix typo in TypeError exception reason in ``web.Application._handle`` (`#3229 <https://github.com/aio-libs/aiohttp/pull/3229>`_) +- Make server access log format placeholder %b documentation reflect + behavior and docstring. (`#3307 <https://github.com/aio-libs/aiohttp/pull/3307>`_) Deprecations and Removals ------------------------- -- Drop ``loop.current_task()`` from ``helpers.current_task()`` (`#2826 <https://github.com/aio-libs/aiohttp/pull/2826>`_) -- Drop ``reader`` parameter from ``request.multipart()``. (`#3090 <https://github.com/aio-libs/aiohttp/pull/3090>`_) +- Deprecate modification of ``session.requote_redirect_url`` (`#2278 <https://github.com/aio-libs/aiohttp/pull/2278>`_) +- Deprecate ``stream.unread_data()`` (`#3260 <https://github.com/aio-libs/aiohttp/pull/3260>`_) +- Deprecated use of boolean in ``resp.enable_compression()`` (`#3318 <https://github.com/aio-libs/aiohttp/pull/3318>`_) +- Encourage creation of aiohttp public objects inside a coroutine (`#3331 <https://github.com/aio-libs/aiohttp/pull/3331>`_) +- Drop dead ``Connection.detach()`` and ``Connection.writer``. Both methods were broken + for more than 2 years. (`#3358 <https://github.com/aio-libs/aiohttp/pull/3358>`_) +- Deprecate ``app.loop``, ``request.loop``, ``client.loop`` and ``connector.loop`` properties. (`#3374 <https://github.com/aio-libs/aiohttp/pull/3374>`_) +- Deprecate explicit debug argument. Use asyncio debug mode instead. (`#3381 <https://github.com/aio-libs/aiohttp/pull/3381>`_) +- Deprecate body parameter in HTTPException (and derived classes) constructor. (`#3385 <https://github.com/aio-libs/aiohttp/pull/3385>`_) +- Deprecate bare connector close, use ``async with connector:`` and ``await connector.close()`` instead. (`#3417 <https://github.com/aio-libs/aiohttp/pull/3417>`_) +- Deprecate obsolete ``read_timeout`` and ``conn_timeout`` in ``ClientSession`` constructor. (`#3438 <https://github.com/aio-libs/aiohttp/pull/3438>`_) + + +Misc +---- + +- #3341, #3351 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 147d8cb..5cfd24d 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -1,6 +1,7 @@ -Contributors ------------- +- Contributors - +---------------- A. Jesse Jiryu Davis +Adam Cooper Adam Mills Adrián Chaves Alec Hanefeld @@ -30,6 +31,7 @@ Andrej Antonov Andrew Leech Andrew Lytvyn Andrew Svetlov +Andrew Zhou Andrii Soldatenko Antoine Pietri Anton Kasyanov @@ -52,6 +54,7 @@ Chris Laws Chris Moore Christopher Schmitt Claudiu Popa +Colin Dunklau Damien Nadé Dan Xu Daniel García @@ -63,11 +66,13 @@ Denilson Amorim Denis Matiychuk Dima Veselov Dimitar Dimitrov +Dmitriy Safonov Dmitry Doroshev +Dmitry Lukashin Dmitry Shamov Dmitry Trofimov +Dmytro Bohomiakov Dmytro Kuznetsov -Dmitriy Safonov Dustin J. Mitchell Eduard Iskandarov Eli Ribble @@ -86,23 +91,29 @@ Gennady Andreyev Georges Dubus Greg Holt Gregory Haynes -Günther Jena +Gus Goulart Gustavo Carneiro +Günther Jena +Hans Adema +Harmon Y. Hu Bo Hugo Herter Hynek Schlawack Igor Alexandrov Igor Davydenko +Igor Mozharovsky Igor Pavlov Ingmar Steen Jacob Champion Jaesung Lee Jake Davis +Jakob Ackermann Jakub Wilk Jashandeep Sohi Jeongkyu Shin Jeroen van der Heijden Jesus Cea +Jian Zeng Jinkyu Yi Joel Watts Jon Nabozny @@ -121,13 +132,13 @@ Kirill Klenov Kirill Malovitsa Kyrylo Perevozchikov Lars P. Søndergaard -Loïc Lajeanne Louis-Philippe Huberdeau +Loïc Lajeanne Lu Gong Lubomir Gelo Ludovic Gasc -Lukasz Marcin Dobrzanski Luis Pedrosa +Lukasz Marcin Dobrzanski Makc Belousow Manuel Miranda Marat Sharafutdinov @@ -141,13 +152,16 @@ Matthieu Rigal Michael Ihnatenko Mikhail Kashkin Mikhail Lukyanchenko +Mikhail Nacharov Misha Behersky +Mitchell Ferree Morgan Delahaye-Prat Moss Collum Mun Gwan-gyeong Nicolas Braem Nikolay Kim Nikolay Novik +Oisin Aylward Olaf Conradi Pahaz Blinov Panagiotis Kolokotronis @@ -157,6 +171,8 @@ Paul Colomiets Paulius Šileikis Paulus Schoutsen Pavel Kamaev +Pavel Polyakov +Pawel Kowalski Pawel Miech Pepe Osca Philipp A. @@ -168,9 +184,10 @@ Robert Lu Roman Podoliaka Samuel Colvin Sean Hunt -Sebastien Geffroy +Sebastian Acuna Sebastian Hanula Sebastian Hüther +Sebastien Geffroy SeongSoo Cho Sergey Ninua Sergey Skripnick @@ -189,8 +206,10 @@ Taras Voinarovskyi Terence Honles Thanos Lefteris Thijs Vermeir +Thomas Forbes Thomas Grainger Tolga Tezel +Tomasz Trebski Trinh Hoang Nhu Vadim Suharnikov Vaibhav Sagar @@ -200,6 +219,8 @@ Vasyl Baran Victor Kovtun Vikas Kawadia Viktor Danyliuk +Ville Skyttä +Vincent Maillol Vitalik Verhovodov Vitaly Haritonsky Vitaly Magerya @@ -209,17 +230,18 @@ Vladimir Shulyak Vladimir Zakharov Vladyslav Bondar W. Trevor King +Wei Lin +Weiwei Wang Will McGugan Willem de Groot William Grzybowski Wilson Ong -Wei Lin -Weiwei Wang Yang Zhou Yannick Koechlin Yannick Péroux Ye Cao Yegor Roganov +Yifei Kong Young-Ho Cha Yuriy Shatrov Yury Selivanov diff --git a/HISTORY.rst b/HISTORY.rst index 6ceaf35..44c1484 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,3 +1,83 @@ +3.4.4 (2018-09-05) +================== + +- Fix installation from sources when compiling toolkit is not available (`#3241 <https://github.com/aio-libs/aiohttp/pull/3241>`_) + +3.4.3 (2018-09-04) +================== + +- Add ``app.pre_frozen`` state to properly handle startup signals in sub-applications. (`#3237 <https://github.com/aio-libs/aiohttp/pull/3237>`_) + + +3.4.2 (2018-09-01) +================== + +- Fix ``iter_chunks`` type annotation (`#3230 <https://github.com/aio-libs/aiohttp/pull/3230>`_) + +3.4.1 (2018-08-28) +================== + +- Fix empty header parsing regression. (`#3218 <https://github.com/aio-libs/aiohttp/pull/3218>`_) +- Fix BaseRequest.raw_headers doc. (`#3215 <https://github.com/aio-libs/aiohttp/pull/3215>`_) +- Fix documentation building on ReadTheDocs (`#3221 <https://github.com/aio-libs/aiohttp/pull/3221>`_) + + +3.4.0 (2018-08-25) +================== + +Features +-------- + +- Add type hints (`#3049 <https://github.com/aio-libs/aiohttp/pull/3049>`_) +- Add ``raise_for_status`` request parameter (`#3073 <https://github.com/aio-libs/aiohttp/pull/3073>`_) +- Add type hints to HTTP client (`#3092 <https://github.com/aio-libs/aiohttp/pull/3092>`_) +- Minor server optimizations (`#3095 <https://github.com/aio-libs/aiohttp/pull/3095>`_) +- Preserve the cause when `HTTPException` is raised from another exception. (`#3096 <https://github.com/aio-libs/aiohttp/pull/3096>`_) +- Add `close_boundary` option in `MultipartWriter.write` method. Support streaming (`#3104 <https://github.com/aio-libs/aiohttp/pull/3104>`_) +- Added a ``remove_slash`` option to the ``normalize_path_middleware`` factory. (`#3173 <https://github.com/aio-libs/aiohttp/pull/3173>`_) +- The class `AbstractRouteDef` is importable from `aiohttp.web`. (`#3183 <https://github.com/aio-libs/aiohttp/pull/3183>`_) + + +Bugfixes +-------- + +- Prevent double closing when client connection is released before the + last ``data_received()`` callback. (`#3031 <https://github.com/aio-libs/aiohttp/pull/3031>`_) +- Make redirect with `normalize_path_middleware` work when using url encoded paths. (`#3051 <https://github.com/aio-libs/aiohttp/pull/3051>`_) +- Postpone web task creation to connection establishment. (`#3052 <https://github.com/aio-libs/aiohttp/pull/3052>`_) +- Fix ``sock_read`` timeout. (`#3053 <https://github.com/aio-libs/aiohttp/pull/3053>`_) +- When using a server-request body as the `data=` argument of a client request, iterate over the content with `readany` instead of `readline` to avoid `Line too long` errors. (`#3054 <https://github.com/aio-libs/aiohttp/pull/3054>`_) +- fix `UrlDispatcher` has no attribute `add_options`, add `web.options` (`#3062 <https://github.com/aio-libs/aiohttp/pull/3062>`_) +- correct filename in content-disposition with multipart body (`#3064 <https://github.com/aio-libs/aiohttp/pull/3064>`_) +- Many HTTP proxies has buggy keepalive support. + Let's not reuse connection but close it after processing every response. (`#3070 <https://github.com/aio-libs/aiohttp/pull/3070>`_) +- raise 413 "Payload Too Large" rather than raising ValueError in request.post() + Add helpful debug message to 413 responses (`#3087 <https://github.com/aio-libs/aiohttp/pull/3087>`_) +- Fix `StreamResponse` equality, now that they are `MutableMapping` objects. (`#3100 <https://github.com/aio-libs/aiohttp/pull/3100>`_) +- Fix server request objects comparison (`#3116 <https://github.com/aio-libs/aiohttp/pull/3116>`_) +- Do not hang on `206 Partial Content` response with `Content-Encoding: gzip` (`#3123 <https://github.com/aio-libs/aiohttp/pull/3123>`_) +- Fix timeout precondition checkers (`#3145 <https://github.com/aio-libs/aiohttp/pull/3145>`_) + + +Improved Documentation +---------------------- + +- Add a new FAQ entry that clarifies that you should not reuse response + objects in middleware functions. (`#3020 <https://github.com/aio-libs/aiohttp/pull/3020>`_) +- Add FAQ section "Why is creating a ClientSession outside of an event loop dangerous?" (`#3072 <https://github.com/aio-libs/aiohttp/pull/3072>`_) +- Fix link to Rambler (`#3115 <https://github.com/aio-libs/aiohttp/pull/3115>`_) +- Fix TCPSite documentation on the Server Reference page. (`#3146 <https://github.com/aio-libs/aiohttp/pull/3146>`_) +- Fix documentation build configuration file for Windows. (`#3147 <https://github.com/aio-libs/aiohttp/pull/3147>`_) +- Remove no longer existing lingering_timeout parameter of Application.make_handler from documentation. (`#3151 <https://github.com/aio-libs/aiohttp/pull/3151>`_) +- Mention that ``app.make_handler`` is deprecated, recommend to use runners + API instead. (`#3157 <https://github.com/aio-libs/aiohttp/pull/3157>`_) + + +Deprecations and Removals +------------------------- + +- Drop ``loop.current_task()`` from ``helpers.current_task()`` (`#2826 <https://github.com/aio-libs/aiohttp/pull/2826>`_) +- Drop ``reader`` parameter from ``request.multipart()``. (`#3090 <https://github.com/aio-libs/aiohttp/pull/3090>`_) 3.3.2 (2018-06-12) @@ -254,8 +334,8 @@ Improved Documentation ================== - Fix SSL proxy support by client. (`#2810 <https://github.com/aio-libs/aiohttp/pull/2810>`_) -- Restore a imperative check in ``setup.py`` for python version. The check - works in parallel to environment marker. As effect a error about unsupported +- Restore an imperative check in ``setup.py`` for python version. The check + works in parallel to environment marker. As effect an error about unsupported Python versions is raised even on outdated systems with very old ``setuptools`` version installed. (`#2813 <https://github.com/aio-libs/aiohttp/pull/2813>`_) @@ -2,11 +2,9 @@ all: test -install-cython: - @pip install -r requirements/cython.txt - -.install-deps: $(shell find requirements -type f) install-cython - @pip install -U -r requirements/dev.txt +.install-deps: $(shell find requirements -type f) + pip install -r requirements/cython.txt + pip install -r requirements/dev.txt @touch .install-deps isort: @@ -19,53 +17,48 @@ flake: .flake .flake: .install-deps $(shell find aiohttp -type f) \ $(shell find tests -type f) \ $(shell find examples -type f) - @flake8 aiohttp examples tests + flake8 aiohttp examples tests python setup.py check -rms @if ! isort -c -rc aiohttp tests examples; then \ echo "Import sort errors, run 'make isort' to fix them!!!"; \ isort --diff -rc aiohttp tests examples; \ false; \ fi + @if ! LC_ALL=C sort -c CONTRIBUTORS.txt; then \ + echo "CONTRIBUTORS.txt sort error"; \ + fi @touch .flake check_changes: - @./tools/check_changes.py + ./tools/check_changes.py mypy: .flake if python -c "import sys; sys.exit(sys.implementation.name!='cpython')"; then \ - mypy aiohttp tests; \ + mypy aiohttp; \ fi .develop: .install-deps $(shell find aiohttp -type f) .flake check_changes mypy - @pip install -e . + # pip install -e . @touch .develop test: .develop - @pytest -q ./tests + @pytest -c pytest.ci.ini -q vtest: .develop - @pytest -s -v ./tests + @pytest -c pytest.ci.ini -s -v cov cover coverage: tox cov-dev: .develop - @echo "Run without extensions" - @AIOHTTP_NO_EXTENSIONS=1 pytest --cov=aiohttp tests - @pytest --cov=aiohttp --cov-report=term --cov-report=html --cov-append tests + @pytest -c pytest.ci.ini --cov-report=html @echo "open file://`pwd`/htmlcov/index.html" -cov-ci-no-ext: .develop - @echo "Run without extensions" - @AIOHTTP_NO_EXTENSIONS=1 pytest --cov=aiohttp tests -cov-ci-aio-debug: .develop - @echo "Run in debug mode" - @PYTHONASYNCIODEBUG=1 pytest --cov=aiohttp --cov-append tests cov-ci-run: .develop @echo "Regular run" - @pytest --cov=aiohttp --cov-report=term --cov-report=html --cov-append tests + @pytest -c pytest.ci.ini --cov-report=html -cov-dev-full: cov-ci-no-ext cov-ci-aio-debug cov-ci-run +cov-dev-full: cov-ci-run @echo "open file://`pwd`/htmlcov/index.html" clean: @@ -1,6 +1,6 @@ -Metadata-Version: 1.2
+Metadata-Version: 2.1
Name: aiohttp
-Version: 3.4.4
+Version: 3.5.1
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author: Nikolay Kim
@@ -8,15 +8,15 @@ Author-email: fafhrd91@gmail.com Maintainer: Nikolay Kim <fafhrd91@gmail.com>, Andrew Svetlov <andrew.svetlov@gmail.com>
Maintainer-email: aio-libs@googlegroups.com
License: Apache 2
-Project-URL: GitHub: repo, https://github.com/aio-libs/aiohttp
+Project-URL: CI: Circle, https://circleci.com/gh/aio-libs/aiohttp
Project-URL: CI: Shippable, https://app.shippable.com/github/aio-libs/aiohttp
-Project-URL: GitHub: issues, https://github.com/aio-libs/aiohttp/issues
+Project-URL: Docs: RTD, https://docs.aiohttp.org
+Project-URL: GitHub: repo, https://github.com/aio-libs/aiohttp
Project-URL: Chat: Gitter, https://gitter.im/aio-libs/Lobby
-Project-URL: CI: Circle, https://circleci.com/gh/aio-libs/aiohttp
+Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/aiohttp
Project-URL: CI: AppVeyor, https://ci.appveyor.com/project/aio-libs/aiohttp
Project-URL: CI: Travis, https://travis-ci.com/aio-libs/aiohttp
-Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/aiohttp
-Project-URL: Docs: RTD, https://docs.aiohttp.org
+Project-URL: GitHub: issues, https://github.com/aio-libs/aiohttp/issues
Description: ==================================
Async http client/server framework
==================================
@@ -47,7 +47,7 @@ Description: ================================== :alt: Latest PyPI package version
.. image:: https://readthedocs.org/projects/aiohttp/badge/?version=latest
- :target: http://docs.aiohttp.org/
+ :target: https://docs.aiohttp.org/
:alt: Latest Read The Docs
.. image:: https://badges.gitter.im/Join%20Chat.svg
@@ -58,9 +58,9 @@ Description: ================================== ============
- Supports both client and server side of HTTP protocol.
- - Supports both client and server Web-Sockets out-of-the-box without the
+ - Supports both client and server Web-Sockets out-of-the-box and avoids
Callback Hell.
- - Web-server has middlewares and pluggable routing.
+ - Provides Web-server with middlewares and pluggable routing.
Getting started
@@ -69,7 +69,7 @@ Description: ================================== Client
------
- To retrieve something from the web:
+ To get something from the web:
.. code-block:: python
@@ -93,10 +93,11 @@ Description: ================================== Server
------
- This is simple usage example:
+ An example using a simple server:
.. code-block:: python
+ # examples/server_simple.py
from aiohttp import web
async def handle(request):
@@ -196,20 +197,20 @@ Description: ================================== ========
The aiohttp community would like to thank Keepsafe
- (https://www.getkeepsafe.com) for it's support in the early days of
+ (https://www.getkeepsafe.com) for its support in the early days of
the project.
Source code
===========
- The latest developer version is available in a github repository:
+ The latest developer version is available in a GitHub repository:
https://github.com/aio-libs/aiohttp
Benchmarks
==========
- If you are interested in by efficiency, AsyncIO community maintains a
+ If you are interested in efficiency, the AsyncIO community maintains a
list of benchmarks on the official wiki:
https://github.com/python/asyncio/wiki/Benchmarks
@@ -229,86 +230,95 @@ Description: ================================== .. towncrier release notes start
- 3.4.4 (2018-09-05)
- ==================
-
- - Fix installation from sources when compiling toolkit is not available (`#3241 <https://github.com/aio-libs/aiohttp/pull/3241>`_)
-
- 3.4.3 (2018-09-04)
- ==================
-
- - Add ``app.pre_frozen`` state to properly handle startup signals in sub-applications. (`#3237 <https://github.com/aio-libs/aiohttp/pull/3237>`_)
+ 3.5.1 (2018-12-24)
+ ====================
+ - Fix a regression about ``ClientSession._requote_redirect_url`` modification in debug
+ mode.
- 3.4.2 (2018-09-01)
- ==================
+ 3.5.0 (2018-12-22)
+ ====================
- - Fix ``iter_chunks`` type annotation (`#3230 <https://github.com/aio-libs/aiohttp/pull/3230>`_)
+ Features
+ --------
- 3.4.1 (2018-08-28)
- ==================
+ - The library type annotations are checked in strict mode now.
+ - Add support for setting cookies for individual request (`#2387 <https://github.com/aio-libs/aiohttp/pull/2387>`_)
+ - Application.add_domain implementation (`#2809 <https://github.com/aio-libs/aiohttp/pull/2809>`_)
+ - The default ``app`` in the request returned by ``test_utils.make_mocked_request``
+ can now have objects assigned to it and retrieved using the ``[]`` operator. (`#3174 <https://github.com/aio-libs/aiohttp/pull/3174>`_)
+ - Make ``request.url`` accessible when transport is closed. (`#3177 <https://github.com/aio-libs/aiohttp/pull/3177>`_)
+ - Add ``zlib_executor_size`` argument to ``Response`` constructor to allow compression to run in a background executor to avoid blocking the main thread and potentially triggering health check failures. (`#3205 <https://github.com/aio-libs/aiohttp/pull/3205>`_)
+ - Enable users to set `ClientTimeout` in `aiohttp.request` (`#3213 <https://github.com/aio-libs/aiohttp/pull/3213>`_)
+ - Don't raise a warning if ``NETRC`` environment variable is not set and ``~/.netrc`` file
+ doesn't exist. (`#3267 <https://github.com/aio-libs/aiohttp/pull/3267>`_)
+ - Add default logging handler to web.run_app
- - Fix empty header parsing regression. (`#3218 <https://github.com/aio-libs/aiohttp/pull/3218>`_)
- - Fix BaseRequest.raw_headers doc. (`#3215 <https://github.com/aio-libs/aiohttp/pull/3215>`_)
- - Fix documentation building on ReadTheDocs (`#3221 <https://github.com/aio-libs/aiohttp/pull/3221>`_)
+ If the `Application.debug` flag is set and the default logger `aiohttp.access` is used, access logs will now be output using a `stderr` `StreamHandler` if no handlers are attached. Furthermore, if the default logger has no log level set, the log level will be set to `DEBUG`. (`#3324 <https://github.com/aio-libs/aiohttp/pull/3324>`_)
+ - Add method argument to ``session.ws_connect()``.
+ Sometimes server API requires a different HTTP method for WebSocket connection establishment.
- 3.4.0 (2018-08-25)
- ==================
-
- Features
- --------
-
- - Add type hints (`#3049 <https://github.com/aio-libs/aiohttp/pull/3049>`_)
- - Add ``raise_for_status`` request parameter (`#3073 <https://github.com/aio-libs/aiohttp/pull/3073>`_)
- - Add type hints to HTTP client (`#3092 <https://github.com/aio-libs/aiohttp/pull/3092>`_)
- - Minor server optimizations (`#3095 <https://github.com/aio-libs/aiohttp/pull/3095>`_)
- - Preserve the cause when `HTTPException` is raised from another exception. (`#3096 <https://github.com/aio-libs/aiohttp/pull/3096>`_)
- - Add `close_boundary` option in `MultipartWriter.write` method. Support streaming (`#3104 <https://github.com/aio-libs/aiohttp/pull/3104>`_)
- - Added a ``remove_slash`` option to the ``normalize_path_middleware`` factory. (`#3173 <https://github.com/aio-libs/aiohttp/pull/3173>`_)
- - The class `AbstractRouteDef` is importable from `aiohttp.web`. (`#3183 <https://github.com/aio-libs/aiohttp/pull/3183>`_)
+ For example, ``Docker exec`` needs POST. (`#3378 <https://github.com/aio-libs/aiohttp/pull/3378>`_)
+ - Create a task per request handling. (`#3406 <https://github.com/aio-libs/aiohttp/pull/3406>`_)
Bugfixes
--------
- - Prevent double closing when client connection is released before the
- last ``data_received()`` callback. (`#3031 <https://github.com/aio-libs/aiohttp/pull/3031>`_)
- - Make redirect with `normalize_path_middleware` work when using url encoded paths. (`#3051 <https://github.com/aio-libs/aiohttp/pull/3051>`_)
- - Postpone web task creation to connection establishment. (`#3052 <https://github.com/aio-libs/aiohttp/pull/3052>`_)
- - Fix ``sock_read`` timeout. (`#3053 <https://github.com/aio-libs/aiohttp/pull/3053>`_)
- - When using a server-request body as the `data=` argument of a client request, iterate over the content with `readany` instead of `readline` to avoid `Line too long` errors. (`#3054 <https://github.com/aio-libs/aiohttp/pull/3054>`_)
- - fix `UrlDispatcher` has no attribute `add_options`, add `web.options` (`#3062 <https://github.com/aio-libs/aiohttp/pull/3062>`_)
- - correct filename in content-disposition with multipart body (`#3064 <https://github.com/aio-libs/aiohttp/pull/3064>`_)
- - Many HTTP proxies has buggy keepalive support.
- Let's not reuse connection but close it after processing every response. (`#3070 <https://github.com/aio-libs/aiohttp/pull/3070>`_)
- - raise 413 "Payload Too Large" rather than raising ValueError in request.post()
- Add helpful debug message to 413 responses (`#3087 <https://github.com/aio-libs/aiohttp/pull/3087>`_)
- - Fix `StreamResponse` equality, now that they are `MutableMapping` objects. (`#3100 <https://github.com/aio-libs/aiohttp/pull/3100>`_)
- - Fix server request objects comparison (`#3116 <https://github.com/aio-libs/aiohttp/pull/3116>`_)
- - Do not hang on `206 Partial Content` response with `Content-Encoding: gzip` (`#3123 <https://github.com/aio-libs/aiohttp/pull/3123>`_)
- - Fix timeout precondition checkers (`#3145 <https://github.com/aio-libs/aiohttp/pull/3145>`_)
+ - Enable passing `access_log_class` via `handler_args` (`#3158 <https://github.com/aio-libs/aiohttp/pull/3158>`_)
+ - Return empty bytes with end-of-chunk marker in empty stream reader. (`#3186 <https://github.com/aio-libs/aiohttp/pull/3186>`_)
+ - Accept ``CIMultiDictProxy`` instances for ``headers`` argument in ``web.Response``
+ constructor. (`#3207 <https://github.com/aio-libs/aiohttp/pull/3207>`_)
+ - Don't uppercase HTTP method in parser (`#3233 <https://github.com/aio-libs/aiohttp/pull/3233>`_)
+ - Make method match regexp RFC-7230 compliant (`#3235 <https://github.com/aio-libs/aiohttp/pull/3235>`_)
+ - Add ``app.pre_frozen`` state to properly handle startup signals in sub-applications. (`#3237 <https://github.com/aio-libs/aiohttp/pull/3237>`_)
+ - Enhanced parsing and validation of helpers.BasicAuth.decode. (`#3239 <https://github.com/aio-libs/aiohttp/pull/3239>`_)
+ - Change imports from collections module in preparation for 3.8. (`#3258 <https://github.com/aio-libs/aiohttp/pull/3258>`_)
+ - Ensure Host header is added first to ClientRequest to better replicate browser (`#3265 <https://github.com/aio-libs/aiohttp/pull/3265>`_)
+ - Fix forward compatibility with Python 3.8: importing ABCs directly from the collections module will not be supported anymore. (`#3273 <https://github.com/aio-libs/aiohttp/pull/3273>`_)
+ - Keep the query string by `normalize_path_middleware`. (`#3278 <https://github.com/aio-libs/aiohttp/pull/3278>`_)
+ - Fix missing parameter ``raise_for_status`` for aiohttp.request() (`#3290 <https://github.com/aio-libs/aiohttp/pull/3290>`_)
+ - Bracket IPv6 addresses in the HOST header (`#3304 <https://github.com/aio-libs/aiohttp/pull/3304>`_)
+ - Fix default message for server ping and pong frames. (`#3308 <https://github.com/aio-libs/aiohttp/pull/3308>`_)
+ - Fix tests/test_connector.py typo and tests/autobahn/server.py duplicate loop def. (`#3337 <https://github.com/aio-libs/aiohttp/pull/3337>`_)
+ - Fix false-negative indicator end_of_HTTP_chunk in StreamReader.readchunk function (`#3361 <https://github.com/aio-libs/aiohttp/pull/3361>`_)
+ - Release HTTP response before raising status exception (`#3364 <https://github.com/aio-libs/aiohttp/pull/3364>`_)
+ - Fix task cancellation when ``sendfile()`` syscall is used by static file handling. (`#3383 <https://github.com/aio-libs/aiohttp/pull/3383>`_)
+ - Fix stack trace for ``asyncio.TimeoutError`` which was not logged, when it is caught
+ in the handler. (`#3414 <https://github.com/aio-libs/aiohttp/pull/3414>`_)
Improved Documentation
----------------------
- - Add a new FAQ entry that clarifies that you should not reuse response
- objects in middleware functions. (`#3020 <https://github.com/aio-libs/aiohttp/pull/3020>`_)
- - Add FAQ section "Why is creating a ClientSession outside of an event loop dangerous?" (`#3072 <https://github.com/aio-libs/aiohttp/pull/3072>`_)
- - Fix link to Rambler (`#3115 <https://github.com/aio-libs/aiohttp/pull/3115>`_)
- - Fix TCPSite documentation on the Server Reference page. (`#3146 <https://github.com/aio-libs/aiohttp/pull/3146>`_)
- - Fix documentation build configuration file for Windows. (`#3147 <https://github.com/aio-libs/aiohttp/pull/3147>`_)
- - Remove no longer existing lingering_timeout parameter of Application.make_handler from documentation. (`#3151 <https://github.com/aio-libs/aiohttp/pull/3151>`_)
- - Mention that ``app.make_handler`` is deprecated, recommend to use runners
- API instead. (`#3157 <https://github.com/aio-libs/aiohttp/pull/3157>`_)
+ - Improve documentation of ``Application.make_handler`` parameters. (`#3152 <https://github.com/aio-libs/aiohttp/pull/3152>`_)
+ - Fix BaseRequest.raw_headers doc. (`#3215 <https://github.com/aio-libs/aiohttp/pull/3215>`_)
+ - Fix typo in TypeError exception reason in ``web.Application._handle`` (`#3229 <https://github.com/aio-libs/aiohttp/pull/3229>`_)
+ - Make server access log format placeholder %b documentation reflect
+ behavior and docstring. (`#3307 <https://github.com/aio-libs/aiohttp/pull/3307>`_)
Deprecations and Removals
-------------------------
- - Drop ``loop.current_task()`` from ``helpers.current_task()`` (`#2826 <https://github.com/aio-libs/aiohttp/pull/2826>`_)
- - Drop ``reader`` parameter from ``request.multipart()``. (`#3090 <https://github.com/aio-libs/aiohttp/pull/3090>`_)
+ - Deprecate modification of ``session.requote_redirect_url`` (`#2278 <https://github.com/aio-libs/aiohttp/pull/2278>`_)
+ - Deprecate ``stream.unread_data()`` (`#3260 <https://github.com/aio-libs/aiohttp/pull/3260>`_)
+ - Deprecated use of boolean in ``resp.enable_compression()`` (`#3318 <https://github.com/aio-libs/aiohttp/pull/3318>`_)
+ - Encourage creation of aiohttp public objects inside a coroutine (`#3331 <https://github.com/aio-libs/aiohttp/pull/3331>`_)
+ - Drop dead ``Connection.detach()`` and ``Connection.writer``. Both methods were broken
+ for more than 2 years. (`#3358 <https://github.com/aio-libs/aiohttp/pull/3358>`_)
+ - Deprecate ``app.loop``, ``request.loop``, ``client.loop`` and ``connector.loop`` properties. (`#3374 <https://github.com/aio-libs/aiohttp/pull/3374>`_)
+ - Deprecate explicit debug argument. Use asyncio debug mode instead. (`#3381 <https://github.com/aio-libs/aiohttp/pull/3381>`_)
+ - Deprecate body parameter in HTTPException (and derived classes) constructor. (`#3385 <https://github.com/aio-libs/aiohttp/pull/3385>`_)
+ - Deprecate bare connector close, use ``async with connector:`` and ``await connector.close()`` instead. (`#3417 <https://github.com/aio-libs/aiohttp/pull/3417>`_)
+ - Deprecate obsolete ``read_timeout`` and ``conn_timeout`` in ``ClientSession`` constructor. (`#3438 <https://github.com/aio-libs/aiohttp/pull/3438>`_)
+
+
+ Misc
+ ----
+
+ - #3341, #3351
Platform: UNKNOWN
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Intended Audience :: Developers
@@ -324,3 +334,4 @@ Classifier: Operating System :: Microsoft :: Windows Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: AsyncIO
Requires-Python: >=3.5.3
+Provides-Extra: speedups
@@ -28,7 +28,7 @@ Async http client/server framework :alt: Latest PyPI package version .. image:: https://readthedocs.org/projects/aiohttp/badge/?version=latest - :target: http://docs.aiohttp.org/ + :target: https://docs.aiohttp.org/ :alt: Latest Read The Docs .. image:: https://badges.gitter.im/Join%20Chat.svg @@ -39,9 +39,9 @@ Key Features ============ - Supports both client and server side of HTTP protocol. -- Supports both client and server Web-Sockets out-of-the-box without the +- Supports both client and server Web-Sockets out-of-the-box and avoids Callback Hell. -- Web-server has middlewares and pluggable routing. +- Provides Web-server with middlewares and pluggable routing. Getting started @@ -50,7 +50,7 @@ Getting started Client ------ -To retrieve something from the web: +To get something from the web: .. code-block:: python @@ -74,10 +74,11 @@ To retrieve something from the web: Server ------ -This is simple usage example: +An example using a simple server: .. code-block:: python + # examples/server_simple.py from aiohttp import web async def handle(request): @@ -177,19 +178,19 @@ Keepsafe ======== The aiohttp community would like to thank Keepsafe -(https://www.getkeepsafe.com) for it's support in the early days of +(https://www.getkeepsafe.com) for its support in the early days of the project. Source code =========== -The latest developer version is available in a github repository: +The latest developer version is available in a GitHub repository: https://github.com/aio-libs/aiohttp Benchmarks ========== -If you are interested in by efficiency, AsyncIO community maintains a +If you are interested in efficiency, the AsyncIO community maintains a list of benchmarks on the official wiki: https://github.com/python/asyncio/wiki/Benchmarks diff --git a/aiohttp.egg-info/PKG-INFO b/aiohttp.egg-info/PKG-INFO index 35f9edd..03f5371 100644 --- a/aiohttp.egg-info/PKG-INFO +++ b/aiohttp.egg-info/PKG-INFO @@ -1,6 +1,6 @@ -Metadata-Version: 1.2
+Metadata-Version: 2.1
Name: aiohttp
-Version: 3.4.4
+Version: 3.5.1
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author: Nikolay Kim
@@ -8,15 +8,15 @@ Author-email: fafhrd91@gmail.com Maintainer: Nikolay Kim <fafhrd91@gmail.com>, Andrew Svetlov <andrew.svetlov@gmail.com>
Maintainer-email: aio-libs@googlegroups.com
License: Apache 2
-Project-URL: GitHub: repo, https://github.com/aio-libs/aiohttp
+Project-URL: CI: Circle, https://circleci.com/gh/aio-libs/aiohttp
Project-URL: CI: Shippable, https://app.shippable.com/github/aio-libs/aiohttp
-Project-URL: GitHub: issues, https://github.com/aio-libs/aiohttp/issues
+Project-URL: Docs: RTD, https://docs.aiohttp.org
+Project-URL: GitHub: repo, https://github.com/aio-libs/aiohttp
Project-URL: Chat: Gitter, https://gitter.im/aio-libs/Lobby
-Project-URL: CI: Circle, https://circleci.com/gh/aio-libs/aiohttp
+Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/aiohttp
Project-URL: CI: AppVeyor, https://ci.appveyor.com/project/aio-libs/aiohttp
Project-URL: CI: Travis, https://travis-ci.com/aio-libs/aiohttp
-Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/aiohttp
-Project-URL: Docs: RTD, https://docs.aiohttp.org
+Project-URL: GitHub: issues, https://github.com/aio-libs/aiohttp/issues
Description: ==================================
Async http client/server framework
==================================
@@ -47,7 +47,7 @@ Description: ================================== :alt: Latest PyPI package version
.. image:: https://readthedocs.org/projects/aiohttp/badge/?version=latest
- :target: http://docs.aiohttp.org/
+ :target: https://docs.aiohttp.org/
:alt: Latest Read The Docs
.. image:: https://badges.gitter.im/Join%20Chat.svg
@@ -58,9 +58,9 @@ Description: ================================== ============
- Supports both client and server side of HTTP protocol.
- - Supports both client and server Web-Sockets out-of-the-box without the
+ - Supports both client and server Web-Sockets out-of-the-box and avoids
Callback Hell.
- - Web-server has middlewares and pluggable routing.
+ - Provides Web-server with middlewares and pluggable routing.
Getting started
@@ -69,7 +69,7 @@ Description: ================================== Client
------
- To retrieve something from the web:
+ To get something from the web:
.. code-block:: python
@@ -93,10 +93,11 @@ Description: ================================== Server
------
- This is simple usage example:
+ An example using a simple server:
.. code-block:: python
+ # examples/server_simple.py
from aiohttp import web
async def handle(request):
@@ -196,20 +197,20 @@ Description: ================================== ========
The aiohttp community would like to thank Keepsafe
- (https://www.getkeepsafe.com) for it's support in the early days of
+ (https://www.getkeepsafe.com) for its support in the early days of
the project.
Source code
===========
- The latest developer version is available in a github repository:
+ The latest developer version is available in a GitHub repository:
https://github.com/aio-libs/aiohttp
Benchmarks
==========
- If you are interested in by efficiency, AsyncIO community maintains a
+ If you are interested in efficiency, the AsyncIO community maintains a
list of benchmarks on the official wiki:
https://github.com/python/asyncio/wiki/Benchmarks
@@ -229,86 +230,95 @@ Description: ================================== .. towncrier release notes start
- 3.4.4 (2018-09-05)
- ==================
-
- - Fix installation from sources when compiling toolkit is not available (`#3241 <https://github.com/aio-libs/aiohttp/pull/3241>`_)
-
- 3.4.3 (2018-09-04)
- ==================
-
- - Add ``app.pre_frozen`` state to properly handle startup signals in sub-applications. (`#3237 <https://github.com/aio-libs/aiohttp/pull/3237>`_)
+ 3.5.1 (2018-12-24)
+ ====================
+ - Fix a regression about ``ClientSession._requote_redirect_url`` modification in debug
+ mode.
- 3.4.2 (2018-09-01)
- ==================
+ 3.5.0 (2018-12-22)
+ ====================
- - Fix ``iter_chunks`` type annotation (`#3230 <https://github.com/aio-libs/aiohttp/pull/3230>`_)
+ Features
+ --------
- 3.4.1 (2018-08-28)
- ==================
+ - The library type annotations are checked in strict mode now.
+ - Add support for setting cookies for individual request (`#2387 <https://github.com/aio-libs/aiohttp/pull/2387>`_)
+ - Application.add_domain implementation (`#2809 <https://github.com/aio-libs/aiohttp/pull/2809>`_)
+ - The default ``app`` in the request returned by ``test_utils.make_mocked_request``
+ can now have objects assigned to it and retrieved using the ``[]`` operator. (`#3174 <https://github.com/aio-libs/aiohttp/pull/3174>`_)
+ - Make ``request.url`` accessible when transport is closed. (`#3177 <https://github.com/aio-libs/aiohttp/pull/3177>`_)
+ - Add ``zlib_executor_size`` argument to ``Response`` constructor to allow compression to run in a background executor to avoid blocking the main thread and potentially triggering health check failures. (`#3205 <https://github.com/aio-libs/aiohttp/pull/3205>`_)
+ - Enable users to set `ClientTimeout` in `aiohttp.request` (`#3213 <https://github.com/aio-libs/aiohttp/pull/3213>`_)
+ - Don't raise a warning if ``NETRC`` environment variable is not set and ``~/.netrc`` file
+ doesn't exist. (`#3267 <https://github.com/aio-libs/aiohttp/pull/3267>`_)
+ - Add default logging handler to web.run_app
- - Fix empty header parsing regression. (`#3218 <https://github.com/aio-libs/aiohttp/pull/3218>`_)
- - Fix BaseRequest.raw_headers doc. (`#3215 <https://github.com/aio-libs/aiohttp/pull/3215>`_)
- - Fix documentation building on ReadTheDocs (`#3221 <https://github.com/aio-libs/aiohttp/pull/3221>`_)
+ If the `Application.debug` flag is set and the default logger `aiohttp.access` is used, access logs will now be output using a `stderr` `StreamHandler` if no handlers are attached. Furthermore, if the default logger has no log level set, the log level will be set to `DEBUG`. (`#3324 <https://github.com/aio-libs/aiohttp/pull/3324>`_)
+ - Add method argument to ``session.ws_connect()``.
+ Sometimes server API requires a different HTTP method for WebSocket connection establishment.
- 3.4.0 (2018-08-25)
- ==================
-
- Features
- --------
-
- - Add type hints (`#3049 <https://github.com/aio-libs/aiohttp/pull/3049>`_)
- - Add ``raise_for_status`` request parameter (`#3073 <https://github.com/aio-libs/aiohttp/pull/3073>`_)
- - Add type hints to HTTP client (`#3092 <https://github.com/aio-libs/aiohttp/pull/3092>`_)
- - Minor server optimizations (`#3095 <https://github.com/aio-libs/aiohttp/pull/3095>`_)
- - Preserve the cause when `HTTPException` is raised from another exception. (`#3096 <https://github.com/aio-libs/aiohttp/pull/3096>`_)
- - Add `close_boundary` option in `MultipartWriter.write` method. Support streaming (`#3104 <https://github.com/aio-libs/aiohttp/pull/3104>`_)
- - Added a ``remove_slash`` option to the ``normalize_path_middleware`` factory. (`#3173 <https://github.com/aio-libs/aiohttp/pull/3173>`_)
- - The class `AbstractRouteDef` is importable from `aiohttp.web`. (`#3183 <https://github.com/aio-libs/aiohttp/pull/3183>`_)
+ For example, ``Docker exec`` needs POST. (`#3378 <https://github.com/aio-libs/aiohttp/pull/3378>`_)
+ - Create a task per request handling. (`#3406 <https://github.com/aio-libs/aiohttp/pull/3406>`_)
Bugfixes
--------
- - Prevent double closing when client connection is released before the
- last ``data_received()`` callback. (`#3031 <https://github.com/aio-libs/aiohttp/pull/3031>`_)
- - Make redirect with `normalize_path_middleware` work when using url encoded paths. (`#3051 <https://github.com/aio-libs/aiohttp/pull/3051>`_)
- - Postpone web task creation to connection establishment. (`#3052 <https://github.com/aio-libs/aiohttp/pull/3052>`_)
- - Fix ``sock_read`` timeout. (`#3053 <https://github.com/aio-libs/aiohttp/pull/3053>`_)
- - When using a server-request body as the `data=` argument of a client request, iterate over the content with `readany` instead of `readline` to avoid `Line too long` errors. (`#3054 <https://github.com/aio-libs/aiohttp/pull/3054>`_)
- - fix `UrlDispatcher` has no attribute `add_options`, add `web.options` (`#3062 <https://github.com/aio-libs/aiohttp/pull/3062>`_)
- - correct filename in content-disposition with multipart body (`#3064 <https://github.com/aio-libs/aiohttp/pull/3064>`_)
- - Many HTTP proxies has buggy keepalive support.
- Let's not reuse connection but close it after processing every response. (`#3070 <https://github.com/aio-libs/aiohttp/pull/3070>`_)
- - raise 413 "Payload Too Large" rather than raising ValueError in request.post()
- Add helpful debug message to 413 responses (`#3087 <https://github.com/aio-libs/aiohttp/pull/3087>`_)
- - Fix `StreamResponse` equality, now that they are `MutableMapping` objects. (`#3100 <https://github.com/aio-libs/aiohttp/pull/3100>`_)
- - Fix server request objects comparison (`#3116 <https://github.com/aio-libs/aiohttp/pull/3116>`_)
- - Do not hang on `206 Partial Content` response with `Content-Encoding: gzip` (`#3123 <https://github.com/aio-libs/aiohttp/pull/3123>`_)
- - Fix timeout precondition checkers (`#3145 <https://github.com/aio-libs/aiohttp/pull/3145>`_)
+ - Enable passing `access_log_class` via `handler_args` (`#3158 <https://github.com/aio-libs/aiohttp/pull/3158>`_)
+ - Return empty bytes with end-of-chunk marker in empty stream reader. (`#3186 <https://github.com/aio-libs/aiohttp/pull/3186>`_)
+ - Accept ``CIMultiDictProxy`` instances for ``headers`` argument in ``web.Response``
+ constructor. (`#3207 <https://github.com/aio-libs/aiohttp/pull/3207>`_)
+ - Don't uppercase HTTP method in parser (`#3233 <https://github.com/aio-libs/aiohttp/pull/3233>`_)
+ - Make method match regexp RFC-7230 compliant (`#3235 <https://github.com/aio-libs/aiohttp/pull/3235>`_)
+ - Add ``app.pre_frozen`` state to properly handle startup signals in sub-applications. (`#3237 <https://github.com/aio-libs/aiohttp/pull/3237>`_)
+ - Enhanced parsing and validation of helpers.BasicAuth.decode. (`#3239 <https://github.com/aio-libs/aiohttp/pull/3239>`_)
+ - Change imports from collections module in preparation for 3.8. (`#3258 <https://github.com/aio-libs/aiohttp/pull/3258>`_)
+ - Ensure Host header is added first to ClientRequest to better replicate browser (`#3265 <https://github.com/aio-libs/aiohttp/pull/3265>`_)
+ - Fix forward compatibility with Python 3.8: importing ABCs directly from the collections module will not be supported anymore. (`#3273 <https://github.com/aio-libs/aiohttp/pull/3273>`_)
+ - Keep the query string by `normalize_path_middleware`. (`#3278 <https://github.com/aio-libs/aiohttp/pull/3278>`_)
+ - Fix missing parameter ``raise_for_status`` for aiohttp.request() (`#3290 <https://github.com/aio-libs/aiohttp/pull/3290>`_)
+ - Bracket IPv6 addresses in the HOST header (`#3304 <https://github.com/aio-libs/aiohttp/pull/3304>`_)
+ - Fix default message for server ping and pong frames. (`#3308 <https://github.com/aio-libs/aiohttp/pull/3308>`_)
+ - Fix tests/test_connector.py typo and tests/autobahn/server.py duplicate loop def. (`#3337 <https://github.com/aio-libs/aiohttp/pull/3337>`_)
+ - Fix false-negative indicator end_of_HTTP_chunk in StreamReader.readchunk function (`#3361 <https://github.com/aio-libs/aiohttp/pull/3361>`_)
+ - Release HTTP response before raising status exception (`#3364 <https://github.com/aio-libs/aiohttp/pull/3364>`_)
+ - Fix task cancellation when ``sendfile()`` syscall is used by static file handling. (`#3383 <https://github.com/aio-libs/aiohttp/pull/3383>`_)
+ - Fix stack trace for ``asyncio.TimeoutError`` which was not logged, when it is caught
+ in the handler. (`#3414 <https://github.com/aio-libs/aiohttp/pull/3414>`_)
Improved Documentation
----------------------
- - Add a new FAQ entry that clarifies that you should not reuse response
- objects in middleware functions. (`#3020 <https://github.com/aio-libs/aiohttp/pull/3020>`_)
- - Add FAQ section "Why is creating a ClientSession outside of an event loop dangerous?" (`#3072 <https://github.com/aio-libs/aiohttp/pull/3072>`_)
- - Fix link to Rambler (`#3115 <https://github.com/aio-libs/aiohttp/pull/3115>`_)
- - Fix TCPSite documentation on the Server Reference page. (`#3146 <https://github.com/aio-libs/aiohttp/pull/3146>`_)
- - Fix documentation build configuration file for Windows. (`#3147 <https://github.com/aio-libs/aiohttp/pull/3147>`_)
- - Remove no longer existing lingering_timeout parameter of Application.make_handler from documentation. (`#3151 <https://github.com/aio-libs/aiohttp/pull/3151>`_)
- - Mention that ``app.make_handler`` is deprecated, recommend to use runners
- API instead. (`#3157 <https://github.com/aio-libs/aiohttp/pull/3157>`_)
+ - Improve documentation of ``Application.make_handler`` parameters. (`#3152 <https://github.com/aio-libs/aiohttp/pull/3152>`_)
+ - Fix BaseRequest.raw_headers doc. (`#3215 <https://github.com/aio-libs/aiohttp/pull/3215>`_)
+ - Fix typo in TypeError exception reason in ``web.Application._handle`` (`#3229 <https://github.com/aio-libs/aiohttp/pull/3229>`_)
+ - Make server access log format placeholder %b documentation reflect
+ behavior and docstring. (`#3307 <https://github.com/aio-libs/aiohttp/pull/3307>`_)
Deprecations and Removals
-------------------------
- - Drop ``loop.current_task()`` from ``helpers.current_task()`` (`#2826 <https://github.com/aio-libs/aiohttp/pull/2826>`_)
- - Drop ``reader`` parameter from ``request.multipart()``. (`#3090 <https://github.com/aio-libs/aiohttp/pull/3090>`_)
+ - Deprecate modification of ``session.requote_redirect_url`` (`#2278 <https://github.com/aio-libs/aiohttp/pull/2278>`_)
+ - Deprecate ``stream.unread_data()`` (`#3260 <https://github.com/aio-libs/aiohttp/pull/3260>`_)
+ - Deprecated use of boolean in ``resp.enable_compression()`` (`#3318 <https://github.com/aio-libs/aiohttp/pull/3318>`_)
+ - Encourage creation of aiohttp public objects inside a coroutine (`#3331 <https://github.com/aio-libs/aiohttp/pull/3331>`_)
+ - Drop dead ``Connection.detach()`` and ``Connection.writer``. Both methods were broken
+ for more than 2 years. (`#3358 <https://github.com/aio-libs/aiohttp/pull/3358>`_)
+ - Deprecate ``app.loop``, ``request.loop``, ``client.loop`` and ``connector.loop`` properties. (`#3374 <https://github.com/aio-libs/aiohttp/pull/3374>`_)
+ - Deprecate explicit debug argument. Use asyncio debug mode instead. (`#3381 <https://github.com/aio-libs/aiohttp/pull/3381>`_)
+ - Deprecate body parameter in HTTPException (and derived classes) constructor. (`#3385 <https://github.com/aio-libs/aiohttp/pull/3385>`_)
+ - Deprecate bare connector close, use ``async with connector:`` and ``await connector.close()`` instead. (`#3417 <https://github.com/aio-libs/aiohttp/pull/3417>`_)
+ - Deprecate obsolete ``read_timeout`` and ``conn_timeout`` in ``ClientSession`` constructor. (`#3438 <https://github.com/aio-libs/aiohttp/pull/3438>`_)
+
+
+ Misc
+ ----
+
+ - #3341, #3351
Platform: UNKNOWN
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Intended Audience :: Developers
@@ -324,3 +334,4 @@ Classifier: Operating System :: Microsoft :: Windows Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: AsyncIO
Requires-Python: >=3.5.3
+Provides-Extra: speedups
diff --git a/aiohttp.egg-info/SOURCES.txt b/aiohttp.egg-info/SOURCES.txt index 4e48f8b..c6f435a 100644 --- a/aiohttp.egg-info/SOURCES.txt +++ b/aiohttp.egg-info/SOURCES.txt @@ -18,9 +18,12 @@ Makefile README.rst codecov.yml pyproject.toml +pytest.ci.ini +pytest.ini setup.cfg setup.py tox.ini +.github/CODEOWNERS .github/ISSUE_TEMPLATE.md .github/PULL_REQUEST_TEMPLATE.md CHANGES/.gitignore @@ -79,6 +82,7 @@ aiohttp/web.py aiohttp/web_app.py aiohttp/web_exceptions.py aiohttp/web_fileresponse.py +aiohttp/web_log.py aiohttp/web_middlewares.py aiohttp/web_protocol.py aiohttp/web_request.py @@ -120,6 +124,7 @@ docs/misc.rst docs/multipart.rst docs/multipart_reference.rst docs/new_router.rst +docs/old-logo.png docs/old-logo.svg docs/powered_by.rst docs/signals.rst @@ -150,6 +155,7 @@ examples/lowlevel_srv.py examples/server.crt examples/server.csr examples/server.key +examples/server_simple.py examples/static_files.py examples/web_classview.py examples/web_cookies.py @@ -221,6 +227,7 @@ tests/test_web_app.py tests/test_web_cli.py tests/test_web_exceptions.py tests/test_web_functional.py +tests/test_web_log.py tests/test_web_middleware.py tests/test_web_protocol.py tests/test_web_request.py diff --git a/aiohttp.egg-info/requires.txt b/aiohttp.egg-info/requires.txt index 5600df2..5227677 100644 --- a/aiohttp.egg-info/requires.txt +++ b/aiohttp.egg-info/requires.txt @@ -6,3 +6,9 @@ yarl<2.0,>=1.0 [:python_version < "3.7"] idna-ssl>=1.0 +typing_extensions>=3.6.5 + +[speedups] +aiodns +brotlipy +cchardet diff --git a/aiohttp/__init__.py b/aiohttp/__init__.py index c462dc7..b5319cf 100644 --- a/aiohttp/__init__.py +++ b/aiohttp/__init__.py @@ -1,4 +1,4 @@ -__version__ = '3.4.4' +__version__ = '3.5.1' # This relies on each of the submodules having an __all__ variable. diff --git a/aiohttp/_find_header.c b/aiohttp/_find_header.c index 3b656f9..fbc6c4f 100644 --- a/aiohttp/_find_header.c +++ b/aiohttp/_find_header.c @@ -1,4 +1,4 @@ -/* The file is autogenerated from aiohtt/hdrs.py +/* The file is autogenerated from aiohttp/hdrs.py Run ./tools/gen.py to update it after the origin changing. */ #include "_find_header.h" @@ -6629,11 +6629,6 @@ PROX: PROXY: NEXT_CHAR(); switch (ch) { - case '_': - if (last) { - return -1; - } - goto PROXY_; case '-': if (last) { return -1; @@ -6724,6 +6719,16 @@ PROXY_AUTH: return -1; } goto PROXY_AUTHE; + case 'O': + if (last) { + return -1; + } + goto PROXY_AUTHO; + case 'o': + if (last) { + return -1; + } + goto PROXY_AUTHO; default: return -1; } @@ -6847,6 +6852,142 @@ PROXY_AUTHENTICAT: return -1; } +PROXY_AUTHO: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto PROXY_AUTHOR; + case 'r': + if (last) { + return -1; + } + goto PROXY_AUTHOR; + default: + return -1; + } + +PROXY_AUTHOR: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto PROXY_AUTHORI; + case 'i': + if (last) { + return -1; + } + goto PROXY_AUTHORI; + default: + return -1; + } + +PROXY_AUTHORI: + NEXT_CHAR(); + switch (ch) { + case 'Z': + if (last) { + return -1; + } + goto PROXY_AUTHORIZ; + case 'z': + if (last) { + return -1; + } + goto PROXY_AUTHORIZ; + default: + return -1; + } + +PROXY_AUTHORIZ: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto PROXY_AUTHORIZA; + case 'a': + if (last) { + return -1; + } + goto PROXY_AUTHORIZA; + default: + return -1; + } + +PROXY_AUTHORIZA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto PROXY_AUTHORIZAT; + case 't': + if (last) { + return -1; + } + goto PROXY_AUTHORIZAT; + default: + return -1; + } + +PROXY_AUTHORIZAT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto PROXY_AUTHORIZATI; + case 'i': + if (last) { + return -1; + } + goto PROXY_AUTHORIZATI; + default: + return -1; + } + +PROXY_AUTHORIZATI: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto PROXY_AUTHORIZATIO; + case 'o': + if (last) { + return -1; + } + goto PROXY_AUTHORIZATIO; + default: + return -1; + } + +PROXY_AUTHORIZATIO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 51; + } + goto PROXY_AUTHORIZATION; + case 'n': + if (last) { + return 51; + } + goto PROXY_AUTHORIZATION; + default: + return -1; + } + R: NEXT_CHAR(); switch (ch) { @@ -9827,6 +9968,7 @@ MAX_FORWARDS: ORIGIN: PRAGMA: PROXY_AUTHENTICATE: +PROXY_AUTHORIZATION: RANGE: REFERER: RETRY_AFTER: diff --git a/aiohttp/_frozenlist.c b/aiohttp/_frozenlist.c index c39c6b6..31163c1 100644 --- a/aiohttp/_frozenlist.c +++ b/aiohttp/_frozenlist.c @@ -1,4 +1,4 @@ -/* Generated by Cython 0.28.5 */ +/* Generated by Cython 0.29.2 */ /* BEGIN: Cython Metadata { @@ -19,7 +19,8 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) #error Cython requires Python 2.6+ or Python 3.3+. #else -#define CYTHON_ABI "0_28_5" +#define CYTHON_ABI "0_29_2" +#define CYTHON_HEX_VERSION 0x001D02F0 #define CYTHON_FUTURE_DIVISION 0 #include <stddef.h> #ifndef offsetof @@ -90,6 +91,10 @@ END: Cython Metadata */ #define CYTHON_PEP489_MULTI_PHASE_INIT 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #elif defined(PYSTON_VERSION) #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 1 @@ -127,6 +132,10 @@ END: Cython Metadata */ #define CYTHON_PEP489_MULTI_PHASE_INIT 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #else #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 0 @@ -180,11 +189,17 @@ END: Cython Metadata */ #define CYTHON_FAST_PYCALL 1 #endif #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (0 && PY_VERSION_HEX >= 0x03050000) + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) #endif #ifndef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif #endif #if !defined(CYTHON_FAST_PYCCALL) #define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) @@ -194,6 +209,9 @@ END: Cython Metadata */ #undef SHIFT #undef BASE #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif #endif #ifndef __has_attribute #define __has_attribute(x) 0 @@ -320,6 +338,9 @@ END: Cython Metadata */ #ifndef Py_TPFLAGS_HAVE_FINALIZE #define Py_TPFLAGS_HAVE_FINALIZE 0 #endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif #if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) #ifndef METH_FASTCALL #define METH_FASTCALL 0x80 @@ -333,15 +354,40 @@ END: Cython Metadata */ #endif #if CYTHON_FAST_PYCCALL #define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))))) + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) #else #define __Pyx_PyFastCFunction_Check(func) 0 #endif +#if CYTHON_USE_DICT_VERSIONS +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ + } +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) #define PyObject_Malloc(s) PyMem_Malloc(s) #define PyObject_Free(p) PyMem_Free(p) #define PyObject_Realloc(p) PyMem_Realloc(p) #endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif #if CYTHON_COMPILING_IN_PYSTON #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) @@ -449,8 +495,8 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) #endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) #else @@ -602,6 +648,9 @@ typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* enc (sizeof(type) == sizeof(Py_ssize_t) &&\ (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} #if defined (__cplusplus) && __cplusplus >= 201103L #include <cstdlib> #define __Pyx_sst_abs(value) std::abs(value) @@ -660,6 +709,7 @@ static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); #define __Pyx_PySequence_Tuple(obj)\ (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) @@ -740,7 +790,7 @@ static int __Pyx_init_sys_getdefaultencoding_params(void) { if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); Py_DECREF(default_encoding); @@ -968,13 +1018,6 @@ static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* k #define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) #endif -/* PyCFunctionFastCall.proto */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); -#else -#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) -#endif - /* PyFunctionFastCall.proto */ #if CYTHON_FAST_PYCALL #define __Pyx_PyFunction_FastCall(func, args, nargs)\ @@ -984,6 +1027,18 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, #else #define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) #endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) #endif /* PyObjectCallMethO.proto */ @@ -991,9 +1046,6 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); #endif -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - /* PyObjectCallNoArg.proto */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); @@ -1001,13 +1053,18 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); #define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) #endif -/* PyIntBinop.proto */ -#if !CYTHON_COMPILING_IN_PYPY -static PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, long intval, int inplace); +/* PyCFunctionFastCall.proto */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); #else -#define __Pyx_PyInt_EqObjC(op1, op2, intval, inplace)\ - PyObject_RichCompare(op1, op2, Py_EQ) - #endif +#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* PyIntCompare.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, long intval, long inplace); /* PySequenceContains.proto */ static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { @@ -1015,9 +1072,14 @@ static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* s return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); } +/* PyObjectCall2Args.proto */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + /* PyObjectCallMethod1.proto */ static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); -static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg); /* pop_index.proto */ static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix); @@ -1074,7 +1136,25 @@ static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /* GetModuleGlobalName.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif /* Import.proto */ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); @@ -1200,6 +1280,7 @@ static const char __pyx_k_reversed[] = "__reversed__"; static const char __pyx_k_setstate[] = "__setstate__"; static const char __pyx_k_pyx_state[] = "__pyx_state"; static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; +static const char __pyx_k_FrozenList[] = "FrozenList"; static const char __pyx_k_pyx_result[] = "__pyx_result"; static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; static const char __pyx_k_PickleError[] = "PickleError"; @@ -1218,6 +1299,7 @@ static const char __pyx_k_pyx_unpickle_FrozenList[] = "__pyx_unpickle_FrozenList static const char __pyx_k_Cannot_modify_frozen_list[] = "Cannot modify frozen list."; static const char __pyx_k_Incompatible_checksums_s_vs_0x94[] = "Incompatible checksums (%s vs 0x949a143 = (_items, frozen))"; static PyObject *__pyx_kp_s_Cannot_modify_frozen_list; +static PyObject *__pyx_n_s_FrozenList; static PyObject *__pyx_kp_s_FrozenList_frozen_r; static PyObject *__pyx_kp_s_Incompatible_checksums_s_vs_0x94; static PyObject *__pyx_n_s_MutableSequence; @@ -1955,12 +2037,9 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_12__iter__(struct __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (__pyx_t_3) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error) - } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_1; @@ -2037,12 +2116,9 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_14__reversed__(str __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (__pyx_t_3) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error) - } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_1; @@ -2653,7 +2729,6 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_24index(struct __p PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; __Pyx_RefNannySetupContext("index", 0); /* "aiohttp/_frozenlist.pyx":74 @@ -2676,38 +2751,10 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_24index(struct __p __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_3) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_v_item}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_v_item}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - { - __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 74, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __pyx_t_3 = NULL; - __Pyx_INCREF(__pyx_v_item); - __Pyx_GIVEREF(__pyx_v_item); - PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_item); - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_item) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; @@ -2726,7 +2773,6 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_24index(struct __p __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.index", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -2762,7 +2808,6 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_26remove(struct __ PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; __Pyx_RefNannySetupContext("remove", 0); /* "aiohttp/_frozenlist.pyx":77 @@ -2795,38 +2840,10 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_26remove(struct __ __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_3) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_v_item}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_v_item}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - { - __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __pyx_t_3 = NULL; - __Pyx_INCREF(__pyx_v_item); - __Pyx_GIVEREF(__pyx_v_item); - PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_item); - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_item) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -2845,7 +2862,6 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_26remove(struct __ __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.remove", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -2913,12 +2929,9 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_28clear(struct __p __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (__pyx_t_3) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 82, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 82, __pyx_L1_error) - } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 82, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -3322,7 +3335,6 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_38count(struct __p PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; __Pyx_RefNannySetupContext("count", 0); /* "aiohttp/_frozenlist.pyx":101 @@ -3345,38 +3357,10 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_38count(struct __p __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_3) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_v_item}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_v_item}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - { - __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 101, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __pyx_t_3 = NULL; - __Pyx_INCREF(__pyx_v_item); - __Pyx_GIVEREF(__pyx_v_item); - PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_item); - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_item) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; @@ -3395,7 +3379,6 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_38count(struct __p __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.count", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -3576,8 +3559,8 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6frozen___get__(st /* "(tree fragment)":1 * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef bint use_setstate - * state = (self._items, self.frozen) + * cdef tuple state + * cdef object _dict */ /* Python wrapper */ @@ -3594,9 +3577,9 @@ static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_43__reduce_cython_ } static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_v_state = 0; + PyObject *__pyx_v__dict = 0; int __pyx_v_use_setstate; - PyObject *__pyx_v_state = NULL; - PyObject *__pyx_v__dict = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; @@ -3606,16 +3589,16 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ PyObject *__pyx_t_5 = NULL; __Pyx_RefNannySetupContext("__reduce_cython__", 0); - /* "(tree fragment)":3 - * def __reduce_cython__(self): + /* "(tree fragment)":5 + * cdef object _dict * cdef bint use_setstate * state = (self._items, self.frozen) # <<<<<<<<<<<<<< * _dict = getattr(self, '__dict__', None) * if _dict is not None: */ - __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->frozen); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->frozen); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_v_self->_items); __Pyx_GIVEREF(__pyx_v_self->_items); @@ -3626,19 +3609,19 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ __pyx_v_state = ((PyObject*)__pyx_t_2); __pyx_t_2 = 0; - /* "(tree fragment)":4 + /* "(tree fragment)":6 * cdef bint use_setstate * state = (self._items, self.frozen) * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< * if _dict is not None: * state += (_dict,) */ - __pyx_t_2 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_2 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_v__dict = __pyx_t_2; __pyx_t_2 = 0; - /* "(tree fragment)":5 + /* "(tree fragment)":7 * state = (self._items, self.frozen) * _dict = getattr(self, '__dict__', None) * if _dict is not None: # <<<<<<<<<<<<<< @@ -3649,25 +3632,25 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ __pyx_t_4 = (__pyx_t_3 != 0); if (__pyx_t_4) { - /* "(tree fragment)":6 + /* "(tree fragment)":8 * _dict = getattr(self, '__dict__', None) * if _dict is not None: * state += (_dict,) # <<<<<<<<<<<<<< * use_setstate = True * else: */ - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 8, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_v__dict); __Pyx_GIVEREF(__pyx_v__dict); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v__dict); - __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_1)); __pyx_t_1 = 0; - /* "(tree fragment)":7 + /* "(tree fragment)":9 * if _dict is not None: * state += (_dict,) * use_setstate = True # <<<<<<<<<<<<<< @@ -3676,7 +3659,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ */ __pyx_v_use_setstate = 1; - /* "(tree fragment)":5 + /* "(tree fragment)":7 * state = (self._items, self.frozen) * _dict = getattr(self, '__dict__', None) * if _dict is not None: # <<<<<<<<<<<<<< @@ -3686,7 +3669,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ goto __pyx_L3; } - /* "(tree fragment)":9 + /* "(tree fragment)":11 * use_setstate = True * else: * use_setstate = self._items is not None # <<<<<<<<<<<<<< @@ -3699,7 +3682,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ } __pyx_L3:; - /* "(tree fragment)":10 + /* "(tree fragment)":12 * else: * use_setstate = self._items is not None * if use_setstate: # <<<<<<<<<<<<<< @@ -3709,7 +3692,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ __pyx_t_4 = (__pyx_v_use_setstate != 0); if (__pyx_t_4) { - /* "(tree fragment)":11 + /* "(tree fragment)":13 * use_setstate = self._items is not None * if use_setstate: * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state # <<<<<<<<<<<<<< @@ -3717,9 +3700,9 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_pyx_unpickle_FrozenList); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 11, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_pyx_unpickle_FrozenList); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); @@ -3730,7 +3713,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ __Pyx_INCREF(Py_None); __Pyx_GIVEREF(Py_None); PyTuple_SET_ITEM(__pyx_t_2, 2, Py_None); - __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); @@ -3745,7 +3728,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ __pyx_t_5 = 0; goto __pyx_L0; - /* "(tree fragment)":10 + /* "(tree fragment)":12 * else: * use_setstate = self._items is not None * if use_setstate: # <<<<<<<<<<<<<< @@ -3754,7 +3737,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ */ } - /* "(tree fragment)":13 + /* "(tree fragment)":15 * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state * else: * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) # <<<<<<<<<<<<<< @@ -3763,9 +3746,9 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ */ /*else*/ { __Pyx_XDECREF(__pyx_r); - __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_pyx_unpickle_FrozenList); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_pyx_unpickle_FrozenList); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); @@ -3776,7 +3759,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ __Pyx_INCREF(__pyx_v_state); __Pyx_GIVEREF(__pyx_v_state); PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_state); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); @@ -3791,8 +3774,8 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ /* "(tree fragment)":1 * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef bint use_setstate - * state = (self._items, self.frozen) + * cdef tuple state + * cdef object _dict */ /* function exit code */ @@ -3810,7 +3793,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython_ return __pyx_r; } -/* "(tree fragment)":14 +/* "(tree fragment)":16 * else: * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< @@ -3836,17 +3819,17 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_44__setstate_cytho PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__setstate_cython__", 0); - /* "(tree fragment)":15 + /* "(tree fragment)":17 * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) * def __setstate_cython__(self, __pyx_state): * __pyx_unpickle_FrozenList__set_state(self, __pyx_state) # <<<<<<<<<<<<<< */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 15, __pyx_L1_error) - __pyx_t_1 = __pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":14 + /* "(tree fragment)":16 * else: * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< @@ -3868,13 +3851,13 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_44__setstate_cytho /* "(tree fragment)":1 * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x949a143: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList = {"__pyx_unpickle_FrozenList", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList, METH_VARARGS|METH_KEYWORDS, 0}; +static PyMethodDef __pyx_mdef_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList = {"__pyx_unpickle_FrozenList", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList, METH_VARARGS|METH_KEYWORDS, 0}; static PyObject *__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v___pyx_type = 0; long __pyx_v___pyx_checksum; @@ -3946,8 +3929,8 @@ static PyObject *__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList(PyOb } static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = NULL; - PyObject *__pyx_v___pyx_result = NULL; + PyObject *__pyx_v___pyx_PickleError = 0; + PyObject *__pyx_v___pyx_result = 0; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; @@ -3955,12 +3938,12 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHO PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; + int __pyx_t_6; __Pyx_RefNannySetupContext("__pyx_unpickle_FrozenList", 0); - /* "(tree fragment)":2 - * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result * if __pyx_checksum != 0x949a143: # <<<<<<<<<<<<<< * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) @@ -3968,38 +3951,38 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHO __pyx_t_1 = ((__pyx_v___pyx_checksum != 0x949a143) != 0); if (__pyx_t_1) { - /* "(tree fragment)":3 - * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":5 + * cdef object __pyx_result * if __pyx_checksum != 0x949a143: * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) * __pyx_result = FrozenList.__new__(__pyx_type) */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_n_s_PickleError); __Pyx_GIVEREF(__pyx_n_s_PickleError); PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, -1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, -1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_t_2); __pyx_v___pyx_PickleError = __pyx_t_2; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "(tree fragment)":4 + /* "(tree fragment)":6 * if __pyx_checksum != 0x949a143: * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) # <<<<<<<<<<<<<< * __pyx_result = FrozenList.__new__(__pyx_type) * if __pyx_state is not None: */ - __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x94, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x94, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_INCREF(__pyx_v___pyx_PickleError); @@ -4013,110 +3996,53 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHO __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_5) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else - #endif - { - __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL; - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_4); - __pyx_t_4 = 0; - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 4, __pyx_L1_error) + __PYX_ERR(1, 6, __pyx_L1_error) - /* "(tree fragment)":2 - * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result * if __pyx_checksum != 0x949a143: # <<<<<<<<<<<<<< * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) */ } - /* "(tree fragment)":5 + /* "(tree fragment)":7 * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) * __pyx_result = FrozenList.__new__(__pyx_type) # <<<<<<<<<<<<<< * if __pyx_state is not None: * __pyx_unpickle_FrozenList__set_state(<FrozenList> __pyx_result, __pyx_state) */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_11_frozenlist_FrozenList), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_11_frozenlist_FrozenList), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_6 = NULL; + __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_6)) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_6) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v___pyx_type}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v___pyx_type}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - { - __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); __pyx_t_6 = NULL; - __Pyx_INCREF(__pyx_v___pyx_type); - __Pyx_GIVEREF(__pyx_v___pyx_type); - PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v___pyx_type); - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - } + __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v___pyx_result = __pyx_t_3; __pyx_t_3 = 0; - /* "(tree fragment)":6 + /* "(tree fragment)":8 * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) * __pyx_result = FrozenList.__new__(__pyx_type) * if __pyx_state is not None: # <<<<<<<<<<<<<< @@ -4124,22 +4050,22 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHO * return __pyx_result */ __pyx_t_1 = (__pyx_v___pyx_state != Py_None); - __pyx_t_7 = (__pyx_t_1 != 0); - if (__pyx_t_7) { + __pyx_t_6 = (__pyx_t_1 != 0); + if (__pyx_t_6) { - /* "(tree fragment)":7 + /* "(tree fragment)":9 * __pyx_result = FrozenList.__new__(__pyx_type) * if __pyx_state is not None: * __pyx_unpickle_FrozenList__set_state(<FrozenList> __pyx_result, __pyx_state) # <<<<<<<<<<<<<< * return __pyx_result * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 7, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "(tree fragment)":6 + /* "(tree fragment)":8 * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) * __pyx_result = FrozenList.__new__(__pyx_type) * if __pyx_state is not None: # <<<<<<<<<<<<<< @@ -4148,7 +4074,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHO */ } - /* "(tree fragment)":8 + /* "(tree fragment)":10 * if __pyx_state is not None: * __pyx_unpickle_FrozenList__set_state(<FrozenList> __pyx_result, __pyx_state) * return __pyx_result # <<<<<<<<<<<<<< @@ -4162,8 +4088,8 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHO /* "(tree fragment)":1 * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x949a143: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ /* function exit code */ @@ -4172,7 +4098,6 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHO __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._frozenlist.__pyx_unpickle_FrozenList", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -4183,7 +4108,7 @@ static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHO return __pyx_r; } -/* "(tree fragment)":9 +/* "(tree fragment)":11 * __pyx_unpickle_FrozenList__set_state(<FrozenList> __pyx_result, __pyx_state) * return __pyx_result * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< @@ -4202,10 +4127,9 @@ static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_s PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; __Pyx_RefNannySetupContext("__pyx_unpickle_FrozenList__set_state", 0); - /* "(tree fragment)":10 + /* "(tree fragment)":12 * return __pyx_result * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] # <<<<<<<<<<<<<< @@ -4214,11 +4138,11 @@ static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_s */ if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyList_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 10, __pyx_L1_error) + if (!(likely(PyList_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->_items); __Pyx_DECREF(__pyx_v___pyx_result->_items); @@ -4226,15 +4150,15 @@ static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_s __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v___pyx_result->frozen = __pyx_t_2; - /* "(tree fragment)":11 + /* "(tree fragment)":13 * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< @@ -4242,36 +4166,36 @@ static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_s */ if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 11, __pyx_L1_error) + __PYX_ERR(1, 13, __pyx_L1_error) } - __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) __pyx_t_4 = ((__pyx_t_3 > 2) != 0); if (__pyx_t_4) { } else { __pyx_t_2 = __pyx_t_4; goto __pyx_L4_bool_binop_done; } - __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) __pyx_t_5 = (__pyx_t_4 != 0); __pyx_t_2 = __pyx_t_5; __pyx_L4_bool_binop_done:; if (__pyx_t_2) { - /* "(tree fragment)":12 + /* "(tree fragment)":14 * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): * __pyx_result.__dict__.update(__pyx_state[2]) # <<<<<<<<<<<<<< */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) + __PYX_ERR(1, 14, __pyx_L1_error) } - __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __pyx_t_8 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { @@ -4283,45 +4207,15 @@ static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_s __Pyx_DECREF_SET(__pyx_t_7, function); } } - if (!__pyx_t_8) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_t_6}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_t_6}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - { - __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __pyx_t_8 = NULL; - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_6); - __pyx_t_6 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } - } + __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":11 + /* "(tree fragment)":13 * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< @@ -4329,7 +4223,7 @@ static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_s */ } - /* "(tree fragment)":9 + /* "(tree fragment)":11 * __pyx_unpickle_FrozenList__set_state(<FrozenList> __pyx_result, __pyx_state) * return __pyx_result * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< @@ -4345,7 +4239,6 @@ static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_s __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); __Pyx_AddTraceback("aiohttp._frozenlist.__pyx_unpickle_FrozenList__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; @@ -4423,13 +4316,13 @@ static PyObject *__pyx_getprop_7aiohttp_11_frozenlist_10FrozenList_frozen(PyObje static PyMethodDef __pyx_methods_7aiohttp_11_frozenlist_FrozenList[] = { {"freeze", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_3freeze, METH_NOARGS, 0}, {"__reversed__", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_15__reversed__, METH_NOARGS, 0}, - {"insert", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_19insert, METH_VARARGS|METH_KEYWORDS, 0}, + {"insert", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_19insert, METH_VARARGS|METH_KEYWORDS, 0}, {"index", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_25index, METH_O, 0}, {"remove", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_27remove, METH_O, 0}, {"clear", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_29clear, METH_NOARGS, 0}, {"extend", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_31extend, METH_O, 0}, {"reverse", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_33reverse, METH_NOARGS, 0}, - {"pop", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_35pop, METH_VARARGS|METH_KEYWORDS, 0}, + {"pop", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_35pop, METH_VARARGS|METH_KEYWORDS, 0}, {"append", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_37append, METH_O, 0}, {"count", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_39count, METH_O, 0}, {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_43__reduce_cython__, METH_NOARGS, 0}, @@ -4616,9 +4509,19 @@ static struct PyModuleDef __pyx_moduledef = { NULL /* m_free */ }; #endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_kp_s_Cannot_modify_frozen_list, __pyx_k_Cannot_modify_frozen_list, sizeof(__pyx_k_Cannot_modify_frozen_list), 0, 0, 1, 0}, + {&__pyx_n_s_FrozenList, __pyx_k_FrozenList, sizeof(__pyx_k_FrozenList), 0, 0, 1, 1}, {&__pyx_kp_s_FrozenList_frozen_r, __pyx_k_FrozenList_frozen_r, sizeof(__pyx_k_FrozenList_frozen_r), 0, 0, 1, 0}, {&__pyx_kp_s_Incompatible_checksums_s_vs_0x94, __pyx_k_Incompatible_checksums_s_vs_0x94, sizeof(__pyx_k_Incompatible_checksums_s_vs_0x94), 0, 0, 1, 0}, {&__pyx_n_s_MutableSequence, __pyx_k_MutableSequence, sizeof(__pyx_k_MutableSequence), 0, 0, 1, 1}, @@ -4663,14 +4566,14 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0} }; -static int __Pyx_InitCachedBuiltins(void) { +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 19, __pyx_L1_error) return 0; __pyx_L1_error:; return -1; } -static int __Pyx_InitCachedConstants(void) { +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); @@ -4687,8 +4590,8 @@ static int __Pyx_InitCachedConstants(void) { /* "(tree fragment)":1 * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x949a143: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ __pyx_tuple__2 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__2); @@ -4701,7 +4604,7 @@ static int __Pyx_InitCachedConstants(void) { return -1; } -static int __Pyx_InitGlobals(void) { +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) @@ -4716,13 +4619,13 @@ static int __Pyx_InitGlobals(void) { return -1; } -static int __Pyx_modinit_global_init_code(void); /*proto*/ -static int __Pyx_modinit_variable_export_code(void); /*proto*/ -static int __Pyx_modinit_function_export_code(void); /*proto*/ -static int __Pyx_modinit_type_init_code(void); /*proto*/ -static int __Pyx_modinit_type_import_code(void); /*proto*/ -static int __Pyx_modinit_variable_import_code(void); /*proto*/ -static int __Pyx_modinit_function_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ static int __Pyx_modinit_global_init_code(void) { __Pyx_RefNannyDeclarations @@ -4761,7 +4664,7 @@ static int __Pyx_modinit_type_init_code(void) { __pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_getattro = __Pyx_PyObject_GenericGetAttr; } if (__Pyx_SetVtable(__pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_dict, __pyx_vtabptr_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) - if (PyObject_SetAttrString(__pyx_m, "FrozenList", (PyObject *)&__pyx_type_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FrozenList, (PyObject *)&__pyx_type_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) __pyx_ptype_7aiohttp_11_frozenlist_FrozenList = &__pyx_type_7aiohttp_11_frozenlist_FrozenList; __Pyx_RefNannyFinishContext(); @@ -4809,15 +4712,6 @@ static int __Pyx_modinit_function_import_code(void) { #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC #endif #endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (!(defined(__cplusplus)) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4))) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif #if PY_MAJOR_VERSION < 3 @@ -4830,11 +4724,36 @@ __Pyx_PyMODINIT_FUNC PyInit__frozenlist(void) { return PyModuleDef_Init(&__pyx_moduledef); } -static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name) { +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { PyObject *value = PyObject_GetAttrString(spec, from_name); int result = 0; if (likely(value)) { - result = PyDict_SetItemString(moddict, to_name, value); + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } Py_DECREF(value); } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); @@ -4843,8 +4762,10 @@ static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const ch } return result; } -static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; if (__pyx_m) return __Pyx_NewRef(__pyx_m); modname = PyObject_GetAttrString(spec, "name"); @@ -4854,10 +4775,10 @@ static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *d if (unlikely(!module)) goto bad; moddict = PyModule_GetDict(module); if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; return module; bad: Py_XDECREF(module); @@ -4865,7 +4786,7 @@ bad: } -static int __pyx_pymod_exec__frozenlist(PyObject *__pyx_pyinit_module) +static CYTHON_SMALL_CODE int __pyx_pymod_exec__frozenlist(PyObject *__pyx_pyinit_module) #endif #endif { @@ -4873,7 +4794,11 @@ static int __pyx_pymod_exec__frozenlist(PyObject *__pyx_pyinit_module) PyObject *__pyx_t_2 = NULL; __Pyx_RefNannyDeclarations #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m && __pyx_m == __pyx_pyinit_module) return 0; + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_frozenlist' has already been imported. Re-initialisation is not supported."); + return -1; + } #elif PY_MAJOR_VERSION >= 3 if (__pyx_m) return __Pyx_NewRef(__pyx_m); #endif @@ -4888,6 +4813,9 @@ if (!__Pyx_RefNanny) { #endif __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__frozenlist(void)", 0); if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) @@ -4942,7 +4870,7 @@ if (!__Pyx_RefNanny) { if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif if (__pyx_module_is_main_aiohttp___frozenlist) { - if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) } #if PY_MAJOR_VERSION >= 3 { @@ -4993,7 +4921,7 @@ if (!__Pyx_RefNanny) { * * MutableSequence.register(FrozenList) # <<<<<<<<<<<<<< */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_MutableSequence); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_MutableSequence); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 108, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_register); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); @@ -5005,8 +4933,8 @@ if (!__Pyx_RefNanny) { /* "(tree fragment)":1 * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x949a143: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList, NULL, __pyx_n_s_aiohttp__frozenlist); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); @@ -5031,9 +4959,9 @@ if (!__Pyx_RefNanny) { __Pyx_XDECREF(__pyx_t_2); if (__pyx_m) { if (__pyx_d) { - __Pyx_AddTraceback("init aiohttp._frozenlist", 0, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("init aiohttp._frozenlist", __pyx_clineno, __pyx_lineno, __pyx_filename); } - Py_DECREF(__pyx_m); __pyx_m = 0; + Py_CLEAR(__pyx_m); } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, "init aiohttp._frozenlist"); } @@ -5054,9 +4982,9 @@ if (!__Pyx_RefNanny) { static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { PyObject *m = NULL, *p = NULL; void *r = NULL; - m = PyImport_ImportModule((char *)modname); + m = PyImport_ImportModule(modname); if (!m) goto end; - p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); + p = PyObject_GetAttrString(m, "RefNannyAPI"); if (!p) goto end; r = PyLong_AsVoidPtr(p); end: @@ -5455,7 +5383,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_ if (wraparound & unlikely(i < 0)) { wrapped_i += PyList_GET_SIZE(o); } - if ((!boundscheck) || likely((0 <= wrapped_i) & (wrapped_i < PyList_GET_SIZE(o)))) { + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { PyObject *r = PyList_GET_ITEM(o, wrapped_i); Py_INCREF(r); return r; @@ -5473,7 +5401,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize if (wraparound & unlikely(i < 0)) { wrapped_i += PyTuple_GET_SIZE(o); } - if ((!boundscheck) || likely((0 <= wrapped_i) & (wrapped_i < PyTuple_GET_SIZE(o)))) { + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); Py_INCREF(r); return r; @@ -5489,7 +5417,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS if (is_list || PyList_CheckExact(o)) { Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) { + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { PyObject *r = PyList_GET_ITEM(o, n); Py_INCREF(r); return r; @@ -5497,7 +5425,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, } else if (PyTuple_CheckExact(o)) { Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) { + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, n); Py_INCREF(r); return r; @@ -5555,32 +5483,8 @@ static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { } #endif -/* PyCFunctionFastCall */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { - PyCFunctionObject *func = (PyCFunctionObject*)func_obj; - PyCFunction meth = PyCFunction_GET_FUNCTION(func); - PyObject *self = PyCFunction_GET_SELF(func); - int flags = PyCFunction_GET_FLAGS(func); - assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))); - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - /* _PyCFunction_FastCallDict() must not be called with an exception set, - because it may clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); - if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)meth)) (self, args, nargs, NULL); - } else { - return (*((__Pyx_PyCFunctionFast)meth)) (self, args, nargs); - } -} -#endif - /* PyFunctionFastCall */ #if CYTHON_FAST_PYCALL -#include "frameobject.h" static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, PyObject *globals) { PyFrameObject *f; @@ -5598,7 +5502,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args if (f == NULL) { return NULL; } - fastlocals = f->f_localsplus; + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); for (i = 0; i < na; i++) { Py_INCREF(*args); fastlocals[i] = *args++; @@ -5718,6 +5622,51 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject } #endif +/* PyObjectCallNoArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, NULL, 0); + } +#endif +#ifdef __Pyx_CyFunction_USED + if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) +#else + if (likely(PyCFunction_Check(func))) +#endif + { + if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { + return __Pyx_PyObject_CallMethO(func, NULL); + } + } + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); +} +#endif + +/* PyCFunctionFastCall */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { + PyCFunctionObject *func = (PyCFunctionObject*)func_obj; + PyCFunction meth = PyCFunction_GET_FUNCTION(func); + PyObject *self = PyCFunction_GET_SELF(func); + int flags = PyCFunction_GET_FLAGS(func); + assert(PyCFunction_Check(func)); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + /* _PyCFunction_FastCallDict() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); + } else { + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); + } +} +#endif + /* PyObjectCallOneArg */ #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { @@ -5758,30 +5707,8 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObjec } #endif -/* PyObjectCallNoArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, NULL, 0); - } -#endif -#ifdef __Pyx_CyFunction_USED - if (likely(PyCFunction_Check(func) || __Pyx_TypeCheck(func, __pyx_CyFunctionType))) { -#else - if (likely(PyCFunction_Check(func))) { -#endif - if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { - return __Pyx_PyObject_CallMethO(func, NULL); - } - } - return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); -} -#endif - -/* PyIntBinop */ - #if !CYTHON_COMPILING_IN_PYPY -static PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, CYTHON_UNUSED int inplace) { +/* PyIntCompare */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, CYTHON_UNUSED long inplace) { if (op1 == op2) { Py_RETURN_TRUE; } @@ -5789,140 +5716,209 @@ static PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED if (likely(PyInt_CheckExact(op1))) { const long b = intval; long a = PyInt_AS_LONG(op1); - if (a == b) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } + if (a == b) Py_RETURN_TRUE; else Py_RETURN_FALSE; } #endif #if CYTHON_USE_PYLONG_INTERNALS if (likely(PyLong_CheckExact(op1))) { - const long b = intval; - long a; + int unequal; + unsigned long uintval; + Py_ssize_t size = Py_SIZE(op1); const digit* digits = ((PyLongObject*)op1)->ob_digit; - const Py_ssize_t size = Py_SIZE(op1); - if (likely(__Pyx_sst_abs(size) <= 1)) { - a = likely(size) ? digits[0] : 0; - if (size == -1) a = -a; + if (intval == 0) { + if (size == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; + } else if (intval < 0) { + if (size >= 0) + Py_RETURN_FALSE; + intval = -intval; + size = -size; } else { - switch (size) { - case -2: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; - } - CYTHON_FALLTHROUGH; - case 2: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; - } - CYTHON_FALLTHROUGH; - case -3: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; - } - CYTHON_FALLTHROUGH; - case 3: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; - } - CYTHON_FALLTHROUGH; - case -4: - if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; - } - CYTHON_FALLTHROUGH; - case 4: - if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; - } - CYTHON_FALLTHROUGH; - #if PyLong_SHIFT < 30 && PyLong_SHIFT != 15 - default: return PyLong_Type.tp_richcompare(op1, op2, Py_EQ); - #else - default: Py_RETURN_FALSE; - #endif - } - } - if (a == b) { - Py_RETURN_TRUE; - } else { + if (size <= 0) Py_RETURN_FALSE; - } + } + uintval = (unsigned long) intval; +#if PyLong_SHIFT * 4 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 4)) { + unequal = (size != 5) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[4] != ((uintval >> (4 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 3 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 3)) { + unequal = (size != 4) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 2 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 2)) { + unequal = (size != 3) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 1 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 1)) { + unequal = (size != 2) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif + unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK)); + if (unequal == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; } #endif if (PyFloat_CheckExact(op1)) { const long b = intval; double a = PyFloat_AS_DOUBLE(op1); - if ((double)a == (double)b) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } + if ((double)a == (double)b) Py_RETURN_TRUE; else Py_RETURN_FALSE; } - return PyObject_RichCompare(op1, op2, Py_EQ); + return ( + PyObject_RichCompare(op1, op2, Py_EQ)); } -#endif -/* PyObjectCallMethod1 */ - static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { - PyObject *result = NULL; -#if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(method))) { - PyObject *self = PyMethod_GET_SELF(method); - if (likely(self)) { - PyObject *args; - PyObject *function = PyMethod_GET_FUNCTION(method); - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(function)) { - PyObject *args[2] = {self, arg}; - result = __Pyx_PyFunction_FastCall(function, args, 2); - goto done; - } - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(function)) { - PyObject *args[2] = {self, arg}; - result = __Pyx_PyCFunction_FastCall(function, args, 2); - goto done; +/* PyObjectCall2Args */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args, *result = NULL; + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyFunction_FastCall(function, args, 2); + } + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyCFunction_FastCall(function, args, 2); + } + #endif + args = PyTuple_New(2); + if (unlikely(!args)) goto done; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + Py_INCREF(function); + result = __Pyx_PyObject_Call(function, args, NULL); + Py_DECREF(args); + Py_DECREF(function); +done: + return result; +} + +/* PyObjectGetMethod */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; } - #endif - args = PyTuple_New(2); - if (unlikely(!args)) goto done; - Py_INCREF(self); - PyTuple_SET_ITEM(args, 0, self); - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 1, arg); - Py_INCREF(function); - result = __Pyx_PyObject_Call(function, args, NULL); - Py_DECREF(args); - Py_DECREF(function); - return result; } } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (descr != NULL) { + *method = descr; + return 0; + } + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); +#else + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(name)); +#endif + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } #endif - result = __Pyx_PyObject_CallOneArg(method, arg); - goto done; -done: + *method = attr; + return 0; +} + +/* PyObjectCallMethod1 */ +static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { + PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); + Py_DECREF(method); return result; } static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { - PyObject *method, *result; - method = __Pyx_PyObject_GetAttrStr(obj, method_name); + PyObject *method = NULL, *result; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_Call2Args(method, obj, arg); + Py_DECREF(method); + return result; + } if (unlikely(!method)) return NULL; - result = __Pyx__PyObject_CallMethod1(method, arg); - Py_DECREF(method); - return result; + return __Pyx__PyObject_CallMethod1(method, arg); } /* pop_index */ - static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix) { +static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix) { PyObject *r; if (unlikely(!py_ix)) return NULL; r = __Pyx__PyObject_PopIndex(L, py_ix); @@ -5940,7 +5936,7 @@ static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t if (cix < 0) { cix += size; } - if (likely(0 <= cix && cix < size)) { + if (likely(__Pyx_is_valid_index(cix, size))) { PyObject* v = PyList_GET_ITEM(L, cix); Py_SIZE(L) -= 1; size -= 1; @@ -5957,7 +5953,7 @@ static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t #endif /* PyErrExceptionMatches */ - #if CYTHON_FAST_THREAD_STATE +#if CYTHON_FAST_THREAD_STATE static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { Py_ssize_t i, n; n = PyTuple_GET_SIZE(tuple); @@ -5982,7 +5978,7 @@ static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tsta #endif /* GetAttr */ - static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { #if CYTHON_USE_TYPE_SLOTS #if PY_MAJOR_VERSION >= 3 if (likely(PyUnicode_Check(n))) @@ -5995,7 +5991,7 @@ static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tsta } /* GetAttr3 */ - static PyObject *__Pyx_GetAttr3Default(PyObject *d) { +static PyObject *__Pyx_GetAttr3Default(PyObject *d) { __Pyx_PyThreadState_declare __Pyx_PyThreadState_assign if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) @@ -6010,34 +6006,42 @@ static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject } /* GetModuleGlobalName */ - static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ PyObject *result; #if !CYTHON_AVOID_BORROWED_REFS #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) if (likely(result)) { - Py_INCREF(result); + return __Pyx_NewRef(result); } else if (unlikely(PyErr_Occurred())) { - result = NULL; - } else { + return NULL; + } #else result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) if (likely(result)) { - Py_INCREF(result); - } else { + return __Pyx_NewRef(result); + } #endif #else result = PyObject_GetItem(__pyx_d, name); - if (!result) { - PyErr_Clear(); -#endif - result = __Pyx_GetBuiltinName(name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); } - return result; + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); } /* Import */ - static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { PyObject *empty_list = 0; PyObject *module = 0; PyObject *global_dict = 0; @@ -6084,7 +6088,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject if (!py_level) goto bad; module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, NULL); + name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); Py_DECREF(py_level); #else module = PyImport_ImportModuleLevelObject( @@ -6102,7 +6106,7 @@ bad: } /* ImportFrom */ - static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Format(PyExc_ImportError, @@ -6116,7 +6120,7 @@ bad: } /* HasAttr */ - static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { PyObject *r; if (unlikely(!__Pyx_PyBaseString_Check(n))) { PyErr_SetString(PyExc_TypeError, @@ -6134,7 +6138,7 @@ bad: } /* PyObject_GenericGetAttrNoDict */ - #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { PyErr_Format(PyExc_AttributeError, #if PY_MAJOR_VERSION >= 3 @@ -6174,7 +6178,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj #endif /* PyObject_GenericGetAttr */ - #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { return PyObject_GenericGetAttr(obj, attr_name); @@ -6184,7 +6188,7 @@ static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_nam #endif /* SetVTable */ - static int __Pyx_SetVtable(PyObject *dict, void *vtable) { +static int __Pyx_SetVtable(PyObject *dict, void *vtable) { #if PY_VERSION_HEX >= 0x02070000 PyObject *ob = PyCapsule_New(vtable, 0, 0); #else @@ -6202,7 +6206,7 @@ bad: } /* SetupReduce */ - static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { +static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { int ret; PyObject *name_attr; name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name); @@ -6278,8 +6282,8 @@ GOOD: } /* CLineInTraceback */ - #ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) { +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { PyObject *use_cline; PyObject *ptype, *pvalue, *ptraceback; #if CYTHON_COMPILING_IN_CPYTHON @@ -6292,7 +6296,9 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li #if CYTHON_COMPILING_IN_CPYTHON cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); if (likely(cython_runtime_dict)) { - use_cline = __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback); + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) } else #endif { @@ -6309,7 +6315,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li c_line = 0; PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); } - else if (PyObject_Not(use_cline) != 0) { + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { c_line = 0; } __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); @@ -6318,7 +6324,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li #endif /* CodeObjectCache */ - static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { int start = 0, mid = 0, end = count - 1; if (end >= 0 && code_line > entries[end].code_line) { return count; @@ -6398,7 +6404,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { } /* AddTraceback */ - #include "compile.h" +#include "compile.h" #include "frameobject.h" #include "traceback.h" static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( @@ -6483,8 +6489,8 @@ bad: } /* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { - const int neg_one = (int) -1, const_zero = (int) 0; +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(int) < sizeof(long)) { @@ -6514,7 +6520,7 @@ bad: } /* CIntFromPyVerify */ - #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) #define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) @@ -6536,8 +6542,8 @@ bad: } /* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) -1, const_zero = (long) 0; +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(long) < sizeof(long)) { @@ -6567,8 +6573,8 @@ bad: } /* CIntFromPy */ - static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) -1, const_zero = (long) 0; +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -6756,8 +6762,8 @@ raise_neg_overflow: } /* CIntFromPy */ - static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) -1, const_zero = (int) 0; +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -6945,7 +6951,7 @@ raise_neg_overflow: } /* FastTypeChecks */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { while (a) { a = a->tp_base; @@ -7045,7 +7051,7 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj #endif /* CheckBinaryVersion */ - static int __Pyx_check_binary_version(void) { +static int __Pyx_check_binary_version(void) { char ctversion[4], rtversion[4]; PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); @@ -7061,7 +7067,7 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj } /* InitStrings */ - static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { #if PY_MAJOR_VERSION < 3 if (t->is_unicode) { @@ -7170,6 +7176,13 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { if (is_true | (x == Py_False) | (x == Py_None)) return is_true; else return PyObject_IsTrue(x); } +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { #if PY_MAJOR_VERSION >= 3 if (PyLong_Check(result)) { @@ -7247,7 +7260,7 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { if (sizeof(Py_ssize_t) >= sizeof(long)) return PyInt_AS_LONG(b); else - return PyInt_AsSsize_t(x); + return PyInt_AsSsize_t(b); } #endif if (likely(PyLong_CheckExact(b))) { diff --git a/aiohttp/_headers.pxi b/aiohttp/_headers.pxi index e953fa5..22ef15c 100644 --- a/aiohttp/_headers.pxi +++ b/aiohttp/_headers.pxi @@ -1,4 +1,7 @@ -# The file is autogenerated from aiohtt/hdrs.py# Run ./tools/gen.py to update it after the origin changing.from . import hdrs +# The file is autogenerated from aiohttp/hdrs.py +# Run ./tools/gen.py to update it after the origin changing. + +from . import hdrs cdef tuple headers = ( hdrs.ACCEPT, hdrs.ACCEPT_CHARSET, diff --git a/aiohttp/_helpers.c b/aiohttp/_helpers.c index ef4e81d..0e7a675 100644 --- a/aiohttp/_helpers.c +++ b/aiohttp/_helpers.c @@ -1,4 +1,4 @@ -/* Generated by Cython 0.28.5 */ +/* Generated by Cython 0.29.2 */ /* BEGIN: Cython Metadata { @@ -19,7 +19,8 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) #error Cython requires Python 2.6+ or Python 3.3+. #else -#define CYTHON_ABI "0_28_5" +#define CYTHON_ABI "0_29_2" +#define CYTHON_HEX_VERSION 0x001D02F0 #define CYTHON_FUTURE_DIVISION 0 #include <stddef.h> #ifndef offsetof @@ -90,6 +91,10 @@ END: Cython Metadata */ #define CYTHON_PEP489_MULTI_PHASE_INIT 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #elif defined(PYSTON_VERSION) #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 1 @@ -127,6 +132,10 @@ END: Cython Metadata */ #define CYTHON_PEP489_MULTI_PHASE_INIT 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #else #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 0 @@ -180,11 +189,17 @@ END: Cython Metadata */ #define CYTHON_FAST_PYCALL 1 #endif #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (0 && PY_VERSION_HEX >= 0x03050000) + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) #endif #ifndef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif #endif #if !defined(CYTHON_FAST_PYCCALL) #define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) @@ -194,6 +209,9 @@ END: Cython Metadata */ #undef SHIFT #undef BASE #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif #endif #ifndef __has_attribute #define __has_attribute(x) 0 @@ -320,6 +338,9 @@ END: Cython Metadata */ #ifndef Py_TPFLAGS_HAVE_FINALIZE #define Py_TPFLAGS_HAVE_FINALIZE 0 #endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif #if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) #ifndef METH_FASTCALL #define METH_FASTCALL 0x80 @@ -333,15 +354,40 @@ END: Cython Metadata */ #endif #if CYTHON_FAST_PYCCALL #define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))))) + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) #else #define __Pyx_PyFastCFunction_Check(func) 0 #endif +#if CYTHON_USE_DICT_VERSIONS +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ + } +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) #define PyObject_Malloc(s) PyMem_Malloc(s) #define PyObject_Free(p) PyMem_Free(p) #define PyObject_Realloc(p) PyMem_Realloc(p) #endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif #if CYTHON_COMPILING_IN_PYSTON #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) @@ -449,8 +495,8 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) #endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) #else @@ -602,6 +648,9 @@ typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* enc (sizeof(type) == sizeof(Py_ssize_t) &&\ (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} #if defined (__cplusplus) && __cplusplus >= 201103L #include <cstdlib> #define __Pyx_sst_abs(value) std::abs(value) @@ -660,6 +709,7 @@ static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); #define __Pyx_PySequence_Tuple(obj)\ (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) @@ -740,7 +790,7 @@ static int __Pyx_init_sys_getdefaultencoding_params(void) { if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); Py_DECREF(default_encoding); @@ -911,6 +961,11 @@ static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* k #define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) #endif +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + /* PyThreadStateGet.proto */ #if CYTHON_FAST_THREAD_STATE #define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; @@ -965,6 +1020,18 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, #else #define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) #endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) #endif /* PyObjectCall.proto */ @@ -974,6 +1041,9 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg #define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) #endif +/* PyObjectCall2Args.proto */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + /* PyObjectCallMethO.proto */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); @@ -1017,7 +1087,25 @@ static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /* GetModuleGlobalName.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif /* Import.proto */ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); @@ -1117,6 +1205,7 @@ static const char __pyx_k_main[] = "__main__"; static const char __pyx_k_name[] = "__name__"; static const char __pyx_k_test[] = "__test__"; static const char __pyx_k_cache[] = "_cache"; +static const char __pyx_k_reify[] = "reify"; static const char __pyx_k_import[] = "__import__"; static const char __pyx_k_pickle[] = "pickle"; static const char __pyx_k_reduce[] = "__reduce__"; @@ -1166,6 +1255,7 @@ static PyObject *__pyx_n_s_reduce; static PyObject *__pyx_n_s_reduce_cython; static PyObject *__pyx_n_s_reduce_ex; static PyObject *__pyx_kp_s_reified_property_is_read_only; +static PyObject *__pyx_n_s_reify; static PyObject *__pyx_n_s_setstate; static PyObject *__pyx_n_s_setstate_cython; static PyObject *__pyx_kp_s_stringsource; @@ -1396,9 +1486,8 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_2__get__(struct __pyx_obj_7a PyObject *__pyx_t_11 = NULL; PyObject *__pyx_t_12 = NULL; PyObject *__pyx_t_13 = NULL; - PyObject *__pyx_t_14 = NULL; + int __pyx_t_14; int __pyx_t_15; - int __pyx_t_16; __Pyx_RefNannySetupContext("__get__", 0); /* "aiohttp/_helpers.pyx":22 @@ -1495,38 +1584,10 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_2__get__(struct __pyx_obj_7a __Pyx_DECREF_SET(__pyx_t_12, function); } } - if (!__pyx_t_13) { - __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_v_inst); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 26, __pyx_L11_except_error) - __Pyx_GOTREF(__pyx_t_11); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_12)) { - PyObject *__pyx_temp[2] = {__pyx_t_13, __pyx_v_inst}; - __pyx_t_11 = __Pyx_PyFunction_FastCall(__pyx_t_12, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 26, __pyx_L11_except_error) - __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; - __Pyx_GOTREF(__pyx_t_11); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_12)) { - PyObject *__pyx_temp[2] = {__pyx_t_13, __pyx_v_inst}; - __pyx_t_11 = __Pyx_PyCFunction_FastCall(__pyx_t_12, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 26, __pyx_L11_except_error) - __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; - __Pyx_GOTREF(__pyx_t_11); - } else - #endif - { - __pyx_t_14 = PyTuple_New(1+1); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 26, __pyx_L11_except_error) - __Pyx_GOTREF(__pyx_t_14); - __Pyx_GIVEREF(__pyx_t_13); PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_13); __pyx_t_13 = NULL; - __Pyx_INCREF(__pyx_v_inst); - __Pyx_GIVEREF(__pyx_v_inst); - PyTuple_SET_ITEM(__pyx_t_14, 0+1, __pyx_v_inst); - __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_14, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 26, __pyx_L11_except_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; - } - } + __pyx_t_11 = (__pyx_t_13) ? __Pyx_PyObject_Call2Args(__pyx_t_12, __pyx_t_13, __pyx_v_inst) : __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_v_inst); + __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 26, __pyx_L11_except_error) + __Pyx_GOTREF(__pyx_t_11); __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; __pyx_v_val = __pyx_t_11; __pyx_t_11 = 0; @@ -1597,7 +1658,6 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_2__get__(struct __pyx_obj_7a } __pyx_L3_error:; __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; - __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; @@ -1626,9 +1686,9 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_2__get__(struct __pyx_obj_7a * return self * raise */ - __pyx_t_15 = (__pyx_v_inst == Py_None); - __pyx_t_16 = (__pyx_t_15 != 0); - if (__pyx_t_16) { + __pyx_t_14 = (__pyx_v_inst == Py_None); + __pyx_t_15 = (__pyx_t_14 != 0); + if (__pyx_t_15) { /* "aiohttp/_helpers.pyx":31 * except AttributeError: @@ -1713,7 +1773,6 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_2__get__(struct __pyx_obj_7a __Pyx_XDECREF(__pyx_t_11); __Pyx_XDECREF(__pyx_t_12); __Pyx_XDECREF(__pyx_t_13); - __Pyx_XDECREF(__pyx_t_14); __Pyx_AddTraceback("aiohttp._helpers.reify.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -1778,8 +1837,8 @@ static int __pyx_pf_7aiohttp_8_helpers_5reify_4__set__(CYTHON_UNUSED struct __py /* "(tree fragment)":1 * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef bint use_setstate - * state = (self.name, self.wrapped) + * cdef tuple state + * cdef object _dict */ /* Python wrapper */ @@ -1796,9 +1855,9 @@ static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_7__reduce_cython__(PyObject } static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self) { + PyObject *__pyx_v_state = 0; + PyObject *__pyx_v__dict = 0; int __pyx_v_use_setstate; - PyObject *__pyx_v_state = NULL; - PyObject *__pyx_v__dict = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; @@ -1809,14 +1868,14 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ PyObject *__pyx_t_6 = NULL; __Pyx_RefNannySetupContext("__reduce_cython__", 0); - /* "(tree fragment)":3 - * def __reduce_cython__(self): + /* "(tree fragment)":5 + * cdef object _dict * cdef bint use_setstate * state = (self.name, self.wrapped) # <<<<<<<<<<<<<< * _dict = getattr(self, '__dict__', None) * if _dict is not None: */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_self->name); __Pyx_GIVEREF(__pyx_v_self->name); @@ -1827,19 +1886,19 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ __pyx_v_state = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":4 + /* "(tree fragment)":6 * cdef bint use_setstate * state = (self.name, self.wrapped) * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< * if _dict is not None: * state += (_dict,) */ - __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v__dict = __pyx_t_1; __pyx_t_1 = 0; - /* "(tree fragment)":5 + /* "(tree fragment)":7 * state = (self.name, self.wrapped) * _dict = getattr(self, '__dict__', None) * if _dict is not None: # <<<<<<<<<<<<<< @@ -1850,25 +1909,25 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ __pyx_t_3 = (__pyx_t_2 != 0); if (__pyx_t_3) { - /* "(tree fragment)":6 + /* "(tree fragment)":8 * _dict = getattr(self, '__dict__', None) * if _dict is not None: * state += (_dict,) # <<<<<<<<<<<<<< * use_setstate = True * else: */ - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v__dict); __Pyx_GIVEREF(__pyx_v__dict); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__dict); - __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 8, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_4)); __pyx_t_4 = 0; - /* "(tree fragment)":7 + /* "(tree fragment)":9 * if _dict is not None: * state += (_dict,) * use_setstate = True # <<<<<<<<<<<<<< @@ -1877,7 +1936,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ */ __pyx_v_use_setstate = 1; - /* "(tree fragment)":5 + /* "(tree fragment)":7 * state = (self.name, self.wrapped) * _dict = getattr(self, '__dict__', None) * if _dict is not None: # <<<<<<<<<<<<<< @@ -1887,7 +1946,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ goto __pyx_L3; } - /* "(tree fragment)":9 + /* "(tree fragment)":11 * use_setstate = True * else: * use_setstate = self.name is not None or self.wrapped is not None # <<<<<<<<<<<<<< @@ -1910,7 +1969,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ } __pyx_L3:; - /* "(tree fragment)":10 + /* "(tree fragment)":12 * else: * use_setstate = self.name is not None or self.wrapped is not None * if use_setstate: # <<<<<<<<<<<<<< @@ -1920,7 +1979,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ __pyx_t_3 = (__pyx_v_use_setstate != 0); if (__pyx_t_3) { - /* "(tree fragment)":11 + /* "(tree fragment)":13 * use_setstate = self.name is not None or self.wrapped is not None * if use_setstate: * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state # <<<<<<<<<<<<<< @@ -1928,9 +1987,9 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) */ __Pyx_XDECREF(__pyx_r); - __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_pyx_unpickle_reify); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 11, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyx_unpickle_reify); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); @@ -1941,7 +2000,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ __Pyx_INCREF(Py_None); __Pyx_GIVEREF(Py_None); PyTuple_SET_ITEM(__pyx_t_1, 2, Py_None); - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); @@ -1956,7 +2015,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ __pyx_t_6 = 0; goto __pyx_L0; - /* "(tree fragment)":10 + /* "(tree fragment)":12 * else: * use_setstate = self.name is not None or self.wrapped is not None * if use_setstate: # <<<<<<<<<<<<<< @@ -1965,7 +2024,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ */ } - /* "(tree fragment)":13 + /* "(tree fragment)":15 * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state * else: * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) # <<<<<<<<<<<<<< @@ -1974,9 +2033,9 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ */ /*else*/ { __Pyx_XDECREF(__pyx_r); - __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_pyx_unpickle_reify); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_pyx_unpickle_reify); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); @@ -1987,7 +2046,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ __Pyx_INCREF(__pyx_v_state); __Pyx_GIVEREF(__pyx_v_state); PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_state); - __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); @@ -2002,8 +2061,8 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ /* "(tree fragment)":1 * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef bint use_setstate - * state = (self.name, self.wrapped) + * cdef tuple state + * cdef object _dict */ /* function exit code */ @@ -2021,7 +2080,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __ return __pyx_r; } -/* "(tree fragment)":14 +/* "(tree fragment)":16 * else: * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< @@ -2047,17 +2106,17 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_8__setstate_cython__(struct PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__setstate_cython__", 0); - /* "(tree fragment)":15 + /* "(tree fragment)":17 * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) * def __setstate_cython__(self, __pyx_state): * __pyx_unpickle_reify__set_state(self, __pyx_state) # <<<<<<<<<<<<<< */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 15, __pyx_L1_error) - __pyx_t_1 = __pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":14 + /* "(tree fragment)":16 * else: * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< @@ -2079,13 +2138,13 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_8__setstate_cython__(struct /* "(tree fragment)":1 * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x770cb8f: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_8_helpers_1__pyx_unpickle_reify = {"__pyx_unpickle_reify", (PyCFunction)__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify, METH_VARARGS|METH_KEYWORDS, 0}; +static PyMethodDef __pyx_mdef_7aiohttp_8_helpers_1__pyx_unpickle_reify = {"__pyx_unpickle_reify", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify, METH_VARARGS|METH_KEYWORDS, 0}; static PyObject *__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v___pyx_type = 0; long __pyx_v___pyx_checksum; @@ -2157,8 +2216,8 @@ static PyObject *__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify(PyObject *__p } static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = NULL; - PyObject *__pyx_v___pyx_result = NULL; + PyObject *__pyx_v___pyx_PickleError = 0; + PyObject *__pyx_v___pyx_result = 0; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; @@ -2166,12 +2225,12 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; + int __pyx_t_6; __Pyx_RefNannySetupContext("__pyx_unpickle_reify", 0); - /* "(tree fragment)":2 - * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result * if __pyx_checksum != 0x770cb8f: # <<<<<<<<<<<<<< * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) @@ -2179,38 +2238,38 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED __pyx_t_1 = ((__pyx_v___pyx_checksum != 0x770cb8f) != 0); if (__pyx_t_1) { - /* "(tree fragment)":3 - * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":5 + * cdef object __pyx_result * if __pyx_checksum != 0x770cb8f: * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) * __pyx_result = reify.__new__(__pyx_type) */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_n_s_PickleError); __Pyx_GIVEREF(__pyx_n_s_PickleError); PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, -1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, -1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_t_2); __pyx_v___pyx_PickleError = __pyx_t_2; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "(tree fragment)":4 + /* "(tree fragment)":6 * if __pyx_checksum != 0x770cb8f: * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) # <<<<<<<<<<<<<< * __pyx_result = reify.__new__(__pyx_type) * if __pyx_state is not None: */ - __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x77, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x77, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_INCREF(__pyx_v___pyx_PickleError); @@ -2224,110 +2283,53 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_5) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else - #endif - { - __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL; - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_4); - __pyx_t_4 = 0; - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 4, __pyx_L1_error) + __PYX_ERR(1, 6, __pyx_L1_error) - /* "(tree fragment)":2 - * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result * if __pyx_checksum != 0x770cb8f: # <<<<<<<<<<<<<< * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) */ } - /* "(tree fragment)":5 + /* "(tree fragment)":7 * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) * __pyx_result = reify.__new__(__pyx_type) # <<<<<<<<<<<<<< * if __pyx_state is not None: * __pyx_unpickle_reify__set_state(<reify> __pyx_result, __pyx_state) */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_8_helpers_reify), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_8_helpers_reify), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_6 = NULL; + __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_6)) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_6) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v___pyx_type}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v___pyx_type}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - { - __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); __pyx_t_6 = NULL; - __Pyx_INCREF(__pyx_v___pyx_type); - __Pyx_GIVEREF(__pyx_v___pyx_type); - PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v___pyx_type); - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - } + __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v___pyx_result = __pyx_t_3; __pyx_t_3 = 0; - /* "(tree fragment)":6 + /* "(tree fragment)":8 * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) * __pyx_result = reify.__new__(__pyx_type) * if __pyx_state is not None: # <<<<<<<<<<<<<< @@ -2335,22 +2337,22 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED * return __pyx_result */ __pyx_t_1 = (__pyx_v___pyx_state != Py_None); - __pyx_t_7 = (__pyx_t_1 != 0); - if (__pyx_t_7) { + __pyx_t_6 = (__pyx_t_1 != 0); + if (__pyx_t_6) { - /* "(tree fragment)":7 + /* "(tree fragment)":9 * __pyx_result = reify.__new__(__pyx_type) * if __pyx_state is not None: * __pyx_unpickle_reify__set_state(<reify> __pyx_result, __pyx_state) # <<<<<<<<<<<<<< * return __pyx_result * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 7, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "(tree fragment)":6 + /* "(tree fragment)":8 * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) * __pyx_result = reify.__new__(__pyx_type) * if __pyx_state is not None: # <<<<<<<<<<<<<< @@ -2359,7 +2361,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED */ } - /* "(tree fragment)":8 + /* "(tree fragment)":10 * if __pyx_state is not None: * __pyx_unpickle_reify__set_state(<reify> __pyx_result, __pyx_state) * return __pyx_result # <<<<<<<<<<<<<< @@ -2373,8 +2375,8 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED /* "(tree fragment)":1 * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x770cb8f: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ /* function exit code */ @@ -2383,7 +2385,6 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._helpers.__pyx_unpickle_reify", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -2394,7 +2395,7 @@ static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED return __pyx_r; } -/* "(tree fragment)":9 +/* "(tree fragment)":11 * __pyx_unpickle_reify__set_state(<reify> __pyx_result, __pyx_state) * return __pyx_result * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< @@ -2413,10 +2414,9 @@ static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(stru PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; __Pyx_RefNannySetupContext("__pyx_unpickle_reify__set_state", 0); - /* "(tree fragment)":10 + /* "(tree fragment)":12 * return __pyx_result * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] # <<<<<<<<<<<<<< @@ -2425,9 +2425,9 @@ static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(stru */ if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->name); @@ -2436,9 +2436,9 @@ static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(stru __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->wrapped); @@ -2446,7 +2446,7 @@ static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(stru __pyx_v___pyx_result->wrapped = __pyx_t_1; __pyx_t_1 = 0; - /* "(tree fragment)":11 + /* "(tree fragment)":13 * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< @@ -2454,36 +2454,36 @@ static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(stru */ if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 11, __pyx_L1_error) + __PYX_ERR(1, 13, __pyx_L1_error) } - __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) __pyx_t_4 = ((__pyx_t_3 > 2) != 0); if (__pyx_t_4) { } else { __pyx_t_2 = __pyx_t_4; goto __pyx_L4_bool_binop_done; } - __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) __pyx_t_5 = (__pyx_t_4 != 0); __pyx_t_2 = __pyx_t_5; __pyx_L4_bool_binop_done:; if (__pyx_t_2) { - /* "(tree fragment)":12 + /* "(tree fragment)":14 * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): * __pyx_result.__dict__.update(__pyx_state[2]) # <<<<<<<<<<<<<< */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) + __PYX_ERR(1, 14, __pyx_L1_error) } - __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __pyx_t_8 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { @@ -2495,45 +2495,15 @@ static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(stru __Pyx_DECREF_SET(__pyx_t_7, function); } } - if (!__pyx_t_8) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_t_6}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_t_6}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - { - __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __pyx_t_8 = NULL; - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_6); - __pyx_t_6 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } - } + __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":11 + /* "(tree fragment)":13 * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< @@ -2541,7 +2511,7 @@ static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(stru */ } - /* "(tree fragment)":9 + /* "(tree fragment)":11 * __pyx_unpickle_reify__set_state(<reify> __pyx_result, __pyx_state) * return __pyx_result * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< @@ -2557,7 +2527,6 @@ static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(stru __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); __Pyx_AddTraceback("aiohttp._helpers.__pyx_unpickle_reify__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; @@ -2744,6 +2713,15 @@ static struct PyModuleDef __pyx_moduledef = { NULL /* m_free */ }; #endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1}, @@ -2771,6 +2749,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, {&__pyx_kp_s_reified_property_is_read_only, __pyx_k_reified_property_is_read_only, sizeof(__pyx_k_reified_property_is_read_only), 0, 0, 1, 0}, + {&__pyx_n_s_reify, __pyx_k_reify, sizeof(__pyx_k_reify), 0, 0, 1, 1}, {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, @@ -2779,7 +2758,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_wrapped, __pyx_k_wrapped, sizeof(__pyx_k_wrapped), 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0} }; -static int __Pyx_InitCachedBuiltins(void) { +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 25, __pyx_L1_error) __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) __PYX_ERR(0, 29, __pyx_L1_error) return 0; @@ -2787,7 +2766,7 @@ static int __Pyx_InitCachedBuiltins(void) { return -1; } -static int __Pyx_InitCachedConstants(void) { +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); @@ -2802,8 +2781,8 @@ static int __Pyx_InitCachedConstants(void) { /* "(tree fragment)":1 * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x770cb8f: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ __pyx_tuple__2 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__2); @@ -2816,7 +2795,7 @@ static int __Pyx_InitCachedConstants(void) { return -1; } -static int __Pyx_InitGlobals(void) { +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); __pyx_int_124832655 = PyInt_FromLong(124832655L); if (unlikely(!__pyx_int_124832655)) __PYX_ERR(0, 1, __pyx_L1_error) return 0; @@ -2824,13 +2803,13 @@ static int __Pyx_InitGlobals(void) { return -1; } -static int __Pyx_modinit_global_init_code(void); /*proto*/ -static int __Pyx_modinit_variable_export_code(void); /*proto*/ -static int __Pyx_modinit_function_export_code(void); /*proto*/ -static int __Pyx_modinit_type_init_code(void); /*proto*/ -static int __Pyx_modinit_type_import_code(void); /*proto*/ -static int __Pyx_modinit_variable_import_code(void); /*proto*/ -static int __Pyx_modinit_function_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ static int __Pyx_modinit_global_init_code(void) { __Pyx_RefNannyDeclarations @@ -2865,7 +2844,7 @@ static int __Pyx_modinit_type_init_code(void) { if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_8_helpers_reify.tp_dictoffset && __pyx_type_7aiohttp_8_helpers_reify.tp_getattro == PyObject_GenericGetAttr)) { __pyx_type_7aiohttp_8_helpers_reify.tp_getattro = __Pyx_PyObject_GenericGetAttr; } - if (PyObject_SetAttrString(__pyx_m, "reify", (PyObject *)&__pyx_type_7aiohttp_8_helpers_reify) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_reify, (PyObject *)&__pyx_type_7aiohttp_8_helpers_reify) < 0) __PYX_ERR(0, 1, __pyx_L1_error) if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_8_helpers_reify) < 0) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_ptype_7aiohttp_8_helpers_reify = &__pyx_type_7aiohttp_8_helpers_reify; __Pyx_RefNannyFinishContext(); @@ -2913,15 +2892,6 @@ static int __Pyx_modinit_function_import_code(void) { #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC #endif #endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (!(defined(__cplusplus)) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4))) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif #if PY_MAJOR_VERSION < 3 @@ -2934,11 +2904,36 @@ __Pyx_PyMODINIT_FUNC PyInit__helpers(void) { return PyModuleDef_Init(&__pyx_moduledef); } -static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name) { +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { PyObject *value = PyObject_GetAttrString(spec, from_name); int result = 0; if (likely(value)) { - result = PyDict_SetItemString(moddict, to_name, value); + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } Py_DECREF(value); } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); @@ -2947,8 +2942,10 @@ static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const ch } return result; } -static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; if (__pyx_m) return __Pyx_NewRef(__pyx_m); modname = PyObject_GetAttrString(spec, "name"); @@ -2958,10 +2955,10 @@ static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *d if (unlikely(!module)) goto bad; moddict = PyModule_GetDict(module); if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; return module; bad: Py_XDECREF(module); @@ -2969,14 +2966,18 @@ bad: } -static int __pyx_pymod_exec__helpers(PyObject *__pyx_pyinit_module) +static CYTHON_SMALL_CODE int __pyx_pymod_exec__helpers(PyObject *__pyx_pyinit_module) #endif #endif { PyObject *__pyx_t_1 = NULL; __Pyx_RefNannyDeclarations #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m && __pyx_m == __pyx_pyinit_module) return 0; + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_helpers' has already been imported. Re-initialisation is not supported."); + return -1; + } #elif PY_MAJOR_VERSION >= 3 if (__pyx_m) return __Pyx_NewRef(__pyx_m); #endif @@ -2991,6 +2992,9 @@ if (!__Pyx_RefNanny) { #endif __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__helpers(void)", 0); if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) @@ -3045,7 +3049,7 @@ if (!__Pyx_RefNanny) { if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif if (__pyx_module_is_main_aiohttp___helpers) { - if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) } #if PY_MAJOR_VERSION >= 3 { @@ -3074,8 +3078,8 @@ if (!__Pyx_RefNanny) { /* "(tree fragment)":1 * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x770cb8f: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_8_helpers_1__pyx_unpickle_reify, NULL, __pyx_n_s_aiohttp__helpers); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); @@ -3099,9 +3103,9 @@ if (!__Pyx_RefNanny) { __Pyx_XDECREF(__pyx_t_1); if (__pyx_m) { if (__pyx_d) { - __Pyx_AddTraceback("init aiohttp._helpers", 0, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("init aiohttp._helpers", __pyx_clineno, __pyx_lineno, __pyx_filename); } - Py_DECREF(__pyx_m); __pyx_m = 0; + Py_CLEAR(__pyx_m); } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, "init aiohttp._helpers"); } @@ -3122,9 +3126,9 @@ if (!__Pyx_RefNanny) { static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { PyObject *m = NULL, *p = NULL; void *r = NULL; - m = PyImport_ImportModule((char *)modname); + m = PyImport_ImportModule(modname); if (!m) goto end; - p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); + p = PyObject_GetAttrString(m, "RefNannyAPI"); if (!p) goto end; r = PyLong_AsVoidPtr(p); end: @@ -3320,7 +3324,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_ if (wraparound & unlikely(i < 0)) { wrapped_i += PyList_GET_SIZE(o); } - if ((!boundscheck) || likely((0 <= wrapped_i) & (wrapped_i < PyList_GET_SIZE(o)))) { + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { PyObject *r = PyList_GET_ITEM(o, wrapped_i); Py_INCREF(r); return r; @@ -3338,7 +3342,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize if (wraparound & unlikely(i < 0)) { wrapped_i += PyTuple_GET_SIZE(o); } - if ((!boundscheck) || likely((0 <= wrapped_i) & (wrapped_i < PyTuple_GET_SIZE(o)))) { + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); Py_INCREF(r); return r; @@ -3354,7 +3358,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS if (is_list || PyList_CheckExact(o)) { Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) { + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { PyObject *r = PyList_GET_ITEM(o, n); Py_INCREF(r); return r; @@ -3362,7 +3366,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, } else if (PyTuple_CheckExact(o)) { Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) { + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, n); Py_INCREF(r); return r; @@ -3420,13 +3424,29 @@ static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { } #endif +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + /* SaveResetException */ #if CYTHON_FAST_THREAD_STATE static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if PY_VERSION_HEX >= 0x030700A3 - *type = tstate->exc_state.exc_type; - *value = tstate->exc_state.exc_value; - *tb = tstate->exc_state.exc_traceback; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; #else *type = tstate->exc_type; *value = tstate->exc_value; @@ -3438,13 +3458,14 @@ static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject * } static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030700A3 - tmp_type = tstate->exc_state.exc_type; - tmp_value = tstate->exc_state.exc_value; - tmp_tb = tstate->exc_state.exc_traceback; - tstate->exc_state.exc_type = type; - tstate->exc_state.exc_value = value; - tstate->exc_state.exc_traceback = tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; #else tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; @@ -3486,10 +3507,11 @@ static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tsta /* GetException */ #if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) #else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) #endif +{ PyObject *local_type, *local_value, *local_tb; #if CYTHON_FAST_THREAD_STATE PyObject *tmp_type, *tmp_value, *tmp_tb; @@ -3522,13 +3544,16 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) *value = local_value; *tb = local_tb; #if CYTHON_FAST_THREAD_STATE - #if PY_VERSION_HEX >= 0x030700A3 - tmp_type = tstate->exc_state.exc_type; - tmp_value = tstate->exc_state.exc_value; - tmp_tb = tstate->exc_state.exc_traceback; - tstate->exc_state.exc_type = local_type; - tstate->exc_state.exc_value = local_value; - tstate->exc_state.exc_traceback = local_tb; + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + } #else tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; @@ -3555,14 +3580,14 @@ bad: } /* PyCFunctionFastCall */ - #if CYTHON_FAST_PYCCALL +#if CYTHON_FAST_PYCCALL static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { PyCFunctionObject *func = (PyCFunctionObject*)func_obj; PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); int flags = PyCFunction_GET_FLAGS(func); assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); assert(nargs >= 0); assert(nargs == 0 || args != NULL); /* _PyCFunction_FastCallDict() must not be called with an exception set, @@ -3570,16 +3595,15 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P caller loses its exception */ assert(!PyErr_Occurred()); if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)meth)) (self, args, nargs, NULL); + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); } else { - return (*((__Pyx_PyCFunctionFast)meth)) (self, args, nargs); + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); } } #endif /* PyFunctionFastCall */ - #if CYTHON_FAST_PYCALL -#include "frameobject.h" +#if CYTHON_FAST_PYCALL static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, PyObject *globals) { PyFrameObject *f; @@ -3597,7 +3621,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args if (f == NULL) { return NULL; } - fastlocals = f->f_localsplus; + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); for (i = 0; i < na; i++) { Py_INCREF(*args); fastlocals[i] = *args++; @@ -3698,7 +3722,7 @@ done: #endif /* PyObjectCall */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { PyObject *result; ternaryfunc call = func->ob_type->tp_call; @@ -3717,8 +3741,37 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg } #endif +/* PyObjectCall2Args */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args, *result = NULL; + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyFunction_FastCall(function, args, 2); + } + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyCFunction_FastCall(function, args, 2); + } + #endif + args = PyTuple_New(2); + if (unlikely(!args)) goto done; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + Py_INCREF(function); + result = __Pyx_PyObject_Call(function, args, NULL); + Py_DECREF(args); + Py_DECREF(function); +done: + return result; +} + /* PyObjectCallMethO */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { PyObject *self, *result; PyCFunction cfunc; @@ -3738,7 +3791,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject #endif /* PyObjectCallOneArg */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { PyObject *result; PyObject *args = PyTuple_New(1); @@ -3778,7 +3831,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObjec #endif /* PyErrFetchRestore */ - #if CYTHON_FAST_THREAD_STATE +#if CYTHON_FAST_THREAD_STATE static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; tmp_type = tstate->curexc_type; @@ -3802,7 +3855,7 @@ static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject #endif /* RaiseException */ - #if PY_MAJOR_VERSION < 3 +#if PY_MAJOR_VERSION < 3 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, CYTHON_UNUSED PyObject *cause) { __Pyx_PyThreadState_declare @@ -3961,7 +4014,7 @@ bad: #endif /* GetAttr */ - static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { #if CYTHON_USE_TYPE_SLOTS #if PY_MAJOR_VERSION >= 3 if (likely(PyUnicode_Check(n))) @@ -3974,7 +4027,7 @@ bad: } /* GetAttr3 */ - static PyObject *__Pyx_GetAttr3Default(PyObject *d) { +static PyObject *__Pyx_GetAttr3Default(PyObject *d) { __Pyx_PyThreadState_declare __Pyx_PyThreadState_assign if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) @@ -3989,34 +4042,42 @@ static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject } /* GetModuleGlobalName */ - static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ PyObject *result; #if !CYTHON_AVOID_BORROWED_REFS #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) if (likely(result)) { - Py_INCREF(result); + return __Pyx_NewRef(result); } else if (unlikely(PyErr_Occurred())) { - result = NULL; - } else { + return NULL; + } #else result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) if (likely(result)) { - Py_INCREF(result); - } else { + return __Pyx_NewRef(result); + } #endif #else result = PyObject_GetItem(__pyx_d, name); - if (!result) { - PyErr_Clear(); -#endif - result = __Pyx_GetBuiltinName(name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); } - return result; + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); } /* Import */ - static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { PyObject *empty_list = 0; PyObject *module = 0; PyObject *global_dict = 0; @@ -4063,7 +4124,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject if (!py_level) goto bad; module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, NULL); + name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); Py_DECREF(py_level); #else module = PyImport_ImportModuleLevelObject( @@ -4081,7 +4142,7 @@ bad: } /* ImportFrom */ - static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Format(PyExc_ImportError, @@ -4095,7 +4156,7 @@ bad: } /* HasAttr */ - static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { PyObject *r; if (unlikely(!__Pyx_PyBaseString_Check(n))) { PyErr_SetString(PyExc_TypeError, @@ -4113,7 +4174,7 @@ bad: } /* PyObject_GenericGetAttrNoDict */ - #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { PyErr_Format(PyExc_AttributeError, #if PY_MAJOR_VERSION >= 3 @@ -4153,7 +4214,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj #endif /* PyObject_GenericGetAttr */ - #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { return PyObject_GenericGetAttr(obj, attr_name); @@ -4163,7 +4224,7 @@ static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_nam #endif /* SetupReduce */ - static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { +static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { int ret; PyObject *name_attr; name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name); @@ -4239,8 +4300,8 @@ GOOD: } /* CLineInTraceback */ - #ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) { +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { PyObject *use_cline; PyObject *ptype, *pvalue, *ptraceback; #if CYTHON_COMPILING_IN_CPYTHON @@ -4253,7 +4314,9 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li #if CYTHON_COMPILING_IN_CPYTHON cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); if (likely(cython_runtime_dict)) { - use_cline = __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback); + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) } else #endif { @@ -4270,7 +4333,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li c_line = 0; PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); } - else if (PyObject_Not(use_cline) != 0) { + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { c_line = 0; } __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); @@ -4279,7 +4342,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li #endif /* CodeObjectCache */ - static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { int start = 0, mid = 0, end = count - 1; if (end >= 0 && code_line > entries[end].code_line) { return count; @@ -4359,7 +4422,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { } /* AddTraceback */ - #include "compile.h" +#include "compile.h" #include "frameobject.h" #include "traceback.h" static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( @@ -4444,7 +4507,7 @@ bad: } /* CIntFromPyVerify */ - #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) #define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) @@ -4466,8 +4529,8 @@ bad: } /* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) -1, const_zero = (long) 0; +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(long) < sizeof(long)) { @@ -4497,8 +4560,8 @@ bad: } /* CIntFromPy */ - static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) -1, const_zero = (long) 0; +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -4686,8 +4749,8 @@ raise_neg_overflow: } /* CIntFromPy */ - static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) -1, const_zero = (int) 0; +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -4875,7 +4938,7 @@ raise_neg_overflow: } /* FastTypeChecks */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { while (a) { a = a->tp_base; @@ -4975,7 +5038,7 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj #endif /* CheckBinaryVersion */ - static int __Pyx_check_binary_version(void) { +static int __Pyx_check_binary_version(void) { char ctversion[4], rtversion[4]; PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); @@ -4991,7 +5054,7 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj } /* InitStrings */ - static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { #if PY_MAJOR_VERSION < 3 if (t->is_unicode) { @@ -5100,6 +5163,13 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { if (is_true | (x == Py_False) | (x == Py_None)) return is_true; else return PyObject_IsTrue(x); } +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { #if PY_MAJOR_VERSION >= 3 if (PyLong_Check(result)) { @@ -5177,7 +5247,7 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { if (sizeof(Py_ssize_t) >= sizeof(long)) return PyInt_AS_LONG(b); else - return PyInt_AsSsize_t(x); + return PyInt_AsSsize_t(b); } #endif if (likely(PyLong_CheckExact(b))) { diff --git a/aiohttp/_http_parser.c b/aiohttp/_http_parser.c index 38bd532..d02f300 100644 --- a/aiohttp/_http_parser.c +++ b/aiohttp/_http_parser.c @@ -1,4 +1,4 @@ -/* Generated by Cython 0.28.5 */ +/* Generated by Cython 0.29.2 */ /* BEGIN: Cython Metadata { @@ -28,7 +28,8 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) #error Cython requires Python 2.6+ or Python 3.3+. #else -#define CYTHON_ABI "0_28_5" +#define CYTHON_ABI "0_29_2" +#define CYTHON_HEX_VERSION 0x001D02F0 #define CYTHON_FUTURE_DIVISION 1 #include <stddef.h> #ifndef offsetof @@ -99,6 +100,10 @@ END: Cython Metadata */ #define CYTHON_PEP489_MULTI_PHASE_INIT 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #elif defined(PYSTON_VERSION) #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 1 @@ -136,6 +141,10 @@ END: Cython Metadata */ #define CYTHON_PEP489_MULTI_PHASE_INIT 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #else #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 0 @@ -189,11 +198,17 @@ END: Cython Metadata */ #define CYTHON_FAST_PYCALL 1 #endif #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (0 && PY_VERSION_HEX >= 0x03050000) + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) #endif #ifndef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif #endif #if !defined(CYTHON_FAST_PYCCALL) #define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) @@ -203,6 +218,9 @@ END: Cython Metadata */ #undef SHIFT #undef BASE #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif #endif #ifndef __has_attribute #define __has_attribute(x) 0 @@ -329,6 +347,9 @@ END: Cython Metadata */ #ifndef Py_TPFLAGS_HAVE_FINALIZE #define Py_TPFLAGS_HAVE_FINALIZE 0 #endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif #if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) #ifndef METH_FASTCALL #define METH_FASTCALL 0x80 @@ -342,15 +363,40 @@ END: Cython Metadata */ #endif #if CYTHON_FAST_PYCCALL #define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))))) + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) #else #define __Pyx_PyFastCFunction_Check(func) 0 #endif +#if CYTHON_USE_DICT_VERSIONS +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ + } +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) #define PyObject_Malloc(s) PyMem_Malloc(s) #define PyObject_Free(p) PyMem_Free(p) #define PyObject_Realloc(p) PyMem_Realloc(p) #endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif #if CYTHON_COMPILING_IN_PYSTON #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) @@ -458,8 +504,8 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) #endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) #else @@ -617,6 +663,9 @@ typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* enc (sizeof(type) == sizeof(Py_ssize_t) &&\ (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} #if defined (__cplusplus) && __cplusplus >= 201103L #include <cstdlib> #define __Pyx_sst_abs(value) std::abs(value) @@ -675,6 +724,7 @@ static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); #define __Pyx_PySequence_Tuple(obj)\ (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) @@ -755,7 +805,7 @@ static int __Pyx_init_sys_getdefaultencoding_params(void) { if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); Py_DECREF(default_encoding); @@ -1307,7 +1357,25 @@ static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /* GetModuleGlobalName.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif /* PyFunctionFastCall.proto */ #if CYTHON_FAST_PYCALL @@ -1318,6 +1386,18 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, #else #define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) #endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) #endif /* PyObjectCall.proto */ @@ -1349,6 +1429,9 @@ static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObje /* PyObjectCallOneArg.proto */ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); +/* PyObjectCall2Args.proto */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + /* PySequenceContains.proto */ static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { int result = PySequence_Contains(seq, item); @@ -1399,6 +1482,11 @@ static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject * static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); #endif +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + /* SaveResetException.proto */ #if CYTHON_FAST_THREAD_STATE #define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) @@ -1462,6 +1550,17 @@ static int __Pyx_setup_reduce(PyObject* type_obj); /* SetVTable.proto */ static int __Pyx_SetVtable(PyObject *dict, void *vtable); +/* TypeImport.proto */ +#ifndef __PYX_HAVE_RT_ImportType_proto +#define __PYX_HAVE_RT_ImportType_proto +enum __Pyx_ImportType_CheckSize { + __Pyx_ImportType_CheckSize_Error = 0, + __Pyx_ImportType_CheckSize_Warn = 1, + __Pyx_ImportType_CheckSize_Ignore = 2 +}; +static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); +#endif + /* CLineInTraceback.proto */ #ifdef CYTHON_CLINE_IN_TRACEBACK #define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) @@ -1531,19 +1630,28 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj /* FetchCommonType.proto */ static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + /* PyObjectCallMethod1.proto */ static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); -static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg); /* CoroutineBase.proto */ typedef PyObject *(*__pyx_coroutine_body_t)(PyObject *, PyThreadState *, PyObject *); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_ExcInfoStruct _PyErr_StackItem +#else typedef struct { - PyObject_HEAD - __pyx_coroutine_body_t body; - PyObject *closure; PyObject *exc_type; PyObject *exc_value; PyObject *exc_traceback; +} __Pyx_ExcInfoStruct; +#endif +typedef struct { + PyObject_HEAD + __pyx_coroutine_body_t body; + PyObject *closure; + __Pyx_ExcInfoStruct gi_exc_state; PyObject *gi_weakreflist; PyObject *classobj; PyObject *yieldfrom; @@ -1560,18 +1668,24 @@ static __pyx_CoroutineObject *__Pyx__Coroutine_New( static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, PyObject *name, PyObject *qualname, PyObject *module_name); +static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *self); static int __Pyx_Coroutine_clear(PyObject *self); static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value); static PyObject *__Pyx_Coroutine_Close(PyObject *self); static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_Coroutine_SwapException(self) +#define __Pyx_Coroutine_ResetAndClearException(self) __Pyx_Coroutine_ExceptionClear(&(self)->gi_exc_state) +#else #define __Pyx_Coroutine_SwapException(self) {\ - __Pyx_ExceptionSwap(&(self)->exc_type, &(self)->exc_value, &(self)->exc_traceback);\ - __Pyx_Coroutine_ResetFrameBackpointer(self);\ + __Pyx_ExceptionSwap(&(self)->gi_exc_state.exc_type, &(self)->gi_exc_state.exc_value, &(self)->gi_exc_state.exc_traceback);\ + __Pyx_Coroutine_ResetFrameBackpointer(&(self)->gi_exc_state);\ } #define __Pyx_Coroutine_ResetAndClearException(self) {\ - __Pyx_ExceptionReset((self)->exc_type, (self)->exc_value, (self)->exc_traceback);\ - (self)->exc_type = (self)->exc_value = (self)->exc_traceback = NULL;\ + __Pyx_ExceptionReset((self)->gi_exc_state.exc_type, (self)->gi_exc_state.exc_value, (self)->gi_exc_state.exc_traceback);\ + (self)->gi_exc_state.exc_type = (self)->gi_exc_state.exc_value = (self)->gi_exc_state.exc_traceback = NULL;\ } +#endif #if CYTHON_FAST_THREAD_STATE #define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ __Pyx_PyGen__FetchStopIterationValue(__pyx_tstate, pvalue) @@ -1580,7 +1694,7 @@ static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue) #endif static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue); -static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__pyx_CoroutineObject *self); +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state); /* PatchModuleWithCoroutine.proto */ static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code); @@ -1600,21 +1714,6 @@ static int __pyx_Generator_init(void); /* CheckBinaryVersion.proto */ static int __Pyx_check_binary_version(void); -/* PyIdentifierFromString.proto */ -#if !defined(__Pyx_PyIdentifier_FromString) -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) -#else - #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) -#endif -#endif - -/* ModuleImport.proto */ -static PyObject *__Pyx_ImportModule(const char *name); - -/* TypeImport.proto */ -static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); - /* InitStrings.proto */ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); @@ -1781,13 +1880,13 @@ static const char __pyx_k_i[] = "i"; static const char __pyx_k_TE[] = "TE"; static const char __pyx_k__2[] = ", "; static const char __pyx_k__3[] = ")>"; -static const char __pyx_k__6[] = ""; +static const char __pyx_k__4[] = ""; static const char __pyx_k_br[] = "br"; static const char __pyx_k_AGE[] = "AGE"; static const char __pyx_k_URI[] = "URI"; static const char __pyx_k_URL[] = "URL"; static const char __pyx_k_VIA[] = "VIA"; -static const char __pyx_k__13[] = ":"; +static const char __pyx_k__11[] = ":"; static const char __pyx_k_add[] = "add"; static const char __pyx_k_all[] = "__all__"; static const char __pyx_k_new[] = "__new__"; @@ -2045,7 +2144,9 @@ static PyObject *__pyx_n_s_FROM; static PyObject *__pyx_n_s_HOST; static PyObject *__pyx_kp_u_Header_name_is_too_long; static PyObject *__pyx_kp_u_Header_value_is_too_long; +static PyObject *__pyx_n_s_HttpRequestParser; static PyObject *__pyx_n_u_HttpRequestParser; +static PyObject *__pyx_n_s_HttpResponseParser; static PyObject *__pyx_n_u_HttpResponseParser; static PyObject *__pyx_n_s_HttpVersion; static PyObject *__pyx_n_s_HttpVersion10; @@ -2082,8 +2183,10 @@ static PyObject *__pyx_n_s_RANGE; static PyObject *__pyx_n_s_REFERER; static PyObject *__pyx_n_s_RETRY_AFTER; static PyObject *__pyx_kp_u_RawRequestMessage; +static PyObject *__pyx_n_s_RawRequestMessage_2; static PyObject *__pyx_n_u_RawRequestMessage_2; static PyObject *__pyx_kp_u_RawResponseMessage; +static PyObject *__pyx_n_s_RawResponseMessage_2; static PyObject *__pyx_n_u_RawResponseMessage_2; static PyObject *__pyx_n_s_SEC_WEBSOCKET_ACCEPT; static PyObject *__pyx_n_s_SEC_WEBSOCKET_EXTENSIONS; @@ -2115,11 +2218,12 @@ static PyObject *__pyx_n_s_WWW_AUTHENTICATE; static PyObject *__pyx_n_s_X_FORWARDED_FOR; static PyObject *__pyx_n_s_X_FORWARDED_HOST; static PyObject *__pyx_n_s_X_FORWARDED_PROTO; -static PyObject *__pyx_kp_u__13; +static PyObject *__pyx_kp_u__11; static PyObject *__pyx_kp_u__2; static PyObject *__pyx_kp_u__3; -static PyObject *__pyx_kp_b__6; -static PyObject *__pyx_kp_u__6; +static PyObject *__pyx_n_s__4; +static PyObject *__pyx_kp_b__4; +static PyObject *__pyx_kp_u__4; static PyObject *__pyx_n_s_add; static PyObject *__pyx_n_s_aiohttp; static PyObject *__pyx_n_s_aiohttp__http_parser; @@ -2280,21 +2384,19 @@ static PyObject *__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_3_genex static __Pyx_CachedCFunction __pyx_umethod_PyUnicode_Type_partition = {0, &__pyx_n_s_partition, 0, 0, 0}; static PyObject *__pyx_int_21004882; static PyObject *__pyx_int_209127132; -static PyObject *__pyx_tuple__4; static PyObject *__pyx_tuple__5; +static PyObject *__pyx_tuple__6; static PyObject *__pyx_tuple__7; static PyObject *__pyx_tuple__8; static PyObject *__pyx_tuple__9; static PyObject *__pyx_tuple__10; -static PyObject *__pyx_tuple__11; static PyObject *__pyx_tuple__12; -static PyObject *__pyx_tuple__14; +static PyObject *__pyx_tuple__13; static PyObject *__pyx_tuple__15; static PyObject *__pyx_tuple__17; -static PyObject *__pyx_tuple__19; +static PyObject *__pyx_codeobj__14; static PyObject *__pyx_codeobj__16; static PyObject *__pyx_codeobj__18; -static PyObject *__pyx_codeobj__20; /* Late includes */ /* "aiohttp/_http_parser.pyx":57 @@ -3067,7 +3169,9 @@ static PyObject *__pyx_gb_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___ __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif __pyx_generator->resume_label = -1; __Pyx_Coroutine_clear((PyObject*)__pyx_generator); __Pyx_RefNannyFinishContext(); @@ -4275,8 +4379,8 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_3url___get /* "(tree fragment)":1 * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef bint use_setstate - * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) + * cdef tuple state + * cdef object _dict */ /* Python wrapper */ @@ -4293,9 +4397,9 @@ static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7__reduce_ } static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_cython__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_v_state = 0; + PyObject *__pyx_v__dict = 0; int __pyx_v_use_setstate; - PyObject *__pyx_v_state = NULL; - PyObject *__pyx_v__dict = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; @@ -4306,14 +4410,14 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ PyObject *__pyx_t_6 = NULL; __Pyx_RefNannySetupContext("__reduce_cython__", 0); - /* "(tree fragment)":3 - * def __reduce_cython__(self): + /* "(tree fragment)":5 + * cdef object _dict * cdef bint use_setstate * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) # <<<<<<<<<<<<<< * _dict = getattr(self, '__dict__', None) * if _dict is not None: */ - __pyx_t_1 = PyTuple_New(10); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(10); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_self->chunked); __Pyx_GIVEREF(__pyx_v_self->chunked); @@ -4348,19 +4452,19 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ __pyx_v_state = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":4 + /* "(tree fragment)":6 * cdef bint use_setstate * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< * if _dict is not None: * state += (_dict,) */ - __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v__dict = __pyx_t_1; __pyx_t_1 = 0; - /* "(tree fragment)":5 + /* "(tree fragment)":7 * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) * _dict = getattr(self, '__dict__', None) * if _dict is not None: # <<<<<<<<<<<<<< @@ -4371,25 +4475,25 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ __pyx_t_3 = (__pyx_t_2 != 0); if (__pyx_t_3) { - /* "(tree fragment)":6 + /* "(tree fragment)":8 * _dict = getattr(self, '__dict__', None) * if _dict is not None: * state += (_dict,) # <<<<<<<<<<<<<< * use_setstate = True * else: */ - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v__dict); __Pyx_GIVEREF(__pyx_v__dict); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__dict); - __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 8, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_4)); __pyx_t_4 = 0; - /* "(tree fragment)":7 + /* "(tree fragment)":9 * if _dict is not None: * state += (_dict,) * use_setstate = True # <<<<<<<<<<<<<< @@ -4398,7 +4502,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ */ __pyx_v_use_setstate = 1; - /* "(tree fragment)":5 + /* "(tree fragment)":7 * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) * _dict = getattr(self, '__dict__', None) * if _dict is not None: # <<<<<<<<<<<<<< @@ -4408,7 +4512,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ goto __pyx_L3; } - /* "(tree fragment)":9 + /* "(tree fragment)":11 * use_setstate = True * else: * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None # <<<<<<<<<<<<<< @@ -4487,7 +4591,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ } __pyx_L3:; - /* "(tree fragment)":10 + /* "(tree fragment)":12 * else: * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None * if use_setstate: # <<<<<<<<<<<<<< @@ -4497,7 +4601,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ __pyx_t_3 = (__pyx_v_use_setstate != 0); if (__pyx_t_3) { - /* "(tree fragment)":11 + /* "(tree fragment)":13 * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None * if use_setstate: * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state # <<<<<<<<<<<<<< @@ -4505,9 +4609,9 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) */ __Pyx_XDECREF(__pyx_r); - __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_pyx_unpickle_RawRequestMessage); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 11, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyx_unpickle_RawRequestMessage); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); @@ -4518,7 +4622,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ __Pyx_INCREF(Py_None); __Pyx_GIVEREF(Py_None); PyTuple_SET_ITEM(__pyx_t_1, 2, Py_None); - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); @@ -4533,7 +4637,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ __pyx_t_6 = 0; goto __pyx_L0; - /* "(tree fragment)":10 + /* "(tree fragment)":12 * else: * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None * if use_setstate: # <<<<<<<<<<<<<< @@ -4542,7 +4646,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ */ } - /* "(tree fragment)":13 + /* "(tree fragment)":15 * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state * else: * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) # <<<<<<<<<<<<<< @@ -4551,9 +4655,9 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ */ /*else*/ { __Pyx_XDECREF(__pyx_r); - __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_pyx_unpickle_RawRequestMessage); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_pyx_unpickle_RawRequestMessage); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); @@ -4564,7 +4668,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ __Pyx_INCREF(__pyx_v_state); __Pyx_GIVEREF(__pyx_v_state); PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_state); - __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); @@ -4579,8 +4683,8 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ /* "(tree fragment)":1 * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef bint use_setstate - * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) + * cdef tuple state + * cdef object _dict */ /* function exit code */ @@ -4598,7 +4702,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_ return __pyx_r; } -/* "(tree fragment)":14 +/* "(tree fragment)":16 * else: * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< @@ -4624,17 +4728,17 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_8__setstat PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__setstate_cython__", 0); - /* "(tree fragment)":15 + /* "(tree fragment)":17 * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) * def __setstate_cython__(self, __pyx_state): * __pyx_unpickle_RawRequestMessage__set_state(self, __pyx_state) # <<<<<<<<<<<<<< */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 15, __pyx_L1_error) - __pyx_t_1 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":14 + /* "(tree fragment)":16 * else: * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< @@ -5319,7 +5423,9 @@ static PyObject *__pyx_gb_7aiohttp_12_http_parser_18RawResponseMessage_8__repr__ __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif __pyx_generator->resume_label = -1; __Pyx_Coroutine_clear((PyObject*)__pyx_generator); __Pyx_RefNannyFinishContext(); @@ -5928,8 +6034,8 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7chunked_ /* "(tree fragment)":1 * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef bint use_setstate - * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) + * cdef tuple state + * cdef object _dict */ /* Python wrapper */ @@ -5946,9 +6052,9 @@ static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_5__reduce } static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce_cython__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_v_state = 0; + PyObject *__pyx_v__dict = 0; int __pyx_v_use_setstate; - PyObject *__pyx_v_state = NULL; - PyObject *__pyx_v__dict = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; @@ -5959,16 +6065,16 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce PyObject *__pyx_t_6 = NULL; __Pyx_RefNannySetupContext("__reduce_cython__", 0); - /* "(tree fragment)":3 - * def __reduce_cython__(self): + /* "(tree fragment)":5 + * cdef object _dict * cdef bint use_setstate * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) # <<<<<<<<<<<<<< * _dict = getattr(self, '__dict__', None) * if _dict is not None: */ - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->code); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->code); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyTuple_New(9); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_2 = PyTuple_New(9); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_v_self->chunked); __Pyx_GIVEREF(__pyx_v_self->chunked); @@ -6000,19 +6106,19 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce __pyx_v_state = ((PyObject*)__pyx_t_2); __pyx_t_2 = 0; - /* "(tree fragment)":4 + /* "(tree fragment)":6 * cdef bint use_setstate * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< * if _dict is not None: * state += (_dict,) */ - __pyx_t_2 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_2 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_v__dict = __pyx_t_2; __pyx_t_2 = 0; - /* "(tree fragment)":5 + /* "(tree fragment)":7 * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) * _dict = getattr(self, '__dict__', None) * if _dict is not None: # <<<<<<<<<<<<<< @@ -6023,25 +6129,25 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce __pyx_t_4 = (__pyx_t_3 != 0); if (__pyx_t_4) { - /* "(tree fragment)":6 + /* "(tree fragment)":8 * _dict = getattr(self, '__dict__', None) * if _dict is not None: * state += (_dict,) # <<<<<<<<<<<<<< * use_setstate = True * else: */ - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 8, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_v__dict); __Pyx_GIVEREF(__pyx_v__dict); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v__dict); - __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_1)); __pyx_t_1 = 0; - /* "(tree fragment)":7 + /* "(tree fragment)":9 * if _dict is not None: * state += (_dict,) * use_setstate = True # <<<<<<<<<<<<<< @@ -6050,7 +6156,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce */ __pyx_v_use_setstate = 1; - /* "(tree fragment)":5 + /* "(tree fragment)":7 * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) * _dict = getattr(self, '__dict__', None) * if _dict is not None: # <<<<<<<<<<<<<< @@ -6060,7 +6166,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce goto __pyx_L3; } - /* "(tree fragment)":9 + /* "(tree fragment)":11 * use_setstate = True * else: * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None # <<<<<<<<<<<<<< @@ -6125,7 +6231,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce } __pyx_L3:; - /* "(tree fragment)":10 + /* "(tree fragment)":12 * else: * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None * if use_setstate: # <<<<<<<<<<<<<< @@ -6135,7 +6241,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce __pyx_t_4 = (__pyx_v_use_setstate != 0); if (__pyx_t_4) { - /* "(tree fragment)":11 + /* "(tree fragment)":13 * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None * if use_setstate: * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state # <<<<<<<<<<<<<< @@ -6143,9 +6249,9 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_pyx_unpickle_RawResponseMessag); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 11, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_pyx_unpickle_RawResponseMessag); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); @@ -6156,7 +6262,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce __Pyx_INCREF(Py_None); __Pyx_GIVEREF(Py_None); PyTuple_SET_ITEM(__pyx_t_2, 2, Py_None); - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1); @@ -6171,7 +6277,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce __pyx_t_6 = 0; goto __pyx_L0; - /* "(tree fragment)":10 + /* "(tree fragment)":12 * else: * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None * if use_setstate: # <<<<<<<<<<<<<< @@ -6180,7 +6286,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce */ } - /* "(tree fragment)":13 + /* "(tree fragment)":15 * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state * else: * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) # <<<<<<<<<<<<<< @@ -6189,9 +6295,9 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce */ /*else*/ { __Pyx_XDECREF(__pyx_r); - __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_pyx_unpickle_RawResponseMessag); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_pyx_unpickle_RawResponseMessag); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); @@ -6202,7 +6308,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce __Pyx_INCREF(__pyx_v_state); __Pyx_GIVEREF(__pyx_v_state); PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_state); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6); @@ -6217,8 +6323,8 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce /* "(tree fragment)":1 * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef bint use_setstate - * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) + * cdef tuple state + * cdef object _dict */ /* function exit code */ @@ -6236,7 +6342,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce return __pyx_r; } -/* "(tree fragment)":14 +/* "(tree fragment)":16 * else: * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< @@ -6262,17 +6368,17 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_6__setsta PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__setstate_cython__", 0); - /* "(tree fragment)":15 + /* "(tree fragment)":17 * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) * def __setstate_cython__(self, __pyx_state): * __pyx_unpickle_RawResponseMessage__set_state(self, __pyx_state) # <<<<<<<<<<<<<< */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 15, __pyx_L1_error) - __pyx_t_1 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":14 + /* "(tree fragment)":16 * else: * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< @@ -7586,9 +7692,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple unsigned int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; + int __pyx_t_5; int __pyx_t_6; - int __pyx_t_7; + PyObject *__pyx_t_7 = NULL; int __pyx_t_8; int __pyx_t_9; int __pyx_t_10; @@ -7679,38 +7785,10 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple __Pyx_DECREF_SET(__pyx_t_3, function); } } - if (!__pyx_t_4) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_self->_headers); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 402, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_self->_headers}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 402, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_self->_headers}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 402, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - { - __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 402, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL; - __Pyx_INCREF(__pyx_v_self->_headers); - __Pyx_GIVEREF(__pyx_v_self->_headers); - PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_self->_headers); - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 402, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - } + __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_self->_headers) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_self->_headers); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 402, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_v_headers = __pyx_t_1; __pyx_t_1 = 0; @@ -7722,16 +7800,16 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * self._upgraded = True * */ - __pyx_t_7 = (__pyx_v_upgrade != 0); - if (!__pyx_t_7) { + __pyx_t_6 = (__pyx_v_upgrade != 0); + if (!__pyx_t_6) { } else { - __pyx_t_6 = __pyx_t_7; + __pyx_t_5 = __pyx_t_6; goto __pyx_L4_bool_binop_done; } - __pyx_t_7 = ((__pyx_v_self->_cparser->method == 5) != 0); - __pyx_t_6 = __pyx_t_7; + __pyx_t_6 = ((__pyx_v_self->_cparser->method == 5) != 0); + __pyx_t_5 = __pyx_t_6; __pyx_L4_bool_binop_done:; - if (__pyx_t_6) { + if (__pyx_t_5) { /* "aiohttp/_http_parser.pyx":405 * @@ -7758,9 +7836,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * raise InvalidHeader(SEC_WEBSOCKET_KEY1) * */ - __pyx_t_6 = (__Pyx_PySequence_ContainsTF(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1, __pyx_v_headers, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 408, __pyx_L1_error) - __pyx_t_7 = (__pyx_t_6 != 0); - if (unlikely(__pyx_t_7)) { + __pyx_t_5 = (__Pyx_PySequence_ContainsTF(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1, __pyx_v_headers, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 408, __pyx_L1_error) + __pyx_t_6 = (__pyx_t_5 != 0); + if (unlikely(__pyx_t_6)) { /* "aiohttp/_http_parser.pyx":409 * # do not support old websocket spec @@ -7769,50 +7847,22 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * * encoding = None */ - __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_InvalidHeader); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 409, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_InvalidHeader); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 409, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = NULL; + __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_5)) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); } } - if (!__pyx_t_5) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 409, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 409, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 409, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - { - __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 409, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5); __pyx_t_5 = NULL; - __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1); - __Pyx_GIVEREF(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1); - PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1); - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 409, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - } + __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 409, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_Raise(__pyx_t_1, 0, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -7856,9 +7906,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * self._content_encoding = None * enc = enc.lower() */ - __pyx_t_7 = (__pyx_v_enc != Py_None); - __pyx_t_6 = (__pyx_t_7 != 0); - if (__pyx_t_6) { + __pyx_t_6 = (__pyx_v_enc != Py_None); + __pyx_t_5 = (__pyx_t_6 != 0); + if (__pyx_t_5) { /* "aiohttp/_http_parser.pyx":414 * enc = self._content_encoding @@ -7892,12 +7942,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple __Pyx_DECREF_SET(__pyx_t_3, function); } } - if (__pyx_t_4) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 415, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else { - __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 415, __pyx_L1_error) - } + __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 415, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF_SET(__pyx_v_enc, __pyx_t_1); @@ -7912,24 +7959,24 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple */ __Pyx_INCREF(__pyx_v_enc); __pyx_t_1 = __pyx_v_enc; - __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_gzip, Py_EQ)); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 416, __pyx_L1_error) - if (!__pyx_t_7) { + __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_gzip, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 416, __pyx_L1_error) + if (!__pyx_t_6) { } else { - __pyx_t_6 = __pyx_t_7; + __pyx_t_5 = __pyx_t_6; goto __pyx_L9_bool_binop_done; } - __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_deflate, Py_EQ)); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 416, __pyx_L1_error) - if (!__pyx_t_7) { + __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_deflate, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 416, __pyx_L1_error) + if (!__pyx_t_6) { } else { - __pyx_t_6 = __pyx_t_7; + __pyx_t_5 = __pyx_t_6; goto __pyx_L9_bool_binop_done; } - __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_br, Py_EQ)); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 416, __pyx_L1_error) - __pyx_t_6 = __pyx_t_7; + __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_br, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 416, __pyx_L1_error) + __pyx_t_5 = __pyx_t_6; __pyx_L9_bool_binop_done:; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_7 = (__pyx_t_6 != 0); - if (__pyx_t_7) { + __pyx_t_6 = (__pyx_t_5 != 0); + if (__pyx_t_6) { /* "aiohttp/_http_parser.pyx":417 * enc = enc.lower() @@ -7966,8 +8013,8 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * msg = _new_request_message( * method, self._path, */ - __pyx_t_7 = ((__pyx_v_self->_cparser->type == HTTP_REQUEST) != 0); - if (__pyx_t_7) { + __pyx_t_6 = ((__pyx_v_self->_cparser->type == HTTP_REQUEST) != 0); + if (__pyx_t_6) { /* "aiohttp/_http_parser.pyx":421 * if self._cparser.type == cparser.HTTP_REQUEST: @@ -8006,13 +8053,13 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * method, self._path, * self.http_version(), headers, raw_headers, */ - __pyx_t_5 = __pyx_f_7aiohttp_12_http_parser__new_request_message(__pyx_v_method, ((PyObject*)__pyx_t_1), __pyx_t_3, __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_encoding, __pyx_v_upgrade, __pyx_v_chunked, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 420, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = __pyx_f_7aiohttp_12_http_parser__new_request_message(__pyx_v_method, ((PyObject*)__pyx_t_1), __pyx_t_3, __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_encoding, __pyx_v_upgrade, __pyx_v_chunked, __pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 420, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_v_msg = __pyx_t_5; - __pyx_t_5 = 0; + __pyx_v_msg = __pyx_t_7; + __pyx_t_7 = 0; /* "aiohttp/_http_parser.pyx":419 * encoding = enc @@ -8040,8 +8087,8 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * headers, raw_headers, should_close, encoding, * upgrade, chunked) */ - __pyx_t_5 = __pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(__pyx_v_self); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 426, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = __pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(__pyx_v_self); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 426, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); __pyx_t_4 = __pyx_v_self->_reason; __Pyx_INCREF(__pyx_t_4); @@ -8052,9 +8099,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * self.http_version(), self._cparser.status_code, self._reason, * headers, raw_headers, should_close, encoding, */ - __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser__new_response_message(__pyx_t_5, __pyx_v_self->_cparser->status_code, ((PyObject*)__pyx_t_4), __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_encoding, __pyx_v_upgrade, __pyx_v_chunked); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 425, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser__new_response_message(__pyx_t_7, __pyx_v_self->_cparser->status_code, ((PyObject*)__pyx_t_4), __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_encoding, __pyx_v_upgrade, __pyx_v_chunked); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 425, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_msg = __pyx_t_3; __pyx_t_3 = 0; @@ -8068,16 +8115,16 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * self._cparser.method == 5): # CONNECT: 5 * payload = StreamReader( */ - __pyx_t_6 = ((__pyx_v_self->_cparser->content_length > 0) != 0); - if (!__pyx_t_6) { + __pyx_t_5 = ((__pyx_v_self->_cparser->content_length > 0) != 0); + if (!__pyx_t_5) { } else { - __pyx_t_7 = __pyx_t_6; + __pyx_t_6 = __pyx_t_5; goto __pyx_L14_bool_binop_done; } - __pyx_t_6 = (__pyx_v_chunked != 0); - if (!__pyx_t_6) { + __pyx_t_5 = (__pyx_v_chunked != 0); + if (!__pyx_t_5) { } else { - __pyx_t_7 = __pyx_t_6; + __pyx_t_6 = __pyx_t_5; goto __pyx_L14_bool_binop_done; } @@ -8088,8 +8135,8 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * payload = StreamReader( * self._protocol, timer=self._timer, loop=self._loop) */ - __pyx_t_6 = ((__pyx_v_self->_cparser->method == 5) != 0); - __pyx_t_7 = __pyx_t_6; + __pyx_t_5 = ((__pyx_v_self->_cparser->method == 5) != 0); + __pyx_t_6 = __pyx_t_5; __pyx_L14_bool_binop_done:; /* "aiohttp/_http_parser.pyx":430 @@ -8099,7 +8146,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * self._cparser.method == 5): # CONNECT: 5 * payload = StreamReader( */ - if (__pyx_t_7) { + if (__pyx_t_6) { /* "aiohttp/_http_parser.pyx":432 * if (self._cparser.content_length > 0 or chunked or @@ -8133,12 +8180,12 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * self._protocol, timer=self._timer, loop=self._loop) * else: */ - __pyx_t_5 = __Pyx_PyObject_Call(__pyx_v_7aiohttp_12_http_parser_StreamReader, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 432, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = __Pyx_PyObject_Call(__pyx_v_7aiohttp_12_http_parser_StreamReader, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 432, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_v_payload = __pyx_t_5; - __pyx_t_5 = 0; + __pyx_v_payload = __pyx_t_7; + __pyx_t_7 = 0; /* "aiohttp/_http_parser.pyx":430 * upgrade, chunked) @@ -8183,17 +8230,17 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * self._payload = DeflateBuffer(payload, encoding) * */ - __pyx_t_6 = (__pyx_v_encoding != Py_None); - __pyx_t_8 = (__pyx_t_6 != 0); + __pyx_t_5 = (__pyx_v_encoding != Py_None); + __pyx_t_8 = (__pyx_t_5 != 0); if (__pyx_t_8) { } else { - __pyx_t_7 = __pyx_t_8; + __pyx_t_6 = __pyx_t_8; goto __pyx_L18_bool_binop_done; } __pyx_t_8 = (__pyx_v_self->_auto_decompress != 0); - __pyx_t_7 = __pyx_t_8; + __pyx_t_6 = __pyx_t_8; __pyx_L18_bool_binop_done:; - if (__pyx_t_7) { + if (__pyx_t_6) { /* "aiohttp/_http_parser.pyx":439 * self._payload = payload @@ -8218,17 +8265,17 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple #if CYTHON_FAST_PYCALL if (PyFunction_Check(__pyx_t_4)) { PyObject *__pyx_temp[3] = {__pyx_t_3, __pyx_v_payload, __pyx_v_encoding}; - __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 439, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 439, __pyx_L1_error) __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GOTREF(__pyx_t_5); + __Pyx_GOTREF(__pyx_t_7); } else #endif #if CYTHON_FAST_PYCCALL if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) { PyObject *__pyx_temp[3] = {__pyx_t_3, __pyx_v_payload, __pyx_v_encoding}; - __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 439, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 439, __pyx_L1_error) __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GOTREF(__pyx_t_5); + __Pyx_GOTREF(__pyx_t_7); } else #endif { @@ -8243,16 +8290,16 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple __Pyx_INCREF(__pyx_v_encoding); __Pyx_GIVEREF(__pyx_v_encoding); PyTuple_SET_ITEM(__pyx_t_1, 1+__pyx_t_9, __pyx_v_encoding); - __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_1, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 439, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_1, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 439, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GIVEREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_7); __Pyx_GOTREF(__pyx_v_self->_payload); __Pyx_DECREF(__pyx_v_self->_payload); - __pyx_v_self->_payload = __pyx_t_5; - __pyx_t_5 = 0; + __pyx_v_self->_payload = __pyx_t_7; + __pyx_t_7 = 0; /* "aiohttp/_http_parser.pyx":438 * @@ -8270,8 +8317,8 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple * payload = EMPTY_PAYLOAD * */ - __pyx_t_7 = ((!(__pyx_v_self->_response_with_body != 0)) != 0); - if (__pyx_t_7) { + __pyx_t_6 = ((!(__pyx_v_self->_response_with_body != 0)) != 0); + if (__pyx_t_6) { /* "aiohttp/_http_parser.pyx":442 * @@ -8303,16 +8350,16 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "append"); __PYX_ERR(0, 444, __pyx_L1_error) } - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 444, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 444, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); __Pyx_INCREF(__pyx_v_msg); __Pyx_GIVEREF(__pyx_v_msg); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_msg); + PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_msg); __Pyx_INCREF(__pyx_v_payload); __Pyx_GIVEREF(__pyx_v_payload); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_payload); - __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_self->_messages, __pyx_t_5); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 444, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_payload); + __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_self->_messages, __pyx_t_7); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 444, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; /* "aiohttp/_http_parser.pyx":393 * self._has_value = True @@ -8329,7 +8376,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_comple __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_7); __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_headers_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; @@ -8380,12 +8427,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_message_comple __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (__pyx_t_3) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 447, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 447, __pyx_L1_error) - } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 447, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -8461,12 +8505,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_header(s __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (__pyx_t_3) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 451, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 451, __pyx_L1_error) - } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 451, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -8529,12 +8570,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_complete __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (__pyx_t_3) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 454, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 454, __pyx_L1_error) - } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 454, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -8655,14 +8693,6 @@ static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser_http * elif parser.http_minor == 1: */ break; - - /* "aiohttp/_http_parser.pyx":465 - * if parser.http_minor == 0: - * return HttpVersion10 - * elif parser.http_minor == 1: # <<<<<<<<<<<<<< - * return HttpVersion11 - * - */ case 1: /* "aiohttp/_http_parser.pyx":466 @@ -8818,7 +8848,6 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(struct PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; __Pyx_RefNannySetupContext("feed_eof", 0); /* "aiohttp/_http_parser.pyx":475 @@ -8849,13 +8878,25 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(struct * "Not enough data for satisfy transfer length header.") * elif self._cparser.flags & cparser.F_CONTENTLENGTH: */ - __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_TransferEncodingError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 477, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 477, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_TransferEncodingError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 477, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_4, 0, 0, 0); + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Not_enough_data_for_satisfy_tran) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Not_enough_data_for_satisfy_tran); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 477, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(0, 477, __pyx_L1_error) /* "aiohttp/_http_parser.pyx":476 @@ -8884,9 +8925,21 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(struct * "Not enough data for satisfy content length header.") * elif self._cparser.http_errno != cparser.HPE_OK: */ - __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_ContentLengthError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 480, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_ContentLengthError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 480, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 480, __pyx_L1_error) + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Not_enough_data_for_satisfy_cont) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Not_enough_data_for_satisfy_cont); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 480, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_Raise(__pyx_t_3, 0, 0, 0); @@ -8931,7 +8984,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(struct * else: * self._payload.feed_eof() */ - __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_PayloadEncodingError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 485, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_PayloadEncodingError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 485, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = __Pyx_decode_bytes(__pyx_v_desc, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeLatin1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 485, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -8945,41 +8998,11 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(struct __Pyx_DECREF_SET(__pyx_t_4, function); } } - if (!__pyx_t_6) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 485, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 485, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 485, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } else - #endif - { - __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 485, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL; - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5); - __pyx_t_5 = 0; - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 485, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } - } + __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 485, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; @@ -9004,22 +9027,19 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(struct /*else*/ { __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_payload, __pyx_n_s_feed_eof); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 487, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = NULL; + __pyx_t_5 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_7)) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(__pyx_t_5); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_4, function); } } - if (__pyx_t_7) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 487, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } else { - __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 487, __pyx_L1_error) - } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 487, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; @@ -9122,7 +9142,6 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(struct __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.feed_eof", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -9492,9 +9511,9 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_6feed_data(struct __Pyx_INCREF(Py_False); __Pyx_GIVEREF(Py_False); PyTuple_SET_ITEM(__pyx_t_5, 1, Py_False); - __Pyx_INCREF(__pyx_kp_b__6); - __Pyx_GIVEREF(__pyx_kp_b__6); - PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_b__6); + __Pyx_INCREF(__pyx_kp_b__4); + __Pyx_GIVEREF(__pyx_kp_b__4); + PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_b__4); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; @@ -9553,7 +9572,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_8__reduce_cython_ * def __setstate_cython__(self, __pyx_state): * raise TypeError("no default __reduce__ due to non-trivial __cinit__") */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_Raise(__pyx_t_1, 0, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -9606,7 +9625,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_10__setstate_cyth * def __setstate_cython__(self, __pyx_state): * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_Raise(__pyx_t_1, 0, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -9892,16 +9911,15 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_ PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; + int __pyx_t_6; int __pyx_t_7; - int __pyx_t_8; - char const *__pyx_t_9; + char const *__pyx_t_8; + PyObject *__pyx_t_9 = NULL; PyObject *__pyx_t_10 = NULL; PyObject *__pyx_t_11 = NULL; PyObject *__pyx_t_12 = NULL; PyObject *__pyx_t_13 = NULL; PyObject *__pyx_t_14 = NULL; - PyObject *__pyx_t_15 = NULL; __Pyx_RefNannySetupContext("_on_status_complete", 0); /* "aiohttp/_http_parser.pyx":549 @@ -9982,38 +10000,10 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_ __Pyx_DECREF_SET(__pyx_t_4, function); } } - if (!__pyx_t_5) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_self->__pyx_base._path); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 553, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_self->__pyx_base._path}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 553, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_self->__pyx_base._path}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 553, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - { - __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 553, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL; - __Pyx_INCREF(__pyx_v_self->__pyx_base._path); - __Pyx_GIVEREF(__pyx_v_self->__pyx_base._path); - PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_self->__pyx_base._path); - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 553, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_v_self->__pyx_base._path) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_self->__pyx_base._path); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 553, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_GIVEREF(__pyx_t_3); __Pyx_GOTREF(__pyx_v_self->__pyx_base._url); @@ -10041,7 +10031,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_ /*else*/ { __pyx_t_3 = __pyx_v_self->__pyx_base._buf; __Pyx_INCREF(__pyx_t_3); - __pyx_t_7 = PyObject_GetBuffer(__pyx_t_3, (&__pyx_v_py_buf), PyBUF_SIMPLE); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(0, 555, __pyx_L1_error) + __pyx_t_6 = PyObject_GetBuffer(__pyx_t_3, (&__pyx_v_py_buf), PyBUF_SIMPLE); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(0, 555, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_http_parser.pyx":556 @@ -10085,35 +10075,34 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_ /*exception exit:*/{ __Pyx_PyThreadState_declare __Pyx_PyThreadState_assign - __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; + __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12) < 0)) __Pyx_ErrFetch(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12); + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11) < 0)) __Pyx_ErrFetch(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11); + __Pyx_XGOTREF(__pyx_t_9); __Pyx_XGOTREF(__pyx_t_10); __Pyx_XGOTREF(__pyx_t_11); __Pyx_XGOTREF(__pyx_t_12); __Pyx_XGOTREF(__pyx_t_13); __Pyx_XGOTREF(__pyx_t_14); - __Pyx_XGOTREF(__pyx_t_15); - __pyx_t_7 = __pyx_lineno; __pyx_t_8 = __pyx_clineno; __pyx_t_9 = __pyx_filename; + __pyx_t_6 = __pyx_lineno; __pyx_t_7 = __pyx_clineno; __pyx_t_8 = __pyx_filename; { PyBuffer_Release((&__pyx_v_py_buf)); } if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_12); __Pyx_XGIVEREF(__pyx_t_13); __Pyx_XGIVEREF(__pyx_t_14); - __Pyx_XGIVEREF(__pyx_t_15); - __Pyx_ExceptionReset(__pyx_t_13, __pyx_t_14, __pyx_t_15); + __Pyx_ExceptionReset(__pyx_t_12, __pyx_t_13, __pyx_t_14); } + __Pyx_XGIVEREF(__pyx_t_9); __Pyx_XGIVEREF(__pyx_t_10); __Pyx_XGIVEREF(__pyx_t_11); - __Pyx_XGIVEREF(__pyx_t_12); - __Pyx_ErrRestore(__pyx_t_10, __pyx_t_11, __pyx_t_12); - __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; - __pyx_lineno = __pyx_t_7; __pyx_clineno = __pyx_t_8; __pyx_filename = __pyx_t_9; + __Pyx_ErrRestore(__pyx_t_9, __pyx_t_10, __pyx_t_11); + __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; + __pyx_lineno = __pyx_t_6; __pyx_clineno = __pyx_t_7; __pyx_filename = __pyx_t_8; goto __pyx_L1_error; } __pyx_L7:; @@ -10130,7 +10119,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_ */ __pyx_t_3 = __pyx_v_self->__pyx_base._buf; __Pyx_INCREF(__pyx_t_3); - __pyx_t_8 = PyByteArray_Resize(__pyx_t_3, 0); if (unlikely(__pyx_t_8 == ((int)-1))) __PYX_ERR(0, 561, __pyx_L1_error) + __pyx_t_7 = PyByteArray_Resize(__pyx_t_3, 0); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(0, 561, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_http_parser.pyx":547 @@ -10148,7 +10137,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_ __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser._on_status_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; @@ -10188,7 +10176,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser_2__reduce_ * def __setstate_cython__(self, __pyx_state): * raise TypeError("no default __reduce__ due to non-trivial __cinit__") */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_Raise(__pyx_t_1, 0, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -10241,7 +10229,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser_4__setstat * def __setstate_cython__(self, __pyx_state): * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_Raise(__pyx_t_1, 0, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -10653,7 +10641,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser_2__reduce * def __setstate_cython__(self, __pyx_state): * raise TypeError("no default __reduce__ due to non-trivial __cinit__") */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_Raise(__pyx_t_1, 0, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -10706,7 +10694,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser_4__setsta * def __setstate_cython__(self, __pyx_state): * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_Raise(__pyx_t_1, 0, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -10786,12 +10774,9 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_message_begin(struct http_parse __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (__pyx_t_3) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 585, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 585, __pyx_L1_error) - } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 585, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_GIVEREF(__pyx_t_1); @@ -10955,7 +10940,7 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_url(struct http_parser *__pyx_v * 'Status line is too long', pyparser._max_line_size, length) * extend(pyparser._buf, at, length) */ - __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 598, __pyx_L3_error) + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 598, __pyx_L3_error) __Pyx_GOTREF(__pyx_t_6); /* "aiohttp/_http_parser.pyx":599 @@ -11257,7 +11242,7 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_status(struct http_parser *__py * 'Status line is too long', pyparser._max_line_size, length) * extend(pyparser._buf, at, length) */ - __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 614, __pyx_L3_error) + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 614, __pyx_L3_error) __Pyx_GOTREF(__pyx_t_6); /* "aiohttp/_http_parser.pyx":615 @@ -11589,7 +11574,7 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_header_field(struct http_parser * 'Header name is too long', pyparser._max_field_size, size) * pyparser._on_header_field(at, length) */ - __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 632, __pyx_L3_error) + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 632, __pyx_L3_error) __Pyx_GOTREF(__pyx_t_7); /* "aiohttp/_http_parser.pyx":633 @@ -11907,7 +11892,7 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_header_value(struct http_parser * 'Header value is too long', pyparser._max_field_size, size) * pyparser._on_header_value(at, length) */ - __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 649, __pyx_L3_error) + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 649, __pyx_L3_error) __Pyx_GOTREF(__pyx_t_7); /* "aiohttp/_http_parser.pyx":650 @@ -12407,15 +12392,14 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_body(struct http_parser *__pyx_ PyObject *__pyx_t_13 = NULL; PyObject *__pyx_t_14 = NULL; PyObject *__pyx_t_15 = NULL; - PyObject *__pyx_t_16 = NULL; - int __pyx_t_17; - char const *__pyx_t_18; + int __pyx_t_16; + char const *__pyx_t_17; + PyObject *__pyx_t_18 = NULL; PyObject *__pyx_t_19 = NULL; PyObject *__pyx_t_20 = NULL; PyObject *__pyx_t_21 = NULL; PyObject *__pyx_t_22 = NULL; PyObject *__pyx_t_23 = NULL; - PyObject *__pyx_t_24 = NULL; __Pyx_RefNannySetupContext("cb_on_body", 0); /* "aiohttp/_http_parser.pyx":676 @@ -12596,41 +12580,11 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_body(struct http_parser *__pyx_ __Pyx_DECREF_SET(__pyx_t_14, function); } } - if (!__pyx_t_15) { - __pyx_t_12 = __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_t_13); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 682, __pyx_L14_error) - __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - __Pyx_GOTREF(__pyx_t_12); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_14)) { - PyObject *__pyx_temp[2] = {__pyx_t_15, __pyx_t_13}; - __pyx_t_12 = __Pyx_PyFunction_FastCall(__pyx_t_14, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 682, __pyx_L14_error) - __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; - __Pyx_GOTREF(__pyx_t_12); - __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_14)) { - PyObject *__pyx_temp[2] = {__pyx_t_15, __pyx_t_13}; - __pyx_t_12 = __Pyx_PyCFunction_FastCall(__pyx_t_14, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 682, __pyx_L14_error) - __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; - __Pyx_GOTREF(__pyx_t_12); - __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - } else - #endif - { - __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 682, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_16); - __Pyx_GIVEREF(__pyx_t_15); PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_15); __pyx_t_15 = NULL; - __Pyx_GIVEREF(__pyx_t_13); - PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_13); - __pyx_t_13 = 0; - __pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_14, __pyx_t_16, NULL); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 682, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_12); - __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0; - } - } + __pyx_t_12 = (__pyx_t_15) ? __Pyx_PyObject_Call2Args(__pyx_t_14, __pyx_t_15, __pyx_t_13) : __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_t_13); + __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 682, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_12); __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; __pyx_t_14 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { @@ -12642,41 +12596,11 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_body(struct http_parser *__pyx_ __Pyx_DECREF_SET(__pyx_t_7, function); } } - if (!__pyx_t_14) { - __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_12); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 682, __pyx_L14_error) - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - __Pyx_GOTREF(__pyx_t_6); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[2] = {__pyx_t_14, __pyx_t_12}; - __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 682, __pyx_L14_error) - __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[2] = {__pyx_t_14, __pyx_t_12}; - __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 682, __pyx_L14_error) - __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - } else - #endif - { - __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 682, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_16); - __Pyx_GIVEREF(__pyx_t_14); PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_14); __pyx_t_14 = NULL; - __Pyx_GIVEREF(__pyx_t_12); - PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_12); - __pyx_t_12 = 0; - __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_16, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 682, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0; - } - } + __pyx_t_6 = (__pyx_t_14) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_14, __pyx_t_12) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_12); + __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 682, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; @@ -12700,48 +12624,20 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_body(struct http_parser *__pyx_ /*else*/ { __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_pyparser->_payload, __pyx_n_s_set_exception); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 684, __pyx_L14_error) __Pyx_GOTREF(__pyx_t_7); - __pyx_t_16 = NULL; + __pyx_t_12 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_16)) { + __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_12)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_16); + __Pyx_INCREF(__pyx_t_12); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_7, function); } } - if (!__pyx_t_16) { - __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_exc); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 684, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_6); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[2] = {__pyx_t_16, __pyx_v_exc}; - __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 684, __pyx_L14_error) - __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; - __Pyx_GOTREF(__pyx_t_6); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[2] = {__pyx_t_16, __pyx_v_exc}; - __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 684, __pyx_L14_error) - __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; - __Pyx_GOTREF(__pyx_t_6); - } else - #endif - { - __pyx_t_12 = PyTuple_New(1+1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 684, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_12); - __Pyx_GIVEREF(__pyx_t_16); PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_16); __pyx_t_16 = NULL; - __Pyx_INCREF(__pyx_v_exc); - __Pyx_GIVEREF(__pyx_v_exc); - PyTuple_SET_ITEM(__pyx_t_12, 0+1, __pyx_v_exc); - __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_12, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 684, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - } - } + __pyx_t_6 = (__pyx_t_12) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_12, __pyx_v_exc) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_exc); + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 684, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } @@ -12782,46 +12678,45 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_body(struct http_parser *__pyx_ /*exception exit:*/{ __Pyx_PyThreadState_declare __Pyx_PyThreadState_assign - __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; + __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; - __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_22, &__pyx_t_23, &__pyx_t_24); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_19, &__pyx_t_20, &__pyx_t_21) < 0)) __Pyx_ErrFetch(&__pyx_t_19, &__pyx_t_20, &__pyx_t_21); + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_21, &__pyx_t_22, &__pyx_t_23); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20) < 0)) __Pyx_ErrFetch(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20); + __Pyx_XGOTREF(__pyx_t_18); __Pyx_XGOTREF(__pyx_t_19); __Pyx_XGOTREF(__pyx_t_20); __Pyx_XGOTREF(__pyx_t_21); __Pyx_XGOTREF(__pyx_t_22); __Pyx_XGOTREF(__pyx_t_23); - __Pyx_XGOTREF(__pyx_t_24); - __pyx_t_8 = __pyx_lineno; __pyx_t_17 = __pyx_clineno; __pyx_t_18 = __pyx_filename; + __pyx_t_8 = __pyx_lineno; __pyx_t_16 = __pyx_clineno; __pyx_t_17 = __pyx_filename; { __Pyx_DECREF(__pyx_v_exc); __pyx_v_exc = NULL; } if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_21); __Pyx_XGIVEREF(__pyx_t_22); __Pyx_XGIVEREF(__pyx_t_23); - __Pyx_XGIVEREF(__pyx_t_24); - __Pyx_ExceptionReset(__pyx_t_22, __pyx_t_23, __pyx_t_24); + __Pyx_ExceptionReset(__pyx_t_21, __pyx_t_22, __pyx_t_23); } + __Pyx_XGIVEREF(__pyx_t_18); __Pyx_XGIVEREF(__pyx_t_19); __Pyx_XGIVEREF(__pyx_t_20); - __Pyx_XGIVEREF(__pyx_t_21); - __Pyx_ErrRestore(__pyx_t_19, __pyx_t_20, __pyx_t_21); - __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; - __pyx_lineno = __pyx_t_8; __pyx_clineno = __pyx_t_17; __pyx_filename = __pyx_t_18; + __Pyx_ErrRestore(__pyx_t_18, __pyx_t_19, __pyx_t_20); + __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; + __pyx_lineno = __pyx_t_8; __pyx_clineno = __pyx_t_16; __pyx_filename = __pyx_t_17; goto __pyx_L5_except_error; } __pyx_L13_return: { - __pyx_t_17 = __pyx_r; + __pyx_t_16 = __pyx_r; __Pyx_DECREF(__pyx_v_exc); __pyx_v_exc = NULL; - __pyx_r = __pyx_t_17; + __pyx_r = __pyx_t_16; goto __pyx_L6_except_return; } } @@ -12868,7 +12763,6 @@ static int __pyx_f_7aiohttp_12_http_parser_cb_on_body(struct http_parser *__pyx_ __Pyx_XDECREF(__pyx_t_13); __Pyx_XDECREF(__pyx_t_14); __Pyx_XDECREF(__pyx_t_15); - __Pyx_XDECREF(__pyx_t_16); __Pyx_AddTraceback("aiohttp._http_parser.cb_on_body", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; @@ -13478,7 +13372,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; __Pyx_RefNannySetupContext("parser_error_from_errno", 0); /* "aiohttp/_http_parser.pyx":726 @@ -13502,6 +13395,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht */ switch (__pyx_v_errno) { case HPE_CB_message_begin: + case HPE_CB_url: /* "aiohttp/_http_parser.pyx":729 * @@ -13510,7 +13404,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * cparser.HPE_CB_header_field, * cparser.HPE_CB_header_value, */ - case HPE_CB_url: + case HPE_CB_header_field: /* "aiohttp/_http_parser.pyx":730 * if errno in (cparser.HPE_CB_message_begin, @@ -13519,7 +13413,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * cparser.HPE_CB_header_value, * cparser.HPE_CB_headers_complete, */ - case HPE_CB_header_field: + case HPE_CB_header_value: /* "aiohttp/_http_parser.pyx":731 * cparser.HPE_CB_url, @@ -13528,7 +13422,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * cparser.HPE_CB_headers_complete, * cparser.HPE_CB_body, */ - case HPE_CB_header_value: + case HPE_CB_headers_complete: /* "aiohttp/_http_parser.pyx":732 * cparser.HPE_CB_header_field, @@ -13537,7 +13431,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * cparser.HPE_CB_body, * cparser.HPE_CB_message_complete, */ - case HPE_CB_headers_complete: + case HPE_CB_body: /* "aiohttp/_http_parser.pyx":733 * cparser.HPE_CB_header_value, @@ -13546,7 +13440,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * cparser.HPE_CB_message_complete, * cparser.HPE_CB_status, */ - case HPE_CB_body: + case HPE_CB_message_complete: /* "aiohttp/_http_parser.pyx":734 * cparser.HPE_CB_headers_complete, @@ -13555,7 +13449,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * cparser.HPE_CB_status, * cparser.HPE_CB_chunk_header, */ - case HPE_CB_message_complete: + case HPE_CB_status: /* "aiohttp/_http_parser.pyx":735 * cparser.HPE_CB_body, @@ -13564,7 +13458,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * cparser.HPE_CB_chunk_header, * cparser.HPE_CB_chunk_complete): */ - case HPE_CB_status: + case HPE_CB_chunk_header: /* "aiohttp/_http_parser.pyx":736 * cparser.HPE_CB_message_complete, @@ -13573,15 +13467,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * cparser.HPE_CB_chunk_complete): * cls = BadHttpMessage */ - case HPE_CB_chunk_header: - - /* "aiohttp/_http_parser.pyx":737 - * cparser.HPE_CB_status, - * cparser.HPE_CB_chunk_header, - * cparser.HPE_CB_chunk_complete): # <<<<<<<<<<<<<< - * cls = BadHttpMessage - * - */ case HPE_CB_chunk_complete: /* "aiohttp/_http_parser.pyx":738 @@ -13591,7 +13476,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * * elif errno == cparser.HPE_INVALID_STATUS: */ - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_BadHttpMessage); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 738, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadHttpMessage); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 738, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v_cls = __pyx_t_1; __pyx_t_1 = 0; @@ -13604,14 +13489,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * cparser.HPE_CB_header_field, */ break; - - /* "aiohttp/_http_parser.pyx":740 - * cls = BadHttpMessage - * - * elif errno == cparser.HPE_INVALID_STATUS: # <<<<<<<<<<<<<< - * cls = BadStatusLine - * - */ case HPE_INVALID_STATUS: /* "aiohttp/_http_parser.pyx":741 @@ -13621,7 +13498,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * * elif errno == cparser.HPE_INVALID_METHOD: */ - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_BadStatusLine); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 741, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadStatusLine); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 741, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v_cls = __pyx_t_1; __pyx_t_1 = 0; @@ -13634,14 +13511,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * */ break; - - /* "aiohttp/_http_parser.pyx":743 - * cls = BadStatusLine - * - * elif errno == cparser.HPE_INVALID_METHOD: # <<<<<<<<<<<<<< - * cls = BadStatusLine - * - */ case HPE_INVALID_METHOD: /* "aiohttp/_http_parser.pyx":744 @@ -13651,7 +13520,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * * elif errno == cparser.HPE_INVALID_URL: */ - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_BadStatusLine); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 744, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadStatusLine); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 744, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v_cls = __pyx_t_1; __pyx_t_1 = 0; @@ -13664,14 +13533,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * */ break; - - /* "aiohttp/_http_parser.pyx":746 - * cls = BadStatusLine - * - * elif errno == cparser.HPE_INVALID_URL: # <<<<<<<<<<<<<< - * cls = InvalidURLError - * - */ case HPE_INVALID_URL: /* "aiohttp/_http_parser.pyx":747 @@ -13681,7 +13542,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * * else: */ - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_InvalidURLError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 747, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_InvalidURLError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 747, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v_cls = __pyx_t_1; __pyx_t_1 = 0; @@ -13703,7 +13564,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht * * return cls(desc.decode('latin-1')) */ - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_BadHttpMessage); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 750, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadHttpMessage); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 750, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v_cls = __pyx_t_1; __pyx_t_1 = 0; @@ -13731,41 +13592,11 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht __Pyx_DECREF_SET(__pyx_t_3, function); } } - if (!__pyx_t_4) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 752, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_2}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 752, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_2}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 752, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } else - #endif - { - __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 752, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL; - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_2); - __pyx_t_2 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 752, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - } + __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 752, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; @@ -13785,7 +13616,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum ht __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("aiohttp._http_parser.parser_error_from_errno", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; @@ -13981,16 +13811,15 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da PyObject *__pyx_t_7 = NULL; PyObject *(*__pyx_t_8)(PyObject *); PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; + int __pyx_t_10; int __pyx_t_11; - int __pyx_t_12; - char const *__pyx_t_13; + char const *__pyx_t_12; + PyObject *__pyx_t_13 = NULL; PyObject *__pyx_t_14 = NULL; PyObject *__pyx_t_15 = NULL; PyObject *__pyx_t_16 = NULL; PyObject *__pyx_t_17 = NULL; PyObject *__pyx_t_18 = NULL; - PyObject *__pyx_t_19 = NULL; __Pyx_RefNannySetupContext("_parse_url", 0); /* "aiohttp/_http_parser.pyx":772 @@ -14227,8 +14056,8 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da * if parsed.field_set & (1 << cparser.UF_HOST): */ /*else*/ { - __Pyx_INCREF(__pyx_kp_u__6); - __Pyx_DECREF_SET(__pyx_v_schema, __pyx_kp_u__6); + __Pyx_INCREF(__pyx_kp_u__4); + __Pyx_DECREF_SET(__pyx_v_schema, __pyx_kp_u__4); } __pyx_L8:; @@ -14292,8 +14121,8 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da * if parsed.field_set & (1 << cparser.UF_PORT): */ /*else*/ { - __Pyx_INCREF(__pyx_kp_u__6); - __Pyx_DECREF_SET(__pyx_v_host, __pyx_kp_u__6); + __Pyx_INCREF(__pyx_kp_u__4); + __Pyx_DECREF_SET(__pyx_v_host, __pyx_kp_u__4); } __pyx_L9:; @@ -14388,8 +14217,8 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da * if parsed.field_set & (1 << cparser.UF_QUERY): */ /*else*/ { - __Pyx_INCREF(__pyx_kp_u__6); - __Pyx_DECREF_SET(__pyx_v_path, __pyx_kp_u__6); + __Pyx_INCREF(__pyx_kp_u__4); + __Pyx_DECREF_SET(__pyx_v_path, __pyx_kp_u__4); } __pyx_L11:; @@ -14453,8 +14282,8 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da * if parsed.field_set & (1 << cparser.UF_FRAGMENT): */ /*else*/ { - __Pyx_INCREF(__pyx_kp_u__6); - __Pyx_DECREF_SET(__pyx_v_query, __pyx_kp_u__6); + __Pyx_INCREF(__pyx_kp_u__4); + __Pyx_DECREF_SET(__pyx_v_query, __pyx_kp_u__4); } __pyx_L12:; @@ -14518,8 +14347,8 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da * if parsed.field_set & (1 << cparser.UF_USERINFO): */ /*else*/ { - __Pyx_INCREF(__pyx_kp_u__6); - __Pyx_DECREF_SET(__pyx_v_fragment, __pyx_kp_u__6); + __Pyx_INCREF(__pyx_kp_u__4); + __Pyx_DECREF_SET(__pyx_v_fragment, __pyx_kp_u__4); } __pyx_L13:; @@ -14572,7 +14401,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da * * return URL_build(scheme=schema, */ - __pyx_t_3 = __Pyx_CallUnboundCMethod1(&__pyx_umethod_PyUnicode_Type_partition, __pyx_v_userinfo, __pyx_kp_u__13); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 837, __pyx_L5_error) + __pyx_t_3 = __Pyx_CallUnboundCMethod1(&__pyx_umethod_PyUnicode_Type_partition, __pyx_v_userinfo, __pyx_kp_u__11); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 837, __pyx_L5_error) __Pyx_GOTREF(__pyx_t_3); if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { PyObject* sequence = __pyx_t_3; @@ -14711,7 +14540,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da * PyMem_Free(parsed) */ /*else*/ { - __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_InvalidURLError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 843, __pyx_L5_error) + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_InvalidURLError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 843, __pyx_L5_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_invalid_url_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 843, __pyx_L5_error) __Pyx_GOTREF(__pyx_t_4); @@ -14727,41 +14556,11 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da __Pyx_DECREF_SET(__pyx_t_4, function); } } - if (!__pyx_t_9) { - __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 843, __pyx_L5_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_GOTREF(__pyx_t_5); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[2] = {__pyx_t_9, __pyx_t_7}; - __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 843, __pyx_L5_error) - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[2] = {__pyx_t_9, __pyx_t_7}; - __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 843, __pyx_L5_error) - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } else - #endif - { - __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 843, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9); __pyx_t_9 = NULL; - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_7); - __pyx_t_7 = 0; - __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_10, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 843, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - } - } + __pyx_t_5 = (__pyx_t_9) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_9, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 843, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { @@ -14773,41 +14572,11 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da __Pyx_DECREF_SET(__pyx_t_3, function); } } - if (!__pyx_t_4) { - __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 843, __pyx_L5_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_6); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5}; - __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 843, __pyx_L5_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5}; - __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 843, __pyx_L5_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } else - #endif - { - __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 843, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_4); __pyx_t_4 = NULL; - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_5); - __pyx_t_5 = 0; - __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_10, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 843, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - } - } + __pyx_t_6 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 843, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_Raise(__pyx_t_6, 0, 0, 0); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; @@ -14825,46 +14594,45 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da /*exception exit:*/{ __Pyx_PyThreadState_declare __Pyx_PyThreadState_assign - __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; __pyx_t_19 = 0; + __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_17, &__pyx_t_18, &__pyx_t_19); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_14, &__pyx_t_15, &__pyx_t_16) < 0)) __Pyx_ErrFetch(&__pyx_t_14, &__pyx_t_15, &__pyx_t_16); + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_16, &__pyx_t_17, &__pyx_t_18); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15) < 0)) __Pyx_ErrFetch(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15); + __Pyx_XGOTREF(__pyx_t_13); __Pyx_XGOTREF(__pyx_t_14); __Pyx_XGOTREF(__pyx_t_15); __Pyx_XGOTREF(__pyx_t_16); __Pyx_XGOTREF(__pyx_t_17); __Pyx_XGOTREF(__pyx_t_18); - __Pyx_XGOTREF(__pyx_t_19); - __pyx_t_11 = __pyx_lineno; __pyx_t_12 = __pyx_clineno; __pyx_t_13 = __pyx_filename; + __pyx_t_10 = __pyx_lineno; __pyx_t_11 = __pyx_clineno; __pyx_t_12 = __pyx_filename; { PyMem_Free(__pyx_v_parsed); } if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_16); __Pyx_XGIVEREF(__pyx_t_17); __Pyx_XGIVEREF(__pyx_t_18); - __Pyx_XGIVEREF(__pyx_t_19); - __Pyx_ExceptionReset(__pyx_t_17, __pyx_t_18, __pyx_t_19); + __Pyx_ExceptionReset(__pyx_t_16, __pyx_t_17, __pyx_t_18); } + __Pyx_XGIVEREF(__pyx_t_13); __Pyx_XGIVEREF(__pyx_t_14); __Pyx_XGIVEREF(__pyx_t_15); - __Pyx_XGIVEREF(__pyx_t_16); - __Pyx_ErrRestore(__pyx_t_14, __pyx_t_15, __pyx_t_16); - __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; __pyx_t_19 = 0; - __pyx_lineno = __pyx_t_11; __pyx_clineno = __pyx_t_12; __pyx_filename = __pyx_t_13; + __Pyx_ErrRestore(__pyx_t_13, __pyx_t_14, __pyx_t_15); + __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; + __pyx_lineno = __pyx_t_10; __pyx_clineno = __pyx_t_11; __pyx_filename = __pyx_t_12; goto __pyx_L1_error; } __pyx_L4_return: { - __pyx_t_19 = __pyx_r; + __pyx_t_18 = __pyx_r; __pyx_r = 0; PyMem_Free(__pyx_v_parsed); - __pyx_r = __pyx_t_19; - __pyx_t_19 = 0; + __pyx_r = __pyx_t_18; + __pyx_t_18 = 0; goto __pyx_L0; } } @@ -14885,7 +14653,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_10); __Pyx_AddTraceback("aiohttp._http_parser._parse_url", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; @@ -14907,13 +14674,13 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_da /* "(tree fragment)":1 * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x1408252: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage = {"__pyx_unpickle_RawRequestMessage", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage, METH_VARARGS|METH_KEYWORDS, 0}; +static PyMethodDef __pyx_mdef_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage = {"__pyx_unpickle_RawRequestMessage", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage, METH_VARARGS|METH_KEYWORDS, 0}; static PyObject *__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v___pyx_type = 0; long __pyx_v___pyx_checksum; @@ -14985,8 +14752,8 @@ static PyObject *__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMess } static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMessage(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = NULL; - PyObject *__pyx_v___pyx_result = NULL; + PyObject *__pyx_v___pyx_PickleError = 0; + PyObject *__pyx_v___pyx_result = 0; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; @@ -14994,12 +14761,12 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMess PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; + int __pyx_t_6; __Pyx_RefNannySetupContext("__pyx_unpickle_RawRequestMessage", 0); - /* "(tree fragment)":2 - * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result * if __pyx_checksum != 0x1408252: # <<<<<<<<<<<<<< * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) @@ -15007,38 +14774,38 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMess __pyx_t_1 = ((__pyx_v___pyx_checksum != 0x1408252) != 0); if (__pyx_t_1) { - /* "(tree fragment)":3 - * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":5 + * cdef object __pyx_result * if __pyx_checksum != 0x1408252: * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) * __pyx_result = RawRequestMessage.__new__(__pyx_type) */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_n_s_PickleError); __Pyx_GIVEREF(__pyx_n_s_PickleError); PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_t_2); __pyx_v___pyx_PickleError = __pyx_t_2; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "(tree fragment)":4 + /* "(tree fragment)":6 * if __pyx_checksum != 0x1408252: * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) # <<<<<<<<<<<<<< * __pyx_result = RawRequestMessage.__new__(__pyx_type) * if __pyx_state is not None: */ - __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x14, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x14, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_INCREF(__pyx_v___pyx_PickleError); @@ -15052,110 +14819,53 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMess __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_5) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else - #endif - { - __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL; - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_4); - __pyx_t_4 = 0; - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 4, __pyx_L1_error) + __PYX_ERR(1, 6, __pyx_L1_error) - /* "(tree fragment)":2 - * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result * if __pyx_checksum != 0x1408252: # <<<<<<<<<<<<<< * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) */ } - /* "(tree fragment)":5 + /* "(tree fragment)":7 * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) * __pyx_result = RawRequestMessage.__new__(__pyx_type) # <<<<<<<<<<<<<< * if __pyx_state is not None: * __pyx_unpickle_RawRequestMessage__set_state(<RawRequestMessage> __pyx_result, __pyx_state) */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_6 = NULL; + __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_6)) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_6) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v___pyx_type}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v___pyx_type}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - { - __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); __pyx_t_6 = NULL; - __Pyx_INCREF(__pyx_v___pyx_type); - __Pyx_GIVEREF(__pyx_v___pyx_type); - PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v___pyx_type); - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - } + __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v___pyx_result = __pyx_t_3; __pyx_t_3 = 0; - /* "(tree fragment)":6 + /* "(tree fragment)":8 * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) * __pyx_result = RawRequestMessage.__new__(__pyx_type) * if __pyx_state is not None: # <<<<<<<<<<<<<< @@ -15163,22 +14873,22 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMess * return __pyx_result */ __pyx_t_1 = (__pyx_v___pyx_state != Py_None); - __pyx_t_7 = (__pyx_t_1 != 0); - if (__pyx_t_7) { + __pyx_t_6 = (__pyx_t_1 != 0); + if (__pyx_t_6) { - /* "(tree fragment)":7 + /* "(tree fragment)":9 * __pyx_result = RawRequestMessage.__new__(__pyx_type) * if __pyx_state is not None: * __pyx_unpickle_RawRequestMessage__set_state(<RawRequestMessage> __pyx_result, __pyx_state) # <<<<<<<<<<<<<< * return __pyx_result * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 7, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "(tree fragment)":6 + /* "(tree fragment)":8 * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) * __pyx_result = RawRequestMessage.__new__(__pyx_type) * if __pyx_state is not None: # <<<<<<<<<<<<<< @@ -15187,7 +14897,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMess */ } - /* "(tree fragment)":8 + /* "(tree fragment)":10 * if __pyx_state is not None: * __pyx_unpickle_RawRequestMessage__set_state(<RawRequestMessage> __pyx_result, __pyx_state) * return __pyx_result # <<<<<<<<<<<<<< @@ -15201,8 +14911,8 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMess /* "(tree fragment)":1 * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x1408252: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ /* function exit code */ @@ -15211,7 +14921,6 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMess __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawRequestMessage", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -15222,7 +14931,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMess return __pyx_r; } -/* "(tree fragment)":9 +/* "(tree fragment)":11 * __pyx_unpickle_RawRequestMessage__set_state(<RawRequestMessage> __pyx_result, __pyx_state) * return __pyx_result * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< @@ -15241,10 +14950,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; __Pyx_RefNannySetupContext("__pyx_unpickle_RawRequestMessage__set_state", 0); - /* "(tree fragment)":10 + /* "(tree fragment)":12 * return __pyx_result * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] # <<<<<<<<<<<<<< @@ -15253,9 +14961,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag */ if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->chunked); @@ -15264,9 +14972,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->compression); @@ -15275,9 +14983,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->headers); @@ -15286,11 +14994,11 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 10, __pyx_L1_error) + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->method); __Pyx_DECREF(__pyx_v___pyx_result->method); @@ -15298,11 +15006,11 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 4, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 4, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 10, __pyx_L1_error) + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->path); __Pyx_DECREF(__pyx_v___pyx_result->path); @@ -15310,9 +15018,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 5, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 5, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->raw_headers); @@ -15321,9 +15029,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 6, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 6, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->should_close); @@ -15332,9 +15040,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 7, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 7, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->upgrade); @@ -15343,9 +15051,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 8, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 8, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->url); @@ -15354,9 +15062,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 9, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 9, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->version); @@ -15364,7 +15072,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __pyx_v___pyx_result->version = __pyx_t_1; __pyx_t_1 = 0; - /* "(tree fragment)":11 + /* "(tree fragment)":13 * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< @@ -15372,36 +15080,36 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag */ if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 11, __pyx_L1_error) + __PYX_ERR(1, 13, __pyx_L1_error) } - __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) __pyx_t_4 = ((__pyx_t_3 > 10) != 0); if (__pyx_t_4) { } else { __pyx_t_2 = __pyx_t_4; goto __pyx_L4_bool_binop_done; } - __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) __pyx_t_5 = (__pyx_t_4 != 0); __pyx_t_2 = __pyx_t_5; __pyx_L4_bool_binop_done:; if (__pyx_t_2) { - /* "(tree fragment)":12 + /* "(tree fragment)":14 * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): * __pyx_result.__dict__.update(__pyx_state[10]) # <<<<<<<<<<<<<< */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) + __PYX_ERR(1, 14, __pyx_L1_error) } - __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 10, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 10, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __pyx_t_8 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { @@ -15413,45 +15121,15 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __Pyx_DECREF_SET(__pyx_t_7, function); } } - if (!__pyx_t_8) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_t_6}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_t_6}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - { - __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __pyx_t_8 = NULL; - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_6); - __pyx_t_6 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } - } + __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":11 + /* "(tree fragment)":13 * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< @@ -15459,7 +15137,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag */ } - /* "(tree fragment)":9 + /* "(tree fragment)":11 * __pyx_unpickle_RawRequestMessage__set_state(<RawRequestMessage> __pyx_result, __pyx_state) * return __pyx_result * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< @@ -15475,7 +15153,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawRequestMessage__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; @@ -15486,13 +15163,13 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessag /* "(tree fragment)":1 * def __pyx_unpickle_RawResponseMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0xc7706dc: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage = {"__pyx_unpickle_RawResponseMessage", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage, METH_VARARGS|METH_KEYWORDS, 0}; +static PyMethodDef __pyx_mdef_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage = {"__pyx_unpickle_RawResponseMessage", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage, METH_VARARGS|METH_KEYWORDS, 0}; static PyObject *__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v___pyx_type = 0; long __pyx_v___pyx_checksum; @@ -15564,8 +15241,8 @@ static PyObject *__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMes } static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMessage(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = NULL; - PyObject *__pyx_v___pyx_result = NULL; + PyObject *__pyx_v___pyx_PickleError = 0; + PyObject *__pyx_v___pyx_result = 0; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; @@ -15573,12 +15250,12 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMes PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; + int __pyx_t_6; __Pyx_RefNannySetupContext("__pyx_unpickle_RawResponseMessage", 0); - /* "(tree fragment)":2 - * def __pyx_unpickle_RawResponseMessage(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result * if __pyx_checksum != 0xc7706dc: # <<<<<<<<<<<<<< * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) @@ -15586,38 +15263,38 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMes __pyx_t_1 = ((__pyx_v___pyx_checksum != 0xc7706dc) != 0); if (__pyx_t_1) { - /* "(tree fragment)":3 - * def __pyx_unpickle_RawResponseMessage(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":5 + * cdef object __pyx_result * if __pyx_checksum != 0xc7706dc: * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) * __pyx_result = RawResponseMessage.__new__(__pyx_type) */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_n_s_PickleError); __Pyx_GIVEREF(__pyx_n_s_PickleError); PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 3, __pyx_L1_error) + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_t_2); __pyx_v___pyx_PickleError = __pyx_t_2; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "(tree fragment)":4 + /* "(tree fragment)":6 * if __pyx_checksum != 0xc7706dc: * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) # <<<<<<<<<<<<<< * __pyx_result = RawResponseMessage.__new__(__pyx_type) * if __pyx_state is not None: */ - __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0xc7, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 4, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0xc7, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_INCREF(__pyx_v___pyx_PickleError); @@ -15631,110 +15308,53 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMes __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_5) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else - #endif - { - __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL; - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_4); - __pyx_t_4 = 0; - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 4, __pyx_L1_error) + __PYX_ERR(1, 6, __pyx_L1_error) - /* "(tree fragment)":2 - * def __pyx_unpickle_RawResponseMessage(__pyx_type, long __pyx_checksum, __pyx_state): + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result * if __pyx_checksum != 0xc7706dc: # <<<<<<<<<<<<<< * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) */ } - /* "(tree fragment)":5 + /* "(tree fragment)":7 * from pickle import PickleError as __pyx_PickleError * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) * __pyx_result = RawResponseMessage.__new__(__pyx_type) # <<<<<<<<<<<<<< * if __pyx_state is not None: * __pyx_unpickle_RawResponseMessage__set_state(<RawResponseMessage> __pyx_result, __pyx_state) */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_6 = NULL; + __pyx_t_4 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_6)) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_2, function); } } - if (!__pyx_t_6) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v___pyx_type}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v___pyx_type}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - { - __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); __pyx_t_6 = NULL; - __Pyx_INCREF(__pyx_v___pyx_type); - __Pyx_GIVEREF(__pyx_v___pyx_type); - PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v___pyx_type); - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - } + __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v___pyx_result = __pyx_t_3; __pyx_t_3 = 0; - /* "(tree fragment)":6 + /* "(tree fragment)":8 * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) * __pyx_result = RawResponseMessage.__new__(__pyx_type) * if __pyx_state is not None: # <<<<<<<<<<<<<< @@ -15742,22 +15362,22 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMes * return __pyx_result */ __pyx_t_1 = (__pyx_v___pyx_state != Py_None); - __pyx_t_7 = (__pyx_t_1 != 0); - if (__pyx_t_7) { + __pyx_t_6 = (__pyx_t_1 != 0); + if (__pyx_t_6) { - /* "(tree fragment)":7 + /* "(tree fragment)":9 * __pyx_result = RawResponseMessage.__new__(__pyx_type) * if __pyx_state is not None: * __pyx_unpickle_RawResponseMessage__set_state(<RawResponseMessage> __pyx_result, __pyx_state) # <<<<<<<<<<<<<< * return __pyx_result * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 7, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "(tree fragment)":6 + /* "(tree fragment)":8 * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) * __pyx_result = RawResponseMessage.__new__(__pyx_type) * if __pyx_state is not None: # <<<<<<<<<<<<<< @@ -15766,7 +15386,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMes */ } - /* "(tree fragment)":8 + /* "(tree fragment)":10 * if __pyx_state is not None: * __pyx_unpickle_RawResponseMessage__set_state(<RawResponseMessage> __pyx_result, __pyx_state) * return __pyx_result # <<<<<<<<<<<<<< @@ -15780,8 +15400,8 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMes /* "(tree fragment)":1 * def __pyx_unpickle_RawResponseMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0xc7706dc: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ /* function exit code */ @@ -15790,7 +15410,6 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMes __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawResponseMessage", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -15801,7 +15420,7 @@ static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMes return __pyx_r; } -/* "(tree fragment)":9 +/* "(tree fragment)":11 * __pyx_unpickle_RawResponseMessage__set_state(<RawResponseMessage> __pyx_result, __pyx_state) * return __pyx_result * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< @@ -15821,10 +15440,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa PyObject *__pyx_t_7 = NULL; PyObject *__pyx_t_8 = NULL; PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; __Pyx_RefNannySetupContext("__pyx_unpickle_RawResponseMessage__set_state", 0); - /* "(tree fragment)":10 + /* "(tree fragment)":12 * return __pyx_result * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] # <<<<<<<<<<<<<< @@ -15833,9 +15451,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa */ if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->chunked); @@ -15844,18 +15462,18 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v___pyx_result->code = __pyx_t_2; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->compression); @@ -15864,9 +15482,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->headers); @@ -15875,9 +15493,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 4, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 4, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->raw_headers); @@ -15886,11 +15504,11 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 5, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 5, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 10, __pyx_L1_error) + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->reason); __Pyx_DECREF(__pyx_v___pyx_result->reason); @@ -15898,9 +15516,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 6, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 6, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->should_close); @@ -15909,9 +15527,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 7, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 7, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->upgrade); @@ -15920,9 +15538,9 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa __pyx_t_1 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 10, __pyx_L1_error) + __PYX_ERR(1, 12, __pyx_L1_error) } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 8, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 10, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 8, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v___pyx_result->version); @@ -15930,7 +15548,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa __pyx_v___pyx_result->version = __pyx_t_1; __pyx_t_1 = 0; - /* "(tree fragment)":11 + /* "(tree fragment)":13 * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< @@ -15938,36 +15556,36 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa */ if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 11, __pyx_L1_error) + __PYX_ERR(1, 13, __pyx_L1_error) } - __pyx_t_4 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_4 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) __pyx_t_5 = ((__pyx_t_4 > 9) != 0); if (__pyx_t_5) { } else { __pyx_t_3 = __pyx_t_5; goto __pyx_L4_bool_binop_done; } - __pyx_t_5 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(1, 11, __pyx_L1_error) + __pyx_t_5 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) __pyx_t_6 = (__pyx_t_5 != 0); __pyx_t_3 = __pyx_t_6; __pyx_L4_bool_binop_done:; if (__pyx_t_3) { - /* "(tree fragment)":12 + /* "(tree fragment)":14 * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): * __pyx_result.__dict__.update(__pyx_state[9]) # <<<<<<<<<<<<<< */ - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_update); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_update); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_8); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; if (unlikely(__pyx_v___pyx_state == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) + __PYX_ERR(1, 14, __pyx_L1_error) } - __pyx_t_7 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 9, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 12, __pyx_L1_error) + __pyx_t_7 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 9, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __pyx_t_9 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_8))) { @@ -15979,45 +15597,15 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa __Pyx_DECREF_SET(__pyx_t_8, function); } } - if (!__pyx_t_9) { - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_8)) { - PyObject *__pyx_temp[2] = {__pyx_t_9, __pyx_t_7}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_8, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_8)) { - PyObject *__pyx_temp[2] = {__pyx_t_9, __pyx_t_7}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_8, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } else - #endif - { - __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9); __pyx_t_9 = NULL; - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_7); - __pyx_t_7 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - } - } + __pyx_t_1 = (__pyx_t_9) ? __Pyx_PyObject_Call2Args(__pyx_t_8, __pyx_t_9, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":11 + /* "(tree fragment)":13 * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< @@ -16025,7 +15613,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa */ } - /* "(tree fragment)":9 + /* "(tree fragment)":11 * __pyx_unpickle_RawResponseMessage__set_state(<RawResponseMessage> __pyx_result, __pyx_state) * return __pyx_result * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< @@ -16041,7 +15629,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessa __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_8); __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_10); __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawResponseMessage__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; @@ -16209,7 +15796,7 @@ static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_url(P } static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_RawRequestMessage[] = { - {"_replace", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_5_replace, METH_VARARGS|METH_KEYWORDS, 0}, + {"_replace", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_5_replace, METH_VARARGS|METH_KEYWORDS, 0}, {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7__reduce_cython__, METH_NOARGS, 0}, {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_9__setstate_cython__, METH_O, 0}, {0, 0, 0, 0} @@ -17318,6 +16905,15 @@ static struct PyModuleDef __pyx_moduledef = { NULL /* m_free */ }; #endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_kp_u_, __pyx_k_, sizeof(__pyx_k_), 0, 1, 0, 0}, @@ -17372,7 +16968,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_HOST, __pyx_k_HOST, sizeof(__pyx_k_HOST), 0, 0, 1, 1}, {&__pyx_kp_u_Header_name_is_too_long, __pyx_k_Header_name_is_too_long, sizeof(__pyx_k_Header_name_is_too_long), 0, 1, 0, 0}, {&__pyx_kp_u_Header_value_is_too_long, __pyx_k_Header_value_is_too_long, sizeof(__pyx_k_Header_value_is_too_long), 0, 1, 0, 0}, + {&__pyx_n_s_HttpRequestParser, __pyx_k_HttpRequestParser, sizeof(__pyx_k_HttpRequestParser), 0, 0, 1, 1}, {&__pyx_n_u_HttpRequestParser, __pyx_k_HttpRequestParser, sizeof(__pyx_k_HttpRequestParser), 0, 1, 0, 1}, + {&__pyx_n_s_HttpResponseParser, __pyx_k_HttpResponseParser, sizeof(__pyx_k_HttpResponseParser), 0, 0, 1, 1}, {&__pyx_n_u_HttpResponseParser, __pyx_k_HttpResponseParser, sizeof(__pyx_k_HttpResponseParser), 0, 1, 0, 1}, {&__pyx_n_s_HttpVersion, __pyx_k_HttpVersion, sizeof(__pyx_k_HttpVersion), 0, 0, 1, 1}, {&__pyx_n_s_HttpVersion10, __pyx_k_HttpVersion10, sizeof(__pyx_k_HttpVersion10), 0, 0, 1, 1}, @@ -17409,8 +17007,10 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_REFERER, __pyx_k_REFERER, sizeof(__pyx_k_REFERER), 0, 0, 1, 1}, {&__pyx_n_s_RETRY_AFTER, __pyx_k_RETRY_AFTER, sizeof(__pyx_k_RETRY_AFTER), 0, 0, 1, 1}, {&__pyx_kp_u_RawRequestMessage, __pyx_k_RawRequestMessage, sizeof(__pyx_k_RawRequestMessage), 0, 1, 0, 0}, + {&__pyx_n_s_RawRequestMessage_2, __pyx_k_RawRequestMessage_2, sizeof(__pyx_k_RawRequestMessage_2), 0, 0, 1, 1}, {&__pyx_n_u_RawRequestMessage_2, __pyx_k_RawRequestMessage_2, sizeof(__pyx_k_RawRequestMessage_2), 0, 1, 0, 1}, {&__pyx_kp_u_RawResponseMessage, __pyx_k_RawResponseMessage, sizeof(__pyx_k_RawResponseMessage), 0, 1, 0, 0}, + {&__pyx_n_s_RawResponseMessage_2, __pyx_k_RawResponseMessage_2, sizeof(__pyx_k_RawResponseMessage_2), 0, 0, 1, 1}, {&__pyx_n_u_RawResponseMessage_2, __pyx_k_RawResponseMessage_2, sizeof(__pyx_k_RawResponseMessage_2), 0, 1, 0, 1}, {&__pyx_n_s_SEC_WEBSOCKET_ACCEPT, __pyx_k_SEC_WEBSOCKET_ACCEPT, sizeof(__pyx_k_SEC_WEBSOCKET_ACCEPT), 0, 0, 1, 1}, {&__pyx_n_s_SEC_WEBSOCKET_EXTENSIONS, __pyx_k_SEC_WEBSOCKET_EXTENSIONS, sizeof(__pyx_k_SEC_WEBSOCKET_EXTENSIONS), 0, 0, 1, 1}, @@ -17442,11 +17042,12 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_X_FORWARDED_FOR, __pyx_k_X_FORWARDED_FOR, sizeof(__pyx_k_X_FORWARDED_FOR), 0, 0, 1, 1}, {&__pyx_n_s_X_FORWARDED_HOST, __pyx_k_X_FORWARDED_HOST, sizeof(__pyx_k_X_FORWARDED_HOST), 0, 0, 1, 1}, {&__pyx_n_s_X_FORWARDED_PROTO, __pyx_k_X_FORWARDED_PROTO, sizeof(__pyx_k_X_FORWARDED_PROTO), 0, 0, 1, 1}, - {&__pyx_kp_u__13, __pyx_k__13, sizeof(__pyx_k__13), 0, 1, 0, 0}, + {&__pyx_kp_u__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 1, 0, 0}, {&__pyx_kp_u__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 1, 0, 0}, {&__pyx_kp_u__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 1, 0, 0}, - {&__pyx_kp_b__6, __pyx_k__6, sizeof(__pyx_k__6), 0, 0, 0, 0}, - {&__pyx_kp_u__6, __pyx_k__6, sizeof(__pyx_k__6), 0, 1, 0, 0}, + {&__pyx_n_s__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 0, 1, 1}, + {&__pyx_kp_b__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 0, 0, 0}, + {&__pyx_kp_u__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 1, 0, 0}, {&__pyx_n_s_add, __pyx_k_add, sizeof(__pyx_k_add), 0, 0, 1, 1}, {&__pyx_n_s_aiohttp, __pyx_k_aiohttp, sizeof(__pyx_k_aiohttp), 0, 0, 1, 1}, {&__pyx_n_s_aiohttp__http_parser, __pyx_k_aiohttp__http_parser, sizeof(__pyx_k_aiohttp__http_parser), 0, 0, 1, 1}, @@ -17552,7 +17153,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_yarl, __pyx_k_yarl, sizeof(__pyx_k_yarl), 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0} }; -static int __Pyx_InitCachedBuiltins(void) { +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 70, __pyx_L1_error) __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(0, 297, __pyx_L1_error) __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(1, 2, __pyx_L1_error) @@ -17562,32 +17163,29 @@ static int __Pyx_InitCachedBuiltins(void) { return -1; } -static int __Pyx_InitCachedConstants(void) { +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - /* "aiohttp/_http_parser.pyx":477 - * if self._payload is not None: - * if self._cparser.flags & cparser.F_CHUNKED: - * raise TransferEncodingError( # <<<<<<<<<<<<<< - * "Not enough data for satisfy transfer length header.") - * elif self._cparser.flags & cparser.F_CONTENTLENGTH: - */ - __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Not_enough_data_for_satisfy_tran); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(0, 477, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__4); - __Pyx_GIVEREF(__pyx_tuple__4); - - /* "aiohttp/_http_parser.pyx":480 - * "Not enough data for satisfy transfer length header.") - * elif self._cparser.flags & cparser.F_CONTENTLENGTH: - * raise ContentLengthError( # <<<<<<<<<<<<<< - * "Not enough data for satisfy content length header.") - * elif self._cparser.http_errno != cparser.HPE_OK: + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") */ - __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Not_enough_data_for_satisfy_cont); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 480, __pyx_L1_error) + __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 2, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__5); __Pyx_GIVEREF(__pyx_tuple__5); + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + /* "(tree fragment)":2 * def __reduce_cython__(self): * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< @@ -17626,25 +17224,6 @@ static int __Pyx_InitCachedConstants(void) { __Pyx_GOTREF(__pyx_tuple__10); __Pyx_GIVEREF(__pyx_tuple__10); - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(1, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__11); - __Pyx_GIVEREF(__pyx_tuple__11); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__12); - __Pyx_GIVEREF(__pyx_tuple__12); - /* "aiohttp/_http_parser.pyx":40 * char* PyByteArray_AsString(object) * @@ -17652,9 +17231,9 @@ static int __Pyx_InitCachedConstants(void) { * 'RawRequestMessage', 'RawResponseMessage') * */ - __pyx_tuple__14 = PyTuple_Pack(4, __pyx_n_u_HttpRequestParser, __pyx_n_u_HttpResponseParser, __pyx_n_u_RawRequestMessage_2, __pyx_n_u_RawResponseMessage_2); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(0, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__14); - __Pyx_GIVEREF(__pyx_tuple__14); + __pyx_tuple__12 = PyTuple_Pack(4, __pyx_n_u_HttpRequestParser, __pyx_n_u_HttpResponseParser, __pyx_n_u_RawRequestMessage_2, __pyx_n_u_RawResponseMessage_2); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__12); + __Pyx_GIVEREF(__pyx_tuple__12); /* "aiohttp/_http_parser.pyx":755 * @@ -17663,24 +17242,24 @@ static int __Pyx_InitCachedConstants(void) { * cdef: * Py_buffer py_buf */ - __pyx_tuple__15 = PyTuple_Pack(3, __pyx_n_s_url, __pyx_n_s_py_buf, __pyx_n_s_buf_data); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(0, 755, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__15); - __Pyx_GIVEREF(__pyx_tuple__15); - __pyx_codeobj__16 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__15, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_aiohttp__http_parser_pyx, __pyx_n_s_parse_url, 755, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__16)) __PYX_ERR(0, 755, __pyx_L1_error) + __pyx_tuple__13 = PyTuple_Pack(3, __pyx_n_s_url, __pyx_n_s_py_buf, __pyx_n_s_buf_data); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 755, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__13); + __Pyx_GIVEREF(__pyx_tuple__13); + __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_aiohttp__http_parser_pyx, __pyx_n_s_parse_url, 755, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) __PYX_ERR(0, 755, __pyx_L1_error) /* "(tree fragment)":1 * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x1408252: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ + __pyx_tuple__15 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__15); + __Pyx_GIVEREF(__pyx_tuple__15); + __pyx_codeobj__16 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__15, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_RawRequestMessage, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__16)) __PYX_ERR(1, 1, __pyx_L1_error) __pyx_tuple__17 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(1, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__17); __Pyx_GIVEREF(__pyx_tuple__17); - __pyx_codeobj__18 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__17, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_RawRequestMessage, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__18)) __PYX_ERR(1, 1, __pyx_L1_error) - __pyx_tuple__19 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__19); - __Pyx_GIVEREF(__pyx_tuple__19); - __pyx_codeobj__20 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__19, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_RawResponseMessag, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__20)) __PYX_ERR(1, 1, __pyx_L1_error) + __pyx_codeobj__18 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__17, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_RawResponseMessag, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__18)) __PYX_ERR(1, 1, __pyx_L1_error) __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; @@ -17688,7 +17267,7 @@ static int __Pyx_InitCachedConstants(void) { return -1; } -static int __Pyx_InitGlobals(void) { +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { __pyx_umethod_PyUnicode_Type_partition.type = (PyObject*)&PyUnicode_Type; if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); __pyx_int_21004882 = PyInt_FromLong(21004882L); if (unlikely(!__pyx_int_21004882)) __PYX_ERR(0, 1, __pyx_L1_error) @@ -17698,13 +17277,13 @@ static int __Pyx_InitGlobals(void) { return -1; } -static int __Pyx_modinit_global_init_code(void); /*proto*/ -static int __Pyx_modinit_variable_export_code(void); /*proto*/ -static int __Pyx_modinit_function_export_code(void); /*proto*/ -static int __Pyx_modinit_type_init_code(void); /*proto*/ -static int __Pyx_modinit_type_import_code(void); /*proto*/ -static int __Pyx_modinit_variable_import_code(void); /*proto*/ -static int __Pyx_modinit_function_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ static int __Pyx_modinit_global_init_code(void) { __Pyx_RefNannyDeclarations @@ -17753,7 +17332,7 @@ static int __Pyx_modinit_type_init_code(void) { if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_getattro == PyObject_GenericGetAttr)) { __pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_getattro = __Pyx_PyObject_GenericGetAttr; } - if (PyObject_SetAttrString(__pyx_m, "RawRequestMessage", (PyObject *)&__pyx_type_7aiohttp_12_http_parser_RawRequestMessage) < 0) __PYX_ERR(0, 93, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_RawRequestMessage_2, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_RawRequestMessage) < 0) __PYX_ERR(0, 93, __pyx_L1_error) if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_RawRequestMessage) < 0) __PYX_ERR(0, 93, __pyx_L1_error) __pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage = &__pyx_type_7aiohttp_12_http_parser_RawRequestMessage; if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_RawResponseMessage) < 0) __PYX_ERR(0, 193, __pyx_L1_error) @@ -17761,7 +17340,7 @@ static int __Pyx_modinit_type_init_code(void) { if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_getattro == PyObject_GenericGetAttr)) { __pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_getattro = __Pyx_PyObject_GenericGetAttr; } - if (PyObject_SetAttrString(__pyx_m, "RawResponseMessage", (PyObject *)&__pyx_type_7aiohttp_12_http_parser_RawResponseMessage) < 0) __PYX_ERR(0, 193, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_RawResponseMessage_2, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_RawResponseMessage) < 0) __PYX_ERR(0, 193, __pyx_L1_error) if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_RawResponseMessage) < 0) __PYX_ERR(0, 193, __pyx_L1_error) __pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage = &__pyx_type_7aiohttp_12_http_parser_RawResponseMessage; __pyx_vtabptr_7aiohttp_12_http_parser_HttpParser = &__pyx_vtable_7aiohttp_12_http_parser_HttpParser; @@ -17793,7 +17372,7 @@ static int __Pyx_modinit_type_init_code(void) { __pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_getattro = __Pyx_PyObject_GenericGetAttr; } if (__Pyx_SetVtable(__pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_dict, __pyx_vtabptr_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 537, __pyx_L1_error) - if (PyObject_SetAttrString(__pyx_m, "HttpRequestParser", (PyObject *)&__pyx_type_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 537, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_HttpRequestParser, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 537, __pyx_L1_error) if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 537, __pyx_L1_error) __pyx_ptype_7aiohttp_12_http_parser_HttpRequestParser = &__pyx_type_7aiohttp_12_http_parser_HttpRequestParser; __pyx_vtabptr_7aiohttp_12_http_parser_HttpResponseParser = &__pyx_vtable_7aiohttp_12_http_parser_HttpResponseParser; @@ -17806,7 +17385,7 @@ static int __Pyx_modinit_type_init_code(void) { __pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_getattro = __Pyx_PyObject_GenericGetAttr; } if (__Pyx_SetVtable(__pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_dict, __pyx_vtabptr_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 564, __pyx_L1_error) - if (PyObject_SetAttrString(__pyx_m, "HttpResponseParser", (PyObject *)&__pyx_type_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 564, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_HttpResponseParser, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 564, __pyx_L1_error) if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 564, __pyx_L1_error) __pyx_ptype_7aiohttp_12_http_parser_HttpResponseParser = &__pyx_type_7aiohttp_12_http_parser_HttpResponseParser; if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__) < 0) __PYX_ERR(0, 118, __pyx_L1_error) @@ -17842,20 +17421,34 @@ static int __Pyx_modinit_type_init_code(void) { static int __Pyx_modinit_type_import_code(void) { __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); /*--- Type import code ---*/ - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 sizeof(PyTypeObject), #else sizeof(PyHeapTypeObject), #endif - 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) __PYX_ERR(2, 9, __pyx_L1_error) - __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), 0); if (unlikely(!__pyx_ptype_7cpython_4bool_bool)) __PYX_ERR(3, 8, __pyx_L1_error) - __pyx_ptype_7cpython_7complex_complex = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "complex", sizeof(PyComplexObject), 0); if (unlikely(!__pyx_ptype_7cpython_7complex_complex)) __PYX_ERR(4, 15, __pyx_L1_error) + __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(2, 9, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4bool_bool) __PYX_ERR(3, 8, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_7complex_complex = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "complex", sizeof(PyComplexObject), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_7complex_complex) __PYX_ERR(4, 15, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); __Pyx_RefNannyFinishContext(); return -1; } @@ -17890,15 +17483,6 @@ static int __Pyx_modinit_function_import_code(void) { #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC #endif #endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (!(defined(__cplusplus)) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4))) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif #if PY_MAJOR_VERSION < 3 @@ -17911,11 +17495,36 @@ __Pyx_PyMODINIT_FUNC PyInit__http_parser(void) { return PyModuleDef_Init(&__pyx_moduledef); } -static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name) { +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { PyObject *value = PyObject_GetAttrString(spec, from_name); int result = 0; if (likely(value)) { - result = PyDict_SetItemString(moddict, to_name, value); + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } Py_DECREF(value); } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); @@ -17924,8 +17533,10 @@ static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const ch } return result; } -static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; if (__pyx_m) return __Pyx_NewRef(__pyx_m); modname = PyObject_GetAttrString(spec, "name"); @@ -17935,10 +17546,10 @@ static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *d if (unlikely(!module)) goto bad; moddict = PyModule_GetDict(module); if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; return module; bad: Py_XDECREF(module); @@ -17946,7 +17557,7 @@ bad: } -static int __pyx_pymod_exec__http_parser(PyObject *__pyx_pyinit_module) +static CYTHON_SMALL_CODE int __pyx_pymod_exec__http_parser(PyObject *__pyx_pyinit_module) #endif #endif { @@ -18035,7 +17646,11 @@ static int __pyx_pymod_exec__http_parser(PyObject *__pyx_pyinit_module) int __pyx_t_83; __Pyx_RefNannyDeclarations #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m && __pyx_m == __pyx_pyinit_module) return 0; + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_http_parser' has already been imported. Re-initialisation is not supported."); + return -1; + } #elif PY_MAJOR_VERSION >= 3 if (__pyx_m) return __Pyx_NewRef(__pyx_m); #endif @@ -18050,6 +17665,9 @@ if (!__Pyx_RefNanny) { #endif __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__http_parser(void)", 0); if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) @@ -18104,7 +17722,7 @@ if (!__Pyx_RefNanny) { if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif if (__pyx_module_is_main_aiohttp___http_parser) { - if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) } #if PY_MAJOR_VERSION >= 3 { @@ -18363,1185 +17981,1206 @@ if (!__Pyx_RefNanny) { __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "aiohttp/_headers.pxi":3 - * # The file is autogenerated from aiohtt/hdrs.py# Run ./tools/gen.py to update it after the origin changing.from . import hdrs + /* "aiohttp/_headers.pxi":4 + * # Run ./tools/gen.py to update it after the origin changing. + * + * from . import hdrs # <<<<<<<<<<<<<< + * cdef tuple headers = ( + * hdrs.ACCEPT, + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_hdrs); + __Pyx_GIVEREF(__pyx_n_s_hdrs); + PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_hdrs); + __pyx_t_1 = __Pyx_Import(__pyx_n_s__4, __pyx_t_2, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_hdrs, __pyx_t_2) < 0) __PYX_ERR(5, 4, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":6 + * from . import hdrs * cdef tuple headers = ( * hdrs.ACCEPT, # <<<<<<<<<<<<<< * hdrs.ACCEPT_CHARSET, * hdrs.ACCEPT_ENCODING, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCEPT); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 3, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":4 + /* "aiohttp/_headers.pxi":7 * cdef tuple headers = ( * hdrs.ACCEPT, * hdrs.ACCEPT_CHARSET, # <<<<<<<<<<<<<< * hdrs.ACCEPT_ENCODING, * hdrs.ACCEPT_LANGUAGE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCEPT_CHARSET); if (unlikely(!__pyx_t_3)) __PYX_ERR(5, 4, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_CHARSET); if (unlikely(!__pyx_t_3)) __PYX_ERR(5, 7, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":5 + /* "aiohttp/_headers.pxi":8 * hdrs.ACCEPT, * hdrs.ACCEPT_CHARSET, * hdrs.ACCEPT_ENCODING, # <<<<<<<<<<<<<< * hdrs.ACCEPT_LANGUAGE, * hdrs.ACCEPT_RANGES, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCEPT_ENCODING); if (unlikely(!__pyx_t_4)) __PYX_ERR(5, 5, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_ENCODING); if (unlikely(!__pyx_t_4)) __PYX_ERR(5, 8, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":6 + /* "aiohttp/_headers.pxi":9 * hdrs.ACCEPT_CHARSET, * hdrs.ACCEPT_ENCODING, * hdrs.ACCEPT_LANGUAGE, # <<<<<<<<<<<<<< * hdrs.ACCEPT_RANGES, * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCEPT_LANGUAGE); if (unlikely(!__pyx_t_5)) __PYX_ERR(5, 6, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_LANGUAGE); if (unlikely(!__pyx_t_5)) __PYX_ERR(5, 9, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":7 + /* "aiohttp/_headers.pxi":10 * hdrs.ACCEPT_ENCODING, * hdrs.ACCEPT_LANGUAGE, * hdrs.ACCEPT_RANGES, # <<<<<<<<<<<<<< * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCEPT_RANGES); if (unlikely(!__pyx_t_6)) __PYX_ERR(5, 7, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 10, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_RANGES); if (unlikely(!__pyx_t_6)) __PYX_ERR(5, 10, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":8 + /* "aiohttp/_headers.pxi":11 * hdrs.ACCEPT_LANGUAGE, * hdrs.ACCEPT_RANGES, * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, # <<<<<<<<<<<<<< * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, * hdrs.ACCESS_CONTROL_ALLOW_METHODS, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCESS_CONTROL_ALLOW_CREDENTIALS); if (unlikely(!__pyx_t_7)) __PYX_ERR(5, 8, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 11, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_CREDENTIALS); if (unlikely(!__pyx_t_7)) __PYX_ERR(5, 11, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":9 + /* "aiohttp/_headers.pxi":12 * hdrs.ACCEPT_RANGES, * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, # <<<<<<<<<<<<<< * hdrs.ACCESS_CONTROL_ALLOW_METHODS, * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCESS_CONTROL_ALLOW_HEADERS); if (unlikely(!__pyx_t_8)) __PYX_ERR(5, 9, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_HEADERS); if (unlikely(!__pyx_t_8)) __PYX_ERR(5, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":10 + /* "aiohttp/_headers.pxi":13 * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, * hdrs.ACCESS_CONTROL_ALLOW_METHODS, # <<<<<<<<<<<<<< * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 10, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCESS_CONTROL_ALLOW_METHODS); if (unlikely(!__pyx_t_9)) __PYX_ERR(5, 10, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_METHODS); if (unlikely(!__pyx_t_9)) __PYX_ERR(5, 13, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":11 + /* "aiohttp/_headers.pxi":14 * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, * hdrs.ACCESS_CONTROL_ALLOW_METHODS, * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, # <<<<<<<<<<<<<< * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, * hdrs.ACCESS_CONTROL_MAX_AGE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 11, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCESS_CONTROL_ALLOW_ORIGIN); if (unlikely(!__pyx_t_10)) __PYX_ERR(5, 11, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_ORIGIN); if (unlikely(!__pyx_t_10)) __PYX_ERR(5, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":12 + /* "aiohttp/_headers.pxi":15 * hdrs.ACCESS_CONTROL_ALLOW_METHODS, * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, # <<<<<<<<<<<<<< * hdrs.ACCESS_CONTROL_MAX_AGE, * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCESS_CONTROL_EXPOSE_HEADERS); if (unlikely(!__pyx_t_11)) __PYX_ERR(5, 12, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_EXPOSE_HEADERS); if (unlikely(!__pyx_t_11)) __PYX_ERR(5, 15, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":13 + /* "aiohttp/_headers.pxi":16 * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, * hdrs.ACCESS_CONTROL_MAX_AGE, # <<<<<<<<<<<<<< * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, * hdrs.ACCESS_CONTROL_REQUEST_METHOD, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCESS_CONTROL_MAX_AGE); if (unlikely(!__pyx_t_12)) __PYX_ERR(5, 13, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 16, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_MAX_AGE); if (unlikely(!__pyx_t_12)) __PYX_ERR(5, 16, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_12); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":14 + /* "aiohttp/_headers.pxi":17 * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, * hdrs.ACCESS_CONTROL_MAX_AGE, * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, # <<<<<<<<<<<<<< * hdrs.ACCESS_CONTROL_REQUEST_METHOD, * hdrs.AGE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCESS_CONTROL_REQUEST_HEADERS); if (unlikely(!__pyx_t_13)) __PYX_ERR(5, 14, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_REQUEST_HEADERS); if (unlikely(!__pyx_t_13)) __PYX_ERR(5, 17, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_13); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":15 + /* "aiohttp/_headers.pxi":18 * hdrs.ACCESS_CONTROL_MAX_AGE, * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, * hdrs.ACCESS_CONTROL_REQUEST_METHOD, # <<<<<<<<<<<<<< * hdrs.AGE, * hdrs.ALLOW, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ACCESS_CONTROL_REQUEST_METHOD); if (unlikely(!__pyx_t_14)) __PYX_ERR(5, 15, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 18, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_REQUEST_METHOD); if (unlikely(!__pyx_t_14)) __PYX_ERR(5, 18, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_14); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":16 + /* "aiohttp/_headers.pxi":19 * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, * hdrs.ACCESS_CONTROL_REQUEST_METHOD, * hdrs.AGE, # <<<<<<<<<<<<<< * hdrs.ALLOW, * hdrs.AUTHORIZATION, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 16, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_15 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_AGE); if (unlikely(!__pyx_t_15)) __PYX_ERR(5, 16, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_15 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_AGE); if (unlikely(!__pyx_t_15)) __PYX_ERR(5, 19, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_15); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":17 + /* "aiohttp/_headers.pxi":20 * hdrs.ACCESS_CONTROL_REQUEST_METHOD, * hdrs.AGE, * hdrs.ALLOW, # <<<<<<<<<<<<<< * hdrs.AUTHORIZATION, * hdrs.CACHE_CONTROL, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ALLOW); if (unlikely(!__pyx_t_16)) __PYX_ERR(5, 17, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 20, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ALLOW); if (unlikely(!__pyx_t_16)) __PYX_ERR(5, 20, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_16); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":18 + /* "aiohttp/_headers.pxi":21 * hdrs.AGE, * hdrs.ALLOW, * hdrs.AUTHORIZATION, # <<<<<<<<<<<<<< * hdrs.CACHE_CONTROL, * hdrs.CONNECTION, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 18, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_AUTHORIZATION); if (unlikely(!__pyx_t_17)) __PYX_ERR(5, 18, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_AUTHORIZATION); if (unlikely(!__pyx_t_17)) __PYX_ERR(5, 21, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_17); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":19 + /* "aiohttp/_headers.pxi":22 * hdrs.ALLOW, * hdrs.AUTHORIZATION, * hdrs.CACHE_CONTROL, # <<<<<<<<<<<<<< * hdrs.CONNECTION, * hdrs.CONTENT_DISPOSITION, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_18 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CACHE_CONTROL); if (unlikely(!__pyx_t_18)) __PYX_ERR(5, 19, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 22, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_18 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CACHE_CONTROL); if (unlikely(!__pyx_t_18)) __PYX_ERR(5, 22, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_18); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":20 + /* "aiohttp/_headers.pxi":23 * hdrs.AUTHORIZATION, * hdrs.CACHE_CONTROL, * hdrs.CONNECTION, # <<<<<<<<<<<<<< * hdrs.CONTENT_DISPOSITION, * hdrs.CONTENT_ENCODING, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 20, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_19 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CONNECTION); if (unlikely(!__pyx_t_19)) __PYX_ERR(5, 20, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 23, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_19 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONNECTION); if (unlikely(!__pyx_t_19)) __PYX_ERR(5, 23, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_19); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":21 + /* "aiohttp/_headers.pxi":24 * hdrs.CACHE_CONTROL, * hdrs.CONNECTION, * hdrs.CONTENT_DISPOSITION, # <<<<<<<<<<<<<< * hdrs.CONTENT_ENCODING, * hdrs.CONTENT_LANGUAGE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 21, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_20 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CONTENT_DISPOSITION); if (unlikely(!__pyx_t_20)) __PYX_ERR(5, 21, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_20 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_DISPOSITION); if (unlikely(!__pyx_t_20)) __PYX_ERR(5, 24, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_20); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":22 + /* "aiohttp/_headers.pxi":25 * hdrs.CONNECTION, * hdrs.CONTENT_DISPOSITION, * hdrs.CONTENT_ENCODING, # <<<<<<<<<<<<<< * hdrs.CONTENT_LANGUAGE, * hdrs.CONTENT_LENGTH, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 22, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_21 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CONTENT_ENCODING); if (unlikely(!__pyx_t_21)) __PYX_ERR(5, 22, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_21 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_ENCODING); if (unlikely(!__pyx_t_21)) __PYX_ERR(5, 25, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_21); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":23 + /* "aiohttp/_headers.pxi":26 * hdrs.CONTENT_DISPOSITION, * hdrs.CONTENT_ENCODING, * hdrs.CONTENT_LANGUAGE, # <<<<<<<<<<<<<< * hdrs.CONTENT_LENGTH, * hdrs.CONTENT_LOCATION, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 23, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_22 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CONTENT_LANGUAGE); if (unlikely(!__pyx_t_22)) __PYX_ERR(5, 23, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 26, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_22 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_LANGUAGE); if (unlikely(!__pyx_t_22)) __PYX_ERR(5, 26, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_22); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":24 + /* "aiohttp/_headers.pxi":27 * hdrs.CONTENT_ENCODING, * hdrs.CONTENT_LANGUAGE, * hdrs.CONTENT_LENGTH, # <<<<<<<<<<<<<< * hdrs.CONTENT_LOCATION, * hdrs.CONTENT_MD5, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_23 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CONTENT_LENGTH); if (unlikely(!__pyx_t_23)) __PYX_ERR(5, 24, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 27, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_23 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_LENGTH); if (unlikely(!__pyx_t_23)) __PYX_ERR(5, 27, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_23); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":25 + /* "aiohttp/_headers.pxi":28 * hdrs.CONTENT_LANGUAGE, * hdrs.CONTENT_LENGTH, * hdrs.CONTENT_LOCATION, # <<<<<<<<<<<<<< * hdrs.CONTENT_MD5, * hdrs.CONTENT_RANGE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 25, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_24 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CONTENT_LOCATION); if (unlikely(!__pyx_t_24)) __PYX_ERR(5, 25, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_24 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_LOCATION); if (unlikely(!__pyx_t_24)) __PYX_ERR(5, 28, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_24); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":26 + /* "aiohttp/_headers.pxi":29 * hdrs.CONTENT_LENGTH, * hdrs.CONTENT_LOCATION, * hdrs.CONTENT_MD5, # <<<<<<<<<<<<<< * hdrs.CONTENT_RANGE, * hdrs.CONTENT_TRANSFER_ENCODING, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 26, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_25 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CONTENT_MD5); if (unlikely(!__pyx_t_25)) __PYX_ERR(5, 26, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 29, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_25 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_MD5); if (unlikely(!__pyx_t_25)) __PYX_ERR(5, 29, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_25); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":27 + /* "aiohttp/_headers.pxi":30 * hdrs.CONTENT_LOCATION, * hdrs.CONTENT_MD5, * hdrs.CONTENT_RANGE, # <<<<<<<<<<<<<< * hdrs.CONTENT_TRANSFER_ENCODING, * hdrs.CONTENT_TYPE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_26 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CONTENT_RANGE); if (unlikely(!__pyx_t_26)) __PYX_ERR(5, 27, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_26 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_RANGE); if (unlikely(!__pyx_t_26)) __PYX_ERR(5, 30, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_26); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":28 + /* "aiohttp/_headers.pxi":31 * hdrs.CONTENT_MD5, * hdrs.CONTENT_RANGE, * hdrs.CONTENT_TRANSFER_ENCODING, # <<<<<<<<<<<<<< * hdrs.CONTENT_TYPE, * hdrs.COOKIE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_27 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CONTENT_TRANSFER_ENCODING); if (unlikely(!__pyx_t_27)) __PYX_ERR(5, 28, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_27 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_TRANSFER_ENCODING); if (unlikely(!__pyx_t_27)) __PYX_ERR(5, 31, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_27); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":29 + /* "aiohttp/_headers.pxi":32 * hdrs.CONTENT_RANGE, * hdrs.CONTENT_TRANSFER_ENCODING, * hdrs.CONTENT_TYPE, # <<<<<<<<<<<<<< * hdrs.COOKIE, * hdrs.DATE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_28 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_CONTENT_TYPE); if (unlikely(!__pyx_t_28)) __PYX_ERR(5, 29, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_28 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_TYPE); if (unlikely(!__pyx_t_28)) __PYX_ERR(5, 32, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_28); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":30 + /* "aiohttp/_headers.pxi":33 * hdrs.CONTENT_TRANSFER_ENCODING, * hdrs.CONTENT_TYPE, * hdrs.COOKIE, # <<<<<<<<<<<<<< * hdrs.DATE, * hdrs.DESTINATION, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_29 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_COOKIE); if (unlikely(!__pyx_t_29)) __PYX_ERR(5, 30, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_29 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_COOKIE); if (unlikely(!__pyx_t_29)) __PYX_ERR(5, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_29); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":31 + /* "aiohttp/_headers.pxi":34 * hdrs.CONTENT_TYPE, * hdrs.COOKIE, * hdrs.DATE, # <<<<<<<<<<<<<< * hdrs.DESTINATION, * hdrs.DIGEST, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_30 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_DATE); if (unlikely(!__pyx_t_30)) __PYX_ERR(5, 31, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_30 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_DATE); if (unlikely(!__pyx_t_30)) __PYX_ERR(5, 34, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_30); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":32 + /* "aiohttp/_headers.pxi":35 * hdrs.COOKIE, * hdrs.DATE, * hdrs.DESTINATION, # <<<<<<<<<<<<<< * hdrs.DIGEST, * hdrs.ETAG, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 32, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_31 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_DESTINATION); if (unlikely(!__pyx_t_31)) __PYX_ERR(5, 32, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_31 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_DESTINATION); if (unlikely(!__pyx_t_31)) __PYX_ERR(5, 35, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_31); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":33 + /* "aiohttp/_headers.pxi":36 * hdrs.DATE, * hdrs.DESTINATION, * hdrs.DIGEST, # <<<<<<<<<<<<<< * hdrs.ETAG, * hdrs.EXPECT, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_32 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_DIGEST); if (unlikely(!__pyx_t_32)) __PYX_ERR(5, 33, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 36, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_32 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_DIGEST); if (unlikely(!__pyx_t_32)) __PYX_ERR(5, 36, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_32); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":34 + /* "aiohttp/_headers.pxi":37 * hdrs.DESTINATION, * hdrs.DIGEST, * hdrs.ETAG, # <<<<<<<<<<<<<< * hdrs.EXPECT, * hdrs.EXPIRES, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 34, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_33 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ETAG); if (unlikely(!__pyx_t_33)) __PYX_ERR(5, 34, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_33 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ETAG); if (unlikely(!__pyx_t_33)) __PYX_ERR(5, 37, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_33); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":35 + /* "aiohttp/_headers.pxi":38 * hdrs.DIGEST, * hdrs.ETAG, * hdrs.EXPECT, # <<<<<<<<<<<<<< * hdrs.EXPIRES, * hdrs.FORWARDED, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_34 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_EXPECT); if (unlikely(!__pyx_t_34)) __PYX_ERR(5, 35, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 38, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_34 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_EXPECT); if (unlikely(!__pyx_t_34)) __PYX_ERR(5, 38, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_34); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":36 + /* "aiohttp/_headers.pxi":39 * hdrs.ETAG, * hdrs.EXPECT, * hdrs.EXPIRES, # <<<<<<<<<<<<<< * hdrs.FORWARDED, * hdrs.FROM, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 36, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_35 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_EXPIRES); if (unlikely(!__pyx_t_35)) __PYX_ERR(5, 36, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 39, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_35 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_EXPIRES); if (unlikely(!__pyx_t_35)) __PYX_ERR(5, 39, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_35); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":37 + /* "aiohttp/_headers.pxi":40 * hdrs.EXPECT, * hdrs.EXPIRES, * hdrs.FORWARDED, # <<<<<<<<<<<<<< * hdrs.FROM, * hdrs.HOST, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 37, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_36 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_FORWARDED); if (unlikely(!__pyx_t_36)) __PYX_ERR(5, 37, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_36 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_FORWARDED); if (unlikely(!__pyx_t_36)) __PYX_ERR(5, 40, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_36); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":38 + /* "aiohttp/_headers.pxi":41 * hdrs.EXPIRES, * hdrs.FORWARDED, * hdrs.FROM, # <<<<<<<<<<<<<< * hdrs.HOST, * hdrs.IF_MATCH, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 38, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_37 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_FROM); if (unlikely(!__pyx_t_37)) __PYX_ERR(5, 38, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 41, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_37 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_FROM); if (unlikely(!__pyx_t_37)) __PYX_ERR(5, 41, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_37); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":39 + /* "aiohttp/_headers.pxi":42 * hdrs.FORWARDED, * hdrs.FROM, * hdrs.HOST, # <<<<<<<<<<<<<< * hdrs.IF_MATCH, * hdrs.IF_MODIFIED_SINCE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 39, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_38 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_HOST); if (unlikely(!__pyx_t_38)) __PYX_ERR(5, 39, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 42, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_38 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_HOST); if (unlikely(!__pyx_t_38)) __PYX_ERR(5, 42, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_38); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":40 + /* "aiohttp/_headers.pxi":43 * hdrs.FROM, * hdrs.HOST, * hdrs.IF_MATCH, # <<<<<<<<<<<<<< * hdrs.IF_MODIFIED_SINCE, * hdrs.IF_NONE_MATCH, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_39 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_IF_MATCH); if (unlikely(!__pyx_t_39)) __PYX_ERR(5, 40, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_39 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_MATCH); if (unlikely(!__pyx_t_39)) __PYX_ERR(5, 43, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_39); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":41 + /* "aiohttp/_headers.pxi":44 * hdrs.HOST, * hdrs.IF_MATCH, * hdrs.IF_MODIFIED_SINCE, # <<<<<<<<<<<<<< * hdrs.IF_NONE_MATCH, * hdrs.IF_RANGE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 41, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_40 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_IF_MODIFIED_SINCE); if (unlikely(!__pyx_t_40)) __PYX_ERR(5, 41, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_40 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_MODIFIED_SINCE); if (unlikely(!__pyx_t_40)) __PYX_ERR(5, 44, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_40); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":42 + /* "aiohttp/_headers.pxi":45 * hdrs.IF_MATCH, * hdrs.IF_MODIFIED_SINCE, * hdrs.IF_NONE_MATCH, # <<<<<<<<<<<<<< * hdrs.IF_RANGE, * hdrs.IF_UNMODIFIED_SINCE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 42, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_41 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_IF_NONE_MATCH); if (unlikely(!__pyx_t_41)) __PYX_ERR(5, 42, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 45, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_41 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_NONE_MATCH); if (unlikely(!__pyx_t_41)) __PYX_ERR(5, 45, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_41); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":43 + /* "aiohttp/_headers.pxi":46 * hdrs.IF_MODIFIED_SINCE, * hdrs.IF_NONE_MATCH, * hdrs.IF_RANGE, # <<<<<<<<<<<<<< * hdrs.IF_UNMODIFIED_SINCE, * hdrs.KEEP_ALIVE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 43, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_42 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_IF_RANGE); if (unlikely(!__pyx_t_42)) __PYX_ERR(5, 43, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 46, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_42 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_RANGE); if (unlikely(!__pyx_t_42)) __PYX_ERR(5, 46, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_42); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":44 + /* "aiohttp/_headers.pxi":47 * hdrs.IF_NONE_MATCH, * hdrs.IF_RANGE, * hdrs.IF_UNMODIFIED_SINCE, # <<<<<<<<<<<<<< * hdrs.KEEP_ALIVE, * hdrs.LAST_EVENT_ID, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 44, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_43 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_IF_UNMODIFIED_SINCE); if (unlikely(!__pyx_t_43)) __PYX_ERR(5, 44, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 47, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_43 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_UNMODIFIED_SINCE); if (unlikely(!__pyx_t_43)) __PYX_ERR(5, 47, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_43); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":45 + /* "aiohttp/_headers.pxi":48 * hdrs.IF_RANGE, * hdrs.IF_UNMODIFIED_SINCE, * hdrs.KEEP_ALIVE, # <<<<<<<<<<<<<< * hdrs.LAST_EVENT_ID, * hdrs.LAST_MODIFIED, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 45, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_44 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_KEEP_ALIVE); if (unlikely(!__pyx_t_44)) __PYX_ERR(5, 45, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 48, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_44 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_KEEP_ALIVE); if (unlikely(!__pyx_t_44)) __PYX_ERR(5, 48, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_44); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":46 + /* "aiohttp/_headers.pxi":49 * hdrs.IF_UNMODIFIED_SINCE, * hdrs.KEEP_ALIVE, * hdrs.LAST_EVENT_ID, # <<<<<<<<<<<<<< * hdrs.LAST_MODIFIED, * hdrs.LINK, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 46, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_45 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_LAST_EVENT_ID); if (unlikely(!__pyx_t_45)) __PYX_ERR(5, 46, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 49, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_45 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LAST_EVENT_ID); if (unlikely(!__pyx_t_45)) __PYX_ERR(5, 49, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_45); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":47 + /* "aiohttp/_headers.pxi":50 * hdrs.KEEP_ALIVE, * hdrs.LAST_EVENT_ID, * hdrs.LAST_MODIFIED, # <<<<<<<<<<<<<< * hdrs.LINK, * hdrs.LOCATION, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 47, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_46 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_LAST_MODIFIED); if (unlikely(!__pyx_t_46)) __PYX_ERR(5, 47, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 50, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_46 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LAST_MODIFIED); if (unlikely(!__pyx_t_46)) __PYX_ERR(5, 50, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_46); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":48 + /* "aiohttp/_headers.pxi":51 * hdrs.LAST_EVENT_ID, * hdrs.LAST_MODIFIED, * hdrs.LINK, # <<<<<<<<<<<<<< * hdrs.LOCATION, * hdrs.MAX_FORWARDS, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 48, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_47 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_LINK); if (unlikely(!__pyx_t_47)) __PYX_ERR(5, 48, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_47 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LINK); if (unlikely(!__pyx_t_47)) __PYX_ERR(5, 51, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_47); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":49 + /* "aiohttp/_headers.pxi":52 * hdrs.LAST_MODIFIED, * hdrs.LINK, * hdrs.LOCATION, # <<<<<<<<<<<<<< * hdrs.MAX_FORWARDS, * hdrs.ORIGIN, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 49, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_48 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_LOCATION); if (unlikely(!__pyx_t_48)) __PYX_ERR(5, 49, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 52, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_48 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LOCATION); if (unlikely(!__pyx_t_48)) __PYX_ERR(5, 52, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_48); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":50 + /* "aiohttp/_headers.pxi":53 * hdrs.LINK, * hdrs.LOCATION, * hdrs.MAX_FORWARDS, # <<<<<<<<<<<<<< * hdrs.ORIGIN, * hdrs.PRAGMA, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 50, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_49 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_MAX_FORWARDS); if (unlikely(!__pyx_t_49)) __PYX_ERR(5, 50, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 53, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_49 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_MAX_FORWARDS); if (unlikely(!__pyx_t_49)) __PYX_ERR(5, 53, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_49); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":51 + /* "aiohttp/_headers.pxi":54 * hdrs.LOCATION, * hdrs.MAX_FORWARDS, * hdrs.ORIGIN, # <<<<<<<<<<<<<< * hdrs.PRAGMA, * hdrs.PROXY_AUTHENTICATE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 51, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_50 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ORIGIN); if (unlikely(!__pyx_t_50)) __PYX_ERR(5, 51, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 54, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_50 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ORIGIN); if (unlikely(!__pyx_t_50)) __PYX_ERR(5, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_50); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":52 + /* "aiohttp/_headers.pxi":55 * hdrs.MAX_FORWARDS, * hdrs.ORIGIN, * hdrs.PRAGMA, # <<<<<<<<<<<<<< * hdrs.PROXY_AUTHENTICATE, * hdrs.PROXY_AUTHORIZATION, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 52, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_51 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_PRAGMA); if (unlikely(!__pyx_t_51)) __PYX_ERR(5, 52, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_51 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_PRAGMA); if (unlikely(!__pyx_t_51)) __PYX_ERR(5, 55, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_51); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":53 + /* "aiohttp/_headers.pxi":56 * hdrs.ORIGIN, * hdrs.PRAGMA, * hdrs.PROXY_AUTHENTICATE, # <<<<<<<<<<<<<< * hdrs.PROXY_AUTHORIZATION, * hdrs.RANGE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 53, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_52 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_PROXY_AUTHENTICATE); if (unlikely(!__pyx_t_52)) __PYX_ERR(5, 53, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_52 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_PROXY_AUTHENTICATE); if (unlikely(!__pyx_t_52)) __PYX_ERR(5, 56, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_52); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":54 + /* "aiohttp/_headers.pxi":57 * hdrs.PRAGMA, * hdrs.PROXY_AUTHENTICATE, * hdrs.PROXY_AUTHORIZATION, # <<<<<<<<<<<<<< * hdrs.RANGE, * hdrs.REFERER, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 54, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_53 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_PROXY_AUTHORIZATION); if (unlikely(!__pyx_t_53)) __PYX_ERR(5, 54, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_53 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_PROXY_AUTHORIZATION); if (unlikely(!__pyx_t_53)) __PYX_ERR(5, 57, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_53); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":55 + /* "aiohttp/_headers.pxi":58 * hdrs.PROXY_AUTHENTICATE, * hdrs.PROXY_AUTHORIZATION, * hdrs.RANGE, # <<<<<<<<<<<<<< * hdrs.REFERER, * hdrs.RETRY_AFTER, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 55, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_54 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_RANGE); if (unlikely(!__pyx_t_54)) __PYX_ERR(5, 55, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_54 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_RANGE); if (unlikely(!__pyx_t_54)) __PYX_ERR(5, 58, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_54); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":56 + /* "aiohttp/_headers.pxi":59 * hdrs.PROXY_AUTHORIZATION, * hdrs.RANGE, * hdrs.REFERER, # <<<<<<<<<<<<<< * hdrs.RETRY_AFTER, * hdrs.SEC_WEBSOCKET_ACCEPT, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 56, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_55 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_REFERER); if (unlikely(!__pyx_t_55)) __PYX_ERR(5, 56, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 59, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_55 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_REFERER); if (unlikely(!__pyx_t_55)) __PYX_ERR(5, 59, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_55); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":57 + /* "aiohttp/_headers.pxi":60 * hdrs.RANGE, * hdrs.REFERER, * hdrs.RETRY_AFTER, # <<<<<<<<<<<<<< * hdrs.SEC_WEBSOCKET_ACCEPT, * hdrs.SEC_WEBSOCKET_EXTENSIONS, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_56 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_RETRY_AFTER); if (unlikely(!__pyx_t_56)) __PYX_ERR(5, 57, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_56 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_RETRY_AFTER); if (unlikely(!__pyx_t_56)) __PYX_ERR(5, 60, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_56); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":58 + /* "aiohttp/_headers.pxi":61 * hdrs.REFERER, * hdrs.RETRY_AFTER, * hdrs.SEC_WEBSOCKET_ACCEPT, # <<<<<<<<<<<<<< * hdrs.SEC_WEBSOCKET_EXTENSIONS, * hdrs.SEC_WEBSOCKET_KEY, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 58, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_57 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_SEC_WEBSOCKET_ACCEPT); if (unlikely(!__pyx_t_57)) __PYX_ERR(5, 58, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 61, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_57 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_ACCEPT); if (unlikely(!__pyx_t_57)) __PYX_ERR(5, 61, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_57); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":59 + /* "aiohttp/_headers.pxi":62 * hdrs.RETRY_AFTER, * hdrs.SEC_WEBSOCKET_ACCEPT, * hdrs.SEC_WEBSOCKET_EXTENSIONS, # <<<<<<<<<<<<<< * hdrs.SEC_WEBSOCKET_KEY, * hdrs.SEC_WEBSOCKET_KEY1, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 59, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_58 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_SEC_WEBSOCKET_EXTENSIONS); if (unlikely(!__pyx_t_58)) __PYX_ERR(5, 59, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_58 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_EXTENSIONS); if (unlikely(!__pyx_t_58)) __PYX_ERR(5, 62, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_58); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":60 + /* "aiohttp/_headers.pxi":63 * hdrs.SEC_WEBSOCKET_ACCEPT, * hdrs.SEC_WEBSOCKET_EXTENSIONS, * hdrs.SEC_WEBSOCKET_KEY, # <<<<<<<<<<<<<< * hdrs.SEC_WEBSOCKET_KEY1, * hdrs.SEC_WEBSOCKET_PROTOCOL, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_59 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_SEC_WEBSOCKET_KEY); if (unlikely(!__pyx_t_59)) __PYX_ERR(5, 60, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 63, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_59 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_KEY); if (unlikely(!__pyx_t_59)) __PYX_ERR(5, 63, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_59); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":61 + /* "aiohttp/_headers.pxi":64 * hdrs.SEC_WEBSOCKET_EXTENSIONS, * hdrs.SEC_WEBSOCKET_KEY, * hdrs.SEC_WEBSOCKET_KEY1, # <<<<<<<<<<<<<< * hdrs.SEC_WEBSOCKET_PROTOCOL, * hdrs.SEC_WEBSOCKET_VERSION, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 61, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_60 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_SEC_WEBSOCKET_KEY1); if (unlikely(!__pyx_t_60)) __PYX_ERR(5, 61, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_60 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_KEY1); if (unlikely(!__pyx_t_60)) __PYX_ERR(5, 64, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_60); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":62 + /* "aiohttp/_headers.pxi":65 * hdrs.SEC_WEBSOCKET_KEY, * hdrs.SEC_WEBSOCKET_KEY1, * hdrs.SEC_WEBSOCKET_PROTOCOL, # <<<<<<<<<<<<<< * hdrs.SEC_WEBSOCKET_VERSION, * hdrs.SERVER, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_61 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_SEC_WEBSOCKET_PROTOCOL); if (unlikely(!__pyx_t_61)) __PYX_ERR(5, 62, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 65, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_61 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_PROTOCOL); if (unlikely(!__pyx_t_61)) __PYX_ERR(5, 65, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_61); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":63 + /* "aiohttp/_headers.pxi":66 * hdrs.SEC_WEBSOCKET_KEY1, * hdrs.SEC_WEBSOCKET_PROTOCOL, * hdrs.SEC_WEBSOCKET_VERSION, # <<<<<<<<<<<<<< * hdrs.SERVER, * hdrs.SET_COOKIE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 63, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_62 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_SEC_WEBSOCKET_VERSION); if (unlikely(!__pyx_t_62)) __PYX_ERR(5, 63, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_62 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_VERSION); if (unlikely(!__pyx_t_62)) __PYX_ERR(5, 66, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_62); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":64 + /* "aiohttp/_headers.pxi":67 * hdrs.SEC_WEBSOCKET_PROTOCOL, * hdrs.SEC_WEBSOCKET_VERSION, * hdrs.SERVER, # <<<<<<<<<<<<<< * hdrs.SET_COOKIE, * hdrs.TE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 64, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_63 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_SERVER); if (unlikely(!__pyx_t_63)) __PYX_ERR(5, 64, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 67, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_63 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SERVER); if (unlikely(!__pyx_t_63)) __PYX_ERR(5, 67, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_63); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":65 + /* "aiohttp/_headers.pxi":68 * hdrs.SEC_WEBSOCKET_VERSION, * hdrs.SERVER, * hdrs.SET_COOKIE, # <<<<<<<<<<<<<< * hdrs.TE, * hdrs.TRAILER, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 65, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_64 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_SET_COOKIE); if (unlikely(!__pyx_t_64)) __PYX_ERR(5, 65, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_64 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SET_COOKIE); if (unlikely(!__pyx_t_64)) __PYX_ERR(5, 68, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_64); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":66 + /* "aiohttp/_headers.pxi":69 * hdrs.SERVER, * hdrs.SET_COOKIE, * hdrs.TE, # <<<<<<<<<<<<<< * hdrs.TRAILER, * hdrs.TRANSFER_ENCODING, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 66, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_65 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_TE); if (unlikely(!__pyx_t_65)) __PYX_ERR(5, 66, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 69, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_65 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_TE); if (unlikely(!__pyx_t_65)) __PYX_ERR(5, 69, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_65); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":67 + /* "aiohttp/_headers.pxi":70 * hdrs.SET_COOKIE, * hdrs.TE, * hdrs.TRAILER, # <<<<<<<<<<<<<< * hdrs.TRANSFER_ENCODING, * hdrs.UPGRADE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_66 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_TRAILER); if (unlikely(!__pyx_t_66)) __PYX_ERR(5, 67, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_66 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_TRAILER); if (unlikely(!__pyx_t_66)) __PYX_ERR(5, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_66); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":68 + /* "aiohttp/_headers.pxi":71 * hdrs.TE, * hdrs.TRAILER, * hdrs.TRANSFER_ENCODING, # <<<<<<<<<<<<<< * hdrs.UPGRADE, * hdrs.URI, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 68, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_67 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_TRANSFER_ENCODING); if (unlikely(!__pyx_t_67)) __PYX_ERR(5, 68, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_67 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_TRANSFER_ENCODING); if (unlikely(!__pyx_t_67)) __PYX_ERR(5, 71, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_67); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":69 + /* "aiohttp/_headers.pxi":72 * hdrs.TRAILER, * hdrs.TRANSFER_ENCODING, * hdrs.UPGRADE, # <<<<<<<<<<<<<< * hdrs.URI, * hdrs.USER_AGENT, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 69, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_68 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_UPGRADE); if (unlikely(!__pyx_t_68)) __PYX_ERR(5, 69, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 72, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_68 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_UPGRADE); if (unlikely(!__pyx_t_68)) __PYX_ERR(5, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_68); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":70 + /* "aiohttp/_headers.pxi":73 * hdrs.TRANSFER_ENCODING, * hdrs.UPGRADE, * hdrs.URI, # <<<<<<<<<<<<<< * hdrs.USER_AGENT, * hdrs.VARY, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_69 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_URI); if (unlikely(!__pyx_t_69)) __PYX_ERR(5, 70, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_69 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_URI); if (unlikely(!__pyx_t_69)) __PYX_ERR(5, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_69); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":71 + /* "aiohttp/_headers.pxi":74 * hdrs.UPGRADE, * hdrs.URI, * hdrs.USER_AGENT, # <<<<<<<<<<<<<< * hdrs.VARY, * hdrs.VIA, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_70 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_USER_AGENT); if (unlikely(!__pyx_t_70)) __PYX_ERR(5, 71, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_70 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_USER_AGENT); if (unlikely(!__pyx_t_70)) __PYX_ERR(5, 74, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_70); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":72 + /* "aiohttp/_headers.pxi":75 * hdrs.URI, * hdrs.USER_AGENT, * hdrs.VARY, # <<<<<<<<<<<<<< * hdrs.VIA, * hdrs.WANT_DIGEST, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 72, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_71 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_VARY); if (unlikely(!__pyx_t_71)) __PYX_ERR(5, 72, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_71 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_VARY); if (unlikely(!__pyx_t_71)) __PYX_ERR(5, 75, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_71); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":73 + /* "aiohttp/_headers.pxi":76 * hdrs.USER_AGENT, * hdrs.VARY, * hdrs.VIA, # <<<<<<<<<<<<<< * hdrs.WANT_DIGEST, * hdrs.WARNING, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 73, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_72 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_VIA); if (unlikely(!__pyx_t_72)) __PYX_ERR(5, 73, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_72 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_VIA); if (unlikely(!__pyx_t_72)) __PYX_ERR(5, 76, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_72); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":74 + /* "aiohttp/_headers.pxi":77 * hdrs.VARY, * hdrs.VIA, * hdrs.WANT_DIGEST, # <<<<<<<<<<<<<< * hdrs.WARNING, * hdrs.WEBSOCKET, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 74, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_73 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_WANT_DIGEST); if (unlikely(!__pyx_t_73)) __PYX_ERR(5, 74, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_73 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_WANT_DIGEST); if (unlikely(!__pyx_t_73)) __PYX_ERR(5, 77, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_73); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":75 + /* "aiohttp/_headers.pxi":78 * hdrs.VIA, * hdrs.WANT_DIGEST, * hdrs.WARNING, # <<<<<<<<<<<<<< * hdrs.WEBSOCKET, * hdrs.WWW_AUTHENTICATE, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 75, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_74 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_WARNING); if (unlikely(!__pyx_t_74)) __PYX_ERR(5, 75, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_74 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_WARNING); if (unlikely(!__pyx_t_74)) __PYX_ERR(5, 78, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_74); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":76 + /* "aiohttp/_headers.pxi":79 * hdrs.WANT_DIGEST, * hdrs.WARNING, * hdrs.WEBSOCKET, # <<<<<<<<<<<<<< * hdrs.WWW_AUTHENTICATE, * hdrs.X_FORWARDED_FOR, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 76, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_75 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_WEBSOCKET); if (unlikely(!__pyx_t_75)) __PYX_ERR(5, 76, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_75 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_WEBSOCKET); if (unlikely(!__pyx_t_75)) __PYX_ERR(5, 79, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_75); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":77 + /* "aiohttp/_headers.pxi":80 * hdrs.WARNING, * hdrs.WEBSOCKET, * hdrs.WWW_AUTHENTICATE, # <<<<<<<<<<<<<< * hdrs.X_FORWARDED_FOR, * hdrs.X_FORWARDED_HOST, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 77, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_76 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_WWW_AUTHENTICATE); if (unlikely(!__pyx_t_76)) __PYX_ERR(5, 77, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_76 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_WWW_AUTHENTICATE); if (unlikely(!__pyx_t_76)) __PYX_ERR(5, 80, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_76); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":78 + /* "aiohttp/_headers.pxi":81 * hdrs.WEBSOCKET, * hdrs.WWW_AUTHENTICATE, * hdrs.X_FORWARDED_FOR, # <<<<<<<<<<<<<< * hdrs.X_FORWARDED_HOST, * hdrs.X_FORWARDED_PROTO, */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_77 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_X_FORWARDED_FOR); if (unlikely(!__pyx_t_77)) __PYX_ERR(5, 78, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 81, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_77 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_X_FORWARDED_FOR); if (unlikely(!__pyx_t_77)) __PYX_ERR(5, 81, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_77); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":79 + /* "aiohttp/_headers.pxi":82 * hdrs.WWW_AUTHENTICATE, * hdrs.X_FORWARDED_FOR, * hdrs.X_FORWARDED_HOST, # <<<<<<<<<<<<<< * hdrs.X_FORWARDED_PROTO, * ) */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 79, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_78 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_X_FORWARDED_HOST); if (unlikely(!__pyx_t_78)) __PYX_ERR(5, 79, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_78 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_X_FORWARDED_HOST); if (unlikely(!__pyx_t_78)) __PYX_ERR(5, 82, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_78); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":80 + /* "aiohttp/_headers.pxi":83 * hdrs.X_FORWARDED_FOR, * hdrs.X_FORWARDED_HOST, * hdrs.X_FORWARDED_PROTO, # <<<<<<<<<<<<<< * ) */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 80, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_79 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_X_FORWARDED_PROTO); if (unlikely(!__pyx_t_79)) __PYX_ERR(5, 80, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 83, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_79 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_X_FORWARDED_PROTO); if (unlikely(!__pyx_t_79)) __PYX_ERR(5, 83, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_79); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "aiohttp/_headers.pxi":3 - * # The file is autogenerated from aiohtt/hdrs.py# Run ./tools/gen.py to update it after the origin changing.from . import hdrs + /* "aiohttp/_headers.pxi":6 + * from . import hdrs * cdef tuple headers = ( * hdrs.ACCEPT, # <<<<<<<<<<<<<< * hdrs.ACCEPT_CHARSET, * hdrs.ACCEPT_ENCODING, */ - __pyx_t_2 = PyTuple_New(78); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); + __pyx_t_1 = PyTuple_New(78); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_2, 5, __pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_8); - PyTuple_SET_ITEM(__pyx_t_2, 6, __pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_9); - PyTuple_SET_ITEM(__pyx_t_2, 7, __pyx_t_9); + PyTuple_SET_ITEM(__pyx_t_1, 7, __pyx_t_9); __Pyx_GIVEREF(__pyx_t_10); - PyTuple_SET_ITEM(__pyx_t_2, 8, __pyx_t_10); + PyTuple_SET_ITEM(__pyx_t_1, 8, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_11); - PyTuple_SET_ITEM(__pyx_t_2, 9, __pyx_t_11); + PyTuple_SET_ITEM(__pyx_t_1, 9, __pyx_t_11); __Pyx_GIVEREF(__pyx_t_12); - PyTuple_SET_ITEM(__pyx_t_2, 10, __pyx_t_12); + PyTuple_SET_ITEM(__pyx_t_1, 10, __pyx_t_12); __Pyx_GIVEREF(__pyx_t_13); - PyTuple_SET_ITEM(__pyx_t_2, 11, __pyx_t_13); + PyTuple_SET_ITEM(__pyx_t_1, 11, __pyx_t_13); __Pyx_GIVEREF(__pyx_t_14); - PyTuple_SET_ITEM(__pyx_t_2, 12, __pyx_t_14); + PyTuple_SET_ITEM(__pyx_t_1, 12, __pyx_t_14); __Pyx_GIVEREF(__pyx_t_15); - PyTuple_SET_ITEM(__pyx_t_2, 13, __pyx_t_15); + PyTuple_SET_ITEM(__pyx_t_1, 13, __pyx_t_15); __Pyx_GIVEREF(__pyx_t_16); - PyTuple_SET_ITEM(__pyx_t_2, 14, __pyx_t_16); + PyTuple_SET_ITEM(__pyx_t_1, 14, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_17); - PyTuple_SET_ITEM(__pyx_t_2, 15, __pyx_t_17); + PyTuple_SET_ITEM(__pyx_t_1, 15, __pyx_t_17); __Pyx_GIVEREF(__pyx_t_18); - PyTuple_SET_ITEM(__pyx_t_2, 16, __pyx_t_18); + PyTuple_SET_ITEM(__pyx_t_1, 16, __pyx_t_18); __Pyx_GIVEREF(__pyx_t_19); - PyTuple_SET_ITEM(__pyx_t_2, 17, __pyx_t_19); + PyTuple_SET_ITEM(__pyx_t_1, 17, __pyx_t_19); __Pyx_GIVEREF(__pyx_t_20); - PyTuple_SET_ITEM(__pyx_t_2, 18, __pyx_t_20); + PyTuple_SET_ITEM(__pyx_t_1, 18, __pyx_t_20); __Pyx_GIVEREF(__pyx_t_21); - PyTuple_SET_ITEM(__pyx_t_2, 19, __pyx_t_21); + PyTuple_SET_ITEM(__pyx_t_1, 19, __pyx_t_21); __Pyx_GIVEREF(__pyx_t_22); - PyTuple_SET_ITEM(__pyx_t_2, 20, __pyx_t_22); + PyTuple_SET_ITEM(__pyx_t_1, 20, __pyx_t_22); __Pyx_GIVEREF(__pyx_t_23); - PyTuple_SET_ITEM(__pyx_t_2, 21, __pyx_t_23); + PyTuple_SET_ITEM(__pyx_t_1, 21, __pyx_t_23); __Pyx_GIVEREF(__pyx_t_24); - PyTuple_SET_ITEM(__pyx_t_2, 22, __pyx_t_24); + PyTuple_SET_ITEM(__pyx_t_1, 22, __pyx_t_24); __Pyx_GIVEREF(__pyx_t_25); - PyTuple_SET_ITEM(__pyx_t_2, 23, __pyx_t_25); + PyTuple_SET_ITEM(__pyx_t_1, 23, __pyx_t_25); __Pyx_GIVEREF(__pyx_t_26); - PyTuple_SET_ITEM(__pyx_t_2, 24, __pyx_t_26); + PyTuple_SET_ITEM(__pyx_t_1, 24, __pyx_t_26); __Pyx_GIVEREF(__pyx_t_27); - PyTuple_SET_ITEM(__pyx_t_2, 25, __pyx_t_27); + PyTuple_SET_ITEM(__pyx_t_1, 25, __pyx_t_27); __Pyx_GIVEREF(__pyx_t_28); - PyTuple_SET_ITEM(__pyx_t_2, 26, __pyx_t_28); + PyTuple_SET_ITEM(__pyx_t_1, 26, __pyx_t_28); __Pyx_GIVEREF(__pyx_t_29); - PyTuple_SET_ITEM(__pyx_t_2, 27, __pyx_t_29); + PyTuple_SET_ITEM(__pyx_t_1, 27, __pyx_t_29); __Pyx_GIVEREF(__pyx_t_30); - PyTuple_SET_ITEM(__pyx_t_2, 28, __pyx_t_30); + PyTuple_SET_ITEM(__pyx_t_1, 28, __pyx_t_30); __Pyx_GIVEREF(__pyx_t_31); - PyTuple_SET_ITEM(__pyx_t_2, 29, __pyx_t_31); + PyTuple_SET_ITEM(__pyx_t_1, 29, __pyx_t_31); __Pyx_GIVEREF(__pyx_t_32); - PyTuple_SET_ITEM(__pyx_t_2, 30, __pyx_t_32); + PyTuple_SET_ITEM(__pyx_t_1, 30, __pyx_t_32); __Pyx_GIVEREF(__pyx_t_33); - PyTuple_SET_ITEM(__pyx_t_2, 31, __pyx_t_33); + PyTuple_SET_ITEM(__pyx_t_1, 31, __pyx_t_33); __Pyx_GIVEREF(__pyx_t_34); - PyTuple_SET_ITEM(__pyx_t_2, 32, __pyx_t_34); + PyTuple_SET_ITEM(__pyx_t_1, 32, __pyx_t_34); __Pyx_GIVEREF(__pyx_t_35); - PyTuple_SET_ITEM(__pyx_t_2, 33, __pyx_t_35); + PyTuple_SET_ITEM(__pyx_t_1, 33, __pyx_t_35); __Pyx_GIVEREF(__pyx_t_36); - PyTuple_SET_ITEM(__pyx_t_2, 34, __pyx_t_36); + PyTuple_SET_ITEM(__pyx_t_1, 34, __pyx_t_36); __Pyx_GIVEREF(__pyx_t_37); - PyTuple_SET_ITEM(__pyx_t_2, 35, __pyx_t_37); + PyTuple_SET_ITEM(__pyx_t_1, 35, __pyx_t_37); __Pyx_GIVEREF(__pyx_t_38); - PyTuple_SET_ITEM(__pyx_t_2, 36, __pyx_t_38); + PyTuple_SET_ITEM(__pyx_t_1, 36, __pyx_t_38); __Pyx_GIVEREF(__pyx_t_39); - PyTuple_SET_ITEM(__pyx_t_2, 37, __pyx_t_39); + PyTuple_SET_ITEM(__pyx_t_1, 37, __pyx_t_39); __Pyx_GIVEREF(__pyx_t_40); - PyTuple_SET_ITEM(__pyx_t_2, 38, __pyx_t_40); + PyTuple_SET_ITEM(__pyx_t_1, 38, __pyx_t_40); __Pyx_GIVEREF(__pyx_t_41); - PyTuple_SET_ITEM(__pyx_t_2, 39, __pyx_t_41); + PyTuple_SET_ITEM(__pyx_t_1, 39, __pyx_t_41); __Pyx_GIVEREF(__pyx_t_42); - PyTuple_SET_ITEM(__pyx_t_2, 40, __pyx_t_42); + PyTuple_SET_ITEM(__pyx_t_1, 40, __pyx_t_42); __Pyx_GIVEREF(__pyx_t_43); - PyTuple_SET_ITEM(__pyx_t_2, 41, __pyx_t_43); + PyTuple_SET_ITEM(__pyx_t_1, 41, __pyx_t_43); __Pyx_GIVEREF(__pyx_t_44); - PyTuple_SET_ITEM(__pyx_t_2, 42, __pyx_t_44); + PyTuple_SET_ITEM(__pyx_t_1, 42, __pyx_t_44); __Pyx_GIVEREF(__pyx_t_45); - PyTuple_SET_ITEM(__pyx_t_2, 43, __pyx_t_45); + PyTuple_SET_ITEM(__pyx_t_1, 43, __pyx_t_45); __Pyx_GIVEREF(__pyx_t_46); - PyTuple_SET_ITEM(__pyx_t_2, 44, __pyx_t_46); + PyTuple_SET_ITEM(__pyx_t_1, 44, __pyx_t_46); __Pyx_GIVEREF(__pyx_t_47); - PyTuple_SET_ITEM(__pyx_t_2, 45, __pyx_t_47); + PyTuple_SET_ITEM(__pyx_t_1, 45, __pyx_t_47); __Pyx_GIVEREF(__pyx_t_48); - PyTuple_SET_ITEM(__pyx_t_2, 46, __pyx_t_48); + PyTuple_SET_ITEM(__pyx_t_1, 46, __pyx_t_48); __Pyx_GIVEREF(__pyx_t_49); - PyTuple_SET_ITEM(__pyx_t_2, 47, __pyx_t_49); + PyTuple_SET_ITEM(__pyx_t_1, 47, __pyx_t_49); __Pyx_GIVEREF(__pyx_t_50); - PyTuple_SET_ITEM(__pyx_t_2, 48, __pyx_t_50); + PyTuple_SET_ITEM(__pyx_t_1, 48, __pyx_t_50); __Pyx_GIVEREF(__pyx_t_51); - PyTuple_SET_ITEM(__pyx_t_2, 49, __pyx_t_51); + PyTuple_SET_ITEM(__pyx_t_1, 49, __pyx_t_51); __Pyx_GIVEREF(__pyx_t_52); - PyTuple_SET_ITEM(__pyx_t_2, 50, __pyx_t_52); + PyTuple_SET_ITEM(__pyx_t_1, 50, __pyx_t_52); __Pyx_GIVEREF(__pyx_t_53); - PyTuple_SET_ITEM(__pyx_t_2, 51, __pyx_t_53); + PyTuple_SET_ITEM(__pyx_t_1, 51, __pyx_t_53); __Pyx_GIVEREF(__pyx_t_54); - PyTuple_SET_ITEM(__pyx_t_2, 52, __pyx_t_54); + PyTuple_SET_ITEM(__pyx_t_1, 52, __pyx_t_54); __Pyx_GIVEREF(__pyx_t_55); - PyTuple_SET_ITEM(__pyx_t_2, 53, __pyx_t_55); + PyTuple_SET_ITEM(__pyx_t_1, 53, __pyx_t_55); __Pyx_GIVEREF(__pyx_t_56); - PyTuple_SET_ITEM(__pyx_t_2, 54, __pyx_t_56); + PyTuple_SET_ITEM(__pyx_t_1, 54, __pyx_t_56); __Pyx_GIVEREF(__pyx_t_57); - PyTuple_SET_ITEM(__pyx_t_2, 55, __pyx_t_57); + PyTuple_SET_ITEM(__pyx_t_1, 55, __pyx_t_57); __Pyx_GIVEREF(__pyx_t_58); - PyTuple_SET_ITEM(__pyx_t_2, 56, __pyx_t_58); + PyTuple_SET_ITEM(__pyx_t_1, 56, __pyx_t_58); __Pyx_GIVEREF(__pyx_t_59); - PyTuple_SET_ITEM(__pyx_t_2, 57, __pyx_t_59); + PyTuple_SET_ITEM(__pyx_t_1, 57, __pyx_t_59); __Pyx_GIVEREF(__pyx_t_60); - PyTuple_SET_ITEM(__pyx_t_2, 58, __pyx_t_60); + PyTuple_SET_ITEM(__pyx_t_1, 58, __pyx_t_60); __Pyx_GIVEREF(__pyx_t_61); - PyTuple_SET_ITEM(__pyx_t_2, 59, __pyx_t_61); + PyTuple_SET_ITEM(__pyx_t_1, 59, __pyx_t_61); __Pyx_GIVEREF(__pyx_t_62); - PyTuple_SET_ITEM(__pyx_t_2, 60, __pyx_t_62); + PyTuple_SET_ITEM(__pyx_t_1, 60, __pyx_t_62); __Pyx_GIVEREF(__pyx_t_63); - PyTuple_SET_ITEM(__pyx_t_2, 61, __pyx_t_63); + PyTuple_SET_ITEM(__pyx_t_1, 61, __pyx_t_63); __Pyx_GIVEREF(__pyx_t_64); - PyTuple_SET_ITEM(__pyx_t_2, 62, __pyx_t_64); + PyTuple_SET_ITEM(__pyx_t_1, 62, __pyx_t_64); __Pyx_GIVEREF(__pyx_t_65); - PyTuple_SET_ITEM(__pyx_t_2, 63, __pyx_t_65); + PyTuple_SET_ITEM(__pyx_t_1, 63, __pyx_t_65); __Pyx_GIVEREF(__pyx_t_66); - PyTuple_SET_ITEM(__pyx_t_2, 64, __pyx_t_66); + PyTuple_SET_ITEM(__pyx_t_1, 64, __pyx_t_66); __Pyx_GIVEREF(__pyx_t_67); - PyTuple_SET_ITEM(__pyx_t_2, 65, __pyx_t_67); + PyTuple_SET_ITEM(__pyx_t_1, 65, __pyx_t_67); __Pyx_GIVEREF(__pyx_t_68); - PyTuple_SET_ITEM(__pyx_t_2, 66, __pyx_t_68); + PyTuple_SET_ITEM(__pyx_t_1, 66, __pyx_t_68); __Pyx_GIVEREF(__pyx_t_69); - PyTuple_SET_ITEM(__pyx_t_2, 67, __pyx_t_69); + PyTuple_SET_ITEM(__pyx_t_1, 67, __pyx_t_69); __Pyx_GIVEREF(__pyx_t_70); - PyTuple_SET_ITEM(__pyx_t_2, 68, __pyx_t_70); + PyTuple_SET_ITEM(__pyx_t_1, 68, __pyx_t_70); __Pyx_GIVEREF(__pyx_t_71); - PyTuple_SET_ITEM(__pyx_t_2, 69, __pyx_t_71); + PyTuple_SET_ITEM(__pyx_t_1, 69, __pyx_t_71); __Pyx_GIVEREF(__pyx_t_72); - PyTuple_SET_ITEM(__pyx_t_2, 70, __pyx_t_72); + PyTuple_SET_ITEM(__pyx_t_1, 70, __pyx_t_72); __Pyx_GIVEREF(__pyx_t_73); - PyTuple_SET_ITEM(__pyx_t_2, 71, __pyx_t_73); + PyTuple_SET_ITEM(__pyx_t_1, 71, __pyx_t_73); __Pyx_GIVEREF(__pyx_t_74); - PyTuple_SET_ITEM(__pyx_t_2, 72, __pyx_t_74); + PyTuple_SET_ITEM(__pyx_t_1, 72, __pyx_t_74); __Pyx_GIVEREF(__pyx_t_75); - PyTuple_SET_ITEM(__pyx_t_2, 73, __pyx_t_75); + PyTuple_SET_ITEM(__pyx_t_1, 73, __pyx_t_75); __Pyx_GIVEREF(__pyx_t_76); - PyTuple_SET_ITEM(__pyx_t_2, 74, __pyx_t_76); + PyTuple_SET_ITEM(__pyx_t_1, 74, __pyx_t_76); __Pyx_GIVEREF(__pyx_t_77); - PyTuple_SET_ITEM(__pyx_t_2, 75, __pyx_t_77); + PyTuple_SET_ITEM(__pyx_t_1, 75, __pyx_t_77); __Pyx_GIVEREF(__pyx_t_78); - PyTuple_SET_ITEM(__pyx_t_2, 76, __pyx_t_78); + PyTuple_SET_ITEM(__pyx_t_1, 76, __pyx_t_78); __Pyx_GIVEREF(__pyx_t_79); - PyTuple_SET_ITEM(__pyx_t_2, 77, __pyx_t_79); - __pyx_t_1 = 0; + PyTuple_SET_ITEM(__pyx_t_1, 77, __pyx_t_79); + __pyx_t_2 = 0; __pyx_t_3 = 0; __pyx_t_4 = 0; __pyx_t_5 = 0; @@ -19620,9 +19259,9 @@ if (!__Pyx_RefNanny) { __pyx_t_78 = 0; __pyx_t_79 = 0; __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_headers); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_headers, ((PyObject*)__pyx_t_2)); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_headers, ((PyObject*)__pyx_t_1)); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":40 * char* PyByteArray_AsString(object) @@ -19631,7 +19270,7 @@ if (!__Pyx_RefNanny) { * 'RawRequestMessage', 'RawResponseMessage') * */ - if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_tuple__14) < 0) __PYX_ERR(0, 40, __pyx_L1_error) + if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_tuple__12) < 0) __PYX_ERR(0, 40, __pyx_L1_error) /* "aiohttp/_http_parser.pyx":43 * 'RawRequestMessage', 'RawResponseMessage') @@ -19640,12 +19279,12 @@ if (!__Pyx_RefNanny) { * cdef object URL_build = URL.build * cdef object CIMultiDict = _CIMultiDict */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_URL_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_URL_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_URL); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_URL, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_URL, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":44 * @@ -19654,12 +19293,12 @@ if (!__Pyx_RefNanny) { * cdef object CIMultiDict = _CIMultiDict * cdef object CIMultiDictProxy = _CIMultiDictProxy */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_7aiohttp_12_http_parser_URL, __pyx_n_s_build); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_7aiohttp_12_http_parser_URL, __pyx_n_s_build); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_URL_build); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_URL_build, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_URL_build, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":45 * cdef object URL = _URL @@ -19668,12 +19307,12 @@ if (!__Pyx_RefNanny) { * cdef object CIMultiDictProxy = _CIMultiDictProxy * cdef object HttpVersion = _HttpVersion */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_CIMultiDict_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 45, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_CIMultiDict_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_CIMultiDict); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CIMultiDict, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CIMultiDict, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":46 * cdef object URL_build = URL.build @@ -19682,12 +19321,12 @@ if (!__Pyx_RefNanny) { * cdef object HttpVersion = _HttpVersion * cdef object HttpVersion10 = _HttpVersion10 */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_CIMultiDictProxy_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 46, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_CIMultiDictProxy_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 46, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":47 * cdef object CIMultiDict = _CIMultiDict @@ -19696,12 +19335,12 @@ if (!__Pyx_RefNanny) { * cdef object HttpVersion10 = _HttpVersion10 * cdef object HttpVersion11 = _HttpVersion11 */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_HttpVersion_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 47, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_HttpVersion_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 47, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":48 * cdef object CIMultiDictProxy = _CIMultiDictProxy @@ -19710,12 +19349,12 @@ if (!__Pyx_RefNanny) { * cdef object HttpVersion11 = _HttpVersion11 * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_HttpVersion10_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 48, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_HttpVersion10_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 48, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion10); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion10, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion10, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":49 * cdef object HttpVersion = _HttpVersion @@ -19724,12 +19363,12 @@ if (!__Pyx_RefNanny) { * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_HttpVersion11_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 49, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_HttpVersion11_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 49, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion11); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion11, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion11, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":50 * cdef object HttpVersion10 = _HttpVersion10 @@ -19738,11 +19377,11 @@ if (!__Pyx_RefNanny) { * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 50, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_79 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_SEC_WEBSOCKET_KEY1); if (unlikely(!__pyx_t_79)) __PYX_ERR(0, 50, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 50, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_79 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_KEY1); if (unlikely(!__pyx_t_79)) __PYX_ERR(0, 50, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_79); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1); __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1, __pyx_t_79); __Pyx_GIVEREF(__pyx_t_79); @@ -19755,15 +19394,15 @@ if (!__Pyx_RefNanny) { * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD * cdef object StreamReader = _StreamReader */ - __pyx_t_79 = __Pyx_GetModuleGlobalName(__pyx_n_s_hdrs); if (unlikely(!__pyx_t_79)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_79, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_79)) __PYX_ERR(0, 51, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_79); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_79, __pyx_n_s_CONTENT_ENCODING); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 51, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_79, __pyx_n_s_CONTENT_ENCODING); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_79); __pyx_t_79 = 0; __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":52 * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 @@ -19772,12 +19411,12 @@ if (!__Pyx_RefNanny) { * cdef object StreamReader = _StreamReader * cdef object DeflateBuffer = _DeflateBuffer */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_EMPTY_PAYLOAD_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 52, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_EMPTY_PAYLOAD_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 52, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":53 * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING @@ -19786,12 +19425,12 @@ if (!__Pyx_RefNanny) { * cdef object DeflateBuffer = _DeflateBuffer * */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_StreamReader_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 53, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_StreamReader_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 53, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_StreamReader); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_StreamReader, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_StreamReader, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":54 * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD @@ -19800,12 +19439,12 @@ if (!__Pyx_RefNanny) { * * */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_DeflateBuffer_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 54, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DeflateBuffer_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 54, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_DeflateBuffer); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_DeflateBuffer, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_DeflateBuffer, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":68 * DEF METHODS_COUNT = 34; @@ -19814,12 +19453,12 @@ if (!__Pyx_RefNanny) { * * for i in range(METHODS_COUNT): */ - __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 68, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser__http_method); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser__http_method, ((PyObject*)__pyx_t_2)); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser__http_method, ((PyObject*)__pyx_t_1)); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":70 * cdef list _http_method = [] @@ -19829,10 +19468,10 @@ if (!__Pyx_RefNanny) { * cparser.http_method_str(<cparser.http_method> i).decode('ascii')) */ for (__pyx_t_80 = 0; __pyx_t_80 < 34; __pyx_t_80+=1) { - __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_t_80); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_i, __pyx_t_2) < 0) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_t_80); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_i, __pyx_t_1) < 0) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":71 * @@ -19853,13 +19492,13 @@ if (!__Pyx_RefNanny) { * * */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_i); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 72, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_81 = ((enum http_method)__Pyx_PyInt_As_enum__http_method(__pyx_t_2)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 72, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_i); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 72, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_81 = ((enum http_method)__Pyx_PyInt_As_enum__http_method(__pyx_t_1)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 72, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_82 = http_method_str(((enum http_method)__pyx_t_81)); - __pyx_t_2 = __Pyx_decode_c_string(__pyx_t_82, 0, strlen(__pyx_t_82), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 72, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_82, 0, strlen(__pyx_t_82), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 72, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); /* "aiohttp/_http_parser.pyx":71 * @@ -19868,8 +19507,8 @@ if (!__Pyx_RefNanny) { * cparser.http_method_str(<cparser.http_method> i).decode('ascii')) * */ - __pyx_t_83 = __Pyx_PyList_Append(__pyx_v_7aiohttp_12_http_parser__http_method, __pyx_t_2); if (unlikely(__pyx_t_83 == ((int)-1))) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_83 = __Pyx_PyList_Append(__pyx_v_7aiohttp_12_http_parser__http_method, __pyx_t_1); if (unlikely(__pyx_t_83 == ((int)-1))) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } /* "aiohttp/_http_parser.pyx":755 @@ -19879,42 +19518,42 @@ if (!__Pyx_RefNanny) { * cdef: * Py_buffer py_buf */ - __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_1parse_url, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 755, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_parse_url, __pyx_t_2) < 0) __PYX_ERR(0, 755, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_1parse_url, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 755, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_parse_url, __pyx_t_1) < 0) __PYX_ERR(0, 755, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "(tree fragment)":1 * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * if __pyx_checksum != 0x1408252: - * from pickle import PickleError as __pyx_PickleError + * cdef object __pyx_PickleError + * cdef object __pyx_result */ - __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_RawRequestMessage, __pyx_t_2) < 0) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_RawRequestMessage, __pyx_t_1) < 0) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "(tree fragment)":9 + /* "(tree fragment)":11 * __pyx_unpickle_RawRequestMessage__set_state(<RawRequestMessage> __pyx_result, __pyx_state) * return __pyx_result * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): */ - __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_RawResponseMessag, __pyx_t_2) < 0) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_RawResponseMessag, __pyx_t_1) < 0) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_http_parser.pyx":1 * #cython: language_level=3 # <<<<<<<<<<<<<< * # * # Based on https://github.com/MagicStack/httptools */ - __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /*--- Wrapped vars code ---*/ @@ -20001,9 +19640,9 @@ if (!__Pyx_RefNanny) { __Pyx_XDECREF(__pyx_t_79); if (__pyx_m) { if (__pyx_d) { - __Pyx_AddTraceback("init aiohttp._http_parser", 0, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("init aiohttp._http_parser", __pyx_clineno, __pyx_lineno, __pyx_filename); } - Py_DECREF(__pyx_m); __pyx_m = 0; + Py_CLEAR(__pyx_m); } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, "init aiohttp._http_parser"); } @@ -20024,9 +19663,9 @@ if (!__Pyx_RefNanny) { static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { PyObject *m = NULL, *p = NULL; void *r = NULL; - m = PyImport_ImportModule((char *)modname); + m = PyImport_ImportModule(modname); if (!m) goto end; - p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); + p = PyObject_GetAttrString(m, "RefNannyAPI"); if (!p) goto end; r = PyLong_AsVoidPtr(p); end: @@ -20080,7 +19719,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_ if (wraparound & unlikely(i < 0)) { wrapped_i += PyList_GET_SIZE(o); } - if ((!boundscheck) || likely((0 <= wrapped_i) & (wrapped_i < PyList_GET_SIZE(o)))) { + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { PyObject *r = PyList_GET_ITEM(o, wrapped_i); Py_INCREF(r); return r; @@ -20098,7 +19737,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize if (wraparound & unlikely(i < 0)) { wrapped_i += PyTuple_GET_SIZE(o); } - if ((!boundscheck) || likely((0 <= wrapped_i) & (wrapped_i < PyTuple_GET_SIZE(o)))) { + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); Py_INCREF(r); return r; @@ -20114,7 +19753,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS if (is_list || PyList_CheckExact(o)) { Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) { + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { PyObject *r = PyList_GET_ITEM(o, n); Py_INCREF(r); return r; @@ -20122,7 +19761,7 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, } else if (PyTuple_CheckExact(o)) { Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) { + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, n); Py_INCREF(r); return r; @@ -20445,10 +20084,15 @@ static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { value = PyDict_GetItemWithError(d, key); if (unlikely(!value)) { if (!PyErr_Occurred()) { - PyObject* args = PyTuple_Pack(1, key); - if (likely(args)) - PyErr_SetObject(PyExc_KeyError, args); - Py_XDECREF(args); + if (unlikely(PyTuple_Check(key))) { + PyObject* args = PyTuple_Pack(1, key); + if (likely(args)) { + PyErr_SetObject(PyExc_KeyError, args); + Py_DECREF(args); + } + } else { + PyErr_SetObject(PyExc_KeyError, key); + } } return NULL; } @@ -20535,35 +20179,42 @@ static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject } /* GetModuleGlobalName */ -static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ PyObject *result; #if !CYTHON_AVOID_BORROWED_REFS #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) if (likely(result)) { - Py_INCREF(result); + return __Pyx_NewRef(result); } else if (unlikely(PyErr_Occurred())) { - result = NULL; - } else { + return NULL; + } #else result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) if (likely(result)) { - Py_INCREF(result); - } else { + return __Pyx_NewRef(result); + } #endif #else result = PyObject_GetItem(__pyx_d, name); - if (!result) { - PyErr_Clear(); -#endif - result = __Pyx_GetBuiltinName(name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); } - return result; + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); } /* PyFunctionFastCall */ - #if CYTHON_FAST_PYCALL -#include "frameobject.h" +#if CYTHON_FAST_PYCALL static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, PyObject *globals) { PyFrameObject *f; @@ -20581,7 +20232,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args if (f == NULL) { return NULL; } - fastlocals = f->f_localsplus; + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); for (i = 0; i < na; i++) { Py_INCREF(*args); fastlocals[i] = *args++; @@ -20682,7 +20333,7 @@ done: #endif /* PyObjectCall */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { PyObject *result; ternaryfunc call = func->ob_type->tp_call; @@ -20702,7 +20353,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg #endif /* PyObjectCallMethO */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { PyObject *self, *result; PyCFunction cfunc; @@ -20722,7 +20373,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject #endif /* PyObjectCallNoArg */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { #if CYTHON_FAST_PYCALL if (PyFunction_Check(func)) { @@ -20730,10 +20381,11 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { } #endif #ifdef __Pyx_CyFunction_USED - if (likely(PyCFunction_Check(func) || __Pyx_TypeCheck(func, __pyx_CyFunctionType))) { + if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) #else - if (likely(PyCFunction_Check(func))) { + if (likely(PyCFunction_Check(func))) #endif + { if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { return __Pyx_PyObject_CallMethO(func, NULL); } @@ -20743,14 +20395,14 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { #endif /* PyCFunctionFastCall */ - #if CYTHON_FAST_PYCCALL +#if CYTHON_FAST_PYCCALL static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { PyCFunctionObject *func = (PyCFunctionObject*)func_obj; PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); int flags = PyCFunction_GET_FLAGS(func); assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); assert(nargs >= 0); assert(nargs == 0 || args != NULL); /* _PyCFunction_FastCallDict() must not be called with an exception set, @@ -20758,15 +20410,15 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P caller loses its exception */ assert(!PyErr_Occurred()); if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)meth)) (self, args, nargs, NULL); + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); } else { - return (*((__Pyx_PyCFunctionFast)meth)) (self, args, nargs); + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); } } #endif /* PyObjectCallOneArg */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { PyObject *result; PyObject *args = PyTuple_New(1); @@ -20805,8 +20457,37 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObjec } #endif +/* PyObjectCall2Args */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args, *result = NULL; + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyFunction_FastCall(function, args, 2); + } + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyCFunction_FastCall(function, args, 2); + } + #endif + args = PyTuple_New(2); + if (unlikely(!args)) goto done; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + Py_INCREF(function); + result = __Pyx_PyObject_Call(function, args, NULL); + Py_DECREF(args); + Py_DECREF(function); +done: + return result; +} + /* RaiseException */ - #if PY_MAJOR_VERSION < 3 +#if PY_MAJOR_VERSION < 3 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, CYTHON_UNUSED PyObject *cause) { __Pyx_PyThreadState_declare @@ -20965,7 +20646,7 @@ bad: #endif /* BytesEquals */ - static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { #if CYTHON_COMPILING_IN_PYPY return PyObject_RichCompareBool(s1, s2, equals); #else @@ -21012,7 +20693,7 @@ bad: } /* UnicodeEquals */ - static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { #if CYTHON_COMPILING_IN_PYPY return PyObject_RichCompareBool(s1, s2, equals); #else @@ -21114,7 +20795,7 @@ return_ne: } /* SliceObject */ - static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj, +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop, PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice, int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) { @@ -21211,11 +20892,12 @@ bad: } /* GetException */ - #if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) #else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) #endif +{ PyObject *local_type, *local_value, *local_tb; #if CYTHON_FAST_THREAD_STATE PyObject *tmp_type, *tmp_value, *tmp_tb; @@ -21248,13 +20930,16 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) *value = local_value; *tb = local_tb; #if CYTHON_FAST_THREAD_STATE - #if PY_VERSION_HEX >= 0x030700A3 - tmp_type = tstate->exc_state.exc_type; - tmp_value = tstate->exc_state.exc_value; - tmp_tb = tstate->exc_state.exc_traceback; - tstate->exc_state.exc_type = local_type; - tstate->exc_state.exc_value = local_value; - tstate->exc_state.exc_traceback = local_tb; + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + } #else tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; @@ -21281,16 +20966,17 @@ bad: } /* SwapException */ - #if CYTHON_FAST_THREAD_STATE +#if CYTHON_FAST_THREAD_STATE static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030700A3 - tmp_type = tstate->exc_state.exc_type; - tmp_value = tstate->exc_state.exc_value; - tmp_tb = tstate->exc_state.exc_traceback; - tstate->exc_state.exc_type = *type; - tstate->exc_state.exc_value = *value; - tstate->exc_state.exc_traceback = *tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; #else tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; @@ -21314,13 +21000,29 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, } #endif +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + /* SaveResetException */ - #if CYTHON_FAST_THREAD_STATE +#if CYTHON_FAST_THREAD_STATE static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if PY_VERSION_HEX >= 0x030700A3 - *type = tstate->exc_state.exc_type; - *value = tstate->exc_state.exc_value; - *tb = tstate->exc_state.exc_traceback; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; #else *type = tstate->exc_type; *value = tstate->exc_value; @@ -21332,13 +21034,14 @@ static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject * } static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030700A3 - tmp_type = tstate->exc_state.exc_type; - tmp_value = tstate->exc_state.exc_value; - tmp_tb = tstate->exc_state.exc_traceback; - tstate->exc_state.exc_type = type; - tstate->exc_state.exc_value = value; - tstate->exc_state.exc_traceback = tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; #else tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; @@ -21354,7 +21057,7 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject #endif /* decode_c_string */ - static CYTHON_INLINE PyObject* __Pyx_decode_c_string( +static CYTHON_INLINE PyObject* __Pyx_decode_c_string( const char* cstring, Py_ssize_t start, Py_ssize_t stop, const char* encoding, const char* errors, PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { @@ -21387,7 +21090,7 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject } /* UnpackUnboundCMethod */ - static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { +static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { PyObject *method; method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); if (unlikely(!method)) @@ -21400,14 +21103,14 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject { PyMethodDescrObject *descr = (PyMethodDescrObject*) method; target->func = descr->d_method->ml_meth; - target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST); + target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); } #endif return 0; } /* CallUnboundCMethod1 */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg) { if (likely(cfunc->func)) { int flag = cfunc->flag; @@ -21415,12 +21118,12 @@ static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* return (*(cfunc->func))(self, arg); } else if (PY_VERSION_HEX >= 0x030600B1 && flag == METH_FASTCALL) { if (PY_VERSION_HEX >= 0x030700A0) { - return (*(__Pyx_PyCFunctionFast)cfunc->func)(self, &arg, 1); + return (*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)cfunc->func)(self, &arg, 1); } else { - return (*(__Pyx_PyCFunctionFastWithKeywords)cfunc->func)(self, &arg, 1, NULL); + return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL); } } else if (PY_VERSION_HEX >= 0x030700A0 && flag == (METH_FASTCALL | METH_KEYWORDS)) { - return (*(__Pyx_PyCFunctionFastWithKeywords)cfunc->func)(self, &arg, 1, NULL); + return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL); } } return __Pyx__CallUnboundCMethod1(cfunc, self, arg); @@ -21436,7 +21139,7 @@ static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObje Py_INCREF(arg); PyTuple_SET_ITEM(args, 0, arg); if (cfunc->flag & METH_KEYWORDS) - result = (*(PyCFunctionWithKeywords)cfunc->func)(self, args, NULL); + result = (*(PyCFunctionWithKeywords)(void*)(PyCFunction)cfunc->func)(self, args, NULL); else result = (*cfunc->func)(self, args); } else { @@ -21459,7 +21162,7 @@ bad: } /* Import */ - static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { PyObject *empty_list = 0; PyObject *module = 0; PyObject *global_dict = 0; @@ -21506,7 +21209,7 @@ bad: if (!py_level) goto bad; module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, NULL); + name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); Py_DECREF(py_level); #else module = PyImport_ImportModuleLevelObject( @@ -21524,7 +21227,7 @@ bad: } /* ImportFrom */ - static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Format(PyExc_ImportError, @@ -21538,7 +21241,7 @@ bad: } /* HasAttr */ - static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { PyObject *r; if (unlikely(!__Pyx_PyBaseString_Check(n))) { PyErr_SetString(PyExc_TypeError, @@ -21556,7 +21259,7 @@ bad: } /* PyObject_GenericGetAttrNoDict */ - #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { PyErr_Format(PyExc_AttributeError, #if PY_MAJOR_VERSION >= 3 @@ -21596,7 +21299,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj #endif /* PyObject_GenericGetAttr */ - #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { return PyObject_GenericGetAttr(obj, attr_name); @@ -21606,7 +21309,7 @@ static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_nam #endif /* SetupReduce */ - static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { +static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { int ret; PyObject *name_attr; name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name); @@ -21682,7 +21385,7 @@ GOOD: } /* SetVTable */ - static int __Pyx_SetVtable(PyObject *dict, void *vtable) { +static int __Pyx_SetVtable(PyObject *dict, void *vtable) { #if PY_VERSION_HEX >= 0x02070000 PyObject *ob = PyCapsule_New(vtable, 0, 0); #else @@ -21699,9 +21402,70 @@ bad: return -1; } +/* TypeImport */ +#ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, + size_t size, enum __Pyx_ImportType_CheckSize check_size) +{ + PyObject *result = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + result = PyObject_GetAttrString(module, class_name); + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if ((size_t)basicsize < size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(result); + return NULL; +} +#endif + /* CLineInTraceback */ - #ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) { +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { PyObject *use_cline; PyObject *ptype, *pvalue, *ptraceback; #if CYTHON_COMPILING_IN_CPYTHON @@ -21714,7 +21478,9 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li #if CYTHON_COMPILING_IN_CPYTHON cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); if (likely(cython_runtime_dict)) { - use_cline = __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback); + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) } else #endif { @@ -21731,7 +21497,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li c_line = 0; PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); } - else if (PyObject_Not(use_cline) != 0) { + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { c_line = 0; } __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); @@ -21740,7 +21506,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li #endif /* CodeObjectCache */ - static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { int start = 0, mid = 0, end = count - 1; if (end >= 0 && code_line > entries[end].code_line) { return count; @@ -21820,7 +21586,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { } /* AddTraceback */ - #include "compile.h" +#include "compile.h" #include "frameobject.h" #include "traceback.h" static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( @@ -21905,8 +21671,8 @@ bad: } /* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { - const int neg_one = (int) -1, const_zero = (int) 0; +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(int) < sizeof(long)) { @@ -21936,7 +21702,7 @@ bad: } /* CIntFromPyVerify */ - #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) #define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) @@ -21958,8 +21724,8 @@ bad: } /* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) { - const unsigned int neg_one = (unsigned int) -1, const_zero = (unsigned int) 0; +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) { + const unsigned int neg_one = (unsigned int) ((unsigned int) 0 - (unsigned int) 1), const_zero = (unsigned int) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(unsigned int) < sizeof(long)) { @@ -21989,8 +21755,8 @@ bad: } /* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value) { - const unsigned short neg_one = (unsigned short) -1, const_zero = (unsigned short) 0; +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value) { + const unsigned short neg_one = (unsigned short) ((unsigned short) 0 - (unsigned short) 1), const_zero = (unsigned short) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(unsigned short) < sizeof(long)) { @@ -22020,8 +21786,8 @@ bad: } /* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) -1, const_zero = (long) 0; +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(long) < sizeof(long)) { @@ -22051,8 +21817,8 @@ bad: } /* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint16_t(uint16_t value) { - const uint16_t neg_one = (uint16_t) -1, const_zero = (uint16_t) 0; +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint16_t(uint16_t value) { + const uint16_t neg_one = (uint16_t) ((uint16_t) 0 - (uint16_t) 1), const_zero = (uint16_t) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(uint16_t) < sizeof(long)) { @@ -22082,8 +21848,8 @@ bad: } /* CIntFromPy */ - static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) -1, const_zero = (int) 0; +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -22271,8 +22037,8 @@ raise_neg_overflow: } /* CIntFromPy */ - static CYTHON_INLINE enum http_method __Pyx_PyInt_As_enum__http_method(PyObject *x) { - const enum http_method neg_one = (enum http_method) -1, const_zero = (enum http_method) 0; +static CYTHON_INLINE enum http_method __Pyx_PyInt_As_enum__http_method(PyObject *x) { + const enum http_method neg_one = (enum http_method) ((enum http_method) 0 - (enum http_method) 1), const_zero = (enum http_method) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -22460,8 +22226,8 @@ raise_neg_overflow: } /* CIntFromPy */ - static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *x) { - const size_t neg_one = (size_t) -1, const_zero = (size_t) 0; +static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *x) { + const size_t neg_one = (size_t) ((size_t) 0 - (size_t) 1), const_zero = (size_t) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -22649,8 +22415,8 @@ raise_neg_overflow: } /* CIntFromPy */ - static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) -1, const_zero = (long) 0; +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -22838,7 +22604,7 @@ raise_neg_overflow: } /* FastTypeChecks */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { while (a) { a = a->tp_base; @@ -22938,7 +22704,7 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj #endif /* FetchCommonType */ - static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { PyObject* fake_module; PyTypeObject* cached_type = NULL; fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI); @@ -22976,59 +22742,122 @@ bad: goto done; } -/* PyObjectCallMethod1 */ - static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { - PyObject *result = NULL; -#if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(method))) { - PyObject *self = PyMethod_GET_SELF(method); - if (likely(self)) { - PyObject *args; - PyObject *function = PyMethod_GET_FUNCTION(method); - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(function)) { - PyObject *args[2] = {self, arg}; - result = __Pyx_PyFunction_FastCall(function, args, 2); - goto done; - } - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(function)) { - PyObject *args[2] = {self, arg}; - result = __Pyx_PyCFunction_FastCall(function, args, 2); - goto done; +/* PyObjectGetMethod */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; } - #endif - args = PyTuple_New(2); - if (unlikely(!args)) goto done; - Py_INCREF(self); - PyTuple_SET_ITEM(args, 0, self); - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 1, arg); - Py_INCREF(function); - result = __Pyx_PyObject_Call(function, args, NULL); - Py_DECREF(args); - Py_DECREF(function); - return result; } } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (descr != NULL) { + *method = descr; + return 0; + } + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); +#else + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(name)); #endif - result = __Pyx_PyObject_CallOneArg(method, arg); - goto done; -done: + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} + +/* PyObjectCallMethod1 */ +static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { + PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); + Py_DECREF(method); return result; } static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { - PyObject *method, *result; - method = __Pyx_PyObject_GetAttrStr(obj, method_name); + PyObject *method = NULL, *result; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_Call2Args(method, obj, arg); + Py_DECREF(method); + return result; + } if (unlikely(!method)) return NULL; - result = __Pyx__PyObject_CallMethod1(method, arg); - Py_DECREF(method); - return result; + return __Pyx__PyObject_CallMethod1(method, arg); } /* CoroutineBase */ - #include <structmember.h> +#include <structmember.h> #include <frameobject.h> #define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom) static int __Pyx_PyGen__FetchStopIterationValue(CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject **pvalue) { @@ -23111,21 +22940,22 @@ static int __Pyx_PyGen__FetchStopIterationValue(CYTHON_UNUSED PyThreadState *__p return 0; } static CYTHON_INLINE -void __Pyx_Coroutine_ExceptionClear(__pyx_CoroutineObject *self) { - PyObject *exc_type = self->exc_type; - PyObject *exc_value = self->exc_value; - PyObject *exc_traceback = self->exc_traceback; - self->exc_type = NULL; - self->exc_value = NULL; - self->exc_traceback = NULL; - Py_XDECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_traceback); +void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) { + PyObject *t, *v, *tb; + t = exc_state->exc_type; + v = exc_state->exc_value; + tb = exc_state->exc_traceback; + exc_state->exc_type = NULL; + exc_state->exc_value = NULL; + exc_state->exc_traceback = NULL; + Py_XDECREF(t); + Py_XDECREF(v); + Py_XDECREF(tb); } #define __Pyx_Coroutine_AlreadyRunningError(gen) (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL) static void __Pyx__Coroutine_AlreadyRunningError(CYTHON_UNUSED __pyx_CoroutineObject *gen) { const char *msg; - if (0) { + if ((0)) { #ifdef __Pyx_Coroutine_USED } else if (__Pyx_Coroutine_Check((PyObject*)gen)) { msg = "coroutine already executing"; @@ -23142,7 +22972,7 @@ static void __Pyx__Coroutine_AlreadyRunningError(CYTHON_UNUSED __pyx_CoroutineOb #define __Pyx_Coroutine_NotStartedError(gen) (__Pyx__Coroutine_NotStartedError(gen), (PyObject*)NULL) static void __Pyx__Coroutine_NotStartedError(CYTHON_UNUSED PyObject *gen) { const char *msg; - if (0) { + if ((0)) { #ifdef __Pyx_Coroutine_USED } else if (__Pyx_Coroutine_Check(gen)) { msg = "can't send non-None value to a just-started coroutine"; @@ -23176,6 +23006,7 @@ static PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, int closing) { __Pyx_PyThreadState_declare PyThreadState *tstate; + __Pyx_ExcInfoStruct *exc_state; PyObject *retval; assert(!self->is_running); if (unlikely(self->resume_label == 0)) { @@ -23192,33 +23023,47 @@ PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, i #else tstate = __Pyx_PyThreadState_Current; #endif - if (self->exc_type) { -#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON -#else - if (self->exc_traceback) { - PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback; + exc_state = &self->gi_exc_state; + if (exc_state->exc_type) { + #if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON + #else + if (exc_state->exc_traceback) { + PyTracebackObject *tb = (PyTracebackObject *) exc_state->exc_traceback; PyFrameObject *f = tb->tb_frame; Py_XINCREF(tstate->frame); assert(f->f_back == NULL); f->f_back = tstate->frame; } -#endif - __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, - &self->exc_traceback); + #endif + } +#if CYTHON_USE_EXC_INFO_STACK + exc_state->previous_item = tstate->exc_info; + tstate->exc_info = exc_state; +#else + if (exc_state->exc_type) { + __Pyx_ExceptionSwap(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); } else { - __Pyx_Coroutine_ExceptionClear(self); - __Pyx_ExceptionSave(&self->exc_type, &self->exc_value, &self->exc_traceback); + __Pyx_Coroutine_ExceptionClear(exc_state); + __Pyx_ExceptionSave(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); } +#endif self->is_running = 1; retval = self->body((PyObject *) self, tstate, value); self->is_running = 0; +#if CYTHON_USE_EXC_INFO_STACK + exc_state = &self->gi_exc_state; + tstate->exc_info = exc_state->previous_item; + exc_state->previous_item = NULL; + __Pyx_Coroutine_ResetFrameBackpointer(exc_state); +#endif return retval; } -static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__pyx_CoroutineObject *self) { - if (likely(self->exc_traceback)) { +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state) { + PyObject *exc_tb = exc_state->exc_traceback; + if (likely(exc_tb)) { #if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON #else - PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback; + PyTracebackObject *tb = (PyTracebackObject *) exc_tb; PyFrameObject *f = tb->tb_frame; Py_CLEAR(f->f_back); #endif @@ -23317,7 +23162,7 @@ static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) { return -1; } else if (__Pyx_CoroutineAwait_CheckExact(yf)) { - retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf); + retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf, NULL); if (!retval) return -1; } else @@ -23382,6 +23227,9 @@ static PyObject *__Pyx_Generator_Next(PyObject *self) { } return __Pyx_Coroutine_SendEx(gen, Py_None, 0); } +static PyObject *__Pyx_Coroutine_Close_Method(PyObject *self, CYTHON_UNUSED PyObject *arg) { + return __Pyx_Coroutine_Close(self); +} static PyObject *__Pyx_Coroutine_Close(PyObject *self) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; PyObject *retval, *raised_exception; @@ -23498,23 +23346,24 @@ static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) { return NULL; return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1); } +static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) { + Py_VISIT(exc_state->exc_type); + Py_VISIT(exc_state->exc_value); + Py_VISIT(exc_state->exc_traceback); + return 0; +} static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) { Py_VISIT(gen->closure); Py_VISIT(gen->classobj); Py_VISIT(gen->yieldfrom); - Py_VISIT(gen->exc_type); - Py_VISIT(gen->exc_value); - Py_VISIT(gen->exc_traceback); - return 0; + return __Pyx_Coroutine_traverse_excstate(&gen->gi_exc_state, visit, arg); } static int __Pyx_Coroutine_clear(PyObject *self) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; Py_CLEAR(gen->closure); Py_CLEAR(gen->classobj); Py_CLEAR(gen->yieldfrom); - Py_CLEAR(gen->exc_type); - Py_CLEAR(gen->exc_value); - Py_CLEAR(gen->exc_traceback); + __Pyx_Coroutine_ExceptionClear(&gen->gi_exc_state); #ifdef __Pyx_AsyncGen_USED if (__Pyx_AsyncGen_CheckExact(self)) { Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer); @@ -23652,7 +23501,7 @@ static void __Pyx_Coroutine_del(PyObject *self) { #endif } static PyObject * -__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self) +__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self, CYTHON_UNUSED void *context) { PyObject *name = self->gi_name; if (unlikely(!name)) name = Py_None; @@ -23660,14 +23509,15 @@ __Pyx_Coroutine_get_name(__pyx_CoroutineObject *self) return name; } static int -__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value) +__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, CYTHON_UNUSED void *context) { PyObject *tmp; #if PY_MAJOR_VERSION >= 3 - if (unlikely(value == NULL || !PyUnicode_Check(value))) { + if (unlikely(value == NULL || !PyUnicode_Check(value))) #else - if (unlikely(value == NULL || !PyString_Check(value))) { + if (unlikely(value == NULL || !PyString_Check(value))) #endif + { PyErr_SetString(PyExc_TypeError, "__name__ must be set to a string object"); return -1; @@ -23679,7 +23529,7 @@ __Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value) return 0; } static PyObject * -__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self) +__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self, CYTHON_UNUSED void *context) { PyObject *name = self->gi_qualname; if (unlikely(!name)) name = Py_None; @@ -23687,14 +23537,15 @@ __Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self) return name; } static int -__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value) +__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, CYTHON_UNUSED void *context) { PyObject *tmp; #if PY_MAJOR_VERSION >= 3 - if (unlikely(value == NULL || !PyUnicode_Check(value))) { + if (unlikely(value == NULL || !PyUnicode_Check(value))) #else - if (unlikely(value == NULL || !PyString_Check(value))) { + if (unlikely(value == NULL || !PyString_Check(value))) #endif + { PyErr_SetString(PyExc_TypeError, "__qualname__ must be set to a string object"); return -1; @@ -23723,9 +23574,12 @@ static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( gen->resume_label = 0; gen->classobj = NULL; gen->yieldfrom = NULL; - gen->exc_type = NULL; - gen->exc_value = NULL; - gen->exc_traceback = NULL; + gen->gi_exc_state.exc_type = NULL; + gen->gi_exc_state.exc_value = NULL; + gen->gi_exc_state.exc_traceback = NULL; +#if CYTHON_USE_EXC_INFO_STACK + gen->gi_exc_state.previous_item = NULL; +#endif gen->gi_weakreflist = NULL; Py_XINCREF(qualname); gen->gi_qualname = qualname; @@ -23740,7 +23594,7 @@ static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( } /* PatchModuleWithCoroutine */ - static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) { +static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) { #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) int result; PyObject *globals, *result_obj; @@ -23780,7 +23634,7 @@ ignore: } /* PatchGeneratorABC */ - #ifndef CYTHON_REGISTER_ABCS +#ifndef CYTHON_REGISTER_ABCS #define CYTHON_REGISTER_ABCS 1 #endif #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) @@ -23837,12 +23691,12 @@ static int __Pyx_patch_abc(void) { } /* Generator */ - static PyMethodDef __pyx_Generator_methods[] = { +static PyMethodDef __pyx_Generator_methods[] = { {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, (char*) PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")}, {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")}, - {"close", (PyCFunction) __Pyx_Coroutine_Close, METH_NOARGS, + {"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS, (char*) PyDoc_STR("close() -> raise GeneratorExit inside generator.")}, {0, 0, 0, 0} }; @@ -23929,7 +23783,7 @@ static int __pyx_Generator_init(void) { } /* CheckBinaryVersion */ - static int __Pyx_check_binary_version(void) { +static int __Pyx_check_binary_version(void) { char ctversion[4], rtversion[4]; PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); @@ -23944,91 +23798,8 @@ static int __pyx_Generator_init(void) { return 0; } -/* ModuleImport */ - #ifndef __PYX_HAVE_RT_ImportModule -#define __PYX_HAVE_RT_ImportModule -static PyObject *__Pyx_ImportModule(const char *name) { - PyObject *py_name = 0; - PyObject *py_module = 0; - py_name = __Pyx_PyIdentifier_FromString(name); - if (!py_name) - goto bad; - py_module = PyImport_Import(py_name); - Py_DECREF(py_name); - return py_module; -bad: - Py_XDECREF(py_name); - return 0; -} -#endif - -/* TypeImport */ - #ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, - size_t size, int strict) -{ - PyObject *py_module = 0; - PyObject *result = 0; - PyObject *py_name = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - py_module = __Pyx_ImportModule(module_name); - if (!py_module) - goto bad; - py_name = __Pyx_PyIdentifier_FromString(class_name); - if (!py_name) - goto bad; - result = PyObject_GetAttr(py_module, py_name); - Py_DECREF(py_name); - py_name = 0; - Py_DECREF(py_module); - py_module = 0; - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if (!strict && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. Expected %zd, got %zd", - module_name, class_name, basicsize, size); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - else if ((size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s has the wrong size, try recompiling. Expected %zd, got %zd", - module_name, class_name, basicsize, size); - goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(py_module); - Py_XDECREF(result); - return NULL; -} -#endif - /* InitStrings */ - static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { #if PY_MAJOR_VERSION < 3 if (t->is_unicode) { @@ -24137,6 +23908,13 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { if (is_true | (x == Py_False) | (x == Py_None)) return is_true; else return PyObject_IsTrue(x); } +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { #if PY_MAJOR_VERSION >= 3 if (PyLong_Check(result)) { @@ -24214,7 +23992,7 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { if (sizeof(Py_ssize_t) >= sizeof(long)) return PyInt_AS_LONG(b); else - return PyInt_AsSsize_t(x); + return PyInt_AsSsize_t(b); } #endif if (likely(PyLong_CheckExact(b))) { diff --git a/aiohttp/_http_writer.c b/aiohttp/_http_writer.c index 403928a..decc877 100644 --- a/aiohttp/_http_writer.c +++ b/aiohttp/_http_writer.c @@ -1,4 +1,4 @@ -/* Generated by Cython 0.28.5 */ +/* Generated by Cython 0.29.2 */ /* BEGIN: Cython Metadata { @@ -20,7 +20,8 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) #error Cython requires Python 2.6+ or Python 3.3+. #else -#define CYTHON_ABI "0_28_5" +#define CYTHON_ABI "0_29_2" +#define CYTHON_HEX_VERSION 0x001D02F0 #define CYTHON_FUTURE_DIVISION 0 #include <stddef.h> #ifndef offsetof @@ -91,6 +92,10 @@ END: Cython Metadata */ #define CYTHON_PEP489_MULTI_PHASE_INIT 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #elif defined(PYSTON_VERSION) #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 1 @@ -128,6 +133,10 @@ END: Cython Metadata */ #define CYTHON_PEP489_MULTI_PHASE_INIT 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #else #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 0 @@ -181,11 +190,17 @@ END: Cython Metadata */ #define CYTHON_FAST_PYCALL 1 #endif #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (0 && PY_VERSION_HEX >= 0x03050000) + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) #endif #ifndef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif #endif #if !defined(CYTHON_FAST_PYCCALL) #define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) @@ -195,6 +210,9 @@ END: Cython Metadata */ #undef SHIFT #undef BASE #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif #endif #ifndef __has_attribute #define __has_attribute(x) 0 @@ -321,6 +339,9 @@ END: Cython Metadata */ #ifndef Py_TPFLAGS_HAVE_FINALIZE #define Py_TPFLAGS_HAVE_FINALIZE 0 #endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif #if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) #ifndef METH_FASTCALL #define METH_FASTCALL 0x80 @@ -334,15 +355,40 @@ END: Cython Metadata */ #endif #if CYTHON_FAST_PYCCALL #define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))))) + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) #else #define __Pyx_PyFastCFunction_Check(func) 0 #endif +#if CYTHON_USE_DICT_VERSIONS +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ + } +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) #define PyObject_Malloc(s) PyMem_Malloc(s) #define PyObject_Free(p) PyMem_Free(p) #define PyObject_Realloc(p) PyMem_Realloc(p) #endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif #if CYTHON_COMPILING_IN_PYSTON #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) @@ -450,8 +496,8 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) #endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) #else @@ -606,6 +652,9 @@ typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* enc (sizeof(type) == sizeof(Py_ssize_t) &&\ (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} #if defined (__cplusplus) && __cplusplus >= 201103L #include <cstdlib> #define __Pyx_sst_abs(value) std::abs(value) @@ -664,6 +713,7 @@ static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); #define __Pyx_PySequence_Tuple(obj)\ (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) @@ -744,7 +794,7 @@ static int __Pyx_init_sys_getdefaultencoding_params(void) { if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); Py_DECREF(default_encoding); @@ -932,6 +982,18 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, #else #define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) #endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) #endif /* PyObjectCall.proto */ @@ -941,6 +1003,9 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg #define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) #endif +/* PyObjectCall2Args.proto */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + /* PyObjectCallMethO.proto */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); @@ -970,40 +1035,13 @@ static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ __Pyx__ArgTypeTest(obj, type, name, exact)) static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); -/* ReRaiseException.proto */ -static CYTHON_INLINE void __Pyx_ReraiseException(void) { - PyObject *type = NULL, *value = NULL, *tb = NULL; -#if CYTHON_FAST_THREAD_STATE - PyThreadState *tstate = PyThreadState_GET(); - #if PY_VERSION_HEX >= 0x030700A3 - type = tstate->exc_state.exc_type; - value = tstate->exc_state.exc_value; - tb = tstate->exc_state.exc_traceback; - #else - type = tstate->exc_type; - value = tstate->exc_value; - tb = tstate->exc_traceback; - #endif -#else - PyErr_GetExcInfo(&type, &value, &tb); -#endif - if (!type || type == Py_None) { -#if !CYTHON_FAST_THREAD_STATE - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(tb); -#endif - PyErr_SetString(PyExc_RuntimeError, - "No active exception to reraise"); - } else { -#if CYTHON_FAST_THREAD_STATE - Py_INCREF(type); - Py_XINCREF(value); - Py_XINCREF(tb); +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); #endif - PyErr_Restore(type, value, tb); - } -} + +/* ReRaiseException.proto */ +static CYTHON_INLINE void __Pyx_ReraiseException(void); /* PyObjectCallNoArg.proto */ #if CYTHON_COMPILING_IN_CPYTHON @@ -1051,6 +1089,17 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject #define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) #endif +/* TypeImport.proto */ +#ifndef __PYX_HAVE_RT_ImportType_proto +#define __PYX_HAVE_RT_ImportType_proto +enum __Pyx_ImportType_CheckSize { + __Pyx_ImportType_CheckSize_Error = 0, + __Pyx_ImportType_CheckSize_Warn = 1, + __Pyx_ImportType_CheckSize_Ignore = 2 +}; +static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); +#endif + /* Import.proto */ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); @@ -1058,7 +1107,25 @@ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); /* GetModuleGlobalName.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif /* CLineInTraceback.proto */ #ifdef CYTHON_CLINE_IN_TRACEBACK @@ -1119,21 +1186,6 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj /* CheckBinaryVersion.proto */ static int __Pyx_check_binary_version(void); -/* PyIdentifierFromString.proto */ -#if !defined(__Pyx_PyIdentifier_FromString) -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) -#else - #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) -#endif -#endif - -/* ModuleImport.proto */ -static PyObject *__Pyx_ImportModule(const char *name); - -/* TypeImport.proto */ -static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); - /* InitStrings.proto */ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); @@ -1179,6 +1231,7 @@ static const char __pyx_k_ret[] = "ret"; static const char __pyx_k_val[] = "val"; static const char __pyx_k_istr[] = "istr"; static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_name[] = "__name__"; static const char __pyx_k_test[] = "__test__"; static const char __pyx_k_items[] = "items"; static const char __pyx_k_format[] = "format"; @@ -1206,6 +1259,7 @@ static PyObject *__pyx_n_s_items; static PyObject *__pyx_n_s_key; static PyObject *__pyx_n_s_main; static PyObject *__pyx_n_s_multidict; +static PyObject *__pyx_n_s_name; static PyObject *__pyx_n_s_ret; static PyObject *__pyx_n_s_serialize_headers; static PyObject *__pyx_n_s_status_line; @@ -2069,7 +2123,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_writer_to_str(PyObject *__pyx_v_s) { PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; __Pyx_RefNannySetupContext("to_str", 0); /* "aiohttp/_http_writer.pyx":104 @@ -2179,38 +2232,10 @@ static PyObject *__pyx_f_7aiohttp_12_http_writer_to_str(PyObject *__pyx_v_s) { __Pyx_DECREF_SET(__pyx_t_4, function); } } - if (!__pyx_t_5) { - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_s); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - } else { - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_s}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_s}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_3); - } else - #endif - { - __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL; - __Pyx_INCREF(__pyx_v_s); - __Pyx_GIVEREF(__pyx_v_s); - PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_s); - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_v_s) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_s); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 110, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); @@ -2258,7 +2283,6 @@ static PyObject *__pyx_f_7aiohttp_12_http_writer_to_str(PyObject *__pyx_v_s) { __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._http_writer.to_str", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; @@ -2278,7 +2302,7 @@ static PyObject *__pyx_f_7aiohttp_12_http_writer_to_str(PyObject *__pyx_v_s) { /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_12_http_writer_1_serialize_headers(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_12_http_writer_1_serialize_headers = {"_serialize_headers", (PyCFunction)__pyx_pw_7aiohttp_12_http_writer_1_serialize_headers, METH_VARARGS|METH_KEYWORDS, 0}; +static PyMethodDef __pyx_mdef_7aiohttp_12_http_writer_1_serialize_headers = {"_serialize_headers", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_writer_1_serialize_headers, METH_VARARGS|METH_KEYWORDS, 0}; static PyObject *__pyx_pw_7aiohttp_12_http_writer_1_serialize_headers(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_status_line = 0; PyObject *__pyx_v_headers = 0; @@ -2490,12 +2514,9 @@ static PyObject *__pyx_pf_7aiohttp_12_http_writer__serialize_headers(CYTHON_UNUS __Pyx_DECREF_SET(__pyx_t_3, function); } } - if (__pyx_t_4) { - __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 131, __pyx_L4_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else { - __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 131, __pyx_L4_error) - } + __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 131, __pyx_L4_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (likely(PyList_CheckExact(__pyx_t_2)) || PyTuple_CheckExact(__pyx_t_2)) { @@ -2956,6 +2977,15 @@ static struct PyModuleDef __pyx_moduledef = { NULL /* m_free */ }; #endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_kp_s_Cannot_serialize_non_str_key_r, __pyx_k_Cannot_serialize_non_str_key_r, sizeof(__pyx_k_Cannot_serialize_non_str_key_r), 0, 0, 1, 0}, @@ -2971,6 +3001,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_key, __pyx_k_key, sizeof(__pyx_k_key), 0, 0, 1, 1}, {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, {&__pyx_n_s_multidict, __pyx_k_multidict, sizeof(__pyx_k_multidict), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, {&__pyx_n_s_ret, __pyx_k_ret, sizeof(__pyx_k_ret), 0, 0, 1, 1}, {&__pyx_n_s_serialize_headers, __pyx_k_serialize_headers, sizeof(__pyx_k_serialize_headers), 0, 0, 1, 1}, {&__pyx_n_s_status_line, __pyx_k_status_line, sizeof(__pyx_k_status_line), 0, 0, 1, 1}, @@ -2979,14 +3010,14 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_writer, __pyx_k_writer, sizeof(__pyx_k_writer), 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0} }; -static int __Pyx_InitCachedBuiltins(void) { +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(0, 110, __pyx_L1_error) return 0; __pyx_L1_error:; return -1; } -static int __Pyx_InitCachedConstants(void) { +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); @@ -3008,20 +3039,20 @@ static int __Pyx_InitCachedConstants(void) { return -1; } -static int __Pyx_InitGlobals(void) { +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); return 0; __pyx_L1_error:; return -1; } -static int __Pyx_modinit_global_init_code(void); /*proto*/ -static int __Pyx_modinit_variable_export_code(void); /*proto*/ -static int __Pyx_modinit_function_export_code(void); /*proto*/ -static int __Pyx_modinit_type_init_code(void); /*proto*/ -static int __Pyx_modinit_type_import_code(void); /*proto*/ -static int __Pyx_modinit_variable_import_code(void); /*proto*/ -static int __Pyx_modinit_function_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ static int __Pyx_modinit_global_init_code(void) { __Pyx_RefNannyDeclarations @@ -3058,18 +3089,24 @@ static int __Pyx_modinit_type_init_code(void) { static int __Pyx_modinit_type_import_code(void) { __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); /*--- Type import code ---*/ - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 sizeof(PyTypeObject), #else sizeof(PyHeapTypeObject), #endif - 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); __Pyx_RefNannyFinishContext(); return -1; } @@ -3104,15 +3141,6 @@ static int __Pyx_modinit_function_import_code(void) { #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC #endif #endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (!(defined(__cplusplus)) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4))) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif #if PY_MAJOR_VERSION < 3 @@ -3125,11 +3153,36 @@ __Pyx_PyMODINIT_FUNC PyInit__http_writer(void) { return PyModuleDef_Init(&__pyx_moduledef); } -static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name) { +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { PyObject *value = PyObject_GetAttrString(spec, from_name); int result = 0; if (likely(value)) { - result = PyDict_SetItemString(moddict, to_name, value); + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } Py_DECREF(value); } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); @@ -3138,8 +3191,10 @@ static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const ch } return result; } -static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; if (__pyx_m) return __Pyx_NewRef(__pyx_m); modname = PyObject_GetAttrString(spec, "name"); @@ -3149,10 +3204,10 @@ static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *d if (unlikely(!module)) goto bad; moddict = PyModule_GetDict(module); if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; return module; bad: Py_XDECREF(module); @@ -3160,7 +3215,7 @@ bad: } -static int __pyx_pymod_exec__http_writer(PyObject *__pyx_pyinit_module) +static CYTHON_SMALL_CODE int __pyx_pymod_exec__http_writer(PyObject *__pyx_pyinit_module) #endif #endif { @@ -3168,7 +3223,11 @@ static int __pyx_pymod_exec__http_writer(PyObject *__pyx_pyinit_module) PyObject *__pyx_t_2 = NULL; __Pyx_RefNannyDeclarations #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m && __pyx_m == __pyx_pyinit_module) return 0; + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_http_writer' has already been imported. Re-initialisation is not supported."); + return -1; + } #elif PY_MAJOR_VERSION >= 3 if (__pyx_m) return __Pyx_NewRef(__pyx_m); #endif @@ -3183,6 +3242,9 @@ if (!__Pyx_RefNanny) { #endif __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__http_writer(void)", 0); if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) @@ -3237,7 +3299,7 @@ if (!__Pyx_RefNanny) { if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif if (__pyx_module_is_main_aiohttp___http_writer) { - if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) } #if PY_MAJOR_VERSION >= 3 { @@ -3292,7 +3354,7 @@ if (!__Pyx_RefNanny) { * * */ - __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_istr); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_istr); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_writer__istr); __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_writer__istr, __pyx_t_2); @@ -3329,9 +3391,9 @@ if (!__Pyx_RefNanny) { __Pyx_XDECREF(__pyx_t_2); if (__pyx_m) { if (__pyx_d) { - __Pyx_AddTraceback("init aiohttp._http_writer", 0, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("init aiohttp._http_writer", __pyx_clineno, __pyx_lineno, __pyx_filename); } - Py_DECREF(__pyx_m); __pyx_m = 0; + Py_CLEAR(__pyx_m); } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, "init aiohttp._http_writer"); } @@ -3352,9 +3414,9 @@ if (!__Pyx_RefNanny) { static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { PyObject *m = NULL, *p = NULL; void *r = NULL; - m = PyImport_ImportModule((char *)modname); + m = PyImport_ImportModule(modname); if (!m) goto end; - p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); + p = PyObject_GetAttrString(m, "RefNannyAPI"); if (!p) goto end; r = PyLong_AsVoidPtr(p); end: @@ -3466,7 +3528,7 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P PyObject *self = PyCFunction_GET_SELF(func); int flags = PyCFunction_GET_FLAGS(func); assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); assert(nargs >= 0); assert(nargs == 0 || args != NULL); /* _PyCFunction_FastCallDict() must not be called with an exception set, @@ -3474,16 +3536,15 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P caller loses its exception */ assert(!PyErr_Occurred()); if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)meth)) (self, args, nargs, NULL); + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); } else { - return (*((__Pyx_PyCFunctionFast)meth)) (self, args, nargs); + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); } } #endif /* PyFunctionFastCall */ #if CYTHON_FAST_PYCALL -#include "frameobject.h" static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, PyObject *globals) { PyFrameObject *f; @@ -3501,7 +3562,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args if (f == NULL) { return NULL; } - fastlocals = f->f_localsplus; + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); for (i = 0; i < na; i++) { Py_INCREF(*args); fastlocals[i] = *args++; @@ -3621,6 +3682,35 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg } #endif +/* PyObjectCall2Args */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args, *result = NULL; + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyFunction_FastCall(function, args, 2); + } + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyCFunction_FastCall(function, args, 2); + } + #endif + args = PyTuple_New(2); + if (unlikely(!args)) goto done; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + Py_INCREF(function); + result = __Pyx_PyObject_Call(function, args, NULL); + Py_DECREF(args); + Py_DECREF(function); +done: + return result; +} + /* PyObjectCallMethO */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { @@ -4003,6 +4093,57 @@ static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *nam return 0; } +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* ReRaiseException */ +static CYTHON_INLINE void __Pyx_ReraiseException(void) { + PyObject *type = NULL, *value = NULL, *tb = NULL; +#if CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = PyThreadState_GET(); + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + type = exc_info->exc_type; + value = exc_info->exc_value; + tb = exc_info->exc_traceback; + #else + type = tstate->exc_type; + value = tstate->exc_value; + tb = tstate->exc_traceback; + #endif +#else + PyErr_GetExcInfo(&type, &value, &tb); +#endif + if (!type || type == Py_None) { +#if !CYTHON_FAST_THREAD_STATE + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(tb); +#endif + PyErr_SetString(PyExc_RuntimeError, + "No active exception to reraise"); + } else { +#if CYTHON_FAST_THREAD_STATE + Py_INCREF(type); + Py_XINCREF(value); + Py_XINCREF(tb); +#endif + PyErr_Restore(type, value, tb); + } +} + /* PyObjectCallNoArg */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { @@ -4012,10 +4153,11 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { } #endif #ifdef __Pyx_CyFunction_USED - if (likely(PyCFunction_Check(func) || __Pyx_TypeCheck(func, __pyx_CyFunctionType))) { + if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) #else - if (likely(PyCFunction_Check(func))) { + if (likely(PyCFunction_Check(func))) #endif + { if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { return __Pyx_PyObject_CallMethO(func, NULL); } @@ -4025,20 +4167,20 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { #endif /* RaiseTooManyValuesToUnpack */ - static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { PyErr_Format(PyExc_ValueError, "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); } /* RaiseNeedMoreValuesToUnpack */ - static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { PyErr_Format(PyExc_ValueError, "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", index, (index == 1) ? "" : "s"); } /* IterFinish */ - static CYTHON_INLINE int __Pyx_IterFinish(void) { +static CYTHON_INLINE int __Pyx_IterFinish(void) { #if CYTHON_FAST_THREAD_STATE PyThreadState *tstate = __Pyx_PyThreadState_Current; PyObject* exc_type = tstate->curexc_type; @@ -4073,7 +4215,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { } /* UnpackItemEndCheck */ - static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { if (unlikely(retval)) { Py_DECREF(retval); __Pyx_RaiseTooManyValuesError(expected); @@ -4085,11 +4227,12 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { } /* GetException */ - #if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) #else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) #endif +{ PyObject *local_type, *local_value, *local_tb; #if CYTHON_FAST_THREAD_STATE PyObject *tmp_type, *tmp_value, *tmp_tb; @@ -4122,13 +4265,16 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) *value = local_value; *tb = local_tb; #if CYTHON_FAST_THREAD_STATE - #if PY_VERSION_HEX >= 0x030700A3 - tmp_type = tstate->exc_state.exc_type; - tmp_value = tstate->exc_state.exc_value; - tmp_tb = tstate->exc_state.exc_traceback; - tstate->exc_state.exc_type = local_type; - tstate->exc_state.exc_value = local_value; - tstate->exc_state.exc_traceback = local_tb; + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + } #else tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; @@ -4155,16 +4301,17 @@ bad: } /* SwapException */ - #if CYTHON_FAST_THREAD_STATE +#if CYTHON_FAST_THREAD_STATE static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030700A3 - tmp_type = tstate->exc_state.exc_type; - tmp_value = tstate->exc_state.exc_value; - tmp_tb = tstate->exc_state.exc_traceback; - tstate->exc_state.exc_type = *type; - tstate->exc_state.exc_value = *value; - tstate->exc_state.exc_traceback = *tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; #else tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; @@ -4189,12 +4336,13 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, #endif /* SaveResetException */ - #if CYTHON_FAST_THREAD_STATE +#if CYTHON_FAST_THREAD_STATE static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if PY_VERSION_HEX >= 0x030700A3 - *type = tstate->exc_state.exc_type; - *value = tstate->exc_state.exc_value; - *tb = tstate->exc_state.exc_traceback; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; #else *type = tstate->exc_type; *value = tstate->exc_value; @@ -4206,13 +4354,14 @@ static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject * } static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030700A3 - tmp_type = tstate->exc_state.exc_type; - tmp_value = tstate->exc_state.exc_value; - tmp_tb = tstate->exc_state.exc_traceback; - tstate->exc_state.exc_type = type; - tstate->exc_state.exc_value = value; - tstate->exc_state.exc_traceback = tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; #else tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; @@ -4227,8 +4376,69 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject } #endif +/* TypeImport */ +#ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, + size_t size, enum __Pyx_ImportType_CheckSize check_size) +{ + PyObject *result = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + result = PyObject_GetAttrString(module, class_name); + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if ((size_t)basicsize < size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(result); + return NULL; +} +#endif + /* Import */ - static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { PyObject *empty_list = 0; PyObject *module = 0; PyObject *global_dict = 0; @@ -4275,7 +4485,7 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject if (!py_level) goto bad; module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, NULL); + name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); Py_DECREF(py_level); #else module = PyImport_ImportModuleLevelObject( @@ -4293,7 +4503,7 @@ bad: } /* ImportFrom */ - static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Format(PyExc_ImportError, @@ -4307,35 +4517,43 @@ bad: } /* GetModuleGlobalName */ - static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ PyObject *result; #if !CYTHON_AVOID_BORROWED_REFS #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) if (likely(result)) { - Py_INCREF(result); + return __Pyx_NewRef(result); } else if (unlikely(PyErr_Occurred())) { - result = NULL; - } else { + return NULL; + } #else result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) if (likely(result)) { - Py_INCREF(result); - } else { + return __Pyx_NewRef(result); + } #endif #else result = PyObject_GetItem(__pyx_d, name); - if (!result) { - PyErr_Clear(); -#endif - result = __Pyx_GetBuiltinName(name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); } - return result; + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); } /* CLineInTraceback */ - #ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) { +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { PyObject *use_cline; PyObject *ptype, *pvalue, *ptraceback; #if CYTHON_COMPILING_IN_CPYTHON @@ -4348,7 +4566,9 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li #if CYTHON_COMPILING_IN_CPYTHON cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); if (likely(cython_runtime_dict)) { - use_cline = __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback); + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) } else #endif { @@ -4365,7 +4585,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li c_line = 0; PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); } - else if (PyObject_Not(use_cline) != 0) { + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { c_line = 0; } __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); @@ -4374,7 +4594,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li #endif /* CodeObjectCache */ - static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { int start = 0, mid = 0, end = count - 1; if (end >= 0 && code_line > entries[end].code_line) { return count; @@ -4454,7 +4674,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { } /* AddTraceback */ - #include "compile.h" +#include "compile.h" #include "frameobject.h" #include "traceback.h" static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( @@ -4539,7 +4759,7 @@ bad: } /* UnicodeAsUCS4 */ - static CYTHON_INLINE Py_UCS4 __Pyx_PyUnicode_AsPy_UCS4(PyObject* x) { +static CYTHON_INLINE Py_UCS4 __Pyx_PyUnicode_AsPy_UCS4(PyObject* x) { Py_ssize_t length; #if CYTHON_PEP393_ENABLED length = PyUnicode_GET_LENGTH(x); @@ -4570,25 +4790,29 @@ bad: } /* ObjectAsUCS4 */ - static Py_UCS4 __Pyx__PyObject_AsPy_UCS4(PyObject* x) { - long ival; - ival = __Pyx_PyInt_As_long(x); - if (unlikely(ival < 0)) { +static Py_UCS4 __Pyx__PyObject_AsPy_UCS4_raise_error(long ival) { + if (ival < 0) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_OverflowError, "cannot convert negative value to Py_UCS4"); - return (Py_UCS4)-1; - } else if (unlikely(ival > 1114111)) { + } else { PyErr_SetString(PyExc_OverflowError, "value too large to convert to Py_UCS4"); - return (Py_UCS4)-1; + } + return (Py_UCS4)-1; +} +static Py_UCS4 __Pyx__PyObject_AsPy_UCS4(PyObject* x) { + long ival; + ival = __Pyx_PyInt_As_long(x); + if (unlikely(!__Pyx_is_valid_index(ival, 1114111 + 1))) { + return __Pyx__PyObject_AsPy_UCS4_raise_error(ival); } return (Py_UCS4)ival; } /* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) -1, const_zero = (long) 0; +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(long) < sizeof(long)) { @@ -4618,7 +4842,7 @@ bad: } /* CIntFromPyVerify */ - #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) #define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) @@ -4640,8 +4864,8 @@ bad: } /* CIntFromPy */ - static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) -1, const_zero = (long) 0; +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -4829,8 +5053,8 @@ raise_neg_overflow: } /* CIntFromPy */ - static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) -1, const_zero = (int) 0; +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -5018,7 +5242,7 @@ raise_neg_overflow: } /* FastTypeChecks */ - #if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { while (a) { a = a->tp_base; @@ -5118,7 +5342,7 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj #endif /* CheckBinaryVersion */ - static int __Pyx_check_binary_version(void) { +static int __Pyx_check_binary_version(void) { char ctversion[4], rtversion[4]; PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); @@ -5133,91 +5357,8 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj return 0; } -/* ModuleImport */ - #ifndef __PYX_HAVE_RT_ImportModule -#define __PYX_HAVE_RT_ImportModule -static PyObject *__Pyx_ImportModule(const char *name) { - PyObject *py_name = 0; - PyObject *py_module = 0; - py_name = __Pyx_PyIdentifier_FromString(name); - if (!py_name) - goto bad; - py_module = PyImport_Import(py_name); - Py_DECREF(py_name); - return py_module; -bad: - Py_XDECREF(py_name); - return 0; -} -#endif - -/* TypeImport */ - #ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, - size_t size, int strict) -{ - PyObject *py_module = 0; - PyObject *result = 0; - PyObject *py_name = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - py_module = __Pyx_ImportModule(module_name); - if (!py_module) - goto bad; - py_name = __Pyx_PyIdentifier_FromString(class_name); - if (!py_name) - goto bad; - result = PyObject_GetAttr(py_module, py_name); - Py_DECREF(py_name); - py_name = 0; - Py_DECREF(py_module); - py_module = 0; - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if (!strict && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. Expected %zd, got %zd", - module_name, class_name, basicsize, size); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - else if ((size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s has the wrong size, try recompiling. Expected %zd, got %zd", - module_name, class_name, basicsize, size); - goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(py_module); - Py_XDECREF(result); - return NULL; -} -#endif - /* InitStrings */ - static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { #if PY_MAJOR_VERSION < 3 if (t->is_unicode) { @@ -5326,6 +5467,13 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { if (is_true | (x == Py_False) | (x == Py_None)) return is_true; else return PyObject_IsTrue(x); } +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { #if PY_MAJOR_VERSION >= 3 if (PyLong_Check(result)) { @@ -5403,7 +5551,7 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { if (sizeof(Py_ssize_t) >= sizeof(long)) return PyInt_AS_LONG(b); else - return PyInt_AsSsize_t(x); + return PyInt_AsSsize_t(b); } #endif if (likely(PyLong_CheckExact(b))) { diff --git a/aiohttp/_websocket.c b/aiohttp/_websocket.c index 2507933..c735b3a 100644 --- a/aiohttp/_websocket.c +++ b/aiohttp/_websocket.c @@ -1,4 +1,4 @@ -/* Generated by Cython 0.28.5 */ +/* Generated by Cython 0.29.2 */ /* BEGIN: Cython Metadata { @@ -20,7 +20,8 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) #error Cython requires Python 2.6+ or Python 3.3+. #else -#define CYTHON_ABI "0_28_5" +#define CYTHON_ABI "0_29_2" +#define CYTHON_HEX_VERSION 0x001D02F0 #define CYTHON_FUTURE_DIVISION 0 #include <stddef.h> #ifndef offsetof @@ -91,6 +92,10 @@ END: Cython Metadata */ #define CYTHON_PEP489_MULTI_PHASE_INIT 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #elif defined(PYSTON_VERSION) #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 1 @@ -128,6 +133,10 @@ END: Cython Metadata */ #define CYTHON_PEP489_MULTI_PHASE_INIT 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #else #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 0 @@ -181,11 +190,17 @@ END: Cython Metadata */ #define CYTHON_FAST_PYCALL 1 #endif #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (0 && PY_VERSION_HEX >= 0x03050000) + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) #endif #ifndef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif #endif #if !defined(CYTHON_FAST_PYCCALL) #define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) @@ -195,6 +210,9 @@ END: Cython Metadata */ #undef SHIFT #undef BASE #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif #endif #ifndef __has_attribute #define __has_attribute(x) 0 @@ -321,6 +339,9 @@ END: Cython Metadata */ #ifndef Py_TPFLAGS_HAVE_FINALIZE #define Py_TPFLAGS_HAVE_FINALIZE 0 #endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif #if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) #ifndef METH_FASTCALL #define METH_FASTCALL 0x80 @@ -334,15 +355,40 @@ END: Cython Metadata */ #endif #if CYTHON_FAST_PYCCALL #define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))))) + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) #else #define __Pyx_PyFastCFunction_Check(func) 0 #endif +#if CYTHON_USE_DICT_VERSIONS +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ + } +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) #define PyObject_Malloc(s) PyMem_Malloc(s) #define PyObject_Free(p) PyMem_Free(p) #define PyObject_Realloc(p) PyMem_Realloc(p) #endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif #if CYTHON_COMPILING_IN_PYSTON #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) @@ -450,8 +496,8 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) #endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) #else @@ -607,6 +653,9 @@ typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* enc (sizeof(type) == sizeof(Py_ssize_t) &&\ (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} #if defined (__cplusplus) && __cplusplus >= 201103L #include <cstdlib> #define __Pyx_sst_abs(value) std::abs(value) @@ -665,6 +714,7 @@ static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); #define __Pyx_PySequence_Tuple(obj)\ (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) @@ -745,7 +795,7 @@ static int __Pyx_init_sys_getdefaultencoding_params(void) { if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); Py_DECREF(default_encoding); @@ -892,6 +942,18 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, #else #define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) #endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) #endif /* PyObjectCall.proto */ @@ -909,6 +971,17 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject /* PyObjectCallOneArg.proto */ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); +/* TypeImport.proto */ +#ifndef __PYX_HAVE_RT_ImportType_proto +#define __PYX_HAVE_RT_ImportType_proto +enum __Pyx_ImportType_CheckSize { + __Pyx_ImportType_CheckSize_Error = 0, + __Pyx_ImportType_CheckSize_Warn = 1, + __Pyx_ImportType_CheckSize_Ignore = 2 +}; +static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); +#endif + /* PyThreadStateGet.proto */ #if CYTHON_FAST_THREAD_STATE #define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; @@ -996,21 +1069,6 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj /* CheckBinaryVersion.proto */ static int __Pyx_check_binary_version(void); -/* PyIdentifierFromString.proto */ -#if !defined(__Pyx_PyIdentifier_FromString) -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) -#else - #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) -#endif -#endif - -/* ModuleImport.proto */ -static PyObject *__Pyx_ImportModule(const char *name); - -/* TypeImport.proto */ -static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); - /* InitStrings.proto */ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); @@ -1111,6 +1169,7 @@ static const char __pyx_k_i[] = "i"; static const char __pyx_k_data[] = "data"; static const char __pyx_k_main[] = "__main__"; static const char __pyx_k_mask[] = "mask"; +static const char __pyx_k_name[] = "__name__"; static const char __pyx_k_test[] = "__test__"; static const char __pyx_k_range[] = "range"; static const char __pyx_k_in_buf[] = "in_buf"; @@ -1132,6 +1191,7 @@ static PyObject *__pyx_n_s_in_buf; static PyObject *__pyx_n_s_main; static PyObject *__pyx_n_s_mask; static PyObject *__pyx_n_s_mask_buf; +static PyObject *__pyx_n_s_name; static PyObject *__pyx_n_s_range; static PyObject *__pyx_n_s_test; static PyObject *__pyx_n_s_uint32_msk; @@ -1146,14 +1206,14 @@ static PyObject *__pyx_codeobj__2; * from libc.stdint cimport uint32_t, uint64_t, uintmax_t * * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< - * """Note, this function mutates it's `data` argument + * """Note, this function mutates its `data` argument * """ */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_websocket_1_websocket_mask_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_7aiohttp_10_websocket__websocket_mask_cython[] = "Note, this function mutates it's `data` argument\n "; -static PyMethodDef __pyx_mdef_7aiohttp_10_websocket_1_websocket_mask_cython = {"_websocket_mask_cython", (PyCFunction)__pyx_pw_7aiohttp_10_websocket_1_websocket_mask_cython, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_websocket__websocket_mask_cython}; +static char __pyx_doc_7aiohttp_10_websocket__websocket_mask_cython[] = "Note, this function mutates its `data` argument\n "; +static PyMethodDef __pyx_mdef_7aiohttp_10_websocket_1_websocket_mask_cython = {"_websocket_mask_cython", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_10_websocket_1_websocket_mask_cython, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_websocket__websocket_mask_cython}; static PyObject *__pyx_pw_7aiohttp_10_websocket_1_websocket_mask_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_mask = 0; PyObject *__pyx_v_data = 0; @@ -1517,7 +1577,7 @@ static PyObject *__pyx_pf_7aiohttp_10_websocket__websocket_mask_cython(CYTHON_UN * from libc.stdint cimport uint32_t, uint64_t, uintmax_t * * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< - * """Note, this function mutates it's `data` argument + * """Note, this function mutates its `data` argument * """ */ @@ -1571,6 +1631,15 @@ static struct PyModuleDef __pyx_moduledef = { NULL /* m_free */ }; #endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_aiohttp__websocket, __pyx_k_aiohttp__websocket, sizeof(__pyx_k_aiohttp__websocket), 0, 0, 1, 1}, @@ -1583,6 +1652,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, {&__pyx_n_s_mask, __pyx_k_mask, sizeof(__pyx_k_mask), 0, 0, 1, 1}, {&__pyx_n_s_mask_buf, __pyx_k_mask_buf, sizeof(__pyx_k_mask_buf), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, {&__pyx_n_s_uint32_msk, __pyx_k_uint32_msk, sizeof(__pyx_k_uint32_msk), 0, 0, 1, 1}, @@ -1590,14 +1660,14 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_websocket_mask_cython, __pyx_k_websocket_mask_cython, sizeof(__pyx_k_websocket_mask_cython), 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0} }; -static int __Pyx_InitCachedBuiltins(void) { +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 53, __pyx_L1_error) return 0; __pyx_L1_error:; return -1; } -static int __Pyx_InitCachedConstants(void) { +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); @@ -1605,7 +1675,7 @@ static int __Pyx_InitCachedConstants(void) { * from libc.stdint cimport uint32_t, uint64_t, uintmax_t * * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< - * """Note, this function mutates it's `data` argument + * """Note, this function mutates its `data` argument * """ */ __pyx_tuple_ = PyTuple_Pack(8, __pyx_n_s_mask, __pyx_n_s_data, __pyx_n_s_data_len, __pyx_n_s_i, __pyx_n_s_in_buf, __pyx_n_s_mask_buf, __pyx_n_s_uint32_msk, __pyx_n_s_uint64_msk); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 9, __pyx_L1_error) @@ -1619,20 +1689,20 @@ static int __Pyx_InitCachedConstants(void) { return -1; } -static int __Pyx_InitGlobals(void) { +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); return 0; __pyx_L1_error:; return -1; } -static int __Pyx_modinit_global_init_code(void); /*proto*/ -static int __Pyx_modinit_variable_export_code(void); /*proto*/ -static int __Pyx_modinit_function_export_code(void); /*proto*/ -static int __Pyx_modinit_type_init_code(void); /*proto*/ -static int __Pyx_modinit_type_import_code(void); /*proto*/ -static int __Pyx_modinit_variable_import_code(void); /*proto*/ -static int __Pyx_modinit_function_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ static int __Pyx_modinit_global_init_code(void) { __Pyx_RefNannyDeclarations @@ -1668,20 +1738,34 @@ static int __Pyx_modinit_type_init_code(void) { static int __Pyx_modinit_type_import_code(void) { __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); /*--- Type import code ---*/ - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 sizeof(PyTypeObject), #else sizeof(PyHeapTypeObject), #endif - 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) __PYX_ERR(1, 9, __pyx_L1_error) - __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), 0); if (unlikely(!__pyx_ptype_7cpython_4bool_bool)) __PYX_ERR(2, 8, __pyx_L1_error) - __pyx_ptype_7cpython_7complex_complex = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "complex", sizeof(PyComplexObject), 0); if (unlikely(!__pyx_ptype_7cpython_7complex_complex)) __PYX_ERR(3, 15, __pyx_L1_error) + __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4bool_bool) __PYX_ERR(2, 8, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_7complex_complex = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "complex", sizeof(PyComplexObject), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_7complex_complex) __PYX_ERR(3, 15, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); __Pyx_RefNannyFinishContext(); return -1; } @@ -1716,15 +1800,6 @@ static int __Pyx_modinit_function_import_code(void) { #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC #endif #endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (!(defined(__cplusplus)) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4))) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif #if PY_MAJOR_VERSION < 3 @@ -1737,11 +1812,36 @@ __Pyx_PyMODINIT_FUNC PyInit__websocket(void) { return PyModuleDef_Init(&__pyx_moduledef); } -static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name) { +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { PyObject *value = PyObject_GetAttrString(spec, from_name); int result = 0; if (likely(value)) { - result = PyDict_SetItemString(moddict, to_name, value); + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } Py_DECREF(value); } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); @@ -1750,8 +1850,10 @@ static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const ch } return result; } -static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; if (__pyx_m) return __Pyx_NewRef(__pyx_m); modname = PyObject_GetAttrString(spec, "name"); @@ -1761,10 +1863,10 @@ static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *d if (unlikely(!module)) goto bad; moddict = PyModule_GetDict(module); if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; return module; bad: Py_XDECREF(module); @@ -1772,14 +1874,18 @@ bad: } -static int __pyx_pymod_exec__websocket(PyObject *__pyx_pyinit_module) +static CYTHON_SMALL_CODE int __pyx_pymod_exec__websocket(PyObject *__pyx_pyinit_module) #endif #endif { PyObject *__pyx_t_1 = NULL; __Pyx_RefNannyDeclarations #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m && __pyx_m == __pyx_pyinit_module) return 0; + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_websocket' has already been imported. Re-initialisation is not supported."); + return -1; + } #elif PY_MAJOR_VERSION >= 3 if (__pyx_m) return __Pyx_NewRef(__pyx_m); #endif @@ -1794,6 +1900,9 @@ if (!__Pyx_RefNanny) { #endif __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__websocket(void)", 0); if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) @@ -1848,7 +1957,7 @@ if (!__Pyx_RefNanny) { if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif if (__pyx_module_is_main_aiohttp___websocket) { - if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) } #if PY_MAJOR_VERSION >= 3 { @@ -1879,7 +1988,7 @@ if (!__Pyx_RefNanny) { * from libc.stdint cimport uint32_t, uint64_t, uintmax_t * * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< - * """Note, this function mutates it's `data` argument + * """Note, this function mutates its `data` argument * """ */ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_10_websocket_1_websocket_mask_cython, NULL, __pyx_n_s_aiohttp__websocket); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error) @@ -1904,9 +2013,9 @@ if (!__Pyx_RefNanny) { __Pyx_XDECREF(__pyx_t_1); if (__pyx_m) { if (__pyx_d) { - __Pyx_AddTraceback("init aiohttp._websocket", 0, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("init aiohttp._websocket", __pyx_clineno, __pyx_lineno, __pyx_filename); } - Py_DECREF(__pyx_m); __pyx_m = 0; + Py_CLEAR(__pyx_m); } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, "init aiohttp._websocket"); } @@ -1927,9 +2036,9 @@ if (!__Pyx_RefNanny) { static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { PyObject *m = NULL, *p = NULL; void *r = NULL; - m = PyImport_ImportModule((char *)modname); + m = PyImport_ImportModule(modname); if (!m) goto end; - p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); + p = PyObject_GetAttrString(m, "RefNannyAPI"); if (!p) goto end; r = PyLong_AsVoidPtr(p); end: @@ -2117,7 +2226,7 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P PyObject *self = PyCFunction_GET_SELF(func); int flags = PyCFunction_GET_FLAGS(func); assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); assert(nargs >= 0); assert(nargs == 0 || args != NULL); /* _PyCFunction_FastCallDict() must not be called with an exception set, @@ -2125,16 +2234,15 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P caller loses its exception */ assert(!PyErr_Occurred()); if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)meth)) (self, args, nargs, NULL); + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); } else { - return (*((__Pyx_PyCFunctionFast)meth)) (self, args, nargs); + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); } } #endif /* PyFunctionFastCall */ #if CYTHON_FAST_PYCALL -#include "frameobject.h" static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, PyObject *globals) { PyFrameObject *f; @@ -2152,7 +2260,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args if (f == NULL) { return NULL; } - fastlocals = f->f_localsplus; + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); for (i = 0; i < na; i++) { Py_INCREF(*args); fastlocals[i] = *args++; @@ -2332,6 +2440,67 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObjec } #endif +/* TypeImport */ +#ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, + size_t size, enum __Pyx_ImportType_CheckSize check_size) +{ + PyObject *result = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + result = PyObject_GetAttrString(module, class_name); + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if ((size_t)basicsize < size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(result); + return NULL; +} +#endif + /* PyErrFetchRestore */ #if CYTHON_FAST_THREAD_STATE static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { @@ -2358,7 +2527,7 @@ static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject /* CLineInTraceback */ #ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) { +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { PyObject *use_cline; PyObject *ptype, *pvalue, *ptraceback; #if CYTHON_COMPILING_IN_CPYTHON @@ -2371,7 +2540,9 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li #if CYTHON_COMPILING_IN_CPYTHON cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); if (likely(cython_runtime_dict)) { - use_cline = __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback); + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) } else #endif { @@ -2388,7 +2559,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li c_line = 0; PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); } - else if (PyObject_Not(use_cline) != 0) { + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { c_line = 0; } __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); @@ -2563,7 +2734,7 @@ bad: /* CIntToPy */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) -1, const_zero = (long) 0; + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(long) < sizeof(long)) { @@ -2616,7 +2787,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { /* CIntFromPy */ static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) -1, const_zero = (long) 0; + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -2805,7 +2976,7 @@ raise_neg_overflow: /* CIntFromPy */ static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) -1, const_zero = (int) 0; + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { @@ -3108,89 +3279,6 @@ static int __Pyx_check_binary_version(void) { return 0; } -/* ModuleImport */ -#ifndef __PYX_HAVE_RT_ImportModule -#define __PYX_HAVE_RT_ImportModule -static PyObject *__Pyx_ImportModule(const char *name) { - PyObject *py_name = 0; - PyObject *py_module = 0; - py_name = __Pyx_PyIdentifier_FromString(name); - if (!py_name) - goto bad; - py_module = PyImport_Import(py_name); - Py_DECREF(py_name); - return py_module; -bad: - Py_XDECREF(py_name); - return 0; -} -#endif - -/* TypeImport */ -#ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, - size_t size, int strict) -{ - PyObject *py_module = 0; - PyObject *result = 0; - PyObject *py_name = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - py_module = __Pyx_ImportModule(module_name); - if (!py_module) - goto bad; - py_name = __Pyx_PyIdentifier_FromString(class_name); - if (!py_name) - goto bad; - result = PyObject_GetAttr(py_module, py_name); - Py_DECREF(py_name); - py_name = 0; - Py_DECREF(py_module); - py_module = 0; - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if (!strict && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. Expected %zd, got %zd", - module_name, class_name, basicsize, size); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - else if ((size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s has the wrong size, try recompiling. Expected %zd, got %zd", - module_name, class_name, basicsize, size); - goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(py_module); - Py_XDECREF(result); - return NULL; -} -#endif - /* InitStrings */ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { @@ -3301,6 +3389,13 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { if (is_true | (x == Py_False) | (x == Py_None)) return is_true; else return PyObject_IsTrue(x); } +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { #if PY_MAJOR_VERSION >= 3 if (PyLong_Check(result)) { @@ -3378,7 +3473,7 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { if (sizeof(Py_ssize_t) >= sizeof(long)) return PyInt_AS_LONG(b); else - return PyInt_AsSsize_t(x); + return PyInt_AsSsize_t(b); } #endif if (likely(PyLong_CheckExact(b))) { diff --git a/aiohttp/_websocket.pyx b/aiohttp/_websocket.pyx index 3412c61..e4d992a 100644 --- a/aiohttp/_websocket.pyx +++ b/aiohttp/_websocket.pyx @@ -7,7 +7,7 @@ cdef extern from "Python.h": from libc.stdint cimport uint32_t, uint64_t, uintmax_t def _websocket_mask_cython(object mask, object data): - """Note, this function mutates it's `data` argument + """Note, this function mutates its `data` argument """ cdef: Py_ssize_t data_len, i diff --git a/aiohttp/abc.py b/aiohttp/abc.py index 81d16ac..2c9034d 100644 --- a/aiohttp/abc.py +++ b/aiohttp/abc.py @@ -1,14 +1,34 @@ import asyncio +import logging from abc import ABC, abstractmethod -from collections.abc import Iterable, Sized +from collections.abc import Sized +from http.cookies import BaseCookie, Morsel # noqa +from typing import (TYPE_CHECKING, Any, Awaitable, Callable, Dict, Generator, + Iterable, List, Optional, Tuple) + +from multidict import CIMultiDict # noqa +from yarl import URL + +from .helpers import get_running_loop +from .typedefs import LooseCookies + + +if TYPE_CHECKING: # pragma: no cover + from .web_request import BaseRequest, Request + from .web_response import StreamResponse + from .web_app import Application + from .web_exceptions import HTTPException +else: + BaseRequest = Request = Application = StreamResponse = None + HTTPException = None class AbstractRouter(ABC): - def __init__(self): + def __init__(self) -> None: self._frozen = False - def post_init(self, app): + def post_init(self, app: Application) -> None: """Post init stage. Not an abstract method for sake of backward compatibility, @@ -17,40 +37,42 @@ class AbstractRouter(ABC): """ @property - def frozen(self): + def frozen(self) -> bool: return self._frozen - def freeze(self): + def freeze(self) -> None: """Freeze router.""" self._frozen = True @abstractmethod - async def resolve(self, request): + async def resolve(self, request: Request) -> 'AbstractMatchInfo': """Return MATCH_INFO for given request""" class AbstractMatchInfo(ABC): + @property # pragma: no branch @abstractmethod - async def handler(self, request): + def handler(self) -> Callable[[Request], Awaitable[StreamResponse]]: """Execute matched request handler""" + @property @abstractmethod - async def expect_handler(self, request): + def expect_handler(self) -> Callable[[Request], Awaitable[None]]: """Expect handler for 100-continue processing""" @property # pragma: no branch @abstractmethod - def http_exception(self): + def http_exception(self) -> Optional[HTTPException]: """HTTPException instance raised on router's resolving, or None""" @abstractmethod # pragma: no branch - def get_info(self): + def get_info(self) -> Dict[str, Any]: """Return a dict with additional info useful for introspection""" @property # pragma: no branch @abstractmethod - def apps(self): + def apps(self) -> Tuple[Application, ...]: """Stack of nested applications. Top level application is left-most element. @@ -58,11 +80,11 @@ class AbstractMatchInfo(ABC): """ @abstractmethod - def add_app(self, app): + def add_app(self, app: Application) -> None: """Add application to the nested apps stack.""" @abstractmethod - def freeze(self): + def freeze(self) -> None: """Freeze the match info. The method is called after route resolution. @@ -75,16 +97,16 @@ class AbstractMatchInfo(ABC): class AbstractView(ABC): """Abstract class based view.""" - def __init__(self, request): + def __init__(self, request: Request) -> None: self._request = request @property - def request(self): + def request(self) -> Request: """Request instance.""" return self._request @abstractmethod - def __await__(self): + def __await__(self) -> Generator[Any, None, StreamResponse]: """Execute the view handler.""" @@ -92,56 +114,86 @@ class AbstractResolver(ABC): """Abstract DNS resolver.""" @abstractmethod - async def resolve(self, hostname): + async def resolve(self, host: str, + port: int, family: int) -> List[Dict[str, Any]]: """Return IP address for given hostname""" @abstractmethod - async def close(self): + async def close(self) -> None: """Release resolver""" -class AbstractCookieJar(Sized, Iterable): +if TYPE_CHECKING: # pragma: no cover + IterableBase = Iterable[Morsel[str]] +else: + IterableBase = Iterable + + +class AbstractCookieJar(Sized, IterableBase): """Abstract Cookie Jar.""" - def __init__(self, *, loop=None): - self._loop = loop or asyncio.get_event_loop() + def __init__(self, *, + loop: Optional[asyncio.AbstractEventLoop]=None) -> None: + self._loop = get_running_loop(loop) @abstractmethod - def clear(self): + def clear(self) -> None: """Clear all cookies.""" @abstractmethod - def update_cookies(self, cookies, response_url=None): + def update_cookies(self, + cookies: LooseCookies, + response_url: URL=URL()) -> None: """Update cookies.""" @abstractmethod - def filter_cookies(self, request_url): + def filter_cookies(self, request_url: URL) -> 'BaseCookie[str]': """Return the jar's cookies filtered by their attributes.""" class AbstractStreamWriter(ABC): """Abstract stream writer.""" + buffer_size = 0 + output_size = 0 + length = 0 # type: Optional[int] + @abstractmethod - async def write(self, chunk): + async def write(self, chunk: bytes) -> None: """Write chunk into stream.""" @abstractmethod - async def write_eof(self, chunk=b''): + async def write_eof(self, chunk: bytes=b'') -> None: """Write last chunk.""" @abstractmethod - async def drain(self): + async def drain(self) -> None: """Flush the write buffer.""" + @abstractmethod + def enable_compression(self, encoding: str='deflate') -> None: + """Enable HTTP body compression""" + + @abstractmethod + def enable_chunking(self) -> None: + """Enable HTTP chunked mode""" + + @abstractmethod + async def write_headers(self, status_line: str, + headers: 'CIMultiDict[str]') -> None: + """Write HTTP headers""" + class AbstractAccessLogger(ABC): """Abstract writer to access log.""" - def __init__(self, logger, log_format): + def __init__(self, logger: logging.Logger, log_format: str) -> None: self.logger = logger self.log_format = log_format @abstractmethod - def log(self, request, response, time): + def log(self, + request: BaseRequest, + response: StreamResponse, + time: float) -> None: """Emit log to logger.""" diff --git a/aiohttp/base_protocol.py b/aiohttp/base_protocol.py index 43c0c46..cf4f9da 100644 --- a/aiohttp/base_protocol.py +++ b/aiohttp/base_protocol.py @@ -1,33 +1,29 @@ import asyncio +from typing import Optional, cast -from .log import internal_logger +from .tcp_helpers import tcp_nodelay class BaseProtocol(asyncio.Protocol): __slots__ = ('_loop', '_paused', '_drain_waiter', '_connection_lost', 'transport') - def __init__(self, loop=None): - if loop is None: - self._loop = asyncio.get_event_loop() - else: - self._loop = loop + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + self._loop = loop # type: asyncio.AbstractEventLoop self._paused = False - self._drain_waiter = None + self._drain_waiter = None # type: Optional[asyncio.Future[None]] self._connection_lost = False - self.transport = None + self._reading_paused = False - def pause_writing(self): + self.transport = None # type: Optional[asyncio.Transport] + + def pause_writing(self) -> None: assert not self._paused self._paused = True - if self._loop.get_debug(): - internal_logger.debug("%r pauses writing", self) - def resume_writing(self): + def resume_writing(self) -> None: assert self._paused self._paused = False - if self._loop.get_debug(): - internal_logger.debug("%r resumes writing", self) waiter = self._drain_waiter if waiter is not None: @@ -35,10 +31,28 @@ class BaseProtocol(asyncio.Protocol): if not waiter.done(): waiter.set_result(None) - def connection_made(self, transport): - self.transport = transport + def pause_reading(self) -> None: + if not self._reading_paused and self.transport is not None: + try: + self.transport.pause_reading() + except (AttributeError, NotImplementedError, RuntimeError): + pass + self._reading_paused = True + + def resume_reading(self) -> None: + if self._reading_paused and self.transport is not None: + try: + self.transport.resume_reading() + except (AttributeError, NotImplementedError, RuntimeError): + pass + self._reading_paused = False + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + tr = cast(asyncio.Transport, transport) + tcp_nodelay(tr, True) + self.transport = tr - def connection_lost(self, exc): + def connection_lost(self, exc: Optional[BaseException]) -> None: self._connection_lost = True # Wake up the writer if currently paused. self.transport = None @@ -55,7 +69,7 @@ class BaseProtocol(asyncio.Protocol): else: waiter.set_exception(exc) - async def _drain_helper(self): + async def _drain_helper(self) -> None: if self._connection_lost: raise ConnectionResetError('Connection lost') if not self._paused: diff --git a/aiohttp/client.py b/aiohttp/client.py index ec6e5a5..de3a996 100644 --- a/aiohttp/client.py +++ b/aiohttp/client.py @@ -8,8 +8,9 @@ import os import sys import traceback import warnings -from collections.abc import Coroutine as CoroutineABC -from typing import Any, Generator, Optional, Tuple +from types import SimpleNamespace, TracebackType +from typing import (Any, Coroutine, Generator, Generic, Iterable, List, # noqa + Mapping, Optional, Set, Tuple, Type, TypeVar, Union) import attr from multidict import CIMultiDict, MultiDict, MultiDictProxy, istr @@ -18,24 +19,27 @@ from yarl import URL from . import client_exceptions, client_reqrep from . import connector as connector_mod from . import hdrs, http, payload +from .abc import AbstractCookieJar from .client_exceptions import * # noqa from .client_exceptions import (ClientError, ClientOSError, InvalidURL, ServerTimeoutError, TooManyRedirects, WSServerHandshakeError) from .client_reqrep import * # noqa -from .client_reqrep import ClientRequest, ClientResponse, _merge_ssl_params +from .client_reqrep import (ClientRequest, ClientResponse, Fingerprint, + _merge_ssl_params) from .client_ws import ClientWebSocketResponse from .connector import * # noqa from .connector import BaseConnector, TCPConnector from .cookiejar import CookieJar -from .helpers import (DEBUG, PY_36, CeilTimeout, TimeoutHandle, - proxies_from_env, sentinel, strip_auth_from_url) -from .http import WS_KEY, WebSocketReader, WebSocketWriter -from .http_websocket import WSHandshakeError, ws_ext_gen, ws_ext_parse +from .helpers import (DEBUG, PY_36, BasicAuth, CeilTimeout, TimeoutHandle, + get_running_loop, proxies_from_env, sentinel, + strip_auth_from_url) +from .http import WS_KEY, HttpVersion, WebSocketReader, WebSocketWriter +from .http_websocket import (WSHandshakeError, WSMessage, ws_ext_gen, # noqa + ws_ext_parse) from .streams import FlowControlDataQueue -from .tcp_helpers import tcp_cork, tcp_nodelay -from .tracing import Trace -from .typedefs import StrOrURL +from .tracing import Trace, TraceConfig +from .typedefs import JSONEncoder, LooseCookies, LooseHeaders, StrOrURL __all__ = (client_exceptions.__all__ + # noqa @@ -45,6 +49,12 @@ __all__ = (client_exceptions.__all__ + # noqa 'ClientWebSocketResponse', 'request')) +try: + from ssl import SSLContext +except ImportError: # pragma: no cover + SSLContext = object # type: ignore + + @attr.s(frozen=True, slots=True) class ClientTimeout: total = attr.ib(type=float, default=None) @@ -69,6 +79,8 @@ class ClientTimeout: # 5 Minute default read timeout DEFAULT_TIMEOUT = ClientTimeout(total=5*60) +_RetType = TypeVar('_RetType') + class ClientSession: """First-class interface for making HTTP requests.""" @@ -78,6 +90,7 @@ class ClientSession: 'requote_redirect_url', '_loop', '_cookie_jar', '_connector_owner', '_default_auth', '_version', '_json_serialize', + '_requote_redirect_url', '_timeout', '_raise_for_status', '_auto_decompress', '_trust_env', '_default_headers', '_skip_auto_headers', '_request_class', '_response_class', @@ -86,28 +99,33 @@ class ClientSession: _source_traceback = None _connector = None - requote_redirect_url = True - - def __init__(self, *, connector=None, loop=None, cookies=None, - headers=None, skip_auto_headers=None, - auth=None, json_serialize=json.dumps, - request_class=ClientRequest, response_class=ClientResponse, - ws_response_class=ClientWebSocketResponse, - version=http.HttpVersion11, - cookie_jar=None, connector_owner=True, - raise_for_status=False, - read_timeout=sentinel, conn_timeout=None, - timeout=sentinel, - auto_decompress=True, trust_env=False, - trace_configs=None): - - implicit_loop = False + def __init__(self, *, connector: Optional[BaseConnector]=None, + loop: Optional[asyncio.AbstractEventLoop]=None, + cookies: Optional[LooseCookies]=None, + headers: LooseHeaders=None, + skip_auto_headers: Optional[Iterable[str]]=None, + auth: Optional[BasicAuth]=None, + json_serialize: JSONEncoder=json.dumps, + request_class: Type[ClientRequest]=ClientRequest, + response_class: Type[ClientResponse]=ClientResponse, + ws_response_class: Type[ClientWebSocketResponse]=ClientWebSocketResponse, # noqa + version: HttpVersion=http.HttpVersion11, + cookie_jar: Optional[AbstractCookieJar]=None, + connector_owner: bool=True, + raise_for_status: bool=False, + read_timeout: Union[float, object]=sentinel, + conn_timeout: Optional[float]=None, + timeout: Union[object, ClientTimeout]=sentinel, + auto_decompress: bool=True, + trust_env: bool=False, + requote_redirect_url: bool=True, + trace_configs: Optional[List[TraceConfig]]=None) -> None: + if loop is None: if connector is not None: loop = connector._loop - else: - implicit_loop = True - loop = asyncio.get_event_loop() + + loop = get_running_loop(loop) if connector is None: connector = TCPConnector(loop=loop) @@ -121,17 +139,6 @@ class ClientSession: if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) - if implicit_loop and not loop.is_running(): - warnings.warn("Creating a client session outside of coroutine is " - "a very dangerous idea", - stacklevel=2) - context = {'client_session': self, - 'message': 'Creating a client session outside ' - 'of coroutine'} - if self._source_traceback is not None: - context['source_traceback'] = self._source_traceback - loop.call_exception_handler(context) - if cookie_jar is None: cookie_jar = CookieJar(loop=loop) self._cookie_jar = cookie_jar @@ -144,8 +151,23 @@ class ClientSession: self._default_auth = auth self._version = version self._json_serialize = json_serialize - if timeout is not sentinel: - self._timeout = timeout + if timeout is sentinel: + self._timeout = DEFAULT_TIMEOUT + if read_timeout is not sentinel: + warnings.warn("read_timeout is deprecated, " + "use timeout argument instead", + DeprecationWarning, + stacklevel=2) + self._timeout = attr.evolve(self._timeout, total=read_timeout) + if conn_timeout is not None: + self._timeout = attr.evolve(self._timeout, + connect=conn_timeout) + warnings.warn("conn_timeout is deprecated, " + "use timeout argument instead", + DeprecationWarning, + stacklevel=2) + else: + self._timeout = timeout # type: ignore if read_timeout is not sentinel: raise ValueError("read_timeout and timeout parameters " "conflict, please setup " @@ -154,16 +176,10 @@ class ClientSession: raise ValueError("conn_timeout and timeout parameters " "conflict, please setup " "timeout.connect") - else: - self._timeout = DEFAULT_TIMEOUT - if read_timeout is not sentinel: - self._timeout = attr.evolve(self._timeout, total=read_timeout) - if conn_timeout is not None: - self._timeout = attr.evolve(self._timeout, - connect=conn_timeout) self._raise_for_status = raise_for_status self._auto_decompress = auto_decompress self._trust_env = trust_env + self._requote_redirect_url = requote_redirect_url # Convert to list of tuples if headers: @@ -185,14 +201,14 @@ class ClientSession: for trace_config in self._trace_configs: trace_config.freeze() - def __init_subclass__(cls): + def __init_subclass__(cls: Type['ClientSession']) -> None: warnings.warn("Inheritance class {} from ClientSession " "is discouraged".format(cls.__name__), DeprecationWarning, stacklevel=2) if DEBUG: - def __setattr__(self, name, val): + def __setattr__(self, name: str, val: Any) -> None: if name not in self.ATTRS: warnings.warn("Setting custom ClientSession.{} attribute " "is discouraged".format(name), @@ -200,7 +216,7 @@ class ClientSession: stacklevel=2) super().__setattr__(name, val) - def __del__(self, _warnings=warnings): + def __del__(self, _warnings: Any=warnings) -> None: if not self.closed: if PY_36: kwargs = {'source': self} @@ -218,33 +234,38 @@ class ClientSession: def request(self, method: str, url: StrOrURL, - **kwargs) -> '_RequestContextManager': + **kwargs: Any) -> '_RequestContextManager': """Perform HTTP request.""" return _RequestContextManager(self._request(method, url, **kwargs)) - async def _request(self, method, url, *, - params=None, - data=None, - json=None, - headers=None, - skip_auto_headers=None, - auth=None, - allow_redirects=True, - max_redirects=10, - compress=None, - chunked=None, - expect100=False, - raise_for_status=None, - read_until_eof=True, - proxy=None, - proxy_auth=None, - timeout=sentinel, - verify_ssl=None, - fingerprint=None, - ssl_context=None, - ssl=None, - proxy_headers=None, - trace_request_ctx=None): + async def _request( + self, + method: str, + str_or_url: StrOrURL, *, + params: Optional[Mapping[str, str]]=None, + data: Any=None, + json: Any=None, + cookies: Optional[LooseCookies]=None, + headers: LooseHeaders=None, + skip_auto_headers: Optional[Iterable[str]]=None, + auth: Optional[BasicAuth]=None, + allow_redirects: bool=True, + max_redirects: int=10, + compress: Optional[str]=None, + chunked: Optional[bool]=None, + expect100: bool=False, + raise_for_status: Optional[bool]=None, + read_until_eof: bool=True, + proxy: Optional[StrOrURL]=None, + proxy_auth: Optional[BasicAuth]=None, + timeout: Union[ClientTimeout, object]=sentinel, + verify_ssl: Optional[bool]=None, + fingerprint: Optional[bytes]=None, + ssl_context: Optional[SSLContext]=None, + ssl: Optional[Union[SSLContext, bool, Fingerprint]]=None, + proxy_headers: Optional[LooseHeaders]=None, + trace_request_ctx: Optional[SimpleNamespace]=None + ) -> ClientResponse: # NOTE: timeout clamps existing connect and read timeouts. We cannot # set the default to None because we need to detect if the user wants @@ -274,9 +295,9 @@ class ClientSession: proxy_headers = self._prepare_headers(proxy_headers) try: - url = URL(url) + url = URL(str_or_url) except ValueError: - raise InvalidURL(url) + raise InvalidURL(str_or_url) skip_headers = set(self._skip_auto_headers) if skip_auto_headers is not None: @@ -290,13 +311,15 @@ class ClientSession: raise InvalidURL(proxy) if timeout is sentinel: - timeout = self._timeout + real_timeout = self._timeout # type: ClientTimeout else: if not isinstance(timeout, ClientTimeout): - timeout = ClientTimeout(total=timeout) + real_timeout = ClientTimeout(total=timeout) # type: ignore + else: + real_timeout = timeout # timeout is cumulative for all request operations # (request, redirects, responses, data consuming) - tm = TimeoutHandle(self._loop, timeout.total) + tm = TimeoutHandle(self._loop, real_timeout.total) handle = tm.start() traces = [ @@ -338,7 +361,16 @@ class ClientSession: "with AUTH argument or credentials " "encoded in URL") - cookies = self._cookie_jar.filter_cookies(url) + session_cookies = self._cookie_jar.filter_cookies(url) + + if cookies is not None: + tmp_cookie_jar = CookieJar() + tmp_cookie_jar.update_cookies(cookies) + req_cookies = tmp_cookie_jar.filter_cookies(url) + if session_cookies and req_cookies: + session_cookies.load(req_cookies) + + cookies = session_cookies if proxy is not None: proxy = URL(proxy) @@ -362,27 +394,28 @@ class ClientSession: # connection timeout try: - with CeilTimeout(self._timeout.connect, + with CeilTimeout(real_timeout.connect, loop=self._loop): + assert self._connector is not None conn = await self._connector.connect( req, traces=traces, - timeout=timeout + timeout=real_timeout ) except asyncio.TimeoutError as exc: raise ServerTimeoutError( 'Connection timeout ' 'to host {0}'.format(url)) from exc - tcp_nodelay(conn.transport, True) - tcp_cork(conn.transport, False) + assert conn.transport is not None + assert conn.protocol is not None conn.protocol.set_response_params( timer=timer, skip_payload=method.upper() == 'HEAD', read_until_eof=read_until_eof, auto_decompress=self._auto_decompress, - read_timeout=timeout.sock_read) + read_timeout=real_timeout.sock_read) try: try: @@ -444,7 +477,7 @@ class ClientSession: try: r_url = URL( - r_url, encoded=not self.requote_redirect_url) + r_url, encoded=not self._requote_redirect_url) except ValueError: raise InvalidURL(r_url) @@ -508,28 +541,32 @@ class ClientSession: ) raise - def ws_connect(self, url: StrOrURL, *, - protocols=(), - timeout=10.0, - receive_timeout=None, - autoclose=True, - autoping=True, - heartbeat=None, - auth=None, - origin=None, - headers=None, - proxy=None, - proxy_auth=None, - ssl=None, - verify_ssl=None, - fingerprint=None, - ssl_context=None, - proxy_headers=None, - compress=0, - max_msg_size=4*1024*1024): + def ws_connect( + self, + url: StrOrURL, *, + method: str=hdrs.METH_GET, + protocols: Iterable[str]=(), + timeout: float=10.0, + receive_timeout: Optional[float]=None, + autoclose: bool=True, + autoping: bool=True, + heartbeat: Optional[float]=None, + auth: Optional[BasicAuth]=None, + origin: Optional[str]=None, + headers: Optional[LooseHeaders]=None, + proxy: Optional[StrOrURL]=None, + proxy_auth: Optional[BasicAuth]=None, + ssl: Union[SSLContext, bool, None, Fingerprint]=None, + verify_ssl: Optional[bool]=None, + fingerprint: Optional[bytes]=None, + ssl_context: Optional[SSLContext]=None, + proxy_headers: Optional[LooseHeaders]=None, + compress: int=0, + max_msg_size: int=4*1024*1024) -> '_WSRequestContextManager': """Initiate websocket connection.""" return _WSRequestContextManager( self._ws_connect(url, + method=method, protocols=protocols, timeout=timeout, receive_timeout=receive_timeout, @@ -549,28 +586,34 @@ class ClientSession: compress=compress, max_msg_size=max_msg_size)) - async def _ws_connect(self, url, *, - protocols=(), - timeout=10.0, - receive_timeout=None, - autoclose=True, - autoping=True, - heartbeat=None, - auth=None, - origin=None, - headers=None, - proxy=None, - proxy_auth=None, - ssl=None, - verify_ssl=None, - fingerprint=None, - ssl_context=None, - proxy_headers=None, - compress=0, - max_msg_size=4*1024*1024): + async def _ws_connect( + self, + url: StrOrURL, *, + method: str=hdrs.METH_GET, + protocols: Iterable[str]=(), + timeout: float=10.0, + receive_timeout: Optional[float]=None, + autoclose: bool=True, + autoping: bool=True, + heartbeat: Optional[float]=None, + auth: Optional[BasicAuth]=None, + origin: Optional[str]=None, + headers: Optional[LooseHeaders]=None, + proxy: Optional[StrOrURL]=None, + proxy_auth: Optional[BasicAuth]=None, + ssl: Union[SSLContext, bool, None, Fingerprint]=None, + verify_ssl: Optional[bool]=None, + fingerprint: Optional[bytes]=None, + ssl_context: Optional[SSLContext]=None, + proxy_headers: Optional[LooseHeaders]=None, + compress: int=0, + max_msg_size: int=4*1024*1024 + ) -> ClientWebSocketResponse: if headers is None: - headers = CIMultiDict() + real_headers = CIMultiDict() # type: CIMultiDict[str] + else: + real_headers = CIMultiDict(headers) default_headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, @@ -579,30 +622,30 @@ class ClientSession: } for key, value in default_headers.items(): - if key not in headers: - headers[key] = value + real_headers.setdefault(key, value) sec_key = base64.b64encode(os.urandom(16)) - headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode() + real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode() if protocols: - headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = ','.join(protocols) + real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = ','.join(protocols) if origin is not None: - headers[hdrs.ORIGIN] = origin + real_headers[hdrs.ORIGIN] = origin if compress: extstr = ws_ext_gen(compress=compress) - headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr + real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint) # send request - resp = await self.get(url, headers=headers, - read_until_eof=False, - auth=auth, - proxy=proxy, - proxy_auth=proxy_auth, - ssl=ssl, - proxy_headers=proxy_headers) + resp = await self.request(method, url, + headers=real_headers, + read_until_eof=False, + auth=auth, + proxy=proxy, + proxy_auth=proxy_auth, + ssl=ssl, + proxy_headers=proxy_headers) try: # check handshake @@ -672,12 +715,15 @@ class ClientSession: compress = 0 notakeover = False - proto = resp.connection.protocol - transport = resp.connection.transport + conn = resp.connection + assert conn is not None + proto = conn.protocol + assert proto is not None + transport = conn.transport + assert transport is not None reader = FlowControlDataQueue( - proto, limit=2 ** 16, loop=self._loop) + proto, limit=2 ** 16, loop=self._loop) # type: FlowControlDataQueue[WSMessage] # noqa proto.set_parser(WebSocketReader(reader, max_msg_size), reader) - tcp_nodelay(transport, True) writer = WebSocketWriter( proto, transport, use_mask=True, compress=compress, notakeover=notakeover) @@ -698,7 +744,9 @@ class ClientSession: compress=compress, client_notakeover=notakeover) - def _prepare_headers(self, headers): + def _prepare_headers( + self, + headers: Optional[LooseHeaders]) -> 'CIMultiDict[str]': """ Add default headers and transform it to CIMultiDict """ # Convert headers to MultiDict @@ -706,7 +754,7 @@ class ClientSession: if headers: if not isinstance(headers, (MultiDictProxy, MultiDict)): headers = CIMultiDict(headers) - added_names = set() + added_names = set() # type: Set[str] for key, value in headers.items(): if key in added_names: result.add(key, value) @@ -716,7 +764,7 @@ class ClientSession: return result def get(self, url: StrOrURL, *, allow_redirects: bool=True, - **kwargs) -> '_RequestContextManager': + **kwargs: Any) -> '_RequestContextManager': """Perform HTTP GET request.""" return _RequestContextManager( self._request(hdrs.METH_GET, url, @@ -724,7 +772,7 @@ class ClientSession: **kwargs)) def options(self, url: StrOrURL, *, allow_redirects: bool=True, - **kwargs) -> '_RequestContextManager': + **kwargs: Any) -> '_RequestContextManager': """Perform HTTP OPTIONS request.""" return _RequestContextManager( self._request(hdrs.METH_OPTIONS, url, @@ -732,7 +780,7 @@ class ClientSession: **kwargs)) def head(self, url: StrOrURL, *, allow_redirects: bool=False, - **kwargs) -> '_RequestContextManager': + **kwargs: Any) -> '_RequestContextManager': """Perform HTTP HEAD request.""" return _RequestContextManager( self._request(hdrs.METH_HEAD, url, @@ -740,7 +788,7 @@ class ClientSession: **kwargs)) def post(self, url: StrOrURL, - *, data: Any=None, **kwargs) -> '_RequestContextManager': + *, data: Any=None, **kwargs: Any) -> '_RequestContextManager': """Perform HTTP POST request.""" return _RequestContextManager( self._request(hdrs.METH_POST, url, @@ -748,7 +796,7 @@ class ClientSession: **kwargs)) def put(self, url: StrOrURL, - *, data: Any=None, **kwargs) -> '_RequestContextManager': + *, data: Any=None, **kwargs: Any) -> '_RequestContextManager': """Perform HTTP PUT request.""" return _RequestContextManager( self._request(hdrs.METH_PUT, url, @@ -756,14 +804,14 @@ class ClientSession: **kwargs)) def patch(self, url: StrOrURL, - *, data: Any=None, **kwargs) -> '_RequestContextManager': + *, data: Any=None, **kwargs: Any) -> '_RequestContextManager': """Perform HTTP PATCH request.""" return _RequestContextManager( self._request(hdrs.METH_PATCH, url, data=data, **kwargs)) - def delete(self, url: StrOrURL, **kwargs) -> '_RequestContextManager': + def delete(self, url: StrOrURL, **kwargs: Any) -> '_RequestContextManager': """Perform HTTP DELETE request.""" return _RequestContextManager( self._request(hdrs.METH_DELETE, url, @@ -776,7 +824,7 @@ class ClientSession: """ if not self.closed: if self._connector is not None and self._connector_owner: - self._connector.close() + await self._connector.close() self._connector = None @property @@ -793,7 +841,7 @@ class ClientSession: return self._connector @property - def cookie_jar(self) -> CookieJar: + def cookie_jar(self) -> AbstractCookieJar: """The session cookies.""" return self._cookie_jar @@ -803,8 +851,25 @@ class ClientSession: return self._version @property + def requote_redirect_url(self) -> bool: + """Do URL requoting on redirection handling.""" + return self._requote_redirect_url + + @requote_redirect_url.setter + def requote_redirect_url(self, val: bool) -> None: + """Do URL requoting on redirection handling.""" + warnings.warn("session.requote_redirect_url modification " + "is deprecated #2778", + DeprecationWarning, + stacklevel=2) + self._requote_redirect_url = val + + @property def loop(self) -> asyncio.AbstractEventLoop: """Session's loop.""" + warnings.warn("client.loop property is deprecated", + DeprecationWarning, + stacklevel=2) return self._loop def detach(self) -> None: @@ -814,50 +879,65 @@ class ClientSession: """ self._connector = None - def __enter__(self): + def __enter__(self) -> None: raise TypeError("Use async with instead") - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__(self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> None: # __exit__ should exist in pair with __enter__ but never executed pass # pragma: no cover async def __aenter__(self) -> 'ClientSession': return self - async def __aexit__(self, exc_type, exc_val, exc_tb): + async def __aexit__(self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> None: await self.close() -class _BaseRequestContextManager(CoroutineABC): +class _BaseRequestContextManager(Coroutine[Any, + Any, + _RetType], + Generic[_RetType]): __slots__ = ('_coro', '_resp') - def __init__(self, coro): + def __init__( + self, + coro: Coroutine['asyncio.Future[Any]', None, _RetType] + ) -> None: self._coro = coro - def send(self, arg): + def send(self, arg: None) -> 'asyncio.Future[Any]': return self._coro.send(arg) - def throw(self, arg): - return self._coro.throw(arg) + def throw(self, arg: BaseException) -> None: # type: ignore + self._coro.throw(arg) # type: ignore - def close(self): + def close(self) -> None: return self._coro.close() - def __await__(self) -> Generator[Any, None, ClientResponse]: + def __await__(self) -> Generator[Any, None, _RetType]: ret = self._coro.__await__() return ret - def __iter__(self): + def __iter__(self) -> Generator[Any, None, _RetType]: return self.__await__() - async def __aenter__(self) -> ClientResponse: + async def __aenter__(self) -> _RetType: self._resp = await self._coro return self._resp -class _RequestContextManager(_BaseRequestContextManager): - async def __aexit__(self, exc_type, exc, tb): +class _RequestContextManager(_BaseRequestContextManager[ClientResponse]): + async def __aexit__(self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType]) -> None: # We're basing behavior on the exception as it can be caused by # user code unrelated to the status of the connection. If you # would like to close a connection you must do that @@ -866,8 +946,12 @@ class _RequestContextManager(_BaseRequestContextManager): self._resp.release() -class _WSRequestContextManager(_BaseRequestContextManager): - async def __aexit__(self, exc_type, exc, tb): +class _WSRequestContextManager(_BaseRequestContextManager[ + ClientWebSocketResponse]): + async def __aexit__(self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType]) -> None: await self._resp.close() @@ -875,39 +959,50 @@ class _SessionRequestContextManager: __slots__ = ('_coro', '_resp', '_session') - def __init__(self, coro, session): + def __init__(self, + coro: Coroutine['asyncio.Future[Any]', None, ClientResponse], + session: ClientSession) -> None: self._coro = coro - self._resp = None + self._resp = None # type: Optional[ClientResponse] self._session = session async def __aenter__(self) -> ClientResponse: self._resp = await self._coro return self._resp - async def __aexit__(self, exc_type, exc_val, exc_tb): + async def __aexit__(self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType]) -> None: + assert self._resp is not None self._resp.close() await self._session.close() -def request(method, url, *, - params=None, - data=None, - json=None, - headers=None, - skip_auto_headers=None, - cookies=None, - auth=None, - allow_redirects=True, - max_redirects=10, - version=http.HttpVersion11, - compress=None, - chunked=None, - expect100=False, - connector=None, - loop=None, - read_until_eof=True, - proxy=None, - proxy_auth=None) -> _SessionRequestContextManager: +def request( + method: str, + url: StrOrURL, *, + params: Optional[Mapping[str, str]]=None, + data: Any=None, + json: Any=None, + headers: LooseHeaders=None, + skip_auto_headers: Optional[Iterable[str]]=None, + auth: Optional[BasicAuth]=None, + allow_redirects: bool=True, + max_redirects: int=10, + compress: Optional[str]=None, + chunked: Optional[bool]=None, + expect100: bool=False, + raise_for_status: Optional[bool]=None, + read_until_eof: bool=True, + proxy: Optional[StrOrURL]=None, + proxy_auth: Optional[BasicAuth]=None, + timeout: Union[ClientTimeout, object]=sentinel, + cookies: Optional[LooseCookies]=None, + version: HttpVersion=http.HttpVersion11, + connector: Optional[BaseConnector]=None, + loop: Optional[asyncio.AbstractEventLoop]=None +) -> _SessionRequestContextManager: """Constructs and sends a request. Returns response object. method - HTTP method url - request url @@ -915,7 +1010,7 @@ def request(method, url, *, string of the new request data - (optional) Dictionary, bytes, or file-like object to send in the body of the request - json - (optional) Any json compatibile python object + json - (optional) Any json compatible python object headers - (optional) Dictionary of HTTP Headers to send with the request cookies - (optional) Dict object to send with the request @@ -933,6 +1028,8 @@ def request(method, url, *, read_until_eof - Read response until eof if response does not have Content-Length header. loop - Optional event loop. + timeout - Optional ClientTimeout settings structure, 5min + total timeout by default. Usage:: >>> import aiohttp >>> resp = await aiohttp.request('GET', 'http://python.org/') @@ -946,7 +1043,7 @@ def request(method, url, *, connector = TCPConnector(loop=loop, force_close=True) session = ClientSession( - loop=loop, cookies=cookies, version=version, + loop=loop, cookies=cookies, version=version, timeout=timeout, connector=connector, connector_owner=connector_owner) return _SessionRequestContextManager( @@ -962,6 +1059,7 @@ def request(method, url, *, compress=compress, chunked=chunked, expect100=expect100, + raise_for_status=raise_for_status, read_until_eof=read_until_eof, proxy=proxy, proxy_auth=proxy_auth,), diff --git a/aiohttp/client_exceptions.py b/aiohttp/client_exceptions.py index 207aa13..a23ff96 100644 --- a/aiohttp/client_exceptions.py +++ b/aiohttp/client_exceptions.py @@ -2,12 +2,23 @@ import asyncio import warnings +from typing import TYPE_CHECKING, Any, Optional, Tuple, Union + +from .typedefs import _CIMultiDict try: import ssl + SSLContext = ssl.SSLContext except ImportError: # pragma: no cover - ssl = None # type: ignore + ssl = SSLContext = None # type: ignore + + +if TYPE_CHECKING: # pragma: no cover + from .client_reqrep import (RequestInfo, ClientResponse, ConnectionKey, # noqa + Fingerprint) +else: + RequestInfo = ClientResponse = ConnectionKey = None __all__ = ( @@ -38,8 +49,12 @@ class ClientResponseError(ClientError): request_info: instance of RequestInfo """ - def __init__(self, request_info, history, *, - code=None, status=None, message='', headers=None): + def __init__(self, request_info: RequestInfo, + history: Tuple[ClientResponse, ...], *, + code: Optional[int]=None, + status: Optional[int]=None, + message: str='', + headers: Optional[_CIMultiDict]=None) -> None: self.request_info = request_info if code is not None: if status is not None: @@ -62,14 +77,14 @@ class ClientResponseError(ClientError): super().__init__("%s, message='%s'" % (self.status, message)) @property - def code(self): + def code(self) -> int: warnings.warn("code property is deprecated, use status instead", DeprecationWarning, stacklevel=2) return self.status @code.setter - def code(self, value): + def code(self, value: int) -> None: warnings.warn("code property is deprecated, use status instead", DeprecationWarning, stacklevel=2) @@ -111,28 +126,29 @@ class ClientConnectorError(ClientOSError): Raised in :class:`aiohttp.connector.TCPConnector` if connection to proxy can not be established. """ - def __init__(self, connection_key, os_error): + def __init__(self, connection_key: ConnectionKey, + os_error: OSError) -> None: self._conn_key = connection_key self._os_error = os_error super().__init__(os_error.errno, os_error.strerror) @property - def os_error(self): + def os_error(self) -> OSError: return self._os_error @property - def host(self): + def host(self) -> str: return self._conn_key.host @property - def port(self): + def port(self) -> Optional[int]: return self._conn_key.port @property - def ssl(self): + def ssl(self) -> Union[SSLContext, None, bool, 'Fingerprint']: return self._conn_key.ssl - def __str__(self): + def __str__(self) -> str: return ('Cannot connect to host {0.host}:{0.port} ssl:{0.ssl} [{1}]' .format(self, self.strerror)) @@ -152,7 +168,7 @@ class ServerConnectionError(ClientConnectionError): class ServerDisconnectedError(ServerConnectionError): """Server disconnected.""" - def __init__(self, message=None): + def __init__(self, message: Optional[str]=None) -> None: self.message = message @@ -163,13 +179,14 @@ class ServerTimeoutError(ServerConnectionError, asyncio.TimeoutError): class ServerFingerprintMismatch(ServerConnectionError): """SSL certificate does not match expected fingerprint.""" - def __init__(self, expected, got, host, port): + def __init__(self, expected: bytes, got: bytes, + host: str, port: int) -> None: self.expected = expected self.got = got self.host = host self.port = port - def __repr__(self): + def __repr__(self) -> str: return '<{} expected={} got={} host={} port={}>'.format( self.__class__.__name__, self.expected, self.got, self.host, self.port) @@ -187,14 +204,16 @@ class InvalidURL(ClientError, ValueError): # Derive from ValueError for backward compatibility - def __init__(self, url): + def __init__(self, url: Any) -> None: + # The type of url is not yarl.URL because the exception can be raised + # on URL(url) call super().__init__(url) @property - def url(self): + def url(self) -> Any: return self.args[0] - def __repr__(self): + def __repr__(self) -> str: return '<{} {}>'.format(self.__class__.__name__, self.url) @@ -223,27 +242,28 @@ class ClientConnectorSSLError(*ssl_error_bases): # type: ignore class ClientConnectorCertificateError(*cert_errors_bases): # type: ignore """Response certificate error.""" - def __init__(self, connection_key, certificate_error): + def __init__(self, connection_key: + ConnectionKey, certificate_error: Exception) -> None: self._conn_key = connection_key self._certificate_error = certificate_error @property - def certificate_error(self): + def certificate_error(self) -> Exception: return self._certificate_error @property - def host(self): + def host(self) -> str: return self._conn_key.host @property - def port(self): + def port(self) -> Optional[int]: return self._conn_key.port @property - def ssl(self): + def ssl(self) -> bool: return self._conn_key.is_ssl - def __str__(self): + def __str__(self) -> str: return ('Cannot connect to host {0.host}:{0.port} ssl:{0.ssl} ' '[{0.certificate_error.__class__.__name__}: ' '{0.certificate_error.args}]'.format(self)) diff --git a/aiohttp/client_proto.py b/aiohttp/client_proto.py index 4c55ae1..9e8047a 100644 --- a/aiohttp/client_proto.py +++ b/aiohttp/client_proto.py @@ -1,41 +1,45 @@ +import asyncio from contextlib import suppress +from typing import Any, Optional, Tuple from .base_protocol import BaseProtocol from .client_exceptions import (ClientOSError, ClientPayloadError, ServerDisconnectedError, ServerTimeoutError) -from .http import HttpResponseParser -from .streams import EMPTY_PAYLOAD, DataQueue +from .helpers import BaseTimerContext +from .http import HttpResponseParser, RawResponseMessage +from .streams import EMPTY_PAYLOAD, DataQueue, StreamReader -class ResponseHandler(BaseProtocol, DataQueue): +class ResponseHandler(BaseProtocol, + DataQueue[Tuple[RawResponseMessage, StreamReader]]): """Helper class to adapt between Protocol and StreamReader.""" - def __init__(self, *, loop=None): + def __init__(self, + loop: asyncio.AbstractEventLoop) -> None: BaseProtocol.__init__(self, loop=loop) - DataQueue.__init__(self, loop=loop) + DataQueue.__init__(self, loop) self._should_close = False self._payload = None self._skip_payload = False self._payload_parser = None - self._reading_paused = False self._timer = None self._tail = b'' self._upgraded = False - self._parser = None + self._parser = None # type: Optional[HttpResponseParser] - self._read_timeout = None - self._read_timeout_handle = None + self._read_timeout = None # type: Optional[float] + self._read_timeout_handle = None # type: Optional[asyncio.TimerHandle] @property - def upgraded(self): + def upgraded(self) -> bool: return self._upgraded @property - def should_close(self): + def should_close(self) -> bool: if (self._payload is not None and not self._payload.is_eof() or self._upgraded): return True @@ -43,37 +47,38 @@ class ResponseHandler(BaseProtocol, DataQueue): return (self._should_close or self._upgraded or self.exception() is not None or self._payload_parser is not None or - len(self) or self._tail) + len(self) > 0 or bool(self._tail)) - def force_close(self): + def force_close(self) -> None: self._should_close = True - def close(self): + def close(self) -> None: transport = self.transport if transport is not None: transport.close() self.transport = None self._payload = None self._drop_timeout() - return transport - def is_connected(self): + def is_connected(self) -> bool: return self.transport is not None - def connection_lost(self, exc): + def connection_lost(self, exc: Optional[BaseException]) -> None: self._drop_timeout() if self._payload_parser is not None: with suppress(Exception): self._payload_parser.feed_eof() - try: - uncompleted = self._parser.feed_eof() - except Exception: - uncompleted = None - if self._payload is not None: - self._payload.set_exception( - ClientPayloadError('Response payload is not completed')) + uncompleted = None + if self._parser is not None: + try: + uncompleted = self._parser.feed_eof() + except Exception: + if self._payload is not None: + self._payload.set_exception( + ClientPayloadError( + 'Response payload is not completed')) if not self.is_eof(): if isinstance(exc, OSError): @@ -92,34 +97,29 @@ class ResponseHandler(BaseProtocol, DataQueue): super().connection_lost(exc) - def eof_received(self): + def eof_received(self) -> None: # should call parser.feed_eof() most likely self._drop_timeout() - def pause_reading(self): - if not self._reading_paused: - try: - self.transport.pause_reading() - except (AttributeError, NotImplementedError, RuntimeError): - pass - self._reading_paused = True - self._drop_timeout() + def pause_reading(self) -> None: + super().pause_reading() + self._drop_timeout() - def resume_reading(self): - if self._reading_paused: - try: - self.transport.resume_reading() - except (AttributeError, NotImplementedError, RuntimeError): - pass - self._reading_paused = False - self._reschedule_timeout() + def resume_reading(self) -> None: + super().resume_reading() + self._reschedule_timeout() - def set_exception(self, exc): + def set_exception(self, exc: BaseException) -> None: self._should_close = True self._drop_timeout() super().set_exception(exc) - def set_parser(self, parser, payload): + def set_parser(self, parser: Any, payload: Any) -> None: + # TODO: actual types are: + # parser: WebSocketReader + # payload: FlowControlDataQueue + # but they are not generi enough + # Need an ABC for both types self._payload = payload self._payload_parser = parser @@ -129,11 +129,11 @@ class ResponseHandler(BaseProtocol, DataQueue): data, self._tail = self._tail, b'' self.data_received(data) - def set_response_params(self, *, timer=None, - skip_payload=False, - read_until_eof=False, - auto_decompress=True, - read_timeout=None): + def set_response_params(self, *, timer: BaseTimerContext=None, + skip_payload: bool=False, + read_until_eof: bool=False, + auto_decompress: bool=True, + read_timeout: Optional[float]=None) -> None: self._skip_payload = skip_payload self._read_timeout = read_timeout @@ -149,12 +149,12 @@ class ResponseHandler(BaseProtocol, DataQueue): data, self._tail = self._tail, b'' self.data_received(data) - def _drop_timeout(self): + def _drop_timeout(self) -> None: if self._read_timeout_handle is not None: self._read_timeout_handle.cancel() self._read_timeout_handle = None - def _reschedule_timeout(self): + def _reschedule_timeout(self) -> None: timeout = self._read_timeout if self._read_timeout_handle is not None: self._read_timeout_handle.cancel() @@ -165,13 +165,13 @@ class ResponseHandler(BaseProtocol, DataQueue): else: self._read_timeout_handle = None - def _on_read_timeout(self): + def _on_read_timeout(self) -> None: exc = ServerTimeoutError("Timeout on reading data from socket") self.set_exception(exc) if self._payload is not None: self._payload.set_exception(exc) - def data_received(self, data): + def data_received(self, data: bytes) -> None: if not data: return @@ -213,13 +213,13 @@ class ResponseHandler(BaseProtocol, DataQueue): self._payload = payload if self._skip_payload or message.code in (204, 304): - self.feed_data((message, EMPTY_PAYLOAD), 0) + self.feed_data((message, EMPTY_PAYLOAD), 0) # type: ignore # noqa else: self.feed_data((message, payload), 0) if payload is not None: # new message(s) was processed # register timeout handler unsubscribing - # either on end-of-stream or immediatelly for + # either on end-of-stream or immediately for # EMPTY_PAYLOAD if payload is not EMPTY_PAYLOAD: payload.on_eof(self._drop_timeout) diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py index 5e82d2f..6a7fe81 100644 --- a/aiohttp/client_reqrep.py +++ b/aiohttp/client_reqrep.py @@ -7,29 +7,35 @@ import traceback import warnings from hashlib import md5, sha1, sha256 from http.cookies import CookieError, Morsel, SimpleCookie -from types import MappingProxyType -from typing import Any, Optional, Tuple +from types import MappingProxyType, TracebackType +from typing import (TYPE_CHECKING, Any, Dict, Iterable, List, Mapping, # noqa + Optional, Tuple, Type, Union, cast) import attr from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy from yarl import URL from . import hdrs, helpers, http, multipart, payload +from .abc import AbstractStreamWriter from .client_exceptions import (ClientConnectionError, ClientOSError, ClientResponseError, ContentTypeError, InvalidURL, ServerFingerprintMismatch) from .formdata import FormData -from .helpers import PY_36, HeadersMixin, TimerNoop, noop, reify, set_result +from .helpers import (PY_36, BaseTimerContext, BasicAuth, HeadersMixin, # noqa + TimerNoop, noop, reify, set_result) from .http import SERVER_SOFTWARE, HttpVersion10, HttpVersion11, StreamWriter from .log import client_logger from .streams import StreamReader # noqa -from .typedefs import DEFAULT_JSON_DECODER, JSONDecoder, RawHeaders +from .typedefs import (DEFAULT_JSON_DECODER, JSONDecoder, LooseCookies, + LooseHeaders, RawHeaders) try: import ssl + from ssl import SSLContext except ImportError: # pragma: no cover ssl = None # type: ignore + SSLContext = object # type: ignore try: import cchardet as chardet @@ -40,25 +46,31 @@ except ImportError: # pragma: no cover __all__ = ('ClientRequest', 'ClientResponse', 'RequestInfo', 'Fingerprint') +if TYPE_CHECKING: # pragma: no cover + from .client import ClientSession # noqa + from .connector import Connection # noqa + from .tracing import Trace # noqa + + json_re = re.compile(r'^application/(?:[\w.+-]+?\+)?json') @attr.s(frozen=True, slots=True) class ContentDisposition: - type = attr.ib(type=str) - parameters = attr.ib(type=MappingProxyType) - filename = attr.ib(type=str) + type = attr.ib(type=str) # type: Optional[str] + parameters = attr.ib(type=MappingProxyType) # type: MappingProxyType[str, str] # noqa + filename = attr.ib(type=str) # type: Optional[str] @attr.s(frozen=True, slots=True) class RequestInfo: url = attr.ib(type=URL) method = attr.ib(type=str) - headers = attr.ib(type=CIMultiDictProxy) + headers = attr.ib(type=CIMultiDictProxy) # type: CIMultiDictProxy[str] real_url = attr.ib(type=URL) @real_url.default - def real_url_default(self): + def real_url_default(self) -> URL: return self.url @@ -69,7 +81,7 @@ class Fingerprint: 32: sha256, } - def __init__(self, fingerprint): + def __init__(self, fingerprint: bytes) -> None: digestlen = len(fingerprint) hashfunc = self.HASHFUNC_BY_DIGESTLEN.get(digestlen) if not hashfunc: @@ -81,10 +93,10 @@ class Fingerprint: self._fingerprint = fingerprint @property - def fingerprint(self): + def fingerprint(self) -> bytes: return self._fingerprint - def check(self, transport): + def check(self, transport: asyncio.Transport) -> None: if not transport.get_extra_info('sslcontext'): return sslobj = transport.get_extra_info('ssl_object') @@ -102,7 +114,12 @@ else: # pragma: no cover SSL_ALLOWED_TYPES = type(None) -def _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint): +def _merge_ssl_params( + ssl: Union['SSLContext', bool, Fingerprint, None], + verify_ssl: Optional[bool], + ssl_context: Optional['SSLContext'], + fingerprint: Optional[bytes] +) -> Union['SSLContext', bool, Fingerprint, None]: if verify_ssl is not None and not verify_ssl: warnings.warn("verify_ssl is deprecated, use ssl=False instead", DeprecationWarning, @@ -142,17 +159,18 @@ class ConnectionKey: # the key should contain an information about used proxy / TLS # to prevent reusing wrong connections from a pool host = attr.ib(type=str) - port = attr.ib(type=int) + port = attr.ib(type=int) # type: Optional[int] is_ssl = attr.ib(type=bool) - ssl = attr.ib() # SSLContext or None - proxy = attr.ib() # URL or None - proxy_auth = attr.ib() # BasicAuth - proxy_headers_hash = attr.ib(type=int) # hash(CIMultiDict) + ssl = attr.ib() # type: Union[SSLContext, None, bool, Fingerprint] + proxy = attr.ib() # type: Optional[URL] + proxy_auth = attr.ib() # type: Optional[BasicAuth] + proxy_headers_hash = attr.ib(type=int) # type: Optional[int] # noqa # hash(CIMultiDict) -def _is_expected_content_type(response_content_type, expected_content_type): +def _is_expected_content_type(response_content_type: str, + expected_content_type: str) -> bool: if expected_content_type == 'application/json': - return json_re.match(response_content_type) + return json_re.match(response_content_type) is not None return expected_content_type in response_content_type @@ -184,24 +202,35 @@ class ClientRequest: # because _writer is instance method, thus it keeps a reference to self. # Until writer has finished finalizer will not be called. - def __init__(self, method, url, *, - params=None, headers=None, skip_auto_headers=frozenset(), - data=None, cookies=None, - auth=None, version=http.HttpVersion11, compress=None, - chunked=None, expect100=False, - loop=None, response_class=None, - proxy=None, proxy_auth=None, - timer=None, session=None, - ssl=None, - proxy_headers=None, - traces=None): + def __init__(self, method: str, url: URL, *, + params: Optional[Mapping[str, str]]=None, + headers: Optional[LooseHeaders]=None, + skip_auto_headers: Iterable[str]=frozenset(), + data: Any=None, + cookies: Optional[LooseCookies]=None, + auth: Optional[BasicAuth]=None, + version: http.HttpVersion=http.HttpVersion11, + compress: Optional[str]=None, + chunked: Optional[bool]=None, + expect100: bool=False, + loop: Optional[asyncio.AbstractEventLoop]=None, + response_class: Optional[Type['ClientResponse']]=None, + proxy: Optional[URL]=None, + proxy_auth: Optional[BasicAuth]=None, + timer: Optional[BaseTimerContext]=None, + session: Optional['ClientSession']=None, + ssl: Union[SSLContext, bool, Fingerprint, None]=None, + proxy_headers: Optional[LooseHeaders]=None, + traces: Optional[List['Trace']]=None): if loop is None: loop = asyncio.get_event_loop() assert isinstance(url, URL), url assert isinstance(proxy, (URL, type(None))), proxy - self._session = session + # FIXME: session is None in tests only, need to fix tests + # assert session is not None + self._session = cast('ClientSession', session) if params: q = MultiDict(url.query) url2 = url.with_query(params) @@ -214,7 +243,11 @@ class ClientRequest: self.compress = compress self.loop = loop self.length = None - self.response_class = response_class or ClientResponse + if response_class is None: + real_response_class = ClientResponse + else: + real_response_class = response_class + self.response_class = real_response_class # type: Type[ClientResponse] self._timer = timer if timer is not None else TimerNoop() self._ssl = ssl @@ -238,18 +271,18 @@ class ClientRequest: traces = [] self._traces = traces - def is_ssl(self): + def is_ssl(self) -> bool: return self.url.scheme in ('https', 'wss') @property - def ssl(self): + def ssl(self) -> Union['SSLContext', None, bool, Fingerprint]: return self._ssl @property - def connection_key(self): + def connection_key(self) -> ConnectionKey: proxy_headers = self.proxy_headers if proxy_headers: - h = hash(tuple((k, v) for k, v in proxy_headers.items())) + h = hash(tuple((k, v) for k, v in proxy_headers.items())) # type: Optional[int] # noqa else: h = None return ConnectionKey(self.host, self.port, self.is_ssl(), @@ -257,19 +290,22 @@ class ClientRequest: self.proxy, self.proxy_auth, h) @property - def host(self): - return self.url.host + def host(self) -> str: + ret = self.url.host + assert ret is not None + return ret @property - def port(self): + def port(self) -> Optional[int]: return self.url.port @property - def request_info(self): + def request_info(self) -> RequestInfo: + headers = CIMultiDictProxy(self.headers) # type: CIMultiDictProxy[str] return RequestInfo(self.url, self.method, - self.headers, self.original_url) + headers, self.original_url) - def update_host(self, url): + def update_host(self, url: URL) -> None: """Update destination host, port and connection type (ssl).""" # get host/port if not url.host: @@ -280,7 +316,7 @@ class ClientRequest: if username: self.auth = helpers.BasicAuth(username, password or '') - def update_version(self, version): + def update_version(self, version: Union[http.HttpVersion, str]) -> None: """Convert request version to two elements tuple. parser HTTP version '1.1' => (1, 1) @@ -288,44 +324,50 @@ class ClientRequest: if isinstance(version, str): v = [l.strip() for l in version.split('.', 1)] try: - version = int(v[0]), int(v[1]) + version = http.HttpVersion(int(v[0]), int(v[1])) except ValueError: raise ValueError( 'Can not parse http version number: {}' .format(version)) from None self.version = version - def update_headers(self, headers): + def update_headers(self, headers: Optional[LooseHeaders]) -> None: """Update request headers.""" - self.headers = CIMultiDict() + self.headers = CIMultiDict() # type: CIMultiDict[str] + + # add host + netloc = cast(str, self.url.raw_host) + if helpers.is_ipv6_address(netloc): + netloc = '[{}]'.format(netloc) + if not self.url.is_default_port(): + netloc += ':' + str(self.url.port) + self.headers[hdrs.HOST] = netloc + if headers: if isinstance(headers, (dict, MultiDictProxy, MultiDict)): - headers = headers.items() + headers = headers.items() # type: ignore for key, value in headers: - self.headers.add(key, value) + # A special case for Host header + if key.lower() == 'host': + self.headers[key] = value + else: + self.headers.add(key, value) - def update_auto_headers(self, skip_auto_headers): + def update_auto_headers(self, skip_auto_headers: Iterable[str]) -> None: self.skip_auto_headers = CIMultiDict( (hdr, None) for hdr in sorted(skip_auto_headers)) used_headers = self.headers.copy() - used_headers.extend(self.skip_auto_headers) + used_headers.extend(self.skip_auto_headers) # type: ignore for hdr, val in self.DEFAULT_HEADERS.items(): if hdr not in used_headers: self.headers.add(hdr, val) - # add host - if hdrs.HOST not in used_headers: - netloc = self.url.raw_host - if not self.url.is_default_port(): - netloc += ':' + str(self.url.port) - self.headers[hdrs.HOST] = netloc - if hdrs.USER_AGENT not in used_headers: self.headers[hdrs.USER_AGENT] = SERVER_SOFTWARE - def update_cookies(self, cookies): + def update_cookies(self, cookies: Optional[LooseCookies]) -> None: """Update request cookies header.""" if not cookies: return @@ -335,18 +377,22 @@ class ClientRequest: c.load(self.headers.get(hdrs.COOKIE, '')) del self.headers[hdrs.COOKIE] - for name, value in cookies.items(): + if isinstance(cookies, Mapping): + iter_cookies = cookies.items() + else: + iter_cookies = cookies # type: ignore + for name, value in iter_cookies: if isinstance(value, Morsel): # Preserve coded_value mrsl_val = value.get(value.key, Morsel()) - mrsl_val.set(value.key, value.value, value.coded_value) + mrsl_val.set(value.key, value.value, value.coded_value) # type: ignore # noqa c[name] = mrsl_val else: - c[name] = value + c[name] = value # type: ignore self.headers[hdrs.COOKIE] = c.output(header='', sep=';').strip() - def update_content_encoding(self, data): + def update_content_encoding(self, data: Any) -> None: """Set request content encoding.""" if not data: return @@ -363,7 +409,7 @@ class ClientRequest: self.headers[hdrs.CONTENT_ENCODING] = self.compress self.chunked = True # enable chunked, no need to deal with length - def update_transfer_encoding(self): + def update_transfer_encoding(self) -> None: """Analyze transfer-encoding header.""" te = self.headers.get(hdrs.TRANSFER_ENCODING, '').lower() @@ -384,7 +430,7 @@ class ClientRequest: if hdrs.CONTENT_LENGTH not in self.headers: self.headers[hdrs.CONTENT_LENGTH] = str(len(self.body)) - def update_auth(self, auth): + def update_auth(self, auth: Optional[BasicAuth]) -> None: """Set basic auth.""" if auth is None: auth = self.auth @@ -396,7 +442,7 @@ class ClientRequest: self.headers[hdrs.AUTHORIZATION] = auth.encode() - def update_body_from_data(self, body): + def update_body_from_data(self, body: Any) -> None: if not body: return @@ -432,7 +478,7 @@ class ClientRequest: if key not in self.headers: self.headers[key] = value - def update_expect_continue(self, expect=False): + def update_expect_continue(self, expect: bool=False) -> None: if expect: self.headers[hdrs.EXPECT] = '100-continue' elif self.headers.get(hdrs.EXPECT, '').lower() == '100-continue': @@ -441,7 +487,9 @@ class ClientRequest: if expect: self._continue = self.loop.create_future() - def update_proxy(self, proxy, proxy_auth, proxy_headers): + def update_proxy(self, proxy: Optional[URL], + proxy_auth: Optional[BasicAuth], + proxy_headers: Optional[LooseHeaders]) -> None: if proxy and not proxy.scheme == 'http': raise ValueError("Only http proxies are supported") if proxy_auth and not isinstance(proxy_auth, helpers.BasicAuth): @@ -450,7 +498,7 @@ class ClientRequest: self.proxy_auth = proxy_auth self.proxy_headers = proxy_headers - def keep_alive(self): + def keep_alive(self) -> bool: if self.version < HttpVersion10: # keep alive not supported at all return False @@ -464,22 +512,25 @@ class ClientRequest: return True - async def write_bytes(self, writer, conn): + async def write_bytes(self, writer: AbstractStreamWriter, + conn: 'Connection') -> None: """Support coroutines that yields bytes objects.""" # 100 response if self._continue is not None: await writer.drain() await self._continue + protocol = conn.protocol + assert protocol is not None try: if isinstance(self.body, payload.Payload): await self.body.write(writer) else: if isinstance(self.body, (bytes, bytearray)): - self.body = (self.body,) + self.body = (self.body,) # type: ignore for chunk in self.body: - await writer.write(chunk) + await writer.write(chunk) # type: ignore await writer.write_eof() except OSError as exc: @@ -488,16 +539,16 @@ class ClientRequest: 'Can not write request body for %s' % self.url) new_exc.__context__ = exc new_exc.__cause__ = exc - conn.protocol.set_exception(new_exc) + protocol.set_exception(new_exc) except asyncio.CancelledError as exc: if not conn.closed: - conn.protocol.set_exception(exc) + protocol.set_exception(exc) except Exception as exc: - conn.protocol.set_exception(exc) + protocol.set_exception(exc) finally: self._writer = None - async def send(self, conn): + async def send(self, conn: 'Connection') -> 'ClientResponse': # Specify request target: # - CONNECT request must send authority form URI # - not CONNECT proxy must send absolute form URI @@ -511,8 +562,10 @@ class ClientRequest: if self.url.raw_query_string: path += '?' + self.url.raw_query_string + protocol = conn.protocol + assert protocol is not None writer = StreamWriter( - conn.protocol, self.loop, + protocol, self.loop, on_chunk_sent=self._on_chunk_request_sent ) @@ -548,7 +601,9 @@ class ClientRequest: self._writer = self.loop.create_task(self.write_bytes(writer, conn)) - self.response = self.response_class( + response_class = self.response_class + assert response_class is not None + self.response = response_class( self.method, self.original_url, writer=self._writer, continue100=self._continue, timer=self._timer, request_info=self.request_info, @@ -558,20 +613,20 @@ class ClientRequest: ) return self.response - async def close(self): + async def close(self) -> None: if self._writer is not None: try: await self._writer finally: self._writer = None - def terminate(self): + def terminate(self) -> None: if self._writer is not None: if not self.loop.is_closed(): self._writer.cancel() self._writer = None - async def _on_chunk_request_sent(self, chunk): + async def _on_chunk_request_sent(self, chunk: bytes) -> None: for trace in self._traces: await trace.send_request_chunk_sent(chunk) @@ -584,7 +639,7 @@ class ClientResponse(HeadersMixin): reason = None # Reason-Phrase content = None # type: StreamReader # Payload stream - _headers = None # type: CIMultiDictProxy # Response headers + _headers = None # type: CIMultiDictProxy[str] # Response headers _raw_headers = None # type: RawHeaders # Response raw headers _connection = None # current connection @@ -594,10 +649,14 @@ class ClientResponse(HeadersMixin): _closed = True # to allow __del__ for non-initialized properly response _released = False - def __init__(self, method, url, *, - writer, continue100, timer, - request_info, - traces, loop, session): + def __init__(self, method: str, url: URL, *, + writer: 'asyncio.Task[None]', + continue100: Optional['asyncio.Future[bool]'], + timer: BaseTimerContext, + request_info: RequestInfo, + traces: List['Trace'], + loop: asyncio.AbstractEventLoop, + session: 'ClientSession') -> None: assert isinstance(url, URL) self.method = method @@ -605,17 +664,18 @@ class ClientResponse(HeadersMixin): self._real_url = url self._url = url.with_fragment(None) - self._body = None # type: bytes - self._writer = writer + self._body = None # type: Any + self._writer = writer # type: Optional[asyncio.Task[None]] self._continue = continue100 # None by default self._closed = True - self._history = () + self._history = () # type: Tuple[ClientResponse, ...] self._request_info = request_info self._timer = timer if timer is not None else TimerNoop() - self._cache = {} # required for @reify method decorator + self._cache = {} # type: Dict[str, Any] self._traces = traces self._loop = loop - self._session = session # store a reference to session #1985 + # store a reference to session #1985 + self._session = session # type: Optional[ClientSession] if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) @@ -635,10 +695,11 @@ class ClientResponse(HeadersMixin): @reify def host(self) -> str: + assert self._url.host is not None return self._url.host @reify - def headers(self) -> CIMultiDictProxy: + def headers(self) -> 'CIMultiDictProxy[str]': return self._headers @reify @@ -654,12 +715,12 @@ class ClientResponse(HeadersMixin): raw = self._headers.get(hdrs.CONTENT_DISPOSITION) if raw is None: return None - disposition_type, params = multipart.parse_content_disposition(raw) - params = MappingProxyType(params) + disposition_type, params_dct = multipart.parse_content_disposition(raw) + params = MappingProxyType(params_dct) filename = multipart.content_disposition_filename(params) return ContentDisposition(disposition_type, params, filename) - def __del__(self, _warnings=warnings): + def __del__(self, _warnings: Any=warnings) -> None: if self._closed: return @@ -681,7 +742,7 @@ class ClientResponse(HeadersMixin): context['source_traceback'] = self._source_traceback self._loop.call_exception_handler(context) - def __repr__(self): + def __repr__(self) -> str: out = io.StringIO() ascii_encodable_url = str(self.url) if self.reason: @@ -697,7 +758,7 @@ class ClientResponse(HeadersMixin): return out.getvalue() @property - def connection(self): + def connection(self) -> Optional['Connection']: return self._connection @reify @@ -706,13 +767,13 @@ class ClientResponse(HeadersMixin): return self._history @reify - def links(self) -> MultiDictProxy: + def links(self) -> 'MultiDictProxy[MultiDictProxy[Union[str, URL]]]': links_str = ", ".join(self.headers.getall("link", [])) - links = MultiDict() # type: MultiDict - if not links_str: - return MultiDictProxy(links) + return MultiDictProxy(MultiDict()) + + links = MultiDict() # type: MultiDict[MultiDictProxy[Union[str, URL]]] for val in re.split(r",(?=\s*<)", links_str): match = re.match(r"\s*<(.*)>(.*)", val) @@ -722,7 +783,7 @@ class ClientResponse(HeadersMixin): url, params_str = match.groups() params = params_str.split(";")[1:] - link = MultiDict() # type: MultiDict + link = MultiDict() # type: MultiDict[Union[str, URL]] for param in params: match = re.match( @@ -736,7 +797,7 @@ class ClientResponse(HeadersMixin): link.add(key, value) - key = link.get("rel", url) + key = link.get("rel", url) # type: ignore link.add("url", self.url.join(URL(url))) @@ -744,7 +805,7 @@ class ClientResponse(HeadersMixin): return MultiDictProxy(links) - async def start(self, connection): + async def start(self, connection: 'Connection') -> 'ClientResponse': """Start response processing.""" self._closed = False self._protocol = connection.protocol @@ -754,7 +815,7 @@ class ClientResponse(HeadersMixin): while True: # read response try: - message, payload = await self._protocol.read() + message, payload = await self._protocol.read() # type: ignore # noqa except http.HttpProcessingError as exc: raise ClientResponseError( self.request_info, self.history, @@ -793,7 +854,7 @@ class ClientResponse(HeadersMixin): 'Can not load response cookies: %s', exc) return self - def _response_eof(self): + def _response_eof(self) -> None: if self._closed: return @@ -845,6 +906,8 @@ class ClientResponse(HeadersMixin): def raise_for_status(self) -> None: if 400 <= self.status: + assert self.reason # always not None for started response + self.release() raise ClientResponseError( self.request_info, self.history, @@ -852,13 +915,13 @@ class ClientResponse(HeadersMixin): message=self.reason, headers=self.headers) - def _cleanup_writer(self): + def _cleanup_writer(self) -> None: if self._writer is not None: self._writer.cancel() self._writer = None self._session = None - def _notify_content(self): + def _notify_content(self) -> None: content = self.content if content and content.exception() is None: content.set_exception( @@ -918,7 +981,7 @@ class ClientResponse(HeadersMixin): if encoding is None: encoding = self.get_encoding() - return self._body.decode(encoding, errors=errors) + return self._body.decode(encoding, errors=errors) # type: ignore async def json(self, *, encoding: str=None, loads: JSONDecoder=DEFAULT_JSON_DECODER, @@ -937,7 +1000,7 @@ class ClientResponse(HeadersMixin): 'unexpected mimetype: %s' % ctype), headers=self.headers) - stripped = self._body.strip() + stripped = self._body.strip() # type: ignore if not stripped: return None @@ -949,7 +1012,10 @@ class ClientResponse(HeadersMixin): async def __aenter__(self) -> 'ClientResponse': return self - async def __aexit__(self, exc_type, exc_val, exc_tb): + async def __aexit__(self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> None: # similar to _RequestContextManager, we do not need to check # for exceptions, response object can closes connection # is state is broken diff --git a/aiohttp/client_ws.py b/aiohttp/client_ws.py index 7a9a0f9..e5e5fbd 100644 --- a/aiohttp/client_ws.py +++ b/aiohttp/client_ws.py @@ -6,20 +6,32 @@ from typing import Any, Optional import async_timeout from .client_exceptions import ClientError +from .client_reqrep import ClientResponse from .helpers import call_later, set_result from .http import (WS_CLOSED_MESSAGE, WS_CLOSING_MESSAGE, WebSocketError, WSMessage, WSMsgType) -from .streams import EofStream -from .typedefs import (DEFAULT_JSON_DECODER, DEFAULT_JSON_ENCODER, Byteish, - JSONDecoder, JSONEncoder) +from .http_websocket import WebSocketWriter # WSMessage +from .streams import EofStream, FlowControlDataQueue # noqa +from .typedefs import (DEFAULT_JSON_DECODER, DEFAULT_JSON_ENCODER, JSONDecoder, + JSONEncoder) class ClientWebSocketResponse: - def __init__(self, reader, writer, protocol, - response, timeout, autoclose, autoping, loop, *, - receive_timeout=None, heartbeat=None, - compress=0, client_notakeover=False): + def __init__(self, + reader: 'FlowControlDataQueue[WSMessage]', + writer: WebSocketWriter, + protocol: Optional[str], + response: ClientResponse, + timeout: float, + autoclose: bool, + autoping: bool, + loop: asyncio.AbstractEventLoop, + *, + receive_timeout: Optional[float]=None, + heartbeat: Optional[float]=None, + compress: int=0, + client_notakeover: bool=False) -> None: self._response = response self._conn = response.connection @@ -28,7 +40,7 @@ class ClientWebSocketResponse: self._protocol = protocol self._closed = False self._closing = False - self._close_code = None + self._close_code = None # type: Optional[int] self._timeout = timeout self._receive_timeout = receive_timeout self._autoclose = autoclose @@ -39,14 +51,14 @@ class ClientWebSocketResponse: self._pong_heartbeat = heartbeat / 2.0 self._pong_response_cb = None self._loop = loop - self._waiting = None - self._exception = None + self._waiting = None # type: Optional[asyncio.Future[bool]] + self._exception = None # type: Optional[BaseException] self._compress = compress self._client_notakeover = client_notakeover self._reset_heartbeat() - def _cancel_heartbeat(self): + def _cancel_heartbeat(self) -> None: if self._pong_response_cb is not None: self._pong_response_cb.cancel() self._pong_response_cb = None @@ -55,14 +67,14 @@ class ClientWebSocketResponse: self._heartbeat_cb.cancel() self._heartbeat_cb = None - def _reset_heartbeat(self): + def _reset_heartbeat(self) -> None: self._cancel_heartbeat() if self._heartbeat is not None: self._heartbeat_cb = call_later( self._send_heartbeat, self._heartbeat, self._loop) - def _send_heartbeat(self): + def _send_heartbeat(self) -> None: if self._heartbeat is not None and not self._closed: # fire-and-forget a task is not perfect but maybe ok for # sending ping. Otherwise we need a long-living heartbeat @@ -74,7 +86,7 @@ class ClientWebSocketResponse: self._pong_response_cb = call_later( self._pong_not_received, self._pong_heartbeat, self._loop) - def _pong_not_received(self): + def _pong_not_received(self) -> None: if not self._closed: self._closed = True self._close_code = 1006 @@ -90,7 +102,7 @@ class ClientWebSocketResponse: return self._close_code @property - def protocol(self): + def protocol(self) -> Optional[str]: return self._protocol @property @@ -101,13 +113,15 @@ class ClientWebSocketResponse: def client_notakeover(self) -> bool: return self._client_notakeover - def get_extra_info(self, name: str, default: Any=None): + def get_extra_info(self, name: str, default: Any=None) -> Any: """extra info from connection transport""" - try: - return self._response.connection.transport.get_extra_info( - name, default) - except Exception: + conn = self._response.connection + if conn is None: return default + transport = conn.transport + if transport is None: + return default + return transport.get_extra_info(name, default) def exception(self) -> Optional[BaseException]: return self._exception @@ -124,7 +138,7 @@ class ClientWebSocketResponse: raise TypeError('data argument must be str (%r)' % type(data)) await self._writer.send(data, binary=False, compress=compress) - async def send_bytes(self, data: Byteish, + async def send_bytes(self, data: bytes, compress: Optional[int]=None) -> None: if not isinstance(data, (bytes, bytearray, memoryview)): raise TypeError('data argument must be byte-ish (%r)' % @@ -136,7 +150,7 @@ class ClientWebSocketResponse: *, dumps: JSONEncoder=DEFAULT_JSON_ENCODER) -> None: await self.send_str(dumps(data), compress=compress) - async def close(self, *, code: int=1000, message: bytes=b''): + async def close(self, *, code: int=1000, message: bytes=b'') -> bool: # we need to break `receive()` cycle first, # `close()` may be called from different task if self._waiting is not None and not self._closed: diff --git a/aiohttp/connector.py b/aiohttp/connector.py index aa4dfd7..01edd0c 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -9,10 +9,15 @@ from contextlib import suppress from http.cookies import SimpleCookie from itertools import cycle, islice from time import monotonic +from types import TracebackType +from typing import (TYPE_CHECKING, Any, Awaitable, Callable, # noqa + DefaultDict, Dict, Iterator, List, Optional, Set, Tuple, + Type, Union, cast) import attr from . import hdrs, helpers +from .abc import AbstractResolver from .client_exceptions import (ClientConnectionError, ClientConnectorCertificateError, ClientConnectorError, ClientConnectorSSLError, @@ -22,39 +27,70 @@ from .client_exceptions import (ClientConnectionError, ssl_errors) from .client_proto import ResponseHandler from .client_reqrep import ClientRequest, Fingerprint, _merge_ssl_params -from .helpers import PY_36, CeilTimeout, is_ip_address, noop, sentinel +from .helpers import (PY_36, CeilTimeout, get_running_loop, is_ip_address, + noop2, sentinel) +from .http import RESPONSES from .locks import EventResultOrError from .resolver import DefaultResolver try: import ssl + SSLContext = ssl.SSLContext except ImportError: # pragma: no cover ssl = None # type: ignore + SSLContext = object # type: ignore __all__ = ('BaseConnector', 'TCPConnector', 'UnixConnector') +if TYPE_CHECKING: # pragma: no cover + from .client import ClientTimeout # noqa + from .client_reqrep import ConnectionKey # noqa + from .tracing import Trace # noqa + + +class _DeprecationWaiter: + __slots__ = ('_awaitable', '_awaited') + + def __init__(self, awaitable: Awaitable[Any]) -> None: + self._awaitable = awaitable + self._awaited = False + + def __await__(self) -> Any: + self._awaited = True + return self._awaitable.__await__() + + def __del__(self) -> None: + if not self._awaited: + warnings.warn("Connector.close() is a coroutine, " + "please use await connector.close()", + DeprecationWarning) + + class Connection: _source_traceback = None _transport = None - def __init__(self, connector, key, protocol, loop): + def __init__(self, connector: 'BaseConnector', + key: 'ConnectionKey', + protocol: ResponseHandler, + loop: asyncio.AbstractEventLoop) -> None: self._key = key self._connector = connector self._loop = loop - self._protocol = protocol - self._callbacks = [] + self._protocol = protocol # type: Optional[ResponseHandler] + self._callbacks = [] # type: List[Callable[[], None]] if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) - def __repr__(self): + def __repr__(self) -> str: return 'Connection<{}>'.format(self._key) - def __del__(self, _warnings=warnings): + def __del__(self, _warnings: Any=warnings) -> None: if self._protocol is not None: if PY_36: kwargs = {'source': self} @@ -76,33 +112,34 @@ class Connection: self._loop.call_exception_handler(context) @property - def loop(self): + def loop(self) -> asyncio.AbstractEventLoop: + warnings.warn("connector.loop property is deprecated", + DeprecationWarning, + stacklevel=2) return self._loop @property - def transport(self): + def transport(self) -> Optional[asyncio.Transport]: + if self._protocol is None: + return None return self._protocol.transport @property - def protocol(self): + def protocol(self) -> Optional[ResponseHandler]: return self._protocol - @property - def writer(self): - return self._protocol.writer - - def add_callback(self, callback): + def add_callback(self, callback: Callable[[], None]) -> None: if callback is not None: self._callbacks.append(callback) - def _notify_release(self): + def _notify_release(self) -> None: callbacks, self._callbacks = self._callbacks[:], [] for cb in callbacks: with suppress(Exception): cb() - def close(self): + def close(self) -> None: self._notify_release() if self._protocol is not None: @@ -110,7 +147,7 @@ class Connection: self._key, self._protocol, should_close=True) self._protocol = None - def release(self): + def release(self) -> None: self._notify_release() if self._protocol is not None: @@ -119,22 +156,15 @@ class Connection: should_close=self._protocol.should_close) self._protocol = None - def detach(self): - self._notify_release() - - if self._protocol is not None: - self._connector._release_acquired(self._protocol) - self._protocol = None - @property - def closed(self): + def closed(self) -> bool: return self._protocol is None or not self._protocol.is_connected() class _TransportPlaceholder: """ placeholder for BaseConnector.connect function """ - def close(self): + def close(self) -> None: pass @@ -157,9 +187,12 @@ class BaseConnector: # abort transport after 2 seconds (cleanup broken connections) _cleanup_closed_period = 2.0 - def __init__(self, *, keepalive_timeout=sentinel, - force_close=False, limit=100, limit_per_host=0, - enable_cleanup_closed=False, loop=None): + def __init__(self, *, + keepalive_timeout: Union[object, None, float]=sentinel, + force_close: bool=False, + limit: int=100, limit_per_host: int=0, + enable_cleanup_closed: bool=False, + loop: Optional[asyncio.AbstractEventLoop]=None) -> None: if force_close: if keepalive_timeout is not None and \ @@ -170,23 +203,22 @@ class BaseConnector: if keepalive_timeout is sentinel: keepalive_timeout = 15.0 - if loop is None: - loop = asyncio.get_event_loop() + loop = get_running_loop(loop) self._closed = False if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) - self._conns = {} + self._conns = {} # type: Dict[ConnectionKey, List[Tuple[ResponseHandler, float]]] # noqa self._limit = limit self._limit_per_host = limit_per_host - self._acquired = set() - self._acquired_per_host = defaultdict(set) - self._keepalive_timeout = keepalive_timeout + self._acquired = set() # type: Set[ResponseHandler] + self._acquired_per_host = defaultdict(set) # type: DefaultDict[ConnectionKey, Set[ResponseHandler]] # noqa + self._keepalive_timeout = cast(float, keepalive_timeout) self._force_close = force_close # {host_key: FIFO list of waiters} - self._waiters = defaultdict(deque) + self._waiters = defaultdict(deque) # type: ignore self._loop = loop self._factory = functools.partial(ResponseHandler, loop=loop) @@ -199,10 +231,10 @@ class BaseConnector: # start cleanup closed transports task self._cleanup_closed_handle = None self._cleanup_closed_disabled = not enable_cleanup_closed - self._cleanup_closed_transports = [] + self._cleanup_closed_transports = [] # type: List[Optional[asyncio.Transport]] # noqa self._cleanup_closed() - def __del__(self, _warnings=warnings): + def __del__(self, _warnings: Any=warnings) -> None: if self._closed: return if not self._conns: @@ -210,7 +242,7 @@ class BaseConnector: conns = [repr(c) for c in self._conns.values()] - self.close() + self._close() if PY_36: kwargs = {'source': self} @@ -226,19 +258,32 @@ class BaseConnector: context['source_traceback'] = self._source_traceback self._loop.call_exception_handler(context) - def __enter__(self): + def __enter__(self) -> 'BaseConnector': + warnings.warn('"witn Connector():" is deprecated, ' + 'use "async with Connector():" instead', + DeprecationWarning) return self - def __exit__(self, *exc): + def __exit__(self, *exc: Any) -> None: self.close() + async def __aenter__(self) -> 'BaseConnector': + return self + + async def __aexit__(self, + exc_type: Optional[Type[BaseException]]=None, + exc_value: Optional[BaseException]=None, + exc_traceback: Optional[TracebackType]=None + ) -> None: + await self.close() + @property - def force_close(self): + def force_close(self) -> bool: """Ultimately close connection on releasing if True.""" return self._force_close @property - def limit(self): + def limit(self) -> int: """The total number for simultaneous connections. If limit is 0 the connector has no limit. @@ -247,7 +292,7 @@ class BaseConnector: return self._limit @property - def limit_per_host(self): + def limit_per_host(self) -> int: """The limit_per_host for simultaneous connections to the same endpoint. @@ -257,7 +302,7 @@ class BaseConnector: """ return self._limit_per_host - def _cleanup(self): + def _cleanup(self) -> None: """Cleanup unused transports.""" if self._cleanup_handle: self._cleanup_handle.cancel() @@ -273,7 +318,8 @@ class BaseConnector: for proto, use_time in conns: if proto.is_connected(): if use_time - deadline < 0: - transport = proto.close() + transport = proto.transport + proto.close() if (key.is_ssl and not self._cleanup_closed_disabled): self._cleanup_closed_transports.append( @@ -290,7 +336,8 @@ class BaseConnector: self._cleanup_handle = helpers.weakref_handle( self, '_cleanup', timeout, self._loop) - def _drop_acquired_per_host(self, key, val): + def _drop_acquired_per_host(self, key: 'ConnectionKey', + val: ResponseHandler) -> None: acquired_per_host = self._acquired_per_host if key not in acquired_per_host: return @@ -299,7 +346,7 @@ class BaseConnector: if not conns: del self._acquired_per_host[key] - def _cleanup_closed(self): + def _cleanup_closed(self) -> None: """Double confirmation for transport close. Some broken ssl servers may leave socket open without proper close. """ @@ -317,8 +364,12 @@ class BaseConnector: self, '_cleanup_closed', self._cleanup_closed_period, self._loop) - def close(self): + def close(self) -> Awaitable[None]: """Close all opened transports.""" + self._close() + return _DeprecationWaiter(noop2()) + + def _close(self) -> None: if self._closed: return @@ -326,7 +377,7 @@ class BaseConnector: try: if self._loop.is_closed(): - return noop() + return # cancel cleanup task if self._cleanup_handle: @@ -356,14 +407,14 @@ class BaseConnector: self._cleanup_closed_handle = None @property - def closed(self): + def closed(self) -> bool: """Is connector closed. A readonly property. """ return self._closed - def _available_connections(self, key): + def _available_connections(self, key: 'ConnectionKey') -> int: """ Return number of available connections taking into account the limit, limit_per_host and the connection key. @@ -379,19 +430,23 @@ class BaseConnector: # check limit per host if (self._limit_per_host and available > 0 and key in self._acquired_per_host): - available = self._limit_per_host - len( - self._acquired_per_host.get(key)) + acquired = self._acquired_per_host.get(key) + assert acquired is not None + available = self._limit_per_host - len(acquired) elif self._limit_per_host and key in self._acquired_per_host: # check limit per host - available = self._limit_per_host - len( - self._acquired_per_host.get(key)) + acquired = self._acquired_per_host.get(key) + assert acquired is not None + available = self._limit_per_host - len(acquired) else: available = 1 return available - async def connect(self, req, traces, timeout): + async def connect(self, req: 'ClientRequest', + traces: List['Trace'], + timeout: 'ClientTimeout') -> Connection: """Get from pool or create new connection.""" key = req.connection_key available = self._available_connections(key) @@ -433,7 +488,7 @@ class BaseConnector: proto = self._get(key) if proto is None: - placeholder = _TransportPlaceholder() + placeholder = cast(ResponseHandler, _TransportPlaceholder()) self._acquired.add(placeholder) self._acquired_per_host[key].add(placeholder) @@ -469,7 +524,7 @@ class BaseConnector: self._acquired_per_host[key].add(proto) return Connection(self, key, proto, self._loop) - def _get(self, key): + def _get(self, key: 'ConnectionKey') -> Optional[ResponseHandler]: try: conns = self._conns[key] except KeyError: @@ -480,7 +535,8 @@ class BaseConnector: proto, t0 = conns.pop() if proto.is_connected(): if t1 - t0 > self._keepalive_timeout: - transport = proto.close() + transport = proto.transport + proto.close() # only for SSL transports if key.is_ssl and not self._cleanup_closed_disabled: self._cleanup_closed_transports.append(transport) @@ -494,7 +550,7 @@ class BaseConnector: del self._conns[key] return None - def _release_waiter(self): + def _release_waiter(self) -> None: """ Iterates over all waiters till found one that is not finsihed and belongs to a host that has available connections. @@ -518,7 +574,8 @@ class BaseConnector: waiter.set_result(None) return - def _release_acquired(self, key, proto): + def _release_acquired(self, key: 'ConnectionKey', + proto: ResponseHandler) -> None: if self._closed: # acquired connection is already released on connector closing return @@ -533,7 +590,8 @@ class BaseConnector: else: self._release_waiter() - def _release(self, key, protocol, *, should_close=False): + def _release(self, key: 'ConnectionKey', protocol: ResponseHandler, + *, should_close: bool=False) -> None: if self._closed: # acquired connection is already released on connector closing return @@ -544,7 +602,8 @@ class BaseConnector: should_close = True if should_close or protocol.should_close: - transport = protocol.close() + transport = protocol.transport + protocol.close() if key.is_ssl and not self._cleanup_closed_disabled: self._cleanup_closed_transports.append(transport) @@ -558,48 +617,50 @@ class BaseConnector: self._cleanup_handle = helpers.weakref_handle( self, '_cleanup', self._keepalive_timeout, self._loop) - async def _create_connection(self, req, traces, timeout): + async def _create_connection(self, req: 'ClientRequest', + traces: List['Trace'], + timeout: 'ClientTimeout') -> ResponseHandler: raise NotImplementedError() class _DNSCacheTable: - def __init__(self, ttl=None): - self._addrs_rr = {} - self._timestamps = {} + def __init__(self, ttl: Optional[float]=None) -> None: + self._addrs_rr = {} # type: Dict[Tuple[str, int], Tuple[Iterator[Dict[str, Any]], int]] # noqa + self._timestamps = {} # type: Dict[Tuple[str, int], float] self._ttl = ttl - def __contains__(self, host): + def __contains__(self, host: object) -> bool: return host in self._addrs_rr - def add(self, host, addrs): - self._addrs_rr[host] = (cycle(addrs), len(addrs)) + def add(self, key: Tuple[str, int], addrs: List[Dict[str, Any]]) -> None: + self._addrs_rr[key] = (cycle(addrs), len(addrs)) if self._ttl: - self._timestamps[host] = monotonic() + self._timestamps[key] = monotonic() - def remove(self, host): - self._addrs_rr.pop(host, None) + def remove(self, key: Tuple[str, int]) -> None: + self._addrs_rr.pop(key, None) if self._ttl: - self._timestamps.pop(host, None) + self._timestamps.pop(key, None) - def clear(self): + def clear(self) -> None: self._addrs_rr.clear() self._timestamps.clear() - def next_addrs(self, host): - loop, length = self._addrs_rr[host] + def next_addrs(self, key: Tuple[str, int]) -> List[Dict[str, Any]]: + loop, length = self._addrs_rr[key] addrs = list(islice(loop, length)) # Consume one more element to shift internal state of `cycle` next(loop) return addrs - def expired(self, host): + def expired(self, key: Tuple[str, int]) -> bool: if self._ttl is None: return False - return self._timestamps[host] + self._ttl < monotonic() + return self._timestamps[key] + self._ttl < monotonic() class TCPConnector(BaseConnector): @@ -627,12 +688,19 @@ class TCPConnector(BaseConnector): loop - Optional event loop. """ - def __init__(self, *, verify_ssl=True, fingerprint=None, - use_dns_cache=True, ttl_dns_cache=10, - family=0, ssl_context=None, ssl=None, local_addr=None, - resolver=None, keepalive_timeout=sentinel, - force_close=False, limit=100, limit_per_host=0, - enable_cleanup_closed=False, loop=None): + def __init__(self, *, verify_ssl: bool=True, + fingerprint: Optional[bytes]=None, + use_dns_cache: bool=True, ttl_dns_cache: int=10, + family: int=0, + ssl_context: Optional[SSLContext]=None, + ssl: Union[None, bool, Fingerprint, SSLContext]=None, + local_addr: Optional[str]=None, + resolver: Optional[AbstractResolver]=None, + keepalive_timeout: Union[None, float, object]=sentinel, + force_close: bool=False, + limit: int=100, limit_per_host: int=0, + enable_cleanup_closed: bool=False, + loop: Optional[asyncio.AbstractEventLoop]=None): super().__init__(keepalive_timeout=keepalive_timeout, force_close=force_close, limit=limit, limit_per_host=limit_per_host, @@ -647,28 +715,30 @@ class TCPConnector(BaseConnector): self._use_dns_cache = use_dns_cache self._cached_hosts = _DNSCacheTable(ttl=ttl_dns_cache) - self._throttle_dns_events = {} + self._throttle_dns_events = {} # type: Dict[Tuple[str, int], EventResultOrError] # noqa self._family = family self._local_addr = local_addr - def close(self): + def close(self) -> Awaitable[None]: """Close all ongoing DNS calls.""" for ev in self._throttle_dns_events.values(): ev.cancel() - super().close() + return super().close() @property - def family(self): + def family(self) -> int: """Socket family like AF_INET.""" return self._family @property - def use_dns_cache(self): + def use_dns_cache(self) -> bool: """True if local DNS caching is enabled.""" return self._use_dns_cache - def clear_dns_cache(self, host=None, port=None): + def clear_dns_cache(self, + host: Optional[str]=None, + port: Optional[int]=None) -> None: """Remove specified host/port or clear all dns local cache.""" if host is not None and port is not None: self._cached_hosts.remove((host, port)) @@ -678,7 +748,10 @@ class TCPConnector(BaseConnector): else: self._cached_hosts.clear() - async def _resolve_host(self, host, port, traces=None): + async def _resolve_host(self, + host: str, port: int, + traces: Optional[List['Trace']]=None + ) -> List[Dict[str, Any]]: if is_ip_address(host): return [{'hostname': host, 'host': host, 'port': port, 'family': self._family, 'proto': 0, 'flags': 0}] @@ -744,7 +817,9 @@ class TCPConnector(BaseConnector): return self._cached_hosts.next_addrs(key) - async def _create_connection(self, req, traces, timeout): + async def _create_connection(self, req: 'ClientRequest', + traces: List['Trace'], + timeout: 'ClientTimeout') -> ResponseHandler: """Create connection. Has same keyword arguments as BaseEventLoop.create_connection. @@ -760,7 +835,7 @@ class TCPConnector(BaseConnector): @staticmethod @functools.lru_cache(None) - def _make_ssl_context(verified): + def _make_ssl_context(verified: bool) -> SSLContext: if verified: return ssl.create_default_context() else: @@ -771,7 +846,7 @@ class TCPConnector(BaseConnector): sslcontext.set_default_verify_paths() return sslcontext - def _get_ssl_context(self, req): + def _get_ssl_context(self, req: 'ClientRequest') -> Optional[SSLContext]: """Logic to get the correct SSL context 0. if req.ssl is false, return None @@ -804,7 +879,8 @@ class TCPConnector(BaseConnector): else: return None - def _get_fingerprint(self, req): + def _get_fingerprint(self, + req: 'ClientRequest') -> Optional['Fingerprint']: ret = req.ssl if isinstance(ret, Fingerprint): return ret @@ -813,13 +889,17 @@ class TCPConnector(BaseConnector): return ret return None - async def _wrap_create_connection(self, *args, - req, timeout, - client_error=ClientConnectorError, - **kwargs): + async def _wrap_create_connection( + self, *args: Any, + req: 'ClientRequest', + timeout: 'ClientTimeout', + client_error: Type[Exception]=ClientConnectorError, + **kwargs: Any) -> Tuple[asyncio.Transport, ResponseHandler]: try: with CeilTimeout(timeout.sock_connect): - return await self._loop.create_connection(*args, **kwargs) + return cast( + Tuple[asyncio.Transport, ResponseHandler], + await self._loop.create_connection(*args, **kwargs)) except cert_errors as exc: raise ClientConnectorCertificateError( req.connection_key, exc) from exc @@ -828,8 +908,14 @@ class TCPConnector(BaseConnector): except OSError as exc: raise client_error(req.connection_key, exc) from exc - async def _create_direct_connection(self, req, traces, timeout, - *, client_error=ClientConnectorError): + async def _create_direct_connection( + self, + req: 'ClientRequest', + traces: List['Trace'], + timeout: 'ClientTimeout', + *, + client_error: Type[Exception]=ClientConnectorError + ) -> Tuple[asyncio.Transport, ResponseHandler]: sslcontext = self._get_ssl_context(req) fingerprint = self._get_fingerprint(req) @@ -837,16 +923,20 @@ class TCPConnector(BaseConnector): # Cancelling this lookup should not cancel the underlying lookup # or else the cancel event will get broadcast to all the waiters # across all connections. + host = req.url.raw_host + assert host is not None + port = req.port + assert port is not None hosts = await asyncio.shield(self._resolve_host( - req.url.raw_host, - req.port, + host, + port, traces=traces), loop=self._loop) except OSError as exc: # in case of proxy it is not ClientProxyConnectionError # it is problem of resolving proxy ip itself raise ClientConnectorError(req.connection_key, exc) from exc - last_exc = None + last_exc = None # type: Optional[Exception] for hinfo in hosts: host = hinfo['host'] @@ -876,16 +966,24 @@ class TCPConnector(BaseConnector): return transp, proto else: + assert last_exc is not None raise last_exc - async def _create_proxy_connection(self, req, traces, timeout): - headers = {} + async def _create_proxy_connection( + self, + req: 'ClientRequest', + traces: List['Trace'], + timeout: 'ClientTimeout' + ) -> Tuple[asyncio.Transport, ResponseHandler]: + headers = {} # type: Dict[str, str] if req.proxy_headers is not None: - headers = req.proxy_headers + headers = req.proxy_headers # type: ignore headers[hdrs.HOST] = req.headers[hdrs.HOST] + url = req.proxy + assert url is not None proxy_req = ClientRequest( - hdrs.METH_GET, req.proxy, + hdrs.METH_GET, url, headers=headers, auth=req.proxy_auth, loop=self._loop, @@ -927,7 +1025,9 @@ class TCPConnector(BaseConnector): conn = Connection(self, key, proto, self._loop) proxy_resp = await proxy_req.send(conn) try: - conn._protocol.set_response_params() + protocol = conn._protocol + assert protocol is not None + protocol.set_response_params() resp = await proxy_resp.start(conn) except BaseException: proxy_resp.close() @@ -938,11 +1038,14 @@ class TCPConnector(BaseConnector): conn._transport = None try: if resp.status != 200: + message = resp.reason + if message is None: + message = RESPONSES[resp.status][0] raise ClientHttpProxyError( proxy_resp.request_info, resp.history, status=resp.status, - message=resp.reason, + message=message, headers=resp.headers) rawsock = transport.get_extra_info('socket', default=None) if rawsock is None: @@ -976,19 +1079,23 @@ class UnixConnector(BaseConnector): loop - Optional event loop. """ - def __init__(self, path, force_close=False, keepalive_timeout=sentinel, - limit=100, limit_per_host=0, loop=None): + def __init__(self, path: str, force_close: bool=False, + keepalive_timeout: Union[object, float, None]=sentinel, + limit: int=100, limit_per_host: int=0, + loop: Optional[asyncio.AbstractEventLoop]=None) -> None: super().__init__(force_close=force_close, keepalive_timeout=keepalive_timeout, limit=limit, limit_per_host=limit_per_host, loop=loop) self._path = path @property - def path(self): + def path(self) -> str: """Path to unix socket.""" return self._path - async def _create_connection(self, req, traces, timeout): + async def _create_connection(self, req: 'ClientRequest', + traces: List['Trace'], + timeout: 'ClientTimeout') -> ResponseHandler: try: with CeilTimeout(timeout.sock_connect): _, proto = await self._loop.create_unix_connection( @@ -996,4 +1103,4 @@ class UnixConnector(BaseConnector): except OSError as exc: raise ClientConnectorError(req.connection_key, exc) from exc - return proto + return cast(ResponseHandler, proto) diff --git a/aiohttp/cookiejar.py b/aiohttp/cookiejar.py index 24fc31d..e5f9bf9 100644 --- a/aiohttp/cookiejar.py +++ b/aiohttp/cookiejar.py @@ -1,21 +1,28 @@ +import asyncio import datetime +import os # noqa import pathlib import pickle import re from collections import defaultdict -from collections.abc import Mapping -from http.cookies import Morsel, SimpleCookie +from http.cookies import BaseCookie, Morsel, SimpleCookie # noqa from math import ceil +from typing import (DefaultDict, Dict, Iterable, Iterator, Mapping, # noqa + Optional, Set, Tuple, Union, cast) from yarl import URL from .abc import AbstractCookieJar from .helpers import is_ip_address +from .typedefs import LooseCookies, PathLike __all__ = ('CookieJar', 'DummyCookieJar') +CookieItem = Union[str, 'Morsel[str]'] + + class CookieJar(AbstractCookieJar): """Implements cookie storage adhering to RFC 6265.""" @@ -34,39 +41,40 @@ class CookieJar(AbstractCookieJar): MAX_TIME = 2051215261.0 # so far in future (2035-01-01) - def __init__(self, *, unsafe=False, loop=None): + def __init__(self, *, unsafe: bool=False, + loop: Optional[asyncio.AbstractEventLoop]=None) -> None: super().__init__(loop=loop) - self._cookies = defaultdict(SimpleCookie) - self._host_only_cookies = set() + self._cookies = defaultdict(SimpleCookie) #type: DefaultDict[str, SimpleCookie] # noqa + self._host_only_cookies = set() # type: Set[Tuple[str, str]] self._unsafe = unsafe self._next_expiration = ceil(self._loop.time()) - self._expirations = {} + self._expirations = {} # type: Dict[Tuple[str, str], int] - def save(self, file_path): + def save(self, file_path: PathLike) -> None: file_path = pathlib.Path(file_path) with file_path.open(mode='wb') as f: pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL) - def load(self, file_path): + def load(self, file_path: PathLike) -> None: file_path = pathlib.Path(file_path) with file_path.open(mode='rb') as f: self._cookies = pickle.load(f) - def clear(self): + def clear(self) -> None: self._cookies.clear() self._host_only_cookies.clear() self._next_expiration = ceil(self._loop.time()) self._expirations.clear() - def __iter__(self): + def __iter__(self) -> 'Iterator[Morsel[str]]': self._do_expiration() for val in self._cookies.values(): yield from val.values() - def __len__(self): + def __len__(self) -> int: return sum(1 for i in self) - def _do_expiration(self): + def _do_expiration(self) -> None: now = self._loop.time() if self._next_expiration > now: return @@ -88,11 +96,14 @@ class CookieJar(AbstractCookieJar): self._next_expiration = ceil(next_expiration) - def _expire_cookie(self, when, domain, name): - self._next_expiration = min(self._next_expiration, when) - self._expirations[(domain, name)] = when + def _expire_cookie(self, when: float, domain: str, name: str) -> None: + iwhen = int(when) + self._next_expiration = min(self._next_expiration, iwhen) + self._expirations[(domain, name)] = iwhen - def update_cookies(self, cookies, response_url=URL()): + def update_cookies(self, + cookies: LooseCookies, + response_url: URL=URL()) -> None: """Update cookies.""" hostname = response_url.raw_host @@ -101,12 +112,12 @@ class CookieJar(AbstractCookieJar): return if isinstance(cookies, Mapping): - cookies = cookies.items() + cookies = cookies.items() # type: ignore for name, cookie in cookies: if not isinstance(cookie, Morsel): tmp = SimpleCookie() - tmp[name] = cookie + tmp[name] = cookie # type: ignore cookie = tmp[name] domain = cookie["domain"] @@ -165,7 +176,7 @@ class CookieJar(AbstractCookieJar): self._do_expiration() - def filter_cookies(self, request_url=URL()): + def filter_cookies(self, request_url: URL=URL()) -> 'BaseCookie[str]': """Returns this jar's cookies filtered by their attributes.""" self._do_expiration() request_url = URL(request_url) @@ -199,14 +210,14 @@ class CookieJar(AbstractCookieJar): # It's critical we use the Morsel so the coded_value # (based on cookie version) is preserved - mrsl_val = cookie.get(cookie.key, Morsel()) + mrsl_val = cast('Morsel[str]', cookie.get(cookie.key, Morsel())) mrsl_val.set(cookie.key, cookie.value, cookie.coded_value) filtered[name] = mrsl_val return filtered @staticmethod - def _is_domain_match(domain, hostname): + def _is_domain_match(domain: str, hostname: str) -> bool: """Implements domain matching adhering to RFC 6265.""" if hostname == domain: return True @@ -222,7 +233,7 @@ class CookieJar(AbstractCookieJar): return not is_ip_address(hostname) @staticmethod - def _is_path_match(req_path, cookie_path): + def _is_path_match(req_path: str, cookie_path: str) -> bool: """Implements path matching adhering to RFC 6265.""" if not req_path.startswith("/"): req_path = "/" @@ -241,10 +252,10 @@ class CookieJar(AbstractCookieJar): return non_matching.startswith("/") @classmethod - def _parse_date(cls, date_str): + def _parse_date(cls, date_str: str) -> Optional[datetime.datetime]: """Implements date string parsing adhering to RFC 6265.""" if not date_str: - return + return None found_time = False found_day = False @@ -294,13 +305,13 @@ class CookieJar(AbstractCookieJar): year += 2000 if False in (found_day, found_month, found_year, found_time): - return + return None if not 1 <= day <= 31: - return + return None if year < 1601 or hour > 23 or minute > 59 or second > 59: - return + return None return datetime.datetime(year, month, day, hour, minute, second, @@ -314,21 +325,24 @@ class DummyCookieJar(AbstractCookieJar): """ - def __init__(self, *, loop=None): + def __init__(self, *, + loop: Optional[asyncio.AbstractEventLoop]=None) -> None: super().__init__(loop=loop) - def __iter__(self): + def __iter__(self) -> 'Iterator[Morsel[str]]': while False: yield None - def __len__(self): + def __len__(self) -> int: return 0 - def clear(self): + def clear(self) -> None: pass - def update_cookies(self, cookies, response_url=None): + def update_cookies(self, + cookies: LooseCookies, + response_url: URL=URL()) -> None: pass - def filter_cookies(self, request_url): - return None + def filter_cookies(self, request_url: URL) -> 'BaseCookie[str]': + return SimpleCookie() diff --git a/aiohttp/formdata.py b/aiohttp/formdata.py index 0f2b5ff..72cd325 100644 --- a/aiohttp/formdata.py +++ b/aiohttp/formdata.py @@ -1,10 +1,12 @@ import io +from typing import Any, Iterable, List, Optional # noqa from urllib.parse import urlencode from multidict import MultiDict, MultiDictProxy from . import hdrs, multipart, payload from .helpers import guess_filename +from .payload import Payload __all__ = ('FormData',) @@ -14,9 +16,12 @@ class FormData: """Helper class for multipart/form-data and application/x-www-form-urlencoded body generation.""" - def __init__(self, fields=(), quote_fields=True, charset=None): + def __init__(self, fields: + Iterable[Any]=(), + quote_fields: bool=True, + charset: Optional[str]=None) -> None: self._writer = multipart.MultipartWriter('form-data') - self._fields = [] + self._fields = [] # type: List[Any] self._is_multipart = False self._quote_fields = quote_fields self._charset = charset @@ -28,11 +33,13 @@ class FormData: self.add_fields(*fields) @property - def is_multipart(self): + def is_multipart(self) -> bool: return self._is_multipart - def add_field(self, name, value, *, content_type=None, filename=None, - content_transfer_encoding=None): + def add_field(self, name: str, value: Any, *, + content_type: Optional[str]=None, + filename: Optional[str]=None, + content_transfer_encoding: Optional[str]=None) -> None: if isinstance(value, io.IOBase): self._is_multipart = True @@ -66,7 +73,7 @@ class FormData: self._fields.append((type_options, headers, value)) - def add_fields(self, *fields): + def add_fields(self, *fields: Any) -> None: to_add = list(fields) while to_add: @@ -74,14 +81,14 @@ class FormData: if isinstance(rec, io.IOBase): k = guess_filename(rec, 'unknown') - self.add_field(k, rec) + self.add_field(k, rec) # type: ignore elif isinstance(rec, (MultiDictProxy, MultiDict)): to_add.extend(rec.items()) elif isinstance(rec, (list, tuple)) and len(rec) == 2: k, fp = rec - self.add_field(k, fp) + self.add_field(k, fp) # type: ignore else: raise TypeError('Only io.IOBase, multidict and (name, file) ' @@ -89,7 +96,7 @@ class FormData: 'more complex parameters, got {!r}' .format(rec)) - def _gen_form_urlencoded(self): + def _gen_form_urlencoded(self) -> payload.BytesPayload: # form data (x-www-form-urlencoded) data = [] for type_options, _, value in self._fields: @@ -107,7 +114,7 @@ class FormData: urlencode(data, doseq=True, encoding=charset).encode(), content_type=content_type) - def _gen_form_data(self): + def _gen_form_data(self) -> multipart.MultipartWriter: """Encode a list of fields using the multipart/form-data MIME format""" for dispparams, headers, value in self._fields: try: @@ -130,13 +137,14 @@ class FormData: ) # FIXME cgi.FieldStorage doesn't likes body parts with # Content-Length which were sent via chunked transfer encoding + assert part.headers is not None part.headers.popall(hdrs.CONTENT_LENGTH, None) self._writer.append_payload(part) return self._writer - def __call__(self): + def __call__(self) -> Payload: if self._is_multipart: return self._gen_form_data() else: diff --git a/aiohttp/frozenlist.pyi b/aiohttp/frozenlist.pyi index 64d17f7..61a0478 100644 --- a/aiohttp/frozenlist.pyi +++ b/aiohttp/frozenlist.pyi @@ -1,5 +1,5 @@ from typing import (Generic, Iterable, Iterator, List, MutableSequence, - Optional, TypeVar, Union) + Optional, TypeVar, Union, overload) _T = TypeVar('_T') _Arg = Union[List[_T], Iterable[_T]] @@ -7,18 +7,30 @@ _Arg = Union[List[_T], Iterable[_T]] class FrozenList(MutableSequence[_T], Generic[_T]): - def __init__(self, items: Optional[_Arg]=None) -> None: ... + def __init__(self, items: Optional[_Arg[_T]]=None) -> None: ... @property def frozen(self) -> bool: ... def freeze(self) -> None: ... - def __getitem__(self, index): ... + @overload + def __getitem__(self, i: int) -> _T: ... - def __setitem__(self, index, value): ... + @overload + def __getitem__(self, s: slice) -> FrozenList[_T]: ... - def __delitem__(self, index): ... + @overload + def __setitem__(self, i: int, o: _T) -> None: ... + + @overload + def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ... + + @overload + def __delitem__(self, i: int) -> None: ... + + @overload + def __delitem__(self, i: slice) -> None: ... def __len__(self) -> int: ... @@ -26,12 +38,12 @@ class FrozenList(MutableSequence[_T], Generic[_T]): def __reversed__(self) -> Iterator[_T]: ... - def __eq__(self, other) -> bool: ... - def __le__(self, other) -> bool: ... - def __ne__(self, other) -> bool: ... - def __lt__(self, other) -> bool: ... - def __ge__(self, other) -> bool: ... - def __gt__(self, other) -> bool: ... + def __eq__(self, other: object) -> bool: ... + def __le__(self, other: FrozenList[_T]) -> bool: ... + def __ne__(self, other: object) -> bool: ... + def __lt__(self, other: FrozenList[_T]) -> bool: ... + def __ge__(self, other: FrozenList[_T]) -> bool: ... + def __gt__(self, other: FrozenList[_T]) -> bool: ... def insert(self, pos: int, item: _T) -> None: ... diff --git a/aiohttp/helpers.py b/aiohttp/helpers.py index cede174..9795f87 100644 --- a/aiohttp/helpers.py +++ b/aiohttp/helpers.py @@ -4,32 +4,35 @@ import asyncio import base64 import binascii import cgi -import datetime import functools import inspect import netrc import os +import platform import re import sys import time +import warnings import weakref from collections import namedtuple -from collections.abc import Mapping as ABCMapping from contextlib import suppress from math import ceil from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple # noqa +from types import TracebackType +from typing import (Any, Callable, Dict, Iterable, Iterator, List, # noqa + Mapping, Optional, Pattern, Set, Tuple, Type, TypeVar, + Union, cast) from urllib.parse import quote from urllib.request import getproxies import async_timeout import attr -from multidict import MultiDict +from multidict import MultiDict, MultiDictProxy from yarl import URL from . import hdrs -from .abc import AbstractAccessLogger -from .log import client_logger +from .log import client_logger, internal_logger +from .typedefs import PathLike # noqa __all__ = ('BasicAuth', 'ChainMapProxy') @@ -41,6 +44,20 @@ if not PY_37: import idna_ssl idna_ssl.patch_match_hostname() +try: + from typing import ContextManager +except ImportError: + from typing_extensions import ContextManager + + +all_tasks = asyncio.Task.all_tasks + +if PY_37: + all_tasks = getattr(asyncio, 'all_tasks') # use the trick to cheat mypy + + +_T = TypeVar('_T') + sentinel = object() # type: Any NO_EXTENSIONS = bool(os.environ.get('AIOHTTP_NO_EXTENSIONS')) # type: bool @@ -49,7 +66,7 @@ NO_EXTENSIONS = bool(os.environ.get('AIOHTTP_NO_EXTENSIONS')) # type: bool # for compatibility with older versions DEBUG = (getattr(sys.flags, 'dev_mode', False) or (not sys.flags.ignore_environment and - bool(os.environ.get('PYTHONASYNCIODEBUG')))) + bool(os.environ.get('PYTHONASYNCIODEBUG')))) # type: bool CHAR = set(chr(i) for i in range(0, 128)) @@ -67,7 +84,11 @@ coroutines._DEBUG = False # type: ignore @asyncio.coroutine -def noop(*args, **kwargs): +def noop(*args, **kwargs): # type: ignore + return # type: ignore + + +async def noop2(*args: Any, **kwargs: Any) -> None: return @@ -95,21 +116,30 @@ class BasicAuth(namedtuple('BasicAuth', ['login', 'password', 'encoding'])): @classmethod def decode(cls, auth_header: str, encoding: str='latin1') -> 'BasicAuth': """Create a BasicAuth object from an Authorization HTTP header.""" - split = auth_header.strip().split(' ') - if len(split) == 2: - if split[0].strip().lower() != 'basic': - raise ValueError('Unknown authorization method %s' % split[0]) - to_decode = split[1] - else: + try: + auth_type, encoded_credentials = auth_header.split(' ', 1) + except ValueError: raise ValueError('Could not parse authorization header.') + if auth_type.lower() != 'basic': + raise ValueError('Unknown authorization method %s' % auth_type) + try: - username, _, password = base64.b64decode( - to_decode.encode('ascii') - ).decode(encoding).partition(':') + decoded = base64.b64decode( + encoded_credentials.encode('ascii'), validate=True + ).decode(encoding) except binascii.Error: raise ValueError('Invalid base64 encoding.') + try: + # RFC 2617 HTTP Authentication + # https://www.ietf.org/rfc/rfc2617.txt + # the colon must be present, but the username and password may be + # otherwise blank. + username, password = decoded.split(':', 1) + except ValueError: + raise ValueError('Invalid credentials.') + return cls(username, password, encoding=encoding) @classmethod @@ -136,40 +166,49 @@ def strip_auth_from_url(url: URL) -> Tuple[URL, Optional[BasicAuth]]: return url.with_user(None), auth -def netrc_from_env(): - netrc_obj = None - netrc_path = os.environ.get('NETRC') - try: - if netrc_path is not None: - netrc_path = Path(netrc_path) - else: +def netrc_from_env() -> Optional[netrc.netrc]: + """Attempt to load the netrc file from the path specified by the env-var + NETRC or in the default location in the user's home directory. + + Returns None if it couldn't be found or fails to parse. + """ + netrc_env = os.environ.get('NETRC') + + if netrc_env is not None: + netrc_path = Path(netrc_env) + else: + try: home_dir = Path.home() - if os.name == 'nt': # pragma: no cover - netrc_path = home_dir.joinpath('_netrc') - else: - netrc_path = home_dir.joinpath('.netrc') + except RuntimeError as e: # pragma: no cover + # if pathlib can't resolve home, it may raise a RuntimeError + client_logger.debug('Could not resolve home directory when ' + 'trying to look for .netrc file: %s', e) + return None - if netrc_path and netrc_path.is_file(): - try: - netrc_obj = netrc.netrc(str(netrc_path)) - except (netrc.NetrcParseError, OSError) as e: - client_logger.warning(".netrc file parses fail: %s", e) + netrc_path = home_dir / ( + '_netrc' if platform.system() == 'Windows' else '.netrc') - if netrc_obj is None: - client_logger.warning("could't find .netrc file") - except RuntimeError as e: # pragma: no cover - """ handle error raised by pathlib """ - client_logger.warning("could't find .netrc file: %s", e) - return netrc_obj + try: + return netrc.netrc(str(netrc_path)) + except netrc.NetrcParseError as e: + client_logger.warning('Could not parse .netrc file: %s', e) + except OSError as e: + # we couldn't read the file (doesn't exist, permissions, etc.) + if netrc_env or netrc_path.is_file(): + # only warn if the environment wanted us to load it, + # or it appears like the default file does actually exist + client_logger.warning('Could not read .netrc file: %s', e) + + return None @attr.s(frozen=True, slots=True) class ProxyInfo: - proxy = attr.ib(type=str) - proxy_auth = attr.ib(type=BasicAuth) + proxy = attr.ib(type=URL) + proxy_auth = attr.ib(type=Optional[BasicAuth]) -def proxies_from_env(): +def proxies_from_env() -> Dict[str, ProxyInfo]: proxy_urls = {k: URL(v) for k, v in getproxies().items() if k in ('http', 'https')} netrc_obj = netrc_from_env() @@ -182,29 +221,48 @@ def proxies_from_env(): "HTTPS proxies %s are not supported, ignoring", proxy) continue if netrc_obj and auth is None: - auth_from_netrc = netrc_obj.authenticators(proxy.host) + auth_from_netrc = None + if proxy.host is not None: + auth_from_netrc = netrc_obj.authenticators(proxy.host) if auth_from_netrc is not None: # auth_from_netrc is a (`user`, `account`, `password`) tuple, # `user` and `account` both can be username, # if `user` is None, use `account` *logins, password = auth_from_netrc - auth = BasicAuth(logins[0] if logins[0] else logins[-1], - password) + login = logins[0] if logins[0] else logins[-1] + auth = BasicAuth(cast(str, login), cast(str, password)) ret[proto] = ProxyInfo(proxy, auth) return ret -def current_task(loop=None): +def current_task(loop: Optional[asyncio.AbstractEventLoop]=None) -> asyncio.Task: # type: ignore # noqa # Return type is intentionally Generic here if PY_37: - return asyncio.current_task(loop=loop) + return asyncio.current_task(loop=loop) # type: ignore else: - return asyncio.Task.current_task(loop=loop) - - -def isasyncgenfunction(obj): - if hasattr(inspect, 'isasyncgenfunction'): - return inspect.isasyncgenfunction(obj) - return False + return asyncio.Task.current_task(loop=loop) # type: ignore + + +def get_running_loop( + loop: Optional[asyncio.AbstractEventLoop]=None +) -> asyncio.AbstractEventLoop: + if loop is None: + loop = asyncio.get_event_loop() + if not loop.is_running(): + warnings.warn("The object should be created from async function", + DeprecationWarning, stacklevel=3) + if loop.get_debug(): + internal_logger.warning( + "The object should be created from async function", + stack_info=True) + return loop + + +def isasyncgenfunction(obj: Any) -> bool: + func = getattr(inspect, 'isasyncgenfunction', None) + if func is not None: + return func(obj) + else: + return False @attr.s(frozen=True, slots=True) @@ -212,10 +270,11 @@ class MimeType: type = attr.ib(type=str) subtype = attr.ib(type=str) suffix = attr.ib(type=str) - parameters = attr.ib(type=MultiDict) + parameters = attr.ib(type=MultiDictProxy) # type: MultiDictProxy[str] -def parse_mimetype(mimetype): +@functools.lru_cache(maxsize=56) +def parse_mimetype(mimetype: str) -> MimeType: """Parses a MIME type into its components. mimetype is a MIME type string. @@ -230,37 +289,41 @@ def parse_mimetype(mimetype): """ if not mimetype: - return MimeType(type='', subtype='', suffix='', parameters={}) + return MimeType(type='', subtype='', suffix='', + parameters=MultiDictProxy(MultiDict())) parts = mimetype.split(';') - params = [] + params = MultiDict() # type: MultiDict[str] for item in parts[1:]: if not item: continue - key, value = item.split('=', 1) if '=' in item else (item, '') - params.append((key.lower().strip(), value.strip(' "'))) - params = MultiDict(params) + key, value = cast(Tuple[str, str], + item.split('=', 1) if '=' in item else (item, '')) + params.add(key.lower().strip(), value.strip(' "')) fulltype = parts[0].strip().lower() if fulltype == '*': fulltype = '*/*' - mtype, stype = fulltype.split('/', 1) \ - if '/' in fulltype else (fulltype, '') - stype, suffix = stype.split('+', 1) if '+' in stype else (stype, '') + mtype, stype = (cast(Tuple[str, str], fulltype.split('/', 1)) + if '/' in fulltype else (fulltype, '')) + stype, suffix = (cast(Tuple[str, str], stype.split('+', 1)) + if '+' in stype else (stype, '')) return MimeType(type=mtype, subtype=stype, suffix=suffix, - parameters=params) + parameters=MultiDictProxy(params)) -def guess_filename(obj, default=None): +def guess_filename(obj: Any, default: Optional[str]=None) -> Optional[str]: name = getattr(obj, 'name', None) if name and isinstance(name, str) and name[0] != '<' and name[-1] != '>': return Path(name).name return default -def content_disposition_header(disptype, quote_fields=True, **params): +def content_disposition_header(disptype: str, + quote_fields: bool=True, + **params: str) -> str: """Sets ``Content-Disposition`` header. disptype is a disposition type: inline, attachment, form-data. @@ -288,193 +351,6 @@ def content_disposition_header(disptype, quote_fields=True, **params): return value -KeyMethod = namedtuple('KeyMethod', 'key method') - - -class AccessLogger(AbstractAccessLogger): - """Helper object to log access. - - Usage: - log = logging.getLogger("spam") - log_format = "%a %{User-Agent}i" - access_logger = AccessLogger(log, log_format) - access_logger.log(request, response, time) - - Format: - %% The percent sign - %a Remote IP-address (IP-address of proxy if using reverse proxy) - %t Time when the request was started to process - %P The process ID of the child that serviced the request - %r First line of request - %s Response status code - %b Size of response in bytes, including HTTP headers - %T Time taken to serve the request, in seconds - %Tf Time taken to serve the request, in seconds with floating fraction - in .06f format - %D Time taken to serve the request, in microseconds - %{FOO}i request.headers['FOO'] - %{FOO}o response.headers['FOO'] - %{FOO}e os.environ['FOO'] - - """ - LOG_FORMAT_MAP = { - 'a': 'remote_address', - 't': 'request_start_time', - 'P': 'process_id', - 'r': 'first_request_line', - 's': 'response_status', - 'b': 'response_size', - 'T': 'request_time', - 'Tf': 'request_time_frac', - 'D': 'request_time_micro', - 'i': 'request_header', - 'o': 'response_header', - } - - LOG_FORMAT = '%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"' - FORMAT_RE = re.compile(r'%(\{([A-Za-z0-9\-_]+)\}([ioe])|[atPrsbOD]|Tf?)') - CLEANUP_RE = re.compile(r'(%[^s])') - _FORMAT_CACHE = {} # type: Dict[str, Tuple[str, List[KeyMethod]]] - - def __init__(self, logger, log_format=LOG_FORMAT): - """Initialise the logger. - - logger is a logger object to be used for logging. - log_format is an string with apache compatible log format description. - - """ - super().__init__(logger, log_format=log_format) - - _compiled_format = AccessLogger._FORMAT_CACHE.get(log_format) - if not _compiled_format: - _compiled_format = self.compile_format(log_format) - AccessLogger._FORMAT_CACHE[log_format] = _compiled_format - - self._log_format, self._methods = _compiled_format - - def compile_format(self, log_format): - """Translate log_format into form usable by modulo formatting - - All known atoms will be replaced with %s - Also methods for formatting of those atoms will be added to - _methods in appropriate order - - For example we have log_format = "%a %t" - This format will be translated to "%s %s" - Also contents of _methods will be - [self._format_a, self._format_t] - These method will be called and results will be passed - to translated string format. - - Each _format_* method receive 'args' which is list of arguments - given to self.log - - Exceptions are _format_e, _format_i and _format_o methods which - also receive key name (by functools.partial) - - """ - # list of (key, method) tuples, we don't use an OrderedDict as users - # can repeat the same key more than once - methods = list() - - for atom in self.FORMAT_RE.findall(log_format): - if atom[1] == '': - format_key = self.LOG_FORMAT_MAP[atom[0]] - m = getattr(AccessLogger, '_format_%s' % atom[0]) - else: - format_key = (self.LOG_FORMAT_MAP[atom[2]], atom[1]) - m = getattr(AccessLogger, '_format_%s' % atom[2]) - m = functools.partial(m, atom[1]) - - methods.append(KeyMethod(format_key, m)) - - log_format = self.FORMAT_RE.sub(r'%s', log_format) - log_format = self.CLEANUP_RE.sub(r'%\1', log_format) - return log_format, methods - - @staticmethod - def _format_i(key, request, response, time): - if request is None: - return '(no headers)' - - # suboptimal, make istr(key) once - return request.headers.get(key, '-') - - @staticmethod - def _format_o(key, request, response, time): - # suboptimal, make istr(key) once - return response.headers.get(key, '-') - - @staticmethod - def _format_a(request, response, time): - if request is None: - return '-' - ip = request.remote - return ip if ip is not None else '-' - - @staticmethod - def _format_t(request, response, time): - now = datetime.datetime.utcnow() - start_time = now - datetime.timedelta(seconds=time) - return start_time.strftime('[%d/%b/%Y:%H:%M:%S +0000]') - - @staticmethod - def _format_P(request, response, time): - return "<%s>" % os.getpid() - - @staticmethod - def _format_r(request, response, time): - if request is None: - return '-' - return '%s %s HTTP/%s.%s' % tuple((request.method, - request.path_qs) + request.version) - - @staticmethod - def _format_s(request, response, time): - return response.status - - @staticmethod - def _format_b(request, response, time): - return response.body_length - - @staticmethod - def _format_T(request, response, time): - return round(time) - - @staticmethod - def _format_Tf(request, response, time): - return '%06f' % time - - @staticmethod - def _format_D(request, response, time): - return round(time * 1000000) - - def _format_line(self, request, response, time): - return ((key, method(request, response, time)) - for key, method in self._methods) - - def log(self, request, response, time): - try: - fmt_info = self._format_line(request, response, time) - - values = list() - extra = dict() - for key, value in fmt_info: - values.append(value) - - if key.__class__ is str: - extra[key] = value - else: - k1, k2 = key - dct = extra.get(k1, {}) - dct[k2] = value - extra[k1] = dct - - self.logger.info(self._log_format % tuple(values), extra=extra) - except Exception: - self.logger.exception("Error in logging") - - class reify: """Use as a class method decorator. It operates almost exactly like the Python `@property` decorator, but it puts the result of the @@ -484,12 +360,12 @@ class reify: """ - def __init__(self, wrapped): + def __init__(self, wrapped: Callable[..., Any]) -> None: self.wrapped = wrapped self.__doc__ = wrapped.__doc__ self.name = wrapped.__name__ - def __get__(self, inst, owner): + def __get__(self, inst: Any, owner: Any) -> Any: try: try: return inst._cache[self.name] @@ -502,7 +378,7 @@ class reify: return self raise - def __set__(self, inst, value): + def __set__(self, inst: Any, value: Any) -> None: raise AttributeError("reified property is read-only") @@ -532,29 +408,34 @@ _ipv4_regexb = re.compile(_ipv4_pattern.encode('ascii')) _ipv6_regexb = re.compile(_ipv6_pattern.encode('ascii'), flags=re.IGNORECASE) -def is_ip_address(host): +def _is_ip_address( + regex: Pattern[str], regexb: Pattern[bytes], + host: Optional[Union[str, bytes]])-> bool: if host is None: return False if isinstance(host, str): - if _ipv4_regex.match(host) or _ipv6_regex.match(host): - return True - else: - return False + return bool(regex.match(host)) elif isinstance(host, (bytes, bytearray, memoryview)): - if _ipv4_regexb.match(host) or _ipv6_regexb.match(host): - return True - else: - return False + return bool(regexb.match(host)) else: raise TypeError("{} [{}] is not a str or bytes" .format(host, type(host))) +is_ipv4_address = functools.partial(_is_ip_address, _ipv4_regex, _ipv4_regexb) +is_ipv6_address = functools.partial(_is_ip_address, _ipv6_regex, _ipv6_regexb) + + +def is_ip_address( + host: Optional[Union[str, bytes, bytearray, memoryview]]) -> bool: + return is_ipv4_address(host) or is_ipv6_address(host) + + _cached_current_datetime = None _cached_formatted_datetime = None -def rfc822_formatted_time(): +def rfc822_formatted_time() -> str: global _cached_current_datetime global _cached_formatted_datetime @@ -568,15 +449,15 @@ def rfc822_formatted_time(): "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec") - year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now) + year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now) # type: ignore # noqa _cached_formatted_datetime = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( _weekdayname[wd], day, _monthname[month], year, hh, mm, ss ) _cached_current_datetime = now - return _cached_formatted_datetime + return _cached_formatted_datetime # type: ignore -def _weakref_handle(info): +def _weakref_handle(info): # type: ignore ref, name = info ob = ref() if ob is not None: @@ -584,7 +465,7 @@ def _weakref_handle(info): getattr(ob, name)() -def weakref_handle(ob, name, timeout, loop, ceil_timeout=True): +def weakref_handle(ob, name, timeout, loop, ceil_timeout=True): # type: ignore if timeout is not None and timeout > 0: when = loop.time() + timeout if ceil_timeout: @@ -593,7 +474,7 @@ def weakref_handle(ob, name, timeout, loop, ceil_timeout=True): return loop.call_at(when, _weakref_handle, (weakref.ref(ob), name)) -def call_later(cb, timeout, loop): +def call_later(cb, timeout, loop): # type: ignore if timeout is not None and timeout > 0: when = ceil(loop.time() + timeout) return loop.call_at(when, cb) @@ -602,31 +483,36 @@ def call_later(cb, timeout, loop): class TimeoutHandle: """ Timeout handle """ - def __init__(self, loop, timeout): + def __init__(self, + loop: asyncio.AbstractEventLoop, + timeout: Optional[float]) -> None: self._timeout = timeout self._loop = loop - self._callbacks = [] + self._callbacks = [] # type: List[Tuple[Callable[..., None], Tuple[Any, ...], Dict[str, Any]]] # noqa - def register(self, callback, *args, **kwargs): + def register(self, callback: Callable[..., None], + *args: Any, **kwargs: Any) -> None: self._callbacks.append((callback, args, kwargs)) - def close(self): + def close(self) -> None: self._callbacks.clear() - def start(self): + def start(self) -> Optional[asyncio.Handle]: if self._timeout is not None and self._timeout > 0: at = ceil(self._loop.time() + self._timeout) return self._loop.call_at(at, self.__call__) + else: + return None - def timer(self): + def timer(self) -> 'BaseTimerContext': if self._timeout is not None and self._timeout > 0: timer = TimerContext(self._loop) self.register(timer.timeout) + return timer else: - timer = TimerNoop() - return timer + return TimerNoop() - def __call__(self): + def __call__(self) -> None: for cb, args, kwargs in self._callbacks: with suppress(Exception): cb(*args, **kwargs) @@ -634,24 +520,30 @@ class TimeoutHandle: self._callbacks.clear() -class TimerNoop: +class BaseTimerContext(ContextManager['BaseTimerContext']): + pass + + +class TimerNoop(BaseTimerContext): - def __enter__(self): + def __enter__(self) -> BaseTimerContext: return self - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__(self, exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> Optional[bool]: return False -class TimerContext: +class TimerContext(BaseTimerContext): """ Low resolution timeout context manager """ - def __init__(self, loop): + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: self._loop = loop - self._tasks = [] + self._tasks = [] # type: List[asyncio.Task[Any]] self._cancelled = False - def __enter__(self): + def __enter__(self) -> BaseTimerContext: task = current_task(loop=self._loop) if task is None: @@ -665,14 +557,17 @@ class TimerContext: self._tasks.append(task) return self - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__(self, exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> Optional[bool]: if self._tasks: self._tasks.pop() if exc_type is asyncio.CancelledError and self._cancelled: raise asyncio.TimeoutError from None + return None - def timeout(self): + def timeout(self) -> None: if not self._cancelled: for task in set(self._tasks): task.cancel() @@ -682,7 +577,7 @@ class TimerContext: class CeilTimeout(async_timeout.timeout): - def __enter__(self): + def __enter__(self) -> async_timeout.timeout: if self._timeout is not None: self._task = current_task(loop=self._loop) if self._task is None: @@ -698,11 +593,11 @@ class HeadersMixin: ATTRS = frozenset([ '_content_type', '_content_dict', '_stored_content_type']) - _content_type = None - _content_dict = None + _content_type = None # type: Optional[str] + _content_dict = None # type: Optional[Dict[str, str]] _stored_content_type = sentinel - def _parse_content_type(self, raw): + def _parse_content_type(self, raw: str) -> None: self._stored_content_type = raw if raw is None: # default value according to RFC 2616 @@ -712,51 +607,53 @@ class HeadersMixin: self._content_type, self._content_dict = cgi.parse_header(raw) @property - def content_type(self): + def content_type(self) -> str: """The value of content part for Content-Type HTTP header.""" - raw = self._headers.get(hdrs.CONTENT_TYPE) + raw = self._headers.get(hdrs.CONTENT_TYPE) # type: ignore if self._stored_content_type != raw: self._parse_content_type(raw) - return self._content_type + return self._content_type # type: ignore @property - def charset(self): + def charset(self) -> Optional[str]: """The value of charset part for Content-Type HTTP header.""" - raw = self._headers.get(hdrs.CONTENT_TYPE) + raw = self._headers.get(hdrs.CONTENT_TYPE) # type: ignore if self._stored_content_type != raw: self._parse_content_type(raw) - return self._content_dict.get('charset') + return self._content_dict.get('charset') # type: ignore @property - def content_length(self): + def content_length(self) -> Optional[int]: """The value of Content-Length HTTP header.""" - content_length = self._headers.get(hdrs.CONTENT_LENGTH) + content_length = self._headers.get(hdrs.CONTENT_LENGTH) # type: ignore - if content_length: + if content_length is not None: return int(content_length) + else: + return None -def set_result(fut, result): +def set_result(fut: 'asyncio.Future[_T]', result: _T) -> None: if not fut.done(): fut.set_result(result) -def set_exception(fut, exc): +def set_exception(fut: 'asyncio.Future[_T]', exc: BaseException) -> None: if not fut.done(): fut.set_exception(exc) -class ChainMapProxy(ABCMapping): +class ChainMapProxy(Mapping[str, Any]): __slots__ = ('_maps',) - def __init__(self, maps): + def __init__(self, maps: Iterable[Mapping[str, Any]]) -> None: self._maps = tuple(maps) - def __init_subclass__(cls): + def __init_subclass__(cls) -> None: raise TypeError("Inheritance class {} from ChainMapProxy " "is forbidden".format(cls.__name__)) - def __getitem__(self, key): + def __getitem__(self, key: str) -> Any: for mapping in self._maps: try: return mapping[key] @@ -764,26 +661,26 @@ class ChainMapProxy(ABCMapping): pass raise KeyError(key) - def get(self, key, default=None): + def get(self, key: str, default: Any=None) -> Any: return self[key] if key in self else default - def __len__(self): + def __len__(self) -> int: # reuses stored hash values if possible - return len(set().union(*self._maps)) + return len(set().union(*self._maps)) # type: ignore - def __iter__(self): - d = {} + def __iter__(self) -> Iterator[str]: + d = {} # type: Dict[str, Any] for mapping in reversed(self._maps): # reuses stored hash values if possible d.update(mapping) return iter(d) - def __contains__(self, key): + def __contains__(self, key: object) -> bool: return any(key in m for m in self._maps) - def __bool__(self): + def __bool__(self) -> bool: return any(self._maps) - def __repr__(self): + def __repr__(self) -> str: content = ", ".join(map(repr, self._maps)) return 'ChainMapProxy({})'.format(content) diff --git a/aiohttp/http.py b/aiohttp/http.py index 0c9747b..a072d27 100644 --- a/aiohttp/http.py +++ b/aiohttp/http.py @@ -1,10 +1,12 @@ import http.server import sys +from typing import Mapping, Tuple # noqa from . import __version__ from .http_exceptions import HttpProcessingError -from .http_parser import (HttpParser, HttpRequestParser, HttpResponseParser, - RawRequestMessage, RawResponseMessage) +from .http_parser import (HeadersParser, HttpParser, HttpRequestParser, + HttpResponseParser, RawRequestMessage, + RawResponseMessage) from .http_websocket import (WS_CLOSED_MESSAGE, WS_CLOSING_MESSAGE, WS_KEY, WebSocketError, WebSocketReader, WebSocketWriter, WSCloseCode, WSMessage, WSMsgType, ws_ext_gen, @@ -20,7 +22,8 @@ __all__ = ( 'StreamWriter', 'HttpVersion', 'HttpVersion10', 'HttpVersion11', # .http_parser - 'HttpParser', 'HttpRequestParser', 'HttpResponseParser', + 'HeadersParser', 'HttpParser', + 'HttpRequestParser', 'HttpResponseParser', 'RawRequestMessage', 'RawResponseMessage', # .http_websocket @@ -31,6 +34,6 @@ __all__ = ( SERVER_SOFTWARE = 'Python/{0[0]}.{0[1]} aiohttp/{1}'.format( - sys.version_info, __version__) + sys.version_info, __version__) # type: str -RESPONSES = http.server.BaseHTTPRequestHandler.responses +RESPONSES = http.server.BaseHTTPRequestHandler.responses # type: Mapping[int, Tuple[str, str]] # noqa diff --git a/aiohttp/http_exceptions.py b/aiohttp/http_exceptions.py index a3d4c90..54dcaad 100644 --- a/aiohttp/http_exceptions.py +++ b/aiohttp/http_exceptions.py @@ -1,5 +1,11 @@ """Low-level http related exceptions.""" + +from typing import Optional, Union + +from .typedefs import _CIMultiDict + + __all__ = ('HttpProcessingError',) @@ -17,7 +23,10 @@ class HttpProcessingError(Exception): message = '' headers = None - def __init__(self, *, code=None, message='', headers=None): + def __init__(self, *, + code: Optional[int]=None, + message: str='', + headers: Optional[_CIMultiDict]=None) -> None: if code is not None: self.code = code self.headers = headers @@ -31,7 +40,8 @@ class BadHttpMessage(HttpProcessingError): code = 400 message = 'Bad Request' - def __init__(self, message, *, headers=None): + def __init__(self, message: str, *, + headers: Optional[_CIMultiDict]=None) -> None: super().__init__(message=message, headers=headers) @@ -59,7 +69,9 @@ class ContentLengthError(PayloadEncodingError): class LineTooLong(BadHttpMessage): - def __init__(self, line, limit='Unknown', actual_size='Unknown'): + def __init__(self, line: str, + limit: str='Unknown', + actual_size: str='Unknown') -> None: super().__init__( "Got more than %s bytes (%s) when reading %s." % ( limit, actual_size, line)) @@ -67,7 +79,7 @@ class LineTooLong(BadHttpMessage): class InvalidHeader(BadHttpMessage): - def __init__(self, hdr): + def __init__(self, hdr: Union[bytes, str]) -> None: if isinstance(hdr, bytes): hdr = hdr.decode('utf-8', 'surrogateescape') super().__init__('Invalid HTTP Header: {}'.format(hdr)) @@ -76,7 +88,7 @@ class InvalidHeader(BadHttpMessage): class BadStatusLine(BadHttpMessage): - def __init__(self, line=''): + def __init__(self, line: str='') -> None: if not line: line = repr(line) self.args = line, diff --git a/aiohttp/http_parser.py b/aiohttp/http_parser.py index ab6d5c4..a738a96 100644 --- a/aiohttp/http_parser.py +++ b/aiohttp/http_parser.py @@ -1,20 +1,25 @@ +import abc +import asyncio import collections import re import string import zlib from enum import IntEnum +from typing import Any, List, Optional, Tuple, Type, Union # noqa -from multidict import CIMultiDict, CIMultiDictProxy +from multidict import CIMultiDict, CIMultiDictProxy, istr from yarl import URL from . import hdrs -from .helpers import NO_EXTENSIONS +from .base_protocol import BaseProtocol +from .helpers import NO_EXTENSIONS, BaseTimerContext from .http_exceptions import (BadStatusLine, ContentEncodingError, ContentLengthError, InvalidHeader, LineTooLong, TransferEncodingError) from .http_writer import HttpVersion, HttpVersion10 from .log import internal_logger from .streams import EMPTY_PAYLOAD, StreamReader +from .typedefs import RawHeaders try: @@ -25,11 +30,19 @@ except ImportError: # pragma: no cover __all__ = ( - 'HttpParser', 'HttpRequestParser', 'HttpResponseParser', + 'HeadersParser', 'HttpParser', 'HttpRequestParser', 'HttpResponseParser', 'RawRequestMessage', 'RawResponseMessage') ASCIISET = set(string.printable) -METHRE = re.compile('[A-Z0-9$-_.]+') + +# See https://tools.ietf.org/html/rfc7230#section-3.1.1 +# and https://tools.ietf.org/html/rfc7230#appendix-B +# +# method = token +# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / +# "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA +# token = 1*tchar +METHRE = re.compile(r"[!#$%&'*+\-.^_`|~0-9A-Za-z]+") VERSRE = re.compile(r'HTTP/(\d+).(\d+)') HDRRE = re.compile(rb'[\x00-\x1F\x7F()<>@,;:\[\]={} \t\\\\\"]') @@ -60,14 +73,108 @@ class ChunkState(IntEnum): PARSE_TRAILERS = 4 -class HttpParser: +class HeadersParser: + def __init__(self, + max_line_size: int=8190, + max_headers: int=32768, + max_field_size: int=8190) -> None: + self.max_line_size = max_line_size + self.max_headers = max_headers + self.max_field_size = max_field_size + + def parse_headers( + self, + lines: List[bytes] + ) -> Tuple['CIMultiDictProxy[str]', RawHeaders]: + headers = CIMultiDict() # type: CIMultiDict[str] + raw_headers = [] + + lines_idx = 1 + line = lines[1] + line_count = len(lines) + + while line: + # Parse initial header name : value pair. + try: + bname, bvalue = line.split(b':', 1) + except ValueError: + raise InvalidHeader(line) from None + + bname = bname.strip(b' \t') + bvalue = bvalue.lstrip() + if HDRRE.search(bname): + raise InvalidHeader(bname) + if len(bname) > self.max_field_size: + raise LineTooLong( + "request header name {}".format( + bname.decode("utf8", "xmlcharrefreplace")), + str(self.max_field_size), + str(len(bname))) + + header_length = len(bvalue) + + # next line + lines_idx += 1 + line = lines[lines_idx] + + # consume continuation lines + continuation = line and line[0] in (32, 9) # (' ', '\t') + + if continuation: + bvalue_lst = [bvalue] + while continuation: + header_length += len(line) + if header_length > self.max_field_size: + raise LineTooLong( + 'request header field {}'.format( + bname.decode("utf8", "xmlcharrefreplace")), + str(self.max_field_size), + str(header_length)) + bvalue_lst.append(line) + + # next line + lines_idx += 1 + if lines_idx < line_count: + line = lines[lines_idx] + if line: + continuation = line[0] in (32, 9) # (' ', '\t') + else: + line = b'' + break + bvalue = b''.join(bvalue_lst) + else: + if header_length > self.max_field_size: + raise LineTooLong( + 'request header field {}'.format( + bname.decode("utf8", "xmlcharrefreplace")), + str(self.max_field_size), + str(header_length)) + + bvalue = bvalue.strip() + name = bname.decode('utf-8', 'surrogateescape') + value = bvalue.decode('utf-8', 'surrogateescape') + + headers.add(name, value) + raw_headers.append((bname, bvalue)) + + return (CIMultiDictProxy(headers), tuple(raw_headers)) + + +class HttpParser(abc.ABC): - def __init__(self, protocol=None, loop=None, - max_line_size=8190, max_headers=32768, max_field_size=8190, - timer=None, code=None, method=None, readall=False, - payload_exception=None, - response_with_body=True, read_until_eof=False, - auto_decompress=True): + def __init__(self, protocol: Optional[BaseProtocol]=None, + loop: Optional[asyncio.AbstractEventLoop]=None, + max_line_size: int=8190, + max_headers: int=32768, + max_field_size: int=8190, + timer: Optional[BaseTimerContext]=None, + code: Optional[int]=None, + method: Optional[str]=None, + readall: bool=False, + payload_exception: Optional[Type[BaseException]]=None, + response_with_body: bool=True, + read_until_eof: bool=False, + auto_decompress: bool=True) -> None: self.protocol = protocol self.loop = loop self.max_line_size = max_line_size @@ -81,14 +188,21 @@ class HttpParser: self.response_with_body = response_with_body self.read_until_eof = read_until_eof - self._lines = [] + self._lines = [] # type: List[bytes] self._tail = b'' self._upgraded = False self._payload = None - self._payload_parser = None + self._payload_parser = None # type: Optional[HttpPayloadParser] self._auto_decompress = auto_decompress + self._headers_parser = HeadersParser(max_line_size, + max_headers, + max_field_size) + + @abc.abstractmethod + def parse_message(self, lines: List[bytes]) -> Any: + pass - def feed_eof(self): + def feed_eof(self) -> Any: if self._payload_parser is not None: self._payload_parser.feed_eof() self._payload_parser = None @@ -99,17 +213,21 @@ class HttpParser: if self._lines: if self._lines[-1] != '\r\n': - self._lines.append('') + self._lines.append(b'') try: return self.parse_message(self._lines) except Exception: return None - def feed_data(self, data, - SEP=b'\r\n', EMPTY=b'', - CONTENT_LENGTH=hdrs.CONTENT_LENGTH, - METH_CONNECT=hdrs.METH_CONNECT, - SEC_WEBSOCKET_KEY1=hdrs.SEC_WEBSOCKET_KEY1): + def feed_data( + self, + data: bytes, + SEP: bytes=b'\r\n', + EMPTY: bytes=b'', + CONTENT_LENGTH: istr=hdrs.CONTENT_LENGTH, + METH_CONNECT: str=hdrs.METH_CONNECT, + SEC_WEBSOCKET_KEY1: istr=hdrs.SEC_WEBSOCKET_KEY1 + ) -> Tuple[List[Any], bool, bytes]: messages = [] @@ -161,6 +279,7 @@ class HttpParser: method = getattr(msg, 'method', self.method) + assert self.protocol is not None # calculate payload if ((length is not None and length > 0) or msg.chunked and not msg.upgrade): @@ -198,7 +317,7 @@ class HttpParser: if not payload_parser.done: self._payload_parser = payload_parser else: - payload = EMPTY_PAYLOAD + payload = EMPTY_PAYLOAD # type: ignore messages.append((msg, payload)) else: @@ -214,6 +333,7 @@ class HttpParser: # feed payload elif data and start_pos < data_len: assert not self._lines + assert self._payload_parser is not None try: eof, data = self._payload_parser.feed_data( data[start_pos:]) @@ -242,89 +362,25 @@ class HttpParser: return messages, self._upgraded, data - def parse_headers(self, lines): + def parse_headers( + self, + lines: List[bytes] + ) -> Tuple['CIMultiDictProxy[str]', + RawHeaders, + Optional[bool], + Optional[str], + bool, + bool]: """Parses RFC 5322 headers from a stream. Line continuations are supported. Returns list of header name and value pairs. Header name is in upper case. """ - headers = CIMultiDict() - raw_headers = [] - - lines_idx = 1 - line = lines[1] - line_count = len(lines) - - while line: - # Parse initial header name : value pair. - try: - bname, bvalue = line.split(b':', 1) - except ValueError: - raise InvalidHeader(line) from None - - bname = bname.strip(b' \t') - bvalue = bvalue.lstrip() - if HDRRE.search(bname): - raise InvalidHeader(bname) - if len(bname) > self.max_field_size: - raise LineTooLong( - "request header name {}".format( - bname.decode("utf8", "xmlcharrefreplace")), - self.max_field_size, - len(bname)) - - header_length = len(bvalue) - - # next line - lines_idx += 1 - line = lines[lines_idx] - - # consume continuation lines - continuation = line and line[0] in (32, 9) # (' ', '\t') - - if continuation: - bvalue = [bvalue] - while continuation: - header_length += len(line) - if header_length > self.max_field_size: - raise LineTooLong( - 'request header field {}'.format( - bname.decode("utf8", "xmlcharrefreplace")), - self.max_field_size, - header_length) - bvalue.append(line) - - # next line - lines_idx += 1 - if lines_idx < line_count: - line = lines[lines_idx] - if line: - continuation = line[0] in (32, 9) # (' ', '\t') - else: - line = b'' - break - bvalue = b''.join(bvalue) - else: - if header_length > self.max_field_size: - raise LineTooLong( - 'request header field {}'.format( - bname.decode("utf8", "xmlcharrefreplace")), - self.max_field_size, - header_length) - - bvalue = bvalue.strip() - name = bname.decode('utf-8', 'surrogateescape') - value = bvalue.decode('utf-8', 'surrogateescape') - - headers.add(name, value) - raw_headers.append((bname, bvalue)) - + headers, raw_headers = self._headers_parser.parse_headers(lines) close_conn = None encoding = None upgrade = False chunked = False - raw_headers = tuple(raw_headers) - headers = CIMultiDictProxy(headers) # keep-alive conn = headers.get(hdrs.CONNECTION) @@ -349,7 +405,7 @@ class HttpParser: if te and 'chunked' in te.lower(): chunked = True - return headers, raw_headers, close_conn, encoding, upgrade, chunked + return (headers, raw_headers, close_conn, encoding, upgrade, chunked) class HttpRequestParser(HttpParser): @@ -358,7 +414,7 @@ class HttpRequestParser(HttpParser): Returns RawRequestMessage. """ - def parse_message(self, lines): + def parse_message(self, lines: List[bytes]) -> Any: # request line line = lines[0].decode('utf-8', 'surrogateescape') try: @@ -368,10 +424,11 @@ class HttpRequestParser(HttpParser): if len(path) > self.max_line_size: raise LineTooLong( - 'Status line is too long', self.max_line_size, len(path)) + 'Status line is too long', + str(self.max_line_size), + str(len(path))) # method - method = method.upper() if not METHRE.match(method): raise BadStatusLine(method) @@ -379,7 +436,7 @@ class HttpRequestParser(HttpParser): try: if version.startswith('HTTP/'): n1, n2 = version[5:].split('.', 1) - version = HttpVersion(int(n1), int(n2)) + version_o = HttpVersion(int(n1), int(n2)) else: raise BadStatusLine(version) except Exception: @@ -390,13 +447,13 @@ class HttpRequestParser(HttpParser): close, compression, upgrade, chunked) = self.parse_headers(lines) if close is None: # then the headers weren't set in the request - if version <= HttpVersion10: # HTTP 1.0 must asks to not close + if version_o <= HttpVersion10: # HTTP 1.0 must asks to not close close = True else: # HTTP 1.1 must ask to close. close = False return RawRequestMessage( - method, path, version, headers, raw_headers, + method, path, version_o, headers, raw_headers, close, compression, upgrade, chunked, URL(path)) @@ -406,7 +463,7 @@ class HttpResponseParser(HttpParser): BadStatusLine could be raised in case of any errors in status line. Returns RawResponseMessage""" - def parse_message(self, lines): + def parse_message(self, lines: List[bytes]) -> Any: line = lines[0].decode('utf-8', 'surrogateescape') try: version, status = line.split(None, 1) @@ -420,22 +477,23 @@ class HttpResponseParser(HttpParser): if len(reason) > self.max_line_size: raise LineTooLong( - 'Status line is too long', self.max_line_size, - len(reason)) + 'Status line is too long', + str(self.max_line_size), + str(len(reason))) # version match = VERSRE.match(version) if match is None: raise BadStatusLine(line) - version = HttpVersion(int(match.group(1)), int(match.group(2))) + version_o = HttpVersion(int(match.group(1)), int(match.group(2))) # The status code is a three-digit number try: - status = int(status) + status_i = int(status) except ValueError: raise BadStatusLine(line) from None - if status > 999: + if status_i > 999: raise BadStatusLine(line) # read headers @@ -443,21 +501,24 @@ class HttpResponseParser(HttpParser): close, compression, upgrade, chunked) = self.parse_headers(lines) if close is None: - close = version <= HttpVersion10 + close = version_o <= HttpVersion10 return RawResponseMessage( - version, status, reason.strip(), + version_o, status_i, reason.strip(), headers, raw_headers, close, compression, upgrade, chunked) class HttpPayloadParser: - def __init__(self, payload, - length=None, chunked=False, compression=None, - code=None, method=None, - readall=False, response_with_body=True, auto_decompress=True): - self.payload = payload - + def __init__(self, payload: StreamReader, + length: Optional[int]=None, + chunked: bool=False, + compression: Optional[str]=None, + code: Optional[int]=None, + method: Optional[str]=None, + readall: bool=False, + response_with_body: bool=True, + auto_decompress: bool=True) -> None: self._length = 0 self._type = ParseState.PARSE_NONE self._chunk = ChunkState.PARSE_CHUNKED_SIZE @@ -468,13 +529,15 @@ class HttpPayloadParser: # payload decompression wrapper if response_with_body and compression and self._auto_decompress: - payload = DeflateBuffer(payload, compression) + real_payload = DeflateBuffer(payload, compression) # type: Union[StreamReader, DeflateBuffer] # noqa + else: + real_payload = payload # payload parser if not response_with_body: # don't parse payload if it's not expected to be received self._type = ParseState.PARSE_NONE - payload.feed_eof() + real_payload.feed_eof() self.done = True elif chunked: @@ -483,7 +546,7 @@ class HttpPayloadParser: self._type = ParseState.PARSE_LENGTH self._length = length if self._length == 0: - payload.feed_eof() + real_payload.feed_eof() self.done = True else: if readall and code != 204: @@ -492,12 +555,12 @@ class HttpPayloadParser: internal_logger.warning( # pragma: no cover 'Content-Length or Transfer-Encoding header is required') self._type = ParseState.PARSE_NONE - payload.feed_eof() + real_payload.feed_eof() self.done = True - self.payload = payload + self.payload = real_payload - def feed_eof(self): + def feed_eof(self) -> None: if self._type == ParseState.PARSE_UNTIL_EOF: self.payload.feed_eof() elif self._type == ParseState.PARSE_LENGTH: @@ -507,7 +570,10 @@ class HttpPayloadParser: raise TransferEncodingError( "Not enough data for satisfy transfer length header.") - def feed_data(self, chunk, SEP=b'\r\n', CHUNK_EXT=b';'): + def feed_data(self, + chunk: bytes, + SEP: bytes=b'\r\n', + CHUNK_EXT: bytes=b';') -> Tuple[bool, bytes]: # Read specified amount of bytes if self._type == ParseState.PARSE_LENGTH: required = self._length @@ -539,14 +605,15 @@ class HttpPayloadParser: if pos >= 0: i = chunk.find(CHUNK_EXT, 0, pos) if i >= 0: - size = chunk[:i] # strip chunk-extensions + size_b = chunk[:i] # strip chunk-extensions else: - size = chunk[:pos] + size_b = chunk[:pos] try: - size = int(bytes(size), 16) + size = int(bytes(size_b), 16) except ValueError: - exc = TransferEncodingError(chunk[:pos]) + exc = TransferEncodingError( + chunk[:pos].decode('ascii', 'surrogateescape')) self.payload.set_exception(exc) raise exc from None @@ -559,7 +626,7 @@ class HttpPayloadParser: self.payload.begin_http_chunk_receiving() else: self._chunk_tail = chunk - return False, None + return False, b'' # read chunk and feed buffer if self._chunk == ChunkState.PARSE_CHUNKED_CHUNK: @@ -569,7 +636,7 @@ class HttpPayloadParser: if required > chunk_len: self._chunk_size = required - chunk_len self.payload.feed_data(chunk, chunk_len) - return False, None + return False, b'' else: self._chunk_size = 0 self.payload.feed_data(chunk[:required], required) @@ -584,7 +651,7 @@ class HttpPayloadParser: self._chunk = ChunkState.PARSE_CHUNKED_SIZE else: self._chunk_tail = chunk - return False, None + return False, b'' # if stream does not contain trailer, after 0\r\n # we should get another \r\n otherwise @@ -605,19 +672,19 @@ class HttpPayloadParser: self._chunk = ChunkState.PARSE_MAYBE_TRAILERS else: self._chunk_tail = chunk - return False, None + return False, b'' # Read all bytes until eof elif self._type == ParseState.PARSE_UNTIL_EOF: self.payload.feed_data(chunk, len(chunk)) - return False, None + return False, b'' class DeflateBuffer: """DeflateStream decompress stream and feed data into specified stream.""" - def __init__(self, out, encoding): + def __init__(self, out: StreamReader, encoding: Optional[str]) -> None: self.out = out self.size = 0 self.encoding = encoding @@ -634,10 +701,10 @@ class DeflateBuffer: if encoding == 'gzip' else -zlib.MAX_WBITS) self.decompressor = zlib.decompressobj(wbits=zlib_mode) - def set_exception(self, exc): + def set_exception(self, exc: BaseException) -> None: self.out.set_exception(exc) - def feed_data(self, chunk, size): + def feed_data(self, chunk: bytes, size: int) -> None: self.size += size try: chunk = self.decompressor.decompress(chunk) @@ -657,7 +724,7 @@ class DeflateBuffer: self._started_decoding = True self.out.feed_data(chunk, len(chunk)) - def feed_eof(self): + def feed_eof(self) -> None: chunk = self.decompressor.flush() if chunk or self.size > 0: @@ -667,10 +734,10 @@ class DeflateBuffer: self.out.feed_eof() - def begin_http_chunk_receiving(self): + def begin_http_chunk_receiving(self) -> None: self.out.begin_http_chunk_receiving() - def end_http_chunk_receiving(self): + def end_http_chunk_receiving(self) -> None: self.out.end_http_chunk_receiving() @@ -680,7 +747,7 @@ RawRequestMessagePy = RawRequestMessage RawResponseMessagePy = RawResponseMessage try: - if not NO_EXTENSIONS: # pragma: no cover + if not NO_EXTENSIONS: from ._http_parser import (HttpRequestParser, # type: ignore # noqa HttpResponseParser, RawRequestMessage, diff --git a/aiohttp/http_websocket.py b/aiohttp/http_websocket.py index dd32b12..0be22cb 100644 --- a/aiohttp/http_websocket.py +++ b/aiohttp/http_websocket.py @@ -1,5 +1,6 @@ """WebSocket protocol versions 13 and 8.""" +import asyncio import collections import json import random @@ -8,9 +9,12 @@ import sys import zlib from enum import IntEnum from struct import Struct +from typing import Any, Callable, List, Optional, Tuple, Union +from .base_protocol import BaseProtocol from .helpers import NO_EXTENSIONS from .log import ws_logger +from .streams import DataQueue __all__ = ('WS_CLOSED_MESSAGE', 'WS_CLOSING_MESSAGE', 'WS_KEY', @@ -79,7 +83,8 @@ _WSMessageBase = collections.namedtuple('_WSMessageBase', class WSMessage(_WSMessageBase): - def json(self, *, loads=json.loads): + def json(self, *, # type: ignore + loads: Callable[[Any], Any]=json.loads) -> None: """Return parsed JSON data. .. versionadded:: 0.22 @@ -94,7 +99,7 @@ WS_CLOSING_MESSAGE = WSMessage(WSMsgType.CLOSING, None, None) class WebSocketError(Exception): """WebSocket protocol parser error.""" - def __init__(self, code, message): + def __init__(self, code: int, message: str) -> None: self.code = code super().__init__(message) @@ -110,7 +115,7 @@ native_byteorder = sys.byteorder _XOR_TABLE = [bytes(a ^ b for a in range(256)) for b in range(256)] -def _websocket_mask_python(mask, data): +def _websocket_mask_python(mask: bytes, data: bytearray) -> None: """Websocket masking function. `mask` is a `bytes` object of length 4; `data` is a `bytearray` @@ -134,7 +139,7 @@ def _websocket_mask_python(mask, data): data[3::4] = data[3::4].translate(d) -if NO_EXTENSIONS: +if NO_EXTENSIONS: # pragma: no cover _websocket_mask = _websocket_mask_python else: try: @@ -155,7 +160,7 @@ _WS_EXT_RE = re.compile(r'^(?:;\s*(?:' _WS_EXT_RE_SPLIT = re.compile(r'permessage-deflate([^,]+)?') -def ws_ext_parse(extstr, isserver=False): +def ws_ext_parse(extstr: str, isserver: bool=False) -> Tuple[int, bool]: if not extstr: return 0, False @@ -207,8 +212,8 @@ def ws_ext_parse(extstr, isserver=False): return compress, notakeover -def ws_ext_gen(compress=15, isserver=False, - server_notakeover=False): +def ws_ext_gen(compress: int=15, isserver: bool=False, + server_notakeover: bool=False) -> str: # client_notakeover=False not used for server # compress wbit 8 does not support in zlib if compress < 9 or compress > 15: @@ -236,32 +241,33 @@ class WSParserState(IntEnum): class WebSocketReader: - def __init__(self, queue, max_msg_size, compress=True): + def __init__(self, queue: DataQueue[WSMessage], + max_msg_size: int, compress: bool=True) -> None: self.queue = queue self._max_msg_size = max_msg_size - self._exc = None + self._exc = None # type: Optional[BaseException] self._partial = bytearray() self._state = WSParserState.READ_HEADER - self._opcode = None + self._opcode = None # type: Optional[int] self._frame_fin = False - self._frame_opcode = None + self._frame_opcode = None # type: Optional[int] self._frame_payload = bytearray() self._tail = b'' self._has_mask = False - self._frame_mask = None + self._frame_mask = None # type: Optional[bytes] self._payload_length = 0 self._payload_length_flag = 0 - self._compressed = None - self._decompressobj = None + self._compressed = None # type: Optional[bool] + self._decompressobj = None # type: Any # zlib.decompressobj actually self._compress = compress - def feed_eof(self): + def feed_eof(self) -> None: self.queue.feed_eof() - def feed_data(self, data): + def feed_data(self, data: bytes) -> Tuple[bool, bytes]: if self._exc: return True, data @@ -272,7 +278,7 @@ class WebSocketReader: self.queue.set_exception(exc) return True, b'' - def _feed_data(self, data): + def _feed_data(self, data: bytes) -> Tuple[bool, bytes]: for fin, opcode, payload, compressed in self.parse_frame(data): if compressed and not self._decompressobj: self._decompressobj = zlib.decompressobj(wbits=-zlib.MAX_WBITS) @@ -338,6 +344,7 @@ class WebSocketReader: 'to be zero, got {!r}'.format(opcode)) if opcode == WSMsgType.CONTINUATION: + assert self._opcode is not None opcode = self._opcode self._opcode = None @@ -383,7 +390,9 @@ class WebSocketReader: return False, b'' - def parse_frame(self, buf): + def parse_frame(self, buf: bytes) -> List[Tuple[bool, Optional[int], + bytearray, + Optional[bool]]]: """Return the next frame from the socket.""" frames = [] if self._tail: @@ -447,9 +456,9 @@ class WebSocketReader: WSCloseCode.PROTOCOL_ERROR, 'Received frame with non-zero reserved bits') - self._frame_fin = fin + self._frame_fin = bool(fin) self._frame_opcode = opcode - self._has_mask = has_mask + self._has_mask = bool(has_mask) self._payload_length_flag = length self._state = WSParserState.READ_PAYLOAD_LENGTH else: @@ -514,6 +523,7 @@ class WebSocketReader: if self._payload_length == 0: if self._has_mask: + assert self._frame_mask is not None _websocket_mask(self._frame_mask, payload) frames.append(( @@ -534,9 +544,10 @@ class WebSocketReader: class WebSocketWriter: - def __init__(self, protocol, transport, *, - use_mask=False, limit=DEFAULT_LIMIT, random=random.Random(), - compress=0, notakeover=False): + def __init__(self, protocol: BaseProtocol, transport: asyncio.Transport, *, + use_mask: bool=False, limit: int=DEFAULT_LIMIT, + random: Any=random.Random(), + compress: int=0, notakeover: bool=False) -> None: self.protocol = protocol self.transport = transport self.use_mask = use_mask @@ -546,9 +557,10 @@ class WebSocketWriter: self._closing = False self._limit = limit self._output_size = 0 - self._compressobj = None + self._compressobj = None # type: Any # actually compressobj - async def _send_frame(self, message, opcode, compress=None): + async def _send_frame(self, message: bytes, opcode: int, + compress: Optional[int]=None) -> None: """Send a frame over the websocket with message as its payload.""" if self._closing: ws_logger.warning('websocket connection is closing.') @@ -608,33 +620,35 @@ class WebSocketWriter: self._output_size = 0 await self.protocol._drain_helper() - async def pong(self, message=b''): + async def pong(self, message: bytes=b'') -> None: """Send pong message.""" if isinstance(message, str): message = message.encode('utf-8') - return await self._send_frame(message, WSMsgType.PONG) + await self._send_frame(message, WSMsgType.PONG) - async def ping(self, message=b''): + async def ping(self, message: bytes=b'') -> None: """Send ping message.""" if isinstance(message, str): message = message.encode('utf-8') - return await self._send_frame(message, WSMsgType.PING) + await self._send_frame(message, WSMsgType.PING) - async def send(self, message, binary=False, compress=None): + async def send(self, message: Union[str, bytes], + binary: bool=False, + compress: Optional[int]=None) -> None: """Send a frame over the websocket with message as its payload.""" if isinstance(message, str): message = message.encode('utf-8') if binary: - return await self._send_frame(message, WSMsgType.BINARY, compress) + await self._send_frame(message, WSMsgType.BINARY, compress) else: - return await self._send_frame(message, WSMsgType.TEXT, compress) + await self._send_frame(message, WSMsgType.TEXT, compress) - async def close(self, code=1000, message=b''): + async def close(self, code: int=1000, message: bytes=b'') -> None: """Close the websocket, sending the specified code and message.""" if isinstance(message, str): message = message.encode('utf-8') try: - return await self._send_frame( + await self._send_frame( PACK_CLOSE_CODE(code) + message, opcode=WSMsgType.CLOSE) finally: self._closing = True diff --git a/aiohttp/http_writer.py b/aiohttp/http_writer.py index 53f8bd6..8c3a9e7 100644 --- a/aiohttp/http_writer.py +++ b/aiohttp/http_writer.py @@ -5,6 +5,8 @@ import collections import zlib from typing import Any, Awaitable, Callable, Optional, Union # noqa +from multidict import CIMultiDict # noqa + from .abc import AbstractStreamWriter from .base_protocol import BaseProtocol from .helpers import NO_EXTENSIONS @@ -17,8 +19,7 @@ HttpVersion10 = HttpVersion(1, 0) HttpVersion11 = HttpVersion(1, 1) -_T_Data = Union[bytes, bytearray, memoryview] -_T_OnChunkSent = Optional[Callable[[_T_Data], Awaitable[None]]] +_T_OnChunkSent = Optional[Callable[[bytes], Awaitable[None]]] class StreamWriter(AbstractStreamWriter): @@ -43,7 +44,7 @@ class StreamWriter(AbstractStreamWriter): self._on_chunk_sent = on_chunk_sent # type: _T_OnChunkSent @property - def transport(self) -> asyncio.Transport: + def transport(self) -> Optional[asyncio.Transport]: return self._transport @property @@ -58,7 +59,7 @@ class StreamWriter(AbstractStreamWriter): if encoding == 'gzip' else -zlib.MAX_WBITS) self._compress = zlib.compressobj(wbits=zlib_mode) - def _write(self, chunk) -> None: + def _write(self, chunk: bytes) -> None: size = len(chunk) self.buffer_size += size self.output_size += size @@ -67,7 +68,8 @@ class StreamWriter(AbstractStreamWriter): raise ConnectionResetError('Cannot write to closing transport') self._transport.write(chunk) - async def write(self, chunk, *, drain=True, LIMIT=0x10000) -> None: + async def write(self, chunk: bytes, + *, drain: bool=True, LIMIT: int=0x10000) -> None: """Writes chunk of data to a stream. write_eof() indicates end of stream. @@ -94,8 +96,8 @@ class StreamWriter(AbstractStreamWriter): if chunk: if self.chunked: - chunk_len = ('%x\r\n' % len(chunk)).encode('ascii') - chunk = chunk_len + chunk + b'\r\n' + chunk_len_pre = ('%x\r\n' % len(chunk)).encode('ascii') + chunk = chunk_len_pre + chunk + b'\r\n' self._write(chunk) @@ -103,13 +105,14 @@ class StreamWriter(AbstractStreamWriter): self.buffer_size = 0 await self.drain() - async def write_headers(self, status_line, headers) -> None: + async def write_headers(self, status_line: str, + headers: 'CIMultiDict[str]') -> None: """Write request/response status and headers.""" # status + headers buf = _serialize_headers(status_line, headers) self._write(buf) - async def write_eof(self, chunk=b'') -> None: + async def write_eof(self, chunk: bytes=b'') -> None: if self._eof: return @@ -152,10 +155,11 @@ class StreamWriter(AbstractStreamWriter): await self._protocol._drain_helper() -def _py_serialize_headers(status_line, headers): - headers = status_line + '\r\n' + ''.join( +def _py_serialize_headers(status_line: str, + headers: 'CIMultiDict[str]') -> bytes: + line = status_line + '\r\n' + ''.join( [k + ': ' + v + '\r\n' for k, v in headers.items()]) - return headers.encode('utf-8') + b'\r\n' + return line.encode('utf-8') + b'\r\n' _serialize_headers = _py_serialize_headers @@ -163,7 +167,7 @@ _serialize_headers = _py_serialize_headers try: import aiohttp._http_writer as _http_writer # type: ignore _c_serialize_headers = _http_writer._serialize_headers - if not NO_EXTENSIONS: # pragma: no cover + if not NO_EXTENSIONS: _serialize_headers = _c_serialize_headers except ImportError: pass diff --git a/aiohttp/locks.py b/aiohttp/locks.py index e57ec2e..9532996 100644 --- a/aiohttp/locks.py +++ b/aiohttp/locks.py @@ -1,5 +1,12 @@ import asyncio import collections +from typing import Any, Optional + + +try: + from typing import Deque +except ImportError: + from typing_extensions import Deque # noqa class EventResultOrError: @@ -9,17 +16,17 @@ class EventResultOrError: thanks to @vorpalsmith for the simple design. """ - def __init__(self, loop): + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: self._loop = loop - self._exc = None + self._exc = None # type: Optional[BaseException] self._event = asyncio.Event(loop=loop) - self._waiters = collections.deque() + self._waiters = collections.deque() # type: Deque[asyncio.Future[Any]] - def set(self, exc=None): + def set(self, exc: Optional[BaseException]=None) -> None: self._exc = exc self._event.set() - async def wait(self): + async def wait(self) -> Any: waiter = self._loop.create_task(self._event.wait()) self._waiters.append(waiter) try: @@ -32,7 +39,7 @@ class EventResultOrError: return val - def cancel(self): + def cancel(self) -> None: """ Cancel all waiters """ for waiter in self._waiters: waiter.cancel() diff --git a/aiohttp/multipart.py b/aiohttp/multipart.py index 0e46ea4..c187a1c 100644 --- a/aiohttp/multipart.py +++ b/aiohttp/multipart.py @@ -5,17 +5,21 @@ import re import uuid import warnings import zlib -from collections import Mapping, Sequence, deque +from collections import deque +from types import TracebackType +from typing import (TYPE_CHECKING, Any, Dict, Iterator, List, Mapping, # noqa + Optional, Sequence, Tuple, Type, Union, cast) from urllib.parse import parse_qsl, unquote, urlencode -from multidict import CIMultiDict +from multidict import CIMultiDict, CIMultiDictProxy, MultiMapping # noqa from .hdrs import (CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_TRANSFER_ENCODING, CONTENT_TYPE) from .helpers import CHAR, TOKEN, parse_mimetype, reify -from .http import HttpParser +from .http import HeadersParser from .payload import (JsonPayload, LookupError, Order, Payload, StringPayload, get_payload, payload_type) +from .streams import StreamReader __all__ = ('MultipartReader', 'MultipartWriter', 'BodyPartReader', @@ -23,6 +27,10 @@ __all__ = ('MultipartReader', 'MultipartWriter', 'BodyPartReader', 'parse_content_disposition', 'content_disposition_filename') +if TYPE_CHECKING: # pragma: no cover + from .client_reqrep import ClientResponse # noqa + + class BadContentDispositionHeader(RuntimeWarning): pass @@ -31,28 +39,30 @@ class BadContentDispositionParam(RuntimeWarning): pass -def parse_content_disposition(header): +def parse_content_disposition(header: Optional[str]) -> Tuple[Optional[str], + Dict[str, str]]: - def is_token(string): - return string and TOKEN >= set(string) + def is_token(string: str) -> bool: + return bool(string) and TOKEN >= set(string) - def is_quoted(string): + def is_quoted(string: str) -> bool: return string[0] == string[-1] == '"' - def is_rfc5987(string): + def is_rfc5987(string: str) -> bool: return is_token(string) and string.count("'") == 2 - def is_extended_param(string): + def is_extended_param(string: str) -> bool: return string.endswith('*') - def is_continuous_param(string): + def is_continuous_param(string: str) -> bool: pos = string.find('*') + 1 if not pos: return False substring = string[pos:-1] if string.endswith('*') else string[pos:] return substring.isdigit() - def unescape(text, *, chars=''.join(map(re.escape, CHAR))): + def unescape(text: str, *, + chars: str=''.join(map(re.escape, CHAR))) -> str: return re.sub('\\\\([{}])'.format(chars), '\\1', text) if not header: @@ -63,7 +73,7 @@ def parse_content_disposition(header): warnings.warn(BadContentDispositionHeader(header)) return None, {} - params = {} + params = {} # type: Dict[str, str] while parts: item = parts.pop(0) @@ -129,7 +139,8 @@ def parse_content_disposition(header): return disptype.lower(), params -def content_disposition_filename(params, name='filename'): +def content_disposition_filename(params: Mapping[str, str], + name: str='filename') -> Optional[str]: name_suf = '%s*' % name if not params: return None @@ -167,31 +178,32 @@ class MultipartResponseWrapper: underlying connection and close it when it needs in. """ - def __init__(self, resp, stream): + def __init__(self, resp: 'ClientResponse', stream: Any) -> None: + # TODO: add strong annotation to stream self.resp = resp self.stream = stream - def __aiter__(self): + def __aiter__(self) -> 'MultipartResponseWrapper': return self - async def __anext__(self): + async def __anext__(self) -> Any: part = await self.next() if part is None: raise StopAsyncIteration # NOQA return part - def at_eof(self): + def at_eof(self) -> bool: """Returns True when all response data had been read.""" return self.resp.content.at_eof() - async def next(self): + async def next(self) -> Any: """Emits next multipart reader object.""" item = await self.stream.next() if self.stream.at_eof(): await self.release() return item - async def release(self): + async def release(self) -> None: """Releases the connection gracefully, reading all the content to the void.""" await self.resp.release() @@ -202,7 +214,9 @@ class BodyPartReader: chunk_size = 8192 - def __init__(self, boundary, headers, content): + def __init__(self, boundary: bytes, + headers: Mapping[str, Optional[str]], + content: StreamReader) -> None: self.headers = headers self._boundary = boundary self._content = content @@ -210,27 +224,28 @@ class BodyPartReader: length = self.headers.get(CONTENT_LENGTH, None) self._length = int(length) if length is not None else None self._read_bytes = 0 - self._unread = deque() - self._prev_chunk = None + # TODO: typeing.Deque is not supported by Python 3.5 + self._unread = deque() # type: Any + self._prev_chunk = None # type: Optional[bytes] self._content_eof = 0 - self._cache = {} + self._cache = {} # type: Dict[str, Any] - def __aiter__(self): + def __aiter__(self) -> 'BodyPartReader': return self - async def __anext__(self): + async def __anext__(self) -> Any: part = await self.next() if part is None: raise StopAsyncIteration # NOQA return part - async def next(self): + async def next(self) -> Any: item = await self.read() if not item: return None return item - async def read(self, *, decode=False): + async def read(self, *, decode: bool=False) -> Any: """Reads body part data. decode: Decodes data following by encoding @@ -246,7 +261,7 @@ class BodyPartReader: return self.decode(data) return data - async def read_chunk(self, size=chunk_size): + async def read_chunk(self, size: int=chunk_size) -> bytes: """Reads body part content chunk of the specified size. size: chunk size @@ -267,7 +282,7 @@ class BodyPartReader: 'reader did not read all the data or it is malformed' return chunk - async def _read_chunk_from_length(self, size): + async def _read_chunk_from_length(self, size: int) -> bytes: # Reads body part content chunk of the specified size. # The body part must has Content-Length header with proper value. assert self._length is not None, \ @@ -276,7 +291,7 @@ class BodyPartReader: chunk = await self._content.read(chunk_size) return chunk - async def _read_chunk_from_stream(self, size): + async def _read_chunk_from_stream(self, size: int) -> bytes: # Reads content chunk of body part with unknown length. # The Content-Length header for body part is not necessary. assert size >= len(self._boundary) + 2, \ @@ -288,6 +303,7 @@ class BodyPartReader: chunk = await self._content.read(size) self._content_eof += int(self._content.at_eof()) assert self._content_eof < 3, "Reading after EOF" + assert self._prev_chunk is not None window = self._prev_chunk + chunk sub = b'\r\n' + self._boundary if first_chunk: @@ -296,7 +312,10 @@ class BodyPartReader: idx = window.find(sub, max(0, len(self._prev_chunk) - len(sub))) if idx >= 0: # pushing boundary back to content - self._content.unread_data(window[idx:]) + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", + category=DeprecationWarning) + self._content.unread_data(window[idx:]) if size > idx: self._prev_chunk = self._prev_chunk[:idx] chunk = window[len(self._prev_chunk):idx] @@ -306,7 +325,7 @@ class BodyPartReader: self._prev_chunk = chunk return result - async def readline(self): + async def readline(self) -> bytes: """Reads body part by line by line.""" if self._at_eof: return b'' @@ -335,14 +354,14 @@ class BodyPartReader: return line - async def release(self): + async def release(self) -> None: """Like read(), but reads all the data to the void.""" if self._at_eof: return while not self._at_eof: await self.read_chunk(self.chunk_size) - async def text(self, *, encoding=None): + async def text(self, *, encoding: Optional[str]=None) -> str: """Like read(), but assumes that body part contains text data.""" data = await self.read(decode=True) # see https://www.w3.org/TR/html5/forms.html#multipart/form-data-encoding-algorithm # NOQA @@ -350,7 +369,7 @@ class BodyPartReader: encoding = encoding or self.get_charset(default='utf-8') return data.decode(encoding) - async def json(self, *, encoding=None): + async def json(self, *, encoding: Optional[str]=None) -> Any: """Like read(), but assumes that body parts contains JSON data.""" data = await self.read(decode=True) if not data: @@ -358,23 +377,27 @@ class BodyPartReader: encoding = encoding or self.get_charset(default='utf-8') return json.loads(data.decode(encoding)) - async def form(self, *, encoding=None): + async def form(self, *, + encoding: Optional[str]=None) -> List[Tuple[str, str]]: """Like read(), but assumes that body parts contains form urlencoded data. """ data = await self.read(decode=True) if not data: - return None - encoding = encoding or self.get_charset(default='utf-8') - return parse_qsl(data.rstrip().decode(encoding), + return [] + if encoding is not None: + real_encoding = encoding + else: + real_encoding = self.get_charset(default='utf-8') + return parse_qsl(data.rstrip().decode(real_encoding), keep_blank_values=True, - encoding=encoding) + encoding=real_encoding) - def at_eof(self): + def at_eof(self) -> bool: """Returns True if the boundary was reached or False otherwise.""" return self._at_eof - def decode(self, data): + def decode(self, data: bytes) -> bytes: """Decodes data according the specified Content-Encoding or Content-Transfer-Encoding headers value. """ @@ -384,8 +407,8 @@ class BodyPartReader: return self._decode_content(data) return data - def _decode_content(self, data): - encoding = self.headers[CONTENT_ENCODING].lower() + def _decode_content(self, data: bytes) -> bytes: + encoding = cast(str, self.headers[CONTENT_ENCODING]).lower() if encoding == 'deflate': return zlib.decompress(data, -zlib.MAX_WBITS) @@ -396,8 +419,8 @@ class BodyPartReader: else: raise RuntimeError('unknown content encoding: {}'.format(encoding)) - def _decode_content_transfer(self, data): - encoding = self.headers[CONTENT_TRANSFER_ENCODING].lower() + def _decode_content_transfer(self, data: bytes) -> bytes: + encoding = cast(str, self.headers[CONTENT_TRANSFER_ENCODING]).lower() if encoding == 'base64': return base64.b64decode(data) @@ -409,23 +432,24 @@ class BodyPartReader: raise RuntimeError('unknown content transfer encoding: {}' ''.format(encoding)) - def get_charset(self, default=None): + def get_charset(self, default: str) -> str: """Returns charset parameter from Content-Type header or default.""" ctype = self.headers.get(CONTENT_TYPE, '') mimetype = parse_mimetype(ctype) return mimetype.parameters.get('charset', default) @reify - def name(self): + def name(self) -> Optional[str]: """Returns name specified in Content-Disposition header or None if missed or header is malformed. """ + _, params = parse_content_disposition( self.headers.get(CONTENT_DISPOSITION)) return content_disposition_filename(params, 'name') @reify - def filename(self): + def filename(self) -> Optional[str]: """Returns filename specified in Content-Disposition header or None if missed or header is malformed. """ @@ -437,19 +461,20 @@ class BodyPartReader: @payload_type(BodyPartReader, order=Order.try_first) class BodyPartReaderPayload(Payload): - def __init__(self, value, *args, **kwargs): + def __init__(self, value: BodyPartReader, + *args: Any, **kwargs: Any) -> None: super().__init__(value, *args, **kwargs) - params = {} + params = {} # type: Dict[str, str] if value.name is not None: params['name'] = value.name if value.filename is not None: params['filename'] = value.filename if params: - self.set_content_disposition('attachment', **params) + self.set_content_disposition('attachment', True, **params) - async def write(self, writer): + async def write(self, writer: Any) -> None: field = self._value chunk = await field.read_chunk(size=2**16) while chunk: @@ -468,26 +493,27 @@ class MultipartReader: #: Body part reader class for non multipart/* content types. part_reader_cls = BodyPartReader - def __init__(self, headers, content): + def __init__(self, headers: Mapping[str, str], + content: StreamReader) -> None: self.headers = headers self._boundary = ('--' + self._get_boundary()).encode() self._content = content self._last_part = None self._at_eof = False self._at_bof = True - self._unread = [] + self._unread = [] # type: List[bytes] - def __aiter__(self): + def __aiter__(self) -> 'MultipartReader': return self - async def __anext__(self): + async def __anext__(self) -> Any: part = await self.next() if part is None: raise StopAsyncIteration # NOQA return part @classmethod - def from_response(cls, response): + def from_response(cls, response: 'ClientResponse') -> Any: """Constructs reader instance from HTTP response. :param response: :class:`~aiohttp.client.ClientResponse` instance @@ -496,13 +522,13 @@ class MultipartReader: response.content)) return obj - def at_eof(self): + def at_eof(self) -> bool: """Returns True if the final boundary was reached or False otherwise. """ return self._at_eof - async def next(self): + async def next(self) -> Any: """Emits the next multipart body part.""" # So, if we're at BOF, we need to skip till the boundary. if self._at_eof: @@ -518,7 +544,7 @@ class MultipartReader: self._last_part = await self.fetch_next_part() return self._last_part - async def release(self): + async def release(self) -> None: """Reads all the body parts to the void till the final boundary.""" while not self._at_eof: item = await self.next() @@ -526,12 +552,12 @@ class MultipartReader: break await item.release() - async def fetch_next_part(self): + async def fetch_next_part(self) -> Any: """Returns the next body part reader.""" headers = await self._read_headers() return self._get_part_reader(headers) - def _get_part_reader(self, headers): + def _get_part_reader(self, headers: 'CIMultiDictProxy[str]') -> Any: """Dispatches the response by the `Content-Type` header, returning suitable reader instance. @@ -547,7 +573,7 @@ class MultipartReader: else: return self.part_reader_cls(self._boundary, headers, self._content) - def _get_boundary(self): + def _get_boundary(self) -> str: mimetype = parse_mimetype(self.headers[CONTENT_TYPE]) assert mimetype.type == 'multipart', ( @@ -565,12 +591,12 @@ class MultipartReader: return boundary - async def _readline(self): + async def _readline(self) -> bytes: if self._unread: return self._unread.pop() return await self._content.readline() - async def _read_until_first_boundary(self): + async def _read_until_first_boundary(self) -> None: while True: chunk = await self._readline() if chunk == b'': @@ -583,7 +609,7 @@ class MultipartReader: self._at_eof = True return - async def _read_boundary(self): + async def _read_boundary(self) -> None: chunk = (await self._readline()).rstrip() if chunk == self._boundary: pass @@ -607,7 +633,7 @@ class MultipartReader: raise ValueError('Invalid boundary %r, expected %r' % (chunk, self._boundary)) - async def _read_headers(self): + async def _read_headers(self) -> 'CIMultiDictProxy[str]': lines = [b''] while True: chunk = await self._content.readline() @@ -615,11 +641,11 @@ class MultipartReader: lines.append(chunk) if not chunk: break - parser = HttpParser() - headers, *_ = parser.parse_headers(lines) + parser = HeadersParser() + headers, raw_headers = parser.parse_headers(lines) return headers - async def _maybe_release_last_part(self): + async def _maybe_release_last_part(self) -> None: """Ensures that the last read body part is read completely.""" if self._last_part is not None: if not self._last_part.at_eof(): @@ -628,10 +654,14 @@ class MultipartReader: self._last_part = None +_Part = Tuple[Payload, 'MultiMapping[str]', str, str] + + class MultipartWriter(Payload): """Multipart body writer.""" - def __init__(self, subtype='mixed', boundary=None): + def __init__(self, subtype: str='mixed', + boundary: Optional[str]=None) -> None: boundary = boundary if boundary is not None else uuid.uuid4().hex # The underlying Payload API demands a str (utf-8), not bytes, # so we need to ensure we don't lose anything during conversion. @@ -648,27 +678,31 @@ class MultipartWriter(Payload): super().__init__(None, content_type=ctype) - self._parts = [] - self._headers = CIMultiDict() + self._parts = [] # type: List[_Part] # noqa + self._headers = CIMultiDict() # type: CIMultiDict[str] + assert self.content_type is not None self._headers[CONTENT_TYPE] = self.content_type - def __enter__(self): + def __enter__(self) -> 'MultipartWriter': return self - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__(self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> None: pass - def __iter__(self): + def __iter__(self) -> Iterator[_Part]: return iter(self._parts) - def __len__(self): + def __len__(self) -> int: return len(self._parts) _valid_tchar_regex = re.compile(br"\A[!#$%&'*+\-.^_`|~\w]+\Z") _invalid_qdtext_char_regex = re.compile(br"[\x00-\x08\x0A-\x1F\x7F]") @property - def _boundary_value(self): + def _boundary_value(self) -> str: """Wrap boundary parameter value in quotes, if necessary. Reads self.boundary and returns a unicode sting. @@ -700,10 +734,14 @@ class MultipartWriter(Payload): return '"' + quoted_value_content.decode('ascii') + '"' @property - def boundary(self): + def boundary(self) -> str: return self._boundary.decode('ascii') - def append(self, obj, headers=None): + def append( + self, + obj: Any, + headers: Optional['MultiMapping[str]']=None + ) -> Payload: if headers is None: headers = CIMultiDict() @@ -711,7 +749,10 @@ class MultipartWriter(Payload): if obj.headers is not None: obj.headers.update(headers) else: - obj._headers = headers + if isinstance(headers, CIMultiDict): + obj._headers = headers + else: + obj._headers = CIMultiDict(headers) return self.append_payload(obj) else: try: @@ -719,14 +760,16 @@ class MultipartWriter(Payload): except LookupError: raise TypeError - def append_payload(self, payload): + def append_payload(self, payload: Payload) -> Payload: """Adds a new body part to multipart writer.""" # content-type + assert payload.headers is not None if CONTENT_TYPE not in payload.headers: + assert payload.content_type is not None payload.headers[CONTENT_TYPE] = payload.content_type # compression - encoding = payload.headers.get(CONTENT_ENCODING, '').lower() + encoding = payload.headers.get(CONTENT_ENCODING, '').lower() # type: Optional[str] # noqa if encoding and encoding not in ('deflate', 'gzip', 'identity'): raise RuntimeError('unknown content encoding: {}'.format(encoding)) if encoding == 'identity': @@ -734,7 +777,7 @@ class MultipartWriter(Payload): # te encoding te_encoding = payload.headers.get( - CONTENT_TRANSFER_ENCODING, '').lower() + CONTENT_TRANSFER_ENCODING, '').lower() # type: Optional[str] # noqa if te_encoding not in ('', 'base64', 'quoted-printable', 'binary'): raise RuntimeError('unknown content transfer encoding: {}' ''.format(te_encoding)) @@ -751,17 +794,26 @@ class MultipartWriter(Payload): [k + ': ' + v + '\r\n' for k, v in payload.headers.items()] ).encode('utf-8') + b'\r\n' - self._parts.append((payload, headers, encoding, te_encoding)) + self._parts.append((payload, headers, encoding, te_encoding)) # type: ignore # noqa return payload - def append_json(self, obj, headers=None): + def append_json( + self, + obj: Any, + headers: Optional['MultiMapping[str]']=None + ) -> Payload: """Helper to append JSON part.""" if headers is None: headers = CIMultiDict() return self.append_payload(JsonPayload(obj, headers=headers)) - def append_form(self, obj, headers=None): + def append_form( + self, + obj: Union[Sequence[Tuple[str, str]], + Mapping[str, str]], + headers: Optional['MultiMapping[str]']=None + ) -> Payload: """Helper to append form urlencoded part.""" assert isinstance(obj, (Sequence, Mapping)) @@ -777,7 +829,7 @@ class MultipartWriter(Payload): content_type='application/x-www-form-urlencoded')) @property - def size(self): + def size(self) -> Optional[int]: """Size of the payload.""" if not self._parts: return 0 @@ -787,7 +839,7 @@ class MultipartWriter(Payload): if encoding or te_encoding or part.size is None: return None - total += ( + total += int( 2 + len(self._boundary) + 2 + # b'--'+self._boundary+b'\r\n' part.size + len(headers) + 2 # b'\r\n' @@ -796,7 +848,8 @@ class MultipartWriter(Payload): total += 2 + len(self._boundary) + 4 # b'--'+self._boundary+b'--\r\n' return total - async def write(self, writer, close_boundary=True): + async def write(self, writer: Any, + close_boundary: bool=True) -> None: """Write body.""" if not self._parts: return @@ -811,7 +864,7 @@ class MultipartWriter(Payload): w.enable_compression(encoding) if te_encoding: w.enable_encoding(te_encoding) - await part.write(w) + await part.write(w) # type: ignore await w.write_eof() else: await part.write(writer) @@ -824,24 +877,25 @@ class MultipartWriter(Payload): class MultipartPayloadWriter: - def __init__(self, writer): + def __init__(self, writer: Any) -> None: self._writer = writer - self._encoding = None - self._compress = None + self._encoding = None # type: Optional[str] + self._compress = None # type: Any + self._encoding_buffer = None # type: Optional[bytearray] - def enable_encoding(self, encoding): + def enable_encoding(self, encoding: str) -> None: if encoding == 'base64': self._encoding = encoding self._encoding_buffer = bytearray() elif encoding == 'quoted-printable': self._encoding = 'quoted-printable' - def enable_compression(self, encoding='deflate'): + def enable_compression(self, encoding: str='deflate') -> None: zlib_mode = (16 + zlib.MAX_WBITS if encoding == 'gzip' else -zlib.MAX_WBITS) self._compress = zlib.compressobj(wbits=zlib_mode) - async def write_eof(self): + async def write_eof(self) -> None: if self._compress is not None: chunk = self._compress.flush() if chunk: @@ -853,7 +907,7 @@ class MultipartPayloadWriter: await self._writer.write(base64.b64encode( self._encoding_buffer)) - async def write(self, chunk): + async def write(self, chunk: bytes) -> None: if self._compress is not None: if chunk: chunk = self._compress.compress(chunk) @@ -861,16 +915,17 @@ class MultipartPayloadWriter: return if self._encoding == 'base64': - self._encoding_buffer.extend(chunk) + buf = self._encoding_buffer + assert buf is not None + buf.extend(chunk) - if self._encoding_buffer: - buffer = self._encoding_buffer - div, mod = divmod(len(buffer), 3) + if buf: + div, mod = divmod(len(buf), 3) enc_chunk, self._encoding_buffer = ( - buffer[:div * 3], buffer[div * 3:]) + buf[:div * 3], buf[div * 3:]) if enc_chunk: - enc_chunk = base64.b64encode(enc_chunk) - await self._writer.write(enc_chunk) + b64chunk = base64.b64encode(enc_chunk) + await self._writer.write(b64chunk) elif self._encoding == 'quoted-printable': await self._writer.write(binascii.b2a_qp(chunk)) else: diff --git a/aiohttp/payload.py b/aiohttp/payload.py index 1b7ea6a..e69638b 100644 --- a/aiohttp/payload.py +++ b/aiohttp/payload.py @@ -5,15 +5,18 @@ import mimetypes import os import warnings from abc import ABC, abstractmethod -from collections.abc import AsyncIterable from itertools import chain +from typing import (IO, TYPE_CHECKING, Any, ByteString, Callable, Dict, # noqa + Iterable, List, Optional, Text, TextIO, Tuple, Type, Union) from multidict import CIMultiDict from . import hdrs +from .abc import AbstractStreamWriter from .helpers import (PY_36, content_disposition_header, guess_filename, parse_mimetype, sentinel) from .streams import DEFAULT_LIMIT, StreamReader +from .typedefs import JSONEncoder, _CIMultiDict __all__ = ('PAYLOAD_REGISTRY', 'get_payload', 'payload_type', 'Payload', @@ -29,27 +32,30 @@ class LookupError(Exception): pass -class Order(enum.Enum): +class Order(str, enum.Enum): normal = 'normal' try_first = 'try_first' try_last = 'try_last' -def get_payload(data, *args, **kwargs): +def get_payload(data: Any, *args: Any, **kwargs: Any) -> 'Payload': return PAYLOAD_REGISTRY.get(data, *args, **kwargs) -def register_payload(factory, type, *, order=Order.normal): +def register_payload(factory: Type['Payload'], + type: Any, + *, + order: Order=Order.normal) -> None: PAYLOAD_REGISTRY.register(factory, type, order=order) class payload_type: - def __init__(self, type, *, order=Order.normal): + def __init__(self, type: Any, *, order: Order=Order.normal) -> None: self.type = type self.order = order - def __call__(self, factory): + def __call__(self, factory: Type['Payload']) -> Type['Payload']: register_payload(factory, self.type, order=self.order) return factory @@ -60,12 +66,16 @@ class PayloadRegistry: note: we need zope.interface for more efficient adapter search """ - def __init__(self): - self._first = [] - self._normal = [] - self._last = [] + def __init__(self) -> None: + self._first = [] # type: List[Tuple[Type[Payload], Any]] + self._normal = [] # type: List[Tuple[Type[Payload], Any]] + self._last = [] # type: List[Tuple[Type[Payload], Any]] - def get(self, data, *args, _CHAIN=chain, **kwargs): + def get(self, + data: Any, + *args: Any, + _CHAIN: Any=chain, + **kwargs: Any) -> 'Payload': if isinstance(data, Payload): return data for factory, type in _CHAIN(self._first, self._normal, self._last): @@ -74,7 +84,11 @@ class PayloadRegistry: raise LookupError() - def register(self, factory, type, *, order=Order.normal): + def register(self, + factory: Type['Payload'], + type: Any, + *, + order: Order=Order.normal) -> None: if order is Order.try_first: self._first.append((factory, type)) elif order is Order.normal: @@ -87,12 +101,23 @@ class PayloadRegistry: class Payload(ABC): - _size = None - _headers = None - _content_type = 'application/octet-stream' - - def __init__(self, value, *, headers=None, content_type=sentinel, - filename=None, encoding=None, **kwargs): + _size = None # type: Optional[float] + _headers = None # type: Optional[_CIMultiDict] + _content_type = 'application/octet-stream' # type: Optional[str] + + def __init__(self, + value: Any, + headers: Optional[ + Union[ + _CIMultiDict, + Dict[str, str], + Iterable[Tuple[str, str]] + ] + ] = None, + content_type: Optional[str]=sentinel, + filename: Optional[str]=None, + encoding: Optional[str]=None, + **kwargs: Any) -> None: self._value = value self._encoding = encoding self._filename = filename @@ -107,27 +132,27 @@ class Payload(ABC): self._content_type = content_type @property - def size(self): + def size(self) -> Optional[float]: """Size of the payload.""" return self._size @property - def filename(self): + def filename(self) -> Optional[str]: """Filename of the payload.""" return self._filename @property - def headers(self): + def headers(self) -> Optional[_CIMultiDict]: """Custom item headers""" return self._headers @property - def encoding(self): + def encoding(self) -> Optional[str]: """Payload encoding""" return self._encoding @property - def content_type(self): + def content_type(self) -> Optional[str]: """Content type""" if self._content_type is not None: return self._content_type @@ -137,7 +162,10 @@ class Payload(ABC): else: return Payload._content_type - def set_content_disposition(self, disptype, quote_fields=True, **params): + def set_content_disposition(self, + disptype: str, + quote_fields: bool=True, + **params: Any) -> None: """Sets ``Content-Disposition`` header.""" if self._headers is None: self._headers = CIMultiDict() @@ -146,7 +174,7 @@ class Payload(ABC): disptype, quote_fields=quote_fields, **params) @abstractmethod - async def write(self, writer): + async def write(self, writer: AbstractStreamWriter) -> None: """Write payload. writer is an AbstractStreamWriter instance: @@ -155,7 +183,10 @@ class Payload(ABC): class BytesPayload(Payload): - def __init__(self, value, *args, **kwargs): + def __init__(self, + value: ByteString, + *args: Any, + **kwargs: Any) -> None: if not isinstance(value, (bytes, bytearray, memoryview)): raise TypeError("value argument must be byte-ish, not (!r)" .format(type(value))) @@ -177,40 +208,56 @@ class BytesPayload(Payload): "io.BytesIO object instead", ResourceWarning, **kwargs) - async def write(self, writer): + async def write(self, writer: AbstractStreamWriter) -> None: await writer.write(self._value) class StringPayload(BytesPayload): - def __init__(self, value, *args, - encoding=None, content_type=None, **kwargs): + def __init__(self, + value: Text, + *args: Any, + encoding: Optional[str]=None, + content_type: Optional[str]=None, + **kwargs: Any) -> None: if encoding is None: if content_type is None: - encoding = 'utf-8' + real_encoding = 'utf-8' content_type = 'text/plain; charset=utf-8' else: mimetype = parse_mimetype(content_type) - encoding = mimetype.parameters.get('charset', 'utf-8') + real_encoding = mimetype.parameters.get('charset', 'utf-8') else: if content_type is None: content_type = 'text/plain; charset=%s' % encoding + real_encoding = encoding super().__init__( - value.encode(encoding), - encoding=encoding, content_type=content_type, *args, **kwargs) + value.encode(real_encoding), + encoding=real_encoding, + content_type=content_type, + *args, + **kwargs, + ) class StringIOPayload(StringPayload): - def __init__(self, value, *args, **kwargs): + def __init__(self, + value: IO[str], + *args: Any, + **kwargs: Any) -> None: super().__init__(value.read(), *args, **kwargs) class IOBasePayload(Payload): - def __init__(self, value, disposition='attachment', *args, **kwargs): + def __init__(self, + value: IO[Any], + disposition: str='attachment', + *args: Any, + **kwargs: Any) -> None: if 'filename' not in kwargs: kwargs['filename'] = guess_filename(value) @@ -219,7 +266,7 @@ class IOBasePayload(Payload): if self._filename is not None and disposition is not None: self.set_content_disposition(disposition, filename=self._filename) - async def write(self, writer): + async def write(self, writer: AbstractStreamWriter) -> None: try: chunk = self._value.read(DEFAULT_LIMIT) while chunk: @@ -231,8 +278,12 @@ class IOBasePayload(Payload): class TextIOPayload(IOBasePayload): - def __init__(self, value, *args, - encoding=None, content_type=None, **kwargs): + def __init__(self, + value: TextIO, + *args: Any, + encoding: Optional[str]=None, + content_type: Optional[str]=None, + **kwargs: Any) -> None: if encoding is None: if content_type is None: @@ -247,16 +298,20 @@ class TextIOPayload(IOBasePayload): super().__init__( value, - content_type=content_type, encoding=encoding, *args, **kwargs) + content_type=content_type, + encoding=encoding, + *args, + **kwargs, + ) @property - def size(self): + def size(self) -> Optional[float]: try: return os.fstat(self._value.fileno()).st_size - self._value.tell() except OSError: return None - async def write(self, writer): + async def write(self, writer: AbstractStreamWriter) -> None: try: chunk = self._value.read(DEFAULT_LIMIT) while chunk: @@ -269,7 +324,7 @@ class TextIOPayload(IOBasePayload): class BytesIOPayload(IOBasePayload): @property - def size(self): + def size(self) -> float: position = self._value.tell() end = self._value.seek(0, os.SEEK_END) self._value.seek(position) @@ -279,7 +334,7 @@ class BytesIOPayload(IOBasePayload): class BufferedReaderPayload(IOBasePayload): @property - def size(self): + def size(self) -> Optional[float]: try: return os.fstat(self._value.fileno()).st_size - self._value.tell() except OSError: @@ -290,18 +345,39 @@ class BufferedReaderPayload(IOBasePayload): class JsonPayload(BytesPayload): - def __init__(self, value, - encoding='utf-8', content_type='application/json', - dumps=json.dumps, *args, **kwargs): + def __init__(self, + value: Any, + encoding: str='utf-8', + content_type: str='application/json', + dumps: JSONEncoder=json.dumps, + *args: Any, + **kwargs: Any) -> None: super().__init__( dumps(value).encode(encoding), content_type=content_type, encoding=encoding, *args, **kwargs) +if TYPE_CHECKING: # pragma: no cover + from typing import AsyncIterator, AsyncIterable + + _AsyncIterator = AsyncIterator[bytes] + _AsyncIterable = AsyncIterable[bytes] +else: + from collections.abc import AsyncIterable, AsyncIterator + + _AsyncIterator = AsyncIterator + _AsyncIterable = AsyncIterable + + class AsyncIterablePayload(Payload): - def __init__(self, value, *args, **kwargs): + _iter = None # type: Optional[_AsyncIterator] + + def __init__(self, + value: _AsyncIterable, + *args: Any, + **kwargs: Any) -> None: if not isinstance(value, AsyncIterable): raise TypeError("value argument must support " "collections.abc.AsyncIterablebe interface, " @@ -314,20 +390,21 @@ class AsyncIterablePayload(Payload): self._iter = value.__aiter__() - async def write(self, writer): - try: - # iter is not None check prevents rare cases - # when the case iterable is used twice - while True: - chunk = await self._iter.__anext__() - await writer.write(chunk) - except StopAsyncIteration: - self._iter = None + async def write(self, writer: AbstractStreamWriter) -> None: + if self._iter: + try: + # iter is not None check prevents rare cases + # when the case iterable is used twice + while True: + chunk = await self._iter.__anext__() + await writer.write(chunk) + except StopAsyncIteration: + self._iter = None class StreamReaderPayload(AsyncIterablePayload): - def __init__(self, value, *args, **kwargs): + def __init__(self, value: StreamReader, *args: Any, **kwargs: Any) -> None: super().__init__(value.iter_any(), *args, **kwargs) diff --git a/aiohttp/payload_streamer.py b/aiohttp/payload_streamer.py index c400aa0..606a719 100644 --- a/aiohttp/payload_streamer.py +++ b/aiohttp/payload_streamer.py @@ -23,7 +23,9 @@ Then you can use `file_sender` like this: import asyncio import warnings +from typing import Any, Awaitable, Callable, Dict, Tuple +from .abc import AbstractStreamWriter from .payload import Payload, payload_type @@ -32,39 +34,42 @@ __all__ = ('streamer',) class _stream_wrapper: - def __init__(self, coro, args, kwargs): + def __init__(self, + coro: Callable[..., Awaitable[None]], + args: Tuple[Any, ...], + kwargs: Dict[str, Any]) -> None: self.coro = asyncio.coroutine(coro) self.args = args self.kwargs = kwargs - async def __call__(self, writer): + async def __call__(self, writer: AbstractStreamWriter) -> None: await self.coro(writer, *self.args, **self.kwargs) class streamer: - def __init__(self, coro): + def __init__(self, coro: Callable[..., Awaitable[None]]) -> None: warnings.warn("@streamer is deprecated, use async generators instead", DeprecationWarning, stacklevel=2) self.coro = coro - def __call__(self, *args, **kwargs): + def __call__(self, *args: Any, **kwargs: Any) -> _stream_wrapper: return _stream_wrapper(self.coro, args, kwargs) @payload_type(_stream_wrapper) class StreamWrapperPayload(Payload): - async def write(self, writer): + async def write(self, writer: AbstractStreamWriter) -> None: await self._value(writer) @payload_type(streamer) class StreamPayload(StreamWrapperPayload): - def __init__(self, value, *args, **kwargs): + def __init__(self, value: Any, *args: Any, **kwargs: Any) -> None: super().__init__(value(), *args, **kwargs) - async def write(self, writer): + async def write(self, writer: AbstractStreamWriter) -> None: await self._value(writer) diff --git a/aiohttp/pytest_plugin.py b/aiohttp/pytest_plugin.py index 064a39f..a2ba2d1 100644 --- a/aiohttp/pytest_plugin.py +++ b/aiohttp/pytest_plugin.py @@ -24,7 +24,7 @@ except ImportError: # pragma: no cover tokio = None -def pytest_addoption(parser): +def pytest_addoption(parser): # type: ignore parser.addoption( '--aiohttp-fast', action='store_true', default=False, help='run tests faster by disabling extra checks') @@ -36,7 +36,7 @@ def pytest_addoption(parser): help='enable event loop debug mode') -def pytest_fixture_setup(fixturedef): +def pytest_fixture_setup(fixturedef): # type: ignore """ Allow fixtures to be coroutines. Run coroutine fixtures in an event loop. """ @@ -57,7 +57,7 @@ def pytest_fixture_setup(fixturedef): fixturedef.argnames += ('request',) strip_request = True - def wrapper(*args, **kwargs): + def wrapper(*args, **kwargs): # type: ignore request = kwargs['request'] if strip_request: del kwargs['request'] @@ -78,7 +78,7 @@ def pytest_fixture_setup(fixturedef): # then advance it again in a finalizer gen = func(*args, **kwargs) - def finalizer(): + def finalizer(): # type: ignore try: return _loop.run_until_complete(gen.__anext__()) except StopAsyncIteration: # NOQA @@ -93,19 +93,19 @@ def pytest_fixture_setup(fixturedef): @pytest.fixture -def fast(request): +def fast(request): # type: ignore """--fast config option""" return request.config.getoption('--aiohttp-fast') @pytest.fixture -def loop_debug(request): +def loop_debug(request): # type: ignore """--enable-loop-debug config option""" return request.config.getoption('--aiohttp-enable-loop-debug') @contextlib.contextmanager -def _runtime_warning_context(): +def _runtime_warning_context(): # type: ignore """ Context manager which checks for RuntimeWarnings, specifically to avoid "coroutine 'X' was never awaited" warnings being missed. @@ -115,7 +115,8 @@ def _runtime_warning_context(): with warnings.catch_warnings(record=True) as _warnings: yield rw = ['{w.filename}:{w.lineno}:{w.message}'.format(w=w) - for w in _warnings if w.category == RuntimeWarning] + for w in _warnings # type: ignore + if w.category == RuntimeWarning] if rw: raise RuntimeError('{} Runtime Warning{},\n{}'.format( len(rw), @@ -125,7 +126,7 @@ def _runtime_warning_context(): @contextlib.contextmanager -def _passthrough_loop_context(loop, fast=False): +def _passthrough_loop_context(loop, fast=False): # type: ignore """ setups and tears down a loop unless one is passed in via the loop argument when it's passed straight through. @@ -140,7 +141,7 @@ def _passthrough_loop_context(loop, fast=False): teardown_test_loop(loop, fast=fast) -def pytest_pycollect_makeitem(collector, name, obj): +def pytest_pycollect_makeitem(collector, name, obj): # type: ignore """ Fix pytest collecting for coroutines. """ @@ -148,7 +149,7 @@ def pytest_pycollect_makeitem(collector, name, obj): return list(collector._genfunctions(name, obj)) -def pytest_pyfunc_call(pyfuncitem): +def pytest_pyfunc_call(pyfuncitem): # type: ignore """ Run coroutines in an event loop instead of a normal function call. """ @@ -164,7 +165,7 @@ def pytest_pyfunc_call(pyfuncitem): return True -def pytest_generate_tests(metafunc): +def pytest_generate_tests(metafunc): # type: ignore if 'loop_factory' not in metafunc.fixturenames: return @@ -180,7 +181,7 @@ def pytest_generate_tests(metafunc): if loops == 'all': loops = 'pyloop,uvloop?,tokio?' - factories = {} + factories = {} # type: ignore for name in loops.split(','): required = not name.endswith('?') name = name.strip(' ?') @@ -198,7 +199,7 @@ def pytest_generate_tests(metafunc): @pytest.fixture -def loop(loop_factory, fast, loop_debug): +def loop(loop_factory, fast, loop_debug): # type: ignore """Return an instance of the event loop.""" policy = loop_factory() asyncio.set_event_loop_policy(policy) @@ -210,27 +211,27 @@ def loop(loop_factory, fast, loop_debug): @pytest.fixture -def unused_port(aiohttp_unused_port): # pragma: no cover +def unused_port(aiohttp_unused_port): # type: ignore # pragma: no cover warnings.warn("Deprecated, use aiohttp_unused_port fixture instead", DeprecationWarning) return aiohttp_unused_port @pytest.fixture -def aiohttp_unused_port(): +def aiohttp_unused_port(): # type: ignore """Return a port that is unused on the current host.""" return _unused_port @pytest.fixture -def aiohttp_server(loop): +def aiohttp_server(loop): # type: ignore """Factory to create a TestServer instance, given an app. aiohttp_server(app, **kwargs) """ servers = [] - async def go(app, *, port=None, **kwargs): + async def go(app, *, port=None, **kwargs): # type: ignore server = TestServer(app, port=port) await server.start_server(loop=loop, **kwargs) servers.append(server) @@ -238,7 +239,7 @@ def aiohttp_server(loop): yield go - async def finalize(): + async def finalize(): # type: ignore while servers: await servers.pop().close() @@ -246,21 +247,21 @@ def aiohttp_server(loop): @pytest.fixture -def test_server(aiohttp_server): # pragma: no cover +def test_server(aiohttp_server): # type: ignore # pragma: no cover warnings.warn("Deprecated, use aiohttp_server fixture instead", DeprecationWarning) return aiohttp_server @pytest.fixture -def aiohttp_raw_server(loop): +def aiohttp_raw_server(loop): # type: ignore """Factory to create a RawTestServer instance, given a web handler. aiohttp_raw_server(handler, **kwargs) """ servers = [] - async def go(handler, *, port=None, **kwargs): + async def go(handler, *, port=None, **kwargs): # type: ignore server = RawTestServer(handler, port=port) await server.start_server(loop=loop, **kwargs) servers.append(server) @@ -268,7 +269,7 @@ def aiohttp_raw_server(loop): yield go - async def finalize(): + async def finalize(): # type: ignore while servers: await servers.pop().close() @@ -276,14 +277,14 @@ def aiohttp_raw_server(loop): @pytest.fixture -def raw_test_server(aiohttp_raw_server): # pragma: no cover +def raw_test_server(aiohttp_raw_server): # type: ignore # pragma: no cover warnings.warn("Deprecated, use aiohttp_raw_server fixture instead", DeprecationWarning) return aiohttp_raw_server @pytest.fixture -def aiohttp_client(loop): +def aiohttp_client(loop): # type: ignore """Factory to create a TestClient instance. aiohttp_client(app, **kwargs) @@ -292,9 +293,9 @@ def aiohttp_client(loop): """ clients = [] - async def go(__param, *args, server_kwargs=None, **kwargs): + async def go(__param, *args, server_kwargs=None, **kwargs): # type: ignore - if (isinstance(__param, Callable) and + if (isinstance(__param, Callable) and # type: ignore not isinstance(__param, (Application, BaseTestServer))): __param = __param(loop, *args, **kwargs) kwargs = {} @@ -316,7 +317,7 @@ def aiohttp_client(loop): yield go - async def finalize(): + async def finalize(): # type: ignore while clients: await clients.pop().close() @@ -324,7 +325,7 @@ def aiohttp_client(loop): @pytest.fixture -def test_client(aiohttp_client): # pragma: no cover +def test_client(aiohttp_client): # type: ignore # pragma: no cover warnings.warn("Deprecated, use aiohttp_client fixture instead", DeprecationWarning) return aiohttp_client diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py index 5d3335f..db69f1c 100644 --- a/aiohttp/resolver.py +++ b/aiohttp/resolver.py @@ -1,7 +1,9 @@ import asyncio import socket +from typing import Any, Dict, List, Optional from .abc import AbstractResolver +from .helpers import get_running_loop __all__ = ('ThreadedResolver', 'AsyncResolver', 'DefaultResolver') @@ -20,12 +22,11 @@ class ThreadedResolver(AbstractResolver): concurrent.futures.ThreadPoolExecutor. """ - def __init__(self, loop=None): - if loop is None: - loop = asyncio.get_event_loop() - self._loop = loop + def __init__(self, loop: Optional[asyncio.AbstractEventLoop]=None) -> None: + self._loop = get_running_loop(loop) - async def resolve(self, host, port=0, family=socket.AF_INET): + async def resolve(self, host: str, port: int=0, + family: int=socket.AF_INET) -> List[Dict[str, Any]]: infos = await self._loop.getaddrinfo( host, port, type=socket.SOCK_STREAM, family=family) @@ -39,28 +40,27 @@ class ThreadedResolver(AbstractResolver): return hosts - async def close(self): + async def close(self) -> None: pass class AsyncResolver(AbstractResolver): """Use the `aiodns` package to make asynchronous DNS lookups""" - def __init__(self, loop=None, *args, **kwargs): - if loop is None: - loop = asyncio.get_event_loop() - + def __init__(self, loop: Optional[asyncio.AbstractEventLoop]=None, + *args: Any, **kwargs: Any) -> None: if aiodns is None: raise RuntimeError("Resolver requires aiodns library") - self._loop = loop + self._loop = get_running_loop(loop) self._resolver = aiodns.DNSResolver(*args, loop=loop, **kwargs) if not hasattr(self._resolver, 'gethostbyname'): # aiodns 1.1 is not available, fallback to DNSResolver.query - self.resolve = self._resolve_with_query + self.resolve = self._resolve_with_query # type: ignore - async def resolve(self, host, port=0, family=socket.AF_INET): + async def resolve(self, host: str, port: int=0, + family: int=socket.AF_INET) -> List[Dict[str, Any]]: try: resp = await self._resolver.gethostbyname(host, family) except aiodns.error.DNSError as exc: @@ -79,7 +79,9 @@ class AsyncResolver(AbstractResolver): return hosts - async def _resolve_with_query(self, host, port=0, family=socket.AF_INET): + async def _resolve_with_query( + self, host: str, port: int=0, + family: int=socket.AF_INET) -> List[Dict[str, Any]]: if family == socket.AF_INET6: qtype = 'AAAA' else: @@ -104,7 +106,7 @@ class AsyncResolver(AbstractResolver): return hosts - async def close(self): + async def close(self) -> None: return self._resolver.cancel() diff --git a/aiohttp/signals.pyi b/aiohttp/signals.pyi index c0c62fd..d9778e7 100644 --- a/aiohttp/signals.pyi +++ b/aiohttp/signals.pyi @@ -15,4 +15,4 @@ class Signal(FrozenList[_T], Generic[_T]): def __repr__(self) -> str: ... - async def send(self, *args, **kwargs) -> None: ... + async def send(self, *args: Any, **kwargs: Any) -> None: ... diff --git a/aiohttp/streams.py b/aiohttp/streams.py index 0794eb2..970816b 100644 --- a/aiohttp/streams.py +++ b/aiohttp/streams.py @@ -1,11 +1,18 @@ import asyncio import collections +import warnings from typing import List # noqa -from typing import Awaitable, Callable, Optional, Tuple +from typing import Awaitable, Callable, Generic, Optional, Tuple, TypeVar -from .helpers import set_exception, set_result +from .base_protocol import BaseProtocol +from .helpers import BaseTimerContext, set_exception, set_result from .log import internal_logger -from .typedefs import Byteish + + +try: # pragma: no cover + from typing import Deque # noqa +except ImportError: + from typing_extensions import Deque # noqa __all__ = ( @@ -14,20 +21,22 @@ __all__ = ( DEFAULT_LIMIT = 2 ** 16 +_T = TypeVar('_T') + class EofStream(Exception): """eof stream indication.""" -class AsyncStreamIterator: +class AsyncStreamIterator(Generic[_T]): - def __init__(self, read_func: Callable[[], Awaitable[bytes]]) -> None: + def __init__(self, read_func: Callable[[], Awaitable[_T]]) -> None: self.read_func = read_func - def __aiter__(self) -> 'AsyncStreamIterator': + def __aiter__(self) -> 'AsyncStreamIterator[_T]': return self - async def __anext__(self) -> bytes: + async def __anext__(self) -> _T: try: rv = await self.read_func() except EofStream: @@ -54,17 +63,17 @@ class ChunkTupleAsyncStreamIterator: class AsyncStreamReaderMixin: - def __aiter__(self) -> AsyncStreamIterator: + def __aiter__(self) -> AsyncStreamIterator[bytes]: return AsyncStreamIterator(self.readline) # type: ignore - def iter_chunked(self, n: int) -> AsyncStreamIterator: + def iter_chunked(self, n: int) -> AsyncStreamIterator[bytes]: """Returns an asynchronous iterator that yields chunks of size n. Python-3.5 available for Python 3.5+ only """ return AsyncStreamIterator(lambda: self.read(n)) # type: ignore - def iter_any(self) -> AsyncStreamIterator: + def iter_any(self) -> AsyncStreamIterator[bytes]: """Returns an asynchronous iterator that yields all the available data as soon as it is received @@ -98,8 +107,10 @@ class StreamReader(AsyncStreamReaderMixin): total_bytes = 0 - def __init__(self, protocol, - *, limit=DEFAULT_LIMIT, timer=None, loop=None): + def __init__(self, protocol: BaseProtocol, + *, limit: int=DEFAULT_LIMIT, + timer: Optional[BaseTimerContext]=None, + loop: Optional[asyncio.AbstractEventLoop]=None) -> None: self._protocol = protocol self._low_water = limit self._high_water = limit * 2 @@ -108,17 +119,17 @@ class StreamReader(AsyncStreamReaderMixin): self._loop = loop self._size = 0 self._cursor = 0 - self._http_chunk_splits = None - self._buffer = collections.deque() + self._http_chunk_splits = None # type: Optional[List[int]] + self._buffer = collections.deque() # type: Deque[bytes] self._buffer_offset = 0 self._eof = False - self._waiter = None - self._eof_waiter = None - self._exception = None + self._waiter = None # type: Optional[asyncio.Future[bool]] + self._eof_waiter = None # type: Optional[asyncio.Future[bool]] + self._exception = None # type: Optional[BaseException] self._timer = timer - self._eof_callbacks = [] + self._eof_callbacks = [] # type: List[Callable[[], None]] - def __repr__(self): + def __repr__(self) -> str: info = [self.__class__.__name__] if self._size: info.append('%d bytes' % self._size) @@ -198,9 +209,13 @@ class StreamReader(AsyncStreamReaderMixin): finally: self._eof_waiter = None - def unread_data(self, data: Byteish) -> None: + def unread_data(self, data: bytes) -> None: """ rollback reading some data from stream, inserting it to buffer head. """ + warnings.warn("unread_data() is deprecated " + "and will be removed in future releases (#3260)", + DeprecationWarning, + stacklevel=2) if not data: return @@ -213,7 +228,7 @@ class StreamReader(AsyncStreamReaderMixin): self._eof_counter = 0 # TODO: size is ignored, remove the param later - def feed_data(self, data: Byteish, size: int=0) -> None: + def feed_data(self, data: bytes, size: int=0) -> None: assert not self._eof, 'feed_data after feed_eof' if not data: @@ -244,7 +259,13 @@ class StreamReader(AsyncStreamReaderMixin): self._http_chunk_splits[-1] != self.total_bytes: self._http_chunk_splits.append(self.total_bytes) - async def _wait(self, func_name): + # wake up readchunk when end of http chunk received + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, False) + + async def _wait(self, func_name: str) -> None: # StreamReader uses a future to link the protocol feed_data() method # to a read coroutine. Running two read coroutines at the same time # would have an unexpected behaviour. It would not possible to know @@ -356,13 +377,15 @@ class StreamReader(AsyncStreamReaderMixin): return (b"", True) await self._wait('readchunk') - if not self._buffer: + if not self._buffer and not self._http_chunk_splits: # end of file return (b"", False) elif self._http_chunk_splits is not None: while self._http_chunk_splits: pos = self._http_chunk_splits[0] self._http_chunk_splits = self._http_chunk_splits[1:] + if pos == self._cursor: + return (b"", True) if pos > self._cursor: return (self._read_nowait(pos-self._cursor), True) return (self._read_nowait(-1), False) @@ -399,7 +422,7 @@ class StreamReader(AsyncStreamReaderMixin): return self._read_nowait(n) - def _read_nowait_chunk(self, n): + def _read_nowait_chunk(self, n: int) -> bytes: first_buffer = self._buffer[0] offset = self._buffer_offset if n != -1 and len(first_buffer) - offset > n: @@ -421,7 +444,7 @@ class StreamReader(AsyncStreamReaderMixin): self._protocol.resume_reading() return data - def _read_nowait(self, n): + def _read_nowait(self, n: int) -> bytes: chunks = [] while self._buffer: @@ -443,7 +466,7 @@ class EmptyStreamReader(AsyncStreamReaderMixin): def set_exception(self, exc: BaseException) -> None: pass - def on_eof(self, callback: Callable[[], None]): + def on_eof(self, callback: Callable[[], None]) -> None: try: callback() except Exception: @@ -461,7 +484,7 @@ class EmptyStreamReader(AsyncStreamReaderMixin): async def wait_eof(self) -> None: return - def feed_data(self, data: Byteish, n: int=0) -> None: + def feed_data(self, data: bytes, n: int=0) -> None: pass async def readline(self) -> bytes: @@ -474,7 +497,7 @@ class EmptyStreamReader(AsyncStreamReaderMixin): return b'' async def readchunk(self) -> Tuple[bytes, bool]: - return (b'', False) + return (b'', True) async def readexactly(self, n: int) -> bytes: raise asyncio.streams.IncompleteReadError(b'', n) @@ -486,16 +509,16 @@ class EmptyStreamReader(AsyncStreamReaderMixin): EMPTY_PAYLOAD = EmptyStreamReader() -class DataQueue: +class DataQueue(Generic[_T]): """DataQueue is a general-purpose blocking queue with one reader.""" - def __init__(self, *, loop=None): + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: self._loop = loop self._eof = False - self._waiter = None - self._exception = None + self._waiter = None # type: Optional[asyncio.Future[bool]] + self._exception = None # type: Optional[BaseException] self._size = 0 - self._buffer = collections.deque() + self._buffer = collections.deque() # type: Deque[Tuple[_T, int]] def __len__(self) -> int: return len(self._buffer) @@ -518,7 +541,7 @@ class DataQueue: set_exception(waiter, exc) self._waiter = None - def feed_data(self, data: Byteish, size: int=0) -> None: + def feed_data(self, data: _T, size: int=0) -> None: self._size += size self._buffer.append((data, size)) @@ -535,7 +558,7 @@ class DataQueue: self._waiter = None set_result(waiter, False) - async def read(self) -> bytes: + async def read(self) -> _T: if not self._buffer and not self._eof: assert not self._waiter self._waiter = self._loop.create_future() @@ -555,29 +578,30 @@ class DataQueue: else: raise EofStream - def __aiter__(self) -> AsyncStreamIterator: + def __aiter__(self) -> AsyncStreamIterator[_T]: return AsyncStreamIterator(self.read) -class FlowControlDataQueue(DataQueue): +class FlowControlDataQueue(DataQueue[_T]): """FlowControlDataQueue resumes and pauses an underlying stream. It is a destination for parsed data.""" - def __init__(self, protocol, *, limit: int=DEFAULT_LIMIT, loop: - Optional[asyncio.AbstractEventLoop]=None) -> None: + def __init__(self, protocol: BaseProtocol, *, + limit: int=DEFAULT_LIMIT, + loop: asyncio.AbstractEventLoop) -> None: super().__init__(loop=loop) self._protocol = protocol self._limit = limit * 2 - def feed_data(self, data: Byteish, size: int=0) -> None: + def feed_data(self, data: _T, size: int=0) -> None: super().feed_data(data, size) if self._size > self._limit and not self._protocol._reading_paused: self._protocol.pause_reading() - async def read(self) -> bytes: + async def read(self) -> _T: try: return await super().read() finally: diff --git a/aiohttp/test_utils.py b/aiohttp/test_utils.py index fdc63ee..7bd7416 100644 --- a/aiohttp/test_utils.py +++ b/aiohttp/test_utils.py @@ -8,23 +8,47 @@ import socket import sys import unittest from abc import ABC, abstractmethod +from types import TracebackType +from typing import (TYPE_CHECKING, Any, Callable, Iterator, List, # noqa + Optional, Type, Union) from unittest import mock from multidict import CIMultiDict, CIMultiDictProxy from yarl import URL import aiohttp -from aiohttp.client import _RequestContextManager, _WSRequestContextManager +from aiohttp.client import (ClientResponse, _RequestContextManager, + _WSRequestContextManager) from . import ClientSession, hdrs +from .abc import AbstractCookieJar +from .client_reqrep import ClientResponse # noqa +from .client_ws import ClientWebSocketResponse # noqa from .helpers import sentinel from .http import HttpVersion, RawRequestMessage from .signals import Signal -from .web import (AppRunner, Request, Server, ServerRunner, TCPSite, - UrlMappingMatchInfo) +from .web import (Application, AppRunner, BaseRunner, Request, Server, + ServerRunner, SockSite, UrlMappingMatchInfo) +from .web_protocol import _RequestHandler -def unused_port(): +if TYPE_CHECKING: # pragma: no cover + from ssl import SSLContext +else: + SSLContext = None + + +def get_unused_port_socket(host: str) -> socket.socket: + return get_port_socket(host, 0) + + +def get_port_socket(host: str, port: int) -> socket.socket: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind((host, port)) + return s + + +def unused_port() -> int: """Return a port that is unused on the current host.""" with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind(('127.0.0.1', 0)) @@ -32,19 +56,26 @@ def unused_port(): class BaseTestServer(ABC): - def __init__(self, *, scheme=sentinel, loop=None, - host='127.0.0.1', port=None, skip_url_asserts=False, - **kwargs): + def __init__(self, + *, + scheme: Union[str, object]=sentinel, + loop: Optional[asyncio.AbstractEventLoop]=None, + host: str='127.0.0.1', + port: Optional[int]=None, + skip_url_asserts: bool=False, + **kwargs: Any) -> None: self._loop = loop - self.runner = None - self._root = None + self.runner = None # type: Optional[BaseRunner] + self._root = None # type: Optional[URL] self.host = host self.port = port self._closed = False self.scheme = scheme self.skip_url_asserts = skip_url_asserts - async def start_server(self, loop=None, **kwargs): + async def start_server(self, + loop: Optional[asyncio.AbstractEventLoop]=None, + **kwargs: Any) -> None: if self.runner: return self._loop = loop @@ -52,10 +83,16 @@ class BaseTestServer(ABC): self.runner = await self._make_runner(**kwargs) await self.runner.setup() if not self.port: - self.port = unused_port() - site = TCPSite(self.runner, host=self.host, port=self.port, - ssl_context=self._ssl) + self.port = 0 + _sock = get_port_socket(self.host, self.port) + self.host, self.port = _sock.getsockname()[:2] + site = SockSite(self.runner, sock=_sock, ssl_context=self._ssl) await site.start() + server = site._server + assert server is not None + sockets = server.sockets + assert sockets is not None + self.port = sockets[0].getsockname()[1] if self.scheme is sentinel: if self._ssl: scheme = 'https' @@ -67,10 +104,11 @@ class BaseTestServer(ABC): self.port)) @abstractmethod # pragma: no cover - async def _make_runner(self, **kwargs): + async def _make_runner(self, **kwargs: Any) -> BaseRunner: pass - def make_url(self, path): + def make_url(self, path: str) -> URL: + assert self._root is not None url = URL(path) if not self.skip_url_asserts: assert not url.is_absolute() @@ -79,20 +117,23 @@ class BaseTestServer(ABC): return URL(str(self._root) + path) @property - def started(self): + def started(self) -> bool: return self.runner is not None @property - def closed(self): + def closed(self) -> bool: return self._closed @property - def handler(self): + def handler(self) -> Server: # for backward compatibility # web.Server instance - return self.runner.server + runner = self.runner + assert runner is not None + assert runner.server is not None + return runner.server - async def close(self): + async def close(self) -> None: """Close all fixtures created by the test client. After that point, the TestClient is no longer usable. @@ -105,45 +146,60 @@ class BaseTestServer(ABC): """ if self.started and not self.closed: + assert self.runner is not None await self.runner.cleanup() self._root = None self.port = None self._closed = True - def __enter__(self): + def __enter__(self) -> None: raise TypeError("Use async with instead") - def __exit__(self, exc_type, exc_value, traceback): + def __exit__(self, + exc_type: Optional[Type[BaseException]], + exc_value: Optional[BaseException], + traceback: Optional[TracebackType]) -> None: # __exit__ should exist in pair with __enter__ but never executed pass # pragma: no cover - async def __aenter__(self): + async def __aenter__(self) -> 'BaseTestServer': await self.start_server(loop=self._loop) return self - async def __aexit__(self, exc_type, exc_value, traceback): + async def __aexit__(self, + exc_type: Optional[Type[BaseException]], + exc_value: Optional[BaseException], + traceback: Optional[TracebackType]) -> None: await self.close() class TestServer(BaseTestServer): - def __init__(self, app, *, - scheme=sentinel, host='127.0.0.1', port=None, **kwargs): + def __init__(self, app: Application, *, + scheme: Union[str, object]=sentinel, + host: str='127.0.0.1', + port: Optional[int]=None, + **kwargs: Any): self.app = app super().__init__(scheme=scheme, host=host, port=port, **kwargs) - async def _make_runner(self, **kwargs): + async def _make_runner(self, **kwargs: Any) -> BaseRunner: return AppRunner(self.app, **kwargs) class RawTestServer(BaseTestServer): - def __init__(self, handler, *, - scheme=sentinel, host='127.0.0.1', port=None, **kwargs): + def __init__(self, handler: _RequestHandler, *, + scheme: Union[str, object]=sentinel, + host: str='127.0.0.1', + port: Optional[int]=None, + **kwargs: Any) -> None: self._handler = handler super().__init__(scheme=scheme, host=host, port=port, **kwargs) - async def _make_runner(self, debug=True, **kwargs): + async def _make_runner(self, + debug: bool=True, + **kwargs: Any) -> ServerRunner: srv = Server( self._handler, loop=self._loop, debug=True, **kwargs) return ServerRunner(srv, debug=debug, **kwargs) @@ -157,7 +213,10 @@ class TestClient: """ - def __init__(self, server, *, cookie_jar=None, loop=None, **kwargs): + def __init__(self, server: BaseTestServer, *, + cookie_jar: Optional[AbstractCookieJar]=None, + loop: Optional[asyncio.AbstractEventLoop]=None, + **kwargs: Any) -> None: if not isinstance(server, BaseTestServer): raise TypeError("server must be TestServer " "instance, found type: %r" % type(server)) @@ -169,30 +228,30 @@ class TestClient: cookie_jar=cookie_jar, **kwargs) self._closed = False - self._responses = [] - self._websockets = [] + self._responses = [] # type: List[ClientResponse] + self._websockets = [] # type: List[ClientWebSocketResponse] - async def start_server(self): + async def start_server(self) -> None: await self._server.start_server(loop=self._loop) @property - def host(self): + def host(self) -> str: return self._server.host @property - def port(self): + def port(self) -> Optional[int]: return self._server.port @property - def server(self): + def server(self) -> BaseTestServer: return self._server @property - def app(self): + def app(self) -> Application: return getattr(self._server, "app", None) @property - def session(self): + def session(self) -> ClientSession: """An internal aiohttp.ClientSession. Unlike the methods on the TestClient, client session requests @@ -202,10 +261,11 @@ class TestClient: """ return self._session - def make_url(self, path): + def make_url(self, path: str) -> URL: return self._server.make_url(path) - async def request(self, method, path, *args, **kwargs): + async def request(self, method: str, path: str, + **kwargs: Any) -> ClientResponse: """Routes a request to tested http server. The interface is identical to aiohttp.ClientSession.request, @@ -214,71 +274,72 @@ class TestClient: """ resp = await self._session.request( - method, self.make_url(path), *args, **kwargs + method, self.make_url(path), **kwargs ) # save it to close later self._responses.append(resp) return resp - def get(self, path, *args, **kwargs): + def get(self, path: str, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP GET request.""" return _RequestContextManager( - self.request(hdrs.METH_GET, path, *args, **kwargs) + self.request(hdrs.METH_GET, path, **kwargs) ) - def post(self, path, *args, **kwargs): + def post(self, path: str, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP POST request.""" return _RequestContextManager( - self.request(hdrs.METH_POST, path, *args, **kwargs) + self.request(hdrs.METH_POST, path, **kwargs) ) - def options(self, path, *args, **kwargs): + def options(self, path: str, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP OPTIONS request.""" return _RequestContextManager( - self.request(hdrs.METH_OPTIONS, path, *args, **kwargs) + self.request(hdrs.METH_OPTIONS, path, **kwargs) ) - def head(self, path, *args, **kwargs): + def head(self, path: str, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP HEAD request.""" return _RequestContextManager( - self.request(hdrs.METH_HEAD, path, *args, **kwargs) + self.request(hdrs.METH_HEAD, path, **kwargs) ) - def put(self, path, *args, **kwargs): + def put(self, path: str, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP PUT request.""" return _RequestContextManager( - self.request(hdrs.METH_PUT, path, *args, **kwargs) + self.request(hdrs.METH_PUT, path, **kwargs) ) - def patch(self, path, *args, **kwargs): + def patch(self, path: str, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP PATCH request.""" return _RequestContextManager( - self.request(hdrs.METH_PATCH, path, *args, **kwargs) + self.request(hdrs.METH_PATCH, path, **kwargs) ) - def delete(self, path, *args, **kwargs): + def delete(self, path: str, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP PATCH request.""" return _RequestContextManager( - self.request(hdrs.METH_DELETE, path, *args, **kwargs) + self.request(hdrs.METH_DELETE, path, **kwargs) ) - def ws_connect(self, path, *args, **kwargs): + def ws_connect(self, path: str, **kwargs: Any) -> _WSRequestContextManager: """Initiate websocket connection. The api corresponds to aiohttp.ClientSession.ws_connect. """ return _WSRequestContextManager( - self._ws_connect(path, *args, **kwargs) + self._ws_connect(path, **kwargs) ) - async def _ws_connect(self, path, *args, **kwargs): + async def _ws_connect(self, path: str, + **kwargs: Any) -> ClientWebSocketResponse: ws = await self._session.ws_connect( - self.make_url(path), *args, **kwargs) + self.make_url(path), **kwargs) self._websockets.append(ws) return ws - async def close(self): + async def close(self) -> None: """Close all fixtures created by the test client. After that point, the TestClient is no longer usable. @@ -299,18 +360,24 @@ class TestClient: await self._server.close() self._closed = True - def __enter__(self): + def __enter__(self) -> None: raise TypeError("Use async with instead") - def __exit__(self, exc_type, exc_value, traceback): + def __exit__(self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType]) -> None: # __exit__ should exist in pair with __enter__ but never executed pass # pragma: no cover - async def __aenter__(self): + async def __aenter__(self) -> 'TestClient': await self.start_server() return self - async def __aexit__(self, exc_type, exc_value, traceback): + async def __aexit__(self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType]) -> None: await self.close() @@ -330,7 +397,7 @@ class AioHTTPTestCase(unittest.TestCase): execute function on the test client using asynchronous methods. """ - async def get_application(self): + async def get_application(self) -> Application: """ This method should be overridden to return the aiohttp.web.Application @@ -339,7 +406,7 @@ class AioHTTPTestCase(unittest.TestCase): """ return self.get_app() - def get_app(self): + def get_app(self) -> Application: """Obsolete method used to constructing web application. Use .get_application() coroutine instead @@ -347,7 +414,7 @@ class AioHTTPTestCase(unittest.TestCase): """ raise RuntimeError("Did you forget to define get_application()?") - def setUp(self): + def setUp(self) -> None: self.loop = setup_test_loop() self.app = self.loop.run_until_complete(self.get_application()) @@ -359,27 +426,27 @@ class AioHTTPTestCase(unittest.TestCase): self.loop.run_until_complete(self.setUpAsync()) - async def setUpAsync(self): + async def setUpAsync(self) -> None: pass - def tearDown(self): + def tearDown(self) -> None: self.loop.run_until_complete(self.tearDownAsync()) self.loop.run_until_complete(self.client.close()) teardown_test_loop(self.loop) - async def tearDownAsync(self): + async def tearDownAsync(self) -> None: pass - async def get_server(self, app): + async def get_server(self, app: Application) -> TestServer: """Return a TestServer instance.""" return TestServer(app, loop=self.loop) - async def get_client(self, server): + async def get_client(self, server: TestServer) -> TestClient: """Return a TestClient instance.""" return TestClient(server, loop=self.loop) -def unittest_run_loop(func, *args, **kwargs): +def unittest_run_loop(func: Any, *args: Any, **kwargs: Any) -> Any: """A decorator dedicated to use with asynchronous methods of an AioHTTPTestCase. @@ -388,15 +455,19 @@ def unittest_run_loop(func, *args, **kwargs): """ @functools.wraps(func, *args, **kwargs) - def new_func(self, *inner_args, **inner_kwargs): + def new_func(self: Any, *inner_args: Any, **inner_kwargs: Any) -> Any: return self.loop.run_until_complete( func(self, *inner_args, **inner_kwargs)) return new_func +_LOOP_FACTORY = Callable[[], asyncio.AbstractEventLoop] + + @contextlib.contextmanager -def loop_context(loop_factory=asyncio.new_event_loop, fast=False): +def loop_context(loop_factory: _LOOP_FACTORY=asyncio.new_event_loop, + fast: bool=False) -> Iterator[asyncio.AbstractEventLoop]: """A contextmanager that creates an event_loop, for test purposes. Handles the creation and cleanup of a test loop. @@ -406,7 +477,9 @@ def loop_context(loop_factory=asyncio.new_event_loop, fast=False): teardown_test_loop(loop, fast=fast) -def setup_test_loop(loop_factory=asyncio.new_event_loop): +def setup_test_loop( + loop_factory: _LOOP_FACTORY=asyncio.new_event_loop +) -> asyncio.AbstractEventLoop: """Create and return an asyncio.BaseEventLoop instance. @@ -423,14 +496,15 @@ def setup_test_loop(loop_factory=asyncio.new_event_loop): asyncio.set_event_loop(loop) if sys.platform != "win32" and not skip_watcher: policy = asyncio.get_event_loop_policy() - watcher = asyncio.SafeChildWatcher() + watcher = asyncio.SafeChildWatcher() # type: ignore watcher.attach_loop(loop) with contextlib.suppress(NotImplementedError): policy.set_child_watcher(watcher) return loop -def teardown_test_loop(loop, fast=False): +def teardown_test_loop(loop: asyncio.AbstractEventLoop, + fast: bool=False) -> None: """Teardown and cleanup an event_loop created by setup_test_loop. @@ -447,18 +521,28 @@ def teardown_test_loop(loop, fast=False): asyncio.set_event_loop(None) -def _create_app_mock(): - app = mock.Mock() +def _create_app_mock() -> mock.MagicMock: + def get_dict(app: Any, key: str) -> Any: + return app.__app_dict[key] + + def set_dict(app: Any, key: str, value: Any) -> None: + app.__app_dict[key] = value + + app = mock.MagicMock() + app.__app_dict = {} + app.__getitem__ = get_dict + app.__setitem__ = set_dict + app._debug = False app.on_response_prepare = Signal(app) app.on_response_prepare.freeze() return app -def _create_transport(sslcontext=None): +def _create_transport(sslcontext: Optional[SSLContext]=None) -> mock.Mock: transport = mock.Mock() - def get_extra_info(key): + def get_extra_info(key: str) -> Optional[SSLContext]: if key == 'sslcontext': return sslcontext else: @@ -468,17 +552,19 @@ def _create_transport(sslcontext=None): return transport -def make_mocked_request(method, path, headers=None, *, - match_info=sentinel, - version=HttpVersion(1, 1), closing=False, - app=None, - writer=sentinel, - protocol=sentinel, - transport=sentinel, - payload=sentinel, - sslcontext=None, - client_max_size=1024**2, - loop=...): +def make_mocked_request(method: str, path: str, + headers: Any=None, *, + match_info: Any=sentinel, + version: HttpVersion=HttpVersion(1, 1), + closing: bool=False, + app: Any=None, + writer: Any=sentinel, + protocol: Any=sentinel, + transport: Any=sentinel, + payload: Any=sentinel, + sslcontext: Optional[SSLContext]=None, + client_max_size: int=1024**2, + loop: Any=...) -> Any: """Creates mocked web.Request testing purposes. Useful in unit tests, when spinning full web server is overkill or @@ -543,10 +629,11 @@ def make_mocked_request(method, path, headers=None, *, return req -def make_mocked_coro(return_value=sentinel, raise_exception=sentinel): +def make_mocked_coro(return_value: Any=sentinel, + raise_exception: Any=sentinel) -> Any: """Creates a coroutine mock.""" @asyncio.coroutine - def mock_coro(*args, **kwargs): + def mock_coro(*args: Any, **kwargs: Any) -> Any: if raise_exception is not sentinel: raise raise_exception return return_value diff --git a/aiohttp/tracing.py b/aiohttp/tracing.py index 165e68c..bc06c81 100644 --- a/aiohttp/tracing.py +++ b/aiohttp/tracing.py @@ -1,13 +1,22 @@ from types import SimpleNamespace +from typing import TYPE_CHECKING, Awaitable, Callable, Type import attr -from multidict import CIMultiDict +from multidict import CIMultiDict # noqa from yarl import URL from .client_reqrep import ClientResponse from .signals import Signal +if TYPE_CHECKING: # pragma: no cover + from .client import ClientSession # noqa + + _Signal = Signal[Callable[['TraceConfig'], Awaitable[None]]] +else: + _Signal = Signal + + __all__ = ( 'TraceConfig', 'TraceRequestStartParams', 'TraceRequestEndParams', 'TraceRequestExceptionParams', 'TraceConnectionQueuedStartParams', @@ -24,31 +33,37 @@ class TraceConfig: """First-class used to trace requests launched via ClientSession objects.""" - def __init__(self, trace_config_ctx_factory=SimpleNamespace): - self._on_request_start = Signal(self) - self._on_request_chunk_sent = Signal(self) - self._on_response_chunk_received = Signal(self) - self._on_request_end = Signal(self) - self._on_request_exception = Signal(self) - self._on_request_redirect = Signal(self) - self._on_connection_queued_start = Signal(self) - self._on_connection_queued_end = Signal(self) - self._on_connection_create_start = Signal(self) - self._on_connection_create_end = Signal(self) - self._on_connection_reuseconn = Signal(self) - self._on_dns_resolvehost_start = Signal(self) - self._on_dns_resolvehost_end = Signal(self) - self._on_dns_cache_hit = Signal(self) - self._on_dns_cache_miss = Signal(self) - - self._trace_config_ctx_factory = trace_config_ctx_factory - - def trace_config_ctx(self, trace_request_ctx=None): + def __init__( + self, + trace_config_ctx_factory: Type[SimpleNamespace]=SimpleNamespace + ) -> None: + self._on_request_start = Signal(self) # type: _Signal + self._on_request_chunk_sent = Signal(self) # type: _Signal + self._on_response_chunk_received = Signal(self) # type: _Signal + self._on_request_end = Signal(self) # type: _Signal + self._on_request_exception = Signal(self) # type: _Signal + self._on_request_redirect = Signal(self) # type: _Signal + self._on_connection_queued_start = Signal(self) # type: _Signal + self._on_connection_queued_end = Signal(self) # type: _Signal + self._on_connection_create_start = Signal(self) # type: _Signal + self._on_connection_create_end = Signal(self) # type: _Signal + self._on_connection_reuseconn = Signal(self) # type: _Signal + self._on_dns_resolvehost_start = Signal(self) # type: _Signal + self._on_dns_resolvehost_end = Signal(self) # type: _Signal + self._on_dns_cache_hit = Signal(self) # type: _Signal + self._on_dns_cache_miss = Signal(self) # type: _Signal + + self._trace_config_ctx_factory = trace_config_ctx_factory # type: Type[SimpleNamespace] # noqa + + def trace_config_ctx( + self, + trace_request_ctx: SimpleNamespace=None + ) -> SimpleNamespace: # noqa """ Return a new trace_config_ctx instance """ return self._trace_config_ctx_factory( trace_request_ctx=trace_request_ctx) - def freeze(self): + def freeze(self) -> None: self._on_request_start.freeze() self._on_request_chunk_sent.freeze() self._on_response_chunk_received.freeze() @@ -66,63 +81,63 @@ class TraceConfig: self._on_dns_cache_miss.freeze() @property - def on_request_start(self): + def on_request_start(self) -> _Signal: return self._on_request_start @property - def on_request_chunk_sent(self): + def on_request_chunk_sent(self) -> _Signal: return self._on_request_chunk_sent @property - def on_response_chunk_received(self): + def on_response_chunk_received(self) -> _Signal: return self._on_response_chunk_received @property - def on_request_end(self): + def on_request_end(self) -> _Signal: return self._on_request_end @property - def on_request_exception(self): + def on_request_exception(self) -> _Signal: return self._on_request_exception @property - def on_request_redirect(self): + def on_request_redirect(self) -> _Signal: return self._on_request_redirect @property - def on_connection_queued_start(self): + def on_connection_queued_start(self) -> _Signal: return self._on_connection_queued_start @property - def on_connection_queued_end(self): + def on_connection_queued_end(self) -> _Signal: return self._on_connection_queued_end @property - def on_connection_create_start(self): + def on_connection_create_start(self) -> _Signal: return self._on_connection_create_start @property - def on_connection_create_end(self): + def on_connection_create_end(self) -> _Signal: return self._on_connection_create_end @property - def on_connection_reuseconn(self): + def on_connection_reuseconn(self) -> _Signal: return self._on_connection_reuseconn @property - def on_dns_resolvehost_start(self): + def on_dns_resolvehost_start(self) -> _Signal: return self._on_dns_resolvehost_start @property - def on_dns_resolvehost_end(self): + def on_dns_resolvehost_end(self) -> _Signal: return self._on_dns_resolvehost_end @property - def on_dns_cache_hit(self): + def on_dns_cache_hit(self) -> _Signal: return self._on_dns_cache_hit @property - def on_dns_cache_miss(self): + def on_dns_cache_miss(self) -> _Signal: return self._on_dns_cache_miss @@ -131,7 +146,7 @@ class TraceRequestStartParams: """ Parameters sent by the `on_request_start` signal""" method = attr.ib(type=str) url = attr.ib(type=URL) - headers = attr.ib(type=CIMultiDict) + headers = attr.ib(type='CIMultiDict[str]') @attr.s(frozen=True, slots=True) @@ -151,7 +166,7 @@ class TraceRequestEndParams: """ Parameters sent by the `on_request_end` signal""" method = attr.ib(type=str) url = attr.ib(type=URL) - headers = attr.ib(type=CIMultiDict) + headers = attr.ib(type='CIMultiDict[str]') response = attr.ib(type=ClientResponse) @@ -160,8 +175,8 @@ class TraceRequestExceptionParams: """ Parameters sent by the `on_request_exception` signal""" method = attr.ib(type=str) url = attr.ib(type=URL) - headers = attr.ib(type=CIMultiDict) - exception = attr.ib(type=Exception) + headers = attr.ib(type='CIMultiDict[str]') + exception = attr.ib(type=BaseException) @attr.s(frozen=True, slots=True) @@ -169,7 +184,7 @@ class TraceRequestRedirectParams: """ Parameters sent by the `on_request_redirect` signal""" method = attr.ib(type=str) url = attr.ib(type=URL) - headers = attr.ib(type=CIMultiDict) + headers = attr.ib(type='CIMultiDict[str]') response = attr.ib(type=ClientResponse) @@ -226,110 +241,128 @@ class Trace: """ Internal class used to keep together the main dependencies used at the moment of send a signal.""" - def __init__(self, session, trace_config, trace_config_ctx): + def __init__(self, + session: 'ClientSession', + trace_config: TraceConfig, + trace_config_ctx: SimpleNamespace) -> None: self._trace_config = trace_config self._trace_config_ctx = trace_config_ctx self._session = session - async def send_request_start(self, method, url, headers): + async def send_request_start(self, + method: str, + url: URL, + headers: 'CIMultiDict[str]') -> None: return await self._trace_config.on_request_start.send( self._session, self._trace_config_ctx, TraceRequestStartParams(method, url, headers) ) - async def send_request_chunk_sent(self, chunk): + async def send_request_chunk_sent(self, chunk: bytes) -> None: return await self._trace_config.on_request_chunk_sent.send( self._session, self._trace_config_ctx, TraceRequestChunkSentParams(chunk) ) - async def send_response_chunk_received(self, chunk): + async def send_response_chunk_received(self, chunk: bytes) -> None: return await self._trace_config.on_response_chunk_received.send( self._session, self._trace_config_ctx, TraceResponseChunkReceivedParams(chunk) ) - async def send_request_end(self, method, url, headers, response): + async def send_request_end(self, + method: str, + url: URL, + headers: 'CIMultiDict[str]', + response: ClientResponse) -> None: return await self._trace_config.on_request_end.send( self._session, self._trace_config_ctx, TraceRequestEndParams(method, url, headers, response) ) - async def send_request_exception(self, method, url, headers, exception): + async def send_request_exception(self, + method: str, + url: URL, + headers: 'CIMultiDict[str]', + exception: BaseException) -> None: return await self._trace_config.on_request_exception.send( self._session, self._trace_config_ctx, TraceRequestExceptionParams(method, url, headers, exception) ) - async def send_request_redirect(self, method, url, headers, response): + async def send_request_redirect(self, + method: str, + url: URL, + headers: 'CIMultiDict[str]', + response: ClientResponse) -> None: return await self._trace_config._on_request_redirect.send( self._session, self._trace_config_ctx, TraceRequestRedirectParams(method, url, headers, response) ) - async def send_connection_queued_start(self): + async def send_connection_queued_start(self) -> None: return await self._trace_config.on_connection_queued_start.send( self._session, self._trace_config_ctx, TraceConnectionQueuedStartParams() ) - async def send_connection_queued_end(self): + async def send_connection_queued_end(self) -> None: return await self._trace_config.on_connection_queued_end.send( self._session, self._trace_config_ctx, TraceConnectionQueuedEndParams() ) - async def send_connection_create_start(self): + async def send_connection_create_start(self) -> None: return await self._trace_config.on_connection_create_start.send( self._session, self._trace_config_ctx, TraceConnectionCreateStartParams() ) - async def send_connection_create_end(self): + async def send_connection_create_end(self) -> None: return await self._trace_config.on_connection_create_end.send( self._session, self._trace_config_ctx, TraceConnectionCreateEndParams() ) - async def send_connection_reuseconn(self): + async def send_connection_reuseconn(self) -> None: return await self._trace_config.on_connection_reuseconn.send( self._session, self._trace_config_ctx, TraceConnectionReuseconnParams() ) - async def send_dns_resolvehost_start(self, host): + async def send_dns_resolvehost_start(self, host: str) -> None: return await self._trace_config.on_dns_resolvehost_start.send( self._session, self._trace_config_ctx, TraceDnsResolveHostStartParams(host) ) - async def send_dns_resolvehost_end(self, host): + async def send_dns_resolvehost_end(self, host: str) -> None: return await self._trace_config.on_dns_resolvehost_end.send( self._session, self._trace_config_ctx, TraceDnsResolveHostEndParams(host) ) - async def send_dns_cache_hit(self, host): + async def send_dns_cache_hit(self, host: str) -> None: return await self._trace_config.on_dns_cache_hit.send( self._session, self._trace_config_ctx, TraceDnsCacheHitParams(host) ) - async def send_dns_cache_miss(self, host): + async def send_dns_cache_miss(self, host: str) -> None: return await self._trace_config.on_dns_cache_miss.send( self._session, self._trace_config_ctx, diff --git a/aiohttp/typedefs.py b/aiohttp/typedefs.py index 921ee17..8e173b8 100644 --- a/aiohttp/typedefs.py +++ b/aiohttp/typedefs.py @@ -1,16 +1,40 @@ import json -from typing import Any, Callable, Mapping, Tuple, Union # noqa +import os # noqa +import pathlib # noqa +import sys +from typing import (TYPE_CHECKING, Any, Callable, Iterable, Mapping, Tuple, + Union) -from multidict import CIMultiDict, CIMultiDictProxy +from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy from yarl import URL DEFAULT_JSON_ENCODER = json.dumps DEFAULT_JSON_DECODER = json.loads +if TYPE_CHECKING: # pragma: no cover + _CIMultiDict = CIMultiDict[str] + _CIMultiDictProxy = CIMultiDictProxy[str] + _MultiDict = MultiDict[str] + _MultiDictProxy = MultiDictProxy[str] + from http.cookies import BaseCookie # noqa +else: + _CIMultiDict = CIMultiDict + _CIMultiDictProxy = CIMultiDictProxy + _MultiDict = MultiDict + _MultiDictProxy = MultiDictProxy + Byteish = Union[bytes, bytearray, memoryview] JSONEncoder = Callable[[Any], str] JSONDecoder = Callable[[str], Any] -LooseHeaders = Union[Mapping, CIMultiDict, CIMultiDictProxy] +LooseHeaders = Union[Mapping[str, str], _CIMultiDict, _CIMultiDictProxy] RawHeaders = Tuple[Tuple[bytes, bytes], ...] StrOrURL = Union[str, URL] +LooseCookies = Union[Iterable[Tuple[str, 'BaseCookie[str]']], + Mapping[str, 'BaseCookie[str]'], 'BaseCookie[str]'] + + +if sys.version_info >= (3, 6): + PathLike = Union[str, 'os.PathLike[str]'] +else: + PathLike = Union[str, pathlib.PurePath] diff --git a/aiohttp/web.py b/aiohttp/web.py index 59bc3ac..e277219 100644 --- a/aiohttp/web.py +++ b/aiohttp/web.py @@ -3,23 +3,28 @@ import logging import socket import sys from argparse import ArgumentParser -from collections import Iterable +from collections.abc import Iterable from importlib import import_module +from typing import Any, Awaitable, Callable, List, Optional, Type, Union, cast -from . import (helpers, web_app, web_exceptions, web_fileresponse, - web_middlewares, web_protocol, web_request, web_response, - web_routedef, web_runner, web_server, web_urldispatcher, web_ws) +from . import (web_app, web_exceptions, web_fileresponse, web_middlewares, + web_protocol, web_request, web_response, web_routedef, + web_runner, web_server, web_urldispatcher, web_ws) +from .abc import AbstractAccessLogger +from .helpers import all_tasks from .log import access_logger from .web_app import * # noqa +from .web_app import Application from .web_exceptions import * # noqa from .web_fileresponse import * # noqa +from .web_log import AccessLogger from .web_middlewares import * # noqa from .web_protocol import * # noqa from .web_request import * # noqa from .web_response import * # noqa from .web_routedef import * # noqa -from .web_runner import * # noqa -from .web_runner import AppRunner, GracefulExit, SockSite, TCPSite, UnixSite +from .web_runner import (AppRunner, BaseRunner, BaseSite, GracefulExit, # noqa + ServerRunner, SockSite, TCPSite, UnixSite) from .web_server import * # noqa from .web_urldispatcher import * # noqa from .web_ws import * # noqa @@ -37,29 +42,46 @@ __all__ = (web_protocol.__all__ + web_server.__all__ + web_runner.__all__ + web_middlewares.__all__ + - ('run_app',)) + ('run_app', 'BaseSite', 'TCPSite', 'UnixSite', + 'SockSite', 'BaseRunner', + 'AppRunner', 'ServerRunner', 'GracefulExit')) -def run_app(app, *, host=None, port=None, path=None, sock=None, - shutdown_timeout=60.0, ssl_context=None, - print=print, backlog=128, access_log_class=helpers.AccessLogger, - access_log_format=helpers.AccessLogger.LOG_FORMAT, - access_log=access_logger, handle_signals=True, - reuse_address=None, reuse_port=None): - """Run an app locally""" - loop = asyncio.get_event_loop() +try: + from ssl import SSLContext +except ImportError: # pragma: no cover + SSLContext = Any # type: ignore + +async def _run_app(app: Union[Application, Awaitable[Application]], *, + host: Optional[str]=None, + port: Optional[int]=None, + path: Optional[str]=None, + sock: Optional[socket.socket]=None, + shutdown_timeout: float=60.0, + ssl_context: Optional[SSLContext]=None, + print: Callable[..., None]=print, + backlog: int=128, + access_log_class: Type[AbstractAccessLogger]=AccessLogger, + access_log_format: str=AccessLogger.LOG_FORMAT, + access_log: logging.Logger=access_logger, + handle_signals: bool=True, + reuse_address: Optional[bool]=None, + reuse_port: Optional[bool]=None) -> None: + # A internal functio to actually do all dirty job for application running if asyncio.iscoroutine(app): - app = loop.run_until_complete(app) + app = await app # type: ignore + + app = cast(Application, app) runner = AppRunner(app, handle_signals=handle_signals, access_log_class=access_log_class, access_log_format=access_log_format, access_log=access_log) - loop.run_until_complete(runner.setup()) + await runner.setup() - sites = [] + sites = [] # type: List[BaseSite] try: if host is not None: @@ -111,23 +133,91 @@ def run_app(app, *, host=None, port=None, path=None, sock=None, ssl_context=ssl_context, backlog=backlog)) for site in sites: - loop.run_until_complete(site.start()) - try: - if print: # pragma: no branch - names = sorted(str(s.name) for s in runner.sites) - print("======== Running on {} ========\n" - "(Press CTRL+C to quit)".format(', '.join(names))) - loop.run_forever() - except (GracefulExit, KeyboardInterrupt): # pragma: no cover - pass + await site.start() + + if print: # pragma: no branch + names = sorted(str(s.name) for s in runner.sites) + print("======== Running on {} ========\n" + "(Press CTRL+C to quit)".format(', '.join(names))) + while True: + await asyncio.sleep(3600) # sleep forever by 1 hour intervals + finally: + await runner.cleanup() + + +def _cancel_all_tasks(loop: asyncio.AbstractEventLoop) -> None: + to_cancel = all_tasks(loop) + if not to_cancel: + return + + for task in to_cancel: + task.cancel() + + loop.run_until_complete( + asyncio.gather(*to_cancel, loop=loop, return_exceptions=True)) + + for task in to_cancel: + if task.cancelled(): + continue + if task.exception() is not None: + loop.call_exception_handler({ + 'message': 'unhandled exception during asyncio.run() shutdown', + 'exception': task.exception(), + 'task': task, + }) + + +def run_app(app: Union[Application, Awaitable[Application]], *, + host: Optional[str]=None, + port: Optional[int]=None, + path: Optional[str]=None, + sock: Optional[socket.socket]=None, + shutdown_timeout: float=60.0, + ssl_context: Optional[SSLContext]=None, + print: Callable[..., None]=print, + backlog: int=128, + access_log_class: Type[AbstractAccessLogger]=AccessLogger, + access_log_format: str=AccessLogger.LOG_FORMAT, + access_log: logging.Logger=access_logger, + handle_signals: bool=True, + reuse_address: Optional[bool]=None, + reuse_port: Optional[bool]=None) -> None: + """Run an app locally""" + loop = asyncio.get_event_loop() + + # Configure if and only if in debugging mode and using the default logger + if loop.get_debug() and access_log.name == 'aiohttp.access': + if access_log.level == logging.NOTSET: + access_log.setLevel(logging.DEBUG) + if not access_log.hasHandlers(): + access_log.addHandler(logging.StreamHandler()) + + try: + loop.run_until_complete(_run_app(app, + host=host, + port=port, + path=path, + sock=sock, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + print=print, + backlog=backlog, + access_log_class=access_log_class, + access_log_format=access_log_format, + access_log=access_log, + handle_signals=handle_signals, + reuse_address=reuse_address, + reuse_port=reuse_port)) + except (GracefulExit, KeyboardInterrupt): # pragma: no cover + pass finally: - loop.run_until_complete(runner.cleanup()) - if hasattr(loop, 'shutdown_asyncgens'): - loop.run_until_complete(loop.shutdown_asyncgens()) - loop.close() + _cancel_all_tasks(loop) + if sys.version_info >= (3, 6): # don't use PY_36 to pass mypy + loop.run_until_complete(loop.shutdown_asyncgens()) + loop.close() -def main(argv): +def main(argv: List[str]) -> None: arg_parser = ArgumentParser( description="aiohttp.web Application server", prog="aiohttp.web" diff --git a/aiohttp/web_app.py b/aiohttp/web_app.py index 346f48a..1466dac 100644 --- a/aiohttp/web_app.py +++ b/aiohttp/web_app.py @@ -1,36 +1,60 @@ import asyncio +import logging import warnings -from collections import MutableMapping from functools import partial -from typing import TYPE_CHECKING, Awaitable, Callable +from typing import (TYPE_CHECKING, Any, AsyncIterator, Awaitable, # noqa + Callable, Dict, Iterable, Iterator, List, Mapping, + MutableMapping, Optional, Sequence, Tuple, Type, Union, + cast) from . import hdrs -from .abc import AbstractAccessLogger, AbstractMatchInfo, AbstractRouter +from .abc import (AbstractAccessLogger, AbstractMatchInfo, AbstractRouter, + AbstractStreamWriter) from .frozenlist import FrozenList -from .helpers import DEBUG, AccessLogger +from .helpers import DEBUG +from .http_parser import RawRequestMessage from .log import web_logger from .signals import Signal +from .streams import StreamReader +from .web_log import AccessLogger from .web_middlewares import _fix_request_current_app +from .web_protocol import RequestHandler from .web_request import Request from .web_response import StreamResponse +from .web_routedef import AbstractRouteDef from .web_server import Server -from .web_urldispatcher import PrefixedSubAppResource, UrlDispatcher +from .web_urldispatcher import (AbstractResource, Domain, MaskDomain, + MatchedSubAppResource, PrefixedSubAppResource, + UrlDispatcher) __all__ = ('Application', 'CleanupError') -if TYPE_CHECKING: # pragma: no branch +if TYPE_CHECKING: # pragma: no cover _AppSignal = Signal[Callable[['Application'], Awaitable[None]]] _RespPrepareSignal = Signal[Callable[[Request, StreamResponse], Awaitable[None]]] + _Handler = Callable[[Request], Awaitable[StreamResponse]] + _Middleware = Union[Callable[[Request, _Handler], + Awaitable[StreamResponse]], + Callable[['Application', _Handler], # old-style + Awaitable[_Handler]]] + _Middlewares = FrozenList[_Middleware] + _MiddlewaresHandlers = Optional[Sequence[Tuple[_Middleware, bool]]] + _Subapps = List['Application'] else: # No type checker mode, skip types _AppSignal = Signal _RespPrepareSignal = Signal + _Handler = Callable + _Middleware = Callable + _Middlewares = FrozenList + _MiddlewaresHandlers = Optional[Sequence] + _Subapps = List -class Application(MutableMapping): +class Application(MutableMapping[str, Any]): ATTRS = frozenset([ 'logger', '_debug', '_router', '_loop', '_handler_args', '_middlewares', '_middlewares_handlers', '_run_middlewares', @@ -39,13 +63,14 @@ class Application(MutableMapping): '_on_cleanup', '_client_max_size', '_cleanup_ctx']) def __init__(self, *, - logger=web_logger, - router=None, - middlewares=(), - handler_args=None, - client_max_size=1024**2, - loop=None, - debug=...): + logger: logging.Logger=web_logger, + router: Optional[UrlDispatcher]=None, + middlewares: Sequence[_Middleware]=(), + handler_args: Mapping[str, Any]=None, + client_max_size: int=1024**2, + loop: Optional[asyncio.AbstractEventLoop]=None, + debug: Any=... # mypy doesn't support ellipsis + ) -> None: if router is None: router = UrlDispatcher() else: @@ -57,19 +82,27 @@ class Application(MutableMapping): warnings.warn("loop argument is deprecated", DeprecationWarning, stacklevel=2) + if debug is not ...: + warnings.warn("debug argument is deprecated", + DeprecationWarning, + stacklevel=2) self._debug = debug self._router = router # type: UrlDispatcher self._loop = loop self._handler_args = handler_args self.logger = logger - self._middlewares = FrozenList(middlewares) - self._middlewares_handlers = None # initialized on freezing - self._run_middlewares = None # initialized on freezing - self._state = {} + self._middlewares = FrozenList(middlewares) # type: _Middlewares + + # initialized on freezing + self._middlewares_handlers = None # type: _MiddlewaresHandlers + # initialized on freezing + self._run_middlewares = None # type: Optional[bool] + + self._state = {} # type: Dict[str, Any] self._frozen = False self._pre_frozen = False - self._subapps = [] + self._subapps = [] # type: _Subapps self._on_response_prepare = Signal(self) # type: _RespPrepareSignal self._on_startup = Signal(self) # type: _AppSignal @@ -80,14 +113,14 @@ class Application(MutableMapping): self._on_cleanup.append(self._cleanup_ctx._on_cleanup) self._client_max_size = client_max_size - def __init_subclass__(cls): + def __init_subclass__(cls: Type['Application']) -> None: warnings.warn("Inheritance class {} from web.Application " "is discouraged".format(cls.__name__), DeprecationWarning, stacklevel=2) - if DEBUG: - def __setattr__(self, name, val): + if DEBUG: # pragma: no cover + def __setattr__(self, name: str, val: Any) -> None: if name not in self.ATTRS: warnings.warn("Setting custom web.Application.{} attribute " "is discouraged".format(name), @@ -97,39 +130,45 @@ class Application(MutableMapping): # MutableMapping API - def __eq__(self, other): + def __eq__(self, other: object) -> bool: return self is other - def __getitem__(self, key): + def __getitem__(self, key: str) -> Any: return self._state[key] - def _check_frozen(self): + def _check_frozen(self) -> None: if self._frozen: warnings.warn("Changing state of started or joined " "application is deprecated", DeprecationWarning, stacklevel=3) - def __setitem__(self, key, value): + def __setitem__(self, key: str, value: Any) -> None: self._check_frozen() self._state[key] = value - def __delitem__(self, key): + def __delitem__(self, key: str) -> None: self._check_frozen() del self._state[key] - def __len__(self): + def __len__(self) -> int: return len(self._state) - def __iter__(self): + def __iter__(self) -> Iterator[str]: return iter(self._state) ######## @property - def loop(self): - return self._loop + def loop(self) -> asyncio.AbstractEventLoop: + # Technically the loop can be None + # but we mask it by explicit type cast + # to provide more convinient type annotation + warnings.warn("loop property is deprecated", + DeprecationWarning, + stacklevel=2) + return cast(asyncio.AbstractEventLoop, self._loop) - def _set_loop(self, loop): + def _set_loop(self, loop: Optional[asyncio.AbstractEventLoop]) -> None: if loop is None: loop = asyncio.get_event_loop() if self._loop is not None and self._loop is not loop: @@ -173,8 +212,8 @@ class Application(MutableMapping): for subapp in self._subapps: subapp.pre_freeze() - self._run_middlewares =\ - self._run_middlewares or subapp._run_middlewares + self._run_middlewares = (self._run_middlewares or + subapp._run_middlewares) @property def frozen(self) -> bool: @@ -191,14 +230,17 @@ class Application(MutableMapping): @property def debug(self) -> bool: + warnings.warn("debug property is deprecated", + DeprecationWarning, + stacklevel=2) return self._debug - def _reg_subapp_signals(self, subapp): + def _reg_subapp_signals(self, subapp: 'Application') -> None: - def reg_handler(signame): + def reg_handler(signame: str) -> None: subsig = getattr(subapp, signame) - async def handler(app): + async def handler(app: 'Application') -> None: await subsig.send(subapp) appsig = getattr(self, signame) appsig.append(handler) @@ -207,18 +249,25 @@ class Application(MutableMapping): reg_handler('on_shutdown') reg_handler('on_cleanup') - def add_subapp(self, prefix: str, subapp: 'Application'): + def add_subapp(self, prefix: str, + subapp: 'Application') -> AbstractResource: + if not isinstance(prefix, str): + raise TypeError("Prefix must be str") + prefix = prefix.rstrip('/') + if not prefix: + raise ValueError("Prefix cannot be empty") + factory = partial(PrefixedSubAppResource, prefix, subapp) + return self._add_subapp(factory, subapp) + + def _add_subapp(self, + resource_factory: Callable[[], AbstractResource], + subapp: 'Application') -> AbstractResource: if self.frozen: raise RuntimeError( "Cannot add sub application to frozen application") if subapp.frozen: raise RuntimeError("Cannot add frozen application") - if prefix.endswith('/'): - prefix = prefix[:-1] - if prefix in ('', '/'): - raise ValueError("Prefix cannot be empty") - - resource = PrefixedSubAppResource(prefix, subapp) + resource = resource_factory() self.router.register_resource(resource) self._reg_subapp_signals(subapp) self._subapps.append(subapp) @@ -227,7 +276,18 @@ class Application(MutableMapping): subapp._set_loop(self._loop) return resource - def add_routes(self, routes): + def add_domain(self, domain: str, + subapp: 'Application') -> AbstractResource: + if not isinstance(domain, str): + raise TypeError("Domain must be str") + elif '*' in domain: + rule = MaskDomain(domain) # type: Domain + else: + rule = Domain(domain) + factory = partial(MatchedSubAppResource, rule, subapp) + return self._add_subapp(factory, subapp) + + def add_routes(self, routes: Iterable[AbstractRouteDef]) -> None: self.router.add_routes(routes) @property @@ -247,7 +307,7 @@ class Application(MutableMapping): return self._on_cleanup @property - def cleanup_ctx(self): + def cleanup_ctx(self) -> 'CleanupContext': return self._cleanup_ctx @property @@ -255,13 +315,14 @@ class Application(MutableMapping): return self._router @property - def middlewares(self): + def middlewares(self) -> _Middlewares: return self._middlewares def _make_handler(self, *, - loop=None, - access_log_class=AccessLogger, - **kwargs): + loop: Optional[asyncio.AbstractEventLoop]=None, + access_log_class: Type[ + AbstractAccessLogger]=AccessLogger, + **kwargs: Any) -> Server: if not issubclass(access_log_class, AbstractAccessLogger): raise TypeError( @@ -272,19 +333,21 @@ class Application(MutableMapping): self._set_loop(loop) self.freeze() - kwargs['debug'] = self.debug + kwargs['debug'] = self._debug + kwargs['access_log_class'] = access_log_class if self._handler_args: for k, v in self._handler_args.items(): kwargs[k] = v - return Server(self._handle, request_factory=self._make_request, - access_log_class=access_log_class, - loop=self.loop, **kwargs) + return Server(self._handle, # type: ignore + request_factory=self._make_request, + loop=self._loop, **kwargs) def make_handler(self, *, - loop=None, - access_log_class=AccessLogger, - **kwargs): + loop: Optional[asyncio.AbstractEventLoop]=None, + access_log_class: Type[ + AbstractAccessLogger]=AccessLogger, + **kwargs: Any) -> Server: warnings.warn("Application.make_handler(...) is deprecated, " "use AppRunner API instead", @@ -316,14 +379,18 @@ class Application(MutableMapping): """ await self.on_cleanup.send(self) - def _make_request(self, message, payload, protocol, writer, task, - _cls=Request): + def _make_request(self, message: RawRequestMessage, + payload: StreamReader, + protocol: RequestHandler, + writer: AbstractStreamWriter, + task: 'asyncio.Task[None]', + _cls: Type[Request]=Request) -> Request: return _cls( message, payload, protocol, writer, task, self._loop, client_max_size=self._client_max_size) - def _prepare_middleware(self): + def _prepare_middleware(self) -> Iterator[Tuple[_Middleware, bool]]: for m in reversed(self._middlewares): if getattr(m, '__middleware_version__', None) == 1: yield m, True @@ -335,18 +402,20 @@ class Application(MutableMapping): yield _fix_request_current_app(self), True - async def _handle(self, request): + async def _handle(self, request: Request) -> StreamResponse: + loop = asyncio.get_event_loop() + debug = loop.get_debug() match_info = await self._router.resolve(request) - if DEBUG: # pragma: no cover + if debug: # pragma: no cover if not isinstance(match_info, AbstractMatchInfo): - raise TypeError("match_info should be AbstractMAtchInfo " + raise TypeError("match_info should be AbstractMatchInfo " "instance, not {!r}".format(match_info)) match_info.add_app(self) match_info.freeze() resp = None - request._match_info = match_info + request._match_info = match_info # type: ignore expect = request.headers.get(hdrs.EXPECT) if expect: resp = await match_info.expect_handler(request) @@ -357,52 +426,50 @@ class Application(MutableMapping): if self._run_middlewares: for app in match_info.apps[::-1]: - for m, new_style in app._middlewares_handlers: + for m, new_style in app._middlewares_handlers: # type: ignore # noqa if new_style: handler = partial(m, handler=handler) else: - handler = await m(app, handler) + handler = await m(app, handler) # type: ignore resp = await handler(request) - if DEBUG: - if not isinstance(resp, StreamResponse): - msg = ("Handler {!r} should return response instance, " - "got {!r} [middlewares {!r}]").format( - match_info.handler, type(resp), - [middleware - for app in match_info.apps - for middleware in app.middlewares]) - raise TypeError(msg) return resp - def __call__(self): + def __call__(self) -> 'Application': """gunicorn compatibility""" return self - def __repr__(self): + def __repr__(self) -> str: return "<Application 0x{:x}>".format(id(self)) class CleanupError(RuntimeError): @property - def exceptions(self): + def exceptions(self) -> List[BaseException]: return self.args[1] -class CleanupContext(FrozenList): +if TYPE_CHECKING: # pragma: no cover + _CleanupContextBase = FrozenList[Callable[[Application], + AsyncIterator[None]]] +else: + _CleanupContextBase = FrozenList + + +class CleanupContext(_CleanupContextBase): - def __init__(self): + def __init__(self) -> None: super().__init__() - self._exits = [] + self._exits = [] # type: List[AsyncIterator[None]] - async def _on_startup(self, app): + async def _on_startup(self, app: Application) -> None: for cb in self: it = cb(app).__aiter__() await it.__anext__() self._exits.append(it) - async def _on_cleanup(self, app): + async def _on_cleanup(self, app: Application) -> None: errors = [] for it in reversed(self._exits): try: diff --git a/aiohttp/web_exceptions.py b/aiohttp/web_exceptions.py index c899c8d..d182613 100644 --- a/aiohttp/web_exceptions.py +++ b/aiohttp/web_exceptions.py @@ -1,3 +1,7 @@ +import warnings +from typing import Any, Dict, Iterable, List, Optional, Set # noqa + +from .typedefs import LooseHeaders, StrOrURL from .web_response import Response @@ -76,8 +80,16 @@ class HTTPException(Response, Exception): __http_exception__ = True - def __init__(self, *, headers=None, reason=None, - body=None, text=None, content_type=None): + def __init__(self, *, + headers: Optional[LooseHeaders]=None, + reason: Optional[str]=None, + body: Any=None, + text: Optional[str]=None, + content_type: Optional[str]=None) -> None: + if body is not None: + warnings.warn( + "body argument is deprecated for http web exceptions", + DeprecationWarning) Response.__init__(self, status=self.status_code, headers=headers, reason=reason, body=body, text=text, content_type=content_type) @@ -85,7 +97,7 @@ class HTTPException(Response, Exception): if self.body is None and not self.empty_body: self.text = "{}: {}".format(self.status, self.reason) - def __bool__(self): + def __bool__(self) -> bool: return True @@ -138,8 +150,14 @@ class HTTPPartialContent(HTTPSuccessful): class _HTTPMove(HTTPRedirection): - def __init__(self, location, *, headers=None, reason=None, - body=None, text=None, content_type=None): + def __init__(self, + location: StrOrURL, + *, + headers: Optional[LooseHeaders]=None, + reason: Optional[str]=None, + body: Any=None, + text: Optional[str]=None, + content_type: Optional[str]=None) -> None: if not location: raise ValueError("HTTP redirects need a location to redirect to.") super().__init__(headers=headers, reason=reason, @@ -217,13 +235,20 @@ class HTTPNotFound(HTTPClientError): class HTTPMethodNotAllowed(HTTPClientError): status_code = 405 - def __init__(self, method, allowed_methods, *, headers=None, reason=None, - body=None, text=None, content_type=None): + def __init__(self, + method: str, + allowed_methods: Iterable[str], + *, + headers: Optional[LooseHeaders]=None, + reason: Optional[str]=None, + body: Any=None, + text: Optional[str]=None, + content_type: Optional[str]=None) -> None: allow = ','.join(sorted(allowed_methods)) super().__init__(headers=headers, reason=reason, body=body, text=text, content_type=content_type) self.headers['Allow'] = allow - self.allowed_methods = allowed_methods + self.allowed_methods = set(allowed_methods) # type: Set[str] self.method = method.upper() @@ -258,7 +283,10 @@ class HTTPPreconditionFailed(HTTPClientError): class HTTPRequestEntityTooLarge(HTTPClientError): status_code = 413 - def __init__(self, max_size, actual_size, **kwargs): + def __init__(self, + max_size: float, + actual_size: float, + **kwargs: Any) -> None: kwargs.setdefault( 'text', 'Maximum request body size {} exceeded, ' @@ -314,8 +342,14 @@ class HTTPRequestHeaderFieldsTooLarge(HTTPClientError): class HTTPUnavailableForLegalReasons(HTTPClientError): status_code = 451 - def __init__(self, link, *, headers=None, reason=None, - body=None, text=None, content_type=None): + def __init__(self, + link: str, + *, + headers: Optional[LooseHeaders]=None, + reason: Optional[str]=None, + body: Any=None, + text: Optional[str]=None, + content_type: Optional[str]=None) -> None: super().__init__(headers=headers, reason=reason, body=body, text=text, content_type=content_type) self.headers['Link'] = '<%s>; rel="blocked-by"' % link diff --git a/aiohttp/web_fileresponse.py b/aiohttp/web_fileresponse.py index 85eb616..d5b1f1f 100644 --- a/aiohttp/web_fileresponse.py +++ b/aiohttp/web_fileresponse.py @@ -1,11 +1,18 @@ +import asyncio import mimetypes import os import pathlib +from functools import partial +from typing import (IO, TYPE_CHECKING, Any, Awaitable, Callable, List, # noqa + Optional, Union, cast) from . import hdrs +from .abc import AbstractStreamWriter +from .base_protocol import BaseProtocol from .helpers import set_exception, set_result from .http_writer import StreamWriter from .log import server_logger +from .typedefs import LooseHeaders from .web_exceptions import (HTTPNotModified, HTTPOk, HTTPPartialContent, HTTPPreconditionFailed, HTTPRequestRangeNotSatisfiable) @@ -14,78 +21,104 @@ from .web_response import StreamResponse __all__ = ('FileResponse',) +if TYPE_CHECKING: # pragma: no cover + from .web_request import BaseRequest # noqa + + +_T_OnChunkSent = Optional[Callable[[bytes], Awaitable[None]]] + NOSENDFILE = bool(os.environ.get("AIOHTTP_NOSENDFILE")) class SendfileStreamWriter(StreamWriter): - def __init__(self, *args, **kwargs): - self._sendfile_buffer = [] - super().__init__(*args, **kwargs) - - def _write(self, chunk): + def __init__(self, + protocol: BaseProtocol, + loop: asyncio.AbstractEventLoop, + fobj: IO[Any], + count: int, + on_chunk_sent: _T_OnChunkSent=None) -> None: + super().__init__(protocol, loop, on_chunk_sent) + self._sendfile_buffer = [] # type: List[bytes] + self._fobj = fobj + self._count = count + self._offset = fobj.tell() + self._in_fd = fobj.fileno() + + def _write(self, chunk: bytes) -> None: # we overwrite StreamWriter._write, so nothing can be appended to # _buffer, and nothing is written to the transport directly by the # parent class self.output_size += len(chunk) self._sendfile_buffer.append(chunk) - def _sendfile_cb(self, fut, out_fd, in_fd, - offset, count, loop, registered): - if registered: - loop.remove_writer(out_fd) + def _sendfile_cb(self, fut: 'asyncio.Future[None]', out_fd: int) -> None: if fut.cancelled(): return + try: + if self._do_sendfile(out_fd): + set_result(fut, None) + except Exception as exc: + set_exception(fut, exc) + def _do_sendfile(self, out_fd: int) -> bool: try: - n = os.sendfile(out_fd, in_fd, offset, count) - if n == 0: # EOF reached - n = count + n = os.sendfile(out_fd, + self._in_fd, + self._offset, + self._count) + if n == 0: # in_fd EOF reached + n = self._count except (BlockingIOError, InterruptedError): n = 0 - except Exception as exc: - set_exception(fut, exc) - return + self.output_size += n + self._offset += n + self._count -= n + assert self._count >= 0 + return self._count == 0 - if n < count: - loop.add_writer(out_fd, self._sendfile_cb, fut, out_fd, in_fd, - offset + n, count - n, loop, True) - else: - set_result(fut, None) + def _done_fut(self, out_fd: int, fut: 'asyncio.Future[None]') -> None: + self.loop.remove_writer(out_fd) - async def sendfile(self, fobj, count): + async def sendfile(self) -> None: + assert self.transport is not None out_socket = self.transport.get_extra_info('socket').dup() out_socket.setblocking(False) out_fd = out_socket.fileno() - in_fd = fobj.fileno() - offset = fobj.tell() loop = self.loop data = b''.join(self._sendfile_buffer) try: await loop.sock_sendall(out_socket, data) - fut = loop.create_future() - self._sendfile_cb(fut, out_fd, in_fd, offset, count, loop, False) - await fut + if not self._do_sendfile(out_fd): + fut = loop.create_future() + fut.add_done_callback(partial(self._done_fut, out_fd)) + loop.add_writer(out_fd, self._sendfile_cb, fut, out_fd) + await fut + except asyncio.CancelledError: + raise except Exception: server_logger.debug('Socket error') self.transport.close() finally: out_socket.close() - self.output_size += count await super().write_eof() - async def write_eof(self, chunk=b''): + async def write_eof(self, chunk: bytes=b'') -> None: pass class FileResponse(StreamResponse): """A response object can be used to send files.""" - def __init__(self, path, chunk_size=256*1024, *args, **kwargs): - super().__init__(*args, **kwargs) + def __init__(self, path: Union[str, pathlib.Path], + chunk_size: int=256*1024, + status: int=200, + reason: Optional[str]=None, + headers: Optional[LooseHeaders]=None) -> None: + super().__init__(status=status, reason=reason, headers=headers) if isinstance(path, str): path = pathlib.Path(path) @@ -93,7 +126,9 @@ class FileResponse(StreamResponse): self._path = path self._chunk_size = chunk_size - async def _sendfile_system(self, request, fobj, count): + async def _sendfile_system(self, request: 'BaseRequest', + fobj: IO[Any], + count: int) -> AbstractStreamWriter: # Write count bytes of fobj to resp using # the os.sendfile system call. # @@ -101,11 +136,12 @@ class FileResponse(StreamResponse): # https://github.com/KeepSafe/aiohttp/issues/1177 # See https://github.com/KeepSafe/aiohttp/issues/958 for details # - # request should be a aiohttp.web.Request instance. + # request should be an aiohttp.web.Request instance. # fobj should be an open file object. # count should be an integer > 0. transport = request.transport + assert transport is not None if (transport.get_extra_info("sslcontext") or transport.get_extra_info("socket") is None or self.compression): @@ -113,16 +149,20 @@ class FileResponse(StreamResponse): else: writer = SendfileStreamWriter( request.protocol, - request.loop + request._loop, + fobj, + count ) request._payload_writer = writer await super().prepare(request) - await writer.sendfile(fobj, count) + await writer.sendfile() return writer - async def _sendfile_fallback(self, request, fobj, count): + async def _sendfile_fallback(self, request: 'BaseRequest', + fobj: IO[Any], + count: int) -> AbstractStreamWriter: # Mimic the _sendfile_system() method, but without using the # os.sendfile() system call. This should be used on systems # that don't support the os.sendfile(). @@ -132,11 +172,12 @@ class FileResponse(StreamResponse): # constructor's chunk_size argument. writer = await super().prepare(request) + assert writer is not None chunk_size = self._chunk_size chunk = fobj.read(chunk_size) - while True: + while chunk: await writer.write(chunk) count = count - chunk_size if count <= 0: @@ -151,7 +192,10 @@ class FileResponse(StreamResponse): else: # pragma: no cover _sendfile = _sendfile_fallback - async def prepare(self, request): + async def prepare( + self, + request: 'BaseRequest' + ) -> Optional[AbstractStreamWriter]: filepath = self._path gzip = False @@ -262,19 +306,21 @@ class FileResponse(StreamResponse): self.set_status(status) if should_set_ct: - self.content_type = ct + self.content_type = ct # type: ignore if encoding: self.headers[hdrs.CONTENT_ENCODING] = encoding if gzip: self.headers[hdrs.VARY] = hdrs.ACCEPT_ENCODING - self.last_modified = st.st_mtime + self.last_modified = st.st_mtime # type: ignore self.content_length = count self.headers[hdrs.ACCEPT_RANGES] = 'bytes' + real_start = cast(int, start) + if status == HTTPPartialContent.status_code: self.headers[hdrs.CONTENT_RANGE] = 'bytes {0}-{1}/{2}'.format( - start, start + count - 1, file_size) + real_start, real_start + count - 1, file_size) with filepath.open('rb') as fobj: if start: # be aware that start could be None or int=0 here. diff --git a/aiohttp/web_log.py b/aiohttp/web_log.py new file mode 100644 index 0000000..1742d2a --- /dev/null +++ b/aiohttp/web_log.py @@ -0,0 +1,236 @@ +import datetime +import functools +import logging +import os +import re +from collections import namedtuple +from typing import Callable, Dict, Iterable, List, Tuple # noqa + +from .abc import AbstractAccessLogger +from .web_request import BaseRequest +from .web_response import StreamResponse + + +KeyMethod = namedtuple('KeyMethod', 'key method') + + +class AccessLogger(AbstractAccessLogger): + """Helper object to log access. + + Usage: + log = logging.getLogger("spam") + log_format = "%a %{User-Agent}i" + access_logger = AccessLogger(log, log_format) + access_logger.log(request, response, time) + + Format: + %% The percent sign + %a Remote IP-address (IP-address of proxy if using reverse proxy) + %t Time when the request was started to process + %P The process ID of the child that serviced the request + %r First line of request + %s Response status code + %b Size of response in bytes, including HTTP headers + %T Time taken to serve the request, in seconds + %Tf Time taken to serve the request, in seconds with floating fraction + in .06f format + %D Time taken to serve the request, in microseconds + %{FOO}i request.headers['FOO'] + %{FOO}o response.headers['FOO'] + %{FOO}e os.environ['FOO'] + + """ + LOG_FORMAT_MAP = { + 'a': 'remote_address', + 't': 'request_start_time', + 'P': 'process_id', + 'r': 'first_request_line', + 's': 'response_status', + 'b': 'response_size', + 'T': 'request_time', + 'Tf': 'request_time_frac', + 'D': 'request_time_micro', + 'i': 'request_header', + 'o': 'response_header', + } + + LOG_FORMAT = '%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"' + FORMAT_RE = re.compile(r'%(\{([A-Za-z0-9\-_]+)\}([ioe])|[atPrsbOD]|Tf?)') + CLEANUP_RE = re.compile(r'(%[^s])') + _FORMAT_CACHE = {} # type: Dict[str, Tuple[str, List[KeyMethod]]] + + def __init__(self, logger: logging.Logger, + log_format: str=LOG_FORMAT) -> None: + """Initialise the logger. + + logger is a logger object to be used for logging. + log_format is a string with apache compatible log format description. + + """ + super().__init__(logger, log_format=log_format) + + _compiled_format = AccessLogger._FORMAT_CACHE.get(log_format) + if not _compiled_format: + _compiled_format = self.compile_format(log_format) + AccessLogger._FORMAT_CACHE[log_format] = _compiled_format + + self._log_format, self._methods = _compiled_format + + def compile_format(self, log_format: str) -> Tuple[str, List[KeyMethod]]: + """Translate log_format into form usable by modulo formatting + + All known atoms will be replaced with %s + Also methods for formatting of those atoms will be added to + _methods in appropriate order + + For example we have log_format = "%a %t" + This format will be translated to "%s %s" + Also contents of _methods will be + [self._format_a, self._format_t] + These method will be called and results will be passed + to translated string format. + + Each _format_* method receive 'args' which is list of arguments + given to self.log + + Exceptions are _format_e, _format_i and _format_o methods which + also receive key name (by functools.partial) + + """ + # list of (key, method) tuples, we don't use an OrderedDict as users + # can repeat the same key more than once + methods = list() + + for atom in self.FORMAT_RE.findall(log_format): + if atom[1] == '': + format_key1 = self.LOG_FORMAT_MAP[atom[0]] + m = getattr(AccessLogger, '_format_%s' % atom[0]) + key_method = KeyMethod(format_key1, m) + else: + format_key2 = (self.LOG_FORMAT_MAP[atom[2]], atom[1]) + m = getattr(AccessLogger, '_format_%s' % atom[2]) + key_method = KeyMethod(format_key2, + functools.partial(m, atom[1])) + + methods.append(key_method) + + log_format = self.FORMAT_RE.sub(r'%s', log_format) + log_format = self.CLEANUP_RE.sub(r'%\1', log_format) + return log_format, methods + + @staticmethod + def _format_i(key: str, + request: BaseRequest, + response: StreamResponse, + time: float) -> str: + if request is None: + return '(no headers)' + + # suboptimal, make istr(key) once + return request.headers.get(key, '-') + + @staticmethod + def _format_o(key: str, + request: BaseRequest, + response: StreamResponse, + time: float) -> str: + # suboptimal, make istr(key) once + return response.headers.get(key, '-') + + @staticmethod + def _format_a(request: BaseRequest, + response: StreamResponse, + time: float) -> str: + if request is None: + return '-' + ip = request.remote + return ip if ip is not None else '-' + + @staticmethod + def _format_t(request: BaseRequest, + response: StreamResponse, + time: float) -> str: + now = datetime.datetime.utcnow() + start_time = now - datetime.timedelta(seconds=time) + return start_time.strftime('[%d/%b/%Y:%H:%M:%S +0000]') + + @staticmethod + def _format_P(request: BaseRequest, + response: StreamResponse, + time: float) -> str: + return "<%s>" % os.getpid() + + @staticmethod + def _format_r(request: BaseRequest, + response: StreamResponse, + time: float) -> str: + if request is None: + return '-' + return '%s %s HTTP/%s.%s' % (request.method, request.path_qs, + request.version.major, + request.version.minor) + + @staticmethod + def _format_s(request: BaseRequest, + response: StreamResponse, + time: float) -> int: + return response.status + + @staticmethod + def _format_b(request: BaseRequest, + response: StreamResponse, + time: float) -> int: + return response.body_length + + @staticmethod + def _format_T(request: BaseRequest, + response: StreamResponse, + time: float) -> str: + return str(round(time)) + + @staticmethod + def _format_Tf(request: BaseRequest, + response: StreamResponse, + time: float) -> str: + return '%06f' % time + + @staticmethod + def _format_D(request: BaseRequest, + response: StreamResponse, + time: float) -> str: + return str(round(time * 1000000)) + + def _format_line(self, + request: BaseRequest, + response: StreamResponse, + time: float) -> Iterable[Tuple[str, + Callable[[BaseRequest, + StreamResponse, + float], + str]]]: + return [(key, method(request, response, time)) + for key, method in self._methods] + + def log(self, + request: BaseRequest, + response: StreamResponse, + time: float) -> None: + try: + fmt_info = self._format_line(request, response, time) + + values = list() + extra = dict() + for key, value in fmt_info: + values.append(value) + + if key.__class__ is str: + extra[key] = value + else: + k1, k2 = key + dct = extra.get(k1, {}) + dct[k2] = value # type: ignore + extra[k1] = dct # type: ignore + + self.logger.info(self._log_format % tuple(values), extra=extra) + except Exception: + self.logger.exception("Error in logging") diff --git a/aiohttp/web_middlewares.py b/aiohttp/web_middlewares.py index f762f5b..39bfab3 100644 --- a/aiohttp/web_middlewares.py +++ b/aiohttp/web_middlewares.py @@ -1,7 +1,10 @@ import re +from typing import TYPE_CHECKING, Awaitable, Callable, Tuple, Type, TypeVar -from aiohttp.web_exceptions import HTTPMovedPermanently -from aiohttp.web_urldispatcher import SystemRoute +from .web_exceptions import HTTPMovedPermanently, _HTTPMove +from .web_request import Request +from .web_response import StreamResponse +from .web_urldispatcher import SystemRoute __all__ = ( @@ -9,27 +12,38 @@ __all__ = ( 'normalize_path_middleware', ) +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application # noqa -async def _check_request_resolves(request, path): +_Func = TypeVar('_Func') + + +async def _check_request_resolves(request: Request, + path: str) -> Tuple[bool, Request]: alt_request = request.clone(rel_url=path) match_info = await request.app.router.resolve(alt_request) - alt_request._match_info = match_info + alt_request._match_info = match_info # type: ignore - if not isinstance(match_info.route, SystemRoute): + if match_info.http_exception is None: return True, alt_request return False, request -def middleware(f): - f.__middleware_version__ = 1 +def middleware(f: _Func) -> _Func: + f.__middleware_version__ = 1 # type: ignore return f +_Handler = Callable[[Request], Awaitable[StreamResponse]] +_Middleware = Callable[[Request, _Handler], Awaitable[StreamResponse]] + + def normalize_path_middleware( - *, append_slash=True, remove_slash=False, - merge_slashes=True, redirect_class=HTTPMovedPermanently): + *, append_slash: bool=True, remove_slash: bool=False, + merge_slashes: bool=True, + redirect_class: Type[_HTTPMove]=HTTPMovedPermanently) -> _Middleware: """ Middleware factory which produces a middleware that normalizes the path of a request. By normalizing it means: @@ -64,7 +78,7 @@ def normalize_path_middleware( assert correct_configuration, "Cannot both remove and append slash" @middleware - async def impl(request, handler): + async def impl(request: Request, handler: _Handler) -> StreamResponse: if isinstance(request.match_info.route, SystemRoute): paths_to_check = [] if '?' in request.raw_path: @@ -91,17 +105,17 @@ def normalize_path_middleware( resolves, request = await _check_request_resolves( request, path) if resolves: - raise redirect_class(request.raw_path) + raise redirect_class(request.raw_path + query) return await handler(request) return impl -def _fix_request_current_app(app): +def _fix_request_current_app(app: 'Application') -> _Middleware: @middleware - async def impl(request, handler): + async def impl(request: Request, handler: _Handler) -> StreamResponse: with request.match_info.set_current_app(app): return await handler(request) return impl diff --git a/aiohttp/web_protocol.py b/aiohttp/web_protocol.py index feda1e4..0919f86 100644 --- a/aiohttp/web_protocol.py +++ b/aiohttp/web_protocol.py @@ -5,24 +5,42 @@ import warnings from collections import deque from contextlib import suppress from html import escape as html_escape +from logging import Logger +from typing import (TYPE_CHECKING, Any, Awaitable, Callable, Optional, Type, + cast) import yarl -from . import helpers +from .abc import AbstractAccessLogger, AbstractStreamWriter from .base_protocol import BaseProtocol -from .helpers import CeilTimeout +from .helpers import CeilTimeout, current_task from .http import (HttpProcessingError, HttpRequestParser, HttpVersion10, RawRequestMessage, StreamWriter) from .log import access_logger, server_logger -from .streams import EMPTY_PAYLOAD -from .tcp_helpers import tcp_cork, tcp_keepalive, tcp_nodelay +from .streams import EMPTY_PAYLOAD, StreamReader +from .tcp_helpers import tcp_keepalive from .web_exceptions import HTTPException +from .web_log import AccessLogger from .web_request import BaseRequest -from .web_response import Response +from .web_response import Response, StreamResponse __all__ = ('RequestHandler', 'RequestPayloadError', 'PayloadAccessError') +if TYPE_CHECKING: # pragma: no cover + from .web_server import Server # noqa + + +_RequestFactory = Callable[[RawRequestMessage, + StreamReader, + 'RequestHandler', + AbstractStreamWriter, + 'asyncio.Task[None]'], + BaseRequest] + +_RequestHandler = Callable[[BaseRequest], Awaitable[StreamResponse]] + + ERROR = RawRequestMessage( 'UNKNOWN', '/', HttpVersion10, {}, {}, True, False, False, False, yarl.URL('/')) @@ -33,7 +51,7 @@ class RequestPayloadError(Exception): class PayloadAccessError(Exception): - """Payload was accesed after responce was sent.""" + """Payload was accessed after response was sent.""" class RequestHandler(BaseProtocol): @@ -86,73 +104,73 @@ class RequestHandler(BaseProtocol): '_reading_paused', 'logger', 'debug', 'access_log', 'access_logger', '_close', '_force_close') - def __init__(self, manager, *, loop=None, - keepalive_timeout=75, # NGINX default value is 75 secs - tcp_keepalive=True, - logger=server_logger, - access_log_class=helpers.AccessLogger, - access_log=access_logger, - access_log_format=helpers.AccessLogger.LOG_FORMAT, - debug=False, - max_line_size=8190, - max_headers=32768, - max_field_size=8190, - lingering_time=10.0): - - super().__init__(loop=loop) + def __init__(self, manager: 'Server', *, + loop: asyncio.AbstractEventLoop, + keepalive_timeout: float=75., # NGINX default is 75 secs + tcp_keepalive: bool=True, + logger: Logger=server_logger, + access_log_class: Type[AbstractAccessLogger]=AccessLogger, + access_log: Logger=access_logger, + access_log_format: str=AccessLogger.LOG_FORMAT, + debug: bool=False, + max_line_size: int=8190, + max_headers: int=32768, + max_field_size: int=8190, + lingering_time: float=10.0): + + super().__init__(loop) self._request_count = 0 self._keepalive = False - self._manager = manager - self._request_handler = manager.request_handler - self._request_factory = manager.request_factory + self._manager = manager # type: Optional[Server] + self._request_handler = manager.request_handler # type: Optional[_RequestHandler] # noqa + self._request_factory = manager.request_factory # type: Optional[_RequestFactory] # noqa self._tcp_keepalive = tcp_keepalive - self._keepalive_time = None - self._keepalive_handle = None + # placeholder to be replaced on keepalive timeout setup + self._keepalive_time = 0.0 + self._keepalive_handle = None # type: Optional[asyncio.Handle] self._keepalive_timeout = keepalive_timeout self._lingering_time = float(lingering_time) - self._messages = deque() + self._messages = deque() # type: Any # Python 3.5 has no typing.Deque self._message_tail = b'' - self._waiter = None - self._error_handler = None - self._task_handler = None + self._waiter = None # type: Optional[asyncio.Future[None]] + self._error_handler = None # type: Optional[asyncio.Task[None]] + self._task_handler = None # type: Optional[asyncio.Task[None]] self._upgrade = False - self._payload_parser = None + self._payload_parser = None # type: Any self._request_parser = HttpRequestParser( self, loop, max_line_size=max_line_size, max_field_size=max_field_size, max_headers=max_headers, - payload_exception=RequestPayloadError) - - self._reading_paused = False + payload_exception=RequestPayloadError) # type: Optional[HttpRequestParser] # noqa self.logger = logger self.debug = debug self.access_log = access_log if access_log: self.access_logger = access_log_class( - access_log, access_log_format) + access_log, access_log_format) # type: Optional[AbstractAccessLogger] # noqa else: self.access_logger = None self._close = False self._force_close = False - def __repr__(self): + def __repr__(self) -> str: return "<{} {}>".format( self.__class__.__name__, 'connected' if self.transport is not None else 'disconnected') @property - def keepalive_timeout(self): + def keepalive_timeout(self) -> float: return self._keepalive_timeout - async def shutdown(self, timeout=15.0): + async def shutdown(self, timeout: Optional[float]=15.0) -> None: """Worker process is about to exit, we need cleanup everything and stop accepting requests. It is especially important for keep-alive connections.""" @@ -183,18 +201,20 @@ class RequestHandler(BaseProtocol): self.transport.close() self.transport = None - def connection_made(self, transport): + def connection_made(self, transport: asyncio.BaseTransport) -> None: super().connection_made(transport) + real_transport = cast(asyncio.Transport, transport) if self._tcp_keepalive: - tcp_keepalive(transport) + tcp_keepalive(real_transport) - tcp_cork(transport, False) - tcp_nodelay(transport, True) self._task_handler = self._loop.create_task(self.start()) - self._manager.connection_made(self, transport) + assert self._manager is not None + self._manager.connection_made(self, real_transport) - def connection_lost(self, exc): + def connection_lost(self, exc: Optional[BaseException]) -> None: + if self._manager is None: + return self._manager.connection_lost(self, exc) super().connection_lost(exc) @@ -220,7 +240,8 @@ class RequestHandler(BaseProtocol): self._payload_parser.feed_eof() self._payload_parser = None - def set_parser(self, parser): + def set_parser(self, parser: Any) -> None: + # Actual type is WebReader assert self._payload_parser is None self._payload_parser = parser @@ -229,15 +250,15 @@ class RequestHandler(BaseProtocol): self._payload_parser.feed_data(self._message_tail) self._message_tail = b'' - def eof_received(self): + def eof_received(self) -> None: pass - def data_received(self, data): + def data_received(self, data: bytes) -> None: if self._force_close or self._close: return - # parse http messages if self._payload_parser is None and not self._upgrade: + assert self._request_parser is not None try: messages, upgraded, tail = self._request_parser.feed_data(data) except HttpProcessingError as exc: @@ -281,7 +302,7 @@ class RequestHandler(BaseProtocol): if eof: self.close() - def keep_alive(self, val): + def keep_alive(self, val: bool) -> None: """Set keep-alive connection mode. :param bool val: new state. @@ -291,14 +312,14 @@ class RequestHandler(BaseProtocol): self._keepalive_handle.cancel() self._keepalive_handle = None - def close(self): + def close(self) -> None: """Stop accepting new pipelinig messages and close connection when handlers done processing messages""" self._close = True if self._waiter: self._waiter.cancel() - def force_close(self): + def force_close(self) -> None: """Force close connection""" self._force_close = True if self._waiter: @@ -307,18 +328,21 @@ class RequestHandler(BaseProtocol): self.transport.close() self.transport = None - def log_access(self, request, response, time): + def log_access(self, + request: BaseRequest, + response: StreamResponse, + time: float) -> None: if self.access_logger is not None: self.access_logger.log(request, response, time) - def log_debug(self, *args, **kw): + def log_debug(self, *args: Any, **kw: Any) -> None: if self.debug: self.logger.debug(*args, **kw) - def log_exception(self, *args, **kw): + def log_exception(self, *args: Any, **kw: Any) -> None: self.logger.exception(*args, **kw) - def _process_keepalive(self): + def _process_keepalive(self) -> None: if self._force_close or not self._keepalive: return @@ -335,23 +359,7 @@ class RequestHandler(BaseProtocol): self._keepalive_handle = self._loop.call_later( self.KEEPALIVE_RESCHEDULE_DELAY, self._process_keepalive) - def pause_reading(self): - if not self._reading_paused: - try: - self.transport.pause_reading() - except (AttributeError, NotImplementedError, RuntimeError): - pass - self._reading_paused = True - - def resume_reading(self): - if self._reading_paused: - try: - self.transport.resume_reading() - except (AttributeError, NotImplementedError, RuntimeError): - pass - self._reading_paused = False - - async def start(self): + async def start(self) -> None: """Process incoming request. It reads request line, request headers and request payload, then @@ -362,8 +370,13 @@ class RequestHandler(BaseProtocol): """ loop = self._loop handler = self._task_handler + assert handler is not None manager = self._manager + assert manager is not None keepalive_timeout = self._keepalive_timeout + resp = None + assert self._request_factory is not None + assert self._request_handler is not None while not self._force_close: if not self._messages: @@ -387,14 +400,17 @@ class RequestHandler(BaseProtocol): message, payload, self, writer, handler) try: try: - resp = await self._request_handler(request) + # a new task is used for copy context vars (#3406) + task = self._loop.create_task( + self._request_handler(request)) + resp = await task except HTTPException as exc: resp = exc except asyncio.CancelledError: self.log_debug('Ignored premature client disconnection') break - except asyncio.TimeoutError: - self.log_debug('Request handler timed out.') + except asyncio.TimeoutError as exc: + self.log_debug('Request handler timed out.', exc_info=exc) resp = self.handle_error(request, 504) except Exception as exc: resp = self.handle_error(request, 500, exc) @@ -407,11 +423,20 @@ class RequestHandler(BaseProtocol): "please raise the exception instead", DeprecationWarning) + if self.debug: + if not isinstance(resp, StreamResponse): + if resp is None: + raise RuntimeError("Missing return " + "statement on request handler") + else: + raise RuntimeError("Web-handler should return " + "a response instance, " + "got {!r}".format(resp)) await resp.prepare(request) await resp.write_eof() # notify server about keep-alive - self._keepalive = resp.keep_alive + self._keepalive = bool(resp.keep_alive) # log access if self.access_log: @@ -431,8 +456,7 @@ class RequestHandler(BaseProtocol): with suppress( asyncio.TimeoutError, asyncio.CancelledError): while not payload.is_eof() and now < end_t: - timeout = min(end_t - now, lingering_time) - with CeilTimeout(timeout, loop=loop): + with CeilTimeout(end_t - now, loop=loop): # read and ignore await payload.readany() now = loop.time() @@ -456,7 +480,7 @@ class RequestHandler(BaseProtocol): self.log_exception('Unhandled exception', exc_info=exc) self.force_close() finally: - if self.transport is None: + if self.transport is None and resp is not None: self.log_debug('Ignored premature client disconnection.') elif not self._force_close: if self._keepalive and not self._close: @@ -477,7 +501,11 @@ class RequestHandler(BaseProtocol): if self.transport is not None and self._error_handler is None: self.transport.close() - def handle_error(self, request, status=500, exc=None, message=None): + def handle_error(self, + request: BaseRequest, + status: int=500, + exc: Optional[BaseException]=None, + message: Optional[str]=None) -> StreamResponse: """Handle errors. Returns HTTP response with specific status code. Logs additional @@ -497,10 +525,11 @@ class RequestHandler(BaseProtocol): msg += "Server got itself in trouble" msg = ("<html><head><title>500 Internal Server Error</title>" "</head><body>" + msg + "</body></html>") + resp = Response(status=status, text=msg, content_type='text/html') else: - msg = message + resp = Response(status=status, text=message, + content_type='text/html') - resp = Response(status=status, text=msg, content_type='text/html') resp.force_close() # some data already got sent, connection is broken @@ -509,10 +538,17 @@ class RequestHandler(BaseProtocol): return resp - async def handle_parse_error(self, writer, status, exc=None, message=None): - request = BaseRequest( - ERROR, EMPTY_PAYLOAD, - self, writer, None, self._loop) + async def handle_parse_error(self, + writer: AbstractStreamWriter, + status: int, + exc: Optional[BaseException]=None, + message: Optional[str]=None) -> None: + request = BaseRequest( # type: ignore + ERROR, + EMPTY_PAYLOAD, + self, writer, + current_task(), + self._loop) resp = self.handle_error(request, status, exc, message) await resp.prepare(request) diff --git a/aiohttp/web_request.py b/aiohttp/web_request.py index 2b1c337..150138c 100644 --- a/aiohttp/web_request.py +++ b/aiohttp/web_request.py @@ -1,5 +1,4 @@ import asyncio -import collections import datetime import io import re @@ -11,7 +10,8 @@ import warnings from email.utils import parsedate from http.cookies import SimpleCookie from types import MappingProxyType -from typing import Any, Dict, Mapping, Optional, Tuple, cast # noqa +from typing import (TYPE_CHECKING, Any, Dict, Iterator, Mapping, # noqa + MutableMapping, Optional, Tuple, Union, cast) from urllib.parse import parse_qsl import attr @@ -19,25 +19,33 @@ from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy from yarl import URL from . import hdrs +from .abc import AbstractStreamWriter from .helpers import DEBUG, ChainMapProxy, HeadersMixin, reify, sentinel +from .http_parser import RawRequestMessage from .multipart import MultipartReader from .streams import EmptyStreamReader, StreamReader from .typedefs import (DEFAULT_JSON_DECODER, JSONDecoder, LooseHeaders, RawHeaders, StrOrURL) from .web_exceptions import HTTPRequestEntityTooLarge -from .web_urldispatcher import UrlMappingMatchInfo +from .web_response import StreamResponse __all__ = ('BaseRequest', 'FileField', 'Request') +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application # noqa + from .web_urldispatcher import UrlMappingMatchInfo # noqa + from .web_protocol import RequestHandler # noqa + + @attr.s(frozen=True, slots=True) class FileField: name = attr.ib(type=str) filename = attr.ib(type=str) file = attr.ib(type=io.BufferedReader) content_type = attr.ib(type=str) - headers = attr.ib(type=CIMultiDictProxy) + headers = attr.ib(type=CIMultiDictProxy) # type: CIMultiDictProxy[str] _TCHAR = string.digits + string.ascii_letters + r"!#$%&'*+.^_`|~-" @@ -70,7 +78,7 @@ _FORWARDED_PAIR_RE = re.compile(_FORWARDED_PAIR) ############################################################ -class BaseRequest(collections.MutableMapping, HeadersMixin): +class BaseRequest(MutableMapping[str, Any], HeadersMixin): POST_METHODS = {hdrs.METH_PATCH, hdrs.METH_POST, hdrs.METH_PUT, hdrs.METH_TRACE, hdrs.METH_DELETE} @@ -78,13 +86,19 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): ATTRS = HeadersMixin.ATTRS | frozenset([ '_message', '_protocol', '_payload_writer', '_payload', '_headers', '_method', '_version', '_rel_url', '_post', '_read_bytes', - '_state', '_cache', '_task', '_client_max_size', '_loop']) - - def __init__(self, message, payload, protocol, payload_writer, task, - loop, - *, client_max_size=1024**2, - state=None, - scheme=None, host=None, remote=None): + '_state', '_cache', '_task', '_client_max_size', '_loop', + '_transport_sslcontext', '_transport_peername']) + + def __init__(self, message: RawRequestMessage, + payload: StreamReader, protocol: 'RequestHandler', + payload_writer: AbstractStreamWriter, + task: 'asyncio.Task[None]', + loop: asyncio.AbstractEventLoop, + *, client_max_size: int=1024**2, + state: Optional[Dict[str, Any]]=None, + scheme: Optional[str]=None, + host: Optional[str]=None, + remote: Optional[str]=None) -> None: if state is None: state = {} self._message = message @@ -96,15 +110,20 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): self._method = message.method self._version = message.version self._rel_url = message.url - self._post = None - self._read_bytes = None + self._post = None # type: Optional[MultiDictProxy[Union[str, bytes, FileField]]] # noqa + self._read_bytes = None # type: Optional[bytes] self._state = state - self._cache = {} + self._cache = {} # type: Dict[str, Any] self._task = task self._client_max_size = client_max_size self._loop = loop + transport = self._protocol.transport + assert transport is not None + self._transport_sslcontext = transport.get_extra_info('sslcontext') + self._transport_peername = transport.get_extra_info('peername') + if scheme is not None: self._cache['scheme'] = scheme if host is not None: @@ -126,7 +145,7 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): if self._read_bytes: raise RuntimeError("Cannot clone request " - "after reading it's content") + "after reading its content") dct = {} # type: Dict[str, Any] if method is not sentinel: @@ -163,25 +182,25 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): **kwargs) @property - def task(self): + def task(self) -> 'asyncio.Task[None]': return self._task @property - def protocol(self): + def protocol(self) -> 'RequestHandler': return self._protocol @property - def transport(self): + def transport(self) -> Optional[asyncio.Transport]: if self._protocol is None: return None return self._protocol.transport @property - def writer(self): + def writer(self) -> AbstractStreamWriter: return self._payload_writer @reify - def message(self): + def message(self) -> RawRequestMessage: warnings.warn("Request.message is deprecated", DeprecationWarning, stacklevel=3) @@ -193,23 +212,26 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): @reify def loop(self) -> asyncio.AbstractEventLoop: + warnings.warn("request.loop property is deprecated", + DeprecationWarning, + stacklevel=2) return self._loop # MutableMapping API - def __getitem__(self, key): + def __getitem__(self, key: str) -> Any: return self._state[key] - def __setitem__(self, key, value): + def __setitem__(self, key: str, value: Any) -> None: self._state[key] = value - def __delitem__(self, key): + def __delitem__(self, key: str) -> None: del self._state[key] - def __len__(self): + def __len__(self) -> int: return len(self._state) - def __iter__(self): + def __iter__(self) -> Iterator[str]: return iter(self._state) ######## @@ -220,7 +242,7 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): return self.scheme == 'https' @reify - def forwarded(self): + def forwarded(self) -> Tuple[Mapping[str, str], ...]: """A tuple containing all parsed Forwarded header(s). Makes an effort to parse Forwarded headers as specified by RFC 7239: @@ -244,7 +266,7 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): length = len(field_value) pos = 0 need_separator = False - elem = {} + elem = {} # type: Dict[str, str] elems.append(types.MappingProxyType(elem)) while 0 <= pos < length: match = _FORWARDED_PAIR_RE.match(field_value, pos) @@ -292,7 +314,7 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): 'http' or 'https'. """ - if self.transport.get_extra_info('sslcontext'): + if self._transport_sslcontext: return 'https' else: return 'http' @@ -338,13 +360,10 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): - overridden value by .clone(remote=new_remote) call. - peername of opened socket """ - if self.transport is None: - return None - peername = self.transport.get_extra_info('peername') - if isinstance(peername, (list, tuple)): - return peername[0] + if isinstance(self._transport_peername, (list, tuple)): + return self._transport_peername[0] else: - return peername + return self._transport_peername @reify def url(self) -> URL: @@ -377,7 +396,7 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): return self._message.path @reify - def query(self) -> MultiDict: + def query(self) -> 'MultiDictProxy[str]': """A multidict with all the variables in the query string.""" return self._rel_url.query @@ -390,7 +409,7 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): return self._rel_url.query_string @reify - def headers(self) -> CIMultiDictProxy: + def headers(self) -> 'CIMultiDictProxy[str]': """A case-insensitive multidict proxy with all headers.""" return self._headers @@ -400,7 +419,7 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): return self._message.raw_headers @staticmethod - def _http_date(_date_str) -> Optional[datetime.datetime]: + def _http_date(_date_str: str) -> Optional[datetime.datetime]: """Process a date string, return a datetime object """ if _date_str is not None: @@ -446,12 +465,12 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): A read-only dictionary-like object. """ raw = self.headers.get(hdrs.COOKIE, '') - parsed = SimpleCookie(raw) # type: ignore + parsed = SimpleCookie(raw) return MappingProxyType( {key: val.value for key, val in parsed.items()}) @reify - def http_range(self): + def http_range(self) -> slice: """The content of Range HTTP header. Return a slice instance. @@ -554,7 +573,7 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): """Return async iterator to process BODY as multipart.""" return MultipartReader(self._headers, self._payload) - async def post(self) -> MultiDictProxy: + async def post(self) -> 'MultiDictProxy[Union[str, bytes, FileField]]': """Return POST parameters.""" if self._post is not None: return self._post @@ -569,7 +588,7 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): self._post = MultiDictProxy(MultiDict()) return self._post - out = MultiDict() # type: MultiDict + out = MultiDict() # type: MultiDict[Union[str, bytes, FileField]] if content_type == 'multipart/form-data': multipart = await self.multipart() @@ -628,26 +647,24 @@ class BaseRequest(collections.MutableMapping, HeadersMixin): self._post = MultiDictProxy(out) return self._post - def __repr__(self): + def __repr__(self) -> str: ascii_encodable_path = self.path.encode('ascii', 'backslashreplace') \ .decode('ascii') return "<{} {} {} >".format(self.__class__.__name__, self._method, ascii_encodable_path) - def __eq__(self, other): + def __eq__(self, other: object) -> bool: return id(self) == id(other) - @asyncio.coroutine - def _prepare_hook(self, response): + async def _prepare_hook(self, response: StreamResponse) -> None: return - yield # pragma: no cover class Request(BaseRequest): ATTRS = BaseRequest.ATTRS | frozenset(['_match_info']) - def __init__(self, *args, **kwargs) -> None: + def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) # matchdict, route_name, handler @@ -657,7 +674,7 @@ class Request(BaseRequest): self._match_info = None # type: Optional[UrlMappingMatchInfo] if DEBUG: - def __setattr__(self, name, val): + def __setattr__(self, name: str, val: Any) -> None: if name not in self.ATTRS: warnings.warn("Setting custom {}.{} attribute " "is discouraged".format(self.__class__.__name__, @@ -681,30 +698,30 @@ class Request(BaseRequest): return new_ret @reify - def match_info(self) -> Optional[UrlMappingMatchInfo]: + def match_info(self) -> 'UrlMappingMatchInfo': """Result of route resolving.""" - return self._match_info + match_info = self._match_info + assert match_info is not None + return match_info @property - def app(self): + def app(self) -> 'Application': """Application instance.""" match_info = self._match_info - if match_info is None: - return None + assert match_info is not None return match_info.current_app @property def config_dict(self) -> ChainMapProxy: match_info = self._match_info - if match_info is None: - return ChainMapProxy([]) + assert match_info is not None lst = match_info.apps app = self.app idx = lst.index(app) sublist = list(reversed(lst[:idx + 1])) return ChainMapProxy(sublist) - async def _prepare_hook(self, response): + async def _prepare_hook(self, response: StreamResponse) -> None: match_info = self._match_info if match_info is None: return diff --git a/aiohttp/web_response.py b/aiohttp/web_response.py index 89835c6..7ff52c6 100644 --- a/aiohttp/web_response.py +++ b/aiohttp/web_response.py @@ -1,4 +1,5 @@ -import collections +import asyncio # noqa +import collections # noqa import datetime import enum import json @@ -6,19 +7,32 @@ import math import time import warnings import zlib +from concurrent.futures import Executor from email.utils import parsedate from http.cookies import SimpleCookie +from typing import (TYPE_CHECKING, Any, Dict, Iterator, Mapping, # noqa + MutableMapping, Optional, Tuple, Union, cast) -from multidict import CIMultiDict, CIMultiDictProxy +from multidict import CIMultiDict, istr from . import hdrs, payload +from .abc import AbstractStreamWriter from .helpers import HeadersMixin, rfc822_formatted_time, sentinel from .http import RESPONSES, SERVER_SOFTWARE, HttpVersion10, HttpVersion11 +from .payload import Payload +from .typedefs import JSONEncoder, LooseHeaders __all__ = ('ContentCoding', 'StreamResponse', 'Response', 'json_response') +if TYPE_CHECKING: # pragma: no cover + from .web_request import BaseRequest # noqa + BaseClass = MutableMapping[str, Any] +else: + BaseClass = collections.MutableMapping + + class ContentCoding(enum.Enum): # The content codings that we have support for. # @@ -34,56 +48,62 @@ class ContentCoding(enum.Enum): ############################################################ -class StreamResponse(collections.MutableMapping, HeadersMixin): +class StreamResponse(BaseClass, HeadersMixin): _length_check = True - def __init__(self, *, status=200, reason=None, headers=None): + def __init__(self, *, + status: int=200, + reason: Optional[str]=None, + headers: Optional[LooseHeaders]=None) -> None: self._body = None - self._keep_alive = None + self._keep_alive = None # type: Optional[bool] self._chunked = False self._compression = False - self._compression_force = None + self._compression_force = None # type: Optional[ContentCoding] self._cookies = SimpleCookie() - self._req = None - self._payload_writer = None + self._req = None # type: Optional[BaseRequest] + self._payload_writer = None # type: Optional[AbstractStreamWriter] self._eof_sent = False self._body_length = 0 - self._state = {} + self._state = {} # type: Dict[str, Any] if headers is not None: - self._headers = CIMultiDict(headers) + self._headers = CIMultiDict(headers) # type: CIMultiDict[str] else: - self._headers = CIMultiDict() + self._headers = CIMultiDict() # type: CIMultiDict[str] self.set_status(status, reason) @property - def prepared(self): + def prepared(self) -> bool: return self._payload_writer is not None @property - def task(self): + def task(self) -> 'asyncio.Task[None]': return getattr(self._req, 'task', None) @property - def status(self): + def status(self) -> int: return self._status @property - def chunked(self): + def chunked(self) -> bool: return self._chunked @property - def compression(self): + def compression(self) -> bool: return self._compression @property - def reason(self): + def reason(self) -> str: return self._reason - def set_status(self, status, reason=None, _RESPONSES=RESPONSES): + def set_status(self, status: int, + reason: Optional[str]=None, + _RESPONSES: Mapping[int, + Tuple[str, str]]=RESPONSES) -> None: assert not self.prepared, \ 'Cannot change the response status code after ' \ 'the headers have been sent' @@ -96,22 +116,23 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): self._reason = reason @property - def keep_alive(self): + def keep_alive(self) -> Optional[bool]: return self._keep_alive - def force_close(self): + def force_close(self) -> None: self._keep_alive = False @property - def body_length(self): + def body_length(self) -> int: return self._body_length @property - def output_length(self): + def output_length(self) -> int: warnings.warn('output_length is deprecated', DeprecationWarning) + assert self._payload_writer return self._payload_writer.buffer_size - def enable_chunked_encoding(self, chunk_size=None): + def enable_chunked_encoding(self, chunk_size: Optional[int]=None) -> None: """Enables automatic chunked transfer encoding.""" self._chunked = True @@ -121,11 +142,15 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): if chunk_size is not None: warnings.warn('Chunk size is deprecated #1615', DeprecationWarning) - def enable_compression(self, force=None): + def enable_compression(self, + force: Optional[Union[bool, ContentCoding]]=None + ) -> None: """Enables response compression encoding.""" # Backwards compatibility for when force was a bool <0.17. if type(force) == bool: force = ContentCoding.deflate if force else ContentCoding.identity + warnings.warn("Using boolean for force is deprecated #3318", + DeprecationWarning) elif force is not None: assert isinstance(force, ContentCoding), ("force should one of " "None, bool or " @@ -135,16 +160,21 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): self._compression_force = force @property - def headers(self): + def headers(self) -> 'CIMultiDict[str]': return self._headers @property - def cookies(self): + def cookies(self) -> SimpleCookie: return self._cookies - def set_cookie(self, name, value, *, expires=None, - domain=None, max_age=None, path='/', - secure=None, httponly=None, version=None): + def set_cookie(self, name: str, value: str, *, + expires: Optional[str]=None, + domain: Optional[str]=None, + max_age: Optional[Union[int, str]]=None, + path: str='/', + secure: Optional[str]=None, + httponly: Optional[str]=None, + version: Optional[str]=None) -> None: """Set or update response cookie. Sets new cookie or updates existent with new value. @@ -168,7 +198,7 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): c['domain'] = domain if max_age is not None: - c['max-age'] = max_age + c['max-age'] = str(max_age) elif 'max-age' in c: del c['max-age'] @@ -181,7 +211,9 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): if version is not None: c['version'] = version - def del_cookie(self, name, *, domain=None, path='/'): + def del_cookie(self, name: str, *, + domain: Optional[str]=None, + path: str='/') -> None: """Delete cookie. Creates new empty expired cookie. @@ -193,12 +225,12 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): domain=domain, path=path) @property - def content_length(self): + def content_length(self) -> Optional[int]: # Just a placeholder for adding setter return super().content_length @content_length.setter - def content_length(self, value): + def content_length(self, value: Optional[int]) -> None: if value is not None: value = int(value) if self._chunked: @@ -209,27 +241,28 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): self._headers.pop(hdrs.CONTENT_LENGTH, None) @property - def content_type(self): + def content_type(self) -> str: # Just a placeholder for adding setter return super().content_type @content_type.setter - def content_type(self, value): + def content_type(self, value: str) -> None: self.content_type # read header values if needed self._content_type = str(value) self._generate_content_type_header() @property - def charset(self): + def charset(self) -> Optional[str]: # Just a placeholder for adding setter return super().charset @charset.setter - def charset(self, value): + def charset(self, value: Optional[str]) -> None: ctype = self.content_type # read header values if needed if ctype == 'application/octet-stream': raise RuntimeError("Setting charset for application/octet-stream " "doesn't make sense, setup content_type first") + assert self._content_dict is not None if value is None: self._content_dict.pop('charset', None) else: @@ -237,12 +270,12 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): self._generate_content_type_header() @property - def last_modified(self): + def last_modified(self) -> Optional[datetime.datetime]: """The value of Last-Modified HTTP header, or None. This header is represented as a `datetime` object. """ - httpdate = self.headers.get(hdrs.LAST_MODIFIED) + httpdate = self._headers.get(hdrs.LAST_MODIFIED) if httpdate is not None: timetuple = parsedate(httpdate) if timetuple is not None: @@ -251,65 +284,66 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): return None @last_modified.setter - def last_modified(self, value): + def last_modified(self, + value: Optional[ + Union[int, float, datetime.datetime, str]]) -> None: if value is None: - self.headers.pop(hdrs.LAST_MODIFIED, None) + self._headers.pop(hdrs.LAST_MODIFIED, None) elif isinstance(value, (int, float)): - self.headers[hdrs.LAST_MODIFIED] = time.strftime( + self._headers[hdrs.LAST_MODIFIED] = time.strftime( "%a, %d %b %Y %H:%M:%S GMT", time.gmtime(math.ceil(value))) elif isinstance(value, datetime.datetime): - self.headers[hdrs.LAST_MODIFIED] = time.strftime( + self._headers[hdrs.LAST_MODIFIED] = time.strftime( "%a, %d %b %Y %H:%M:%S GMT", value.utctimetuple()) elif isinstance(value, str): - self.headers[hdrs.LAST_MODIFIED] = value - - def _generate_content_type_header(self, CONTENT_TYPE=hdrs.CONTENT_TYPE): - params = '; '.join("%s=%s" % i for i in self._content_dict.items()) + self._headers[hdrs.LAST_MODIFIED] = value + + def _generate_content_type_header( + self, + CONTENT_TYPE: istr=hdrs.CONTENT_TYPE) -> None: + assert self._content_dict is not None + assert self._content_type is not None + params = '; '.join("{}={}".format(k, v) + for k, v in self._content_dict.items()) if params: ctype = self._content_type + '; ' + params else: ctype = self._content_type - self.headers[CONTENT_TYPE] = ctype + self._headers[CONTENT_TYPE] = ctype - def _do_start_compression(self, coding): + async def _do_start_compression(self, coding: ContentCoding) -> None: if coding != ContentCoding.identity: - self.headers[hdrs.CONTENT_ENCODING] = coding.value + assert self._payload_writer is not None + self._headers[hdrs.CONTENT_ENCODING] = coding.value self._payload_writer.enable_compression(coding.value) # Compressed payload may have different content length, # remove the header self._headers.popall(hdrs.CONTENT_LENGTH, None) - def _start_compression(self, request): + async def _start_compression(self, request: 'BaseRequest') -> None: if self._compression_force: - self._do_start_compression(self._compression_force) + await self._do_start_compression(self._compression_force) else: accept_encoding = request.headers.get( hdrs.ACCEPT_ENCODING, '').lower() for coding in ContentCoding: if coding.value in accept_encoding: - self._do_start_compression(coding) + await self._do_start_compression(coding) return - async def prepare(self, request): + async def prepare( + self, + request: 'BaseRequest' + ) -> Optional[AbstractStreamWriter]: if self._eof_sent: - return + return None if self._payload_writer is not None: return self._payload_writer await request._prepare_hook(self) return await self._start(request) - async def _start(self, request, - HttpVersion10=HttpVersion10, - HttpVersion11=HttpVersion11, - CONNECTION=hdrs.CONNECTION, - DATE=hdrs.DATE, - SERVER=hdrs.SERVER, - CONTENT_TYPE=hdrs.CONTENT_TYPE, - CONTENT_LENGTH=hdrs.CONTENT_LENGTH, - SET_COOKIE=hdrs.SET_COOKIE, - SERVER_SOFTWARE=SERVER_SOFTWARE, - TRANSFER_ENCODING=hdrs.TRANSFER_ENCODING): + async def _start(self, request: 'BaseRequest') -> AbstractStreamWriter: self._req = request keep_alive = self._keep_alive @@ -323,10 +357,10 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): headers = self._headers for cookie in self._cookies.values(): value = cookie.output(header='')[1:] - headers.add(SET_COOKIE, value) + headers.add(hdrs.SET_COOKIE, value) if self._compression: - self._start_compression(request) + await self._start_compression(request) if self._chunked: if version != HttpVersion11: @@ -334,32 +368,32 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): "Using chunked encoding is forbidden " "for HTTP/{0.major}.{0.minor}".format(request.version)) writer.enable_chunking() - headers[TRANSFER_ENCODING] = 'chunked' - if CONTENT_LENGTH in headers: - del headers[CONTENT_LENGTH] + headers[hdrs.TRANSFER_ENCODING] = 'chunked' + if hdrs.CONTENT_LENGTH in headers: + del headers[hdrs.CONTENT_LENGTH] elif self._length_check: writer.length = self.content_length if writer.length is None: if version >= HttpVersion11: writer.enable_chunking() - headers[TRANSFER_ENCODING] = 'chunked' - if CONTENT_LENGTH in headers: - del headers[CONTENT_LENGTH] + headers[hdrs.TRANSFER_ENCODING] = 'chunked' + if hdrs.CONTENT_LENGTH in headers: + del headers[hdrs.CONTENT_LENGTH] else: keep_alive = False - headers.setdefault(CONTENT_TYPE, 'application/octet-stream') - headers.setdefault(DATE, rfc822_formatted_time()) - headers.setdefault(SERVER, SERVER_SOFTWARE) + headers.setdefault(hdrs.CONTENT_TYPE, 'application/octet-stream') + headers.setdefault(hdrs.DATE, rfc822_formatted_time()) + headers.setdefault(hdrs.SERVER, SERVER_SOFTWARE) # connection header - if CONNECTION not in headers: + if hdrs.CONNECTION not in headers: if keep_alive: if version == HttpVersion10: - headers[CONNECTION] = 'keep-alive' + headers[hdrs.CONNECTION] = 'keep-alive' else: if version == HttpVersion11: - headers[CONNECTION] = 'close' + headers[hdrs.CONNECTION] = 'close' # status line status_line = 'HTTP/{}.{} {} {}'.format( @@ -368,7 +402,7 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): return writer - async def write(self, data): + async def write(self, data: bytes) -> None: assert isinstance(data, (bytes, bytearray, memoryview)), \ "data argument must be byte-ish (%r)" % type(data) @@ -379,7 +413,7 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): await self._payload_writer.write(data) - async def drain(self): + async def drain(self) -> None: assert not self._eof_sent, "EOF has already been sent" assert self._payload_writer is not None, \ "Response has not been started" @@ -388,7 +422,7 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): stacklevel=2) await self._payload_writer.drain() - async def write_eof(self, data=b''): + async def write_eof(self, data: bytes=b'') -> None: assert isinstance(data, (bytes, bytearray, memoryview)), \ "data argument must be byte-ish (%r)" % type(data) @@ -404,57 +438,67 @@ class StreamResponse(collections.MutableMapping, HeadersMixin): self._body_length = self._payload_writer.output_size self._payload_writer = None - def __repr__(self): + def __repr__(self) -> str: if self._eof_sent: info = "eof" elif self.prepared: + assert self._req is not None info = "{} {} ".format(self._req.method, self._req.path) else: info = "not prepared" return "<{} {} {}>".format(self.__class__.__name__, self.reason, info) - def __getitem__(self, key): + def __getitem__(self, key: str) -> Any: return self._state[key] - def __setitem__(self, key, value): + def __setitem__(self, key: str, value: Any) -> None: self._state[key] = value - def __delitem__(self, key): + def __delitem__(self, key: str) -> None: del self._state[key] - def __len__(self): + def __len__(self) -> int: return len(self._state) - def __iter__(self): + def __iter__(self) -> Iterator[str]: return iter(self._state) - def __hash__(self): + def __hash__(self) -> int: return hash(id(self)) - def __eq__(self, other): + def __eq__(self, other: object) -> bool: return self is other class Response(StreamResponse): - def __init__(self, *, body=None, status=200, - reason=None, text=None, headers=None, content_type=None, - charset=None): + def __init__(self, *, + body: Any=None, + status: int=200, + reason: Optional[str]=None, + text: Optional[str]=None, + headers: Optional[LooseHeaders]=None, + content_type: Optional[str]=None, + charset: Optional[str]=None, + zlib_executor_size: Optional[int]=None, + zlib_executor: Executor=None) -> None: if body is not None and text is not None: raise ValueError("body and text are not allowed together") if headers is None: - headers = CIMultiDict() - elif not isinstance(headers, (CIMultiDict, CIMultiDictProxy)): - headers = CIMultiDict(headers) + real_headers = CIMultiDict() # type: CIMultiDict[str] + elif not isinstance(headers, CIMultiDict): + real_headers = CIMultiDict(headers) + else: + real_headers = headers # = cast('CIMultiDict[str]', headers) if content_type is not None and "charset" in content_type: raise ValueError("charset must not be in content_type " "argument") if text is not None: - if hdrs.CONTENT_TYPE in headers: + if hdrs.CONTENT_TYPE in real_headers: if content_type or charset: raise ValueError("passing both Content-Type header and " "content_type or charset params " @@ -468,12 +512,12 @@ class Response(StreamResponse): content_type = 'text/plain' if charset is None: charset = 'utf-8' - headers[hdrs.CONTENT_TYPE] = ( + real_headers[hdrs.CONTENT_TYPE] = ( content_type + '; charset=' + charset) body = text.encode(charset) text = None else: - if hdrs.CONTENT_TYPE in headers: + if hdrs.CONTENT_TYPE in real_headers: if content_type is not None or charset is not None: raise ValueError("passing both Content-Type header and " "content_type or charset params " @@ -482,28 +526,30 @@ class Response(StreamResponse): if content_type is not None: if charset is not None: content_type += '; charset=' + charset - headers[hdrs.CONTENT_TYPE] = content_type + real_headers[hdrs.CONTENT_TYPE] = content_type - super().__init__(status=status, reason=reason, headers=headers) + super().__init__(status=status, reason=reason, headers=real_headers) if text is not None: self.text = text else: self.body = body - self._compressed_body = None + self._compressed_body = None # type: Optional[bytes] + self._zlib_executor_size = zlib_executor_size + self._zlib_executor = zlib_executor @property - def body(self): + def body(self) -> Optional[Union[bytes, Payload]]: return self._body @body.setter - def body(self, body, - CONTENT_TYPE=hdrs.CONTENT_TYPE, - CONTENT_LENGTH=hdrs.CONTENT_LENGTH): + def body(self, body: bytes, + CONTENT_TYPE: istr=hdrs.CONTENT_TYPE, + CONTENT_LENGTH: istr=hdrs.CONTENT_LENGTH) -> None: if body is None: - self._body = None - self._body_payload = False + self._body = None # type: Optional[bytes] + self._body_payload = False # type: bool elif isinstance(body, (bytes, bytearray)): self._body = body self._body_payload = False @@ -536,13 +582,13 @@ class Response(StreamResponse): self._compressed_body = None @property - def text(self): + def text(self) -> Optional[str]: if self._body is None: return None return self._body.decode(self.charset or 'utf-8') @text.setter - def text(self, text): + def text(self, text: str) -> None: assert text is None or isinstance(text, str), \ "text argument must be str (%r)" % type(text) @@ -556,11 +602,11 @@ class Response(StreamResponse): self._compressed_body = None @property - def content_length(self): + def content_length(self) -> Optional[int]: if self._chunked: return None - if hdrs.CONTENT_LENGTH in self.headers: + if hdrs.CONTENT_LENGTH in self._headers: return super().content_length if self._compressed_body is not None: @@ -575,29 +621,33 @@ class Response(StreamResponse): return 0 @content_length.setter - def content_length(self, value): + def content_length(self, value: Optional[int]) -> None: raise RuntimeError("Content length is set automatically") - async def write_eof(self): + async def write_eof(self, data: bytes=b'') -> None: if self._eof_sent: return - if self._compressed_body is not None: - body = self._compressed_body + if self._compressed_body is None: + body = self._body # type: Optional[Union[bytes, Payload]] else: - body = self._body + body = self._compressed_body + assert not data, "data arg is not supported, got {!r}".format(data) + assert self._req is not None + assert self._payload_writer is not None if body is not None: if (self._req._method == hdrs.METH_HEAD or self._status in [204, 304]): await super().write_eof() elif self._body_payload: - await body.write(self._payload_writer) + payload = cast(Payload, body) + await payload.write(self._payload_writer) await super().write_eof() else: - await super().write_eof(body) + await super().write_eof(cast(bytes, body)) else: await super().write_eof() - async def _start(self, request): + async def _start(self, request: 'BaseRequest') -> AbstractStreamWriter: if not self._chunked and hdrs.CONTENT_LENGTH not in self._headers: if not self._body_payload: if self._body is not None: @@ -607,25 +657,46 @@ class Response(StreamResponse): return await super()._start(request) - def _do_start_compression(self, coding): + def _compress_body(self, zlib_mode: int) -> None: + compressobj = zlib.compressobj(wbits=zlib_mode) + body_in = self._body + assert body_in is not None + self._compressed_body = \ + compressobj.compress(body_in) + compressobj.flush() + + async def _do_start_compression(self, coding: ContentCoding) -> None: if self._body_payload or self._chunked: - return super()._do_start_compression(coding) + return await super()._do_start_compression(coding) + if coding != ContentCoding.identity: # Instead of using _payload_writer.enable_compression, # compress the whole body zlib_mode = (16 + zlib.MAX_WBITS - if coding.value == 'gzip' else -zlib.MAX_WBITS) - compressobj = zlib.compressobj(wbits=zlib_mode) - self._compressed_body = compressobj.compress(self._body) +\ - compressobj.flush() + if coding == ContentCoding.gzip else -zlib.MAX_WBITS) + body_in = self._body + assert body_in is not None + if self._zlib_executor_size is not None and \ + len(body_in) > self._zlib_executor_size: + await asyncio.get_event_loop().run_in_executor( + self._zlib_executor, self._compress_body, zlib_mode) + else: + self._compress_body(zlib_mode) + + body_out = self._compressed_body + assert body_out is not None + self._headers[hdrs.CONTENT_ENCODING] = coding.value - self._headers[hdrs.CONTENT_LENGTH] = \ - str(len(self._compressed_body)) + self._headers[hdrs.CONTENT_LENGTH] = str(len(body_out)) -def json_response(data=sentinel, *, text=None, body=None, status=200, - reason=None, headers=None, content_type='application/json', - dumps=json.dumps): +def json_response(data: Any=sentinel, *, + text: str=None, + body: bytes=None, + status: int=200, + reason: Optional[str]=None, + headers: LooseHeaders=None, + content_type: str='application/json', + dumps: JSONEncoder=json.dumps) -> Response: if data is not sentinel: if text or body: raise ValueError( diff --git a/aiohttp/web_routedef.py b/aiohttp/web_routedef.py index cbaef72..eadf464 100644 --- a/aiohttp/web_routedef.py +++ b/aiohttp/web_routedef.py @@ -1,9 +1,21 @@ import abc -from collections.abc import Sequence +import os # noqa +from typing import (TYPE_CHECKING, Any, Awaitable, Callable, Dict, Iterator, + List, Optional, Sequence, Union, overload) import attr from . import hdrs +from .abc import AbstractView +from .typedefs import PathLike + + +if TYPE_CHECKING: # pragma: no cover + from .web_urldispatcher import UrlDispatcher + from .web_request import Request + from .web_response import StreamResponse +else: + Request = StreamResponse = UrlDispatcher = None __all__ = ('AbstractRouteDef', 'RouteDef', 'StaticDef', 'RouteTableDef', @@ -13,18 +25,22 @@ __all__ = ('AbstractRouteDef', 'RouteDef', 'StaticDef', 'RouteTableDef', class AbstractRouteDef(abc.ABC): @abc.abstractmethod - def register(self, router): + def register(self, router: UrlDispatcher) -> None: pass # pragma: no cover +_SimpleHandler = Callable[[Request], Awaitable[StreamResponse]] +_HandlerType = Union[AbstractView, _SimpleHandler] + + @attr.s(frozen=True, repr=False, slots=True) class RouteDef(AbstractRouteDef): method = attr.ib(type=str) path = attr.ib(type=str) - handler = attr.ib() - kwargs = attr.ib() + handler = attr.ib() # type: _HandlerType + kwargs = attr.ib(type=Dict[str, Any]) - def __repr__(self): + def __repr__(self) -> str: info = [] for name, value in sorted(self.kwargs.items()): info.append(", {}={!r}".format(name, value)) @@ -32,7 +48,7 @@ class RouteDef(AbstractRouteDef): "{info}>".format(method=self.method, path=self.path, handler=self.handler, info=''.join(info))) - def register(self, router): + def register(self, router: UrlDispatcher) -> None: if self.method in hdrs.METH_ALL: reg = getattr(router, 'add_'+self.method.lower()) reg(self.path, self.handler, **self.kwargs) @@ -44,10 +60,10 @@ class RouteDef(AbstractRouteDef): @attr.s(frozen=True, repr=False, slots=True) class StaticDef(AbstractRouteDef): prefix = attr.ib(type=str) - path = attr.ib(type=str) - kwargs = attr.ib() + path = attr.ib() # type: PathLike + kwargs = attr.ib(type=Dict[str, Any]) - def __repr__(self): + def __repr__(self) -> str: info = [] for name, value in sorted(self.kwargs.items()): info.append(", {}={!r}".format(name, value)) @@ -55,97 +71,113 @@ class StaticDef(AbstractRouteDef): "{info}>".format(prefix=self.prefix, path=self.path, info=''.join(info))) - def register(self, router): + def register(self, router: UrlDispatcher) -> None: router.add_static(self.prefix, self.path, **self.kwargs) -def route(method, path, handler, **kwargs): +def route(method: str, path: str, handler: _HandlerType, + **kwargs: Any) -> RouteDef: return RouteDef(method, path, handler, kwargs) -def head(path, handler, **kwargs): +def head(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: return route(hdrs.METH_HEAD, path, handler, **kwargs) -def options(path, handler, **kwargs): +def options(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: return route(hdrs.METH_OPTIONS, path, handler, **kwargs) -def get(path, handler, *, name=None, allow_head=True, **kwargs): +def get(path: str, handler: _HandlerType, *, name: Optional[str]=None, + allow_head: bool=True, **kwargs: Any) -> RouteDef: return route(hdrs.METH_GET, path, handler, name=name, allow_head=allow_head, **kwargs) -def post(path, handler, **kwargs): +def post(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: return route(hdrs.METH_POST, path, handler, **kwargs) -def put(path, handler, **kwargs): +def put(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: return route(hdrs.METH_PUT, path, handler, **kwargs) -def patch(path, handler, **kwargs): +def patch(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: return route(hdrs.METH_PATCH, path, handler, **kwargs) -def delete(path, handler, **kwargs): +def delete(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: return route(hdrs.METH_DELETE, path, handler, **kwargs) -def view(path, handler, **kwargs): +def view(path: str, handler: AbstractView, **kwargs: Any) -> RouteDef: return route(hdrs.METH_ANY, path, handler, **kwargs) -def static(prefix, path, **kwargs): +def static(prefix: str, path: PathLike, + **kwargs: Any) -> StaticDef: return StaticDef(prefix, path, kwargs) -class RouteTableDef(Sequence): +_Deco = Callable[[_HandlerType], _HandlerType] + + +class RouteTableDef(Sequence[AbstractRouteDef]): """Route definition table""" - def __init__(self): - self._items = [] + def __init__(self) -> None: + self._items = [] # type: List[AbstractRouteDef] - def __repr__(self): + def __repr__(self) -> str: return "<RouteTableDef count={}>".format(len(self._items)) - def __getitem__(self, index): + @overload + def __getitem__(self, index: int) -> AbstractRouteDef: ... # noqa + + @overload # noqa + def __getitem__(self, index: slice) -> List[AbstractRouteDef]: ... # noqa + + def __getitem__(self, index): # type: ignore # noqa return self._items[index] - def __iter__(self): + def __iter__(self) -> Iterator[AbstractRouteDef]: return iter(self._items) - def __len__(self): + def __len__(self) -> int: return len(self._items) - def __contains__(self, item): + def __contains__(self, item: object) -> bool: return item in self._items - def route(self, method, path, **kwargs): - def inner(handler): + def route(self, + method: str, + path: str, + **kwargs: Any) -> _Deco: + def inner(handler: _HandlerType) -> _HandlerType: self._items.append(RouteDef(method, path, handler, kwargs)) return handler return inner - def head(self, path, **kwargs): + def head(self, path: str, **kwargs: Any) -> _Deco: return self.route(hdrs.METH_HEAD, path, **kwargs) - def get(self, path, **kwargs): + def get(self, path: str, **kwargs: Any) -> _Deco: return self.route(hdrs.METH_GET, path, **kwargs) - def post(self, path, **kwargs): + def post(self, path: str, **kwargs: Any) -> _Deco: return self.route(hdrs.METH_POST, path, **kwargs) - def put(self, path, **kwargs): + def put(self, path: str, **kwargs: Any) -> _Deco: return self.route(hdrs.METH_PUT, path, **kwargs) - def patch(self, path, **kwargs): + def patch(self, path: str, **kwargs: Any) -> _Deco: return self.route(hdrs.METH_PATCH, path, **kwargs) - def delete(self, path, **kwargs): + def delete(self, path: str, **kwargs: Any) -> _Deco: return self.route(hdrs.METH_DELETE, path, **kwargs) - def view(self, path, **kwargs): + def view(self, path: str, **kwargs: Any) -> _Deco: return self.route(hdrs.METH_ANY, path, **kwargs) - def static(self, prefix, path, **kwargs): + def static(self, prefix: str, path: PathLike, + **kwargs: Any) -> None: self._items.append(StaticDef(prefix, path, kwargs)) diff --git a/aiohttp/web_runner.py b/aiohttp/web_runner.py index 18ee2e8..6b8cf0a 100644 --- a/aiohttp/web_runner.py +++ b/aiohttp/web_runner.py @@ -2,13 +2,21 @@ import asyncio import signal import socket from abc import ABC, abstractmethod +from typing import Any, List, Optional, Set from yarl import URL from .web_app import Application +from .web_server import Server -__all__ = ('TCPSite', 'UnixSite', 'SockSite', 'BaseRunner', +try: + from ssl import SSLContext +except ImportError: + SSLContext = object # type: ignore + + +__all__ = ('BaseSite', 'TCPSite', 'UnixSite', 'SockSite', 'BaseRunner', 'AppRunner', 'ServerRunner', 'GracefulExit') @@ -16,7 +24,7 @@ class GracefulExit(SystemExit): code = 1 -def _raise_graceful_exit(): +def _raise_graceful_exit() -> None: raise GracefulExit() @@ -24,27 +32,28 @@ class BaseSite(ABC): __slots__ = ('_runner', '_shutdown_timeout', '_ssl_context', '_backlog', '_server') - def __init__(self, runner, *, - shutdown_timeout=60.0, ssl_context=None, - backlog=128): + def __init__(self, runner: 'BaseRunner', *, + shutdown_timeout: float=60.0, + ssl_context: Optional[SSLContext]=None, + backlog: int=128) -> None: if runner.server is None: raise RuntimeError("Call runner.setup() before making a site") self._runner = runner self._shutdown_timeout = shutdown_timeout self._ssl_context = ssl_context self._backlog = backlog - self._server = None + self._server = None # type: Optional[asyncio.AbstractServer] @property @abstractmethod - def name(self): + def name(self) -> str: pass # pragma: no cover @abstractmethod - async def start(self): + async def start(self) -> None: self._runner._reg_site(self) - async def stop(self): + async def stop(self) -> None: self._runner._check_site(self) if self._server is None: self._runner._unreg_site(self) @@ -52,6 +61,7 @@ class BaseSite(ABC): self._server.close() await self._server.wait_closed() await self._runner.shutdown() + assert self._runner.server await self._runner.server.shutdown(self._shutdown_timeout) self._runner._unreg_site(self) @@ -59,10 +69,12 @@ class BaseSite(ABC): class TCPSite(BaseSite): __slots__ = ('_host', '_port', '_reuse_address', '_reuse_port') - def __init__(self, runner, host=None, port=None, *, - shutdown_timeout=60.0, ssl_context=None, - backlog=128, reuse_address=None, - reuse_port=None): + def __init__(self, runner: 'BaseRunner', + host: str=None, port: int=None, *, + shutdown_timeout: float=60.0, + ssl_context: Optional[SSLContext]=None, + backlog: int=128, reuse_address: Optional[bool]=None, + reuse_port: Optional[bool]=None) -> None: super().__init__(runner, shutdown_timeout=shutdown_timeout, ssl_context=ssl_context, backlog=backlog) if host is None: @@ -75,15 +87,17 @@ class TCPSite(BaseSite): self._reuse_port = reuse_port @property - def name(self): + def name(self) -> str: scheme = 'https' if self._ssl_context else 'http' return str(URL.build(scheme=scheme, host=self._host, port=self._port)) - async def start(self): + async def start(self) -> None: await super().start() loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None self._server = await loop.create_server( - self._runner.server, self._host, self._port, + server, self._host, self._port, ssl=self._ssl_context, backlog=self._backlog, reuse_address=self._reuse_address, reuse_port=self._reuse_port) @@ -92,32 +106,36 @@ class TCPSite(BaseSite): class UnixSite(BaseSite): __slots__ = ('_path', ) - def __init__(self, runner, path, *, - shutdown_timeout=60.0, ssl_context=None, - backlog=128): + def __init__(self, runner: 'BaseRunner', path: str, *, + shutdown_timeout: float=60.0, + ssl_context: Optional[SSLContext]=None, + backlog: int=128) -> None: super().__init__(runner, shutdown_timeout=shutdown_timeout, ssl_context=ssl_context, backlog=backlog) self._path = path @property - def name(self): + def name(self) -> str: scheme = 'https' if self._ssl_context else 'http' return '{}://unix:{}:'.format(scheme, self._path) - async def start(self): + async def start(self) -> None: await super().start() loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None self._server = await loop.create_unix_server( - self._runner.server, self._path, + server, self._path, ssl=self._ssl_context, backlog=self._backlog) class SockSite(BaseSite): __slots__ = ('_sock', '_name') - def __init__(self, runner, sock, *, - shutdown_timeout=60.0, ssl_context=None, - backlog=128): + def __init__(self, runner: 'BaseRunner', sock: socket.socket, *, + shutdown_timeout: float=60.0, + ssl_context: Optional[SSLContext]=None, + backlog: int=128) -> None: super().__init__(runner, shutdown_timeout=shutdown_timeout, ssl_context=ssl_context, backlog=backlog) self._sock = sock @@ -130,41 +148,49 @@ class SockSite(BaseSite): self._name = name @property - def name(self): + def name(self) -> str: return self._name - async def start(self): + async def start(self) -> None: await super().start() loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None self._server = await loop.create_server( - self._runner.server, sock=self._sock, + server, sock=self._sock, ssl=self._ssl_context, backlog=self._backlog) class BaseRunner(ABC): __slots__ = ('_handle_signals', '_kwargs', '_server', '_sites') - def __init__(self, *, handle_signals=False, **kwargs): + def __init__(self, *, handle_signals: bool=False, **kwargs: Any) -> None: self._handle_signals = handle_signals self._kwargs = kwargs - self._server = None - self._sites = [] + self._server = None # type: Optional[Server] + self._sites = [] # type: List[BaseSite] @property - def server(self): + def server(self) -> Optional[Server]: return self._server @property - def addresses(self): - return [sock.getsockname() - for site in self._sites - for sock in site._server.sockets] + def addresses(self) -> List[str]: + ret = [] # type: List[str] + for site in self._sites: + server = site._server + if server is not None: + sockets = server.sockets + if sockets is not None: + for sock in sockets: + ret.append(sock.getsockname()) + return ret @property - def sites(self): + def sites(self) -> Set[BaseSite]: return set(self._sites) - async def setup(self): + async def setup(self) -> None: loop = asyncio.get_event_loop() if self._handle_signals: @@ -178,10 +204,10 @@ class BaseRunner(ABC): self._server = await self._make_server() @abstractmethod - async def shutdown(self): + async def shutdown(self) -> None: pass # pragma: no cover - async def cleanup(self): + async def cleanup(self) -> None: loop = asyncio.get_event_loop() if self._server is None: @@ -205,25 +231,25 @@ class BaseRunner(ABC): pass @abstractmethod - async def _make_server(self): + async def _make_server(self) -> Server: pass # pragma: no cover @abstractmethod - async def _cleanup_server(self): + async def _cleanup_server(self) -> None: pass # pragma: no cover - def _reg_site(self, site): + def _reg_site(self, site: BaseSite) -> None: if site in self._sites: raise RuntimeError("Site {} is already registered in runner {}" .format(site, self)) self._sites.append(site) - def _check_site(self, site): + def _check_site(self, site: BaseSite) -> None: if site not in self._sites: raise RuntimeError("Site {} is not registered in runner {}" .format(site, self)) - def _unreg_site(self, site): + def _unreg_site(self, site: BaseSite) -> None: if site not in self._sites: raise RuntimeError("Site {} is not registered in runner {}" .format(site, self)) @@ -235,17 +261,18 @@ class ServerRunner(BaseRunner): __slots__ = ('_web_server',) - def __init__(self, web_server, *, handle_signals=False, **kwargs): + def __init__(self, web_server: Server, *, + handle_signals: bool=False, **kwargs: Any) -> None: super().__init__(handle_signals=handle_signals, **kwargs) self._web_server = web_server - async def shutdown(self): + async def shutdown(self) -> None: pass - async def _make_server(self): + async def _make_server(self) -> Server: return self._web_server - async def _cleanup_server(self): + async def _cleanup_server(self) -> None: pass @@ -254,7 +281,8 @@ class AppRunner(BaseRunner): __slots__ = ('_app',) - def __init__(self, app, *, handle_signals=False, **kwargs): + def __init__(self, app: Application, *, + handle_signals: bool=False, **kwargs: Any) -> None: super().__init__(handle_signals=handle_signals, **kwargs) if not isinstance(app, Application): raise TypeError("The first argument should be web.Application " @@ -262,13 +290,13 @@ class AppRunner(BaseRunner): self._app = app @property - def app(self): + def app(self) -> Application: return self._app - async def shutdown(self): + async def shutdown(self) -> None: await self._app.shutdown() - async def _make_server(self): + async def _make_server(self) -> Server: loop = asyncio.get_event_loop() self._app._set_loop(loop) self._app.on_startup.freeze() @@ -277,5 +305,5 @@ class AppRunner(BaseRunner): return self._app._make_handler(loop=loop, **self._kwargs) - async def _cleanup_server(self): + async def _cleanup_server(self) -> None: await self._app.cleanup() diff --git a/aiohttp/web_server.py b/aiohttp/web_server.py index 3620bd1..48c0069 100644 --- a/aiohttp/web_server.py +++ b/aiohttp/web_server.py @@ -1,7 +1,12 @@ """Low level HTTP server.""" import asyncio +from typing import Any, Awaitable, Callable, Dict, List, Optional # noqa -from .web_protocol import RequestHandler +from .abc import AbstractStreamWriter +from .helpers import get_running_loop +from .http_parser import RawRequestMessage +from .streams import StreamReader +from .web_protocol import RequestHandler, _RequestFactory, _RequestHandler from .web_request import BaseRequest @@ -10,35 +15,44 @@ __all__ = ('Server',) class Server: - def __init__(self, handler, *, request_factory=None, loop=None, **kwargs): - if loop is None: - loop = asyncio.get_event_loop() - self._loop = loop - self._connections = {} + def __init__(self, + handler: _RequestHandler, + *, + request_factory: Optional[_RequestFactory]=None, + loop: Optional[asyncio.AbstractEventLoop]=None, + **kwargs: Any) -> None: + self._loop = get_running_loop(loop) + self._connections = {} # type: Dict[RequestHandler, asyncio.Transport] self._kwargs = kwargs self.requests_count = 0 self.request_handler = handler self.request_factory = request_factory or self._make_request @property - def connections(self): + def connections(self) -> List[RequestHandler]: return list(self._connections.keys()) - def connection_made(self, handler, transport): + def connection_made(self, handler: RequestHandler, + transport: asyncio.Transport) -> None: self._connections[handler] = transport - def connection_lost(self, handler, exc=None): + def connection_lost(self, handler: RequestHandler, + exc: Optional[BaseException]=None) -> None: if handler in self._connections: del self._connections[handler] - def _make_request(self, message, payload, protocol, writer, task): + def _make_request(self, message: RawRequestMessage, + payload: StreamReader, + protocol: RequestHandler, + writer: AbstractStreamWriter, + task: 'asyncio.Task[None]') -> BaseRequest: return BaseRequest( message, payload, protocol, writer, task, self._loop) - async def shutdown(self, timeout=None): + async def shutdown(self, timeout: Optional[float]=None) -> None: coros = [conn.shutdown(timeout) for conn in self._connections] await asyncio.gather(*coros, loop=self._loop) self._connections.clear() - def __call__(self): + def __call__(self) -> RequestHandler: return RequestHandler(self, loop=self._loop, **self._kwargs) diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py index 9d85648..dc7005d 100644 --- a/aiohttp/web_urldispatcher.py +++ b/aiohttp/web_urldispatcher.py @@ -1,18 +1,19 @@ import abc import asyncio import base64 -import collections import hashlib import inspect import keyword import os import re import warnings -from collections.abc import Container, Iterable, Sized from contextlib import contextmanager from functools import wraps from pathlib import Path from types import MappingProxyType +from typing import (TYPE_CHECKING, Any, Awaitable, Callable, Container, # noqa + Dict, Generator, Iterable, Iterator, List, Mapping, + Optional, Set, Sized, Tuple, Union, cast) from yarl import URL @@ -20,10 +21,13 @@ from . import hdrs from .abc import AbstractMatchInfo, AbstractRouter, AbstractView from .helpers import DEBUG from .http import HttpVersion11 -from .web_exceptions import (HTTPExpectationFailed, HTTPForbidden, - HTTPMethodNotAllowed, HTTPNotFound) +from .typedefs import PathLike +from .web_exceptions import (HTTPException, HTTPExpectationFailed, + HTTPForbidden, HTTPMethodNotAllowed, HTTPNotFound) from .web_fileresponse import FileResponse -from .web_response import Response +from .web_request import Request +from .web_response import Response, StreamResponse +from .web_routedef import AbstractRouteDef __all__ = ('UrlDispatcher', 'UrlMappingMatchInfo', @@ -31,23 +35,35 @@ __all__ = ('UrlDispatcher', 'UrlMappingMatchInfo', 'AbstractRoute', 'ResourceRoute', 'StaticResource', 'View') + +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application # noqa + BaseDict = Dict[str, str] +else: + BaseDict = dict + HTTP_METHOD_RE = re.compile(r"^[0-9A-Za-z!#\$%&'\*\+\-\.\^_`\|~]+$") ROUTE_RE = re.compile(r'(\{[_a-zA-Z][^{}]*(?:\{[^{}]*\}[^{}]*)*\})') PATH_SEP = re.escape('/') -class AbstractResource(Sized, Iterable): +_WebHandler = Callable[[Request], Awaitable[StreamResponse]] +_ExpectHandler = Callable[[Request], Awaitable[None]] +_Resolve = Tuple[Optional[AbstractMatchInfo], Set[str]] + - def __init__(self, *, name=None): +class AbstractResource(Sized, Iterable['AbstractRoute']): + + def __init__(self, *, name: Optional[str]=None) -> None: self._name = name @property - def name(self): + def name(self) -> Optional[str]: return self._name @property @abc.abstractmethod - def canonical(self): + def canonical(self) -> str: """Exposes the resource's canonical path. For example '/foo/bar/{name}' @@ -55,17 +71,17 @@ class AbstractResource(Sized, Iterable): """ @abc.abstractmethod # pragma: no branch - def url_for(self, **kwargs): + def url_for(self, **kwargs: str) -> URL: """Construct url for resource with additional params.""" @abc.abstractmethod # pragma: no branch - async def resolve(self, request): + async def resolve(self, request: Request) -> _Resolve: """Resolve resource Return (UrlMappingMatchInfo, allowed_methods) pair.""" @abc.abstractmethod - def add_prefix(self, prefix): + def add_prefix(self, prefix: str) -> None: """Add a prefix to processed URLs. Required for subapplications support. @@ -73,22 +89,23 @@ class AbstractResource(Sized, Iterable): """ @abc.abstractmethod - def get_info(self): + def get_info(self) -> Dict[str, Any]: """Return a dict with additional info useful for introspection""" - def freeze(self): + def freeze(self) -> None: pass @abc.abstractmethod - def raw_match(self, path): + def raw_match(self, path: str) -> bool: """Perform a raw match against path""" class AbstractRoute(abc.ABC): - def __init__(self, method, handler, *, - expect_handler=None, - resource=None): + def __init__(self, method: str, + handler: Union[_WebHandler, AbstractView], *, + expect_handler: _ExpectHandler=None, + resource: AbstractResource=None) -> None: if expect_handler is None: expect_handler = _default_expect_handler @@ -114,8 +131,8 @@ class AbstractRoute(abc.ABC): "use async ones", DeprecationWarning) @wraps(handler) - async def handler_wrapper(*args, **kwargs): - result = old_handler(*args, **kwargs) + async def handler_wrapper(request: Request) -> StreamResponse: + result = old_handler(request) if asyncio.iscoroutine(result): result = await result return result @@ -128,67 +145,67 @@ class AbstractRoute(abc.ABC): self._resource = resource @property - def method(self): + def method(self) -> str: return self._method @property - def handler(self): + def handler(self) -> _WebHandler: return self._handler @property @abc.abstractmethod - def name(self): + def name(self) -> Optional[str]: """Optional route's name, always equals to resource's name.""" @property - def resource(self): + def resource(self) -> Optional[AbstractResource]: return self._resource @abc.abstractmethod - def get_info(self): + def get_info(self) -> Dict[str, Any]: """Return a dict with additional info useful for introspection""" @abc.abstractmethod # pragma: no branch - def url_for(self, *args, **kwargs): + def url_for(self, *args: str, **kwargs: str) -> URL: """Construct url for route with additional params.""" - async def handle_expect_header(self, request): - return await self._expect_handler(request) + async def handle_expect_header(self, request: Request) -> None: + await self._expect_handler(request) -class UrlMappingMatchInfo(dict, AbstractMatchInfo): +class UrlMappingMatchInfo(BaseDict, AbstractMatchInfo): - def __init__(self, match_dict, route): + def __init__(self, match_dict: Dict[str, str], route: AbstractRoute): super().__init__(match_dict) self._route = route - self._apps = [] - self._current_app = None + self._apps = [] # type: List[Application] + self._current_app = None # type: Optional[Application] self._frozen = False @property - def handler(self): + def handler(self) -> _WebHandler: return self._route.handler @property - def route(self): + def route(self) -> AbstractRoute: return self._route @property - def expect_handler(self): + def expect_handler(self) -> _ExpectHandler: return self._route.handle_expect_header @property - def http_exception(self): + def http_exception(self) -> Optional[HTTPException]: return None - def get_info(self): + def get_info(self) -> Dict[str, str]: return self._route.get_info() @property - def apps(self): + def apps(self) -> Tuple['Application', ...]: return tuple(self._apps) - def add_app(self, app): + def add_app(self, app: 'Application') -> None: if self._frozen: raise RuntimeError("Cannot change apps stack after .freeze() call") if self._current_app is None: @@ -196,11 +213,14 @@ class UrlMappingMatchInfo(dict, AbstractMatchInfo): self._apps.insert(0, app) @property - def current_app(self): - return self._current_app + def current_app(self) -> 'Application': + app = self._current_app + assert app is not None + return app @contextmanager - def set_current_app(self, app): + def set_current_app(self, + app: 'Application') -> Generator[None, None, None]: if DEBUG: # pragma: no cover if app not in self._apps: raise RuntimeError( @@ -213,29 +233,29 @@ class UrlMappingMatchInfo(dict, AbstractMatchInfo): finally: self._current_app = prev - def freeze(self): + def freeze(self) -> None: self._frozen = True - def __repr__(self): + def __repr__(self) -> str: return "<MatchInfo {}: {}>".format(super().__repr__(), self._route) class MatchInfoError(UrlMappingMatchInfo): - def __init__(self, http_exception): + def __init__(self, http_exception: HTTPException) -> None: self._exception = http_exception super().__init__({}, SystemRoute(self._exception)) @property - def http_exception(self): + def http_exception(self) -> HTTPException: return self._exception - def __repr__(self): + def __repr__(self) -> str: return "<MatchInfoError {}: {}>".format(self._exception.status, self._exception.reason) -async def _default_expect_handler(request): +async def _default_expect_handler(request: Request) -> None: """Default handler for Expect header. Just send "100 Continue" to client. @@ -244,20 +264,21 @@ async def _default_expect_handler(request): expect = request.headers.get(hdrs.EXPECT) if request.version == HttpVersion11: if expect.lower() == "100-continue": - await request.writer.write( - b"HTTP/1.1 100 Continue\r\n\r\n", drain=False) + await request.writer.write(b"HTTP/1.1 100 Continue\r\n\r\n") else: raise HTTPExpectationFailed(text="Unknown Expect: %s" % expect) class Resource(AbstractResource): - def __init__(self, *, name=None): + def __init__(self, *, name: Optional[str]=None) -> None: super().__init__(name=name) - self._routes = [] + self._routes = [] # type: List[ResourceRoute] - def add_route(self, method, handler, *, - expect_handler=None): + def add_route(self, method: str, + handler: Union[AbstractView, _WebHandler], *, + expect_handler: Optional[_ExpectHandler]=None + ) -> 'ResourceRoute': for route_obj in self._routes: if route_obj.method == method or route_obj.method == hdrs.METH_ANY: @@ -270,13 +291,13 @@ class Resource(AbstractResource): self.register_route(route_obj) return route_obj - def register_route(self, route): + def register_route(self, route: 'ResourceRoute') -> None: assert isinstance(route, ResourceRoute), \ 'Instance of Route class is required, got {!r}'.format(route) self._routes.append(route) - async def resolve(self, request): - allowed_methods = set() + async def resolve(self, request: Request) -> _Resolve: + allowed_methods = set() # type: Set[str] match_dict = self._match(request.rel_url.raw_path) if match_dict is None: @@ -293,10 +314,14 @@ class Resource(AbstractResource): else: return None, allowed_methods - def __len__(self): + @abc.abstractmethod + def _match(self, path: str) -> Optional[Dict[str, str]]: + pass # pragma: no cover + + def __len__(self) -> int: return len(self._routes) - def __iter__(self): + def __iter__(self) -> Iterator[AbstractRoute]: return iter(self._routes) # TODO: implement all abstract methods @@ -304,42 +329,42 @@ class Resource(AbstractResource): class PlainResource(Resource): - def __init__(self, path, *, name=None): + def __init__(self, path: str, *, name: Optional[str]=None) -> None: super().__init__(name=name) assert not path or path.startswith('/') self._path = path @property - def canonical(self): + def canonical(self) -> str: return self._path - def freeze(self): + def freeze(self) -> None: if not self._path: self._path = '/' - def add_prefix(self, prefix): + def add_prefix(self, prefix: str) -> None: assert prefix.startswith('/') assert not prefix.endswith('/') assert len(prefix) > 1 self._path = prefix + self._path - def _match(self, path): + def _match(self, path: str) -> Optional[Dict[str, str]]: # string comparison is about 10 times faster than regexp matching if self._path == path: return {} else: return None - def raw_match(self, path): + def raw_match(self, path: str) -> bool: return self._path == path - def get_info(self): + def get_info(self) -> Dict[str, Any]: return {'path': self._path} - def url_for(self): + def url_for(self) -> URL: # type: ignore return URL.build(path=self._path, encoded=True) - def __repr__(self): + def __repr__(self) -> str: name = "'" + self.name + "' " if self.name is not None else "" return "<PlainResource {name} {path}>".format(name=name, path=self._path) @@ -352,7 +377,7 @@ class DynamicResource(Resource): r'\{(?P<var>[_a-zA-Z][_a-zA-Z0-9]*):(?P<re>.+)\}') GOOD = r'[^{}/]+' - def __init__(self, path, *, name=None): + def __init__(self, path: str, *, name: Optional[str]=None) -> None: super().__init__(name=name) pattern = '' formatter = '' @@ -387,17 +412,17 @@ class DynamicResource(Resource): self._formatter = formatter @property - def canonical(self): + def canonical(self) -> str: return self._formatter - def add_prefix(self, prefix): + def add_prefix(self, prefix: str) -> None: assert prefix.startswith('/') assert not prefix.endswith('/') assert len(prefix) > 1 self._pattern = re.compile(re.escape(prefix)+self._pattern.pattern) self._formatter = prefix + self._formatter - def _match(self, path): + def _match(self, path: str) -> Optional[Dict[str, str]]: match = self._pattern.fullmatch(path) if match is None: return None @@ -405,19 +430,19 @@ class DynamicResource(Resource): return {key: URL.build(path=value, encoded=True).path for key, value in match.groupdict().items()} - def raw_match(self, path): + def raw_match(self, path: str) -> bool: return self._formatter == path - def get_info(self): + def get_info(self) -> Dict[str, Any]: return {'formatter': self._formatter, 'pattern': self._pattern} - def url_for(self, **parts): + def url_for(self, **parts: str) -> URL: url = self._formatter.format_map({k: URL.build(path=v).raw_path for k, v in parts.items()}) return URL.build(path=url) - def __repr__(self): + def __repr__(self) -> str: name = "'" + self.name + "' " if self.name is not None else "" return ("<DynamicResource {name} {formatter}>" .format(name=name, formatter=self._formatter)) @@ -425,23 +450,23 @@ class DynamicResource(Resource): class PrefixResource(AbstractResource): - def __init__(self, prefix, *, name=None): + def __init__(self, prefix: str, *, name: Optional[str]=None) -> None: assert not prefix or prefix.startswith('/'), prefix assert prefix in ('', '/') or not prefix.endswith('/'), prefix super().__init__(name=name) self._prefix = URL.build(path=prefix).raw_path @property - def canonical(self): + def canonical(self) -> str: return self._prefix - def add_prefix(self, prefix): + def add_prefix(self, prefix: str) -> None: assert prefix.startswith('/') assert not prefix.endswith('/') assert len(prefix) > 1 self._prefix = prefix + self._prefix - def raw_match(self, prefix): + def raw_match(self, prefix: str) -> bool: return False # TODO: impl missing abstract methods @@ -450,10 +475,12 @@ class PrefixResource(AbstractResource): class StaticResource(PrefixResource): VERSION_KEY = 'v' - def __init__(self, prefix, directory, *, name=None, - expect_handler=None, chunk_size=256 * 1024, - show_index=False, follow_symlinks=False, - append_version=False): + def __init__(self, prefix: str, directory: PathLike, + *, name: Optional[str]=None, + expect_handler: Optional[_ExpectHandler]=None, + chunk_size: int=256 * 1024, + show_index: bool=False, follow_symlinks: bool=False, + append_version: bool=False)-> None: super().__init__(prefix, name=name) try: directory = Path(directory) @@ -478,7 +505,8 @@ class StaticResource(PrefixResource): 'HEAD': ResourceRoute('HEAD', self._handle, self, expect_handler=expect_handler)} - def url_for(self, *, filename, append_version=None): + def url_for(self, *, filename: Union[str, Path], # type: ignore + append_version: Optional[bool]=None) -> URL: if append_version is None: append_version = self._append_version if isinstance(filename, Path): @@ -490,7 +518,7 @@ class StaticResource(PrefixResource): # filename is not encoded url = URL.build(path=self._prefix + filename) - if append_version is True: + if append_version: try: if filename.startswith('/'): filename = filename[1:] @@ -512,24 +540,24 @@ class StaticResource(PrefixResource): return url @staticmethod - def _get_file_hash(byte_array): + def _get_file_hash(byte_array: bytes) -> str: m = hashlib.sha256() # todo sha256 can be configurable param m.update(byte_array) b64 = base64.urlsafe_b64encode(m.digest()) return b64.decode('ascii') - def get_info(self): + def get_info(self) -> Dict[str, Any]: return {'directory': self._directory, 'prefix': self._prefix} - def set_options_route(self, handler): + def set_options_route(self, handler: _WebHandler) -> None: if 'OPTIONS' in self._routes: raise RuntimeError('OPTIONS route was set already') self._routes['OPTIONS'] = ResourceRoute( 'OPTIONS', handler, self, expect_handler=self._expect_handler) - async def resolve(self, request): + async def resolve(self, request: Request) -> _Resolve: path = request.rel_url.raw_path method = request.method allowed_methods = set(self._routes) @@ -544,13 +572,13 @@ class StaticResource(PrefixResource): return (UrlMappingMatchInfo(match_dict, self._routes[method]), allowed_methods) - def __len__(self): + def __len__(self) -> int: return len(self._routes) - def __iter__(self): + def __iter__(self) -> Iterator[AbstractRoute]: return iter(self._routes.values()) - async def _handle(self, request): + async def _handle(self, request: Request) -> StreamResponse: rel_url = request.match_info['filename'] try: filename = Path(rel_url) @@ -572,24 +600,22 @@ class StaticResource(PrefixResource): request.app.logger.exception(error) raise HTTPNotFound() from error - # on opening a dir, load it's contents if allowed + # on opening a dir, load its contents if allowed if filepath.is_dir(): if self._show_index: try: - ret = Response(text=self._directory_as_html(filepath), - content_type="text/html") + return Response(text=self._directory_as_html(filepath), + content_type="text/html") except PermissionError: raise HTTPForbidden() else: raise HTTPForbidden() elif filepath.is_file(): - ret = FileResponse(filepath, chunk_size=self._chunk_size) + return FileResponse(filepath, chunk_size=self._chunk_size) else: raise HTTPNotFound - return ret - - def _directory_as_html(self, filepath): + def _directory_as_html(self, filepath: Path) -> str: # returns directory's index as html # sanity check @@ -624,7 +650,7 @@ class StaticResource(PrefixResource): return html - def __repr__(self): + def __repr__(self) -> str: name = "'" + self.name + "'" if self.name is not None else "" return "<StaticResource {name} {path} -> {directory!r}>".format( name=name, path=self._prefix, directory=self._directory) @@ -632,26 +658,26 @@ class StaticResource(PrefixResource): class PrefixedSubAppResource(PrefixResource): - def __init__(self, prefix, app): + def __init__(self, prefix: str, app: 'Application') -> None: super().__init__(prefix) self._app = app for resource in app.router.resources(): resource.add_prefix(prefix) - def add_prefix(self, prefix): + def add_prefix(self, prefix: str) -> None: super().add_prefix(prefix) for resource in self._app.router.resources(): resource.add_prefix(prefix) - def url_for(self, *args, **kwargs): + def url_for(self, *args: str, **kwargs: str) -> URL: raise RuntimeError(".url_for() is not supported " "by sub-application root") - def get_info(self): + def get_info(self) -> Dict[str, Any]: return {'app': self._app, 'prefix': self._prefix} - async def resolve(self, request): + async def resolve(self, request: Request) -> _Resolve: if not request.url.raw_path.startswith(self._prefix): return None, set() match_info = await self._app.router.resolve(request) @@ -662,76 +688,180 @@ class PrefixedSubAppResource(PrefixResource): methods = set() return match_info, methods - def __len__(self): + def __len__(self) -> int: return len(self._app.router.routes()) - def __iter__(self): + def __iter__(self) -> Iterator[AbstractRoute]: return iter(self._app.router.routes()) - def __repr__(self): + def __repr__(self) -> str: return "<PrefixedSubAppResource {prefix} -> {app!r}>".format( prefix=self._prefix, app=self._app) +class AbstractRuleMatching(abc.ABC): + @abc.abstractmethod # pragma: no branch + async def match(self, request: Request) -> bool: + """Return bool if the request satisfies the criteria""" + + @abc.abstractmethod # pragma: no branch + def get_info(self) -> Dict[str, Any]: + """Return a dict with additional info useful for introspection""" + + @property + @abc.abstractmethod # pragma: no branch + def canonical(self) -> str: + """Return a str""" + + +class Domain(AbstractRuleMatching): + re_part = re.compile(r"(?!-)[a-z\d-]{1,63}(?<!-)") + + def __init__(self, domain: str) -> None: + super().__init__() + self._domain = self.validation(domain) + + @property + def canonical(self) -> str: + return self._domain + + def validation(self, domain: str) -> str: + if not isinstance(domain, str): + raise TypeError("Domain must be str") + domain = domain.rstrip('.').lower() + if not domain: + raise ValueError("Domain cannot be empty") + elif '://' in domain: + raise ValueError("Scheme not supported") + url = URL('http://' + domain) + if not all( + self.re_part.fullmatch(x) + for x in url.raw_host.split(".")): # type: ignore + raise ValueError("Domain not valid") + if url.port == 80: + return url.raw_host # type: ignore + return '{}:{}'.format(url.raw_host, url.port) + + async def match(self, request: Request) -> bool: + host = request.headers.get(hdrs.HOST) + return host and self.match_domain(host) + + def match_domain(self, host: str) -> bool: + return host.lower() == self._domain + + def get_info(self) -> Dict[str, Any]: + return {'domain': self._domain} + + +class MaskDomain(Domain): + re_part = re.compile(r"(?!-)[a-z\d\*-]{1,63}(?<!-)") + + def __init__(self, domain: str) -> None: + super().__init__(domain) + mask = self._domain.replace('.', r'\.').replace('*', '.*') + self._mask = re.compile(mask) + + @property + def canonical(self) -> str: + return self._mask.pattern + + def match_domain(self, host: str) -> bool: + return self._mask.fullmatch(host) is not None + + +class MatchedSubAppResource(PrefixedSubAppResource): + + def __init__(self, rule: AbstractRuleMatching, app: 'Application') -> None: + AbstractResource.__init__(self) + self._prefix = '' + self._app = app + self._rule = rule + + @property + def canonical(self) -> str: + return self._rule.canonical + + def get_info(self) -> Dict[str, Any]: + return {'app': self._app, + 'rule': self._rule} + + async def resolve(self, request: Request) -> _Resolve: + if not await self._rule.match(request): + return None, set() + match_info = await self._app.router.resolve(request) + match_info.add_app(self._app) + if isinstance(match_info.http_exception, HTTPMethodNotAllowed): + methods = match_info.http_exception.allowed_methods + else: + methods = set() + return match_info, methods + + def __repr__(self) -> str: + return "<MatchedSubAppResource -> {app!r}>" \ + "".format(app=self._app) + + class ResourceRoute(AbstractRoute): """A route with resource""" - def __init__(self, method, handler, resource, *, - expect_handler=None): + def __init__(self, method: str, + handler: Union[_WebHandler, AbstractView], + resource: AbstractResource, *, + expect_handler: Optional[_ExpectHandler]=None) -> None: super().__init__(method, handler, expect_handler=expect_handler, resource=resource) - def __repr__(self): + def __repr__(self) -> str: return "<ResourceRoute [{method}] {resource} -> {handler!r}".format( method=self.method, resource=self._resource, handler=self.handler) @property - def name(self): - return self._resource.name + def name(self) -> Optional[str]: + return self._resource.name # type: ignore - def url_for(self, *args, **kwargs): + def url_for(self, *args: str, **kwargs: str) -> URL: """Construct url for route with additional params.""" - return self._resource.url_for(*args, **kwargs) + return self._resource.url_for(*args, **kwargs) # type: ignore - def get_info(self): - return self._resource.get_info() + def get_info(self) -> Dict[str, Any]: + return self._resource.get_info() # type: ignore class SystemRoute(AbstractRoute): - def __init__(self, http_exception): - super().__init__(hdrs.METH_ANY, self._handler) + def __init__(self, http_exception: HTTPException) -> None: + super().__init__(hdrs.METH_ANY, self._handle) self._http_exception = http_exception - def url_for(self, *args, **kwargs): + def url_for(self, *args: str, **kwargs: str) -> URL: raise RuntimeError(".url_for() is not allowed for SystemRoute") @property - def name(self): + def name(self) -> Optional[str]: return None - def get_info(self): + def get_info(self) -> Dict[str, Any]: return {'http_exception': self._http_exception} - async def _handler(self, request): + async def _handle(self, request: Request) -> StreamResponse: raise self._http_exception @property - def status(self): + def status(self) -> int: return self._http_exception.status @property - def reason(self): + def reason(self) -> str: return self._http_exception.reason - def __repr__(self): + def __repr__(self) -> str: return "<SystemRoute {self.status}: {self.reason}>".format(self=self) class View(AbstractView): - async def _iter(self): + async def _iter(self) -> StreamResponse: if self.request.method not in hdrs.METH_ALL: self._raise_allowed_methods() method = getattr(self, self.request.method.lower(), None) @@ -740,60 +870,62 @@ class View(AbstractView): resp = await method() return resp - def __await__(self): + def __await__(self) -> Generator[Any, None, StreamResponse]: return self._iter().__await__() - def _raise_allowed_methods(self): + def _raise_allowed_methods(self) -> None: allowed_methods = { m for m in hdrs.METH_ALL if hasattr(self, m.lower())} raise HTTPMethodNotAllowed(self.request.method, allowed_methods) -class ResourcesView(Sized, Iterable, Container): +class ResourcesView(Sized, + Iterable[AbstractResource], + Container[AbstractResource]): - def __init__(self, resources): + def __init__(self, resources: List[AbstractResource]) -> None: self._resources = resources - def __len__(self): + def __len__(self) -> int: return len(self._resources) - def __iter__(self): + def __iter__(self) -> Iterator[AbstractResource]: yield from self._resources - def __contains__(self, resource): + def __contains__(self, resource: object) -> bool: return resource in self._resources -class RoutesView(Sized, Iterable, Container): +class RoutesView(Sized, Iterable[AbstractRoute], Container[AbstractRoute]): - def __init__(self, resources): - self._routes = [] + def __init__(self, resources: List[AbstractResource]): + self._routes = [] # type: List[AbstractRoute] for resource in resources: - for route_obj in resource: - self._routes.append(route_obj) + for route in resource: + self._routes.append(route) - def __len__(self): + def __len__(self) -> int: return len(self._routes) - def __iter__(self): + def __iter__(self) -> Iterator[AbstractRoute]: yield from self._routes - def __contains__(self, route_obj): - return route_obj in self._routes + def __contains__(self, route: object) -> bool: + return route in self._routes -class UrlDispatcher(AbstractRouter, collections.abc.Mapping): +class UrlDispatcher(AbstractRouter, Mapping[str, AbstractResource]): NAME_SPLIT_RE = re.compile(r'[.:-]') - def __init__(self): + def __init__(self) -> None: super().__init__() - self._resources = [] - self._named_resources = {} + self._resources = [] # type: List[AbstractResource] + self._named_resources = {} # type: Dict[str, AbstractResource] - async def resolve(self, request): + async def resolve(self, request: Request) -> AbstractMatchInfo: method = request.method - allowed_methods = set() + allowed_methods = set() # type: Set[str] for resource in self._resources: match_dict, allowed = await resource.resolve(request) @@ -808,28 +940,28 @@ class UrlDispatcher(AbstractRouter, collections.abc.Mapping): else: return MatchInfoError(HTTPNotFound()) - def __iter__(self): + def __iter__(self) -> Iterator[str]: return iter(self._named_resources) - def __len__(self): + def __len__(self) -> int: return len(self._named_resources) - def __contains__(self, name): - return name in self._named_resources + def __contains__(self, resource: object) -> bool: + return resource in self._named_resources - def __getitem__(self, name): + def __getitem__(self, name: str) -> AbstractResource: return self._named_resources[name] - def resources(self): + def resources(self) -> ResourcesView: return ResourcesView(self._resources) - def routes(self): + def routes(self) -> RoutesView: return RoutesView(self._resources) - def named_resources(self): + def named_resources(self) -> Mapping[str, AbstractResource]: return MappingProxyType(self._named_resources) - def register_resource(self, resource): + def register_resource(self, resource: AbstractResource) -> None: assert isinstance(resource, AbstractResource), \ 'Instance of AbstractResource class is required, got {!r}'.format( resource) @@ -854,14 +986,15 @@ class UrlDispatcher(AbstractRouter, collections.abc.Mapping): self._named_resources[name] = resource self._resources.append(resource) - def add_resource(self, path, *, name=None): + def add_resource(self, path: str, *, + name: Optional[str]=None) -> Resource: if path and not path.startswith('/'): raise ValueError("path should be started with / or be empty") # Reuse last added resource if path and name are the same if self._resources: resource = self._resources[-1] if resource.name == name and resource.raw_match(path): - return resource + return cast(Resource, resource) if not ('{' in path or '}' in path or ROUTE_RE.search(path)): url = URL.build(path=path) resource = PlainResource(url.raw_path, name=name) @@ -871,16 +1004,21 @@ class UrlDispatcher(AbstractRouter, collections.abc.Mapping): self.register_resource(resource) return resource - def add_route(self, method, path, handler, - *, name=None, expect_handler=None): + def add_route(self, method: str, path: str, + handler: Union[_WebHandler, AbstractView], + *, name: Optional[str]=None, + expect_handler: Optional[_ExpectHandler]=None + ) -> AbstractRoute: resource = self.add_resource(path, name=name) return resource.add_route(method, handler, expect_handler=expect_handler) - def add_static(self, prefix, path, *, name=None, expect_handler=None, - chunk_size=256 * 1024, - show_index=False, follow_symlinks=False, - append_version=False): + def add_static(self, prefix: str, path: PathLike, *, + name: Optional[str]=None, + expect_handler: Optional[_ExpectHandler]=None, + chunk_size: int=256 * 1024, + show_index: bool=False, follow_symlinks: bool=False, + append_version: bool=False) -> AbstractResource: """Add static files view. prefix - url prefix @@ -900,19 +1038,23 @@ class UrlDispatcher(AbstractRouter, collections.abc.Mapping): self.register_resource(resource) return resource - def add_head(self, path, handler, **kwargs): + def add_head(self, path: str, handler: _WebHandler, + **kwargs: Any) -> AbstractRoute: """ Shortcut for add_route with method HEAD """ return self.add_route(hdrs.METH_HEAD, path, handler, **kwargs) - def add_options(self, path, handler, **kwargs): + def add_options(self, path: str, handler: _WebHandler, + **kwargs: Any) -> AbstractRoute: """ Shortcut for add_route with method OPTIONS """ return self.add_route(hdrs.METH_OPTIONS, path, handler, **kwargs) - def add_get(self, path, handler, *, name=None, allow_head=True, **kwargs): + def add_get(self, path: str, handler: _WebHandler, *, + name: Optional[str]=None, allow_head: bool=True, + **kwargs: Any) -> AbstractRoute: """ Shortcut for add_route with method GET, if allow_head is true another route is added allowing head requests to the same endpoint @@ -922,45 +1064,50 @@ class UrlDispatcher(AbstractRouter, collections.abc.Mapping): resource.add_route(hdrs.METH_HEAD, handler, **kwargs) return resource.add_route(hdrs.METH_GET, handler, **kwargs) - def add_post(self, path, handler, **kwargs): + def add_post(self, path: str, handler: _WebHandler, + **kwargs: Any) -> AbstractRoute: """ Shortcut for add_route with method POST """ return self.add_route(hdrs.METH_POST, path, handler, **kwargs) - def add_put(self, path, handler, **kwargs): + def add_put(self, path: str, handler: _WebHandler, + **kwargs: Any) -> AbstractRoute: """ Shortcut for add_route with method PUT """ return self.add_route(hdrs.METH_PUT, path, handler, **kwargs) - def add_patch(self, path, handler, **kwargs): + def add_patch(self, path: str, handler: _WebHandler, + **kwargs: Any) -> AbstractRoute: """ Shortcut for add_route with method PATCH """ return self.add_route(hdrs.METH_PATCH, path, handler, **kwargs) - def add_delete(self, path, handler, **kwargs): + def add_delete(self, path: str, handler: _WebHandler, + **kwargs: Any) -> AbstractRoute: """ Shortcut for add_route with method DELETE """ return self.add_route(hdrs.METH_DELETE, path, handler, **kwargs) - def add_view(self, path, handler, **kwargs): + def add_view(self, path: str, handler: AbstractView, + **kwargs: Any) -> AbstractRoute: """ Shortcut for add_route with ANY methods for a class-based view """ return self.add_route(hdrs.METH_ANY, path, handler, **kwargs) - def freeze(self): + def freeze(self) -> None: super().freeze() for resource in self._resources: resource.freeze() - def add_routes(self, routes): + def add_routes(self, routes: Iterable[AbstractRouteDef]) -> None: """Append routes to route table. Parameter should be a sequence of RouteDef objects. """ - for route_obj in routes: - route_obj.register(self) + for route_def in routes: + route_def.register(self) diff --git a/aiohttp/web_ws.py b/aiohttp/web_ws.py index 1327395..72dae04 100644 --- a/aiohttp/web_ws.py +++ b/aiohttp/web_ws.py @@ -3,19 +3,23 @@ import base64 import binascii import hashlib import json +from typing import Any, Iterable, Optional, Tuple import async_timeout import attr from multidict import CIMultiDict from . import hdrs +from .abc import AbstractStreamWriter from .helpers import call_later, set_result from .http import (WS_CLOSED_MESSAGE, WS_CLOSING_MESSAGE, WS_KEY, WebSocketError, WebSocketReader, WebSocketWriter, WSMessage, WSMsgType, ws_ext_gen, ws_ext_parse) from .log import ws_logger from .streams import EofStream, FlowControlDataQueue +from .typedefs import JSONDecoder, JSONEncoder from .web_exceptions import HTTPBadRequest, HTTPException, HTTPMethodNotAllowed +from .web_request import BaseRequest from .web_response import StreamResponse @@ -27,30 +31,32 @@ THRESHOLD_CONNLOST_ACCESS = 5 @attr.s(frozen=True, slots=True) class WebSocketReady: ok = attr.ib(type=bool) - protocol = attr.ib(type=str) + protocol = attr.ib(type=Optional[str]) - def __bool__(self): + def __bool__(self) -> bool: return self.ok class WebSocketResponse(StreamResponse): def __init__(self, *, - timeout=10.0, receive_timeout=None, - autoclose=True, autoping=True, heartbeat=None, - protocols=(), compress=True, max_msg_size=4*1024*1024): + timeout: float=10.0, receive_timeout: Optional[float]=None, + autoclose: bool=True, autoping: bool=True, + heartbeat: Optional[float]=None, + protocols: Iterable[str]=(), + compress: bool=True, max_msg_size: int=4*1024*1024) -> None: super().__init__(status=101) self._protocols = protocols - self._ws_protocol = None - self._writer = None - self._reader = None + self._ws_protocol = None # type: Optional[str] + self._writer = None # type: Optional[WebSocketWriter] + self._reader = None # type: Optional[FlowControlDataQueue[WSMessage]] self._closed = False self._closing = False self._conn_lost = 0 - self._close_code = None - self._loop = None - self._waiting = None - self._exception = None + self._close_code = None # type: Optional[int] + self._loop = None # type: Optional[asyncio.AbstractEventLoop] + self._waiting = None # type: Optional[asyncio.Future[bool]] + self._exception = None # type: Optional[BaseException] self._timeout = timeout self._receive_timeout = receive_timeout self._autoclose = autoclose @@ -63,7 +69,7 @@ class WebSocketResponse(StreamResponse): self._compress = compress self._max_msg_size = max_msg_size - def _cancel_heartbeat(self): + def _cancel_heartbeat(self) -> None: if self._pong_response_cb is not None: self._pong_response_cb.cancel() self._pong_response_cb = None @@ -72,44 +78,48 @@ class WebSocketResponse(StreamResponse): self._heartbeat_cb.cancel() self._heartbeat_cb = None - def _reset_heartbeat(self): + def _reset_heartbeat(self) -> None: self._cancel_heartbeat() if self._heartbeat is not None: self._heartbeat_cb = call_later( self._send_heartbeat, self._heartbeat, self._loop) - def _send_heartbeat(self): + def _send_heartbeat(self) -> None: if self._heartbeat is not None and not self._closed: # fire-and-forget a task is not perfect but maybe ok for # sending ping. Otherwise we need a long-living heartbeat # task in the class. - self._loop.create_task(self._writer.ping()) + self._loop.create_task(self._writer.ping()) # type: ignore if self._pong_response_cb is not None: self._pong_response_cb.cancel() self._pong_response_cb = call_later( self._pong_not_received, self._pong_heartbeat, self._loop) - def _pong_not_received(self): + def _pong_not_received(self) -> None: if self._req is not None and self._req.transport is not None: self._closed = True self._close_code = 1006 self._exception = asyncio.TimeoutError() self._req.transport.close() - async def prepare(self, request): + async def prepare(self, request: BaseRequest) -> AbstractStreamWriter: # make pre-check to don't hide it by do_handshake() exceptions if self._payload_writer is not None: return self._payload_writer protocol, writer = self._pre_start(request) payload_writer = await super().prepare(request) + assert payload_writer is not None self._post_start(request, protocol, writer) await payload_writer.drain() return payload_writer - def _handshake(self, request): + def _handshake(self, request: BaseRequest) -> Tuple['CIMultiDict[str]', + str, + bool, + bool]: headers = request.headers if request.method != hdrs.METH_GET: raise HTTPMethodNotAllowed(request.method, [hdrs.METH_GET]) @@ -158,14 +168,15 @@ class WebSocketResponse(StreamResponse): accept_val = base64.b64encode( hashlib.sha1(key.encode() + WS_KEY).digest()).decode() - response_headers = CIMultiDict({hdrs.UPGRADE: 'websocket', - hdrs.CONNECTION: 'upgrade', - hdrs.TRANSFER_ENCODING: 'chunked', - hdrs.SEC_WEBSOCKET_ACCEPT: accept_val}) + response_headers = CIMultiDict( # type: ignore + {hdrs.UPGRADE: 'websocket', + hdrs.CONNECTION: 'upgrade', + hdrs.TRANSFER_ENCODING: 'chunked', + hdrs.SEC_WEBSOCKET_ACCEPT: accept_val}) notakeover = False - compress = self._compress - if compress: + compress = 0 + if self._compress: extensions = headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS) # Server side always get return with no exception. # If something happened, just drop compress extension @@ -177,10 +188,13 @@ class WebSocketResponse(StreamResponse): if protocol: response_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = protocol - return (response_headers, protocol, compress, notakeover) + return (response_headers, # type: ignore + protocol, + compress, + notakeover) - def _pre_start(self, request): - self._loop = request.loop + def _pre_start(self, request: BaseRequest) -> Tuple[str, WebSocketWriter]: + self._loop = request._loop headers, protocol, compress, notakeover = self._handshake( request) @@ -191,24 +205,29 @@ class WebSocketResponse(StreamResponse): self.headers.update(headers) self.force_close() self._compress = compress + transport = request._protocol.transport + assert transport is not None writer = WebSocketWriter(request._protocol, - request._protocol.transport, + transport, compress=compress, notakeover=notakeover) return protocol, writer - def _post_start(self, request, protocol, writer): + def _post_start(self, request: BaseRequest, + protocol: str, writer: WebSocketWriter) -> None: self._ws_protocol = protocol self._writer = writer + loop = self._loop + assert loop is not None self._reader = FlowControlDataQueue( - request._protocol, limit=2 ** 16, loop=self._loop) + request._protocol, limit=2 ** 16, loop=loop) request.protocol.set_parser(WebSocketReader( self._reader, self._max_msg_size, compress=self._compress)) # disable HTTP keepalive for WebSocket request.protocol.keep_alive(False) - def can_prepare(self, request): + def can_prepare(self, request: BaseRequest) -> WebSocketReady: if self._writer is not None: raise RuntimeError('Already started') try: @@ -219,43 +238,44 @@ class WebSocketResponse(StreamResponse): return WebSocketReady(True, protocol) @property - def closed(self): + def closed(self) -> bool: return self._closed @property - def close_code(self): + def close_code(self) -> Optional[int]: return self._close_code @property - def ws_protocol(self): + def ws_protocol(self) -> Optional[str]: return self._ws_protocol @property - def compress(self): + def compress(self) -> bool: return self._compress - def exception(self): + def exception(self) -> Optional[BaseException]: return self._exception - async def ping(self, message='b'): + async def ping(self, message: bytes=b'') -> None: if self._writer is None: raise RuntimeError('Call .prepare() first') await self._writer.ping(message) - async def pong(self, message='b'): + async def pong(self, message: bytes=b'') -> None: # unsolicited pong if self._writer is None: raise RuntimeError('Call .prepare() first') await self._writer.pong(message) - async def send_str(self, data, compress=None): + async def send_str(self, data: str, compress: Optional[bool]=None) -> None: if self._writer is None: raise RuntimeError('Call .prepare() first') if not isinstance(data, str): raise TypeError('data argument must be str (%r)' % type(data)) await self._writer.send(data, binary=False, compress=compress) - async def send_bytes(self, data, compress=None): + async def send_bytes(self, data: bytes, + compress: Optional[bool]=None) -> None: if self._writer is None: raise RuntimeError('Call .prepare() first') if not isinstance(data, (bytes, bytearray, memoryview)): @@ -263,10 +283,11 @@ class WebSocketResponse(StreamResponse): type(data)) await self._writer.send(data, binary=True, compress=compress) - async def send_json(self, data, compress=None, *, dumps=json.dumps): + async def send_json(self, data: Any, compress: Optional[bool]=None, *, + dumps: JSONEncoder=json.dumps) -> None: await self.send_str(dumps(data), compress=compress) - async def write_eof(self): + async def write_eof(self) -> None: # type: ignore if self._eof_sent: return if self._payload_writer is None: @@ -275,23 +296,27 @@ class WebSocketResponse(StreamResponse): await self.close() self._eof_sent = True - async def close(self, *, code=1000, message=b''): + async def close(self, *, code: int=1000, message: bytes=b'') -> bool: if self._writer is None: raise RuntimeError('Call .prepare() first') self._cancel_heartbeat() + reader = self._reader + assert reader is not None # we need to break `receive()` cycle first, # `close()` may be called from different task if self._waiting is not None and not self._closed: - self._reader.feed_data(WS_CLOSING_MESSAGE, 0) + reader.feed_data(WS_CLOSING_MESSAGE, 0) await self._waiting if not self._closed: self._closed = True try: await self._writer.close(code, message) - await self._payload_writer.drain() + writer = self._payload_writer + assert writer is not None + await writer.drain() except (asyncio.CancelledError, asyncio.TimeoutError): self._close_code = 1006 raise @@ -303,9 +328,11 @@ class WebSocketResponse(StreamResponse): if self._closing: return True + reader = self._reader + assert reader is not None try: with async_timeout.timeout(self._timeout, loop=self._loop): - msg = await self._reader.read() + msg = await reader.read() except asyncio.CancelledError: self._close_code = 1006 raise @@ -324,10 +351,12 @@ class WebSocketResponse(StreamResponse): else: return False - async def receive(self, timeout=None): + async def receive(self, timeout: Optional[float]=None) -> WSMessage: if self._reader is None: raise RuntimeError('Call .prepare() first') + loop = self._loop + assert loop is not None while True: if self._waiting is not None: raise RuntimeError( @@ -342,7 +371,7 @@ class WebSocketResponse(StreamResponse): return WS_CLOSING_MESSAGE try: - self._waiting = self._loop.create_future() + self._waiting = loop.create_future() try: with async_timeout.timeout( timeout or self._receive_timeout, loop=self._loop): @@ -385,7 +414,7 @@ class WebSocketResponse(StreamResponse): return msg - async def receive_str(self, *, timeout=None): + async def receive_str(self, *, timeout: Optional[float]=None) -> str: msg = await self.receive(timeout) if msg.type != WSMsgType.TEXT: raise TypeError( @@ -393,7 +422,7 @@ class WebSocketResponse(StreamResponse): msg.type, msg.data)) return msg.data - async def receive_bytes(self, *, timeout=None): + async def receive_bytes(self, *, timeout: Optional[float]=None) -> bytes: msg = await self.receive(timeout) if msg.type != WSMsgType.BINARY: raise TypeError( @@ -401,17 +430,18 @@ class WebSocketResponse(StreamResponse): msg.data)) return msg.data - async def receive_json(self, *, loads=json.loads, timeout=None): + async def receive_json(self, *, loads: JSONDecoder=json.loads, + timeout: Optional[float]=None) -> Any: data = await self.receive_str(timeout=timeout) return loads(data) - async def write(self, data): + async def write(self, data: bytes) -> None: raise RuntimeError("Cannot call .write() for websocket") - def __aiter__(self): + def __aiter__(self) -> 'WebSocketResponse': return self - async def __anext__(self): + async def __anext__(self) -> WSMessage: msg = await self.receive() if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING, diff --git a/aiohttp/worker.py b/aiohttp/worker.py index a4b32c4..53bf828 100644 --- a/aiohttp/worker.py +++ b/aiohttp/worker.py @@ -6,19 +6,24 @@ import re import signal import sys from contextlib import suppress +from types import FrameType +from typing import Any, Optional # noqa from gunicorn.config import AccessLogFormat as GunicornAccessLogFormat from gunicorn.workers import base from aiohttp import web -from .helpers import AccessLogger, set_result +from .helpers import set_result +from .web_log import AccessLogger try: import ssl + SSLContext = ssl.SSLContext # noqa except ImportError: # pragma: no cover ssl = None # type: ignore + SSLContext = object # type: ignore __all__ = ('GunicornWebWorker', @@ -31,15 +36,15 @@ class GunicornWebWorker(base.Worker): DEFAULT_AIOHTTP_LOG_FORMAT = AccessLogger.LOG_FORMAT DEFAULT_GUNICORN_LOG_FORMAT = GunicornAccessLogFormat.default - def __init__(self, *args, **kw): # pragma: no cover + def __init__(self, *args: Any, **kw: Any) -> None: # pragma: no cover super().__init__(*args, **kw) - self._runner = None - self._task = None + self._runner = None # type: Optional[web.AppRunner] + self._task = None # type: Optional[asyncio.Task[None]] self.exit_code = 0 - self._notify_waiter = None + self._notify_waiter = None # type: Optional[asyncio.Future[bool]] - def init_process(self): + def init_process(self) -> None: # create new event_loop after fork asyncio.get_event_loop().close() @@ -48,7 +53,7 @@ class GunicornWebWorker(base.Worker): super().init_process() - def run(self): + def run(self) -> None: access_log = self.log.access_log if self.cfg.accesslog else None params = dict( logger=self.log, @@ -56,36 +61,42 @@ class GunicornWebWorker(base.Worker): access_log=access_log, access_log_format=self._get_valid_log_format( self.cfg.access_log_format)) - if asyncio.iscoroutinefunction(self.wsgi): - self.wsgi = self.loop.run_until_complete(self.wsgi()) + if asyncio.iscoroutinefunction(self.wsgi): # type: ignore + self.wsgi = self.loop.run_until_complete( + self.wsgi()) # type: ignore self._runner = web.AppRunner(self.wsgi, **params) self.loop.run_until_complete(self._runner.setup()) self._task = self.loop.create_task(self._run()) with suppress(Exception): # ignore all finalization problems self.loop.run_until_complete(self._task) - if hasattr(self.loop, 'shutdown_asyncgens'): - self.loop.run_until_complete(self.loop.shutdown_asyncgens()) + if sys.version_info >= (3, 6): + if hasattr(self.loop, 'shutdown_asyncgens'): + self.loop.run_until_complete(self.loop.shutdown_asyncgens()) self.loop.close() sys.exit(self.exit_code) - async def _run(self): + async def _run(self) -> None: ctx = self._create_ssl_context(self.cfg) if self.cfg.is_ssl else None + runner = self._runner + assert runner is not None + server = runner.server + assert server is not None for sock in self.sockets: site = web.SockSite( - self._runner, sock, ssl_context=ctx, + runner, sock, ssl_context=ctx, shutdown_timeout=self.cfg.graceful_timeout / 100 * 95) await site.start() # If our parent changed then we shut down. pid = os.getpid() try: - while self.alive: + while self.alive: # type: ignore self.notify() - cnt = self._runner.server.requests_count + cnt = server.requests_count if self.cfg.max_requests and cnt > self.cfg.max_requests: self.alive = False self.log.info("Max requests, shutting down: %s", self) @@ -98,17 +109,19 @@ class GunicornWebWorker(base.Worker): except BaseException: pass - await self._runner.cleanup() + await runner.cleanup() - def _wait_next_notify(self): + def _wait_next_notify(self) -> 'asyncio.Future[bool]': self._notify_waiter_done() - self._notify_waiter = waiter = self.loop.create_future() + loop = self.loop + assert loop is not None + self._notify_waiter = waiter = loop.create_future() self.loop.call_later(1.0, self._notify_waiter_done, waiter) return waiter - def _notify_waiter_done(self, waiter=None): + def _notify_waiter_done(self, waiter: 'asyncio.Future[bool]'=None) -> None: if waiter is None: waiter = self._notify_waiter if waiter is not None: @@ -117,7 +130,7 @@ class GunicornWebWorker(base.Worker): if waiter is self._notify_waiter: self._notify_waiter = None - def init_signals(self): + def init_signals(self) -> None: # Set up signals through the event loop API. self.loop.add_signal_handler(signal.SIGQUIT, self.handle_quit, @@ -143,7 +156,7 @@ class GunicornWebWorker(base.Worker): signal.siginterrupt(signal.SIGTERM, False) signal.siginterrupt(signal.SIGUSR1, False) - def handle_quit(self, sig, frame): + def handle_quit(self, sig: int, frame: FrameType) -> None: self.alive = False # worker_int callback @@ -152,14 +165,14 @@ class GunicornWebWorker(base.Worker): # wakeup closing process self._notify_waiter_done() - def handle_abort(self, sig, frame): + def handle_abort(self, sig: int, frame: FrameType) -> None: self.alive = False self.exit_code = 1 self.cfg.worker_abort(self) sys.exit(1) @staticmethod - def _create_ssl_context(cfg): + def _create_ssl_context(cfg: Any) -> 'SSLContext': """ Creates SSLContext instance for usage in asyncio.create_server. See ssl.SSLSocket.__init__ for more details. @@ -176,7 +189,7 @@ class GunicornWebWorker(base.Worker): ctx.set_ciphers(cfg.ciphers) return ctx - def _get_valid_log_format(self, source_format): + def _get_valid_log_format(self, source_format: str) -> str: if source_format == self.DEFAULT_GUNICORN_LOG_FORMAT: return self.DEFAULT_AIOHTTP_LOG_FORMAT elif re.search(r'%\([^\)]+\)', source_format): @@ -193,7 +206,7 @@ class GunicornWebWorker(base.Worker): class GunicornUVLoopWebWorker(GunicornWebWorker): - def init_process(self): + def init_process(self) -> None: import uvloop # Close any existing event loop before setting a @@ -210,7 +223,7 @@ class GunicornUVLoopWebWorker(GunicornWebWorker): class GunicornTokioWebWorker(GunicornWebWorker): - def init_process(self): # pragma: no cover + def init_process(self) -> None: # pragma: no cover import tokio # Close any existing event loop before setting a diff --git a/codecov.yml b/codecov.yml index 4487fb3..0ac68c4 100644 --- a/codecov.yml +++ b/codecov.yml @@ -3,3 +3,33 @@ coverage: status: project: no + +flags: + library: + paths: + - aiohttp/ + configs: + paths: + - requirements/ + - ".git*" + - "*.toml" + - "*.yml" + changelog: + paths: + - CHANGES/ + - CHANGES.rst + docs: + paths: + - docs/ + - "*.md" + - "*.rst" + - "*.txt" + tests: + paths: + - tests/ + tools: + paths: + - tools/ + third-party: + paths: + - vendor/ diff --git a/debian/changelog b/debian/changelog index bf67796..feddc5c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +python-aiohttp (3.5.1-1) unstable; urgency=medium + + * New upstream release + * Remove idna_ssl patch - no longer needed in Python >= 3.7 + * Standards-Version bumped to 4.3.0 (no changes needed) + + -- Piotr Ożarowski <piotr@debian.org> Mon, 31 Dec 2018 18:15:56 +0100 + python-aiohttp (3.4.4-1~exp1) experimental; urgency=medium * Team upload diff --git a/debian/control b/debian/control index dba1fc6..ba5e733 100644 --- a/debian/control +++ b/debian/control @@ -20,7 +20,7 @@ Build-Depends: debhelper (>= 11), python3-pytest-mock, python3-chardet, python3-gunicorn -Standards-Version: 4.2.1 +Standards-Version: 4.3.0 Homepage: https://aiohttp.readthedocs.org Vcs-Git: https://salsa.debian.org/python-team/modules/python-aiohttp.git Vcs-Browser: https://salsa.debian.org/python-team/modules/python-aiohttp diff --git a/debian/idna_ssl.py b/debian/idna_ssl.py deleted file mode 100644 index 14f9db9..0000000 --- a/debian/idna_ssl.py +++ /dev/null @@ -1,31 +0,0 @@ -import ssl - -import idna - -__version__ = '1.0.0' - -real_match_hostname = ssl.match_hostname - - -def patched_match_hostname(cert, hostname): - try: - hostname = idna.encode(hostname, uts46=True).decode('ascii') - except UnicodeError: - hostname = hostname.encode('idna').decode('ascii') - - return real_match_hostname(cert, hostname) - - -def patch_match_hostname(): - if hasattr(ssl.match_hostname, 'patched'): - return - - ssl.match_hostname = patched_match_hostname - ssl.match_hostname.patched = True - - -def reset_match_hostname(): - if not hasattr(ssl.match_hostname, 'patched'): - return - - ssl.match_hostname = real_match_hostname diff --git a/debian/patches/0001-bundle-idna_ssl.patch b/debian/patches/0001-bundle-idna_ssl.patch deleted file mode 100644 index 91d8a2c..0000000 --- a/debian/patches/0001-bundle-idna_ssl.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 3de99c20ba2eea70259b34f6c4cb4b3b7704834e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Piotr=20O=C5=BCarowski?= <piotr@debian.org> -Date: Wed, 14 Feb 2018 13:55:21 +0100 -Subject: bundle idna_ssl - -yeah, usually we do that the other way around ;) - -this is just a temporary fix and hopefully will not be released with -Debian stable ---- - aiohttp/helpers.py | 2 +- - setup.py | 3 +-- - 2 files changed, 2 insertions(+), 3 deletions(-) - -diff --git a/aiohttp/helpers.py b/aiohttp/helpers.py -index cede174..401a56f 100644 ---- a/aiohttp/helpers.py -+++ b/aiohttp/helpers.py -@@ -38,7 +38,7 @@ PY_36 = sys.version_info >= (3, 6) - PY_37 = sys.version_info >= (3, 7) - - if not PY_37: -- import idna_ssl -+ from aiohttp import idna_ssl - idna_ssl.patch_match_hostname() - - -diff --git a/setup.py b/setup.py -index ce23fc1..65a15c1 100644 ---- a/setup.py -+++ b/setup.py -@@ -90,8 +90,7 @@ install_requires = [ - 'chardet>=2.0,<4.0', - 'multidict>=4.0,<5.0', - 'async_timeout>=3.0,<4.0', -- 'yarl>=1.0,<2.0', -- 'idna-ssl>=1.0; python_version<"3.7"', -+ 'yarl>=1.0,<2.0' - ] - - diff --git a/debian/patches/series b/debian/patches/series index c1e3308..426e934 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1 @@ -0001-bundle-idna_ssl.patch 0002-Use-local-install-of-jquery.patch diff --git a/debian/python3-aiohttp.pyinstall b/debian/python3-aiohttp.pyinstall deleted file mode 100644 index 4cefa31..0000000 --- a/debian/python3-aiohttp.pyinstall +++ /dev/null @@ -1 +0,0 @@ -debian/idna_ssl.py aiohttp diff --git a/docs/_static/aiohttp-icon-128x128.png b/docs/_static/aiohttp-icon-128x128.png Binary files differindex 91bef23..e486a04 100644 --- a/docs/_static/aiohttp-icon-128x128.png +++ b/docs/_static/aiohttp-icon-128x128.png diff --git a/docs/built_with.rst b/docs/built_with.rst index fd32ee0..b4d16fc 100644 --- a/docs/built_with.rst +++ b/docs/built_with.rst @@ -22,3 +22,4 @@ project, pointing to `<https://github.com/aio-libs/aiohttp>`_. * `Arsenic <https://github.com/hde/arsenic>`_ Async WebDriver. * `Home Assistant <https://home-assistant.io>`_ Home Automation Platform. * `Backend.AI <https://backend.ai>`_ Code execution API service. +* `doh-proxy <https://github.com/facebookexperimental/doh-proxy>`_ DNS Over HTTPS Proxy. diff --git a/docs/client_quickstart.rst b/docs/client_quickstart.rst index 6072c42..09078c4 100644 --- a/docs/client_quickstart.rst +++ b/docs/client_quickstart.rst @@ -61,6 +61,15 @@ Other HTTP methods are available as well:: A session contains a connection pool inside. Connection reusage and keep-alives (both are on by default) may speed up total performance. +A session context manager usage is not mandatory +but ``await session.close()`` method +should be called in this case, e.g.:: + + session = aiohttp.ClientSession() + async with session.get('...'): + # ... + await session.close() + Passing Parameters In URLs ========================== @@ -108,7 +117,7 @@ is not encoded by library. Note that ``+`` is not encoded:: Canonization encodes *host* part by :term:`IDNA` codec and applies :term:`requoting` to *path* and *query* parts. - For example ``URL('http://example.com/путь%30?a=%31')`` is converted to + For example ``URL('http://example.com/путь/%30?a=%31')`` is converted to ``URL('http://example.com/%D0%BF%D1%83%D1%82%D1%8C/0?a=1')``. Sometimes canonization is not desirable if server accepts exact @@ -126,7 +135,7 @@ is not encoded by library. Note that ``+`` is not encoded:: Response Content and Status Code ================================ -We can read the content of the server's response and it's status +We can read the content of the server's response and its status code. Consider the GitHub time-line again:: async with session.get('https://api.github.com/events') as resp: @@ -416,7 +425,7 @@ Supported :class:`ClientTimeout` fields are: ``connect`` - Total timeout for acquiring a connection from pool. The time + The time consists connection establishment for a new connection or waiting for a free connection from a pool if pool connection limits are exceeded. @@ -431,7 +440,8 @@ Supported :class:`ClientTimeout` fields are: The maximum allowed timeout for period between reading a new data portion from a peer. -All fields are floats, ``None`` or ``0`` disables a particular timeout check. +All fields are floats, ``None`` or ``0`` disables a particular timeout check, see the +:class:`ClientTimeout` reference for defaults and additional details. Thus the default timeout is:: diff --git a/docs/client_reference.rst b/docs/client_reference.rst index dfeda51..cfa8d7b 100644 --- a/docs/client_reference.rst +++ b/docs/client_reference.rst @@ -48,7 +48,10 @@ The client session supports the context manager protocol for self closing. timeout=sentinel, \ raise_for_status=False, \ connector_owner=True, \ - auto_decompress=True, proxies=None) + auto_decompress=True, \ + requote_redirect_url=False, \ + trust_env=False, \ + trace_configs=None) The class for creating client sessions and making requests. @@ -176,6 +179,17 @@ The client session supports the context manager protocol for self closing. Added support for ``~/.netrc`` file. + :param bool requote_redirect_url: Apply *URL requoting* for redirection URLs if + automatic redirection is enabled (``True`` by + default). + + .. versionadded:: 3.5 + + :param trace_configs: A list of :class:`TraceConfig` instances used for client + tracing. ``None`` (default) is used for request tracing + disabling. See :ref:`aiohttp-client-tracing-reference` for + more information. + .. attribute:: closed ``True`` if the session has been closed, ``False`` otherwise. @@ -207,14 +221,20 @@ The client session supports the context manager protocol for self closing. .. note:: This parameter affects all subsequent requests. + .. deprecated:: 3.5 + + The attribute modification is deprecated. + .. attribute:: loop A loop instance used for session creation. A read-only property. + .. deprecated:: 3.5 + .. comethod:: request(method, url, *, params=None, data=None, json=None,\ - headers=None, skip_auto_headers=None, \ + cookies=None, headers=None, skip_auto_headers=None, \ auth=None, allow_redirects=True,\ max_redirects=10,\ compress=None, chunked=None, expect100=False, raise_for_status=None,\ @@ -253,6 +273,14 @@ The client session supports the context manager protocol for self closing. (optional). *json* and *data* parameters could not be used at the same time. + :param dict cookies: HTTP Cookies to send with + the request (optional) + + Global session cookies and the explicitly set cookies will be merged + when sending the request. + + .. versionadded:: 3.5 + :param dict headers: HTTP Headers to send with the request (optional) @@ -506,7 +534,8 @@ The client session supports the context manager protocol for self closing. :return ClientResponse: a :class:`client response <ClientResponse>` object. - .. comethod:: ws_connect(url, *, protocols=(), timeout=10.0,\ + .. comethod:: ws_connect(url, *, method='GET', \ + protocols=(), timeout=10.0,\ receive_timeout=None,\ auth=None,\ autoclose=True,\ @@ -626,6 +655,11 @@ The client session supports the context manager protocol for self closing. .. versionadded:: 3.3 + :param str method: HTTP method to establish WebSocket connection, + ``'GET'`` by default. + + .. versionadded:: 3.5 + .. comethod:: close() @@ -658,9 +692,9 @@ certification chaining. allow_redirects=True, max_redirects=10, \ encoding='utf-8', \ version=HttpVersion(major=1, minor=1), \ - compress=None, chunked=None, expect100=False, raise_for_status=None, \ + compress=None, chunked=None, expect100=False, raise_for_status=False, \ connector=None, loop=None,\ - read_until_eof=True) + read_until_eof=True, timeout=sentinel) :async-with: @@ -719,6 +753,9 @@ certification chaining. does not have Content-Length header. ``True`` by default (optional). + :param timeout: a :class:`ClientTimeout` settings structure, 5min + total timeout by default. + :param loop: :ref:`event loop<asyncio-event-loop>` used for processing HTTP requests. If param is ``None``, :func:`asyncio.get_event_loop` @@ -824,7 +861,7 @@ BaseConnector Read-only property. - .. method:: close() + .. comethod:: close() Close all opened connections. @@ -1043,6 +1080,8 @@ Connection Event loop used for connection + .. deprecated:: 3.5 + .. attribute:: transport Connection transport @@ -1059,13 +1098,6 @@ Connection later if timeout (30 seconds by default) for connection was not expired. - .. method:: detach() - - Detach underlying socket from connection. - - Underlying socket is not closed, next :meth:`close` or - :meth:`release` calls don't return socket to free pool. - Response object --------------- @@ -1108,7 +1140,7 @@ Response object .. attribute:: real_url - Unmodified URL of request (:class:`~yarl.URL`). + Unmodified URL of request with URL fragment unstripped (:class:`~yarl.URL`). .. versionadded:: 3.2 @@ -1827,13 +1859,6 @@ Response errors Derived from :exc:`ClientResponseError` -.. class:: WSServerHandshakeError - - Web socket server response error. - - Derived from :exc:`ClientResponseError` - - .. class:: ContentTypeError Invalid content type. diff --git a/docs/contributing.rst b/docs/contributing.rst index 373d0b2..b908c35 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -29,6 +29,15 @@ Workflow is pretty straightforward: 7. Optionally make backport Pull Request(s) for landing a bug fix into released aiohttp versions. +.. note:: + + The project uses *Squash-and-Merge* strategy for *GitHub Merge* button. + + Basically it means that there is **no need to rebase** a Pull Request against + *master* branch. Just ``git merge`` *master* into your working copy (a fork) if + needed. The Pull Request is automatically squashed into the single commit + once the PR is accepted. + Preconditions for running aiohttp test suite -------------------------------------------- diff --git a/docs/logging.rst b/docs/logging.rst index 3f981e2..721b520 100644 --- a/docs/logging.rst +++ b/docs/logging.rst @@ -28,24 +28,24 @@ configuring whole loggers in your application. Access logs ----------- -Access log by default is switched on and uses ``'aiohttp.access'`` -logger name. +Access logs are enabled by default. If the `debug` flag is set, and the default +logger ``'aiohttp.access'`` is used, access logs will be output to +:obj:`~sys.stderr` if no handlers are attached. +Furthermore, if the default logger has no log level set, the log level will be +set to :obj:`logging.DEBUG`. -The log may be controlled by :meth:`aiohttp.web.AppRunner` and +This logging may be controlled by :meth:`aiohttp.web.AppRunner` and :func:`aiohttp.web.run_app`. - -Pass *access_log* parameter with value of :class:`logging.Logger` -instance to override default logger. +To override the default logger, pass an instance of :class:`logging.Logger` to +override the default logger. .. note:: - Use ``web.run_app(app, access_log=None)`` for disabling access logs. - + Use ``web.run_app(app, access_log=None)`` to disable access logs. -Other parameter called *access_log_format* may be used for specifying log -format (see below). +In addition, *access_log_format* may be used to specify the log format. .. _aiohttp-logging-access-log-format-spec: @@ -71,7 +71,7 @@ request and response: +--------------+---------------------------------------------------------+ | ``%s`` | Response status code | +--------------+---------------------------------------------------------+ -| ``%b`` | Size of response in bytes, excluding HTTP headers | +| ``%b`` | Size of response in bytes, including HTTP headers | +--------------+---------------------------------------------------------+ | ``%T`` | The time taken to serve the request, in seconds | +--------------+---------------------------------------------------------+ @@ -85,7 +85,7 @@ request and response: | ``%{FOO}o`` | ``response.headers['FOO']`` | +--------------+---------------------------------------------------------+ -Default access log format is:: +The default access log format is:: '%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"' @@ -93,7 +93,7 @@ Default access log format is:: *access_log_class* introduced. -Example of drop-in replacement for :class:`aiohttp.helpers.AccessLogger`:: +Example of a drop-in replacement for :class:`aiohttp.helpers.AccessLogger`:: from aiohttp.abc import AbstractAccessLogger @@ -110,13 +110,13 @@ Example of drop-in replacement for :class:`aiohttp.helpers.AccessLogger`:: Gunicorn access logs ^^^^^^^^^^^^^^^^^^^^ When `Gunicorn <http://docs.gunicorn.org/en/latest/index.html>`_ is used for -:ref:`deployment <aiohttp-deployment-gunicorn>` its default access log format +:ref:`deployment <aiohttp-deployment-gunicorn>`, its default access log format will be automatically replaced with the default aiohttp's access log format. If Gunicorn's option access_logformat_ is -specified explicitly it should use aiohttp's format specification. +specified explicitly, it should use aiohttp's format specification. -Gunicorn access log works only if accesslog_ is specified explicitly in your +Gunicorn's access log works only if accesslog_ is specified explicitly in your config or as a command line option. This configuration can be either a path or ``'-'``. If the application uses a custom logging setup intercepting the ``'gunicorn.access'`` logger, @@ -129,13 +129,13 @@ access log file upon every startup. Error logs ---------- -*aiohttp.web* uses logger named ``'aiohttp.server'`` to store errors +:mod:`aiohttp.web` uses a logger named ``'aiohttp.server'`` to store errors given on web requests handling. -The log is enabled by default. +This log is enabled by default. -To use different logger name please pass *logger* parameter -(:class:`logging.Logger` instance) to :meth:`aiohttp.web.AppRunner` constructor. +To use a different logger name, pass *logger* (:class:`logging.Logger` +instance) to the :meth:`aiohttp.web.AppRunner` constructor. .. _access_logformat: diff --git a/docs/old-logo.png b/docs/old-logo.png Binary files differnew file mode 100644 index 0000000..eac760b --- /dev/null +++ b/docs/old-logo.png diff --git a/docs/powered_by.rst b/docs/powered_by.rst index 7343939..e00b661 100644 --- a/docs/powered_by.rst +++ b/docs/powered_by.rst @@ -35,3 +35,4 @@ make a Pull Request! * `Prom.ua <https://prom.ua/>`_ - Online trading platform * `globo.com <https://www.globo.com/>`_ - (some parts) Brazilian largest media portal * `Glose <https://www.glose.com/>`_ - Social reader for E-Books +* `Emoji Generator <https://emoji-gen.ninja>`_ - Text icon generator diff --git a/docs/signals.rst b/docs/signals.rst index 4251f79..1126c2f 100644 --- a/docs/signals.rst +++ b/docs/signals.rst @@ -5,7 +5,7 @@ Signals Signal is a list of registered asynchronous callbacks. -The signal's life-cycle has two stages: after creation it's content +The signal's life-cycle has two stages: after creation its content could be filled by using standard list operations: ``sig.append()`` etc. diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index c88ba8f..c83dab6 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -9,6 +9,7 @@ alives api api’s app +apps app’s arg Arsenic @@ -30,6 +31,7 @@ BaseEventLoop basename BasicAuth BodyPartReader +boolean botocore Bugfixes builtin diff --git a/docs/testing.rst b/docs/testing.rst index ab7c398..be52da7 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -297,6 +297,8 @@ functionality, the AioHTTPTestCase is provided:: The event loop in which the application and server are running. + .. deprecated:: 3.5 + .. attribute:: app The application returned by :meth:`get_app` @@ -483,7 +485,7 @@ High level test creation:: from aiohttp import request # loop_context is provided as a utility. You can use any - # asyncio.BaseEventLoop class in it's place. + # asyncio.BaseEventLoop class in its place. with loop_context() as loop: app = _create_example_app() with TestClient(TestServer(app), loop=loop) as client: diff --git a/docs/third_party.rst b/docs/third_party.rst index 1d3dace..608f23d 100644 --- a/docs/third_party.rst +++ b/docs/third_party.rst @@ -231,3 +231,6 @@ period ask to raise the status. for `Azure Application Insights <https://azure.microsoft.com/en-us/services/application-insights/>`_ implemented using ``aiohttp`` client, including a middleware for ``aiohttp`` servers to collect web apps telemetry. + +- `aiogmaps <https://github.com/hzlmn/aiogmaps>`_ + Asynchronous client for Google Maps API Web Services. Python 3.6+ required. diff --git a/docs/web_advanced.rst b/docs/web_advanced.rst index 5f9981d..a2d1744 100644 --- a/docs/web_advanced.rst +++ b/docs/web_advanced.rst @@ -393,6 +393,82 @@ and safe to use as the key. Otherwise, something based on your company name/url would be satisfactory (i.e. ``org.company.app``). + +.. _aiohttp-web-contextvars: + + +ContextVars support +------------------- + +Starting from Python 3.7 asyncio has :mod:`Context Variables <contextvars>` as a +context-local storage (a generalization of thread-local concept that works with asyncio +tasks also). + + +*aiohttp* server supports it in the following way: + +* A server inherits the current task's context used when creating it. + :func:`aiohttp.web.run_app()` runs a task for handling all underlying jobs running + the app, but alternatively :ref:`aiohttp-web-app-runners` can be used. + +* Application initialization / finalization events (:attr:`Application.cleanup_ctx`, + :attr:`Application.on_startup` and :attr:`Application.on_shutdown`, + :attr:`Application.on_cleanup`) are executed inside the same context. + + E.g. all context modifications made on application startup a visible on teardown. + +* On every request handling *aiohttp* creates a context copy. :term:`web-handler` has + all variables installed on initialization stage. But the context modification made by + a handler or middleware is invisible to another HTTP request handling call. + +An example of context vars usage:: + + from contextvars import ContextVar + + from aiohttp import web + + VAR = ContextVar('VAR', default='default') + + + async def coro(): + return VAR.get() + + + async def handler(request): + var = VAR.get() + VAR.set('handler') + ret = await coro() + return web.Response(text='\n'.join([var, + ret])) + + + async def on_startup(app): + print('on_startup', VAR.get()) + VAR.set('on_startup') + + + async def on_cleanup(app): + print('on_cleanup', VAR.get()) + VAR.set('on_cleanup') + + + async def init(): + print('init', VAR.get()) + VAR.set('init') + app = web.Application() + app.router.add_get('/', handler) + + app.on_startup.append(on_startup) + app.on_cleanup.append(on_cleanup) + return app + + + web.run_app(init()) + print('done', VAR.get()) + +.. versionadded:: 3.5 + + .. _aiohttp-web-middlewares: Middlewares diff --git a/docs/web_lowlevel.rst b/docs/web_lowlevel.rst index 42485f2..696c58d 100644 --- a/docs/web_lowlevel.rst +++ b/docs/web_lowlevel.rst @@ -55,9 +55,13 @@ The following code demonstrates very trivial usage example:: return web.Response(text="OK") - async def main(loop): + async def main(): server = web.Server(handler) - await loop.create_server(server, "127.0.0.1", 8080) + runner = web.ServerRunner(server) + await runner.setup() + site = web.TCPSite(runner, 'localhost', 8080) + await site.start() + print("======= Serving on http://127.0.0.1:8080/ ======") # pause here for very long time by serving HTTP requests and @@ -68,7 +72,7 @@ The following code demonstrates very trivial usage example:: loop = asyncio.get_event_loop() try: - loop.run_until_complete(main(loop)) + loop.run_until_complete(main()) except KeyboardInterrupt: pass loop.close() @@ -79,7 +83,8 @@ In the snippet we have ``handler`` which returns a regular This *handler* is processed by ``server`` (:class:`Server` which acts as *protocol factory*). Network communication is created by -``loop.create_server`` call to serve ``http://127.0.0.1:8080/``. +:ref:`runners API <aiohttp-web-app-runners-reference>` to serve +``http://127.0.0.1:8080/``. The handler should process every request for every *path*, e.g. ``GET``, ``POST``, Web-Socket. diff --git a/docs/web_quickstart.rst b/docs/web_quickstart.rst index 8459d88..0026ebb 100644 --- a/docs/web_quickstart.rst +++ b/docs/web_quickstart.rst @@ -129,7 +129,7 @@ Wildcard *HTTP method* is also supported by :func:`route` or :meth:`RouteTableDef.route`, allowing a handler to serve incoming requests on a *path* having **any** *HTTP method*:: - app.add_routes[web.route('*', '/path', all_handler)] + app.add_routes([web.route('*', '/path', all_handler)]) The *HTTP method* can be queried later in the request handler using the :attr:`Request.method` property. diff --git a/docs/web_reference.rst b/docs/web_reference.rst index bc3d476..8f3bd0f 100644 --- a/docs/web_reference.rst +++ b/docs/web_reference.rst @@ -225,7 +225,7 @@ and :ref:`aiohttp-web-signals` handlers. Read-only :class:`asyncio.AbstractEventLoop` property. - .. versionadded:: 2.3 + .. deprecated:: 3.5 .. attribute:: cookies @@ -467,7 +467,7 @@ and :ref:`aiohttp-web-signals` handlers. .. class:: Request - An request used for receiving request's information by *web handler*. + A request used for receiving request's information by *web handler*. Every :ref:`handler<aiohttp-web-handler>` accepts a request instance as the first positional parameter. @@ -805,7 +805,8 @@ Response ^^^^^^^^ .. class:: Response(*, body=None, status=200, reason=None, text=None, \ - headers=None, content_type=None, charset=None) + headers=None, content_type=None, charset=None, zlib_executor_size=sentinel, + zlib_executor=None) The most usable response class, inherited from :class:`StreamResponse`. @@ -830,6 +831,15 @@ Response :param str charset: response's charset. ``'utf-8'`` if *text* is passed also, ``None`` otherwise. + :param int zlib_executor_size: length in bytes which will trigger zlib compression + of body to happen in an executor + + .. versionadded:: 3.5 + + :param int zlib_executor: executor to use for zlib compression + + .. versionadded:: 3.5 + .. attribute:: body @@ -1281,6 +1291,10 @@ duplicated like one using :meth:`Application.copy`. :param debug: Switches debug mode. + .. deprecated:: 3.5 + + Use asyncio :ref:`asyncio-debug-mode` instead. + .. attribute:: router Read-only property that returns *router instance*. @@ -1293,11 +1307,16 @@ duplicated like one using :meth:`Application.copy`. :ref:`event loop<asyncio-event-loop>` used for processing HTTP requests. + .. deprecated:: 3.5 .. attribute:: debug Boolean value indicating whether the debug mode is turned on or off. + .. deprecated:: 3.5 + + Use asyncio :ref:`asyncio-debug-mode` instead. + .. attribute:: on_response_prepare A :class:`~aiohttp.Signal` that is fired at the beginning @@ -1387,6 +1406,21 @@ duplicated like one using :meth:`Application.copy`. :returns: a :class:`PrefixedSubAppResource` instance. + .. method:: add_domain(domain, subapp) + + Register nested sub-application that serves + the domain name or domain name mask. + + In resolving process if request.headers['host'] + matches the pattern *domain* then + further resolving is passed to *subapp*. + + :param str domain: domain or mask of domain for the resource. + + :param Application subapp: nested application. + + :returns: a :class:`MatchedSubAppResource` instance. + .. method:: add_routes(routes_table) Register route definitions from *routes_table*. @@ -1405,12 +1439,12 @@ duplicated like one using :meth:`Application.copy`. Creates HTTP protocol factory for handling requests. :param loop: :ref:`event loop<asyncio-event-loop>` used - for processing HTTP requests. + for processing HTTP requests. - If param is ``None`` :func:`asyncio.get_event_loop` - used for getting default event loop. + If param is ``None`` :func:`asyncio.get_event_loop` + used for getting default event loop. - .. deprecated:: 2.0 + .. deprecated:: 2.0 :param bool tcp_keepalive: Enable TCP Keep-Alive. Default: ``True``. :param int keepalive_timeout: Number of seconds before closing Keep-Alive @@ -1419,7 +1453,7 @@ duplicated like one using :meth:`Application.copy`. :data:`aiohttp.log.server_logger`. :param access_log: Custom logging object. Default: :data:`aiohttp.log.access_logger`. - :param access_log_class: class for `access_logger`. Default: + :param access_log_class: Class for `access_logger`. Default: :data:`aiohttp.helpers.AccessLogger`. Must to be a subclass of :class:`aiohttp.abc.AbstractAccessLogger`. :param str access_log_format: Access log format string. Default: @@ -1430,10 +1464,10 @@ duplicated like one using :meth:`Application.copy`. :param int max_field_size: Optional maximum header field size. Default: ``8190``. - :param float lingering_time: maximum time during which the server - reads and ignore additional data coming from the client when - lingering close is on. Use ``0`` for disabling lingering on - server channel closing. + :param float lingering_time: Maximum time during which the server + reads and ignores additional data coming from the client when + lingering close is on. Use ``0`` to disable lingering on + server channel closing. You should pass result of the method as *protocol_factory* to :meth:`~asyncio.AbstractEventLoop.create_server`, e.g.:: @@ -1500,12 +1534,12 @@ Server A protocol factory compatible with :meth:`~asyncio.AbstreactEventLoop.create_server`. - .. class:: Server +.. class:: Server The class is responsible for creating HTTP protocol objects that can handle HTTP connections. - .. attribute:: Server.connections + .. attribute:: connections List of all currently opened connections. @@ -1978,7 +2012,7 @@ Resource classes hierarchy:: (hash) to the url query string for cache boosting - By default has value from an constructor (``False`` by default) + By default has value from a constructor (``False`` by default) When set to ``True`` - ``v=FILE_HASH`` query string param will be added When set to ``False`` has no impact @@ -2445,28 +2479,15 @@ application on specific TCP or Unix socket, e.g.:: .. versionadded:: 3.0 - :class:`AppRunner` and :class:`TCPSite` / :class:`UnixSite` / - :class:`SockSite` are added in aiohttp 3.0 - -.. class:: AppRunner(app, *, handle_signals=False, **kwargs) - - A runner for :class:`Application`. Used with conjunction with sites - to serve on specific port. + :class:`AppRunner` / :class:`ServerRunner` and :class:`TCPSite` / + :class:`UnixSite` / :class:`SockSite` are added in aiohttp 3.0 - :param Application app: web application instance to serve. - - :param bool handle_signals: add signal handlers for - :data:`signal.SIGINT` and - :data:`signal.SIGTERM` (``False`` by - default). - :param kwargs: named parameters to pass into - :meth:`Application.make_handler`. +.. class:: BaseRunner - .. attribute:: app - - Read-only attribute for accessing to :class:`Application` served - instance. + A base class for runners. Use :class:`AppRunner` for serving + :class:`Application`, :class:`ServerRunner` for low-level + :class:`Server`. .. attribute:: server @@ -2488,6 +2509,37 @@ application on specific TCP or Unix socket, e.g.:: .. comethod:: setup() + Initialize the server. Should be called before adding sites. + + .. comethod:: cleanup() + + Stop handling all registered sites and cleanup used resources. + + +.. class:: AppRunner(app, *, handle_signals=False, **kwargs) + + A runner for :class:`Application`. Used with conjunction with sites + to serve on specific port. + + Inherited from :class:`BaseRunner`. + + :param Application app: web application instance to serve. + + :param bool handle_signals: add signal handlers for + :data:`signal.SIGINT` and + :data:`signal.SIGTERM` (``False`` by + default). + + :param kwargs: named parameters to pass into + web protocol. + + .. attribute:: app + + Read-only attribute for accessing to :class:`Application` served + instance. + + .. comethod:: setup() + Initialize application. Should be called before adding sites. The method calls :attr:`Application.on_startup` registered signals. @@ -2499,6 +2551,28 @@ application on specific TCP or Unix socket, e.g.:: :attr:`Application.on_shutdown` and :attr:`Application.on_cleanup` signals are called internally. + +.. class:: ServerRunner(web_server, *, handle_signals=False, **kwargs) + + A runner for low-level :class:`Server`. Used with conjunction with sites + to serve on specific port. + + Inherited from :class:`BaseRunner`. + + :param Server web_server: low-level web server instance to serve. + + :param bool handle_signals: add signal handlers for + :data:`signal.SIGINT` and + :data:`signal.SIGTERM` (``False`` by + default). + + :param kwargs: named parameters to pass into + web protocol. + + .. seealso:: + + :ref:`aiohttp-web-lowlevel` demonstrates low-level server usage + .. class:: BaseSite An abstract class for handled sites. @@ -2506,7 +2580,7 @@ application on specific TCP or Unix socket, e.g.:: .. attribute:: name An identifier for site, read-only :class:`str` property. Could - be an handled URL or UNIX socket path. + be a handled URL or UNIX socket path. .. comethod:: start() diff --git a/examples/server_simple.py b/examples/server_simple.py new file mode 100644 index 0000000..2bf6aa6 --- /dev/null +++ b/examples/server_simple.py @@ -0,0 +1,31 @@ +# server_simple.py +from aiohttp import web + + +async def handle(request): + name = request.match_info.get("name", "Anonymous") + text = "Hello, " + name + return web.Response(text=text) + + +async def wshandle(request): + ws = web.WebSocketResponse() + await ws.prepare(request) + + async for msg in ws: + if msg.type == web.WSMsgType.text: + await ws.send_str("Hello, {}".format(msg.data)) + elif msg.type == web.WSMsgType.binary: + await ws.send_bytes(msg.data) + elif msg.type == web.WSMsgType.close: + break + + return ws + + +app = web.Application() +app.add_routes([web.get("/", handle), + web.get("/echo", wshandle), + web.get("/{name}", handle)]) + +web.run_app(app) diff --git a/pytest.ci.ini b/pytest.ci.ini new file mode 100644 index 0000000..4858817 --- /dev/null +++ b/pytest.ci.ini @@ -0,0 +1,7 @@ +[pytest] +addopts = --cov=aiohttp --cov-report term-missing:skip-covered -v -rxXs +filterwarnings = error +junit_suite_name = aiohttp_test_suite +norecursedirs = dist docs build .tox .eggs +minversion = 3.8.2 +testpaths = tests/ diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..b04e4f8 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +addopts = --cov=aiohttp -v -rxXs +filterwarnings = error +junit_suite_name = aiohttp_test_suite +norecursedirs = dist docs build .tox .eggs +minversion = 3.8.2 +testpaths = tests/ diff --git a/requirements/ci-wheel.txt b/requirements/ci-wheel.txt index f92c724..576842d 100644 --- a/requirements/ci-wheel.txt +++ b/requirements/ci-wheel.txt @@ -1,25 +1,24 @@ -r flake.txt -attrs==18.1.0 +attrs==18.2.0 async-generator==1.10 -async-timeout==3.0.0 +async-timeout==3.0.1 brotlipy==0.7.0 -cchardet==2.1.1 +cchardet==2.1.4 chardet==3.0.4 -coverage==4.5.1 -cython==0.28.5 -gunicorn==19.8.1 -pyflakes==2.0.0 -multidict==4.3.1 -pytest==3.7.2 -pytest-cov==2.5.1 +coverage==4.5.2 +cython==0.29.2 +gunicorn==19.9.0 +multidict==4.5.2 +pytest==4.0.2 +pytest-cov==2.6.0 pytest-mock==1.10.0 -pytest-xdist==1.22.5 -tox==3.1.3 -twine==1.11.0 -yarl==1.2.6 +tox==3.6.0 +twine==1.12.1 +yarl==1.3.0 # Using PEP 508 env markers to control dependency on runtimes: aiodns==1.1.1; platform_system!="Windows" # required c-ares will not build on windows -codecov==2.0.15; platform_system!="Windows" # We only use it in Travis CI -uvloop==0.11.2; platform_system!="Windows" and implementation_name=="cpython" and python_version<"3.7" # MagicStack/uvloop#14 +codecov==2.0.15 +uvloop==0.11.3; platform_system!="Windows" and implementation_name=="cpython" and python_version<"3.7" # MagicStack/uvloop#14 idna-ssl==1.1.0; python_version<"3.7" +typing_extensions==3.6.6; python_version<"3.7" diff --git a/requirements/ci.txt b/requirements/ci.txt index 5be88d2..a3925c7 100644 --- a/requirements/ci.txt +++ b/requirements/ci.txt @@ -1,5 +1,6 @@ setuptools-git==1.2 -mypy==0.620; implementation_name=="cpython" +mypy==0.650; implementation_name=="cpython" +mypy-extensions==0.4.1; implementation_name=="cpython" -r ci-wheel.txt -r doc.txt diff --git a/requirements/cython.txt b/requirements/cython.txt index 64c06c6..927eb7f 100644 --- a/requirements/cython.txt +++ b/requirements/cython.txt @@ -1 +1 @@ -cython==0.28.5 +cython==0.29.2 diff --git a/requirements/dev.txt b/requirements/dev.txt index 3116a6e..9f384c2 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,6 +1,3 @@ -r ci.txt -r towncrier.txt -ipdb==0.11 -pytest-sugar==0.9.1 -ipython==6.5.0 -cherry_picker==1.2.0; python_version>="3.6" +cherry_picker==1.2.1; python_version>="3.6" diff --git a/requirements/doc.txt b/requirements/doc.txt index 29a725d..41179cd 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -1,5 +1,5 @@ -sphinx==1.7.7 +sphinx==1.8.2 sphinxcontrib-asyncio==0.2.0 pygments>=2.1 -aiohttp-theme==0.1.4 +aiohttp-theme==0.1.5 sphinxcontrib-blockdiag==1.5.5 diff --git a/requirements/flake.txt b/requirements/flake.txt index d4b0e33..df6fd48 100644 --- a/requirements/flake.txt +++ b/requirements/flake.txt @@ -1,2 +1,2 @@ -flake8==3.5.0 +flake8==3.6.0 isort==4.3.4 diff --git a/requirements/wheel.txt b/requirements/wheel.txt index b2d5ed4..de37455 100644 --- a/requirements/wheel.txt +++ b/requirements/wheel.txt @@ -1,3 +1,3 @@ -cython==0.28.5 -pytest==3.7.2 -twine==1.11.0 +cython==0.29.2 +pytest==4.0.2 +twine==1.12.1 @@ -11,14 +11,9 @@ max-line-length = 79 zip_ok = false
[flake8]
-ignore = N801,N802,N803,E226
+ignore = N801,N802,N803,E226,W504,E252
max-line-length = 79
-[tool:pytest]
-testpaths = tests
-addopts = --aiohttp-loop=all
-filterwarnings = error
-
[isort]
known_third_party = jinja2
known_first_party = aiohttp,aiohttp_jinja2,aiopg
@@ -34,6 +29,15 @@ branch = True source = aiohttp, tests
omit = site-packages
+[mypy]
+follow_imports = silent
+strict_optional = True
+warn_redundant_casts = True
+check_untyped_defs = True
+disallow_any_generics = True
+disallow_untyped_defs = True
+warn_unused_ignores = True
+
[mypy-pytest]
ignore_missing_imports = true
@@ -92,6 +92,7 @@ install_requires = [ 'async_timeout>=3.0,<4.0', 'yarl>=1.0,<2.0', 'idna-ssl>=1.0; python_version<"3.7"', + 'typing_extensions>=3.6.5; python_version<"3.7"', ] @@ -102,8 +103,11 @@ def read(f): NEEDS_PYTEST = {'pytest', 'test'}.intersection(sys.argv) pytest_runner = ['pytest-runner'] if NEEDS_PYTEST else [] -tests_require = ['pytest', 'gunicorn', - 'pytest-timeout', 'async-generator'] +tests_require = [ + 'pytest', 'gunicorn', + 'pytest-timeout', 'async-generator', + 'pytest-xdist', +] args = dict( @@ -147,6 +151,13 @@ args = dict( packages=['aiohttp'], python_requires='>=3.5.3', install_requires=install_requires, + extras_require={ + 'speedups': [ + 'aiodns', + 'brotlipy', + 'cchardet', + ], + }, tests_require=tests_require, setup_requires=pytest_runner, include_package_data=True, diff --git a/tests/aiohttp.jpg b/tests/aiohttp.jpg Binary files differindex 2dfbbd4..e8c51c3 100644 --- a/tests/aiohttp.jpg +++ b/tests/aiohttp.jpg diff --git a/tests/aiohttp.png b/tests/aiohttp.png Binary files differindex 1a3c949..db272a4 100644 --- a/tests/aiohttp.png +++ b/tests/aiohttp.png diff --git a/tests/autobahn/server.py b/tests/autobahn/server.py index 0a1a0e3..693dcd0 100644 --- a/tests/autobahn/server.py +++ b/tests/autobahn/server.py @@ -50,8 +50,6 @@ if __name__ == '__main__': loop = asyncio.get_event_loop() logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s') - - loop = asyncio.get_event_loop() app, srv, handler = loop.run_until_complete(main(loop)) try: loop.run_forever() diff --git a/tests/test_base_protocol.py b/tests/test_base_protocol.py index 773b466..531e55e 100644 --- a/tests/test_base_protocol.py +++ b/tests/test_base_protocol.py @@ -7,26 +7,23 @@ import pytest from aiohttp.base_protocol import BaseProtocol -def test_loop(loop): +async def test_loop() -> None: + loop = asyncio.get_event_loop() asyncio.set_event_loop(None) - pr = BaseProtocol(loop=loop) + pr = BaseProtocol(loop) assert pr._loop is loop -def test_default_loop(loop): - asyncio.set_event_loop(loop) - pr = BaseProtocol() - assert pr._loop is loop - - -def test_pause_writing(loop): - pr = BaseProtocol(loop=loop) +async def test_pause_writing() -> None: + loop = asyncio.get_event_loop() + pr = BaseProtocol(loop) assert not pr._paused pr.pause_writing() assert pr._paused -def test_resume_writing_no_waiters(loop): +async def test_resume_writing_no_waiters() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) pr.pause_writing() assert pr._paused @@ -34,7 +31,8 @@ def test_resume_writing_no_waiters(loop): assert not pr._paused -def test_connection_made(loop): +async def test_connection_made() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) tr = mock.Mock() assert pr.transport is None @@ -42,7 +40,8 @@ def test_connection_made(loop): assert pr.transport is not None -def test_connection_lost_not_paused(loop): +async def test_connection_lost_not_paused() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) tr = mock.Mock() pr.connection_made(tr) @@ -52,7 +51,8 @@ def test_connection_lost_not_paused(loop): assert pr._connection_lost -def test_connection_lost_paused_without_waiter(loop): +async def test_connection_lost_paused_without_waiter() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) tr = mock.Mock() pr.connection_made(tr) @@ -63,7 +63,8 @@ def test_connection_lost_paused_without_waiter(loop): assert pr._connection_lost -async def test_drain_lost(loop): +async def test_drain_lost() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) tr = mock.Mock() pr.connection_made(tr) @@ -72,7 +73,8 @@ async def test_drain_lost(loop): await pr._drain_helper() -async def test_drain_not_paused(loop): +async def test_drain_not_paused() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) tr = mock.Mock() pr.connection_made(tr) @@ -81,7 +83,8 @@ async def test_drain_not_paused(loop): assert pr._drain_waiter is None -async def test_resume_drain_waited(loop): +async def test_resume_drain_waited() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) tr = mock.Mock() pr.connection_made(tr) @@ -96,7 +99,8 @@ async def test_resume_drain_waited(loop): assert pr._drain_waiter is None -async def test_lost_drain_waited_ok(loop): +async def test_lost_drain_waited_ok() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) tr = mock.Mock() pr.connection_made(tr) @@ -111,7 +115,8 @@ async def test_lost_drain_waited_ok(loop): assert pr._drain_waiter is None -async def test_lost_drain_waited_exception(loop): +async def test_lost_drain_waited_exception() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) tr = mock.Mock() pr.connection_made(tr) @@ -129,7 +134,8 @@ async def test_lost_drain_waited_exception(loop): assert pr._drain_waiter is None -async def test_lost_drain_cancelled(loop): +async def test_lost_drain_cancelled() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) tr = mock.Mock() pr.connection_made(tr) @@ -152,7 +158,8 @@ async def test_lost_drain_cancelled(loop): assert pr._drain_waiter is None -async def test_resume_drain_cancelled(loop): +async def test_resume_drain_cancelled() -> None: + loop = asyncio.get_event_loop() pr = BaseProtocol(loop=loop) tr = mock.Mock() pr.connection_made(tr) diff --git a/tests/test_classbasedview.py b/tests/test_classbasedview.py index c0bdbbc..5abc3a8 100644 --- a/tests/test_classbasedview.py +++ b/tests/test_classbasedview.py @@ -6,13 +6,13 @@ from aiohttp import web from aiohttp.web_urldispatcher import View -def test_ctor(): +def test_ctor() -> None: request = mock.Mock() view = View(request) assert view.request is request -async def test_render_ok(): +async def test_render_ok() -> None: resp = web.Response(text='OK') class MyView(View): @@ -25,7 +25,7 @@ async def test_render_ok(): assert resp is resp2 -async def test_render_unknown_method(): +async def test_render_unknown_method() -> None: class MyView(View): async def get(self): @@ -40,7 +40,7 @@ async def test_render_unknown_method(): assert ctx.value.status == 405 -async def test_render_unsupported_method(): +async def test_render_unsupported_method() -> None: class MyView(View): async def get(self): diff --git a/tests/test_client_connection.py b/tests/test_client_connection.py index 86a9bbc..5427a58 100644 --- a/tests/test_client_connection.py +++ b/tests/test_client_connection.py @@ -12,11 +12,6 @@ def key(): @pytest.fixture -def request(): - return mock.Mock() - - -@pytest.fixture def loop(): return mock.Mock() @@ -31,15 +26,15 @@ def protocol(): return mock.Mock(should_close=False) -def test_ctor(connector, key, protocol, loop): +def test_ctor(connector, key, protocol, loop) -> None: conn = Connection(connector, key, protocol, loop) - assert conn.loop is loop + with pytest.warns(DeprecationWarning): + assert conn.loop is loop assert conn.protocol is protocol - assert conn.writer is protocol.writer conn.close() -def test_callbacks_on_close(connector, key, protocol, loop): +def test_callbacks_on_close(connector, key, protocol, loop) -> None: conn = Connection(connector, key, protocol, loop) notified = False @@ -52,7 +47,7 @@ def test_callbacks_on_close(connector, key, protocol, loop): assert notified -def test_callbacks_on_release(connector, key, protocol, loop): +def test_callbacks_on_release(connector, key, protocol, loop) -> None: conn = Connection(connector, key, protocol, loop) notified = False @@ -65,20 +60,7 @@ def test_callbacks_on_release(connector, key, protocol, loop): assert notified -def test_callbacks_on_detach(connector, key, protocol, loop): - conn = Connection(connector, key, protocol, loop) - notified = False - - def cb(): - nonlocal notified - notified = True - - conn.add_callback(cb) - conn.detach() - assert notified - - -def test_callbacks_exception(connector, key, protocol, loop): +def test_callbacks_exception(connector, key, protocol, loop) -> None: conn = Connection(connector, key, protocol, loop) notified = False @@ -95,7 +77,7 @@ def test_callbacks_exception(connector, key, protocol, loop): assert notified -def test_del(connector, key, protocol, loop): +def test_del(connector, key, protocol, loop) -> None: loop.is_closed.return_value = False conn = Connection(connector, key, protocol, loop) exc_handler = mock.Mock() @@ -113,7 +95,7 @@ def test_del(connector, key, protocol, loop): loop.call_exception_handler.assert_called_with(msg) -def test_close(connector, key, protocol, loop): +def test_close(connector, key, protocol, loop) -> None: conn = Connection(connector, key, protocol, loop) assert not conn.closed conn.close() @@ -122,7 +104,7 @@ def test_close(connector, key, protocol, loop): assert conn.closed -def test_release(connector, key, protocol, loop): +def test_release(connector, key, protocol, loop) -> None: conn = Connection(connector, key, protocol, loop) assert not conn.closed conn.release() @@ -132,7 +114,7 @@ def test_release(connector, key, protocol, loop): assert conn.closed -def test_release_proto_should_close(connector, key, protocol, loop): +def test_release_proto_should_close(connector, key, protocol, loop) -> None: protocol.should_close = True conn = Connection(connector, key, protocol, loop) assert not conn.closed @@ -143,7 +125,7 @@ def test_release_proto_should_close(connector, key, protocol, loop): assert conn.closed -def test_release_released(connector, key, protocol, loop): +def test_release_released(connector, key, protocol, loop) -> None: conn = Connection(connector, key, protocol, loop) conn.release() connector._release.reset_mock() @@ -151,22 +133,3 @@ def test_release_released(connector, key, protocol, loop): assert not protocol.transport.close.called assert conn._protocol is None assert not connector._release.called - - -def test_detach(connector, key, protocol, loop): - conn = Connection(connector, key, protocol, loop) - assert not conn.closed - conn.detach() - assert conn._protocol is None - assert connector._release_acquired.called - assert not connector._release.called - assert conn.closed - - -def test_detach_closed(connector, key, protocol, loop): - conn = Connection(connector, key, protocol, loop) - conn.release() - conn.detach() - - assert not connector._release_acquired.called - assert conn._protocol is None diff --git a/tests/test_client_exceptions.py b/tests/test_client_exceptions.py index eac8fdb..cedf5f0 100644 --- a/tests/test_client_exceptions.py +++ b/tests/test_client_exceptions.py @@ -6,14 +6,14 @@ from yarl import URL from aiohttp import client -def test_fingerprint_mismatch(): +def test_fingerprint_mismatch() -> None: err = client.ServerFingerprintMismatch('exp', 'got', 'host', 8888) expected = ('<ServerFingerprintMismatch expected=exp' ' got=got host=host port=8888>') assert expected == repr(err) -def test_invalid_url(): +def test_invalid_url() -> None: url = URL('http://example.com') err = client.InvalidURL(url) assert err.args[0] is url @@ -21,20 +21,20 @@ def test_invalid_url(): assert repr(err) == "<InvalidURL http://example.com>" -def test_response_default_status(): +def test_response_default_status() -> None: err = client.ClientResponseError(history=None, request_info=None) assert err.status == 0 -def test_response_status(): +def test_response_status() -> None: err = client.ClientResponseError(status=400, history=None, request_info=None) assert err.status == 400 -def test_response_deprecated_code_property(): +def test_response_deprecated_code_property() -> None: with pytest.warns(DeprecationWarning): err = client.ClientResponseError(code=400, history=None, @@ -47,7 +47,7 @@ def test_response_deprecated_code_property(): assert err.code == err.status -def test_response_both_code_and_status(): +def test_response_both_code_and_status() -> None: with pytest.raises(ValueError): client.ClientResponseError(code=400, status=400, diff --git a/tests/test_client_fingerprint.py b/tests/test_client_fingerprint.py index b3b295b..aa1b4c7 100644 --- a/tests/test_client_fingerprint.py +++ b/tests/test_client_fingerprint.py @@ -10,25 +10,25 @@ from aiohttp.client_reqrep import _merge_ssl_params ssl = pytest.importorskip('ssl') -def test_fingerprint_sha256(): +def test_fingerprint_sha256() -> None: sha256 = hashlib.sha256(b'12345678'*64).digest() fp = aiohttp.Fingerprint(sha256) assert fp.fingerprint == sha256 -def test_fingerprint_sha1(): +def test_fingerprint_sha1() -> None: sha1 = hashlib.sha1(b'12345678'*64).digest() with pytest.raises(ValueError): aiohttp.Fingerprint(sha1) -def test_fingerprint_md5(): +def test_fingerprint_md5() -> None: md5 = hashlib.md5(b'12345678'*64).digest() with pytest.raises(ValueError): aiohttp.Fingerprint(md5) -def test_fingerprint_check_no_ssl(): +def test_fingerprint_check_no_ssl() -> None: sha256 = hashlib.sha256(b'12345678'*64).digest() fp = aiohttp.Fingerprint(sha256) transport = mock.Mock() @@ -36,25 +36,25 @@ def test_fingerprint_check_no_ssl(): assert fp.check(transport) is None -def test__merge_ssl_params_verify_ssl(): +def test__merge_ssl_params_verify_ssl() -> None: with pytest.warns(DeprecationWarning): assert _merge_ssl_params(None, False, None, None) is False -def test__merge_ssl_params_verify_ssl_conflict(): +def test__merge_ssl_params_verify_ssl_conflict() -> None: ctx = ssl.SSLContext() with pytest.warns(DeprecationWarning): with pytest.raises(ValueError): _merge_ssl_params(ctx, False, None, None) -def test__merge_ssl_params_ssl_context(): +def test__merge_ssl_params_ssl_context() -> None: ctx = ssl.SSLContext() with pytest.warns(DeprecationWarning): assert _merge_ssl_params(None, None, ctx, None) is ctx -def test__merge_ssl_params_ssl_context_conflict(): +def test__merge_ssl_params_ssl_context_conflict() -> None: ctx1 = ssl.SSLContext() ctx2 = ssl.SSLContext() with pytest.warns(DeprecationWarning): @@ -62,14 +62,14 @@ def test__merge_ssl_params_ssl_context_conflict(): _merge_ssl_params(ctx1, None, ctx2, None) -def test__merge_ssl_params_fingerprint(): +def test__merge_ssl_params_fingerprint() -> None: digest = hashlib.sha256(b'123').digest() with pytest.warns(DeprecationWarning): ret = _merge_ssl_params(None, None, None, digest) assert ret.fingerprint == digest -def test__merge_ssl_params_fingerprint_conflict(): +def test__merge_ssl_params_fingerprint_conflict() -> None: fingerprint = aiohttp.Fingerprint(hashlib.sha256(b'123').digest()) ctx = ssl.SSLContext() with pytest.warns(DeprecationWarning): @@ -77,11 +77,11 @@ def test__merge_ssl_params_fingerprint_conflict(): _merge_ssl_params(ctx, None, None, fingerprint) -def test__merge_ssl_params_ssl(): +def test__merge_ssl_params_ssl() -> None: ctx = ssl.SSLContext() assert ctx is _merge_ssl_params(ctx, None, None, None) -def test__merge_ssl_params_invlid(): +def test__merge_ssl_params_invlid() -> None: with pytest.raises(TypeError): _merge_ssl_params(object(), None, None, None) diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index 33d27b4..74f17af 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -43,7 +43,8 @@ def ceil(val): return val -async def test_keepalive_two_requests_success(aiohttp_client): +async def test_keepalive_two_requests_success( + aiohttp_client) -> None: async def handler(request): body = await request.read() assert b'' == body @@ -63,7 +64,7 @@ async def test_keepalive_two_requests_success(aiohttp_client): assert 1 == len(client._session.connector._conns) -async def test_keepalive_response_released(aiohttp_client): +async def test_keepalive_response_released(aiohttp_client) -> None: async def handler(request): body = await request.read() assert b'' == body @@ -83,7 +84,7 @@ async def test_keepalive_response_released(aiohttp_client): assert 1 == len(client._session.connector._conns) -async def test_keepalive_server_force_close_connection(aiohttp_client): +async def test_keepalive_server_force_close_connection(aiohttp_client) -> None: async def handler(request): body = await request.read() assert b'' == body @@ -105,7 +106,7 @@ async def test_keepalive_server_force_close_connection(aiohttp_client): assert 0 == len(client._session.connector._conns) -async def test_release_early(aiohttp_client): +async def test_release_early(aiohttp_client) -> None: async def handler(request): await request.read() return web.Response(body=b'OK') @@ -119,7 +120,7 @@ async def test_release_early(aiohttp_client): assert 1 == len(client._session.connector._conns) -async def test_HTTP_304(aiohttp_client): +async def test_HTTP_304(aiohttp_client) -> None: async def handler(request): body = await request.read() assert b'' == body @@ -135,7 +136,7 @@ async def test_HTTP_304(aiohttp_client): assert content == b'' -async def test_HTTP_304_WITH_BODY(aiohttp_client): +async def test_HTTP_304_WITH_BODY(aiohttp_client) -> None: async def handler(request): body = await request.read() assert b'' == body @@ -151,7 +152,7 @@ async def test_HTTP_304_WITH_BODY(aiohttp_client): assert content == b'' -async def test_auto_header_user_agent(aiohttp_client): +async def test_auto_header_user_agent(aiohttp_client) -> None: async def handler(request): assert 'aiohttp' in request.headers['user-agent'] return web.Response() @@ -164,7 +165,7 @@ async def test_auto_header_user_agent(aiohttp_client): assert 200 == resp.status -async def test_skip_auto_headers_user_agent(aiohttp_client): +async def test_skip_auto_headers_user_agent(aiohttp_client) -> None: async def handler(request): assert hdrs.USER_AGENT not in request.headers return web.Response() @@ -177,7 +178,7 @@ async def test_skip_auto_headers_user_agent(aiohttp_client): assert 200 == resp.status -async def test_skip_default_auto_headers_user_agent(aiohttp_client): +async def test_skip_default_auto_headers_user_agent(aiohttp_client) -> None: async def handler(request): assert hdrs.USER_AGENT not in request.headers return web.Response() @@ -190,7 +191,7 @@ async def test_skip_default_auto_headers_user_agent(aiohttp_client): assert 200 == resp.status -async def test_skip_auto_headers_content_type(aiohttp_client): +async def test_skip_auto_headers_content_type(aiohttp_client) -> None: async def handler(request): assert hdrs.CONTENT_TYPE not in request.headers return web.Response() @@ -203,7 +204,7 @@ async def test_skip_auto_headers_content_type(aiohttp_client): assert 200 == resp.status -async def test_post_data_bytesio(aiohttp_client): +async def test_post_data_bytesio(aiohttp_client) -> None: data = b'some buffer' async def handler(request): @@ -220,7 +221,7 @@ async def test_post_data_bytesio(aiohttp_client): assert 200 == resp.status -async def test_post_data_with_bytesio_file(aiohttp_client): +async def test_post_data_with_bytesio_file(aiohttp_client) -> None: data = b'some buffer' async def handler(request): @@ -237,7 +238,7 @@ async def test_post_data_with_bytesio_file(aiohttp_client): assert 200 == resp.status -async def test_post_data_stringio(aiohttp_client): +async def test_post_data_stringio(aiohttp_client) -> None: data = 'some buffer' async def handler(request): @@ -255,7 +256,7 @@ async def test_post_data_stringio(aiohttp_client): assert 200 == resp.status -async def test_post_data_textio_encoding(aiohttp_client): +async def test_post_data_textio_encoding(aiohttp_client) -> None: data = 'текст' async def handler(request): @@ -273,7 +274,7 @@ async def test_post_data_textio_encoding(aiohttp_client): assert 200 == resp.status -async def test_ssl_client(ssl_ctx, aiohttp_server, aiohttp_client): +async def test_ssl_client(ssl_ctx, aiohttp_server, aiohttp_client) -> None: connector = aiohttp.TCPConnector(ssl=False) async def handler(request): @@ -337,7 +338,8 @@ async def test_tcp_connector_fingerprint_fail(aiohttp_server, aiohttp_client, assert exc.got == fingerprint -async def test_format_task_get(aiohttp_server, loop): +async def test_format_task_get(aiohttp_server) -> None: + loop = asyncio.get_event_loop() async def handler(request): return web.Response(body=b'OK') @@ -353,7 +355,7 @@ async def test_format_task_get(aiohttp_server, loop): await client.close() -async def test_str_params(aiohttp_client): +async def test_str_params(aiohttp_client) -> None: async def handler(request): assert 'q=t est' in request.rel_url.query_string @@ -367,7 +369,7 @@ async def test_str_params(aiohttp_client): assert 200 == resp.status -async def test_drop_params_on_redirect(aiohttp_client): +async def test_drop_params_on_redirect(aiohttp_client) -> None: async def handler_redirect(request): return web.Response(status=301, headers={'Location': '/ok?a=redirect'}) @@ -385,7 +387,7 @@ async def test_drop_params_on_redirect(aiohttp_client): assert resp.status == 200 -async def test_drop_fragment_on_redirect(aiohttp_client): +async def test_drop_fragment_on_redirect(aiohttp_client) -> None: async def handler_redirect(request): return web.Response(status=301, headers={'Location': '/ok#fragment'}) @@ -403,7 +405,7 @@ async def test_drop_fragment_on_redirect(aiohttp_client): assert resp.url.path == '/ok' -async def test_drop_fragment(aiohttp_client): +async def test_drop_fragment(aiohttp_client) -> None: async def handler_ok(request): return web.Response(status=200) @@ -417,7 +419,7 @@ async def test_drop_fragment(aiohttp_client): assert resp.url.path == '/ok' -async def test_history(aiohttp_client): +async def test_history(aiohttp_client) -> None: async def handler_redirect(request): return web.Response(status=301, headers={'Location': '/ok'}) @@ -439,7 +441,7 @@ async def test_history(aiohttp_client): assert resp_redirect.status == 200 -async def test_keepalive_closed_by_server(aiohttp_client): +async def test_keepalive_closed_by_server(aiohttp_client) -> None: async def handler(request): body = await request.read() assert b'' == body @@ -463,7 +465,7 @@ async def test_keepalive_closed_by_server(aiohttp_client): assert 0 == len(client._session.connector._conns) -async def test_wait_for(aiohttp_client): +async def test_wait_for(aiohttp_client) -> None: async def handler(request): return web.Response(body=b'OK') @@ -477,7 +479,7 @@ async def test_wait_for(aiohttp_client): assert txt == 'OK' -async def test_raw_headers(aiohttp_client): +async def test_raw_headers(aiohttp_client) -> None: async def handler(request): return web.Response() @@ -495,7 +497,19 @@ async def test_raw_headers(aiohttp_client): resp.close() -async def test_empty_header_values(aiohttp_client): +async def test_host_header_first(aiohttp_client) -> None: + async def handler(request): + assert list(request.headers)[0] == hdrs.HOST + return web.Response() + + app = web.Application() + app.router.add_route('GET', '/', handler) + client = await aiohttp_client(app) + resp = await client.get('/') + assert resp.status == 200 + + +async def test_empty_header_values(aiohttp_client) -> None: async def handler(request): resp = web.Response() resp.headers['X-Empty'] = '' @@ -515,7 +529,7 @@ async def test_empty_header_values(aiohttp_client): resp.close() -async def test_204_with_gzipped_content_encoding(aiohttp_client): +async def test_204_with_gzipped_content_encoding(aiohttp_client) -> None: async def handler(request): resp = web.StreamResponse(status=204) resp.content_length = 0 @@ -534,7 +548,7 @@ async def test_204_with_gzipped_content_encoding(aiohttp_client): assert resp.closed -async def test_timeout_on_reading_headers(aiohttp_client, mocker): +async def test_timeout_on_reading_headers(aiohttp_client, mocker) -> None: mocker.patch('aiohttp.helpers.ceil').side_effect = ceil async def handler(request): @@ -551,7 +565,7 @@ async def test_timeout_on_reading_headers(aiohttp_client, mocker): await client.get('/', timeout=0.01) -async def test_timeout_on_conn_reading_headers(aiohttp_client, mocker): +async def test_timeout_on_conn_reading_headers(aiohttp_client, mocker) -> None: # tests case where user did not set a connection timeout mocker.patch('aiohttp.helpers.ceil').side_effect = ceil @@ -572,7 +586,7 @@ async def test_timeout_on_conn_reading_headers(aiohttp_client, mocker): await client.get('/', timeout=0.01) -async def test_timeout_on_session_read_timeout(aiohttp_client, mocker): +async def test_timeout_on_session_read_timeout(aiohttp_client, mocker) -> None: mocker.patch('aiohttp.helpers.ceil').side_effect = ceil async def handler(request): @@ -585,13 +599,18 @@ async def test_timeout_on_session_read_timeout(aiohttp_client, mocker): app.router.add_route('GET', '/', handler) conn = aiohttp.TCPConnector() - client = await aiohttp_client(app, connector=conn, read_timeout=0.01) + client = await aiohttp_client( + app, + connector=conn, + timeout=aiohttp.ClientTimeout(sock_read=0.01)) with pytest.raises(asyncio.TimeoutError): await client.get('/') -async def test_timeout_on_reading_data(loop, aiohttp_client, mocker): +async def test_timeout_on_reading_data(aiohttp_client, mocker) -> None: + loop = asyncio.get_event_loop() + mocker.patch('aiohttp.helpers.ceil').side_effect = ceil fut = loop.create_future() @@ -613,7 +632,7 @@ async def test_timeout_on_reading_data(loop, aiohttp_client, mocker): await resp.read() -async def test_timeout_none(aiohttp_client, mocker): +async def test_timeout_none(aiohttp_client, mocker) -> None: mocker.patch('aiohttp.helpers.ceil').side_effect = ceil async def handler(request): @@ -629,7 +648,8 @@ async def test_timeout_none(aiohttp_client, mocker): assert resp.status == 200 -async def test_readline_error_on_conn_close(loop, aiohttp_client): +async def test_readline_error_on_conn_close(aiohttp_client) -> None: + loop = asyncio.get_event_loop() async def handler(request): resp_ = web.StreamResponse() @@ -667,7 +687,7 @@ async def test_readline_error_on_conn_close(loop, aiohttp_client): await session.close() -async def test_no_error_on_conn_close_if_eof(aiohttp_client): +async def test_no_error_on_conn_close_if_eof(aiohttp_client) -> None: async def handler(request): resp_ = web.StreamResponse() @@ -696,7 +716,7 @@ async def test_no_error_on_conn_close_if_eof(aiohttp_client): await session.close() -async def test_error_not_overwrote_on_conn_close(aiohttp_client): +async def test_error_not_overwrote_on_conn_close(aiohttp_client) -> None: async def handler(request): resp_ = web.StreamResponse() @@ -718,7 +738,7 @@ async def test_error_not_overwrote_on_conn_close(aiohttp_client): assert isinstance(resp.content.exception(), ValueError) -async def test_HTTP_200_OK_METHOD(aiohttp_client): +async def test_HTTP_200_OK_METHOD(aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -744,7 +764,7 @@ async def test_HTTP_200_OK_METHOD(aiohttp_client): assert meth.upper() == content -async def test_HTTP_200_OK_METHOD_connector(aiohttp_client): +async def test_HTTP_200_OK_METHOD_connector(aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -755,7 +775,7 @@ async def test_HTTP_200_OK_METHOD_connector(aiohttp_client): app = web.Application() for meth in ('get', 'post', 'put', 'delete', 'head'): app.router.add_route(meth.upper(), '/', handler) - client = await aiohttp_client(app, connector=conn, conn_timeout=0.2) + client = await aiohttp_client(app, connector=conn) for meth in ('get', 'post', 'put', 'delete', 'head'): resp = await client.request(meth, '/') @@ -772,7 +792,7 @@ async def test_HTTP_200_OK_METHOD_connector(aiohttp_client): assert meth.upper() == content -async def test_HTTP_302_REDIRECT_GET(aiohttp_client): +async def test_HTTP_302_REDIRECT_GET(aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -791,7 +811,7 @@ async def test_HTTP_302_REDIRECT_GET(aiohttp_client): resp.close() -async def test_HTTP_302_REDIRECT_HEAD(aiohttp_client): +async def test_HTTP_302_REDIRECT_HEAD(aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -813,7 +833,7 @@ async def test_HTTP_302_REDIRECT_HEAD(aiohttp_client): resp.close() -async def test_HTTP_302_REDIRECT_NON_HTTP(aiohttp_client): +async def test_HTTP_302_REDIRECT_NON_HTTP(aiohttp_client) -> None: async def redirect(request): raise web.HTTPFound(location='ftp://127.0.0.1/test/') @@ -826,7 +846,7 @@ async def test_HTTP_302_REDIRECT_NON_HTTP(aiohttp_client): await client.get('/redirect') -async def test_HTTP_302_REDIRECT_POST(aiohttp_client): +async def test_HTTP_302_REDIRECT_POST(aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -847,7 +867,8 @@ async def test_HTTP_302_REDIRECT_POST(aiohttp_client): resp.close() -async def test_HTTP_302_REDIRECT_POST_with_content_length_hdr(aiohttp_client): +async def test_HTTP_302_REDIRECT_POST_with_content_length_hdr( + aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -857,7 +878,7 @@ async def test_HTTP_302_REDIRECT_POST_with_content_length_hdr(aiohttp_client): raise web.HTTPFound(location='/') data = json.dumps({'some': 'data'}) - app = web.Application(debug=True) + app = web.Application() app.router.add_get('/', handler) app.router.add_post('/redirect', redirect) client = await aiohttp_client(app) @@ -874,7 +895,7 @@ async def test_HTTP_302_REDIRECT_POST_with_content_length_hdr(aiohttp_client): resp.close() -async def test_HTTP_307_REDIRECT_POST(aiohttp_client): +async def test_HTTP_307_REDIRECT_POST(aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -896,7 +917,7 @@ async def test_HTTP_307_REDIRECT_POST(aiohttp_client): resp.close() -async def test_HTTP_308_PERMANENT_REDIRECT_POST(aiohttp_client): +async def test_HTTP_308_PERMANENT_REDIRECT_POST(aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -918,7 +939,7 @@ async def test_HTTP_308_PERMANENT_REDIRECT_POST(aiohttp_client): resp.close() -async def test_HTTP_302_max_redirects(aiohttp_client): +async def test_HTTP_302_max_redirects(aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -942,7 +963,7 @@ async def test_HTTP_302_max_redirects(aiohttp_client): assert ctx.value.request_info.method == 'GET' -async def test_HTTP_200_GET_WITH_PARAMS(aiohttp_client): +async def test_HTTP_200_GET_WITH_PARAMS(aiohttp_client) -> None: async def handler(request): return web.Response(text='&'.join( @@ -959,7 +980,7 @@ async def test_HTTP_200_GET_WITH_PARAMS(aiohttp_client): resp.close() -async def test_HTTP_200_GET_WITH_MultiDict_PARAMS(aiohttp_client): +async def test_HTTP_200_GET_WITH_MultiDict_PARAMS(aiohttp_client) -> None: async def handler(request): return web.Response(text='&'.join( @@ -977,7 +998,7 @@ async def test_HTTP_200_GET_WITH_MultiDict_PARAMS(aiohttp_client): resp.close() -async def test_HTTP_200_GET_WITH_MIXED_PARAMS(aiohttp_client): +async def test_HTTP_200_GET_WITH_MIXED_PARAMS(aiohttp_client) -> None: async def handler(request): return web.Response(text='&'.join( @@ -994,7 +1015,7 @@ async def test_HTTP_200_GET_WITH_MIXED_PARAMS(aiohttp_client): resp.close() -async def test_POST_DATA(aiohttp_client): +async def test_POST_DATA(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -1011,7 +1032,7 @@ async def test_POST_DATA(aiohttp_client): resp.close() -async def test_POST_DATA_with_explicit_formdata(aiohttp_client): +async def test_POST_DATA_with_explicit_formdata(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -1031,7 +1052,7 @@ async def test_POST_DATA_with_explicit_formdata(aiohttp_client): resp.close() -async def test_POST_DATA_with_charset(aiohttp_client): +async def test_POST_DATA_with_charset(aiohttp_client) -> None: async def handler(request): mp = await request.multipart() @@ -1053,7 +1074,7 @@ async def test_POST_DATA_with_charset(aiohttp_client): resp.close() -async def test_POST_DATA_formdats_with_charset(aiohttp_client): +async def test_POST_DATA_formdats_with_charset(aiohttp_client) -> None: async def handler(request): mp = await request.post() @@ -1074,7 +1095,7 @@ async def test_POST_DATA_formdats_with_charset(aiohttp_client): resp.close() -async def test_POST_DATA_with_charset_post(aiohttp_client): +async def test_POST_DATA_with_charset_post(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -1094,7 +1115,8 @@ async def test_POST_DATA_with_charset_post(aiohttp_client): resp.close() -async def test_POST_DATA_with_context_transfer_encoding(aiohttp_client): +async def test_POST_DATA_with_context_transfer_encoding( + aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -1139,7 +1161,7 @@ async def test_POST_DATA_with_content_type_context_transfer_encoding( resp.close() -async def test_POST_MultiDict(aiohttp_client): +async def test_POST_MultiDict(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -1156,7 +1178,7 @@ async def test_POST_MultiDict(aiohttp_client): resp.close() -async def test_POST_DATA_DEFLATE(aiohttp_client): +async def test_POST_DATA_DEFLATE(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -1173,7 +1195,7 @@ async def test_POST_DATA_DEFLATE(aiohttp_client): resp.close() -async def test_POST_FILES(aiohttp_client, fname): +async def test_POST_FILES(aiohttp_client, fname) -> None: async def handler(request): data = await request.post() @@ -1196,7 +1218,7 @@ async def test_POST_FILES(aiohttp_client, fname): resp.close() -async def test_POST_FILES_DEFLATE(aiohttp_client, fname): +async def test_POST_FILES_DEFLATE(aiohttp_client, fname) -> None: async def handler(request): data = await request.post() @@ -1222,7 +1244,7 @@ async def test_POST_FILES_DEFLATE(aiohttp_client, fname): resp.close() -async def test_POST_bytes(aiohttp_client): +async def test_POST_bytes(aiohttp_client) -> None: body = b'0' * 12345 async def handler(request): @@ -1239,7 +1261,7 @@ async def test_POST_bytes(aiohttp_client): resp.close() -async def test_POST_bytes_too_large(aiohttp_client): +async def test_POST_bytes_too_large(aiohttp_client) -> None: body = b'0' * (2 ** 20 + 1) async def handler(request): @@ -1258,7 +1280,7 @@ async def test_POST_bytes_too_large(aiohttp_client): resp.close() -async def test_POST_FILES_STR(aiohttp_client, fname): +async def test_POST_FILES_STR(aiohttp_client, fname) -> None: async def handler(request): data = await request.post() @@ -1278,7 +1300,7 @@ async def test_POST_FILES_STR(aiohttp_client, fname): resp.close() -async def test_POST_FILES_STR_SIMPLE(aiohttp_client, fname): +async def test_POST_FILES_STR_SIMPLE(aiohttp_client, fname) -> None: async def handler(request): data = await request.read() @@ -1297,7 +1319,7 @@ async def test_POST_FILES_STR_SIMPLE(aiohttp_client, fname): resp.close() -async def test_POST_FILES_LIST(aiohttp_client, fname): +async def test_POST_FILES_LIST(aiohttp_client, fname) -> None: async def handler(request): data = await request.post() @@ -1317,7 +1339,7 @@ async def test_POST_FILES_LIST(aiohttp_client, fname): resp.close() -async def test_POST_FILES_CT(aiohttp_client, fname): +async def test_POST_FILES_CT(aiohttp_client, fname) -> None: async def handler(request): data = await request.post() @@ -1340,7 +1362,7 @@ async def test_POST_FILES_CT(aiohttp_client, fname): resp.close() -async def test_POST_FILES_SINGLE(aiohttp_client, fname): +async def test_POST_FILES_SINGLE(aiohttp_client, fname) -> None: async def handler(request): data = await request.text() @@ -1366,7 +1388,8 @@ async def test_POST_FILES_SINGLE(aiohttp_client, fname): resp.close() -async def test_POST_FILES_SINGLE_content_disposition(aiohttp_client, fname): +async def test_POST_FILES_SINGLE_content_disposition( + aiohttp_client, fname) -> None: async def handler(request): data = await request.text() @@ -1394,7 +1417,7 @@ async def test_POST_FILES_SINGLE_content_disposition(aiohttp_client, fname): resp.close() -async def test_POST_FILES_SINGLE_BINARY(aiohttp_client, fname): +async def test_POST_FILES_SINGLE_BINARY(aiohttp_client, fname) -> None: async def handler(request): data = await request.read() @@ -1418,7 +1441,7 @@ async def test_POST_FILES_SINGLE_BINARY(aiohttp_client, fname): resp.close() -async def test_POST_FILES_IO(aiohttp_client): +async def test_POST_FILES_IO(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -1437,7 +1460,7 @@ async def test_POST_FILES_IO(aiohttp_client): resp.close() -async def test_POST_FILES_IO_WITH_PARAMS(aiohttp_client): +async def test_POST_FILES_IO_WITH_PARAMS(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -1463,7 +1486,7 @@ async def test_POST_FILES_IO_WITH_PARAMS(aiohttp_client): resp.close() -async def test_POST_FILES_WITH_DATA(aiohttp_client, fname): +async def test_POST_FILES_WITH_DATA(aiohttp_client, fname) -> None: async def handler(request): data = await request.post() @@ -1487,7 +1510,7 @@ async def test_POST_FILES_WITH_DATA(aiohttp_client, fname): resp.close() -async def test_POST_STREAM_DATA(aiohttp_client, fname): +async def test_POST_STREAM_DATA(aiohttp_client, fname) -> None: async def handler(request): assert request.content_type == 'application/octet-stream' @@ -1521,7 +1544,7 @@ async def test_POST_STREAM_DATA(aiohttp_client, fname): resp.close() -async def test_POST_STREAM_DATA_no_params(aiohttp_client, fname): +async def test_POST_STREAM_DATA_no_params(aiohttp_client, fname) -> None: async def handler(request): assert request.content_type == 'application/octet-stream' @@ -1555,7 +1578,7 @@ async def test_POST_STREAM_DATA_no_params(aiohttp_client, fname): resp.close() -async def test_json(aiohttp_client): +async def test_json(aiohttp_client) -> None: async def handler(request): assert request.content_type == 'application/json' @@ -1576,7 +1599,7 @@ async def test_json(aiohttp_client): await client.post('/', data="some data", json={'some': 'data'}) -async def test_json_custom(aiohttp_client): +async def test_json_custom(aiohttp_client) -> None: async def handler(request): assert request.content_type == 'application/json' @@ -1605,7 +1628,7 @@ async def test_json_custom(aiohttp_client): await client.post('/', data="some data", json={'some': 'data'}) -async def test_expect_continue(aiohttp_client): +async def test_expect_continue(aiohttp_client) -> None: expect_called = False async def handler(request): @@ -1630,7 +1653,7 @@ async def test_expect_continue(aiohttp_client): assert expect_called -async def test_encoding_deflate(aiohttp_client): +async def test_encoding_deflate(aiohttp_client) -> None: async def handler(request): resp = web.Response(text='text') @@ -1649,7 +1672,7 @@ async def test_encoding_deflate(aiohttp_client): resp.close() -async def test_encoding_deflate_nochunk(aiohttp_client): +async def test_encoding_deflate_nochunk(aiohttp_client) -> None: async def handler(request): resp = web.Response(text='text') @@ -1667,7 +1690,7 @@ async def test_encoding_deflate_nochunk(aiohttp_client): resp.close() -async def test_encoding_gzip(aiohttp_client): +async def test_encoding_gzip(aiohttp_client) -> None: async def handler(request): resp = web.Response(text='text') @@ -1686,7 +1709,7 @@ async def test_encoding_gzip(aiohttp_client): resp.close() -async def test_encoding_gzip_write_by_chunks(aiohttp_client): +async def test_encoding_gzip_write_by_chunks(aiohttp_client) -> None: async def handler(request): resp = web.StreamResponse() @@ -1707,7 +1730,7 @@ async def test_encoding_gzip_write_by_chunks(aiohttp_client): resp.close() -async def test_encoding_gzip_nochunk(aiohttp_client): +async def test_encoding_gzip_nochunk(aiohttp_client) -> None: async def handler(request): resp = web.Response(text='text') @@ -1725,7 +1748,7 @@ async def test_encoding_gzip_nochunk(aiohttp_client): resp.close() -async def test_bad_payload_compression(aiohttp_client): +async def test_bad_payload_compression(aiohttp_client) -> None: async def handler(request): resp = web.Response(text='text') @@ -1745,7 +1768,7 @@ async def test_bad_payload_compression(aiohttp_client): resp.close() -async def test_bad_payload_chunked_encoding(aiohttp_client): +async def test_bad_payload_chunked_encoding(aiohttp_client) -> None: async def handler(request): resp = web.StreamResponse() @@ -1770,7 +1793,7 @@ async def test_bad_payload_chunked_encoding(aiohttp_client): resp.close() -async def test_bad_payload_content_length(aiohttp_client): +async def test_bad_payload_content_length(aiohttp_client) -> None: async def handler(request): resp = web.Response(text='text') @@ -1791,7 +1814,7 @@ async def test_bad_payload_content_length(aiohttp_client): resp.close() -async def test_payload_content_length_by_chunks(aiohttp_client): +async def test_payload_content_length_by_chunks(aiohttp_client) -> None: async def handler(request): resp = web.StreamResponse(headers={'content-length': '3'}) @@ -1811,7 +1834,7 @@ async def test_payload_content_length_by_chunks(aiohttp_client): resp.close() -async def test_chunked(aiohttp_client): +async def test_chunked(aiohttp_client) -> None: async def handler(request): resp = web.Response(text='text') @@ -1830,7 +1853,7 @@ async def test_chunked(aiohttp_client): resp.close() -async def test_shortcuts(aiohttp_client): +async def test_shortcuts(aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -1858,7 +1881,7 @@ async def test_shortcuts(aiohttp_client): assert meth.upper() == content -async def test_cookies(aiohttp_client): +async def test_cookies(aiohttp_client) -> None: async def handler(request): assert request.cookies.keys() == {'test1', 'test3'} @@ -1879,7 +1902,34 @@ async def test_cookies(aiohttp_client): resp.close() -async def test_morsel_with_attributes(aiohttp_client): +async def test_cookies_per_request(aiohttp_client) -> None: + + async def handler(request): + assert request.cookies.keys() == {'test1', 'test3', 'test4', 'test6'} + assert request.cookies['test1'] == '123' + assert request.cookies['test3'] == '456' + assert request.cookies['test4'] == '789' + assert request.cookies['test6'] == 'abc' + return web.Response() + + c = http.cookies.Morsel() + c.set('test3', '456', '456') + + app = web.Application() + app.router.add_get('/', handler) + client = await aiohttp_client( + app, cookies={'test1': '123', 'test2': c}) + + rc = http.cookies.Morsel() + rc.set('test6', 'abc', 'abc') + + resp = await client.get( + '/', cookies={'test4': '789', 'test5': rc}) + assert 200 == resp.status + resp.close() + + +async def test_morsel_with_attributes(aiohttp_client) -> None: # A comment from original test: # # No cookie attribute should pass here @@ -1909,7 +1959,7 @@ async def test_morsel_with_attributes(aiohttp_client): resp.close() -async def test_set_cookies(aiohttp_client): +async def test_set_cookies(aiohttp_client) -> None: async def handler(request): ret = web.Response() @@ -1936,7 +1986,7 @@ async def test_set_cookies(aiohttp_client): mock.ANY) -async def test_request_conn_error(): +async def test_request_conn_error() -> None: client = aiohttp.ClientSession() with pytest.raises(aiohttp.ClientConnectionError): await client.get('http://0.0.0.0:1') @@ -1944,7 +1994,7 @@ async def test_request_conn_error(): @pytest.mark.xfail -async def test_broken_connection(aiohttp_client): +async def test_broken_connection(aiohttp_client) -> None: async def handler(request): request.transport.close() @@ -1958,7 +2008,7 @@ async def test_broken_connection(aiohttp_client): await client.get('/') -async def test_broken_connection_2(aiohttp_client): +async def test_broken_connection_2(aiohttp_client) -> None: async def handler(request): resp = web.StreamResponse(headers={'content-length': '1000'}) @@ -1977,7 +2027,7 @@ async def test_broken_connection_2(aiohttp_client): resp.close() -async def test_custom_headers(aiohttp_client): +async def test_custom_headers(aiohttp_client) -> None: async def handler(request): assert request.headers["x-api-key"] == "foo" @@ -1993,7 +2043,7 @@ async def test_custom_headers(aiohttp_client): assert resp.status == 200 -async def test_redirect_to_absolute_url(aiohttp_client): +async def test_redirect_to_absolute_url(aiohttp_client) -> None: async def handler(request): return web.Response(text=request.method) @@ -2011,7 +2061,7 @@ async def test_redirect_to_absolute_url(aiohttp_client): resp.close() -async def test_redirect_without_location_header(aiohttp_client): +async def test_redirect_without_location_header(aiohttp_client) -> None: body = b'redirect' async def handler_redirect(request): @@ -2026,7 +2076,7 @@ async def test_redirect_without_location_header(aiohttp_client): assert data == body -async def test_chunked_deprecated(aiohttp_client): +async def test_chunked_deprecated(aiohttp_client) -> None: async def handler_redirect(request): return web.Response(status=301) @@ -2039,7 +2089,7 @@ async def test_chunked_deprecated(aiohttp_client): await client.post('/', chunked=1024) -async def test_raise_for_status(aiohttp_client): +async def test_raise_for_status(aiohttp_client) -> None: async def handler_redirect(request): raise web.HTTPBadRequest() @@ -2052,7 +2102,7 @@ async def test_raise_for_status(aiohttp_client): await client.get('/') -async def test_raise_for_status_per_request(aiohttp_client): +async def test_raise_for_status_per_request(aiohttp_client) -> None: async def handler_redirect(request): raise web.HTTPBadRequest() @@ -2065,7 +2115,7 @@ async def test_raise_for_status_per_request(aiohttp_client): await client.get('/', raise_for_status=True) -async def test_raise_for_status_disable_per_request(aiohttp_client): +async def test_raise_for_status_disable_per_request(aiohttp_client) -> None: async def handler_redirect(request): raise web.HTTPBadRequest() @@ -2079,7 +2129,46 @@ async def test_raise_for_status_disable_per_request(aiohttp_client): resp.close() -async def test_invalid_idna(): +async def test_request_raise_for_status_default(aiohttp_server) -> None: + async def handler(request): + raise web.HTTPBadRequest() + + app = web.Application() + app.router.add_get('/', handler) + server = await aiohttp_server(app) + + async with aiohttp.request('GET', server.make_url('/')) as resp: + assert resp.status == 400 + + +async def test_request_raise_for_status_disabled(aiohttp_server) -> None: + async def handler(request): + raise web.HTTPBadRequest() + + app = web.Application() + app.router.add_get('/', handler) + server = await aiohttp_server(app) + url = server.make_url('/') + + async with aiohttp.request('GET', url, raise_for_status=False) as resp: + assert resp.status == 400 + + +async def test_request_raise_for_status_enabled(aiohttp_server) -> None: + async def handler(request): + raise web.HTTPBadRequest() + + app = web.Application() + app.router.add_get('/', handler) + server = await aiohttp_server(app) + url = server.make_url('/') + + with pytest.raises(aiohttp.ClientResponseError): + async with aiohttp.request('GET', url, raise_for_status=True): + assert False, "never executed" # pragma: no cover + + +async def test_invalid_idna() -> None: session = aiohttp.ClientSession() try: with pytest.raises(aiohttp.InvalidURL): @@ -2088,7 +2177,7 @@ async def test_invalid_idna(): await session.close() -async def test_creds_in_auth_and_url(): +async def test_creds_in_auth_and_url() -> None: session = aiohttp.ClientSession() try: with pytest.raises(ValueError): @@ -2098,7 +2187,7 @@ async def test_creds_in_auth_and_url(): await session.close() -async def test_drop_auth_on_redirect_to_other_host(aiohttp_server): +async def test_drop_auth_on_redirect_to_other_host(aiohttp_server) -> None: async def srv1(request): assert request.host == 'host1.com' @@ -2143,7 +2232,7 @@ async def test_drop_auth_on_redirect_to_other_host(aiohttp_server): assert resp.status == 200 -async def test_async_with_session(): +async def test_async_with_session() -> None: with pytest.warns(None) as cm: async with aiohttp.ClientSession() as session: pass @@ -2152,7 +2241,7 @@ async def test_async_with_session(): assert session.closed -async def test_session_close_awaitable(): +async def test_session_close_awaitable() -> None: session = aiohttp.ClientSession() with pytest.warns(None) as cm: await session.close() @@ -2161,7 +2250,7 @@ async def test_session_close_awaitable(): assert session.closed -async def test_close_run_until_complete_not_deprecated(): +async def test_close_run_until_complete_not_deprecated() -> None: session = aiohttp.ClientSession() with pytest.warns(None) as cm: @@ -2170,7 +2259,7 @@ async def test_close_run_until_complete_not_deprecated(): assert len(cm.list) == 0 -async def test_close_resp_on_error_async_with_session(aiohttp_server): +async def test_close_resp_on_error_async_with_session(aiohttp_server) -> None: async def handler(request): resp = web.StreamResponse(headers={'content-length': '100'}) await resp.prepare(request) @@ -2190,7 +2279,7 @@ async def test_close_resp_on_error_async_with_session(aiohttp_server): assert len(session._connector._conns) == 0 -async def test_release_resp_on_normal_exit_from_cm(aiohttp_server): +async def test_release_resp_on_normal_exit_from_cm(aiohttp_server) -> None: async def handler(request): return web.Response() @@ -2205,7 +2294,7 @@ async def test_release_resp_on_normal_exit_from_cm(aiohttp_server): assert len(session._connector._conns) == 1 -async def test_non_close_detached_session_on_error_cm(aiohttp_server): +async def test_non_close_detached_session_on_error_cm(aiohttp_server) -> None: async def handler(request): resp = web.StreamResponse(headers={'content-length': '100'}) await resp.prepare(request) @@ -2226,7 +2315,7 @@ async def test_non_close_detached_session_on_error_cm(aiohttp_server): assert not session.closed -async def test_close_detached_session_on_non_existing_addr(): +async def test_close_detached_session_on_non_existing_addr() -> None: class FakeResolver(AbstractResolver): async def resolve(host, port=0, family=socket.AF_INET): return {} @@ -2247,7 +2336,7 @@ async def test_close_detached_session_on_non_existing_addr(): assert session.closed -async def test_aiohttp_request_context_manager(aiohttp_server): +async def test_aiohttp_request_context_manager(aiohttp_server) -> None: async def handler(request): return web.Response() @@ -2260,14 +2349,14 @@ async def test_aiohttp_request_context_manager(aiohttp_server): assert resp.status == 200 -async def test_aiohttp_request_ctx_manager_not_found(): +async def test_aiohttp_request_ctx_manager_not_found() -> None: with pytest.raises(aiohttp.ClientConnectionError): async with aiohttp.request('GET', 'http://wrong-dns-name.com'): assert False, "never executed" # pragma: no cover -async def test_aiohttp_request_coroutine(aiohttp_server): +async def test_aiohttp_request_coroutine(aiohttp_server) -> None: async def handler(request): return web.Response() @@ -2280,7 +2369,7 @@ async def test_aiohttp_request_coroutine(aiohttp_server): @asyncio.coroutine -def test_yield_from_in_session_request(aiohttp_client): +def test_yield_from_in_session_request(aiohttp_client) -> None: # a test for backward compatibility with yield from syntax async def handler(request): return web.Response() @@ -2294,7 +2383,7 @@ def test_yield_from_in_session_request(aiohttp_client): @asyncio.coroutine -def test_close_context_manager(aiohttp_client): +def test_close_context_manager(aiohttp_client) -> None: # a test for backward compatibility with yield from syntax async def handler(request): return web.Response() @@ -2308,7 +2397,7 @@ def test_close_context_manager(aiohttp_client): assert not ctx._coro.cr_running -async def test_session_auth(aiohttp_client): +async def test_session_auth(aiohttp_client) -> None: async def handler(request): return web.json_response({'headers': dict(request.headers)}) @@ -2323,7 +2412,7 @@ async def test_session_auth(aiohttp_client): assert content['headers']["Authorization"] == "Basic bG9naW46cGFzcw==" -async def test_session_auth_override(aiohttp_client): +async def test_session_auth_override(aiohttp_client) -> None: async def handler(request): return web.json_response({'headers': dict(request.headers)}) @@ -2339,7 +2428,7 @@ async def test_session_auth_override(aiohttp_client): assert val == "Basic b3RoZXJfbG9naW46cGFzcw==" -async def test_session_auth_header_conflict(aiohttp_client): +async def test_session_auth_header_conflict(aiohttp_client) -> None: async def handler(request): return web.Response() @@ -2352,7 +2441,7 @@ async def test_session_auth_header_conflict(aiohttp_client): await client.get('/', headers=headers) -async def test_session_headers(aiohttp_client): +async def test_session_headers(aiohttp_client) -> None: async def handler(request): return web.json_response({'headers': dict(request.headers)}) @@ -2367,7 +2456,7 @@ async def test_session_headers(aiohttp_client): assert content['headers']["X-Real-IP"] == "192.168.0.1" -async def test_session_headers_merge(aiohttp_client): +async def test_session_headers_merge(aiohttp_client) -> None: async def handler(request): return web.json_response({'headers': dict(request.headers)}) @@ -2385,7 +2474,7 @@ async def test_session_headers_merge(aiohttp_client): assert content['headers']["X-Sent-By"] == "aiohttp" -async def test_multidict_headers(aiohttp_client): +async def test_multidict_headers(aiohttp_client) -> None: async def handler(request): assert await request.read() == data return web.Response() @@ -2403,7 +2492,7 @@ async def test_multidict_headers(aiohttp_client): assert r.status == 200 -async def test_request_conn_closed(aiohttp_client): +async def test_request_conn_closed(aiohttp_client) -> None: async def handler(request): request.transport.close() return web.Response() @@ -2417,7 +2506,7 @@ async def test_request_conn_closed(aiohttp_client): await resp.read() -async def test_dont_close_explicit_connector(aiohttp_client): +async def test_dont_close_explicit_connector(aiohttp_client) -> None: async def handler(request): return web.Response() @@ -2431,7 +2520,8 @@ async def test_dont_close_explicit_connector(aiohttp_client): assert 1 == len(client.session.connector._conns) -async def test_server_close_keepalive_connection(loop): +async def test_server_close_keepalive_connection() -> None: + loop = asyncio.get_event_loop() class Proto(asyncio.Protocol): @@ -2472,7 +2562,8 @@ async def test_server_close_keepalive_connection(loop): await server.wait_closed() -async def test_handle_keepalive_on_closed_connection(loop): +async def test_handle_keepalive_on_closed_connection() -> None: + loop = asyncio.get_event_loop() class Proto(asyncio.Protocol): @@ -2517,7 +2608,7 @@ async def test_handle_keepalive_on_closed_connection(loop): await server.wait_closed() -async def test_error_in_performing_request(loop, ssl_ctx, +async def test_error_in_performing_request(ssl_ctx, aiohttp_client, aiohttp_server): async def handler(request): return web.Response() @@ -2526,6 +2617,7 @@ async def test_error_in_performing_request(loop, ssl_ctx, # skip log messages about destroyed but pending tasks pass + loop = asyncio.get_event_loop() loop.set_exception_handler(exception_handler) app = web.Application() @@ -2544,7 +2636,8 @@ async def test_error_in_performing_request(loop, ssl_ctx, await client.get('/') -async def test_await_after_cancelling(loop, aiohttp_client): +async def test_await_after_cancelling(aiohttp_client) -> None: + loop = asyncio.get_event_loop() async def handler(request): return web.Response() @@ -2577,7 +2670,7 @@ async def test_await_after_cancelling(loop, aiohttp_client): await asyncio.gather(fetch1(), fetch2(), canceller()) -async def test_async_payload_generator(aiohttp_client): +async def test_async_payload_generator(aiohttp_client) -> None: async def handler(request): data = await request.read() @@ -2598,7 +2691,7 @@ async def test_async_payload_generator(aiohttp_client): assert resp.status == 200 -async def test_read_from_closed_response(aiohttp_client): +async def test_read_from_closed_response(aiohttp_client) -> None: async def handler(request): return web.Response(body=b'data') @@ -2614,7 +2707,7 @@ async def test_read_from_closed_response(aiohttp_client): await resp.read() -async def test_read_from_closed_response2(aiohttp_client): +async def test_read_from_closed_response2(aiohttp_client) -> None: async def handler(request): return web.Response(body=b'data') @@ -2631,7 +2724,7 @@ async def test_read_from_closed_response2(aiohttp_client): await resp.read() -async def test_read_from_closed_content(aiohttp_client): +async def test_read_from_closed_content(aiohttp_client) -> None: async def handler(request): return web.Response(body=b'data') @@ -2647,7 +2740,7 @@ async def test_read_from_closed_content(aiohttp_client): await resp.content.readline() -async def test_read_timeout(aiohttp_client): +async def test_read_timeout(aiohttp_client) -> None: async def handler(request): await asyncio.sleep(5) return web.Response() @@ -2662,7 +2755,7 @@ async def test_read_timeout(aiohttp_client): await client.get('/') -async def test_read_timeout_on_prepared_response(aiohttp_client): +async def test_read_timeout_on_prepared_response(aiohttp_client) -> None: async def handler(request): resp = aiohttp.web.StreamResponse() await resp.prepare(request) diff --git a/tests/test_client_proto.py b/tests/test_client_proto.py index 64c3b2c..0e7b3dc 100644 --- a/tests/test_client_proto.py +++ b/tests/test_client_proto.py @@ -9,7 +9,7 @@ from aiohttp.client_reqrep import ClientResponse from aiohttp.helpers import TimerNoop -async def test_oserror(loop): +async def test_oserror(loop) -> None: proto = ResponseHandler(loop=loop) transport = mock.Mock() proto.connection_made(transport) @@ -19,8 +19,10 @@ async def test_oserror(loop): assert isinstance(proto.exception(), ClientOSError) -async def test_pause_resume_on_error(loop): +async def test_pause_resume_on_error(loop) -> None: proto = ResponseHandler(loop=loop) + transport = mock.Mock() + proto.connection_made(transport) proto.pause_reading() assert proto._reading_paused @@ -29,7 +31,7 @@ async def test_pause_resume_on_error(loop): assert not proto._reading_paused -async def test_client_proto_bad_message(loop): +async def test_client_proto_bad_message(loop) -> None: proto = ResponseHandler(loop=loop) transport = mock.Mock() proto.connection_made(transport) @@ -41,7 +43,7 @@ async def test_client_proto_bad_message(loop): assert isinstance(proto.exception(), http.HttpProcessingError) -async def test_uncompleted_message(loop): +async def test_uncompleted_message(loop) -> None: proto = ResponseHandler(loop=loop) transport = mock.Mock() proto.connection_made(transport) @@ -57,7 +59,7 @@ async def test_uncompleted_message(loop): assert dict(exc.message.headers) == {'Location': 'http://python.org/'} -async def test_client_protocol_readuntil_eof(loop): +async def test_client_protocol_readuntil_eof(loop) -> None: proto = ResponseHandler(loop=loop) transport = mock.Mock() proto.connection_made(transport) @@ -91,20 +93,20 @@ async def test_client_protocol_readuntil_eof(loop): assert response.content.is_eof() -async def test_empty_data(loop): +async def test_empty_data(loop) -> None: proto = ResponseHandler(loop=loop) proto.data_received(b'') # do nothing -async def test_schedule_timeout(loop): +async def test_schedule_timeout(loop) -> None: proto = ResponseHandler(loop=loop) proto.set_response_params(read_timeout=1) assert proto._read_timeout_handle is not None -async def test_drop_timeout(loop): +async def test_drop_timeout(loop) -> None: proto = ResponseHandler(loop=loop) proto.set_response_params(read_timeout=1) assert proto._read_timeout_handle is not None @@ -112,7 +114,7 @@ async def test_drop_timeout(loop): assert proto._read_timeout_handle is None -async def test_reschedule_timeout(loop): +async def test_reschedule_timeout(loop) -> None: proto = ResponseHandler(loop=loop) proto.set_response_params(read_timeout=1) assert proto._read_timeout_handle is not None @@ -122,7 +124,7 @@ async def test_reschedule_timeout(loop): assert proto._read_timeout_handle is not h -async def test_eof_received(loop): +async def test_eof_received(loop) -> None: proto = ResponseHandler(loop=loop) proto.set_response_params(read_timeout=1) assert proto._read_timeout_handle is not None diff --git a/tests/test_client_request.py b/tests/test_client_request.py index 07939be..3c674ea 100644 --- a/tests/test_client_request.py +++ b/tests/test_client_request.py @@ -74,39 +74,39 @@ def conn(transport, protocol): ) -def test_method1(make_request): +def test_method1(make_request) -> None: req = make_request('get', 'http://python.org/') assert req.method == 'GET' -def test_method2(make_request): +def test_method2(make_request) -> None: req = make_request('head', 'http://python.org/') assert req.method == 'HEAD' -def test_method3(make_request): +def test_method3(make_request) -> None: req = make_request('HEAD', 'http://python.org/') assert req.method == 'HEAD' -def test_version_1_0(make_request): +def test_version_1_0(make_request) -> None: req = make_request('get', 'http://python.org/', version='1.0') assert req.version == (1, 0) -def test_version_default(make_request): +def test_version_default(make_request) -> None: req = make_request('get', 'http://python.org/') assert req.version == (1, 1) -def test_request_info(make_request): +def test_request_info(make_request) -> None: req = make_request('get', 'http://python.org/') assert req.request_info == aiohttp.RequestInfo(URL('http://python.org/'), 'GET', req.headers) -def test_request_info_with_fragment(make_request): +def test_request_info_with_fragment(make_request) -> None: req = make_request('get', 'http://python.org/#urlfragment') assert req.request_info == aiohttp.RequestInfo( URL('http://python.org/'), @@ -114,18 +114,18 @@ def test_request_info_with_fragment(make_request): URL('http://python.org/#urlfragment')) -def test_version_err(make_request): +def test_version_err(make_request) -> None: with pytest.raises(ValueError): make_request('get', 'http://python.org/', version='1.c') -def test_https_proxy(make_request): +def test_https_proxy(make_request) -> None: with pytest.raises(ValueError): make_request( 'get', 'http://python.org/', proxy=URL('https://proxy.org')) -def test_keep_alive(make_request): +def test_keep_alive(make_request) -> None: req = make_request('get', 'http://python.org/', version=(0, 9)) assert not req.keep_alive() @@ -144,123 +144,148 @@ def test_keep_alive(make_request): assert not req.keep_alive() -def test_host_port_default_http(make_request): +def test_host_port_default_http(make_request) -> None: req = make_request('get', 'http://python.org/') assert req.host == 'python.org' assert req.port == 80 assert not req.ssl -def test_host_port_default_https(make_request): +def test_host_port_default_https(make_request) -> None: req = make_request('get', 'https://python.org/') assert req.host == 'python.org' assert req.port == 443 assert req.is_ssl() -def test_host_port_nondefault_http(make_request): +def test_host_port_nondefault_http(make_request) -> None: req = make_request('get', 'http://python.org:960/') assert req.host == 'python.org' assert req.port == 960 assert not req.is_ssl() -def test_host_port_nondefault_https(make_request): +def test_host_port_nondefault_https(make_request) -> None: req = make_request('get', 'https://python.org:960/') assert req.host == 'python.org' assert req.port == 960 assert req.is_ssl() -def test_host_port_default_ws(make_request): +def test_host_port_default_ws(make_request) -> None: req = make_request('get', 'ws://python.org/') assert req.host == 'python.org' assert req.port == 80 assert not req.is_ssl() -def test_host_port_default_wss(make_request): +def test_host_port_default_wss(make_request) -> None: req = make_request('get', 'wss://python.org/') assert req.host == 'python.org' assert req.port == 443 assert req.is_ssl() -def test_host_port_nondefault_ws(make_request): +def test_host_port_nondefault_ws(make_request) -> None: req = make_request('get', 'ws://python.org:960/') assert req.host == 'python.org' assert req.port == 960 assert not req.is_ssl() -def test_host_port_nondefault_wss(make_request): +def test_host_port_nondefault_wss(make_request) -> None: req = make_request('get', 'wss://python.org:960/') assert req.host == 'python.org' assert req.port == 960 assert req.is_ssl() -def test_host_port_err(make_request): +def test_host_port_err(make_request) -> None: with pytest.raises(ValueError): make_request('get', 'http://python.org:123e/') -def test_hostname_err(make_request): +def test_hostname_err(make_request) -> None: with pytest.raises(ValueError): make_request('get', 'http://:8080/') -def test_host_header_host_without_port(make_request): +def test_host_header_host_first(make_request) -> None: + req = make_request('get', 'http://python.org/') + assert list(req.headers)[0] == 'Host' + + +def test_host_header_host_without_port(make_request) -> None: req = make_request('get', 'http://python.org/') assert req.headers['HOST'] == 'python.org' -def test_host_header_host_with_default_port(make_request): +def test_host_header_host_with_default_port(make_request) -> None: req = make_request('get', 'http://python.org:80/') assert req.headers['HOST'] == 'python.org' -def test_host_header_host_with_nondefault_port(make_request): +def test_host_header_host_with_nondefault_port(make_request) -> None: req = make_request('get', 'http://python.org:99/') assert req.headers['HOST'] == 'python.org:99' -def test_host_header_host_idna_encode(make_request): +def test_host_header_host_idna_encode(make_request) -> None: req = make_request('get', 'http://xn--9caa.com') assert req.headers['HOST'] == 'xn--9caa.com' -def test_host_header_host_unicode(make_request): +def test_host_header_host_unicode(make_request) -> None: req = make_request('get', 'http://éé.com') assert req.headers['HOST'] == 'xn--9caa.com' -def test_host_header_explicit_host(make_request): +def test_host_header_explicit_host(make_request) -> None: req = make_request('get', 'http://python.org/', headers={'host': 'example.com'}) assert req.headers['HOST'] == 'example.com' -def test_host_header_explicit_host_with_port(make_request): +def test_host_header_explicit_host_with_port(make_request) -> None: req = make_request('get', 'http://python.org/', headers={'host': 'example.com:99'}) assert req.headers['HOST'] == 'example.com:99' -def test_default_loop(loop): +def test_host_header_ipv4(make_request) -> None: + req = make_request('get', 'http://127.0.0.2') + assert req.headers['HOST'] == '127.0.0.2' + + +def test_host_header_ipv6(make_request) -> None: + req = make_request('get', 'http://[::2]') + assert req.headers['HOST'] == '[::2]' + + +def test_host_header_ipv4_with_port(make_request) -> None: + req = make_request('get', 'http://127.0.0.2:99') + assert req.headers['HOST'] == '127.0.0.2:99' + + +def test_host_header_ipv6_with_port(make_request) -> None: + req = make_request('get', 'http://[::2]:99') + assert req.headers['HOST'] == '[::2]:99' + + +def test_default_loop(loop) -> None: asyncio.set_event_loop(loop) req = ClientRequest('get', URL('http://python.org/')) assert req.loop is loop -def test_default_headers_useragent(make_request): +def test_default_headers_useragent(make_request) -> None: req = make_request('get', 'http://python.org/') assert 'SERVER' not in req.headers assert 'USER-AGENT' in req.headers -def test_default_headers_useragent_custom(make_request): +def test_default_headers_useragent_custom(make_request) -> None: req = make_request('get', 'http://python.org/', headers={'user-agent': 'my custom agent'}) @@ -268,14 +293,14 @@ def test_default_headers_useragent_custom(make_request): assert 'my custom agent' == req.headers['User-Agent'] -def test_skip_default_useragent_header(make_request): +def test_skip_default_useragent_header(make_request) -> None: req = make_request('get', 'http://python.org/', skip_auto_headers=set([istr('user-agent')])) assert 'User-Agent' not in req.headers -def test_headers(make_request): +def test_headers(make_request) -> None: req = make_request('post', 'http://python.org/', headers={'Content-Type': 'text/plain'}) @@ -284,85 +309,85 @@ def test_headers(make_request): assert req.headers['ACCEPT-ENCODING'] == 'gzip, deflate' -def test_headers_list(make_request): +def test_headers_list(make_request) -> None: req = make_request('post', 'http://python.org/', headers=[('Content-Type', 'text/plain')]) assert 'CONTENT-TYPE' in req.headers assert req.headers['CONTENT-TYPE'] == 'text/plain' -def test_headers_default(make_request): +def test_headers_default(make_request) -> None: req = make_request('get', 'http://python.org/', headers={'ACCEPT-ENCODING': 'deflate'}) assert req.headers['ACCEPT-ENCODING'] == 'deflate' -def test_invalid_url(make_request): +def test_invalid_url(make_request) -> None: with pytest.raises(aiohttp.InvalidURL): make_request('get', 'hiwpefhipowhefopw') -def test_no_path(make_request): +def test_no_path(make_request) -> None: req = make_request('get', 'http://python.org') assert '/' == req.url.path -def test_ipv6_default_http_port(make_request): +def test_ipv6_default_http_port(make_request) -> None: req = make_request('get', 'http://[2001:db8::1]/') assert req.host == '2001:db8::1' assert req.port == 80 assert not req.ssl -def test_ipv6_default_https_port(make_request): +def test_ipv6_default_https_port(make_request) -> None: req = make_request('get', 'https://[2001:db8::1]/') assert req.host == '2001:db8::1' assert req.port == 443 assert req.is_ssl() -def test_ipv6_nondefault_http_port(make_request): +def test_ipv6_nondefault_http_port(make_request) -> None: req = make_request('get', 'http://[2001:db8::1]:960/') assert req.host == '2001:db8::1' assert req.port == 960 assert not req.is_ssl() -def test_ipv6_nondefault_https_port(make_request): +def test_ipv6_nondefault_https_port(make_request) -> None: req = make_request('get', 'https://[2001:db8::1]:960/') assert req.host == '2001:db8::1' assert req.port == 960 assert req.is_ssl() -def test_basic_auth(make_request): +def test_basic_auth(make_request) -> None: req = make_request('get', 'http://python.org', auth=aiohttp.BasicAuth('nkim', '1234')) assert 'AUTHORIZATION' in req.headers assert 'Basic bmtpbToxMjM0' == req.headers['AUTHORIZATION'] -def test_basic_auth_utf8(make_request): +def test_basic_auth_utf8(make_request) -> None: req = make_request('get', 'http://python.org', auth=aiohttp.BasicAuth('nkim', 'секрет', 'utf-8')) assert 'AUTHORIZATION' in req.headers assert 'Basic bmtpbTrRgdC10LrRgNC10YI=' == req.headers['AUTHORIZATION'] -def test_basic_auth_tuple_forbidden(make_request): +def test_basic_auth_tuple_forbidden(make_request) -> None: with pytest.raises(TypeError): make_request('get', 'http://python.org', auth=('nkim', '1234')) -def test_basic_auth_from_url(make_request): +def test_basic_auth_from_url(make_request) -> None: req = make_request('get', 'http://nkim:1234@python.org') assert 'AUTHORIZATION' in req.headers assert 'Basic bmtpbToxMjM0' == req.headers['AUTHORIZATION'] assert 'python.org' == req.host -def test_basic_auth_from_url_overriden(make_request): +def test_basic_auth_from_url_overridden(make_request) -> None: req = make_request('get', 'http://garbage@python.org', auth=aiohttp.BasicAuth('nkim', '1234')) assert 'AUTHORIZATION' in req.headers @@ -370,49 +395,49 @@ def test_basic_auth_from_url_overriden(make_request): assert 'python.org' == req.host -def test_path_is_not_double_encoded1(make_request): +def test_path_is_not_double_encoded1(make_request) -> None: req = make_request('get', "http://0.0.0.0/get/test case") assert req.url.raw_path == "/get/test%20case" -def test_path_is_not_double_encoded2(make_request): +def test_path_is_not_double_encoded2(make_request) -> None: req = make_request('get', "http://0.0.0.0/get/test%2fcase") assert req.url.raw_path == "/get/test%2Fcase" -def test_path_is_not_double_encoded3(make_request): +def test_path_is_not_double_encoded3(make_request) -> None: req = make_request('get', "http://0.0.0.0/get/test%20case") assert req.url.raw_path == "/get/test%20case" -def test_path_safe_chars_preserved(make_request): +def test_path_safe_chars_preserved(make_request) -> None: req = make_request('get', "http://0.0.0.0/get/:=+/%2B/") assert req.url.path == "/get/:=+/+/" -def test_params_are_added_before_fragment1(make_request): +def test_params_are_added_before_fragment1(make_request) -> None: req = make_request('GET', "http://example.com/path#fragment", params={"a": "b"}) assert str(req.url) == "http://example.com/path?a=b" -def test_params_are_added_before_fragment2(make_request): +def test_params_are_added_before_fragment2(make_request) -> None: req = make_request('GET', "http://example.com/path?key=value#fragment", params={"a": "b"}) assert str(req.url) == "http://example.com/path?key=value&a=b" -def test_path_not_contain_fragment1(make_request): +def test_path_not_contain_fragment1(make_request) -> None: req = make_request('GET', "http://example.com/path#fragment") assert req.url.path == "/path" -def test_path_not_contain_fragment2(make_request): +def test_path_not_contain_fragment2(make_request) -> None: req = make_request('GET', "http://example.com/path?key=value#fragment") assert str(req.url) == "http://example.com/path?key=value" -def test_cookies(make_request): +def test_cookies(make_request) -> None: req = make_request('get', 'http://test.com/path', cookies={'cookie1': 'val1'}) @@ -420,7 +445,7 @@ def test_cookies(make_request): assert 'cookie1=val1' == req.headers['COOKIE'] -def test_cookies_merge_with_headers(make_request): +def test_cookies_merge_with_headers(make_request) -> None: req = make_request('get', 'http://test.com/path', headers={'cookie': 'cookie1=val1'}, cookies={'cookie2': 'val2'}) @@ -428,25 +453,25 @@ def test_cookies_merge_with_headers(make_request): assert 'cookie1=val1; cookie2=val2' == req.headers['COOKIE'] -def test_unicode_get1(make_request): +def test_unicode_get1(make_request) -> None: req = make_request('get', 'http://python.org', params={'foo': 'f\xf8\xf8'}) assert 'http://python.org/?foo=f%C3%B8%C3%B8' == str(req.url) -def test_unicode_get2(make_request): +def test_unicode_get2(make_request) -> None: req = make_request('', 'http://python.org', params={'f\xf8\xf8': 'f\xf8\xf8'}) assert 'http://python.org/?f%C3%B8%C3%B8=f%C3%B8%C3%B8' == str(req.url) -def test_unicode_get3(make_request): +def test_unicode_get3(make_request) -> None: req = make_request('', 'http://python.org', params={'foo': 'foo'}) assert 'http://python.org/?foo=foo' == str(req.url) -def test_unicode_get4(make_request): +def test_unicode_get4(make_request) -> None: def join(*suffix): return urllib.parse.urljoin('http://python.org/', '/'.join(suffix)) @@ -454,7 +479,7 @@ def test_unicode_get4(make_request): assert 'http://python.org/%C3%B8?foo=foo' == str(req.url) -def test_query_multivalued_param(make_request): +def test_query_multivalued_param(make_request) -> None: for meth in ClientRequest.ALL_METHODS: req = make_request( meth, 'http://python.org', @@ -463,38 +488,38 @@ def test_query_multivalued_param(make_request): assert str(req.url) == 'http://python.org/?test=foo&test=baz' -def test_query_str_param(make_request): +def test_query_str_param(make_request) -> None: for meth in ClientRequest.ALL_METHODS: req = make_request(meth, 'http://python.org', params='test=foo') assert str(req.url) == 'http://python.org/?test=foo' -def test_query_bytes_param_raises(make_request): +def test_query_bytes_param_raises(make_request) -> None: for meth in ClientRequest.ALL_METHODS: with pytest.raises(TypeError): make_request(meth, 'http://python.org', params=b'test=foo') -def test_query_str_param_is_not_encoded(make_request): +def test_query_str_param_is_not_encoded(make_request) -> None: for meth in ClientRequest.ALL_METHODS: req = make_request(meth, 'http://python.org', params='test=f+oo') assert str(req.url) == 'http://python.org/?test=f+oo' -def test_params_update_path_and_url(make_request): +def test_params_update_path_and_url(make_request) -> None: req = make_request('get', 'http://python.org', params=(('test', 'foo'), ('test', 'baz'))) assert str(req.url) == 'http://python.org/?test=foo&test=baz' -def test_params_empty_path_and_url(make_request): +def test_params_empty_path_and_url(make_request) -> None: req_empty = make_request('get', 'http://python.org', params={}) assert str(req_empty.url) == 'http://python.org' req_none = make_request('get', 'http://python.org') assert str(req_none.url) == 'http://python.org' -def test_gen_netloc_all(make_request): +def test_gen_netloc_all(make_request) -> None: req = make_request('get', 'https://aiohttp:pwpwpw@' + '12345678901234567890123456789' + @@ -503,7 +528,7 @@ def test_gen_netloc_all(make_request): '012345678901234567890:8080' -def test_gen_netloc_no_port(make_request): +def test_gen_netloc_no_port(make_request) -> None: req = make_request('get', 'https://aiohttp:pwpwpw@' + '12345678901234567890123456789' + @@ -512,7 +537,7 @@ def test_gen_netloc_no_port(make_request): '012345678901234567890' -async def test_connection_header(loop, conn): +async def test_connection_header(loop, conn) -> None: req = ClientRequest('get', URL('http://python.org'), loop=loop) req.keep_alive = mock.Mock() req.headers.clear() @@ -535,7 +560,7 @@ async def test_connection_header(loop, conn): assert req.headers.get('CONNECTION') == 'close' -async def test_no_content_length(loop, conn): +async def test_no_content_length(loop, conn) -> None: req = ClientRequest('get', URL('http://python.org'), loop=loop) resp = await req.send(conn) assert req.headers.get('CONTENT-LENGTH') is None @@ -543,7 +568,7 @@ async def test_no_content_length(loop, conn): resp.close() -async def test_no_content_length_head(loop, conn): +async def test_no_content_length_head(loop, conn) -> None: req = ClientRequest('head', URL('http://python.org'), loop=loop) resp = await req.send(conn) assert req.headers.get('CONTENT-LENGTH') is None @@ -551,14 +576,14 @@ async def test_no_content_length_head(loop, conn): resp.close() -async def test_content_type_auto_header_get(loop, conn): +async def test_content_type_auto_header_get(loop, conn) -> None: req = ClientRequest('get', URL('http://python.org'), loop=loop) resp = await req.send(conn) assert 'CONTENT-TYPE' not in req.headers resp.close() -async def test_content_type_auto_header_form(loop, conn): +async def test_content_type_auto_header_form(loop, conn) -> None: req = ClientRequest('post', URL('http://python.org'), data={'hey': 'you'}, loop=loop) resp = await req.send(conn) @@ -567,7 +592,7 @@ async def test_content_type_auto_header_form(loop, conn): resp.close() -async def test_content_type_auto_header_bytes(loop, conn): +async def test_content_type_auto_header_bytes(loop, conn) -> None: req = ClientRequest('post', URL('http://python.org'), data=b'hey you', loop=loop) resp = await req.send(conn) @@ -575,7 +600,7 @@ async def test_content_type_auto_header_bytes(loop, conn): resp.close() -async def test_content_type_skip_auto_header_bytes(loop, conn): +async def test_content_type_skip_auto_header_bytes(loop, conn) -> None: req = ClientRequest('post', URL('http://python.org'), data=b'hey you', skip_auto_headers={'Content-Type'}, loop=loop) @@ -584,7 +609,7 @@ async def test_content_type_skip_auto_header_bytes(loop, conn): resp.close() -async def test_content_type_skip_auto_header_form(loop, conn): +async def test_content_type_skip_auto_header_form(loop, conn) -> None: req = ClientRequest('post', URL('http://python.org'), data={'hey': 'you'}, loop=loop, skip_auto_headers={'Content-Type'}) @@ -593,7 +618,8 @@ async def test_content_type_skip_auto_header_form(loop, conn): resp.close() -async def test_content_type_auto_header_content_length_no_skip(loop, conn): +async def test_content_type_auto_header_content_length_no_skip(loop, + conn) -> None: req = ClientRequest('post', URL('http://python.org'), data=io.BytesIO(b'hey'), skip_auto_headers={'Content-Length'}, @@ -603,7 +629,7 @@ async def test_content_type_auto_header_content_length_no_skip(loop, conn): resp.close() -async def test_urlencoded_formdata_charset(loop, conn): +async def test_urlencoded_formdata_charset(loop, conn) -> None: req = ClientRequest( 'post', URL('http://python.org'), data=aiohttp.FormData({'hey': 'you'}, charset='koi8-r'), loop=loop) @@ -612,7 +638,7 @@ async def test_urlencoded_formdata_charset(loop, conn): req.headers.get('CONTENT-TYPE') -async def test_post_data(loop, conn): +async def test_post_data(loop, conn) -> None: for meth in ClientRequest.POST_METHODS: req = ClientRequest( meth, URL('http://python.org/'), @@ -626,7 +652,7 @@ async def test_post_data(loop, conn): resp.close() -async def test_pass_falsy_data(loop): +async def test_pass_falsy_data(loop) -> None: with mock.patch( 'aiohttp.client_reqrep.ClientRequest.update_body_from_data'): req = ClientRequest( @@ -636,7 +662,7 @@ async def test_pass_falsy_data(loop): await req.close() -async def test_pass_falsy_data_file(loop, tmpdir): +async def test_pass_falsy_data_file(loop, tmpdir) -> None: testfile = tmpdir.join('tmpfile').open('w+b') testfile.write(b'data') testfile.seek(0) @@ -651,7 +677,7 @@ async def test_pass_falsy_data_file(loop, tmpdir): # Elasticsearch API requires to send request body with GET-requests -async def test_get_with_data(loop): +async def test_get_with_data(loop) -> None: for meth in ClientRequest.GET_METHODS: req = ClientRequest( meth, URL('http://python.org/'), data={'life': '42'}, @@ -661,7 +687,7 @@ async def test_get_with_data(loop): await req.close() -async def test_bytes_data(loop, conn): +async def test_bytes_data(loop, conn) -> None: for meth in ClientRequest.POST_METHODS: req = ClientRequest( meth, URL('http://python.org/'), @@ -675,7 +701,7 @@ async def test_bytes_data(loop, conn): resp.close() -async def test_content_encoding(loop, conn): +async def test_content_encoding(loop, conn) -> None: req = ClientRequest('post', URL('http://python.org/'), data='foo', compress='deflate', loop=loop) with mock.patch('aiohttp.client_reqrep.StreamWriter') as m_writer: @@ -689,7 +715,8 @@ async def test_content_encoding(loop, conn): resp.close() -async def test_content_encoding_dont_set_headers_if_no_body(loop, conn): +async def test_content_encoding_dont_set_headers_if_no_body(loop, + conn) -> None: req = ClientRequest('post', URL('http://python.org/'), compress='deflate', loop=loop) with mock.patch('aiohttp.client_reqrep.http'): @@ -700,7 +727,7 @@ async def test_content_encoding_dont_set_headers_if_no_body(loop, conn): resp.close() -async def test_content_encoding_header(loop, conn): +async def test_content_encoding_header(loop, conn) -> None: req = ClientRequest( 'post', URL('http://python.org/'), data='foo', headers={'Content-Encoding': 'deflate'}, loop=loop) @@ -714,14 +741,14 @@ async def test_content_encoding_header(loop, conn): resp.close() -async def test_compress_and_content_encoding(loop, conn): +async def test_compress_and_content_encoding(loop, conn) -> None: with pytest.raises(ValueError): ClientRequest('post', URL('http://python.org/'), data='foo', headers={'content-encoding': 'deflate'}, compress='deflate', loop=loop) -async def test_chunked(loop, conn): +async def test_chunked(loop, conn) -> None: req = ClientRequest( 'post', URL('http://python.org/'), headers={'TRANSFER-ENCODING': 'gzip'}, loop=loop) @@ -731,7 +758,7 @@ async def test_chunked(loop, conn): resp.close() -async def test_chunked2(loop, conn): +async def test_chunked2(loop, conn) -> None: req = ClientRequest( 'post', URL('http://python.org/'), headers={'Transfer-encoding': 'chunked'}, loop=loop) @@ -741,7 +768,7 @@ async def test_chunked2(loop, conn): resp.close() -async def test_chunked_explicit(loop, conn): +async def test_chunked_explicit(loop, conn) -> None: req = ClientRequest( 'post', URL('http://python.org/'), chunked=True, loop=loop) with mock.patch('aiohttp.client_reqrep.StreamWriter') as m_writer: @@ -754,21 +781,21 @@ async def test_chunked_explicit(loop, conn): resp.close() -async def test_chunked_length(loop, conn): +async def test_chunked_length(loop, conn) -> None: with pytest.raises(ValueError): ClientRequest( 'post', URL('http://python.org/'), headers={'CONTENT-LENGTH': '1000'}, chunked=True, loop=loop) -async def test_chunked_transfer_encoding(loop, conn): +async def test_chunked_transfer_encoding(loop, conn) -> None: with pytest.raises(ValueError): ClientRequest( 'post', URL('http://python.org/'), headers={'TRANSFER-ENCODING': 'chunked'}, chunked=True, loop=loop) -async def test_file_upload_not_chunked(loop): +async def test_file_upload_not_chunked(loop) -> None: here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: @@ -781,7 +808,7 @@ async def test_file_upload_not_chunked(loop): await req.close() -async def test_precompressed_data_stays_intact(loop): +async def test_precompressed_data_stays_intact(loop) -> None: data = zlib.compress(b'foobar') req = ClientRequest( 'post', URL('http://python.org/'), @@ -795,7 +822,7 @@ async def test_precompressed_data_stays_intact(loop): await req.close() -async def test_file_upload_not_chunked_seek(loop): +async def test_file_upload_not_chunked_seek(loop) -> None: here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: @@ -809,7 +836,7 @@ async def test_file_upload_not_chunked_seek(loop): await req.close() -async def test_file_upload_force_chunked(loop): +async def test_file_upload_force_chunked(loop) -> None: here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: @@ -823,7 +850,7 @@ async def test_file_upload_force_chunked(loop): await req.close() -async def test_expect100(loop, conn): +async def test_expect100(loop, conn) -> None: req = ClientRequest('get', URL('http://python.org/'), expect100=True, loop=loop) resp = await req.send(conn) @@ -833,7 +860,7 @@ async def test_expect100(loop, conn): resp.close() -async def test_expect_100_continue_header(loop, conn): +async def test_expect_100_continue_header(loop, conn) -> None: req = ClientRequest('get', URL('http://python.org/'), headers={'expect': '100-continue'}, loop=loop) resp = await req.send(conn) @@ -843,7 +870,7 @@ async def test_expect_100_continue_header(loop, conn): resp.close() -async def test_data_stream(loop, buf, conn): +async def test_data_stream(loop, buf, conn) -> None: @async_generator async def gen(): await yield_(b'binary data') @@ -863,7 +890,7 @@ async def test_data_stream(loop, buf, conn): await req.close() -async def test_data_stream_deprecated(loop, buf, conn): +async def test_data_stream_deprecated(loop, buf, conn) -> None: with pytest.warns(DeprecationWarning): @aiohttp.streamer async def gen(writer): @@ -884,7 +911,7 @@ async def test_data_stream_deprecated(loop, buf, conn): await req.close() -async def test_data_file(loop, buf, conn): +async def test_data_file(loop, buf, conn) -> None: req = ClientRequest( 'POST', URL('http://python.org/'), data=io.BufferedReader(io.BytesIO(b'*' * 2)), @@ -902,7 +929,7 @@ async def test_data_file(loop, buf, conn): await req.close() -async def test_data_stream_exc(loop, conn): +async def test_data_stream_exc(loop, conn) -> None: fut = loop.create_future() @async_generator @@ -928,7 +955,7 @@ async def test_data_stream_exc(loop, conn): await req.close() -async def test_data_stream_exc_deprecated(loop, conn): +async def test_data_stream_exc_deprecated(loop, conn) -> None: fut = loop.create_future() with pytest.warns(DeprecationWarning): @@ -955,7 +982,7 @@ async def test_data_stream_exc_deprecated(loop, conn): await req.close() -async def test_data_stream_exc_chain(loop, conn): +async def test_data_stream_exc_chain(loop, conn) -> None: fut = loop.create_future() @async_generator @@ -984,7 +1011,7 @@ async def test_data_stream_exc_chain(loop, conn): await req.close() -async def test_data_stream_exc_chain_deprecated(loop, conn): +async def test_data_stream_exc_chain_deprecated(loop, conn) -> None: fut = loop.create_future() with pytest.warns(DeprecationWarning): @@ -1014,7 +1041,7 @@ async def test_data_stream_exc_chain_deprecated(loop, conn): await req.close() -async def test_data_stream_continue(loop, buf, conn): +async def test_data_stream_continue(loop, buf, conn) -> None: @async_generator async def gen(): await yield_(b'binary data') @@ -1039,7 +1066,7 @@ async def test_data_stream_continue(loop, buf, conn): resp.close() -async def test_data_stream_continue_deprecated(loop, buf, conn): +async def test_data_stream_continue_deprecated(loop, buf, conn) -> None: with pytest.warns(DeprecationWarning): @aiohttp.streamer async def gen(writer): @@ -1066,7 +1093,7 @@ async def test_data_stream_continue_deprecated(loop, buf, conn): resp.close() -async def test_data_continue(loop, buf, conn): +async def test_data_continue(loop, buf, conn) -> None: req = ClientRequest( 'POST', URL('http://python.org/'), data=b'data', expect100=True, loop=loop) @@ -1085,7 +1112,7 @@ async def test_data_continue(loop, buf, conn): resp.close() -async def test_close(loop, buf, conn): +async def test_close(loop, buf, conn) -> None: @async_generator async def gen(): await asyncio.sleep(0.00001) @@ -1100,7 +1127,7 @@ async def test_close(loop, buf, conn): resp.close() -async def test_close_deprecated(loop, buf, conn): +async def test_close_deprecated(loop, buf, conn) -> None: with pytest.warns(DeprecationWarning): @aiohttp.streamer async def gen(writer): @@ -1116,7 +1143,7 @@ async def test_close_deprecated(loop, buf, conn): resp.close() -async def test_custom_response_class(loop, conn): +async def test_custom_response_class(loop, conn) -> None: class CustomResponse(ClientResponse): def read(self, decode=False): return 'customized!' @@ -1130,7 +1157,7 @@ async def test_custom_response_class(loop, conn): resp.close() -async def test_oserror_on_write_bytes(loop, conn): +async def test_oserror_on_write_bytes(loop, conn) -> None: req = ClientRequest( 'POST', URL('http://python.org/'), loop=loop) @@ -1144,7 +1171,7 @@ async def test_oserror_on_write_bytes(loop, conn): assert isinstance(exc, aiohttp.ClientOSError) -async def test_terminate(loop, conn): +async def test_terminate(loop, conn) -> None: req = ClientRequest('get', URL('http://python.org'), loop=loop) resp = await req.send(conn) assert req._writer is not None @@ -1156,7 +1183,7 @@ async def test_terminate(loop, conn): resp.close() -def test_terminate_with_closed_loop(loop, conn): +def test_terminate_with_closed_loop(loop, conn) -> None: req = resp = writer = None async def go(): @@ -1177,7 +1204,7 @@ def test_terminate_with_closed_loop(loop, conn): resp.close() -def test_terminate_without_writer(loop): +def test_terminate_without_writer(loop) -> None: req = ClientRequest('get', URL('http://python.org'), loop=loop) assert req._writer is None @@ -1185,7 +1212,7 @@ def test_terminate_without_writer(loop): assert req._writer is None -async def test_custom_req_rep(loop): +async def test_custom_req_rep(loop) -> None: conn = None class CustomResponse(ClientResponse): @@ -1239,23 +1266,23 @@ async def test_custom_req_rep(loop): conn.close() -def test_verify_ssl_false_with_ssl_context(loop): +def test_verify_ssl_false_with_ssl_context(loop) -> None: with pytest.warns(DeprecationWarning): with pytest.raises(ValueError): _merge_ssl_params(None, verify_ssl=False, ssl_context=mock.Mock(), fingerprint=None) -def test_bad_fingerprint(loop): +def test_bad_fingerprint(loop) -> None: with pytest.raises(ValueError): Fingerprint(b'invalid') -def test_insecure_fingerprint_md5(loop): +def test_insecure_fingerprint_md5(loop) -> None: with pytest.raises(ValueError): Fingerprint(hashlib.md5(b"foo").digest()) -def test_insecure_fingerprint_sha1(loop): +def test_insecure_fingerprint_sha1(loop) -> None: with pytest.raises(ValueError): Fingerprint(hashlib.sha1(b"foo").digest()) diff --git a/tests/test_client_response.py b/tests/test_client_response.py index 1285294..c61998d 100644 --- a/tests/test_client_response.py +++ b/tests/test_client_response.py @@ -21,7 +21,7 @@ def session(): return mock.Mock() -async def test_http_processing_error(session): +async def test_http_processing_error(session) -> None: loop = mock.Mock() request_info = mock.Mock() response = ClientResponse( @@ -36,7 +36,7 @@ async def test_http_processing_error(session): loop.get_debug.return_value = True connection = mock.Mock() - connection.protocol = aiohttp.DataQueue(loop=loop) + connection.protocol = aiohttp.DataQueue(loop) connection.protocol.set_response_params = mock.Mock() connection.protocol.set_exception(http.HttpProcessingError()) @@ -46,7 +46,7 @@ async def test_http_processing_error(session): assert info.value.request_info is request_info -def test_del(session): +def test_del(session) -> None: loop = mock.Mock() response = ClientResponse('get', URL('http://del-cl-resp.org'), request_info=mock.Mock(), @@ -71,7 +71,7 @@ def test_del(session): connection.release.assert_called_with() -def test_close(loop, session): +def test_close(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -88,7 +88,7 @@ def test_close(loop, session): response.close() -def test_wait_for_100_1(loop, session): +def test_wait_for_100_1(loop, session) -> None: response = ClientResponse( 'get', URL('http://python.org'), continue100=object(), request_info=mock.Mock(), @@ -101,7 +101,7 @@ def test_wait_for_100_1(loop, session): response.close() -def test_wait_for_100_2(loop, session): +def test_wait_for_100_2(loop, session) -> None: response = ClientResponse( 'get', URL('http://python.org'), request_info=mock.Mock(), @@ -115,7 +115,7 @@ def test_wait_for_100_2(loop, session): response.close() -def test_repr(loop, session): +def test_repr(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -130,7 +130,7 @@ def test_repr(loop, session): in repr(response) -def test_repr_non_ascii_url(): +def test_repr_non_ascii_url() -> None: response = ClientResponse('get', URL('http://fake-host.org/\u03bb'), request_info=mock.Mock(), writer=mock.Mock(), @@ -143,7 +143,7 @@ def test_repr_non_ascii_url(): in repr(response) -def test_repr_non_ascii_reason(): +def test_repr_non_ascii_reason() -> None: response = ClientResponse('get', URL('http://fake-host.org/path'), request_info=mock.Mock(), writer=mock.Mock(), @@ -157,7 +157,7 @@ def test_repr_non_ascii_reason(): in repr(response) -def test_url_obj_deprecated(): +def test_url_obj_deprecated() -> None: response = ClientResponse('get', URL('http://fake-host.org/'), request_info=mock.Mock(), writer=mock.Mock(), @@ -170,7 +170,7 @@ def test_url_obj_deprecated(): response.url_obj -async def test_read_and_release_connection(loop, session): +async def test_read_and_release_connection(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -192,7 +192,7 @@ async def test_read_and_release_connection(loop, session): assert response._connection is None -async def test_read_and_release_connection_with_error(loop, session): +async def test_read_and_release_connection_with_error(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -210,7 +210,7 @@ async def test_read_and_release_connection_with_error(loop, session): assert response._closed -async def test_release(loop, session): +async def test_release(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -230,7 +230,7 @@ async def test_release(loop, session): @pytest.mark.skipif(sys.implementation.name != 'cpython', reason="Other implementations has different GC strategies") -async def test_release_on_del(loop, session): +async def test_release_on_del(loop, session) -> None: connection = mock.Mock() connection.protocol.upgraded = False @@ -251,7 +251,7 @@ async def test_release_on_del(loop, session): assert connection.release.called -async def test_response_eof(loop, session): +async def test_response_eof(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -269,7 +269,7 @@ async def test_response_eof(loop, session): assert response._connection is None -async def test_response_eof_upgraded(loop, session): +async def test_response_eof_upgraded(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -287,7 +287,7 @@ async def test_response_eof_upgraded(loop, session): assert response._connection is conn -async def test_response_eof_after_connection_detach(loop, session): +async def test_response_eof_after_connection_detach(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -305,7 +305,7 @@ async def test_response_eof_after_connection_detach(loop, session): assert response._connection is None -async def test_text(loop, session): +async def test_text(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -330,7 +330,7 @@ async def test_text(loop, session): assert response._connection is None -async def test_text_bad_encoding(loop, session): +async def test_text_bad_encoding(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -358,7 +358,7 @@ async def test_text_bad_encoding(loop, session): assert response._connection is None -async def test_text_custom_encoding(loop, session): +async def test_text_custom_encoding(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -385,7 +385,7 @@ async def test_text_custom_encoding(loop, session): assert not response.get_encoding.called -async def test_text_detect_encoding(loop, session): +async def test_text_detect_encoding(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -410,7 +410,7 @@ async def test_text_detect_encoding(loop, session): assert response._connection is None -async def test_text_detect_encoding_if_invalid_charset(loop, session): +async def test_text_detect_encoding_if_invalid_charset(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -436,7 +436,7 @@ async def test_text_detect_encoding_if_invalid_charset(loop, session): assert response.get_encoding().lower() in ('windows-1251', 'maccyrillic') -async def test_text_after_read(loop, session): +async def test_text_after_read(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -461,7 +461,7 @@ async def test_text_after_read(loop, session): assert response._connection is None -async def test_json(loop, session): +async def test_json(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -486,7 +486,7 @@ async def test_json(loop, session): assert response._connection is None -async def test_json_extended_content_type(loop, session): +async def test_json_extended_content_type(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -512,7 +512,7 @@ async def test_json_extended_content_type(loop, session): assert response._connection is None -async def test_json_custom_content_type(loop, session): +async def test_json_custom_content_type(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -537,7 +537,7 @@ async def test_json_custom_content_type(loop, session): assert response._connection is None -async def test_json_custom_loader(loop, session): +async def test_json_custom_loader(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -557,7 +557,7 @@ async def test_json_custom_loader(loop, session): assert res == 'data-custom' -async def test_json_invalid_content_type(loop, session): +async def test_json_invalid_content_type(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -576,7 +576,7 @@ async def test_json_invalid_content_type(loop, session): assert info.value.request_info == response.request_info -async def test_json_no_content(loop, session): +async def test_json_no_content(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -593,7 +593,7 @@ async def test_json_no_content(loop, session): assert res is None -async def test_json_override_encoding(loop, session): +async def test_json_override_encoding(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -620,7 +620,7 @@ async def test_json_override_encoding(loop, session): assert not response.get_encoding.called -def test_get_encoding_unknown(loop, session): +def test_get_encoding_unknown(loop, session) -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -636,7 +636,7 @@ def test_get_encoding_unknown(loop, session): assert response.get_encoding() == 'utf-8' -def test_raise_for_status_2xx(): +def test_raise_for_status_2xx() -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -650,7 +650,7 @@ def test_raise_for_status_2xx(): response.raise_for_status() # should not raise -def test_raise_for_status_4xx(): +def test_raise_for_status_4xx() -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -665,9 +665,10 @@ def test_raise_for_status_4xx(): response.raise_for_status() assert str(cm.value.status) == '409' assert str(cm.value.message) == "CONFLICT" + assert response.closed -def test_resp_host(): +def test_resp_host() -> None: response = ClientResponse('get', URL('http://del-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -679,7 +680,7 @@ def test_resp_host(): assert 'del-cl-resp.org' == response.host -def test_content_type(): +def test_content_type() -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -693,7 +694,7 @@ def test_content_type(): assert 'application/json' == response.content_type -def test_content_type_no_header(): +def test_content_type_no_header() -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -707,7 +708,7 @@ def test_content_type_no_header(): assert 'application/octet-stream' == response.content_type -def test_charset(): +def test_charset() -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -721,7 +722,7 @@ def test_charset(): assert 'cp1251' == response.charset -def test_charset_no_header(): +def test_charset_no_header() -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -735,7 +736,7 @@ def test_charset_no_header(): assert response.charset is None -def test_charset_no_charset(): +def test_charset_no_charset() -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -749,7 +750,7 @@ def test_charset_no_charset(): assert response.charset is None -def test_content_disposition_full(): +def test_content_disposition_full() -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -768,7 +769,7 @@ def test_content_disposition_full(): response.content_disposition.parameters["foo"] = "baz" -def test_content_disposition_no_parameters(): +def test_content_disposition_no_parameters() -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -784,7 +785,7 @@ def test_content_disposition_no_parameters(): assert {} == response.content_disposition.parameters -def test_content_disposition_no_header(): +def test_content_disposition_no_header() -> None: response = ClientResponse('get', URL('http://def-cl-resp.org'), request_info=mock.Mock(), writer=mock.Mock(), @@ -798,7 +799,7 @@ def test_content_disposition_no_header(): assert response.content_disposition is None -def test_response_request_info(): +def test_response_request_info() -> None: url = 'http://def-cl-resp.org' headers = {'Content-Type': 'application/json;charset=cp1251'} response = ClientResponse( @@ -820,7 +821,7 @@ def test_response_request_info(): assert headers == response.request_info.headers -def test_request_info_in_exception(): +def test_request_info_in_exception() -> None: url = 'http://def-cl-resp.org' headers = {'Content-Type': 'application/json;charset=cp1251'} response = ClientResponse( @@ -845,7 +846,7 @@ def test_request_info_in_exception(): assert cm.value.request_info == response.request_info -def test_no_redirect_history_in_exception(): +def test_no_redirect_history_in_exception() -> None: url = 'http://def-cl-resp.org' headers = {'Content-Type': 'application/json;charset=cp1251'} response = ClientResponse( @@ -870,7 +871,7 @@ def test_no_redirect_history_in_exception(): assert () == cm.value.history -def test_redirect_history_in_exception(): +def test_redirect_history_in_exception() -> None: hist_url = 'http://def-cl-resp.org' url = 'http://def-cl-resp.org/index.htm' hist_headers = {'Content-Type': 'application/json;charset=cp1251', @@ -921,7 +922,7 @@ def test_redirect_history_in_exception(): assert [hist_response] == cm.value.history -async def test_response_read_triggers_callback(loop, session): +async def test_response_read_triggers_callback(loop, session) -> None: trace = mock.Mock() trace.send_response_chunk_received = make_mocked_coro() response_body = b'This is response' @@ -958,7 +959,7 @@ async def test_response_read_triggers_callback(loop, session): ) -def test_response_real_url(loop, session): +def test_response_real_url(loop, session) -> None: url = URL('http://def-cl-resp.org/#urlfragment') response = ClientResponse('get', url, request_info=mock.Mock(), @@ -972,7 +973,7 @@ def test_response_real_url(loop, session): assert response.real_url == url -def test_response_links_comma_separated(loop, session): +def test_response_links_comma_separated(loop, session) -> None: url = URL('http://def-cl-resp.org/') response = ClientResponse('get', url, request_info=mock.Mock(), @@ -1001,7 +1002,7 @@ def test_response_links_comma_separated(loop, session): ) -def test_response_links_multiple_headers(loop, session): +def test_response_links_multiple_headers(loop, session) -> None: url = URL('http://def-cl-resp.org/') response = ClientResponse('get', url, request_info=mock.Mock(), @@ -1033,7 +1034,7 @@ def test_response_links_multiple_headers(loop, session): ) -def test_response_links_no_rel(loop, session): +def test_response_links_no_rel(loop, session) -> None: url = URL('http://def-cl-resp.org/') response = ClientResponse('get', url, request_info=mock.Mock(), @@ -1058,7 +1059,7 @@ def test_response_links_no_rel(loop, session): ) -def test_response_links_quoted(loop, session): +def test_response_links_quoted(loop, session) -> None: url = URL('http://def-cl-resp.org/') response = ClientResponse('get', url, request_info=mock.Mock(), @@ -1083,7 +1084,7 @@ def test_response_links_quoted(loop, session): ) -def test_response_links_relative(loop, session): +def test_response_links_relative(loop, session) -> None: url = URL('http://def-cl-resp.org/') response = ClientResponse('get', url, request_info=mock.Mock(), @@ -1108,7 +1109,7 @@ def test_response_links_relative(loop, session): ) -def test_response_links_empty(loop, session): +def test_response_links_empty(loop, session) -> None: url = URL('http://def-cl-resp.org/') response = ClientResponse('get', url, request_info=mock.Mock(), diff --git a/tests/test_client_session.py b/tests/test_client_session.py index bc304bc..43fc6cf 100644 --- a/tests/test_client_session.py +++ b/tests/test_client_session.py @@ -21,7 +21,9 @@ from aiohttp.helpers import DEBUG, PY_36 @pytest.fixture def connector(loop): - conn = BaseConnector(loop=loop) + async def make_conn(): + return BaseConnector(loop=loop) + conn = loop.run_until_complete(make_conn()) proto = mock.Mock() conn._conns['a'] = [(proto, 123)] yield conn @@ -32,7 +34,7 @@ def connector(loop): def create_session(loop): session = None - def maker(*args, **kwargs): + async def maker(*args, **kwargs): nonlocal session session = ClientSession(*args, loop=loop, **kwargs) return session @@ -42,8 +44,8 @@ def create_session(loop): @pytest.fixture -def session(create_session): - return create_session() +def session(create_session, loop): + return loop.run_until_complete(create_session()) @pytest.fixture @@ -59,60 +61,61 @@ def params(): read_until_eof=False) -def test_close_coro(create_session, loop): - session = create_session() - loop.run_until_complete(session.close()) +async def test_close_coro(create_session) -> None: + session = await create_session() + await session.close() -def test_init_headers_simple_dict(create_session): - session = create_session(headers={"h1": "header1", - "h2": "header2"}) +async def test_init_headers_simple_dict(create_session) -> None: + session = await create_session(headers={"h1": "header1", + "h2": "header2"}) assert (sorted(session._default_headers.items()) == ([("h1", "header1"), ("h2", "header2")])) -def test_init_headers_list_of_tuples(create_session): - session = create_session(headers=[("h1", "header1"), - ("h2", "header2"), - ("h3", "header3")]) +async def test_init_headers_list_of_tuples(create_session) -> None: + session = await create_session(headers=[("h1", "header1"), + ("h2", "header2"), + ("h3", "header3")]) assert (session._default_headers == CIMultiDict([("h1", "header1"), ("h2", "header2"), ("h3", "header3")])) -def test_init_headers_MultiDict(create_session): - session = create_session(headers=MultiDict([("h1", "header1"), - ("h2", "header2"), - ("h3", "header3")])) +async def test_init_headers_MultiDict(create_session) -> None: + session = await create_session(headers=MultiDict([("h1", "header1"), + ("h2", "header2"), + ("h3", "header3")])) assert (session._default_headers == CIMultiDict([("H1", "header1"), ("H2", "header2"), ("H3", "header3")])) -def test_init_headers_list_of_tuples_with_duplicates(create_session): - session = create_session(headers=[("h1", "header11"), - ("h2", "header21"), - ("h1", "header12")]) +async def test_init_headers_list_of_tuples_with_duplicates( + create_session) -> None: + session = await create_session(headers=[("h1", "header11"), + ("h2", "header21"), + ("h1", "header12")]) assert (session._default_headers == CIMultiDict([("H1", "header11"), ("H2", "header21"), ("H1", "header12")])) -def test_init_cookies_with_simple_dict(create_session): - session = create_session(cookies={"c1": "cookie1", - "c2": "cookie2"}) +async def test_init_cookies_with_simple_dict(create_session) -> None: + session = await create_session(cookies={"c1": "cookie1", + "c2": "cookie2"}) cookies = session.cookie_jar.filter_cookies() assert set(cookies) == {'c1', 'c2'} assert cookies['c1'].value == 'cookie1' assert cookies['c2'].value == 'cookie2' -def test_init_cookies_with_list_of_tuples(create_session): - session = create_session(cookies=[("c1", "cookie1"), - ("c2", "cookie2")]) +async def test_init_cookies_with_list_of_tuples(create_session) -> None: + session = await create_session(cookies=[("c1", "cookie1"), + ("c2", "cookie2")]) cookies = session.cookie_jar.filter_cookies() assert set(cookies) == {'c1', 'c2'} @@ -120,35 +123,36 @@ def test_init_cookies_with_list_of_tuples(create_session): assert cookies['c2'].value == 'cookie2' -def test_merge_headers(create_session): +async def test_merge_headers(create_session) -> None: # Check incoming simple dict - session = create_session(headers={"h1": "header1", - "h2": "header2"}) + session = await create_session(headers={"h1": "header1", + "h2": "header2"}) headers = session._prepare_headers({"h1": "h1"}) assert isinstance(headers, CIMultiDict) assert headers == {"h1": "h1", "h2": "header2"} -def test_merge_headers_with_multi_dict(create_session): - session = create_session(headers={"h1": "header1", - "h2": "header2"}) +async def test_merge_headers_with_multi_dict(create_session) -> None: + session = await create_session(headers={"h1": "header1", + "h2": "header2"}) headers = session._prepare_headers(MultiDict([("h1", "h1")])) assert isinstance(headers, CIMultiDict) assert headers == {"h1": "h1", "h2": "header2"} -def test_merge_headers_with_list_of_tuples(create_session): - session = create_session(headers={"h1": "header1", - "h2": "header2"}) +async def test_merge_headers_with_list_of_tuples(create_session) -> None: + session = await create_session(headers={"h1": "header1", + "h2": "header2"}) headers = session._prepare_headers([("h1", "h1")]) assert isinstance(headers, CIMultiDict) assert headers == {"h1": "h1", "h2": "header2"} -def test_merge_headers_with_list_of_tuples_duplicated_names(create_session): - session = create_session(headers={"h1": "header1", - "h2": "header2"}) +async def test_merge_headers_with_list_of_tuples_duplicated_names( + create_session) -> None: + session = await create_session(headers={"h1": "header1", + "h2": "header2"}) headers = session._prepare_headers([("h1", "v1"), ("h1", "v2")]) @@ -159,7 +163,7 @@ def test_merge_headers_with_list_of_tuples_duplicated_names(create_session): ("h2", "header2")] -def test_http_GET(session, params): +def test_http_GET(session, params) -> None: with mock.patch("aiohttp.client.ClientSession._request") as patched: session.get("http://test.example.com", params={"x": 1}, @@ -172,7 +176,7 @@ def test_http_GET(session, params): **params)] -def test_http_OPTIONS(session, params): +def test_http_OPTIONS(session, params) -> None: with mock.patch("aiohttp.client.ClientSession._request") as patched: session.options("http://opt.example.com", params={"x": 2}, @@ -185,7 +189,7 @@ def test_http_OPTIONS(session, params): **params)] -def test_http_HEAD(session, params): +def test_http_HEAD(session, params) -> None: with mock.patch("aiohttp.client.ClientSession._request") as patched: session.head("http://head.example.com", params={"x": 2}, @@ -198,7 +202,7 @@ def test_http_HEAD(session, params): **params)] -def test_http_POST(session, params): +def test_http_POST(session, params) -> None: with mock.patch("aiohttp.client.ClientSession._request") as patched: session.post("http://post.example.com", params={"x": 2}, @@ -212,7 +216,7 @@ def test_http_POST(session, params): **params)] -def test_http_PUT(session, params): +def test_http_PUT(session, params) -> None: with mock.patch("aiohttp.client.ClientSession._request") as patched: session.put("http://put.example.com", params={"x": 2}, @@ -226,7 +230,7 @@ def test_http_PUT(session, params): **params)] -def test_http_PATCH(session, params): +def test_http_PATCH(session, params) -> None: with mock.patch("aiohttp.client.ClientSession._request") as patched: session.patch("http://patch.example.com", params={"x": 2}, @@ -240,7 +244,7 @@ def test_http_PATCH(session, params): **params)] -def test_http_DELETE(session, params): +def test_http_DELETE(session, params) -> None: with mock.patch("aiohttp.client.ClientSession._request") as patched: session.delete("http://delete.example.com", params={"x": 2}, @@ -253,24 +257,24 @@ def test_http_DELETE(session, params): **params)] -async def test_close(create_session, connector): - session = create_session(connector=connector) +async def test_close(create_session, connector) -> None: + session = await create_session(connector=connector) await session.close() assert session.connector is None assert connector.closed -async def test_closed(session): +async def test_closed(session) -> None: assert not session.closed await session.close() assert session.closed -async def test_connector(create_session, loop, mocker): +async def test_connector(create_session, loop, mocker) -> None: connector = TCPConnector(loop=loop) mocker.spy(connector, 'close') - session = create_session(connector=connector) + session = await create_session(connector=connector) assert session.connector is connector await session.close() @@ -278,8 +282,8 @@ async def test_connector(create_session, loop, mocker): connector.close() -async def test_create_connector(create_session, loop, mocker): - session = create_session() +async def test_create_connector(create_session, loop, mocker) -> None: + session = await create_session() connector = session.connector mocker.spy(session.connector, 'close') @@ -287,19 +291,25 @@ async def test_create_connector(create_session, loop, mocker): assert connector.close.called -def test_connector_loop(loop): +def test_connector_loop(loop) -> None: with contextlib.ExitStack() as stack: another_loop = asyncio.new_event_loop() stack.enter_context(contextlib.closing(another_loop)) - connector = TCPConnector(loop=another_loop) + + async def make_connector(): + return TCPConnector() + connector = another_loop.run_until_complete(make_connector()) + stack.enter_context(contextlib.closing(connector)) with pytest.raises(RuntimeError) as ctx: - ClientSession(connector=connector, loop=loop) + async def make_sess(): + return ClientSession(connector=connector, loop=loop) + loop.run_until_complete(make_sess()) assert re.match("Session and connector has to use same event loop", str(ctx.value)) -def test_detach(session): +def test_detach(session) -> None: conn = session.connector try: assert not conn.closed @@ -311,21 +321,21 @@ def test_detach(session): conn.close() -async def test_request_closed_session(session): +async def test_request_closed_session(session) -> None: await session.close() with pytest.raises(RuntimeError): await session.request('get', '/') -def test_close_flag_for_closed_connector(session): +def test_close_flag_for_closed_connector(session) -> None: conn = session.connector assert not session.closed conn.close() assert session.closed -async def test_double_close(connector, create_session): - session = create_session(connector=connector) +async def test_double_close(connector, create_session) -> None: + session = await create_session(connector=connector) await session.close() assert session.connector is None @@ -334,17 +344,42 @@ async def test_double_close(connector, create_session): assert connector.closed -def test_del(connector, loop): +async def test_del(connector, loop) -> None: + loop.set_debug(False) + # N.B. don't use session fixture, it stores extra reference internally + session = ClientSession(connector=connector, loop=loop) + logs = [] + loop.set_exception_handler(lambda loop, ctx: logs.append(ctx)) + + with pytest.warns(ResourceWarning): + del session + gc.collect() + + assert len(logs) == 1 + expected = {'client_session': mock.ANY, + 'message': 'Unclosed client session'} + assert logs[0] == expected + + +async def test_del_debug(connector, loop) -> None: + loop.set_debug(True) # N.B. don't use session fixture, it stores extra reference internally session = ClientSession(connector=connector, loop=loop) - loop.set_exception_handler(lambda loop, ctx: None) + logs = [] + loop.set_exception_handler(lambda loop, ctx: logs.append(ctx)) with pytest.warns(ResourceWarning): del session gc.collect() + assert len(logs) == 1 + expected = {'client_session': mock.ANY, + 'message': 'Unclosed client session', + 'source_traceback': mock.ANY} + assert logs[0] == expected + -def test_context_manager(connector, loop): +async def test_context_manager(connector, loop) -> None: with pytest.raises(TypeError): with ClientSession(loop=loop, connector=connector) as session: pass @@ -352,7 +387,7 @@ def test_context_manager(connector, loop): assert session.closed -async def test_borrow_connector_loop(connector, create_session, loop): +async def test_borrow_connector_loop(connector, create_session, loop) -> None: session = ClientSession(connector=connector, loop=None) try: assert session._loop, loop @@ -360,12 +395,12 @@ async def test_borrow_connector_loop(connector, create_session, loop): await session.close() -async def test_reraise_os_error(create_session): +async def test_reraise_os_error(create_session) -> None: err = OSError(1, "permission error") req = mock.Mock() req_factory = mock.Mock(return_value=req) req.send = mock.Mock(side_effect=err) - session = create_session(request_class=req_factory) + session = await create_session(request_class=req_factory) async def create_connection(req, traces, timeout): # return self.transport, self.protocol @@ -380,7 +415,7 @@ async def test_reraise_os_error(create_session): assert e.strerror == err.strerror -async def test_close_conn_on_error(create_session): +async def test_close_conn_on_error(create_session) -> None: class UnexpectedException(BaseException): pass @@ -388,7 +423,7 @@ async def test_close_conn_on_error(create_session): req = mock.Mock() req_factory = mock.Mock(return_value=req) req.send = mock.Mock(side_effect=err) - session = create_session(request_class=req_factory) + session = await create_session(request_class=req_factory) connections = [] original_connect = session._connector.connect @@ -417,7 +452,7 @@ async def test_close_conn_on_error(create_session): c.__del__() -async def test_cookie_jar_usage(loop, aiohttp_client): +async def test_cookie_jar_usage(loop, aiohttp_client) -> None: req_url = None jar = mock.Mock() @@ -458,18 +493,19 @@ async def test_cookie_jar_usage(loop, aiohttp_client): assert resp_cookies["response"].value == "resp_value" -def test_session_default_version(loop): +async def test_session_default_version(loop) -> None: session = aiohttp.ClientSession(loop=loop) assert session.version == aiohttp.HttpVersion11 -async def test_session_loop(loop): +async def test_session_loop(loop) -> None: session = aiohttp.ClientSession(loop=loop) - assert session.loop is loop + with pytest.warns(DeprecationWarning): + assert session.loop is loop await session.close() -def test_proxy_str(session, params): +def test_proxy_str(session, params) -> None: with mock.patch("aiohttp.client.ClientSession._request") as patched: session.get("http://test.example.com", proxy='http://proxy.com', @@ -482,20 +518,7 @@ def test_proxy_str(session, params): **params)] -def test_client_session_implicit_loop_warn(): - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - - with pytest.warns(UserWarning): - session = aiohttp.ClientSession() - assert session._loop is loop - loop.run_until_complete(session.close()) - - asyncio.set_event_loop(None) - loop.close() - - -async def test_request_tracing(loop, aiohttp_client): +async def test_request_tracing(loop, aiohttp_client) -> None: async def handler(request): return web.json_response({'ok': True}) @@ -559,7 +582,7 @@ async def test_request_tracing(loop, aiohttp_client): {'ok': True}).encode('utf8') -async def test_request_tracing_exception(loop): +async def test_request_tracing_exception(loop) -> None: on_request_end = mock.Mock(side_effect=asyncio.coroutine(mock.Mock())) on_request_exception = mock.Mock( side_effect=asyncio.coroutine(mock.Mock()) @@ -598,7 +621,7 @@ async def test_request_tracing_exception(loop): assert not on_request_end.called -async def test_request_tracing_interpose_headers(loop, aiohttp_client): +async def test_request_tracing_interpose_headers(loop, aiohttp_client) -> None: async def handler(request): return web.Response() @@ -634,7 +657,7 @@ async def test_request_tracing_interpose_headers(loop, aiohttp_client): @pytest.mark.skipif(not PY_36, reason="Python 3.6+ required") -def test_client_session_inheritance(): +def test_client_session_inheritance() -> None: with pytest.warns(DeprecationWarning): class A(ClientSession): pass @@ -642,17 +665,20 @@ def test_client_session_inheritance(): @pytest.mark.skipif(not DEBUG, reason="The check is applied in DEBUG mode only") -def test_client_session_custom_attr(loop): +async def test_client_session_custom_attr(loop) -> None: session = ClientSession(loop=loop) with pytest.warns(DeprecationWarning): session.custom = None -def test_client_session_timeout_args(loop): +async def test_client_session_timeout_args(loop) -> None: session1 = ClientSession(loop=loop) assert session1._timeout == client.DEFAULT_TIMEOUT - session2 = ClientSession(loop=loop, read_timeout=20*60, conn_timeout=30*60) + with pytest.warns(DeprecationWarning): + session2 = ClientSession(loop=loop, + read_timeout=20*60, + conn_timeout=30*60) assert session2._timeout == client.ClientTimeout(total=20*60, connect=30*60) @@ -665,3 +691,21 @@ def test_client_session_timeout_args(loop): ClientSession(loop=loop, timeout=client.ClientTimeout(total=10 * 60), conn_timeout=30 * 60) + + +async def test_requote_redirect_url_default() -> None: + session = ClientSession() + assert session.requote_redirect_url + + +async def test_requote_redirect_url_default_disable() -> None: + session = ClientSession(requote_redirect_url=False) + assert not session.requote_redirect_url + + +async def test_requote_redirect_setter() -> None: + session = ClientSession() + assert session.requote_redirect_url + with pytest.warns(DeprecationWarning): + session.requote_redirect_url = False + assert not session.requote_redirect_url diff --git a/tests/test_client_ws.py b/tests/test_client_ws.py index d2efc69..5643003 100644 --- a/tests/test_client_ws.py +++ b/tests/test_client_ws.py @@ -29,7 +29,7 @@ def ws_key(key): return base64.b64encode(hashlib.sha1(key + WS_KEY).digest()).decode() -async def test_ws_connect(ws_key, loop, key_data): +async def test_ws_connect(ws_key, loop, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -39,7 +39,7 @@ async def test_ws_connect(ws_key, loop, key_data): hdrs.SEC_WEBSOCKET_PROTOCOL: 'chat' } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -53,11 +53,11 @@ async def test_ws_connect(ws_key, loop, key_data): assert hdrs.ORIGIN not in m_req.call_args[1]["headers"] -async def test_ws_connect_with_origin(key_data, loop): +async def test_ws_connect_with_origin(key_data, loop) -> None: resp = mock.Mock() resp.status = 403 with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -71,7 +71,7 @@ async def test_ws_connect_with_origin(key_data, loop): assert m_req.call_args[1]["headers"][hdrs.ORIGIN] == origin -async def test_ws_connect_custom_response(loop, ws_key, key_data): +async def test_ws_connect_custom_response(loop, ws_key, key_data) -> None: class CustomResponse(client.ClientWebSocketResponse): def read(self, decode=False): @@ -85,7 +85,7 @@ async def test_ws_connect_custom_response(loop, ws_key, key_data): hdrs.SEC_WEBSOCKET_ACCEPT: ws_key, } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -97,7 +97,7 @@ async def test_ws_connect_custom_response(loop, ws_key, key_data): assert res.read() == 'customized!' -async def test_ws_connect_err_status(loop, ws_key, key_data): +async def test_ws_connect_err_status(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 500 resp.headers = { @@ -106,7 +106,7 @@ async def test_ws_connect_err_status(loop, ws_key, key_data): hdrs.SEC_WEBSOCKET_ACCEPT: ws_key } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -119,7 +119,7 @@ async def test_ws_connect_err_status(loop, ws_key, key_data): assert ctx.value.message == 'Invalid response status' -async def test_ws_connect_err_upgrade(loop, ws_key, key_data): +async def test_ws_connect_err_upgrade(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -128,7 +128,7 @@ async def test_ws_connect_err_upgrade(loop, ws_key, key_data): hdrs.SEC_WEBSOCKET_ACCEPT: ws_key } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -141,7 +141,7 @@ async def test_ws_connect_err_upgrade(loop, ws_key, key_data): assert ctx.value.message == 'Invalid upgrade header' -async def test_ws_connect_err_conn(loop, ws_key, key_data): +async def test_ws_connect_err_conn(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -150,7 +150,7 @@ async def test_ws_connect_err_conn(loop, ws_key, key_data): hdrs.SEC_WEBSOCKET_ACCEPT: ws_key } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -163,7 +163,7 @@ async def test_ws_connect_err_conn(loop, ws_key, key_data): assert ctx.value.message == 'Invalid connection header' -async def test_ws_connect_err_challenge(loop, ws_key, key_data): +async def test_ws_connect_err_challenge(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -172,7 +172,7 @@ async def test_ws_connect_err_challenge(loop, ws_key, key_data): hdrs.SEC_WEBSOCKET_ACCEPT: 'asdfasdfasdfasdfasdfasdf' } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -185,7 +185,7 @@ async def test_ws_connect_err_challenge(loop, ws_key, key_data): assert ctx.value.message == 'Invalid challenge response' -async def test_ws_connect_common_headers(ws_key, loop, key_data): +async def test_ws_connect_common_headers(ws_key, loop, key_data) -> None: """Emulate a headers dict being reused for a second ws_connect. In this scenario, we need to ensure that the newly generated secret key @@ -193,7 +193,7 @@ async def test_ws_connect_common_headers(ws_key, loop, key_data): """ headers = {} - async def test_connection(): + async def test_connection() -> None: async def mock_get(*args, **kwargs): resp = mock.Mock() @@ -210,7 +210,7 @@ async def test_ws_connect_common_headers(ws_key, loop, key_data): } return resp with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get', + with mock.patch('aiohttp.client.ClientSession.request', side_effect=mock_get) as m_req: m_os.urandom.return_value = key_data @@ -229,7 +229,7 @@ async def test_ws_connect_common_headers(ws_key, loop, key_data): await test_connection() -async def test_close(loop, ws_key, key_data): +async def test_close(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -239,7 +239,7 @@ async def test_close(loop, ws_key, key_data): } with mock.patch('aiohttp.client.WebSocketWriter') as WebSocketWriter: with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -269,7 +269,7 @@ async def test_close(loop, ws_key, key_data): await session.close() -async def test_close_eofstream(loop, ws_key, key_data): +async def test_close_eofstream(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -279,7 +279,7 @@ async def test_close_eofstream(loop, ws_key, key_data): } with mock.patch('aiohttp.client.WebSocketWriter') as WebSocketWriter: with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -299,7 +299,7 @@ async def test_close_eofstream(loop, ws_key, key_data): await session.close() -async def test_close_exc(loop, ws_key, key_data): +async def test_close_exc(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -309,7 +309,7 @@ async def test_close_exc(loop, ws_key, key_data): } with mock.patch('aiohttp.client.WebSocketWriter') as WebSocketWriter: with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -331,7 +331,7 @@ async def test_close_exc(loop, ws_key, key_data): await session.close() -async def test_close_exc2(loop, ws_key, key_data): +async def test_close_exc2(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -341,7 +341,7 @@ async def test_close_exc2(loop, ws_key, key_data): } with mock.patch('aiohttp.client.WebSocketWriter') as WebSocketWriter: with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -364,7 +364,7 @@ async def test_close_exc2(loop, ws_key, key_data): await resp.close() -async def test_send_data_after_close(ws_key, key_data, loop, mocker): +async def test_send_data_after_close(ws_key, key_data, loop, mocker) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -373,7 +373,7 @@ async def test_send_data_after_close(ws_key, key_data, loop, mocker): hdrs.SEC_WEBSOCKET_ACCEPT: ws_key, } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -394,7 +394,7 @@ async def test_send_data_after_close(ws_key, key_data, loop, mocker): ws_logger.warning.reset_mock() -async def test_send_data_type_errors(ws_key, key_data, loop): +async def test_send_data_type_errors(ws_key, key_data, loop) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -404,7 +404,7 @@ async def test_send_data_type_errors(ws_key, key_data, loop): } with mock.patch('aiohttp.client.WebSocketWriter') as WebSocketWriter: with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -421,7 +421,7 @@ async def test_send_data_type_errors(ws_key, key_data, loop): await resp.send_json(set()) -async def test_reader_read_exception(ws_key, key_data, loop): +async def test_reader_read_exception(ws_key, key_data, loop) -> None: hresp = mock.Mock() hresp.status = 101 hresp.headers = { @@ -431,7 +431,7 @@ async def test_reader_read_exception(ws_key, key_data, loop): } with mock.patch('aiohttp.client.WebSocketWriter') as WebSocketWriter: with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(hresp) @@ -453,7 +453,7 @@ async def test_reader_read_exception(ws_key, key_data, loop): await session.close() -async def test_receive_runtime_err(loop): +async def test_receive_runtime_err(loop) -> None: resp = client.ClientWebSocketResponse( mock.Mock(), mock.Mock(), mock.Mock(), mock.Mock(), 10.0, True, True, loop) @@ -463,7 +463,7 @@ async def test_receive_runtime_err(loop): await resp.receive() -async def test_ws_connect_close_resp_on_err(loop, ws_key, key_data): +async def test_ws_connect_close_resp_on_err(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 500 resp.headers = { @@ -472,7 +472,7 @@ async def test_ws_connect_close_resp_on_err(loop, ws_key, key_data): hdrs.SEC_WEBSOCKET_ACCEPT: ws_key } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -484,7 +484,8 @@ async def test_ws_connect_close_resp_on_err(loop, ws_key, key_data): resp.close.assert_called_with() -async def test_ws_connect_non_overlapped_protocols(ws_key, loop, key_data): +async def test_ws_connect_non_overlapped_protocols(ws_key, + loop, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -494,7 +495,7 @@ async def test_ws_connect_non_overlapped_protocols(ws_key, loop, key_data): hdrs.SEC_WEBSOCKET_PROTOCOL: 'other,another' } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -506,7 +507,8 @@ async def test_ws_connect_non_overlapped_protocols(ws_key, loop, key_data): assert res.protocol is None -async def test_ws_connect_non_overlapped_protocols_2(ws_key, loop, key_data): +async def test_ws_connect_non_overlapped_protocols_2(ws_key, + loop, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -516,7 +518,7 @@ async def test_ws_connect_non_overlapped_protocols_2(ws_key, loop, key_data): hdrs.SEC_WEBSOCKET_PROTOCOL: 'other,another' } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -531,7 +533,7 @@ async def test_ws_connect_non_overlapped_protocols_2(ws_key, loop, key_data): del res -async def test_ws_connect_deflate(loop, ws_key, key_data): +async def test_ws_connect_deflate(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -541,7 +543,7 @@ async def test_ws_connect_deflate(loop, ws_key, key_data): hdrs.SEC_WEBSOCKET_EXTENSIONS: 'permessage-deflate', } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -553,7 +555,7 @@ async def test_ws_connect_deflate(loop, ws_key, key_data): assert res.client_notakeover is False -async def test_ws_connect_deflate_per_message(loop, ws_key, key_data): +async def test_ws_connect_deflate_per_message(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -564,7 +566,7 @@ async def test_ws_connect_deflate_per_message(loop, ws_key, key_data): } with mock.patch('aiohttp.client.WebSocketWriter') as WebSocketWriter: with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -586,7 +588,8 @@ async def test_ws_connect_deflate_per_message(loop, ws_key, key_data): await session.close() -async def test_ws_connect_deflate_server_not_support(loop, ws_key, key_data): +async def test_ws_connect_deflate_server_not_support(loop, + ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -595,7 +598,7 @@ async def test_ws_connect_deflate_server_not_support(loop, ws_key, key_data): hdrs.SEC_WEBSOCKET_ACCEPT: ws_key, } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -607,7 +610,7 @@ async def test_ws_connect_deflate_server_not_support(loop, ws_key, key_data): assert res.client_notakeover is False -async def test_ws_connect_deflate_notakeover(loop, ws_key, key_data): +async def test_ws_connect_deflate_notakeover(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -618,7 +621,7 @@ async def test_ws_connect_deflate_notakeover(loop, ws_key, key_data): 'client_no_context_takeover', } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -630,7 +633,7 @@ async def test_ws_connect_deflate_notakeover(loop, ws_key, key_data): assert res.client_notakeover is True -async def test_ws_connect_deflate_client_wbits(loop, ws_key, key_data): +async def test_ws_connect_deflate_client_wbits(loop, ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -641,7 +644,7 @@ async def test_ws_connect_deflate_client_wbits(loop, ws_key, key_data): 'client_max_window_bits=10', } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -653,7 +656,8 @@ async def test_ws_connect_deflate_client_wbits(loop, ws_key, key_data): assert res.client_notakeover is False -async def test_ws_connect_deflate_client_wbits_bad(loop, ws_key, key_data): +async def test_ws_connect_deflate_client_wbits_bad(loop, + ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -664,7 +668,7 @@ async def test_ws_connect_deflate_client_wbits_bad(loop, ws_key, key_data): 'client_max_window_bits=6', } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) @@ -674,7 +678,8 @@ async def test_ws_connect_deflate_client_wbits_bad(loop, ws_key, key_data): 'http://test.org', compress=15) -async def test_ws_connect_deflate_server_ext_bad(loop, ws_key, key_data): +async def test_ws_connect_deflate_server_ext_bad(loop, + ws_key, key_data) -> None: resp = mock.Mock() resp.status = 101 resp.headers = { @@ -684,7 +689,7 @@ async def test_ws_connect_deflate_server_ext_bad(loop, ws_key, key_data): hdrs.SEC_WEBSOCKET_EXTENSIONS: 'permessage-deflate; bad', } with mock.patch('aiohttp.client.os') as m_os: - with mock.patch('aiohttp.client.ClientSession.get') as m_req: + with mock.patch('aiohttp.client.ClientSession.request') as m_req: m_os.urandom.return_value = key_data m_req.return_value = loop.create_future() m_req.return_value.set_result(resp) diff --git a/tests/test_client_ws_functional.py b/tests/test_client_ws_functional.py index aee2af2..6335abe 100644 --- a/tests/test_client_ws_functional.py +++ b/tests/test_client_ws_functional.py @@ -15,7 +15,7 @@ def ceil(mocker): mocker.patch('aiohttp.helpers.ceil').side_effect = ceil -async def test_send_recv_text(loop, aiohttp_client): +async def test_send_recv_text(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -41,7 +41,7 @@ async def test_send_recv_text(loop, aiohttp_client): assert resp.get_extra_info('socket') is None -async def test_send_recv_bytes_bad_type(loop, aiohttp_client): +async def test_send_recv_bytes_bad_type(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -63,7 +63,7 @@ async def test_send_recv_bytes_bad_type(loop, aiohttp_client): await resp.close() -async def test_send_recv_bytes(loop, aiohttp_client): +async def test_send_recv_bytes(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -87,7 +87,7 @@ async def test_send_recv_bytes(loop, aiohttp_client): await resp.close() -async def test_send_recv_text_bad_type(loop, aiohttp_client): +async def test_send_recv_text_bad_type(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -111,7 +111,7 @@ async def test_send_recv_text_bad_type(loop, aiohttp_client): await resp.close() -async def test_send_recv_json(loop, aiohttp_client): +async def test_send_recv_json(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -134,8 +134,8 @@ async def test_send_recv_json(loop, aiohttp_client): await resp.close() -async def test_ping_pong(loop, aiohttp_client): - +async def test_ping_pong(aiohttp_client) -> None: + loop = asyncio.get_event_loop() closed = loop.create_future() async def handler(request): @@ -170,8 +170,8 @@ async def test_ping_pong(loop, aiohttp_client): await closed -async def test_ping_pong_manual(loop, aiohttp_client): - +async def test_ping_pong_manual(aiohttp_client) -> None: + loop = asyncio.get_event_loop() closed = loop.create_future() async def handler(request): @@ -211,7 +211,7 @@ async def test_ping_pong_manual(loop, aiohttp_client): await closed -async def test_close(loop, aiohttp_client): +async def test_close(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -239,7 +239,7 @@ async def test_close(loop, aiohttp_client): assert msg.type == aiohttp.WSMsgType.CLOSED -async def test_concurrent_close(loop, aiohttp_client): +async def test_concurrent_close(aiohttp_client) -> None: client_ws = None async def handler(request): @@ -266,13 +266,13 @@ async def test_concurrent_close(loop, aiohttp_client): msg = await ws.receive() assert msg.type == aiohttp.WSMsgType.CLOSING - await asyncio.sleep(0.01, loop=loop) + await asyncio.sleep(0.01) msg = await ws.receive() assert msg.type == aiohttp.WSMsgType.CLOSED -async def test_close_from_server(loop, aiohttp_client): - +async def test_close_from_server(aiohttp_client) -> None: + loop = asyncio.get_event_loop() closed = loop.create_future() async def handler(request): @@ -303,8 +303,8 @@ async def test_close_from_server(loop, aiohttp_client): await closed -async def test_close_manual(loop, aiohttp_client): - +async def test_close_manual(aiohttp_client) -> None: + loop = asyncio.get_event_loop() closed = loop.create_future() async def handler(request): @@ -340,14 +340,14 @@ async def test_close_manual(loop, aiohttp_client): assert resp.closed -async def test_close_timeout(loop, aiohttp_client): +async def test_close_timeout(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() await ws.prepare(request) await ws.receive_bytes() await ws.send_str('test') - await asyncio.sleep(1, loop=loop) + await asyncio.sleep(1) return ws app = web.Application() @@ -366,14 +366,15 @@ async def test_close_timeout(loop, aiohttp_client): assert isinstance(resp.exception(), asyncio.TimeoutError) -async def test_close_cancel(loop, aiohttp_client): +async def test_close_cancel(aiohttp_client) -> None: + loop = asyncio.get_event_loop() async def handler(request): ws = web.WebSocketResponse() await ws.prepare(request) await ws.receive_bytes() await ws.send_str('test') - await asyncio.sleep(10, loop=loop) + await asyncio.sleep(10) app = web.Application() app.router.add_route('GET', '/', handler) @@ -386,14 +387,14 @@ async def test_close_cancel(loop, aiohttp_client): assert text.data == 'test' t = loop.create_task(resp.close()) - await asyncio.sleep(0.1, loop=loop) + await asyncio.sleep(0.1) t.cancel() - await asyncio.sleep(0.1, loop=loop) + await asyncio.sleep(0.1) assert resp.closed assert resp.exception() is None -async def test_override_default_headers(loop, aiohttp_client): +async def test_override_default_headers(aiohttp_client) -> None: async def handler(request): assert request.headers[hdrs.SEC_WEBSOCKET_VERSION] == '8' @@ -413,7 +414,7 @@ async def test_override_default_headers(loop, aiohttp_client): await resp.close() -async def test_additional_headers(loop, aiohttp_client): +async def test_additional_headers(aiohttp_client) -> None: async def handler(request): assert request.headers['x-hdr'] == 'xtra' @@ -433,7 +434,7 @@ async def test_additional_headers(loop, aiohttp_client): await resp.close() -async def test_recv_protocol_error(loop, aiohttp_client): +async def test_recv_protocol_error(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -458,7 +459,7 @@ async def test_recv_protocol_error(loop, aiohttp_client): await resp.close() -async def test_recv_timeout(loop, aiohttp_client): +async def test_recv_timeout(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -466,7 +467,7 @@ async def test_recv_timeout(loop, aiohttp_client): await ws.receive_str() - await asyncio.sleep(0.1, loop=request.app.loop) + await asyncio.sleep(0.1) await ws.close() return ws @@ -478,13 +479,13 @@ async def test_recv_timeout(loop, aiohttp_client): await resp.send_str('ask') with pytest.raises(asyncio.TimeoutError): - with async_timeout.timeout(0.01, loop=app.loop): + with async_timeout.timeout(0.01): await resp.receive() await resp.close() -async def test_receive_timeout(loop, aiohttp_client): +async def test_receive_timeout(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -505,7 +506,7 @@ async def test_receive_timeout(loop, aiohttp_client): await resp.close() -async def test_custom_receive_timeout(loop, aiohttp_client): +async def test_custom_receive_timeout(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -526,7 +527,7 @@ async def test_custom_receive_timeout(loop, aiohttp_client): await resp.close() -async def test_heartbeat(loop, aiohttp_client, ceil): +async def test_heartbeat(aiohttp_client, ceil) -> None: ping_received = False async def handler(request): @@ -551,7 +552,7 @@ async def test_heartbeat(loop, aiohttp_client, ceil): assert ping_received -async def test_heartbeat_no_pong(loop, aiohttp_client, ceil): +async def test_heartbeat_no_pong(aiohttp_client, ceil) -> None: ping_received = False async def handler(request): @@ -576,7 +577,7 @@ async def test_heartbeat_no_pong(loop, aiohttp_client, ceil): assert ping_received -async def test_send_recv_compress(loop, aiohttp_client): +async def test_send_recv_compress(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -602,7 +603,7 @@ async def test_send_recv_compress(loop, aiohttp_client): assert resp.get_extra_info('socket') is None -async def test_send_recv_compress_wbits(loop, aiohttp_client): +async def test_send_recv_compress_wbits(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -630,7 +631,7 @@ async def test_send_recv_compress_wbits(loop, aiohttp_client): assert resp.get_extra_info('socket') is None -async def test_send_recv_compress_wbit_error(loop, aiohttp_client): +async def test_send_recv_compress_wbit_error(aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -648,7 +649,7 @@ async def test_send_recv_compress_wbit_error(loop, aiohttp_client): await client.ws_connect('/', compress=1) -async def test_ws_client_async_for(loop, aiohttp_client): +async def test_ws_client_async_for(aiohttp_client) -> None: items = ['q1', 'q2', 'q3'] async def handler(request): @@ -674,7 +675,7 @@ async def test_ws_client_async_for(loop, aiohttp_client): assert resp.closed -async def test_ws_async_with(loop, aiohttp_server): +async def test_ws_async_with(aiohttp_server) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -689,7 +690,7 @@ async def test_ws_async_with(loop, aiohttp_server): server = await aiohttp_server(app) - async with aiohttp.ClientSession(loop=loop) as client: + async with aiohttp.ClientSession() as client: async with client.ws_connect(server.make_url('/')) as ws: await ws.send_str('request') msg = await ws.receive() @@ -698,7 +699,7 @@ async def test_ws_async_with(loop, aiohttp_server): assert ws.closed -async def test_ws_async_with_send(loop, aiohttp_server): +async def test_ws_async_with_send(aiohttp_server) -> None: # send_xxx methods have to return awaitable objects async def handler(request): @@ -714,7 +715,7 @@ async def test_ws_async_with_send(loop, aiohttp_server): server = await aiohttp_server(app) - async with aiohttp.ClientSession(loop=loop) as client: + async with aiohttp.ClientSession() as client: async with client.ws_connect(server.make_url('/')) as ws: await ws.send_str('request') msg = await ws.receive() @@ -723,7 +724,7 @@ async def test_ws_async_with_send(loop, aiohttp_server): assert ws.closed -async def test_ws_async_with_shortcut(loop, aiohttp_server): +async def test_ws_async_with_shortcut(aiohttp_server) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -737,7 +738,7 @@ async def test_ws_async_with_shortcut(loop, aiohttp_server): app.router.add_route('GET', '/', handler) server = await aiohttp_server(app) - async with aiohttp.ClientSession(loop=loop) as client: + async with aiohttp.ClientSession() as client: async with client.ws_connect(server.make_url('/')) as ws: await ws.send_str('request') msg = await ws.receive() @@ -746,8 +747,8 @@ async def test_ws_async_with_shortcut(loop, aiohttp_server): assert ws.closed -async def test_closed_async_for(loop, aiohttp_client): - +async def test_closed_async_for(aiohttp_client) -> None: + loop = asyncio.get_event_loop() closed = loop.create_future() async def handler(request): @@ -779,3 +780,52 @@ async def test_closed_async_for(loop, aiohttp_client): assert resp.closed await closed + + +async def test_peer_connection_lost(aiohttp_client) -> None: + + async def handler(request): + ws = web.WebSocketResponse() + await ws.prepare(request) + + msg = await ws.receive_str() + assert msg == 'ask' + await ws.send_str('answer') + request.transport.close() + await asyncio.sleep(10) + return ws + + app = web.Application() + app.router.add_route('GET', '/', handler) + client = await aiohttp_client(app) + resp = await client.ws_connect('/') + await resp.send_str('ask') + assert 'answer' == await resp.receive_str() + + msg = await resp.receive() + assert msg.type == aiohttp.WSMsgType.CLOSED + await resp.close() + + +async def test_peer_connection_lost_iter(aiohttp_client) -> None: + + async def handler(request): + ws = web.WebSocketResponse() + await ws.prepare(request) + + msg = await ws.receive_str() + assert msg == 'ask' + await ws.send_str('answer') + request.transport.close() + await asyncio.sleep(100) + return ws + + app = web.Application() + app.router.add_route('GET', '/', handler) + client = await aiohttp_client(app) + resp = await client.ws_connect('/') + await resp.send_str('ask') + async for msg in resp: + assert 'answer' == msg.data + + await resp.close() diff --git a/tests/test_connector.py b/tests/test_connector.py index 5093d67..88db979 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -7,6 +7,7 @@ import os.path import platform import socket import ssl +import sys import uuid from collections import deque from unittest import mock @@ -65,7 +66,7 @@ def unix_server(loop, unix_sockname): loop.run_until_complete(runner.cleanup()) -def test_connection_del(loop): +def test_connection_del(loop) -> None: connector = mock.Mock() key = mock.Mock() protocol = mock.Mock() @@ -90,7 +91,7 @@ def test_connection_del(loop): exc_handler.assert_called_with(loop, msg) -def test_connection_del_loop_debug(loop): +def test_connection_del_loop_debug(loop) -> None: connector = mock.Mock() key = mock.Mock() protocol = mock.Mock() @@ -111,7 +112,7 @@ def test_connection_del_loop_debug(loop): exc_handler.assert_called_with(loop, msg) -def test_connection_del_loop_closed(loop): +def test_connection_del_loop_closed(loop) -> None: connector = mock.Mock() key = mock.Mock() protocol = mock.Mock() @@ -129,19 +130,8 @@ def test_connection_del_loop_closed(loop): assert not exc_handler.called -def test_connection_detach(loop): - connector = mock.Mock() - key = mock.Mock() - protocol = mock.Mock() - conn = Connection(connector, key, protocol, loop=loop) - conn._notify_release = mock.Mock() - conn.detach() - assert conn._notify_release.called - connector._release_acquired.assert_called_with(protocol) - - -def test_del(loop): - conn = aiohttp.BaseConnector(loop=loop) +async def test_del(loop) -> None: + conn = aiohttp.BaseConnector() proto = mock.Mock(should_close=False) conn._release('a', proto) conns_impl = conn._conns @@ -164,7 +154,7 @@ def test_del(loop): @pytest.mark.xfail -async def test_del_with_scheduled_cleanup(loop): +async def test_del_with_scheduled_cleanup(loop) -> None: loop.set_debug(True) conn = aiohttp.BaseConnector(loop=loop, keepalive_timeout=0.01) transp = mock.Mock() @@ -190,8 +180,12 @@ async def test_del_with_scheduled_cleanup(loop): exc_handler.assert_called_with(loop, msg) -def test_del_with_closed_loop(loop): - conn = aiohttp.BaseConnector(loop=loop) +@pytest.mark.skipif(sys.implementation.name != 'cpython', + reason="CPython GC is required for the test") +def test_del_with_closed_loop(loop) -> None: + async def make_conn(): + return aiohttp.BaseConnector() + conn = loop.run_until_complete(make_conn()) transp = mock.Mock() conn._conns['a'] = [(transp, 123)] @@ -209,7 +203,7 @@ def test_del_with_closed_loop(loop): assert exc_handler.called -def test_del_empty_conector(loop): +async def test_del_empty_connector(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) exc_handler = mock.Mock() @@ -220,30 +214,32 @@ def test_del_empty_conector(loop): assert not exc_handler.called -async def test_create_conn(loop): +async def test_create_conn(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) with pytest.raises(NotImplementedError): await conn._create_connection(object(), [], object()) -def test_context_manager(loop): +async def test_context_manager(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) - conn.close = mock.Mock() - with conn as c: - assert conn is c + with pytest.warns(DeprecationWarning): + with conn as c: + assert conn is c - assert conn.close.called + assert conn.closed -def test_ctor_loop(): - with mock.patch('aiohttp.connector.asyncio') as m_asyncio: - session = aiohttp.BaseConnector() +async def test_async_context_manager(loop) -> None: + conn = aiohttp.BaseConnector(loop=loop) - assert session._loop is m_asyncio.get_event_loop.return_value + async with conn as c: + assert conn is c + assert conn.closed -def test_close(loop): + +async def test_close(loop) -> None: proto = mock.Mock() conn = aiohttp.BaseConnector(loop=loop) @@ -256,7 +252,7 @@ def test_close(loop): assert conn.closed -def test_get(loop): +async def test_get(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) assert conn._get(1) is None @@ -266,7 +262,7 @@ def test_get(loop): conn.close() -def test_get_expired(loop): +async def test_get_expired(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) key = ConnectionKey('localhost', 80, False, None, None, None, None) assert conn._get(key) is None @@ -278,20 +274,21 @@ def test_get_expired(loop): conn.close() -def test_get_expired_ssl(loop): +async def test_get_expired_ssl(loop) -> None: conn = aiohttp.BaseConnector(loop=loop, enable_cleanup_closed=True) key = ConnectionKey('localhost', 80, True, None, None, None, None) assert conn._get(key) is None proto = mock.Mock() + transport = proto.transport conn._conns[key] = [(proto, loop.time() - 1000)] assert conn._get(key) is None assert not conn._conns - assert conn._cleanup_closed_transports == [proto.close.return_value] + assert conn._cleanup_closed_transports == [transport] conn.close() -def test_release_acquired(loop, key): +async def test_release_acquired(loop, key) -> None: proto = mock.Mock() conn = aiohttp.BaseConnector(loop=loop, limit=5) conn._release_waiter = mock.Mock() @@ -310,7 +307,7 @@ def test_release_acquired(loop, key): conn.close() -def test_release_acquired_closed(loop, key): +async def test_release_acquired_closed(loop, key) -> None: proto = mock.Mock() conn = aiohttp.BaseConnector(loop=loop, limit=5) conn._release_waiter = mock.Mock() @@ -325,7 +322,7 @@ def test_release_acquired_closed(loop, key): conn.close() -def test_release(loop, key): +async def test_release(loop, key) -> None: conn = aiohttp.BaseConnector(loop=loop) conn._release_waiter = mock.Mock() @@ -342,20 +339,21 @@ def test_release(loop, key): conn.close() -def test_release_ssl_transport(loop, ssl_key): +async def test_release_ssl_transport(loop, ssl_key) -> None: conn = aiohttp.BaseConnector(loop=loop, enable_cleanup_closed=True) conn._release_waiter = mock.Mock() proto = mock.Mock() + transport = proto.transport conn._acquired.add(proto) conn._acquired_per_host[ssl_key].add(proto) conn._release(ssl_key, proto, should_close=True) - assert conn._cleanup_closed_transports == [proto.close.return_value] + assert conn._cleanup_closed_transports == [transport] conn.close() -def test_release_already_closed(loop): +async def test_release_already_closed(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) proto = mock.Mock() @@ -371,7 +369,7 @@ def test_release_already_closed(loop): assert not conn._release_acquired.called -def test_release_waiter_no_limit(loop, key, key2): +async def test_release_waiter_no_limit(loop, key, key2) -> None: # limit is 0 conn = aiohttp.BaseConnector(limit=0, loop=loop) w = mock.Mock() @@ -383,7 +381,7 @@ def test_release_waiter_no_limit(loop, key, key2): conn.close() -def test_release_waiter_first_available(loop, key, key2): +async def test_release_waiter_first_available(loop, key, key2) -> None: conn = aiohttp.BaseConnector(loop=loop) w1, w2 = mock.Mock(), mock.Mock() w1.done.return_value = False @@ -396,7 +394,7 @@ def test_release_waiter_first_available(loop, key, key2): conn.close() -def test_release_waiter_release_first(loop, key, key2): +async def test_release_waiter_release_first(loop, key, key2) -> None: conn = aiohttp.BaseConnector(loop=loop, limit=1) w1, w2 = mock.Mock(), mock.Mock() w1.done.return_value = False @@ -408,7 +406,7 @@ def test_release_waiter_release_first(loop, key, key2): conn.close() -def test_release_waiter_skip_done_waiter(loop, key, key2): +async def test_release_waiter_skip_done_waiter(loop, key, key2) -> None: conn = aiohttp.BaseConnector(loop=loop, limit=1) w1, w2 = mock.Mock(), mock.Mock() w1.done.return_value = True @@ -420,7 +418,7 @@ def test_release_waiter_skip_done_waiter(loop, key, key2): conn.close() -def test_release_waiter_per_host(loop, key, key2): +async def test_release_waiter_per_host(loop, key, key2) -> None: # no limit conn = aiohttp.BaseConnector(loop=loop, limit=0, limit_per_host=2) w1, w2 = mock.Mock(), mock.Mock() @@ -434,7 +432,7 @@ def test_release_waiter_per_host(loop, key, key2): conn.close() -def test_release_waiter_no_available(loop, key, key2): +async def test_release_waiter_no_available(loop, key, key2) -> None: # limit is 0 conn = aiohttp.BaseConnector(limit=0, loop=loop) w = mock.Mock() @@ -447,7 +445,7 @@ def test_release_waiter_no_available(loop, key, key2): conn.close() -def test_release_close(loop, key): +async def test_release_close(loop, key) -> None: conn = aiohttp.BaseConnector(loop=loop) proto = mock.Mock(should_close=True) @@ -457,20 +455,20 @@ def test_release_close(loop, key): assert proto.close.called -def test__drop_acquire_per_host1(loop): +async def test__drop_acquire_per_host1(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) conn._drop_acquired_per_host(123, 456) assert len(conn._acquired_per_host) == 0 -def test__drop_acquire_per_host2(loop): +async def test__drop_acquire_per_host2(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) conn._acquired_per_host[123].add(456) conn._drop_acquired_per_host(123, 456) assert len(conn._acquired_per_host) == 0 -def test__drop_acquire_per_host3(loop): +async def test__drop_acquire_per_host3(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) conn._acquired_per_host[123].add(456) conn._acquired_per_host[123].add(789) @@ -479,7 +477,7 @@ def test__drop_acquire_per_host3(loop): assert conn._acquired_per_host[123] == {789} -async def test_tcp_connector_certificate_error(loop): +async def test_tcp_connector_certificate_error(loop) -> None: req = ClientRequest('GET', URL('https://127.0.0.1:443'), loop=loop) async def certificate_error(*args, **kwargs): @@ -496,7 +494,7 @@ async def test_tcp_connector_certificate_error(loop): assert isinstance(ctx.value, aiohttp.ClientSSLError) -async def test_tcp_connector_multiple_hosts_errors(loop): +async def test_tcp_connector_multiple_hosts_errors(loop) -> None: conn = aiohttp.TCPConnector(loop=loop) ip1 = '192.168.1.1' @@ -601,7 +599,7 @@ async def test_tcp_connector_multiple_hosts_errors(loop): assert connected -async def test_tcp_connector_resolve_host(loop): +async def test_tcp_connector_resolve_host(loop) -> None: conn = aiohttp.TCPConnector(loop=loop, use_dns_cache=True) res = await conn._resolve_host('localhost', 8080) @@ -629,7 +627,7 @@ def dns_response(loop): return coro -async def test_tcp_connector_dns_cache_not_expired(loop, dns_response): +async def test_tcp_connector_dns_cache_not_expired(loop, dns_response) -> None: with mock.patch('aiohttp.connector.DefaultResolver') as m_resolver: conn = aiohttp.TCPConnector( loop=loop, @@ -646,7 +644,7 @@ async def test_tcp_connector_dns_cache_not_expired(loop, dns_response): ) -async def test_tcp_connector_dns_cache_forever(loop, dns_response): +async def test_tcp_connector_dns_cache_forever(loop, dns_response) -> None: with mock.patch('aiohttp.connector.DefaultResolver') as m_resolver: conn = aiohttp.TCPConnector( loop=loop, @@ -663,7 +661,8 @@ async def test_tcp_connector_dns_cache_forever(loop, dns_response): ) -async def test_tcp_connector_use_dns_cache_disabled(loop, dns_response): +async def test_tcp_connector_use_dns_cache_disabled(loop, + dns_response) -> None: with mock.patch('aiohttp.connector.DefaultResolver') as m_resolver: conn = aiohttp.TCPConnector(loop=loop, use_dns_cache=False) m_resolver().resolve.side_effect = [dns_response(), dns_response()] @@ -675,7 +674,7 @@ async def test_tcp_connector_use_dns_cache_disabled(loop, dns_response): ]) -async def test_tcp_connector_dns_throttle_requests(loop, dns_response): +async def test_tcp_connector_dns_throttle_requests(loop, dns_response) -> None: with mock.patch('aiohttp.connector.DefaultResolver') as m_resolver: conn = aiohttp.TCPConnector( loop=loop, @@ -693,7 +692,8 @@ async def test_tcp_connector_dns_throttle_requests(loop, dns_response): ) -async def test_tcp_connector_dns_throttle_requests_exception_spread(loop): +async def test_tcp_connector_dns_throttle_requests_exception_spread( + loop) -> None: with mock.patch('aiohttp.connector.DefaultResolver') as m_resolver: conn = aiohttp.TCPConnector( loop=loop, @@ -730,7 +730,7 @@ async def test_tcp_connector_dns_throttle_requests_cancelled_when_close( await f -async def test_tcp_connector_dns_tracing(loop, dns_response): +async def test_tcp_connector_dns_tracing(loop, dns_response) -> None: session = mock.Mock() trace_config_ctx = mock.Mock() on_dns_resolvehost_start = mock.Mock( @@ -805,7 +805,8 @@ async def test_tcp_connector_dns_tracing(loop, dns_response): ) -async def test_tcp_connector_dns_tracing_cache_disabled(loop, dns_response): +async def test_tcp_connector_dns_tracing_cache_disabled(loop, + dns_response) -> None: session = mock.Mock() trace_config_ctx = mock.Mock() on_dns_resolvehost_start = mock.Mock( @@ -878,7 +879,8 @@ async def test_tcp_connector_dns_tracing_cache_disabled(loop, dns_response): ]) -async def test_tcp_connector_dns_tracing_throttle_requests(loop, dns_response): +async def test_tcp_connector_dns_tracing_throttle_requests( + loop, dns_response) -> None: session = mock.Mock() trace_config_ctx = mock.Mock() on_dns_cache_hit = mock.Mock( @@ -924,7 +926,7 @@ async def test_tcp_connector_dns_tracing_throttle_requests(loop, dns_response): ) -def test_dns_error(loop): +async def test_dns_error(loop) -> None: connector = aiohttp.TCPConnector(loop=loop) connector._resolve_host = make_mocked_coro( raise_exception=OSError('dont take it serious')) @@ -934,10 +936,10 @@ def test_dns_error(loop): loop=loop) with pytest.raises(aiohttp.ClientConnectorError): - loop.run_until_complete(connector.connect(req, [], ClientTimeout())) + await connector.connect(req, [], ClientTimeout()) -def test_get_pop_empty_conns(loop): +async def test_get_pop_empty_conns(loop) -> None: # see issue #473 conn = aiohttp.BaseConnector(loop=loop) key = ('127.0.0.1', 80, False) @@ -947,7 +949,7 @@ def test_get_pop_empty_conns(loop): assert not conn._conns -def test_release_close_do_not_add_to_pool(loop, key): +async def test_release_close_do_not_add_to_pool(loop, key) -> None: # see issue #473 conn = aiohttp.BaseConnector(loop=loop) @@ -958,10 +960,10 @@ def test_release_close_do_not_add_to_pool(loop, key): assert not conn._conns -def test_release_close_do_not_delete_existing_connections(loop, key): +async def test_release_close_do_not_delete_existing_connections(key) -> None: proto1 = mock.Mock() - conn = aiohttp.BaseConnector(loop=loop) + conn = aiohttp.BaseConnector() conn._conns[key] = [(proto1, 1)] proto = mock.Mock(should_close=True) @@ -972,7 +974,7 @@ def test_release_close_do_not_delete_existing_connections(loop, key): conn.close() -def test_release_not_started(loop): +async def test_release_not_started(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) proto = mock.Mock(should_close=False) key = 1 @@ -986,7 +988,7 @@ def test_release_not_started(loop): conn.close() -def test_release_not_opened(loop, key): +async def test_release_not_opened(loop, key) -> None: conn = aiohttp.BaseConnector(loop=loop) proto = mock.Mock() @@ -995,7 +997,7 @@ def test_release_not_opened(loop, key): assert proto.close.called -async def test_connect(loop, key): +async def test_connect(loop, key) -> None: proto = mock.Mock() proto.is_connected.return_value = True @@ -1015,7 +1017,7 @@ async def test_connect(loop, key): connection.close() -async def test_connect_tracing(loop): +async def test_connect_tracing(loop) -> None: session = mock.Mock() trace_config_ctx = mock.Mock() on_connection_create_start = mock.Mock( @@ -1064,7 +1066,7 @@ async def test_connect_tracing(loop): ) -async def test_close_during_connect(loop): +async def test_close_during_connect(loop) -> None: proto = mock.Mock() proto.is_connected.return_value = True @@ -1086,7 +1088,7 @@ async def test_close_during_connect(loop): assert proto.close.called -def test_ctor_cleanup(): +async def test_ctor_cleanup() -> None: loop = mock.Mock() loop.time.return_value = 1.5 conn = aiohttp.BaseConnector( @@ -1095,7 +1097,7 @@ def test_ctor_cleanup(): assert conn._cleanup_closed_handle is not None -def test_cleanup(key): +async def test_cleanup(key) -> None: testset = { key: [(mock.Mock(), 10), (mock.Mock(), 300)], @@ -1115,8 +1117,9 @@ def test_cleanup(key): assert conn._cleanup_handle is not None -def test_cleanup_close_ssl_transport(ssl_key): +async def test_cleanup_close_ssl_transport(ssl_key) -> None: proto = mock.Mock() + transport = proto.transport testset = {ssl_key: [(proto, 10)]} loop = mock.Mock() @@ -1128,10 +1131,10 @@ def test_cleanup_close_ssl_transport(ssl_key): conn._cleanup() assert existing_handle.cancel.called assert conn._conns == {} - assert conn._cleanup_closed_transports == [proto.close.return_value] + assert conn._cleanup_closed_transports == [transport] -def test_cleanup2(): +async def test_cleanup2() -> None: testset = {1: [(mock.Mock(), 300)]} testset[1][0][0].is_connected.return_value = True @@ -1148,7 +1151,7 @@ def test_cleanup2(): conn.close() -def test_cleanup3(key): +async def test_cleanup3(key) -> None: testset = {key: [(mock.Mock(), 290.1), (mock.Mock(), 305.1)]} testset[key][0][0].is_connected.return_value = True @@ -1167,7 +1170,7 @@ def test_cleanup3(key): conn.close() -def test_cleanup_closed(loop, mocker): +async def test_cleanup_closed(loop, mocker) -> None: if not hasattr(loop, '__dict__'): pytest.skip("can not override loop attributes") @@ -1184,7 +1187,7 @@ def test_cleanup_closed(loop, mocker): assert cleanup_closed_handle.cancel.called -def test_cleanup_closed_disabled(loop, mocker): +async def test_cleanup_closed_disabled(loop, mocker) -> None: conn = aiohttp.BaseConnector( loop=loop, enable_cleanup_closed=False) @@ -1195,7 +1198,7 @@ def test_cleanup_closed_disabled(loop, mocker): assert not conn._cleanup_closed_transports -def test_tcp_connector_ctor(loop): +async def test_tcp_connector_ctor(loop) -> None: conn = aiohttp.TCPConnector(loop=loop) assert conn._ssl is None @@ -1203,27 +1206,27 @@ def test_tcp_connector_ctor(loop): assert conn.family == 0 -def test_tcp_connector_ctor_fingerprint_valid(loop): +async def test_tcp_connector_ctor_fingerprint_valid(loop) -> None: valid = aiohttp.Fingerprint(hashlib.sha256(b"foo").digest()) conn = aiohttp.TCPConnector(ssl=valid, loop=loop) assert conn._ssl is valid -def test_insecure_fingerprint_md5(loop): +async def test_insecure_fingerprint_md5(loop) -> None: with pytest.raises(ValueError): aiohttp.TCPConnector( ssl=aiohttp.Fingerprint(hashlib.md5(b"foo").digest()), loop=loop) -def test_insecure_fingerprint_sha1(loop): +async def test_insecure_fingerprint_sha1(loop) -> None: with pytest.raises(ValueError): aiohttp.TCPConnector( ssl=aiohttp.Fingerprint(hashlib.sha1(b"foo").digest()), loop=loop) -def test_tcp_connector_clear_dns_cache(loop): +async def test_tcp_connector_clear_dns_cache(loop) -> None: conn = aiohttp.TCPConnector(loop=loop) hosts = ['a', 'b'] conn._cached_hosts.add(('localhost', 123), hosts) @@ -1244,32 +1247,32 @@ def test_tcp_connector_clear_dns_cache(loop): conn._cached_hosts.next_addrs(('localhost', 124)) -def test_tcp_connector_clear_dns_cache_bad_args(loop): +async def test_tcp_connector_clear_dns_cache_bad_args(loop) -> None: conn = aiohttp.TCPConnector(loop=loop) with pytest.raises(ValueError): conn.clear_dns_cache('localhost') -def test_dont_recreate_ssl_context(loop): +async def test_dont_recreate_ssl_context(loop) -> None: conn = aiohttp.TCPConnector(loop=loop) ctx = conn._make_ssl_context(True) assert ctx is conn._make_ssl_context(True) -def test_dont_recreate_ssl_context2(loop): +async def test_dont_recreate_ssl_context2(loop) -> None: conn = aiohttp.TCPConnector(loop=loop) ctx = conn._make_ssl_context(False) assert ctx is conn._make_ssl_context(False) -def test___get_ssl_context1(loop): +async def test___get_ssl_context1(loop) -> None: conn = aiohttp.TCPConnector(loop=loop) req = mock.Mock() req.is_ssl.return_value = False assert conn._get_ssl_context(req) is None -def test___get_ssl_context2(loop): +async def test___get_ssl_context2(loop) -> None: ctx = ssl.SSLContext() conn = aiohttp.TCPConnector(loop=loop) req = mock.Mock() @@ -1278,7 +1281,7 @@ def test___get_ssl_context2(loop): assert conn._get_ssl_context(req) is ctx -def test___get_ssl_context3(loop): +async def test___get_ssl_context3(loop) -> None: ctx = ssl.SSLContext() conn = aiohttp.TCPConnector(loop=loop, ssl=ctx) req = mock.Mock() @@ -1287,7 +1290,7 @@ def test___get_ssl_context3(loop): assert conn._get_ssl_context(req) is ctx -def test___get_ssl_context4(loop): +async def test___get_ssl_context4(loop) -> None: ctx = ssl.SSLContext() conn = aiohttp.TCPConnector(loop=loop, ssl=ctx) req = mock.Mock() @@ -1296,7 +1299,7 @@ def test___get_ssl_context4(loop): assert conn._get_ssl_context(req) is conn._make_ssl_context(False) -def test___get_ssl_context5(loop): +async def test___get_ssl_context5(loop) -> None: ctx = ssl.SSLContext() conn = aiohttp.TCPConnector(loop=loop, ssl=ctx) req = mock.Mock() @@ -1305,7 +1308,7 @@ def test___get_ssl_context5(loop): assert conn._get_ssl_context(req) is conn._make_ssl_context(False) -def test___get_ssl_context6(loop): +async def test___get_ssl_context6(loop) -> None: conn = aiohttp.TCPConnector(loop=loop) req = mock.Mock() req.is_ssl.return_value = True @@ -1313,7 +1316,7 @@ def test___get_ssl_context6(loop): assert conn._get_ssl_context(req) is conn._make_ssl_context(True) -def test_close_twice(loop): +async def test_close_twice(loop) -> None: proto = mock.Mock() conn = aiohttp.BaseConnector(loop=loop) @@ -1329,7 +1332,7 @@ def test_close_twice(loop): assert conn.closed -def test_close_cancels_cleanup_handle(loop): +async def test_close_cancels_cleanup_handle(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) conn._release(1, mock.Mock(should_close=False)) assert conn._cleanup_handle is not None @@ -1337,7 +1340,7 @@ def test_close_cancels_cleanup_handle(loop): assert conn._cleanup_handle is None -def test_close_abort_closed_transports(loop): +async def test_close_abort_closed_transports(loop) -> None: tr = mock.Mock() conn = aiohttp.BaseConnector(loop=loop) @@ -1349,22 +1352,19 @@ def test_close_abort_closed_transports(loop): assert conn.closed -def test_close_cancels_cleanup_closed_handle(loop): +async def test_close_cancels_cleanup_closed_handle(loop) -> None: conn = aiohttp.BaseConnector(loop=loop, enable_cleanup_closed=True) assert conn._cleanup_closed_handle is not None conn.close() assert conn._cleanup_closed_handle is None -def test_ctor_with_default_loop(): - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) +async def test_ctor_with_default_loop(loop) -> None: conn = aiohttp.BaseConnector() assert loop is conn._loop - loop.close() -async def test_connect_with_limit(loop, key): +async def test_connect_with_limit(loop, key) -> None: proto = mock.Mock() proto.is_connected.return_value = True @@ -1407,7 +1407,7 @@ async def test_connect_with_limit(loop, key): conn.close() -async def test_connect_queued_operation_tracing(loop, key): +async def test_connect_queued_operation_tracing(loop, key) -> None: session = mock.Mock() trace_config_ctx = mock.Mock() on_connection_queued_start = mock.Mock( @@ -1467,7 +1467,7 @@ async def test_connect_queued_operation_tracing(loop, key): conn.close() -async def test_connect_reuseconn_tracing(loop, key): +async def test_connect_reuseconn_tracing(loop, key) -> None: session = mock.Mock() trace_config_ctx = mock.Mock() on_connection_reuseconn = mock.Mock( @@ -1507,7 +1507,7 @@ async def test_connect_reuseconn_tracing(loop, key): conn.close() -async def test_connect_with_limit_and_limit_per_host(loop, key): +async def test_connect_with_limit_and_limit_per_host(loop, key) -> None: proto = mock.Mock() proto.is_connected.return_value = True @@ -1541,7 +1541,7 @@ async def test_connect_with_limit_and_limit_per_host(loop, key): conn.close() -async def test_connect_with_no_limit_and_limit_per_host(loop, key): +async def test_connect_with_no_limit_and_limit_per_host(loop, key) -> None: proto = mock.Mock() proto.is_connected.return_value = True @@ -1573,7 +1573,7 @@ async def test_connect_with_no_limit_and_limit_per_host(loop, key): conn.close() -async def test_connect_with_no_limits(loop, key): +async def test_connect_with_no_limits(loop, key) -> None: proto = mock.Mock() proto.is_connected.return_value = True @@ -1605,7 +1605,7 @@ async def test_connect_with_no_limits(loop, key): conn.close() -async def test_connect_with_limit_cancelled(loop): +async def test_connect_with_limit_cancelled(loop) -> None: proto = mock.Mock() proto.is_connected.return_value = True @@ -1632,7 +1632,7 @@ async def test_connect_with_limit_cancelled(loop): connection.close() -async def test_connect_with_capacity_release_waiters(loop): +async def test_connect_with_capacity_release_waiters(loop) -> None: def check_with_exc(err): conn = aiohttp.BaseConnector(limit=1, loop=loop) @@ -1652,7 +1652,7 @@ async def test_connect_with_capacity_release_waiters(loop): check_with_exc(asyncio.TimeoutError()) -async def test_connect_with_limit_concurrent(loop): +async def test_connect_with_limit_concurrent(loop) -> None: proto = mock.Mock() proto.should_close = False proto.is_connected.return_value = True @@ -1713,7 +1713,7 @@ async def test_connect_with_limit_concurrent(loop): assert max_connections == num_connections -async def test_connect_waiters_cleanup(loop): +async def test_connect_waiters_cleanup(loop) -> None: proto = mock.Mock() proto.is_connected.return_value = True @@ -1732,7 +1732,7 @@ async def test_connect_waiters_cleanup(loop): assert not conn._waiters.keys() -async def test_connect_waiters_cleanup_key_error(loop): +async def test_connect_waiters_cleanup_key_error(loop) -> None: proto = mock.Mock() proto.is_connected.return_value = True @@ -1755,7 +1755,7 @@ async def test_connect_waiters_cleanup_key_error(loop): assert not conn._waiters.keys() == [] -async def test_close_with_acquired_connection(loop): +async def test_close_with_acquired_connection(loop) -> None: proto = mock.Mock() proto.is_connected.return_value = True @@ -1781,38 +1781,38 @@ async def test_close_with_acquired_connection(loop): assert connection.closed -def test_default_force_close(loop): +async def test_default_force_close(loop) -> None: connector = aiohttp.BaseConnector(loop=loop) assert not connector.force_close -def test_limit_property(loop): +async def test_limit_property(loop) -> None: conn = aiohttp.BaseConnector(loop=loop, limit=15) assert 15 == conn.limit conn.close() -def test_limit_per_host_property(loop): +async def test_limit_per_host_property(loop) -> None: conn = aiohttp.BaseConnector(loop=loop, limit_per_host=15) assert 15 == conn.limit_per_host conn.close() -def test_limit_property_default(loop): +async def test_limit_property_default(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) assert conn.limit == 100 conn.close() -def test_limit_per_host_property_default(loop): +async def test_limit_per_host_property_default(loop) -> None: conn = aiohttp.BaseConnector(loop=loop) assert conn.limit_per_host == 0 conn.close() -def test_force_close_and_explicit_keep_alive(loop): +async def test_force_close_and_explicit_keep_alive(loop) -> None: with pytest.raises(ValueError): aiohttp.BaseConnector(loop=loop, keepalive_timeout=30, force_close=True) @@ -1826,7 +1826,7 @@ def test_force_close_and_explicit_keep_alive(loop): assert conn -async def test_error_on_connection(loop, key): +async def test_error_on_connection(loop, key) -> None: conn = aiohttp.BaseConnector(limit=1, loop=loop) req = mock.Mock() @@ -1868,7 +1868,7 @@ async def test_error_on_connection(loop, key): ret.release() -async def test_cancelled_waiter(loop): +async def test_cancelled_waiter(loop) -> None: conn = aiohttp.BaseConnector(limit=1, loop=loop) req = mock.Mock() req.connection_key = 'key' @@ -1890,7 +1890,7 @@ async def test_cancelled_waiter(loop): await conn2 -async def test_error_on_connection_with_cancelled_waiter(loop, key): +async def test_error_on_connection_with_cancelled_waiter(loop, key) -> None: conn = aiohttp.BaseConnector(limit=1, loop=loop) req = mock.Mock() @@ -1940,7 +1940,7 @@ async def test_error_on_connection_with_cancelled_waiter(loop, key): ret.release() -async def test_tcp_connector(aiohttp_client, loop): +async def test_tcp_connector(aiohttp_client, loop) -> None: async def handler(request): return web.Response() @@ -1955,19 +1955,19 @@ async def test_tcp_connector(aiohttp_client, loop): @pytest.mark.skipif(not hasattr(socket, 'AF_UNIX'), reason="requires unix socket") -def test_unix_connector_not_found(loop): +async def test_unix_connector_not_found(loop) -> None: connector = aiohttp.UnixConnector('/' + uuid.uuid4().hex, loop=loop) req = ClientRequest( 'GET', URL('http://www.python.org'), loop=loop) with pytest.raises(aiohttp.ClientConnectorError): - loop.run_until_complete(connector.connect(req, None, ClientTimeout())) + await connector.connect(req, None, ClientTimeout()) @pytest.mark.skipif(not hasattr(socket, 'AF_UNIX'), reason="requires unix socket") -def test_unix_connector_permission(loop): +async def test_unix_connector_permission(loop) -> None: loop.create_unix_connection = make_mocked_coro( raise_exception=PermissionError()) connector = aiohttp.UnixConnector('/' + uuid.uuid4().hex, loop=loop) @@ -1976,15 +1976,15 @@ def test_unix_connector_permission(loop): 'GET', URL('http://www.python.org'), loop=loop) with pytest.raises(aiohttp.ClientConnectorError): - loop.run_until_complete(connector.connect(req, None, ClientTimeout())) + await connector.connect(req, None, ClientTimeout()) -def test_default_use_dns_cache(loop): - conn = aiohttp.TCPConnector(loop=loop) +async def test_default_use_dns_cache() -> None: + conn = aiohttp.TCPConnector() assert conn.use_dns_cache -async def test_resolver_not_called_with_address_is_ip(loop): +async def test_resolver_not_called_with_address_is_ip(loop) -> None: resolver = mock.MagicMock() connector = aiohttp.TCPConnector(resolver=resolver) @@ -1999,7 +1999,7 @@ async def test_resolver_not_called_with_address_is_ip(loop): resolver.resolve.assert_not_called() -async def test_tcp_connector_raise_connector_ssl_error(aiohttp_server): +async def test_tcp_connector_raise_connector_ssl_error(aiohttp_server) -> None: async def handler(request): return web.Response() @@ -2037,7 +2037,8 @@ async def test_tcp_connector_raise_connector_ssl_error(aiohttp_server): await session.close() -async def test_tcp_connector_do_not_raise_connector_ssl_error(aiohttp_server): +async def test_tcp_connector_do_not_raise_connector_ssl_error( + aiohttp_server) -> None: async def handler(request): return web.Response() @@ -2074,7 +2075,7 @@ async def test_tcp_connector_do_not_raise_connector_ssl_error(aiohttp_server): conn.close() -async def test_tcp_connector_uses_provided_local_addr(aiohttp_server): +async def test_tcp_connector_uses_provided_local_addr(aiohttp_server) -> None: async def handler(request): return web.Response() @@ -2101,7 +2102,7 @@ async def test_tcp_connector_uses_provided_local_addr(aiohttp_server): @pytest.mark.skipif(not hasattr(socket, 'AF_UNIX'), reason='requires UNIX sockets') -async def test_unix_connector(unix_server, unix_sockname): +async def test_unix_connector(unix_server, unix_sockname) -> None: async def handler(request): return web.Response() @@ -2127,7 +2128,7 @@ class TestDNSCacheTable: def dns_cache_table(self): return _DNSCacheTable() - def test_next_addrs_basic(self, dns_cache_table): + def test_next_addrs_basic(self, dns_cache_table) -> None: dns_cache_table.add('localhost', ['127.0.0.1']) dns_cache_table.add('foo', ['127.0.0.2']) @@ -2138,34 +2139,34 @@ class TestDNSCacheTable: with pytest.raises(KeyError): dns_cache_table.next_addrs('no-such-host') - def test_remove(self, dns_cache_table): + def test_remove(self, dns_cache_table) -> None: dns_cache_table.add('localhost', ['127.0.0.1']) dns_cache_table.remove('localhost') with pytest.raises(KeyError): dns_cache_table.next_addrs('localhost') - def test_clear(self, dns_cache_table): + def test_clear(self, dns_cache_table) -> None: dns_cache_table.add('localhost', ['127.0.0.1']) dns_cache_table.clear() with pytest.raises(KeyError): dns_cache_table.next_addrs('localhost') - def test_not_expired_ttl_None(self, dns_cache_table): + def test_not_expired_ttl_None(self, dns_cache_table) -> None: dns_cache_table.add('localhost', ['127.0.0.1']) assert not dns_cache_table.expired('localhost') - def test_not_expired_ttl(self): + def test_not_expired_ttl(self) -> None: dns_cache_table = _DNSCacheTable(ttl=0.1) dns_cache_table.add('localhost', ['127.0.0.1']) assert not dns_cache_table.expired('localhost') - async def test_expired_ttl(self, loop): + async def test_expired_ttl(self, loop) -> None: dns_cache_table = _DNSCacheTable(ttl=0.01) dns_cache_table.add('localhost', ['127.0.0.1']) await asyncio.sleep(0.02, loop=loop) assert dns_cache_table.expired('localhost') - def test_next_addrs(self, dns_cache_table): + def test_next_addrs(self, dns_cache_table) -> None: dns_cache_table.add('foo', ['127.0.0.1', '127.0.0.2', '127.0.0.3']) # Each calls to next_addrs return the hosts using @@ -2182,7 +2183,7 @@ class TestDNSCacheTable: addrs = dns_cache_table.next_addrs('foo') assert addrs == ['127.0.0.1', '127.0.0.2', '127.0.0.3'] - def test_next_addrs_single(self, dns_cache_table): + def test_next_addrs_single(self, dns_cache_table) -> None: dns_cache_table.add('foo', ['127.0.0.1']) addrs = dns_cache_table.next_addrs('foo') diff --git a/tests/test_cookiejar.py b/tests/test_cookiejar.py index cc0202a..4cf5b93 100644 --- a/tests/test_cookiejar.py +++ b/tests/test_cookiejar.py @@ -54,7 +54,7 @@ def cookies_to_receive(): ) -def test_date_parsing(): +def test_date_parsing() -> None: parse_func = CookieJar._parse_date utc = datetime.timezone.utc @@ -98,7 +98,7 @@ def test_date_parsing(): assert parse_func("Tue, 1 Jan 1970 77:88:99 GMT") is None -def test_domain_matching(): +def test_domain_matching() -> None: test_func = CookieJar._is_domain_match assert test_func("test.com", "test.com") @@ -111,7 +111,7 @@ def test_domain_matching(): assert not test_func("test.com", "127.0.0.1") -def test_path_matching(): +def test_path_matching() -> None: test_func = CookieJar._is_path_match assert test_func("/", "") @@ -133,7 +133,7 @@ def test_path_matching(): assert not test_func("/different-folder/", "/folder/") -def test_constructor(loop, cookies_to_send, cookies_to_receive): +async def test_constructor(loop, cookies_to_send, cookies_to_receive) -> None: jar = CookieJar(loop=loop) jar.update_cookies(cookies_to_send) jar_cookies = SimpleCookie() @@ -144,7 +144,7 @@ def test_constructor(loop, cookies_to_send, cookies_to_receive): assert jar._loop is loop -def test_save_load(loop, cookies_to_send, cookies_to_receive): +async def test_save_load(loop, cookies_to_send, cookies_to_receive) -> None: file_path = tempfile.mkdtemp() + '/aiohttp.test.cookie' # export cookie jar @@ -163,7 +163,7 @@ def test_save_load(loop, cookies_to_send, cookies_to_receive): assert jar_test == cookies_to_receive -def test_update_cookie_with_unicode_domain(loop): +async def test_update_cookie_with_unicode_domain(loop) -> None: cookies = ( "idna-domain-first=first; Domain=xn--9caa.com; Path=/;", "idna-domain-second=second; Domain=xn--9caa.com; Path=/;", @@ -180,8 +180,8 @@ def test_update_cookie_with_unicode_domain(loop): assert jar_test == SimpleCookie(" ".join(cookies)) -def test_filter_cookie_with_unicode_domain(loop): - jar = CookieJar(loop=loop) +async def test_filter_cookie_with_unicode_domain(loop) -> None: + jar = CookieJar() jar.update_cookies(SimpleCookie( "idna-domain-first=first; Domain=xn--9caa.com; Path=/; " )) @@ -189,13 +189,7 @@ def test_filter_cookie_with_unicode_domain(loop): assert len(jar.filter_cookies(URL("http://xn--9caa.com"))) == 1 -def test_ctor_ith_default_loop(loop): - asyncio.set_event_loop(loop) - jar = CookieJar() - assert jar._loop is loop - - -def test_domain_filter_ip_cookie_send(loop): +async def test_domain_filter_ip_cookie_send(loop) -> None: jar = CookieJar(loop=loop) cookies = SimpleCookie( "shared-cookie=first; " @@ -226,14 +220,14 @@ def test_domain_filter_ip_cookie_send(loop): assert cookies_sent == 'Cookie: shared-cookie=first' -def test_domain_filter_ip_cookie_receive(loop, cookies_to_receive): - jar = CookieJar(loop=loop) +async def test_domain_filter_ip_cookie_receive(cookies_to_receive) -> None: + jar = CookieJar() jar.update_cookies(cookies_to_receive, URL("http://1.2.3.4/")) assert len(jar) == 0 -def test_preserving_ip_domain_cookies(loop): +async def test_preserving_ip_domain_cookies(loop) -> None: jar = CookieJar(loop=loop, unsafe=True) jar.update_cookies(SimpleCookie( "shared-cookie=first; " @@ -245,7 +239,7 @@ def test_preserving_ip_domain_cookies(loop): 'Cookie: shared-cookie=first') -def test_preserving_quoted_cookies(loop): +async def test_preserving_quoted_cookies(loop) -> None: jar = CookieJar(loop=loop, unsafe=True) jar.update_cookies(SimpleCookie( "ip-cookie=\"second\"; Domain=127.0.0.1;" @@ -255,7 +249,7 @@ def test_preserving_quoted_cookies(loop): assert cookies_sent == 'Cookie: ip-cookie=\"second\"' -def test_ignore_domain_ending_with_dot(loop): +async def test_ignore_domain_ending_with_dot(loop) -> None: jar = CookieJar(loop=loop, unsafe=True) jar.update_cookies(SimpleCookie("cookie=val; Domain=example.com.;"), URL("http://www.example.com")) @@ -272,7 +266,9 @@ class TestCookieJarBase(unittest.TestCase): asyncio.set_event_loop(None) # N.B. those need to be overridden in child test cases - self.jar = CookieJar(loop=self.loop) + async def make_jar(): + return CookieJar() + self.jar = self.loop.run_until_complete(make_jar()) def tearDown(self): self.loop.close() @@ -333,7 +329,9 @@ class TestCookieJarSafe(TestCookieJarBase): "wrong-path-cookie=nineth; Domain=pathtest.com; Path=somepath;" ) - self.jar = CookieJar(loop=self.loop) + async def make_jar(): + return CookieJar() + self.jar = self.loop.run_until_complete(make_jar()) def timed_request(self, url, update_time, send_time): with mock.patch.object(self.loop, 'time', return_value=update_time): @@ -346,7 +344,7 @@ class TestCookieJarSafe(TestCookieJarBase): return cookies_sent - def test_domain_filter_same_host(self): + def test_domain_filter_same_host(self) -> None: cookies_sent, cookies_received = ( self.request_reply_with_same_url("http://example.com/")) @@ -362,7 +360,7 @@ class TestCookieJarSafe(TestCookieJarBase): "dotted-domain-cookie" }) - def test_domain_filter_same_host_and_subdomain(self): + def test_domain_filter_same_host_and_subdomain(self) -> None: cookies_sent, cookies_received = ( self.request_reply_with_same_url("http://test1.example.com/")) @@ -380,7 +378,7 @@ class TestCookieJarSafe(TestCookieJarBase): "dotted-domain-cookie" }) - def test_domain_filter_same_host_diff_subdomain(self): + def test_domain_filter_same_host_diff_subdomain(self) -> None: cookies_sent, cookies_received = ( self.request_reply_with_same_url("http://different.example.com/")) @@ -396,7 +394,7 @@ class TestCookieJarSafe(TestCookieJarBase): "dotted-domain-cookie" }) - def test_domain_filter_diff_host(self): + def test_domain_filter_diff_host(self) -> None: cookies_sent, cookies_received = ( self.request_reply_with_same_url("http://different.org/")) @@ -410,7 +408,7 @@ class TestCookieJarSafe(TestCookieJarBase): "different-domain-cookie" }) - def test_domain_filter_host_only(self): + def test_domain_filter_host_only(self) -> None: self.jar.update_cookies(self.cookies_to_receive, URL("http://example.com/")) @@ -420,7 +418,7 @@ class TestCookieJarSafe(TestCookieJarBase): cookies_sent = self.jar.filter_cookies(URL("http://different.org/")) self.assertNotIn("unconstrained-cookie", set(cookies_sent.keys())) - def test_secure_filter(self): + def test_secure_filter(self) -> None: cookies_sent, _ = ( self.request_reply_with_same_url("http://secure.com/")) @@ -436,7 +434,7 @@ class TestCookieJarSafe(TestCookieJarBase): "secure-cookie" }) - def test_path_filter_root(self): + def test_path_filter_root(self) -> None: cookies_sent, _ = ( self.request_reply_with_same_url("http://pathtest.com/")) @@ -446,7 +444,7 @@ class TestCookieJarSafe(TestCookieJarBase): "path1-cookie" }) - def test_path_filter_folder(self): + def test_path_filter_folder(self) -> None: cookies_sent, _ = ( self.request_reply_with_same_url("http://pathtest.com/one/")) @@ -458,7 +456,7 @@ class TestCookieJarSafe(TestCookieJarBase): "path2-cookie" }) - def test_path_filter_file(self): + def test_path_filter_file(self) -> None: cookies_sent, _ = self.request_reply_with_same_url( "http://pathtest.com/one/two") @@ -471,7 +469,7 @@ class TestCookieJarSafe(TestCookieJarBase): "path3-cookie" }) - def test_path_filter_subfolder(self): + def test_path_filter_subfolder(self) -> None: cookies_sent, _ = self.request_reply_with_same_url( "http://pathtest.com/one/two/") @@ -485,7 +483,7 @@ class TestCookieJarSafe(TestCookieJarBase): "path4-cookie" }) - def test_path_filter_subsubfolder(self): + def test_path_filter_subsubfolder(self) -> None: cookies_sent, _ = self.request_reply_with_same_url( "http://pathtest.com/one/two/three/") @@ -499,7 +497,7 @@ class TestCookieJarSafe(TestCookieJarBase): "path4-cookie" }) - def test_path_filter_different_folder(self): + def test_path_filter_different_folder(self) -> None: cookies_sent, _ = ( self.request_reply_with_same_url("http://pathtest.com/hundred/")) @@ -510,7 +508,7 @@ class TestCookieJarSafe(TestCookieJarBase): "path1-cookie" }) - def test_path_value(self): + def test_path_value(self) -> None: _, cookies_received = ( self.request_reply_with_same_url("http://pathtest.com/")) @@ -525,7 +523,7 @@ class TestCookieJarSafe(TestCookieJarBase): self.assertEqual(cookies_received["path-cookie"]["path"], "/somepath") self.assertEqual(cookies_received["wrong-path-cookie"]["path"], "/") - def test_expires(self): + def test_expires(self) -> None: ts_before = datetime.datetime( 1975, 1, 1, tzinfo=datetime.timezone.utc).timestamp() @@ -547,7 +545,7 @@ class TestCookieJarSafe(TestCookieJarBase): "shared-cookie" }) - def test_max_age(self): + def test_max_age(self) -> None: cookies_sent = self.timed_request( "http://maxagetest.com/", 1000, 1000) @@ -563,7 +561,7 @@ class TestCookieJarSafe(TestCookieJarBase): "shared-cookie" }) - def test_invalid_values(self): + def test_invalid_values(self) -> None: cookies_sent, cookies_received = ( self.request_reply_with_same_url("http://invalid-values.com/")) @@ -579,7 +577,7 @@ class TestCookieJarSafe(TestCookieJarBase): cookie = cookies_sent["invalid-expires-cookie"] self.assertEqual(cookie["expires"], "") - def test_cookie_not_expired_when_added_after_removal(self): + def test_cookie_not_expired_when_added_after_removal(self) -> None: """Test case for https://github.com/aio-libs/aiohttp/issues/2084""" timestamps = [533588.993, 533588.993, 533588.993, 533588.993, 533589.093, 533589.093] @@ -588,7 +586,9 @@ class TestCookieJarSafe(TestCookieJarBase): loop.time.side_effect = itertools.chain( timestamps, itertools.cycle([timestamps[-1]])) - jar = CookieJar(unsafe=True, loop=loop) + async def make_jar(): + return CookieJar(unsafe=True) + jar = self.loop.run_until_complete(make_jar()) # Remove `foo` cookie. jar.update_cookies(SimpleCookie('foo=""; Max-Age=0')) # Set `foo` cookie to `bar`. @@ -598,13 +598,13 @@ class TestCookieJarSafe(TestCookieJarBase): assert len(jar) == 1 -def test_dummy_cookie_jar(loop): +async def test_dummy_cookie_jar() -> None: cookie = SimpleCookie('foo=bar; Domain=example.com;') - dummy_jar = DummyCookieJar(loop=loop) + dummy_jar = DummyCookieJar() assert len(dummy_jar) == 0 dummy_jar.update_cookies(cookie) assert len(dummy_jar) == 0 with pytest.raises(StopIteration): next(iter(dummy_jar)) - assert dummy_jar.filter_cookies(URL("http://example.com/")) is None + assert not dummy_jar.filter_cookies(URL("http://example.com/")) dummy_jar.clear() diff --git a/tests/test_flowcontrol_streams.py b/tests/test_flowcontrol_streams.py index 431d411..e70b0c1 100644 --- a/tests/test_flowcontrol_streams.py +++ b/tests/test_flowcontrol_streams.py @@ -26,13 +26,13 @@ def buffer(loop, protocol): class TestFlowControlStreamReader: - async def test_read(self, stream): + async def test_read(self, stream) -> None: stream.feed_data(b'da', 2) res = await stream.read(1) assert res == b'd' assert not stream._protocol.resume_reading.called - async def test_read_resume_paused(self, stream): + async def test_read_resume_paused(self, stream) -> None: stream.feed_data(b'test', 4) stream._protocol._reading_paused = True @@ -40,40 +40,40 @@ class TestFlowControlStreamReader: assert res == b't' assert stream._protocol.pause_reading.called - async def test_readline(self, stream): + async def test_readline(self, stream) -> None: stream.feed_data(b'd\n', 5) res = await stream.readline() assert res == b'd\n' assert not stream._protocol.resume_reading.called - async def test_readline_resume_paused(self, stream): + async def test_readline_resume_paused(self, stream) -> None: stream._protocol._reading_paused = True stream.feed_data(b'd\n', 5) res = await stream.readline() assert res == b'd\n' assert stream._protocol.resume_reading.called - async def test_readany(self, stream): + async def test_readany(self, stream) -> None: stream.feed_data(b'data', 4) res = await stream.readany() assert res == b'data' assert not stream._protocol.resume_reading.called - async def test_readany_resume_paused(self, stream): + async def test_readany_resume_paused(self, stream) -> None: stream._protocol._reading_paused = True stream.feed_data(b'data', 4) res = await stream.readany() assert res == b'data' assert stream._protocol.resume_reading.called - async def test_readchunk(self, stream): + async def test_readchunk(self, stream) -> None: stream.feed_data(b'data', 4) res, end_of_http_chunk = await stream.readchunk() assert res == b'data' assert not end_of_http_chunk assert not stream._protocol.resume_reading.called - async def test_readchunk_resume_paused(self, stream): + async def test_readchunk_resume_paused(self, stream) -> None: stream._protocol._reading_paused = True stream.feed_data(b'data', 4) res, end_of_http_chunk = await stream.readchunk() @@ -81,18 +81,18 @@ class TestFlowControlStreamReader: assert not end_of_http_chunk assert stream._protocol.resume_reading.called - async def test_readexactly(self, stream): + async def test_readexactly(self, stream) -> None: stream.feed_data(b'data', 4) res = await stream.readexactly(3) assert res == b'dat' assert not stream._protocol.resume_reading.called - async def test_feed_data(self, stream): + async def test_feed_data(self, stream) -> None: stream._protocol._reading_paused = False stream.feed_data(b'datadata', 8) assert stream._protocol.pause_reading.called - async def test_read_nowait(self, stream): + async def test_read_nowait(self, stream) -> None: stream._protocol._reading_paused = True stream.feed_data(b'data1', 5) stream.feed_data(b'data2', 5) @@ -117,13 +117,13 @@ class TestFlowControlStreamReader: class TestFlowControlDataQueue: - def test_feed_pause(self, buffer): + def test_feed_pause(self, buffer) -> None: buffer._protocol._reading_paused = False buffer.feed_data(object(), 100) assert buffer._protocol.pause_reading.called - async def test_resume_on_read(self, buffer): + async def test_resume_on_read(self, buffer) -> None: buffer.feed_data(object(), 100) buffer._protocol._reading_paused = True diff --git a/tests/test_formdata.py b/tests/test_formdata.py index 744edfe..55f8653 100644 --- a/tests/test_formdata.py +++ b/tests/test_formdata.py @@ -21,7 +21,7 @@ def writer(buf): return writer -def test_formdata_multipart(buf, writer): +def test_formdata_multipart(buf, writer) -> None: form = FormData() assert not form.is_multipart @@ -29,24 +29,24 @@ def test_formdata_multipart(buf, writer): assert form.is_multipart -def test_invalid_formdata_payload(): +def test_invalid_formdata_payload() -> None: form = FormData() form.add_field('test', object(), filename='test.txt') with pytest.raises(TypeError): form() -def test_invalid_formdata_params(): +def test_invalid_formdata_params() -> None: with pytest.raises(TypeError): FormData('asdasf') -def test_invalid_formdata_params2(): +def test_invalid_formdata_params2() -> None: with pytest.raises(TypeError): FormData('as') # 2-char str is not allowed -def test_invalid_formdata_content_type(): +def test_invalid_formdata_content_type() -> None: form = FormData() invalid_vals = [0, 0.1, {}, [], b'foo'] for invalid_val in invalid_vals: @@ -54,7 +54,7 @@ def test_invalid_formdata_content_type(): form.add_field('foo', 'bar', content_type=invalid_val) -def test_invalid_formdata_filename(): +def test_invalid_formdata_filename() -> None: form = FormData() invalid_vals = [0, 0.1, {}, [], b'foo'] for invalid_val in invalid_vals: @@ -62,7 +62,7 @@ def test_invalid_formdata_filename(): form.add_field('foo', 'bar', filename=invalid_val) -def test_invalid_formdata_content_transfer_encoding(): +def test_invalid_formdata_content_transfer_encoding() -> None: form = FormData() invalid_vals = [0, 0.1, {}, [], b'foo'] for invalid_val in invalid_vals: @@ -72,7 +72,7 @@ def test_invalid_formdata_content_transfer_encoding(): content_transfer_encoding=invalid_val) -async def test_formdata_field_name_is_quoted(buf, writer): +async def test_formdata_field_name_is_quoted(buf, writer) -> None: form = FormData(charset="ascii") form.add_field("emails[]", "xxx@x.co", content_type="multipart/form-data") payload = form() @@ -80,7 +80,7 @@ async def test_formdata_field_name_is_quoted(buf, writer): assert b'name="emails%5B%5D"' in buf -async def test_formdata_field_name_is_not_quoted(buf, writer): +async def test_formdata_field_name_is_not_quoted(buf, writer) -> None: form = FormData(quote_fields=False, charset="ascii") form.add_field("emails[]", "xxx@x.co", content_type="multipart/form-data") payload = form() diff --git a/tests/test_frozenlist.py b/tests/test_frozenlist.py index 289f3e3..b6d8d86 100644 --- a/tests/test_frozenlist.py +++ b/tests/test_frozenlist.py @@ -10,212 +10,212 @@ class FrozenListMixin: SKIP_METHODS = {'__abstractmethods__', '__slots__'} - def test_subclass(self): + def test_subclass(self) -> None: assert issubclass(self.FrozenList, MutableSequence) - def test_iface(self): + def test_iface(self) -> None: for name in set(dir(MutableSequence)) - self.SKIP_METHODS: if name.startswith('_') and not name.endswith('_'): continue assert hasattr(self.FrozenList, name) - def test_ctor_default(self): + def test_ctor_default(self) -> None: _list = self.FrozenList([]) assert not _list.frozen - def test_ctor(self): + def test_ctor(self) -> None: _list = self.FrozenList([1]) assert not _list.frozen - def test_ctor_copy_list(self): + def test_ctor_copy_list(self) -> None: orig = [1] _list = self.FrozenList(orig) del _list[0] assert _list != orig - def test_freeze(self): + def test_freeze(self) -> None: _list = self.FrozenList() _list.freeze() assert _list.frozen - def test_repr(self): + def test_repr(self) -> None: _list = self.FrozenList([1]) assert repr(_list) == '<FrozenList(frozen=False, [1])>' _list.freeze() assert repr(_list) == '<FrozenList(frozen=True, [1])>' - def test_getitem(self): + def test_getitem(self) -> None: _list = self.FrozenList([1, 2]) assert _list[1] == 2 - def test_setitem(self): + def test_setitem(self) -> None: _list = self.FrozenList([1, 2]) _list[1] = 3 assert _list[1] == 3 - def test_delitem(self): + def test_delitem(self) -> None: _list = self.FrozenList([1, 2]) del _list[0] assert len(_list) == 1 assert _list[0] == 2 - def test_len(self): + def test_len(self) -> None: _list = self.FrozenList([1]) assert len(_list) == 1 - def test_iter(self): + def test_iter(self) -> None: _list = self.FrozenList([1, 2]) assert list(iter(_list)) == [1, 2] - def test_reversed(self): + def test_reversed(self) -> None: _list = self.FrozenList([1, 2]) assert list(reversed(_list)) == [2, 1] - def test_eq(self): + def test_eq(self) -> None: _list = self.FrozenList([1]) assert _list == [1] - def test_ne(self): + def test_ne(self) -> None: _list = self.FrozenList([1]) assert _list != [2] - def test_le(self): + def test_le(self) -> None: _list = self.FrozenList([1]) assert _list <= [1] - def test_lt(self): + def test_lt(self) -> None: _list = self.FrozenList([1]) assert _list <= [3] - def test_ge(self): + def test_ge(self) -> None: _list = self.FrozenList([1]) assert _list >= [1] - def test_gt(self): + def test_gt(self) -> None: _list = self.FrozenList([2]) assert _list > [1] - def test_insert(self): + def test_insert(self) -> None: _list = self.FrozenList([2]) _list.insert(0, 1) assert _list == [1, 2] - def test_frozen_setitem(self): + def test_frozen_setitem(self) -> None: _list = self.FrozenList([1]) _list.freeze() with pytest.raises(RuntimeError): _list[0] = 2 - def test_frozen_delitem(self): + def test_frozen_delitem(self) -> None: _list = self.FrozenList([1]) _list.freeze() with pytest.raises(RuntimeError): del _list[0] - def test_frozen_insert(self): + def test_frozen_insert(self) -> None: _list = self.FrozenList([1]) _list.freeze() with pytest.raises(RuntimeError): _list.insert(0, 2) - def test_contains(self): + def test_contains(self) -> None: _list = self.FrozenList([2]) assert 2 in _list - def test_iadd(self): + def test_iadd(self) -> None: _list = self.FrozenList([1]) _list += [2] assert _list == [1, 2] - def test_iadd_frozen(self): + def test_iadd_frozen(self) -> None: _list = self.FrozenList([1]) _list.freeze() with pytest.raises(RuntimeError): _list += [2] assert _list == [1] - def test_index(self): + def test_index(self) -> None: _list = self.FrozenList([1]) assert _list.index(1) == 0 - def test_remove(self): + def test_remove(self) -> None: _list = self.FrozenList([1]) _list.remove(1) assert len(_list) == 0 - def test_remove_frozen(self): + def test_remove_frozen(self) -> None: _list = self.FrozenList([1]) _list.freeze() with pytest.raises(RuntimeError): _list.remove(1) assert _list == [1] - def test_clear(self): + def test_clear(self) -> None: _list = self.FrozenList([1]) _list.clear() assert len(_list) == 0 - def test_clear_frozen(self): + def test_clear_frozen(self) -> None: _list = self.FrozenList([1]) _list.freeze() with pytest.raises(RuntimeError): _list.clear() assert _list == [1] - def test_extend(self): + def test_extend(self) -> None: _list = self.FrozenList([1]) _list.extend([2]) assert _list == [1, 2] - def test_extend_frozen(self): + def test_extend_frozen(self) -> None: _list = self.FrozenList([1]) _list.freeze() with pytest.raises(RuntimeError): _list.extend([2]) assert _list == [1] - def test_reverse(self): + def test_reverse(self) -> None: _list = self.FrozenList([1, 2]) _list.reverse() assert _list == [2, 1] - def test_reverse_frozen(self): + def test_reverse_frozen(self) -> None: _list = self.FrozenList([1, 2]) _list.freeze() with pytest.raises(RuntimeError): _list.reverse() assert _list == [1, 2] - def test_pop(self): + def test_pop(self) -> None: _list = self.FrozenList([1, 2]) assert _list.pop(0) == 1 assert _list == [2] - def test_pop_default(self): + def test_pop_default(self) -> None: _list = self.FrozenList([1, 2]) assert _list.pop() == 2 assert _list == [1] - def test_pop_frozen(self): + def test_pop_frozen(self) -> None: _list = self.FrozenList([1, 2]) _list.freeze() with pytest.raises(RuntimeError): _list.pop() assert _list == [1, 2] - def test_append(self): + def test_append(self) -> None: _list = self.FrozenList([1, 2]) _list.append(3) assert _list == [1, 2, 3] - def test_append_frozen(self): + def test_append_frozen(self) -> None: _list = self.FrozenList([1, 2]) _list.freeze() with pytest.raises(RuntimeError): _list.append(3) assert _list == [1, 2] - def test_count(self): + def test_count(self) -> None: _list = self.FrozenList([1, 2]) assert _list.count(1) == 1 diff --git a/tests/test_helpers.py b/tests/test_helpers.py index a3dfe9a..130b094 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -1,5 +1,5 @@ import asyncio -import datetime +import base64 import gc import os import platform @@ -11,7 +11,6 @@ from multidict import MultiDict from yarl import URL from aiohttp import helpers -from aiohttp.abc import AbstractAccessLogger IS_PYPY = platform.python_implementation() == 'PyPy' @@ -38,7 +37,7 @@ IS_PYPY = platform.python_implementation() == 'PyPy' ('text/plain;base64', helpers.MimeType('text', 'plain', '', MultiDict({'base64': ''}))) ]) -def test_parse_mimetype(mimetype, expected): +def test_parse_mimetype(mimetype, expected) -> None: result = helpers.parse_mimetype(mimetype) assert isinstance(result, helpers.MimeType) @@ -47,231 +46,111 @@ def test_parse_mimetype(mimetype, expected): # ------------------- guess_filename ---------------------------------- -def test_guess_filename_with_tempfile(): +def test_guess_filename_with_tempfile() -> None: with tempfile.TemporaryFile() as fp: assert (helpers.guess_filename(fp, 'no-throw') is not None) # ------------------- BasicAuth ----------------------------------- -def test_basic_auth1(): +def test_basic_auth1() -> None: # missing password here with pytest.raises(ValueError): helpers.BasicAuth(None) -def test_basic_auth2(): +def test_basic_auth2() -> None: with pytest.raises(ValueError): helpers.BasicAuth('nkim', None) -def test_basic_with_auth_colon_in_login(): +def test_basic_with_auth_colon_in_login() -> None: with pytest.raises(ValueError): helpers.BasicAuth('nkim:1', 'pwd') -def test_basic_auth3(): +def test_basic_auth3() -> None: auth = helpers.BasicAuth('nkim') assert auth.login == 'nkim' assert auth.password == '' -def test_basic_auth4(): +def test_basic_auth4() -> None: auth = helpers.BasicAuth('nkim', 'pwd') assert auth.login == 'nkim' assert auth.password == 'pwd' assert auth.encode() == 'Basic bmtpbTpwd2Q=' -def test_basic_auth_decode(): - auth = helpers.BasicAuth.decode('Basic bmtpbTpwd2Q=') +@pytest.mark.parametrize('header', ( + 'Basic bmtpbTpwd2Q=', + 'basic bmtpbTpwd2Q=', +)) +def test_basic_auth_decode(header) -> None: + auth = helpers.BasicAuth.decode(header) assert auth.login == 'nkim' assert auth.password == 'pwd' -def test_basic_auth_invalid(): +def test_basic_auth_invalid() -> None: with pytest.raises(ValueError): helpers.BasicAuth.decode('bmtpbTpwd2Q=') -def test_basic_auth_decode_not_basic(): +def test_basic_auth_decode_not_basic() -> None: with pytest.raises(ValueError): helpers.BasicAuth.decode('Complex bmtpbTpwd2Q=') -def test_basic_auth_decode_bad_base64(): +def test_basic_auth_decode_bad_base64() -> None: with pytest.raises(ValueError): helpers.BasicAuth.decode('Basic bmtpbTpwd2Q') -def test_basic_auth_from_url(): +@pytest.mark.parametrize('header', ('Basic ???', 'Basic ')) +def test_basic_auth_decode_illegal_chars_base64(header) -> None: + with pytest.raises(ValueError, match='Invalid base64 encoding.'): + helpers.BasicAuth.decode(header) + + +def test_basic_auth_decode_invalid_credentials() -> None: + with pytest.raises(ValueError, match='Invalid credentials.'): + header = 'Basic {}'.format(base64.b64encode(b'username').decode()) + helpers.BasicAuth.decode(header) + + +@pytest.mark.parametrize('credentials, expected_auth', ( + (':', helpers.BasicAuth( + login='', password='', encoding='latin1')), + ('username:', helpers.BasicAuth( + login='username', password='', encoding='latin1')), + (':password', helpers.BasicAuth( + login='', password='password', encoding='latin1')), + ('username:password', helpers.BasicAuth( + login='username', password='password', encoding='latin1')), +)) +def test_basic_auth_decode_blank_username(credentials, expected_auth) -> None: + header = 'Basic {}'.format(base64.b64encode(credentials.encode()).decode()) + assert helpers.BasicAuth.decode(header) == expected_auth + + +def test_basic_auth_from_url() -> None: url = URL('http://user:pass@example.com') auth = helpers.BasicAuth.from_url(url) assert auth.login == 'user' assert auth.password == 'pass' -def test_basic_auth_from_not_url(): +def test_basic_auth_from_not_url() -> None: with pytest.raises(TypeError): helpers.BasicAuth.from_url('http://user:pass@example.com') -# ------------- access logger ------------------------- - - -def test_access_logger_format(): - log_format = '%T "%{ETag}o" %X {X} %%P' - mock_logger = mock.Mock() - access_logger = helpers.AccessLogger(mock_logger, log_format) - expected = '%s "%s" %%X {X} %%%s' - assert expected == access_logger._log_format - - -@pytest.mark.skip( - IS_PYPY, - """ - Because of patching :py:class:`datetime.datetime`, under PyPy it - fails in :py:func:`isinstance` call in - :py:meth:`datetime.datetime.__sub__` (called from - :py:meth:`aiohttp.helpers.AccessLogger._format_t`): - - *** TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types - - (Pdb) from datetime import datetime - (Pdb) isinstance(now, datetime) - *** TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types - (Pdb) datetime.__class__ - <class 'unittest.mock.MagicMock'> - (Pdb) isinstance(now, datetime.__class__) - False - - Ref: https://bitbucket.org/pypy/pypy/issues/1187/call-to-isinstance-in-__sub__-self-other - Ref: https://github.com/celery/celery/issues/811 - Ref: https://stackoverflow.com/a/46102240/595220 - """, # noqa: E501 -) -def test_access_logger_atoms(mocker): - utcnow = datetime.datetime(1843, 1, 1, 0, 30) - mock_datetime = mocker.patch("aiohttp.helpers.datetime.datetime") - mock_getpid = mocker.patch("os.getpid") - mock_datetime.utcnow.return_value = utcnow - mock_getpid.return_value = 42 - log_format = '%a %t %P %r %s %b %T %Tf %D "%{H1}i" "%{H2}i"' - mock_logger = mock.Mock() - access_logger = helpers.AccessLogger(mock_logger, log_format) - request = mock.Mock(headers={'H1': 'a', 'H2': 'b'}, - method="GET", path_qs="/path", - version=(1, 1), - remote="127.0.0.2") - response = mock.Mock(headers={}, body_length=42, status=200) - access_logger.log(request, response, 3.1415926) - assert not mock_logger.exception.called - expected = ('127.0.0.2 [01/Jan/1843:00:29:56 +0000] <42> ' - 'GET /path HTTP/1.1 200 42 3 3.141593 3141593 "a" "b"') - extra = { - 'first_request_line': 'GET /path HTTP/1.1', - 'process_id': '<42>', - 'remote_address': '127.0.0.2', - 'request_start_time': '[01/Jan/1843:00:29:56 +0000]', - 'request_time': 3, - 'request_time_frac': '3.141593', - 'request_time_micro': 3141593, - 'response_size': 42, - 'response_status': 200, - 'request_header': {'H1': 'a', 'H2': 'b'}, - } - - mock_logger.info.assert_called_with(expected, extra=extra) - - -def test_access_logger_dicts(): - log_format = '%{User-Agent}i %{Content-Length}o %{None}i' - mock_logger = mock.Mock() - access_logger = helpers.AccessLogger(mock_logger, log_format) - request = mock.Mock(headers={"User-Agent": "Mock/1.0"}, version=(1, 1), - remote="127.0.0.2") - response = mock.Mock(headers={"Content-Length": 123}) - access_logger.log(request, response, 0.0) - assert not mock_logger.error.called - expected = 'Mock/1.0 123 -' - extra = { - 'request_header': {"User-Agent": "Mock/1.0", 'None': '-'}, - 'response_header': {'Content-Length': 123} - } - - mock_logger.info.assert_called_with(expected, extra=extra) - - -def test_access_logger_unix_socket(): - log_format = '|%a|' - mock_logger = mock.Mock() - access_logger = helpers.AccessLogger(mock_logger, log_format) - request = mock.Mock(headers={"User-Agent": "Mock/1.0"}, version=(1, 1), - remote="") - response = mock.Mock() - access_logger.log(request, response, 0.0) - assert not mock_logger.error.called - expected = '||' - mock_logger.info.assert_called_with(expected, extra={'remote_address': ''}) - - -def test_logger_no_message(): - mock_logger = mock.Mock() - access_logger = helpers.AccessLogger(mock_logger, - "%r %{content-type}i") - extra_dict = { - 'first_request_line': '-', - 'request_header': {'content-type': '(no headers)'} - } - - access_logger.log(None, None, 0.0) - mock_logger.info.assert_called_with("- (no headers)", extra=extra_dict) - - -def test_logger_internal_error(): - mock_logger = mock.Mock() - access_logger = helpers.AccessLogger(mock_logger, "%D") - access_logger.log(None, None, 'invalid') - mock_logger.exception.assert_called_with("Error in logging") - - -def test_logger_no_transport(): - mock_logger = mock.Mock() - access_logger = helpers.AccessLogger(mock_logger, "%a") - access_logger.log(None, None, 0) - mock_logger.info.assert_called_with("-", extra={'remote_address': '-'}) - - -def test_logger_abc(): - class Logger(AbstractAccessLogger): - def log(self, request, response, time): - 1 / 0 - - mock_logger = mock.Mock() - access_logger = Logger(mock_logger, None) - - with pytest.raises(ZeroDivisionError): - access_logger.log(None, None, None) - - class Logger(AbstractAccessLogger): - def log(self, request, response, time): - self.logger.info(self.log_format.format( - request=request, - response=response, - time=time - )) - - mock_logger = mock.Mock() - access_logger = Logger(mock_logger, '{request} {response} {time}') - access_logger.log('request', 'response', 1) - mock_logger.info.assert_called_with('request response 1') - - class ReifyMixin: reify = NotImplemented - def test_reify(self): + def test_reify(self) -> None: class A: def __init__(self): self._cache = {} @@ -283,7 +162,7 @@ class ReifyMixin: a = A() assert 1 == a.prop - def test_reify_class(self): + def test_reify_class(self) -> None: class A: def __init__(self): self._cache = {} @@ -296,7 +175,7 @@ class ReifyMixin: assert isinstance(A.prop, self.reify) assert 'Docstring.' == A.prop.__doc__ - def test_reify_assignment(self): + def test_reify_assignment(self) -> None: class A: def __init__(self): self._cache = {} @@ -322,7 +201,7 @@ if not helpers.NO_EXTENSIONS and not IS_PYPY: # ----------------------------------- is_ip_address() ---------------------- -def test_is_ip_address(): +def test_is_ip_address() -> None: assert helpers.is_ip_address("127.0.0.1") assert helpers.is_ip_address("::1") assert helpers.is_ip_address("FE80:0000:0000:0000:0202:B3FF:FE1E:8329") @@ -340,7 +219,7 @@ def test_is_ip_address(): assert not helpers.is_ip_address("1200::AB00:1234::2552:7777:1313") -def test_is_ip_address_bytes(): +def test_is_ip_address_bytes() -> None: assert helpers.is_ip_address(b"127.0.0.1") assert helpers.is_ip_address(b"::1") assert helpers.is_ip_address(b"FE80:0000:0000:0000:0202:B3FF:FE1E:8329") @@ -358,11 +237,20 @@ def test_is_ip_address_bytes(): assert not helpers.is_ip_address(b"1200::AB00:1234::2552:7777:1313") -def test_ip_addresses(): +def test_ipv4_addresses() -> None: ip_addresses = [ '0.0.0.0', '127.0.0.1', '255.255.255.255', + ] + for address in ip_addresses: + assert helpers.is_ipv4_address(address) + assert not helpers.is_ipv6_address(address) + assert helpers.is_ip_address(address) + + +def test_ipv6_addresses() -> None: + ip_addresses = [ '0:0:0:0:0:0:0:0', 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', '00AB:0002:3008:8CFD:00AB:0002:3008:8CFD', @@ -373,10 +261,12 @@ def test_ip_addresses(): '1::1', ] for address in ip_addresses: + assert not helpers.is_ipv4_address(address) + assert helpers.is_ipv6_address(address) assert helpers.is_ip_address(address) -def test_host_addresses(): +def test_host_addresses() -> None: hosts = [ 'www.four.part.host' 'www.python.org', @@ -387,7 +277,7 @@ def test_host_addresses(): assert not helpers.is_ip_address(host) -def test_is_ip_address_invalid_type(): +def test_is_ip_address_invalid_type() -> None: with pytest.raises(TypeError): helpers.is_ip_address(123) @@ -397,7 +287,7 @@ def test_is_ip_address_invalid_type(): # ----------------------------------- TimeoutHandle ------------------- -def test_timeout_handle(loop): +def test_timeout_handle(loop) -> None: handle = helpers.TimeoutHandle(loop, 10.2) cb = mock.Mock() handle.register(cb) @@ -406,7 +296,7 @@ def test_timeout_handle(loop): assert not handle._callbacks -def test_timeout_handle_cb_exc(loop): +def test_timeout_handle_cb_exc(loop) -> None: handle = helpers.TimeoutHandle(loop, 10.2) cb = mock.Mock() handle.register(cb) @@ -416,7 +306,7 @@ def test_timeout_handle_cb_exc(loop): assert not handle._callbacks -def test_timer_context_cancelled(): +def test_timer_context_cancelled() -> None: with mock.patch('aiohttp.helpers.asyncio') as m_asyncio: m_asyncio.TimeoutError = asyncio.TimeoutError loop = mock.Mock() @@ -433,7 +323,7 @@ def test_timer_context_cancelled(): assert m_asyncio.Task.current_task.return_value.cancel.called -def test_timer_context_no_task(loop): +def test_timer_context_no_task(loop) -> None: with pytest.raises(RuntimeError): with helpers.TimerContext(loop): pass @@ -442,14 +332,14 @@ def test_timer_context_no_task(loop): # -------------------------------- CeilTimeout -------------------------- -async def test_weakref_handle(loop): +async def test_weakref_handle(loop) -> None: cb = mock.Mock() helpers.weakref_handle(cb, 'test', 0.01, loop, False) await asyncio.sleep(0.1, loop=loop) assert cb.test.called -async def test_weakref_handle_weak(loop): +async def test_weakref_handle_weak(loop) -> None: cb = mock.Mock() helpers.weakref_handle(cb, 'test', 0.01, loop, False) del cb @@ -457,7 +347,7 @@ async def test_weakref_handle_weak(loop): await asyncio.sleep(0.1, loop=loop) -def test_ceil_call_later(): +def test_ceil_call_later() -> None: cb = mock.Mock() loop = mock.Mock() loop.time.return_value = 10.1 @@ -465,20 +355,20 @@ def test_ceil_call_later(): loop.call_at.assert_called_with(21.0, cb) -def test_ceil_call_later_no_timeout(): +def test_ceil_call_later_no_timeout() -> None: cb = mock.Mock() loop = mock.Mock() helpers.call_later(cb, 0, loop) assert not loop.call_at.called -async def test_ceil_timeout(loop): +async def test_ceil_timeout(loop) -> None: with helpers.CeilTimeout(None, loop=loop) as timeout: assert timeout._timeout is None assert timeout._cancel_handler is None -def test_ceil_timeout_no_task(loop): +def test_ceil_timeout_no_task(loop) -> None: with pytest.raises(RuntimeError): with helpers.CeilTimeout(10, loop=loop): pass @@ -486,12 +376,12 @@ def test_ceil_timeout_no_task(loop): # -------------------------------- ContentDisposition ------------------- -def test_content_disposition(): +def test_content_disposition() -> None: assert (helpers.content_disposition_header('attachment', foo='bar') == 'attachment; foo="bar"') -def test_content_disposition_bad_type(): +def test_content_disposition_bad_type() -> None: with pytest.raises(ValueError): helpers.content_disposition_header('foo bar') with pytest.raises(ValueError): @@ -502,7 +392,7 @@ def test_content_disposition_bad_type(): helpers.content_disposition_header('') -def test_set_content_disposition_bad_param(): +def test_set_content_disposition_bad_param() -> None: with pytest.raises(ValueError): helpers.content_disposition_header('inline', **{'foo bar': 'baz'}) with pytest.raises(ValueError): @@ -516,7 +406,7 @@ def test_set_content_disposition_bad_param(): # --------------------- proxies_from_env ------------------------------ -def test_proxies_from_env_http(mocker): +def test_proxies_from_env_http(mocker) -> None: url = URL('http://aiohttp.io/path') mocker.patch.dict(os.environ, {'http_proxy': str(url)}) ret = helpers.proxies_from_env() @@ -525,7 +415,7 @@ def test_proxies_from_env_http(mocker): assert ret['http'].proxy_auth is None -def test_proxies_from_env_http_proxy_for_https_proto(mocker): +def test_proxies_from_env_http_proxy_for_https_proto(mocker) -> None: url = URL('http://aiohttp.io/path') mocker.patch.dict(os.environ, {'https_proxy': str(url)}) ret = helpers.proxies_from_env() @@ -534,7 +424,7 @@ def test_proxies_from_env_http_proxy_for_https_proto(mocker): assert ret['https'].proxy_auth is None -def test_proxies_from_env_https_proxy_skipped(mocker): +def test_proxies_from_env_https_proxy_skipped(mocker) -> None: url = URL('https://aiohttp.io/path') mocker.patch.dict(os.environ, {'https_proxy': str(url)}) log = mocker.patch('aiohttp.log.client_logger.warning') @@ -543,7 +433,7 @@ def test_proxies_from_env_https_proxy_skipped(mocker): URL('https://aiohttp.io/path')) -def test_proxies_from_env_http_with_auth(mocker): +def test_proxies_from_env_http_with_auth(mocker) -> None: url = URL('http://user:pass@aiohttp.io/path') mocker.patch.dict(os.environ, {'http_proxy': str(url)}) ret = helpers.proxies_from_env() @@ -554,17 +444,28 @@ def test_proxies_from_env_http_with_auth(mocker): assert proxy_auth.password == 'pass' assert proxy_auth.encoding == 'latin1' +# ------------ get_running_loop --------------------------------- + + +def test_get_running_loop_not_running(loop) -> None: + with pytest.warns(DeprecationWarning): + helpers.get_running_loop() + + +async def test_get_running_loop_ok(loop) -> None: + assert helpers.get_running_loop() is loop + # ------------- set_result / set_exception ---------------------- -async def test_set_result(loop): +async def test_set_result(loop) -> None: fut = loop.create_future() helpers.set_result(fut, 123) assert 123 == await fut -async def test_set_result_cancelled(loop): +async def test_set_result_cancelled(loop) -> None: fut = loop.create_future() fut.cancel() helpers.set_result(fut, 123) @@ -573,14 +474,14 @@ async def test_set_result_cancelled(loop): await fut -async def test_set_exception(loop): +async def test_set_exception(loop) -> None: fut = loop.create_future() helpers.set_exception(fut, RuntimeError()) with pytest.raises(RuntimeError): await fut -async def test_set_exception_cancelled(loop): +async def test_set_exception_cancelled(loop) -> None: fut = loop.create_future() fut.cancel() helpers.set_exception(fut, RuntimeError()) @@ -594,55 +495,55 @@ async def test_set_exception_cancelled(loop): class TestChainMapProxy: @pytest.mark.skipif(not helpers.PY_36, reason="Requires Python 3.6+") - def test_inheritance(self): + def test_inheritance(self) -> None: with pytest.raises(TypeError): class A(helpers.ChainMapProxy): pass - def test_getitem(self): + def test_getitem(self) -> None: d1 = {'a': 2, 'b': 3} d2 = {'a': 1} cp = helpers.ChainMapProxy([d1, d2]) assert cp['a'] == 2 assert cp['b'] == 3 - def test_getitem_not_found(self): + def test_getitem_not_found(self) -> None: d = {'a': 1} cp = helpers.ChainMapProxy([d]) with pytest.raises(KeyError): cp['b'] - def test_get(self): + def test_get(self) -> None: d1 = {'a': 2, 'b': 3} d2 = {'a': 1} cp = helpers.ChainMapProxy([d1, d2]) assert cp.get('a') == 2 - def test_get_default(self): + def test_get_default(self) -> None: d1 = {'a': 2, 'b': 3} d2 = {'a': 1} cp = helpers.ChainMapProxy([d1, d2]) assert cp.get('c', 4) == 4 - def test_get_non_default(self): + def test_get_non_default(self) -> None: d1 = {'a': 2, 'b': 3} d2 = {'a': 1} cp = helpers.ChainMapProxy([d1, d2]) assert cp.get('a', 4) == 2 - def test_len(self): + def test_len(self) -> None: d1 = {'a': 2, 'b': 3} d2 = {'a': 1} cp = helpers.ChainMapProxy([d1, d2]) assert len(cp) == 2 - def test_iter(self): + def test_iter(self) -> None: d1 = {'a': 2, 'b': 3} d2 = {'a': 1} cp = helpers.ChainMapProxy([d1, d2]) assert set(cp) == {'a', 'b'} - def test_contains(self): + def test_contains(self) -> None: d1 = {'a': 2, 'b': 3} d2 = {'a': 1} cp = helpers.ChainMapProxy([d1, d2]) @@ -650,12 +551,12 @@ class TestChainMapProxy: assert 'b' in cp assert 'c' not in cp - def test_bool(self): + def test_bool(self) -> None: assert helpers.ChainMapProxy([{'a': 1}]) assert not helpers.ChainMapProxy([{}, {}]) assert not helpers.ChainMapProxy([]) - def test_repr(self): + def test_repr(self) -> None: d1 = {'a': 2, 'b': 3} d2 = {'a': 1} cp = helpers.ChainMapProxy([d1, d2]) diff --git a/tests/test_http_exceptions.py b/tests/test_http_exceptions.py index bc6994b..2085955 100644 --- a/tests/test_http_exceptions.py +++ b/tests/test_http_exceptions.py @@ -3,17 +3,17 @@ from aiohttp import http_exceptions -def test_bad_status_line1(): +def test_bad_status_line1() -> None: err = http_exceptions.BadStatusLine(b'') assert str(err) == "b''" -def test_bad_status_line2(): +def test_bad_status_line2() -> None: err = http_exceptions.BadStatusLine('Test') assert str(err) == 'Test' -def test_http_error_exception(): +def test_http_error_exception() -> None: exc = http_exceptions.HttpProcessingError( code=500, message='Internal error') assert exc.code == 500 diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py index df4350d..f5c1a88 100644 --- a/tests/test_http_parser.py +++ b/tests/test_http_parser.py @@ -1,5 +1,6 @@ """Tests for aiohttp/protocol.py""" +import asyncio import zlib from unittest import mock @@ -70,7 +71,7 @@ def stream(): return mock.Mock() -def test_parse_headers(parser): +def test_parse_headers(parser) -> None: text = b'''GET /test HTTP/1.1\r test: line\r continue\r @@ -90,7 +91,7 @@ test2: data\r assert not msg.upgrade -def test_parse(parser): +def test_parse(parser) -> None: text = b'GET /test HTTP/1.1\r\n\r\n' messages, upgrade, tail = parser.feed_data(text) assert len(messages) == 1 @@ -102,7 +103,7 @@ def test_parse(parser): assert msg.version == (1, 1) -async def test_parse_body(parser): +async def test_parse_body(parser) -> None: text = b'GET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody' messages, upgrade, tail = parser.feed_data(text) assert len(messages) == 1 @@ -111,7 +112,7 @@ async def test_parse_body(parser): assert body == b'body' -async def test_parse_body_with_CRLF(parser): +async def test_parse_body_with_CRLF(parser) -> None: text = b'\r\nGET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody' messages, upgrade, tail = parser.feed_data(text) assert len(messages) == 1 @@ -120,7 +121,7 @@ async def test_parse_body_with_CRLF(parser): assert body == b'body' -def test_parse_delayed(parser): +def test_parse_delayed(parser) -> None: text = b'GET /test HTTP/1.1\r\n' messages, upgrade, tail = parser.feed_data(text) assert len(messages) == 0 @@ -132,7 +133,7 @@ def test_parse_delayed(parser): assert msg.method == 'GET' -def test_headers_multi_feed(parser): +def test_headers_multi_feed(parser) -> None: text1 = b'GET /test HTTP/1.1\r\n' text2 = b'test: line\r' text3 = b'\n continue\r\n\r\n' @@ -154,7 +155,7 @@ def test_headers_multi_feed(parser): assert not msg.upgrade -def test_headers_split_field(parser): +def test_headers_split_field(parser) -> None: text1 = b'GET /test HTTP/1.1\r\n' text2 = b't' text3 = b'es' @@ -175,7 +176,7 @@ def test_headers_split_field(parser): assert not msg.upgrade -def test_parse_headers_multi(parser): +def test_parse_headers_multi(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'Set-Cookie: c1=cookie1\r\n' b'Set-Cookie: c2=cookie2\r\n\r\n') @@ -192,21 +193,21 @@ def test_parse_headers_multi(parser): assert msg.compression is None -def test_conn_default_1_0(parser): +def test_conn_default_1_0(parser) -> None: text = b'GET /test HTTP/1.0\r\n\r\n' messages, upgrade, tail = parser.feed_data(text) msg = messages[0][0] assert msg.should_close -def test_conn_default_1_1(parser): +def test_conn_default_1_1(parser) -> None: text = b'GET /test HTTP/1.1\r\n\r\n' messages, upgrade, tail = parser.feed_data(text) msg = messages[0][0] assert not msg.should_close -def test_conn_close(parser): +def test_conn_close(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'connection: close\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -214,7 +215,7 @@ def test_conn_close(parser): assert msg.should_close -def test_conn_close_1_0(parser): +def test_conn_close_1_0(parser) -> None: text = (b'GET /test HTTP/1.0\r\n' b'connection: close\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -222,7 +223,7 @@ def test_conn_close_1_0(parser): assert msg.should_close -def test_conn_keep_alive_1_0(parser): +def test_conn_keep_alive_1_0(parser) -> None: text = (b'GET /test HTTP/1.0\r\n' b'connection: keep-alive\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -230,7 +231,7 @@ def test_conn_keep_alive_1_0(parser): assert not msg.should_close -def test_conn_keep_alive_1_1(parser): +def test_conn_keep_alive_1_1(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'connection: keep-alive\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -238,7 +239,7 @@ def test_conn_keep_alive_1_1(parser): assert not msg.should_close -def test_conn_other_1_0(parser): +def test_conn_other_1_0(parser) -> None: text = (b'GET /test HTTP/1.0\r\n' b'connection: test\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -246,7 +247,7 @@ def test_conn_other_1_0(parser): assert msg.should_close -def test_conn_other_1_1(parser): +def test_conn_other_1_1(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'connection: test\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -254,7 +255,7 @@ def test_conn_other_1_1(parser): assert not msg.should_close -def test_request_chunked(parser): +def test_request_chunked(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'transfer-encoding: chunked\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -264,7 +265,7 @@ def test_request_chunked(parser): assert isinstance(payload, streams.StreamReader) -def test_conn_upgrade(parser): +def test_conn_upgrade(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'connection: upgrade\r\n' b'upgrade: websocket\r\n\r\n') @@ -275,7 +276,7 @@ def test_conn_upgrade(parser): assert upgrade -def test_compression_empty(parser): +def test_compression_empty(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'content-encoding: \r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -283,7 +284,7 @@ def test_compression_empty(parser): assert msg.compression is None -def test_compression_deflate(parser): +def test_compression_deflate(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'content-encoding: deflate\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -291,7 +292,7 @@ def test_compression_deflate(parser): assert msg.compression == 'deflate' -def test_compression_gzip(parser): +def test_compression_gzip(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'content-encoding: gzip\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -300,7 +301,7 @@ def test_compression_gzip(parser): @pytest.mark.skipif(brotli is None, reason="brotli is not installed") -def test_compression_brotli(parser): +def test_compression_brotli(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'content-encoding: br\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -308,7 +309,7 @@ def test_compression_brotli(parser): assert msg.compression == 'br' -def test_compression_unknown(parser): +def test_compression_unknown(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'content-encoding: compress\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -316,7 +317,7 @@ def test_compression_unknown(parser): assert msg.compression is None -def test_headers_connect(parser): +def test_headers_connect(parser) -> None: text = (b'CONNECT www.google.com HTTP/1.1\r\n' b'content-length: 0\r\n\r\n') messages, upgrade, tail = parser.feed_data(text) @@ -325,7 +326,7 @@ def test_headers_connect(parser): assert isinstance(payload, streams.StreamReader) -def test_headers_old_websocket_key1(parser): +def test_headers_old_websocket_key1(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'SEC-WEBSOCKET-KEY1: line\r\n\r\n') @@ -333,7 +334,7 @@ def test_headers_old_websocket_key1(parser): parser.feed_data(text) -def test_headers_content_length_err_1(parser): +def test_headers_content_length_err_1(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'content-length: line\r\n\r\n') @@ -341,7 +342,7 @@ def test_headers_content_length_err_1(parser): parser.feed_data(text) -def test_headers_content_length_err_2(parser): +def test_headers_content_length_err_2(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'content-length: -1\r\n\r\n') @@ -349,14 +350,14 @@ def test_headers_content_length_err_2(parser): parser.feed_data(text) -def test_invalid_header(parser): +def test_invalid_header(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'test line\r\n\r\n') with pytest.raises(http_exceptions.BadHttpMessage): parser.feed_data(text) -def test_invalid_name(parser): +def test_invalid_name(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'test[]: line\r\n\r\n') @@ -365,17 +366,17 @@ def test_invalid_name(parser): @pytest.mark.parametrize('size', [40960, 8191]) -def test_max_header_field_size(parser, size): +def test_max_header_field_size(parser, size) -> None: name = b't' * size text = (b'GET /test HTTP/1.1\r\n' + name + b':data\r\n\r\n') - match = ("400, message='Got more than 8190 bytes \({}\) when reading" + match = ("400, message='Got more than 8190 bytes \\({}\\) when reading" .format(size)) with pytest.raises(http_exceptions.LineTooLong, match=match): parser.feed_data(text) -def test_max_header_field_size_under_limit(parser): +def test_max_header_field_size_under_limit(parser) -> None: name = b't' * 8190 text = (b'GET /test HTTP/1.1\r\n' + name + b':data\r\n\r\n') @@ -394,18 +395,18 @@ def test_max_header_field_size_under_limit(parser): @pytest.mark.parametrize('size', [40960, 8191]) -def test_max_header_value_size(parser, size): +def test_max_header_value_size(parser, size) -> None: name = b't' * size text = (b'GET /test HTTP/1.1\r\n' b'data:' + name + b'\r\n\r\n') - match = ("400, message='Got more than 8190 bytes \({}\) when reading" + match = ("400, message='Got more than 8190 bytes \\({}\\) when reading" .format(size)) with pytest.raises(http_exceptions.LineTooLong, match=match): parser.feed_data(text) -def test_max_header_value_size_under_limit(parser): +def test_max_header_value_size_under_limit(parser) -> None: value = b'A' * 8190 text = (b'GET /test HTTP/1.1\r\n' b'data:' + value + b'\r\n\r\n') @@ -425,18 +426,18 @@ def test_max_header_value_size_under_limit(parser): @pytest.mark.parametrize('size', [40965, 8191]) -def test_max_header_value_size_continuation(parser, size): +def test_max_header_value_size_continuation(parser, size) -> None: name = b'T' * (size - 5) text = (b'GET /test HTTP/1.1\r\n' b'data: test\r\n ' + name + b'\r\n\r\n') - match = ("400, message='Got more than 8190 bytes \({}\) when reading" + match = ("400, message='Got more than 8190 bytes \\({}\\) when reading" .format(size)) with pytest.raises(http_exceptions.LineTooLong, match=match): parser.feed_data(text) -def test_max_header_value_size_continuation_under_limit(parser): +def test_max_header_value_size_continuation_under_limit(parser) -> None: value = b'A' * 8185 text = (b'GET /test HTTP/1.1\r\n' b'data: test\r\n ' + value + b'\r\n\r\n') @@ -455,7 +456,7 @@ def test_max_header_value_size_continuation_under_limit(parser): assert msg.url == URL('/test') -def test_http_request_parser(parser): +def test_http_request_parser(parser) -> None: text = b'GET /path HTTP/1.1\r\n\r\n' messages, upgrade, tail = parser.feed_data(text) msg = messages[0][0] @@ -472,13 +473,13 @@ def test_http_request_parser(parser): assert msg.url == URL('/path') -def test_http_request_bad_status_line(parser): +def test_http_request_bad_status_line(parser) -> None: text = b'getpath \r\n\r\n' with pytest.raises(http_exceptions.BadStatusLine): parser.feed_data(text) -def test_http_request_upgrade(parser): +def test_http_request_upgrade(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'connection: upgrade\r\n' b'upgrade: websocket\r\n\r\n' @@ -491,7 +492,7 @@ def test_http_request_upgrade(parser): assert tail == b'some raw data' -def test_http_request_parser_utf8(parser): +def test_http_request_parser_utf8(parser) -> None: text = 'GET /path HTTP/1.1\r\nx-test:тест\r\n\r\n'.encode('utf-8') messages, upgrade, tail = parser.feed_data(text) msg = messages[0][0] @@ -508,7 +509,7 @@ def test_http_request_parser_utf8(parser): assert msg.url == URL('/path') -def test_http_request_parser_non_utf8(parser): +def test_http_request_parser_non_utf8(parser) -> None: text = 'GET /path HTTP/1.1\r\nx-test:тест\r\n\r\n'.encode('cp1251') msg = parser.feed_data(text)[0][0][0] @@ -525,7 +526,7 @@ def test_http_request_parser_non_utf8(parser): assert msg.url == URL('/path') -def test_http_request_parser_two_slashes(parser): +def test_http_request_parser_two_slashes(parser) -> None: text = b'GET //path HTTP/1.1\r\n\r\n' msg = parser.feed_data(text)[0][0][0] @@ -538,27 +539,27 @@ def test_http_request_parser_two_slashes(parser): assert not msg.chunked -def test_http_request_parser_bad_method(parser): +def test_http_request_parser_bad_method(parser) -> None: with pytest.raises(http_exceptions.BadStatusLine): - parser.feed_data(b'!12%()+=~$ /get HTTP/1.1\r\n\r\n') + parser.feed_data(b'=":<G>(e),[T];?" /get HTTP/1.1\r\n\r\n') -def test_http_request_parser_bad_version(parser): +def test_http_request_parser_bad_version(parser) -> None: with pytest.raises(http_exceptions.BadHttpMessage): parser.feed_data(b'GET //get HT/11\r\n\r\n') @pytest.mark.parametrize('size', [40965, 8191]) -def test_http_request_max_status_line(parser, size): +def test_http_request_max_status_line(parser, size) -> None: path = b't' * (size - 5) - match = ("400, message='Got more than 8190 bytes \({}\) when reading" + match = ("400, message='Got more than 8190 bytes \\({}\\) when reading" .format(size)) with pytest.raises(http_exceptions.LineTooLong, match=match): parser.feed_data( b'GET /path' + path + b' HTTP/1.1\r\n\r\n') -def test_http_request_max_status_line_under_limit(parser): +def test_http_request_max_status_line_under_limit(parser) -> None: path = b't' * (8190 - 5) messages, upgraded, tail = parser.feed_data( b'GET /path' + path + b' HTTP/1.1\r\n\r\n') @@ -576,7 +577,7 @@ def test_http_request_max_status_line_under_limit(parser): assert msg.url == URL('/path' + path.decode()) -def test_http_response_parser_utf8(response): +def test_http_response_parser_utf8(response) -> None: text = 'HTTP/1.1 200 Ok\r\nx-test:тест\r\n\r\n'.encode('utf-8') messages, upgraded, tail = response.feed_data(text) @@ -593,16 +594,16 @@ def test_http_response_parser_utf8(response): @pytest.mark.parametrize('size', [40962, 8191]) -def test_http_response_parser_bad_status_line_too_long(response, size): +def test_http_response_parser_bad_status_line_too_long(response, size) -> None: reason = b't' * (size - 2) - match = ("400, message='Got more than 8190 bytes \({}\) when reading" + match = ("400, message='Got more than 8190 bytes \\({}\\) when reading" .format(size)) with pytest.raises(http_exceptions.LineTooLong, match=match): response.feed_data( b'HTTP/1.1 200 Ok' + reason + b'\r\n\r\n') -def test_http_response_parser_status_line_under_limit(response): +def test_http_response_parser_status_line_under_limit(response) -> None: reason = b'O' * 8190 messages, upgraded, tail = response.feed_data( b'HTTP/1.1 200 ' + reason + b'\r\n\r\n') @@ -612,12 +613,12 @@ def test_http_response_parser_status_line_under_limit(response): assert msg.reason == reason.decode() -def test_http_response_parser_bad_version(response): +def test_http_response_parser_bad_version(response) -> None: with pytest.raises(http_exceptions.BadHttpMessage): response.feed_data(b'HT/11 200 Ok\r\n\r\n') -def test_http_response_parser_no_reason(response): +def test_http_response_parser_no_reason(response) -> None: msg = response.feed_data(b'HTTP/1.1 200\r\n\r\n')[0][0][0] assert msg.version == (1, 1) @@ -625,27 +626,27 @@ def test_http_response_parser_no_reason(response): assert not msg.reason -def test_http_response_parser_bad(response): +def test_http_response_parser_bad(response) -> None: with pytest.raises(http_exceptions.BadHttpMessage): response.feed_data(b'HTT/1\r\n\r\n') -def test_http_response_parser_code_under_100(response): +def test_http_response_parser_code_under_100(response) -> None: msg = response.feed_data(b'HTTP/1.1 99 test\r\n\r\n')[0][0][0] assert msg.code == 99 -def test_http_response_parser_code_above_999(response): +def test_http_response_parser_code_above_999(response) -> None: with pytest.raises(http_exceptions.BadHttpMessage): response.feed_data(b'HTTP/1.1 9999 test\r\n\r\n') -def test_http_response_parser_code_not_int(response): +def test_http_response_parser_code_not_int(response) -> None: with pytest.raises(http_exceptions.BadHttpMessage): response.feed_data(b'HTTP/1.1 ttt test\r\n\r\n') -def test_http_request_chunked_payload(parser): +def test_http_request_chunked_payload(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'transfer-encoding: chunked\r\n\r\n') msg, payload = parser.feed_data(text)[0][0] @@ -661,7 +662,7 @@ def test_http_request_chunked_payload(parser): assert payload.is_eof() -def test_http_request_chunked_payload_and_next_message(parser): +def test_http_request_chunked_payload_and_next_message(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'transfer-encoding: chunked\r\n\r\n') msg, payload = parser.feed_data(text)[0][0] @@ -683,7 +684,7 @@ def test_http_request_chunked_payload_and_next_message(parser): assert not payload2.is_eof() -def test_http_request_chunked_payload_chunks(parser): +def test_http_request_chunked_payload_chunks(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'transfer-encoding: chunked\r\n\r\n') msg, payload = parser.feed_data(text)[0][0] @@ -706,7 +707,7 @@ def test_http_request_chunked_payload_chunks(parser): assert payload.is_eof() -def test_parse_chunked_payload_chunk_extension(parser): +def test_parse_chunked_payload_chunk_extension(parser) -> None: text = (b'GET /test HTTP/1.1\r\n' b'transfer-encoding: chunked\r\n\r\n') msg, payload = parser.feed_data(text)[0][0] @@ -727,7 +728,8 @@ def _test_parse_no_length_or_te_on_post(loop, protocol, request_cls): assert payload.is_eof() -def test_parse_payload_response_without_body(loop, protocol, response_cls): +def test_parse_payload_response_without_body(loop, protocol, + response_cls) -> None: parser = response_cls(protocol, loop, response_with_body=False) text = (b'HTTP/1.1 200 Ok\r\n' b'content-length: 10\r\n\r\n') @@ -736,7 +738,7 @@ def test_parse_payload_response_without_body(loop, protocol, response_cls): assert payload.is_eof() -def test_parse_length_payload(response): +def test_parse_length_payload(response) -> None: text = (b'HTTP/1.1 200 Ok\r\n' b'content-length: 4\r\n\r\n') msg, payload = response.feed_data(text)[0][0] @@ -750,13 +752,13 @@ def test_parse_length_payload(response): assert b'data' == b''.join(d for d in payload._buffer) -def test_parse_no_length_payload(parser): +def test_parse_no_length_payload(parser) -> None: text = b'PUT / HTTP/1.1\r\n\r\n' msg, payload = parser.feed_data(text)[0][0] assert payload.is_eof() -def test_partial_url(parser): +def test_partial_url(parser) -> None: messages, upgrade, tail = parser.feed_data(b'GET /te') assert len(messages) == 0 messages, upgrade, tail = parser.feed_data(b'st HTTP/1.1\r\n\r\n') @@ -770,7 +772,7 @@ def test_partial_url(parser): assert payload.is_eof() -def test_url_parse_non_strict_mode(parser): +def test_url_parse_non_strict_mode(parser) -> None: payload = 'GET /test/тест HTTP/1.1\r\n\r\n'.encode('utf-8') messages, upgrade, tail = parser.feed_data(payload) assert len(messages) == 1 @@ -785,8 +787,9 @@ def test_url_parse_non_strict_mode(parser): class TestParsePayload: - def test_parse_eof_payload(self, stream): - out = aiohttp.FlowControlDataQueue(stream) + async def test_parse_eof_payload(self, stream) -> None: + out = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) p = HttpPayloadParser(out, readall=True) p.feed_data(b'data') p.feed_eof() @@ -794,15 +797,17 @@ class TestParsePayload: assert out.is_eof() assert [(bytearray(b'data'), 4)] == list(out._buffer) - def test_parse_no_body(self, stream): - out = aiohttp.FlowControlDataQueue(stream) + async def test_parse_no_body(self, stream) -> None: + out = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) p = HttpPayloadParser(out, method='PUT') assert out.is_eof() assert p.done - def test_parse_length_payload_eof(self, stream): - out = aiohttp.FlowControlDataQueue(stream) + async def test_parse_length_payload_eof(self, stream) -> None: + out = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) p = HttpPayloadParser(out, length=4) p.feed_data(b'da') @@ -810,16 +815,18 @@ class TestParsePayload: with pytest.raises(http_exceptions.ContentLengthError): p.feed_eof() - def test_parse_chunked_payload_size_error(self, stream): - out = aiohttp.FlowControlDataQueue(stream) + async def test_parse_chunked_payload_size_error(self, stream) -> None: + out = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) p = HttpPayloadParser(out, chunked=True) with pytest.raises(http_exceptions.TransferEncodingError): p.feed_data(b'blah\r\n') assert isinstance(out.exception(), http_exceptions.TransferEncodingError) - def test_http_payload_parser_length(self, stream): - out = aiohttp.FlowControlDataQueue(stream) + async def test_http_payload_parser_length(self, stream) -> None: + out = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) p = HttpPayloadParser(out, length=2) eof, tail = p.feed_data(b'1245') assert eof @@ -830,37 +837,41 @@ class TestParsePayload: _comp = zlib.compressobj(wbits=-zlib.MAX_WBITS) _COMPRESSED = b''.join([_comp.compress(b'data'), _comp.flush()]) - def test_http_payload_parser_deflate(self, stream): + async def test_http_payload_parser_deflate(self, stream) -> None: length = len(self._COMPRESSED) - out = aiohttp.FlowControlDataQueue(stream) + out = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) p = HttpPayloadParser( out, length=length, compression='deflate') p.feed_data(self._COMPRESSED) assert b'data' == b''.join(d for d, _ in out._buffer) assert out.is_eof() - def test_http_payload_parser_deflate_no_wbits(self, stream): + async def test_http_payload_parser_deflate_no_wbits(self, stream) -> None: comp = zlib.compressobj() COMPRESSED = b''.join([comp.compress(b'data'), comp.flush()]) length = len(COMPRESSED) - out = aiohttp.FlowControlDataQueue(stream) + out = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) p = HttpPayloadParser( out, length=length, compression='deflate') p.feed_data(COMPRESSED) assert b'data' == b''.join(d for d, _ in out._buffer) assert out.is_eof() - def test_http_payload_parser_length_zero(self, stream): - out = aiohttp.FlowControlDataQueue(stream) + async def test_http_payload_parser_length_zero(self, stream) -> None: + out = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) p = HttpPayloadParser(out, length=0) assert p.done assert out.is_eof() @pytest.mark.skipif(brotli is None, reason="brotli is not installed") - def test_http_payload_brotli(self, stream): + async def test_http_payload_brotli(self, stream) -> None: compressed = brotli.compress(b'brotli data') - out = aiohttp.FlowControlDataQueue(stream) + out = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) p = HttpPayloadParser( out, length=len(compressed), compression='br') p.feed_data(compressed) @@ -870,8 +881,9 @@ class TestParsePayload: class TestDeflateBuffer: - def test_feed_data(self, stream): - buf = aiohttp.FlowControlDataQueue(stream) + async def test_feed_data(self, stream) -> None: + buf = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) dbuf = DeflateBuffer(buf, 'deflate') dbuf.decompressor = mock.Mock() @@ -880,8 +892,9 @@ class TestDeflateBuffer: dbuf.feed_data(b'data', 4) assert [b'line'] == list(d for d, _ in buf._buffer) - def test_feed_data_err(self, stream): - buf = aiohttp.FlowControlDataQueue(stream) + async def test_feed_data_err(self, stream) -> None: + buf = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) dbuf = DeflateBuffer(buf, 'deflate') exc = ValueError() @@ -891,8 +904,9 @@ class TestDeflateBuffer: with pytest.raises(http_exceptions.ContentEncodingError): dbuf.feed_data(b'data', 4) - def test_feed_eof(self, stream): - buf = aiohttp.FlowControlDataQueue(stream) + async def test_feed_eof(self, stream) -> None: + buf = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) dbuf = DeflateBuffer(buf, 'deflate') dbuf.decompressor = mock.Mock() @@ -902,8 +916,9 @@ class TestDeflateBuffer: assert [b'line'] == list(d for d, _ in buf._buffer) assert buf._eof - def test_feed_eof_err_deflate(self, stream): - buf = aiohttp.FlowControlDataQueue(stream) + async def test_feed_eof_err_deflate(self, stream) -> None: + buf = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) dbuf = DeflateBuffer(buf, 'deflate') dbuf.decompressor = mock.Mock() @@ -913,8 +928,9 @@ class TestDeflateBuffer: with pytest.raises(http_exceptions.ContentEncodingError): dbuf.feed_eof() - def test_feed_eof_no_err_gzip(self, stream): - buf = aiohttp.FlowControlDataQueue(stream) + async def test_feed_eof_no_err_gzip(self, stream) -> None: + buf = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) dbuf = DeflateBuffer(buf, 'gzip') dbuf.decompressor = mock.Mock() @@ -924,8 +940,9 @@ class TestDeflateBuffer: dbuf.feed_eof() assert [b'line'] == list(d for d, _ in buf._buffer) - def test_feed_eof_no_err_brotli(self, stream): - buf = aiohttp.FlowControlDataQueue(stream) + async def test_feed_eof_no_err_brotli(self, stream) -> None: + buf = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) dbuf = DeflateBuffer(buf, 'br') dbuf.decompressor = mock.Mock() @@ -935,8 +952,9 @@ class TestDeflateBuffer: dbuf.feed_eof() assert [b'line'] == list(d for d, _ in buf._buffer) - def test_empty_body(self, stream): - buf = aiohttp.FlowControlDataQueue(stream) + async def test_empty_body(self, stream) -> None: + buf = aiohttp.FlowControlDataQueue(stream, + loop=asyncio.get_event_loop()) dbuf = DeflateBuffer(buf, 'deflate') dbuf.feed_eof() diff --git a/tests/test_http_writer.py b/tests/test_http_writer.py index bbbbe7d..7ed385d 100644 --- a/tests/test_http_writer.py +++ b/tests/test_http_writer.py @@ -32,13 +32,14 @@ def protocol(loop, transport): return protocol -def test_payloadwriter_properties(transport, protocol, loop): +def test_payloadwriter_properties(transport, + protocol, loop) -> None: writer = http.StreamWriter(protocol, loop) assert writer.protocol == protocol assert writer.transport == transport -async def test_write_payload_eof(transport, protocol, loop): +async def test_write_payload_eof(transport, protocol, loop) -> None: write = transport.write = mock.Mock() msg = http.StreamWriter(protocol, loop) @@ -50,7 +51,7 @@ async def test_write_payload_eof(transport, protocol, loop): assert b'data1data2' == content.split(b'\r\n\r\n', 1)[-1] -async def test_write_payload_chunked(buf, protocol, transport, loop): +async def test_write_payload_chunked(buf, protocol, transport, loop) -> None: msg = http.StreamWriter(protocol, loop) msg.enable_chunking() await msg.write(b'data') @@ -59,7 +60,9 @@ async def test_write_payload_chunked(buf, protocol, transport, loop): assert b'4\r\ndata\r\n0\r\n\r\n' == buf -async def test_write_payload_chunked_multiple(buf, protocol, transport, loop): +async def test_write_payload_chunked_multiple(buf, + protocol, + transport, loop) -> None: msg = http.StreamWriter(protocol, loop) msg.enable_chunking() await msg.write(b'data1') @@ -69,7 +72,7 @@ async def test_write_payload_chunked_multiple(buf, protocol, transport, loop): assert b'5\r\ndata1\r\n5\r\ndata2\r\n0\r\n\r\n' == buf -async def test_write_payload_length(protocol, transport, loop): +async def test_write_payload_length(protocol, transport, loop) -> None: write = transport.write = mock.Mock() msg = http.StreamWriter(protocol, loop) @@ -82,7 +85,7 @@ async def test_write_payload_length(protocol, transport, loop): assert b'da' == content.split(b'\r\n\r\n', 1)[-1] -async def test_write_payload_chunked_filter(protocol, transport, loop): +async def test_write_payload_chunked_filter(protocol, transport, loop) -> None: write = transport.write = mock.Mock() msg = http.StreamWriter(protocol, loop) @@ -118,7 +121,8 @@ compressor = zlib.compressobj(wbits=-zlib.MAX_WBITS) COMPRESSED = b''.join([compressor.compress(b'data'), compressor.flush()]) -async def test_write_payload_deflate_compression(protocol, transport, loop): +async def test_write_payload_deflate_compression(protocol, + transport, loop) -> None: write = transport.write = mock.Mock() msg = http.StreamWriter(protocol, loop) msg.enable_compression('deflate') @@ -147,7 +151,7 @@ async def test_write_payload_deflate_and_chunked( assert b'6\r\nKI,I\x04\x00\r\n0\r\n\r\n' == buf -async def test_write_drain(protocol, transport, loop): +async def test_write_drain(protocol, transport, loop) -> None: msg = http.StreamWriter(protocol, loop) msg.drain = make_mocked_coro() await msg.write(b'1' * (64 * 1024 * 2), drain=False) @@ -158,7 +162,7 @@ async def test_write_drain(protocol, transport, loop): assert msg.buffer_size == 0 -async def test_write_calls_callback(protocol, transport, loop): +async def test_write_calls_callback(protocol, transport, loop) -> None: on_chunk_sent = make_mocked_coro() msg = http.StreamWriter( protocol, loop, @@ -170,7 +174,7 @@ async def test_write_calls_callback(protocol, transport, loop): assert on_chunk_sent.call_args == mock.call(chunk) -async def test_write_eof_calls_callback(protocol, transport, loop): +async def test_write_eof_calls_callback(protocol, transport, loop) -> None: on_chunk_sent = make_mocked_coro() msg = http.StreamWriter( protocol, loop, @@ -182,7 +186,7 @@ async def test_write_eof_calls_callback(protocol, transport, loop): assert on_chunk_sent.call_args == mock.call(chunk) -async def test_write_to_closing_transport(protocol, transport, loop): +async def test_write_to_closing_transport(protocol, transport, loop) -> None: msg = http.StreamWriter(protocol, loop) await msg.write(b'Before closing') @@ -192,13 +196,13 @@ async def test_write_to_closing_transport(protocol, transport, loop): await msg.write(b'After closing') -async def test_drain(protocol, transport, loop): +async def test_drain(protocol, transport, loop) -> None: msg = http.StreamWriter(protocol, loop) await msg.drain() assert protocol._drain_helper.called -async def test_drain_no_transport(protocol, transport, loop): +async def test_drain_no_transport(protocol, transport, loop) -> None: msg = http.StreamWriter(protocol, loop) msg._protocol.transport = None await msg.drain() diff --git a/tests/test_locks.py b/tests/test_locks.py index 2febb5a..1f90f99 100644 --- a/tests/test_locks.py +++ b/tests/test_locks.py @@ -8,7 +8,7 @@ from aiohttp.locks import EventResultOrError class TestEventResultOrError: - async def test_set_exception(self, loop): + async def test_set_exception(self, loop) -> None: ev = EventResultOrError(loop=loop) async def c(): @@ -24,7 +24,7 @@ class TestEventResultOrError: ev.set(exc=e) assert (await t) == e - async def test_set(self, loop): + async def test_set(self, loop) -> None: ev = EventResultOrError(loop=loop) async def c(): @@ -36,7 +36,7 @@ class TestEventResultOrError: ev.set() assert (await t) == 1 - async def test_cancel_waiters(self, loop): + async def test_cancel_waiters(self, loop) -> None: ev = EventResultOrError(loop=loop) async def c(): diff --git a/tests/test_loop.py b/tests/test_loop.py index 246fe4e..25d36c7 100644 --- a/tests/test_loop.py +++ b/tests/test_loop.py @@ -10,7 +10,7 @@ from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop @pytest.mark.skipif(platform.system() == "Windows", reason="the test is not valid for Windows") -async def test_subprocess_co(loop): +async def test_subprocess_co(loop) -> None: assert isinstance(threading.current_thread(), threading._MainThread) proc = await asyncio.create_subprocess_shell( "exit 0", loop=loop, stdin=asyncio.subprocess.DEVNULL, @@ -25,15 +25,15 @@ class TestCase(AioHTTPTestCase): return app async def on_startup_hook(self, app): - self.startup_loop = app.loop + self.on_startup_called = True @unittest_run_loop - async def test_on_startup_hook(self): - self.assertIsNotNone(self.startup_loop) + async def test_on_startup_hook(self) -> None: + self.assertTrue(self.on_startup_called) - def test_default_loop(self): + def test_default_loop(self) -> None: self.assertIs(self.loop, asyncio.get_event_loop()) -def test_default_loop(loop): +def test_default_loop(loop) -> None: assert asyncio.get_event_loop() is loop diff --git a/tests/test_multipart.py b/tests/test_multipart.py index 7985d1f..d054a64 100644 --- a/tests/test_multipart.py +++ b/tests/test_multipart.py @@ -1,3 +1,4 @@ +import asyncio import io import json import zlib @@ -80,13 +81,13 @@ class StreamWithShortenRead(Stream): class TestMultipartResponseWrapper: - def test_at_eof(self): + def test_at_eof(self) -> None: wrapper = MultipartResponseWrapper(mock.Mock(), mock.Mock()) wrapper.at_eof() assert wrapper.resp.content.at_eof.called - async def test_next(self): + async def test_next(self) -> None: wrapper = MultipartResponseWrapper(mock.Mock(), mock.Mock()) wrapper.stream.next = make_mocked_coro(b'') @@ -94,14 +95,14 @@ class TestMultipartResponseWrapper: await wrapper.next() assert wrapper.stream.next.called - async def test_release(self): + async def test_release(self) -> None: wrapper = MultipartResponseWrapper(mock.Mock(), mock.Mock()) wrapper.resp.release = make_mocked_coro(None) await wrapper.release() assert wrapper.resp.release.called - async def test_release_when_stream_at_eof(self): + async def test_release_when_stream_at_eof(self) -> None: wrapper = MultipartResponseWrapper(mock.Mock(), mock.Mock()) wrapper.resp.release = make_mocked_coro(None) @@ -114,14 +115,14 @@ class TestMultipartResponseWrapper: class TestPartReader: - async def test_next(self): + async def test_next(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream(b'Hello, world!\r\n--:')) result = await obj.next() assert b'Hello, world!' == result assert obj.at_eof() - async def test_next_next(self): + async def test_next_next(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream(b'Hello, world!\r\n--:')) result = await obj.next() @@ -130,21 +131,21 @@ class TestPartReader: result = await obj.next() assert result is None - async def test_read(self): + async def test_read(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream(b'Hello, world!\r\n--:')) result = await obj.read() assert b'Hello, world!' == result assert obj.at_eof() - async def test_read_chunk_at_eof(self): + async def test_read_chunk_at_eof(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream(b'--:')) obj._at_eof = True result = await obj.read_chunk() assert b'' == result - async def test_read_chunk_without_content_length(self): + async def test_read_chunk_without_content_length(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream(b'Hello, world!\r\n--:')) c1 = await obj.read_chunk(8) @@ -153,7 +154,8 @@ class TestPartReader: assert c1 + c2 == b'Hello, world!' assert c3 == b'' - async def test_read_incomplete_chunk(self, loop): + async def test_read_incomplete_chunk(self) -> None: + loop = asyncio.get_event_loop() stream = Stream(b'') def prepare(data): @@ -176,7 +178,7 @@ class TestPartReader: c3 = await obj.read_chunk(8) assert c3 == b'!' - async def test_read_all_at_once(self): + async def test_read_all_at_once(self) -> None: stream = Stream(b'Hello, World!\r\n--:--\r\n') obj = aiohttp.BodyPartReader(BOUNDARY, {}, stream) result = await obj.read_chunk() @@ -185,7 +187,7 @@ class TestPartReader: assert b'' == result assert obj.at_eof() - async def test_read_incomplete_body_chunked(self): + async def test_read_incomplete_body_chunked(self) -> None: stream = Stream(b'Hello, World!\r\n-') obj = aiohttp.BodyPartReader(BOUNDARY, {}, stream) result = b'' @@ -194,7 +196,8 @@ class TestPartReader: result += await obj.read_chunk(7) assert b'Hello, World!\r\n-' == result - async def test_read_boundary_with_incomplete_chunk(self, loop): + async def test_read_boundary_with_incomplete_chunk(self) -> None: + loop = asyncio.get_event_loop() stream = Stream(b'') def prepare(data): @@ -217,7 +220,7 @@ class TestPartReader: c3 = await obj.read_chunk(8) assert c3 == b'' - async def test_multi_read_chunk(self): + async def test_multi_read_chunk(self) -> None: stream = Stream(b'Hello,\r\n--:\r\n\r\nworld!\r\n--:--') obj = aiohttp.BodyPartReader(BOUNDARY, {}, stream) result = await obj.read_chunk(8) @@ -226,7 +229,7 @@ class TestPartReader: assert b'' == result assert obj.at_eof() - async def test_read_chunk_properly_counts_read_bytes(self): + async def test_read_chunk_properly_counts_read_bytes(self) -> None: expected = b'.' * 10 size = len(expected) obj = aiohttp.BodyPartReader( @@ -242,7 +245,7 @@ class TestPartReader: assert b'.' * size == result assert obj.at_eof() - async def test_read_does_not_read_boundary(self): + async def test_read_does_not_read_boundary(self) -> None: stream = Stream(b'Hello, world!\r\n--:') obj = aiohttp.BodyPartReader( BOUNDARY, {}, stream) @@ -250,7 +253,7 @@ class TestPartReader: assert b'Hello, world!' == result assert b'--:' == (await stream.read()) - async def test_multiread(self): + async def test_multiread(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream(b'Hello,\r\n--:\r\n\r\nworld!\r\n--:--')) result = await obj.read() @@ -259,7 +262,7 @@ class TestPartReader: assert b'' == result assert obj.at_eof() - async def test_read_multiline(self): + async def test_read_multiline(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream(b'Hello\n,\r\nworld!\r\n--:--')) result = await obj.read() @@ -268,7 +271,7 @@ class TestPartReader: assert b'' == result assert obj.at_eof() - async def test_read_respects_content_length(self): + async def test_read_respects_content_length(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {'CONTENT-LENGTH': 100500}, Stream(b'.' * 100500 + b'\r\n--:--')) @@ -276,7 +279,7 @@ class TestPartReader: assert b'.' * 100500 == result assert obj.at_eof() - async def test_read_with_content_encoding_gzip(self): + async def test_read_with_content_encoding_gzip(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_ENCODING: 'gzip'}, Stream(b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\x0b\xc9\xccMU' @@ -285,14 +288,14 @@ class TestPartReader: result = await obj.read(decode=True) assert b'Time to Relax!' == result - async def test_read_with_content_encoding_deflate(self): + async def test_read_with_content_encoding_deflate(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_ENCODING: 'deflate'}, Stream(b'\x0b\xc9\xccMU(\xc9W\x08J\xcdI\xacP\x04\x00\r\n--:--')) result = await obj.read(decode=True) assert b'Time to Relax!' == result - async def test_read_with_content_encoding_identity(self): + async def test_read_with_content_encoding_identity(self) -> None: thing = (b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\x0b\xc9\xccMU' b'(\xc9W\x08J\xcdI\xacP\x04\x00$\xfb\x9eV\x0e\x00\x00\x00' b'\r\n') @@ -302,21 +305,22 @@ class TestPartReader: result = await obj.read(decode=True) assert thing[:-2] == result - async def test_read_with_content_encoding_unknown(self): + async def test_read_with_content_encoding_unknown(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_ENCODING: 'snappy'}, Stream(b'\x0e4Time to Relax!\r\n--:--')) with pytest.raises(RuntimeError): await obj.read(decode=True) - async def test_read_with_content_transfer_encoding_base64(self): + async def test_read_with_content_transfer_encoding_base64(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TRANSFER_ENCODING: 'base64'}, Stream(b'VGltZSB0byBSZWxheCE=\r\n--:--')) result = await obj.read(decode=True) assert b'Time to Relax!' == result - async def test_read_with_content_transfer_encoding_quoted_printable(self): + async def test_read_with_content_transfer_encoding_quoted_printable( + self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TRANSFER_ENCODING: 'quoted-printable'}, Stream(b'=D0=9F=D1=80=D0=B8=D0=B2=D0=B5=D1=82,' @@ -327,7 +331,8 @@ class TestPartReader: assert result == expected @pytest.mark.parametrize('encoding', ('binary', '8bit', '7bit')) - async def test_read_with_content_transfer_encoding_binary(self, encoding): + async def test_read_with_content_transfer_encoding_binary( + self, encoding) -> None: data = b'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82,' \ b' \xd0\xbc\xd0\xb8\xd1\x80!' obj = aiohttp.BodyPartReader( @@ -336,41 +341,41 @@ class TestPartReader: result = await obj.read(decode=True) assert data == result - async def test_read_with_content_transfer_encoding_unknown(self): + async def test_read_with_content_transfer_encoding_unknown(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TRANSFER_ENCODING: 'unknown'}, Stream(b'\x0e4Time to Relax!\r\n--:--')) with pytest.raises(RuntimeError): await obj.read(decode=True) - async def test_read_text(self): + async def test_read_text(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream(b'Hello, world!\r\n--:--')) result = await obj.text() assert 'Hello, world!' == result - async def test_read_text_default_encoding(self): + async def test_read_text_default_encoding(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream('Привет, Мир!\r\n--:--'.encode('utf-8'))) result = await obj.text() assert 'Привет, Мир!' == result - async def test_read_text_encoding(self): + async def test_read_text_encoding(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream('Привет, Мир!\r\n--:--'.encode('cp1251'))) result = await obj.text(encoding='cp1251') assert 'Привет, Мир!' == result - async def test_read_text_guess_encoding(self): + async def test_read_text_guess_encoding(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TYPE: 'text/plain;charset=cp1251'}, Stream('Привет, Мир!\r\n--:--'.encode('cp1251'))) result = await obj.text() assert 'Привет, Мир!' == result - async def test_read_text_compressed(self): + async def test_read_text_compressed(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_ENCODING: 'deflate', CONTENT_TYPE: 'text/plain'}, @@ -378,35 +383,35 @@ class TestPartReader: result = await obj.text() assert 'Time to Relax!' == result - async def test_read_text_while_closed(self): + async def test_read_text_while_closed(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TYPE: 'text/plain'}, Stream(b'')) obj._at_eof = True result = await obj.text() assert '' == result - async def test_read_json(self): + async def test_read_json(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TYPE: 'application/json'}, Stream(b'{"test": "passed"}\r\n--:--')) result = await obj.json() assert {'test': 'passed'} == result - async def test_read_json_encoding(self): + async def test_read_json_encoding(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TYPE: 'application/json'}, Stream('{"тест": "пассед"}\r\n--:--'.encode('cp1251'))) result = await obj.json(encoding='cp1251') assert {'тест': 'пассед'} == result - async def test_read_json_guess_encoding(self): + async def test_read_json_guess_encoding(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TYPE: 'application/json; charset=cp1251'}, Stream('{"тест": "пассед"}\r\n--:--'.encode('cp1251'))) result = await obj.json() assert {'тест': 'пассед'} == result - async def test_read_json_compressed(self): + async def test_read_json_compressed(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_ENCODING: 'deflate', CONTENT_TYPE: 'application/json'}, @@ -414,7 +419,7 @@ class TestPartReader: result = await obj.json() assert {'test': 'passed'} == result - async def test_read_json_while_closed(self): + async def test_read_json_while_closed(self) -> None: stream = Stream(b'') obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TYPE: 'application/json'}, stream) @@ -422,21 +427,21 @@ class TestPartReader: result = await obj.json() assert result is None - async def test_read_form(self): + async def test_read_form(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TYPE: 'application/x-www-form-urlencoded'}, Stream(b'foo=bar&foo=baz&boo=\r\n--:--')) result = await obj.form() assert [('foo', 'bar'), ('foo', 'baz'), ('boo', '')] == result - async def test_read_form_encoding(self): + async def test_read_form_encoding(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TYPE: 'application/x-www-form-urlencoded'}, Stream('foo=bar&foo=baz&boo=\r\n--:--'.encode('cp1251'))) result = await obj.form(encoding='cp1251') assert [('foo', 'bar'), ('foo', 'baz'), ('boo', '')] == result - async def test_read_form_guess_encoding(self): + async def test_read_form_guess_encoding(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TYPE: 'application/x-www-form-urlencoded; charset=utf-8'}, @@ -444,16 +449,16 @@ class TestPartReader: result = await obj.form() assert [('foo', 'bar'), ('foo', 'baz'), ('boo', '')] == result - async def test_read_form_while_closed(self): + async def test_read_form_while_closed(self) -> None: stream = Stream(b'') obj = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_TYPE: 'application/x-www-form-urlencoded'}, stream) obj._at_eof = True result = await obj.form() - assert result is None + assert not result - async def test_readline(self): + async def test_readline(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {}, Stream(b'Hello\n,\r\nworld!\r\n--:--')) result = await obj.readline() @@ -466,7 +471,7 @@ class TestPartReader: assert b'' == result assert obj.at_eof() - async def test_release(self): + async def test_release(self) -> None: stream = Stream(b'Hello,\r\n--:\r\n\r\nworld!\r\n--:--') obj = aiohttp.BodyPartReader( BOUNDARY, {}, stream) @@ -474,7 +479,7 @@ class TestPartReader: assert obj.at_eof() assert b'--:\r\n\r\nworld!\r\n--:--' == stream.content.read() - async def test_release_respects_content_length(self): + async def test_release_respects_content_length(self) -> None: obj = aiohttp.BodyPartReader( BOUNDARY, {'CONTENT-LENGTH': 100500}, Stream(b'.' * 100500 + b'\r\n--:--')) @@ -482,7 +487,7 @@ class TestPartReader: assert result is None assert obj.at_eof() - async def test_release_release(self): + async def test_release_release(self) -> None: stream = Stream(b'Hello,\r\n--:\r\n\r\nworld!\r\n--:--') obj = aiohttp.BodyPartReader( BOUNDARY, {}, stream) @@ -490,14 +495,14 @@ class TestPartReader: await obj.release() assert b'--:\r\n\r\nworld!\r\n--:--' == stream.content.read() - async def test_filename(self): + async def test_filename(self) -> None: part = aiohttp.BodyPartReader( BOUNDARY, {CONTENT_DISPOSITION: 'attachment; filename=foo.html'}, None) assert 'foo.html' == part.filename - async def test_reading_long_part(self): + async def test_reading_long_part(self) -> None: size = 2 * stream_reader_default_limit protocol = mock.Mock(_reading_paused=False) stream = StreamReader(protocol) @@ -511,7 +516,7 @@ class TestPartReader: class TestMultipartReader: - def test_from_response(self): + def test_from_response(self) -> None: resp = Response({CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\nhello\r\n--:--')) res = aiohttp.MultipartReader.from_response(resp) @@ -520,28 +525,28 @@ class TestMultipartReader: assert isinstance(res.stream, aiohttp.MultipartReader) - def test_bad_boundary(self): + def test_bad_boundary(self) -> None: resp = Response( {CONTENT_TYPE: 'multipart/related;boundary=' + 'a' * 80}, Stream(b'')) with pytest.raises(ValueError): aiohttp.MultipartReader.from_response(resp) - def test_dispatch(self): + def test_dispatch(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\necho\r\n--:--')) res = reader._get_part_reader({CONTENT_TYPE: 'text/plain'}) assert isinstance(res, reader.part_reader_cls) - def test_dispatch_bodypart(self): + def test_dispatch_bodypart(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\necho\r\n--:--')) res = reader._get_part_reader({CONTENT_TYPE: 'text/plain'}) assert isinstance(res, reader.part_reader_cls) - def test_dispatch_multipart(self): + def test_dispatch_multipart(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'----:--\r\n' @@ -556,7 +561,7 @@ class TestMultipartReader: {CONTENT_TYPE: 'multipart/related;boundary=--:--'}) assert isinstance(res, reader.__class__) - def test_dispatch_custom_multipart_reader(self): + def test_dispatch_custom_multipart_reader(self) -> None: class CustomReader(aiohttp.MultipartReader): pass reader = aiohttp.MultipartReader( @@ -574,21 +579,21 @@ class TestMultipartReader: {CONTENT_TYPE: 'multipart/related;boundary=--:--'}) assert isinstance(res, CustomReader) - async def test_emit_next(self): + async def test_emit_next(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\necho\r\n--:--')) res = await reader.next() assert isinstance(res, reader.part_reader_cls) - async def test_invalid_boundary(self): + async def test_invalid_boundary(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'---:\r\n\r\necho\r\n---:--')) with pytest.raises(ValueError): await reader.next() - async def test_release(self): + async def test_release(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/mixed;boundary=":"'}, Stream(b'--:\r\n' @@ -606,7 +611,7 @@ class TestMultipartReader: await reader.release() assert reader.at_eof() - async def test_release_release(self): + async def test_release_release(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\necho\r\n--:--')) @@ -615,7 +620,7 @@ class TestMultipartReader: await reader.release() assert reader.at_eof() - async def test_release_next(self): + async def test_release_next(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\necho\r\n--:--')) @@ -624,7 +629,7 @@ class TestMultipartReader: res = await reader.next() assert res is None - async def test_second_next_releases_previous_object(self): + async def test_second_next_releases_previous_object(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n' @@ -640,7 +645,7 @@ class TestMultipartReader: assert first.at_eof() assert not second.at_eof() - async def test_release_without_read_the_last_object(self): + async def test_release_without_read_the_last_object(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n' @@ -658,7 +663,7 @@ class TestMultipartReader: assert second.at_eof() assert third is None - async def test_read_chunk_by_length_doesnt_breaks_reader(self): + async def test_read_chunk_by_length_doesnt_breaks_reader(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n' @@ -679,7 +684,7 @@ class TestMultipartReader: body_parts.append(read_part) assert body_parts == [b'test', b'passed'] - async def test_read_chunk_from_stream_doesnt_breaks_reader(self): + async def test_read_chunk_from_stream_doesnt_breaks_reader(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n' @@ -702,7 +707,7 @@ class TestMultipartReader: body_parts.append(read_part) assert body_parts == [b'chunk', b'two_chunks'] - async def test_reading_skips_prelude(self): + async def test_reading_skips_prelude(self) -> None: reader = aiohttp.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'Multi-part data is not supported.\r\n' @@ -721,12 +726,12 @@ class TestMultipartReader: assert not second.at_eof() -async def test_writer(writer): +async def test_writer(writer) -> None: assert writer.size == 0 assert writer.boundary == ':' -async def test_writer_serialize_io_chunk(buf, stream, writer): +async def test_writer_serialize_io_chunk(buf, stream, writer) -> None: flo = io.BytesIO(b'foobarbaz') writer.append(flo) await writer.write(stream) @@ -734,14 +739,14 @@ async def test_writer_serialize_io_chunk(buf, stream, writer): b'\r\nContent-Length: 9\r\n\r\nfoobarbaz\r\n--:--\r\n') -async def test_writer_serialize_json(buf, stream, writer): +async def test_writer_serialize_json(buf, stream, writer) -> None: writer.append_json({'привет': 'мир'}) await writer.write(stream) assert (b'{"\\u043f\\u0440\\u0438\\u0432\\u0435\\u0442":' b' "\\u043c\\u0438\\u0440"}' in buf) -async def test_writer_serialize_form(buf, stream, writer): +async def test_writer_serialize_form(buf, stream, writer) -> None: data = [('foo', 'bar'), ('foo', 'baz'), ('boo', 'zoo')] writer.append_form(data) await writer.write(stream) @@ -749,7 +754,7 @@ async def test_writer_serialize_form(buf, stream, writer): assert (b'foo=bar&foo=baz&boo=zoo' in buf) -async def test_writer_serialize_form_dict(buf, stream, writer): +async def test_writer_serialize_form_dict(buf, stream, writer) -> None: data = {'hello': 'мир'} writer.append_form(data) await writer.write(stream) @@ -757,7 +762,7 @@ async def test_writer_serialize_form_dict(buf, stream, writer): assert (b'hello=%D0%BC%D0%B8%D1%80' in buf) -async def test_writer_write(buf, stream, writer): +async def test_writer_write(buf, stream, writer) -> None: writer.append('foo-bar-baz') writer.append_json({'test': 'passed'}) writer.append_form({'test': 'passed'}) @@ -806,7 +811,7 @@ async def test_writer_write(buf, stream, writer): b'--:--\r\n') == bytes(buf)) -async def test_writer_write_no_close_boundary(buf, stream): +async def test_writer_write_no_close_boundary(buf, stream) -> None: writer = aiohttp.MultipartWriter(boundary=':') writer.append('foo-bar-baz') writer.append_json({'test': 'passed'}) @@ -915,64 +920,64 @@ async def test_writer_content_transfer_encoding_quote_printable(buf, stream, b' =D0=BC=D0=B8=D1=80!' == message.split(b'\r\n')[0]) -def test_writer_content_transfer_encoding_unknown(buf, stream, writer): +def test_writer_content_transfer_encoding_unknown(buf, stream, writer) -> None: with pytest.raises(RuntimeError): writer.append('Time to Relax!', {CONTENT_TRANSFER_ENCODING: 'unknown'}) class TestMultipartWriter: - def test_default_subtype(self, writer): + def test_default_subtype(self, writer) -> None: mimetype = parse_mimetype(writer.headers.get(CONTENT_TYPE)) assert 'multipart' == mimetype.type assert 'mixed' == mimetype.subtype - def test_unquoted_boundary(self): + def test_unquoted_boundary(self) -> None: writer = aiohttp.MultipartWriter(boundary='abc123') expected = {CONTENT_TYPE: 'multipart/mixed; boundary=abc123'} assert expected == writer.headers - def test_quoted_boundary(self): + def test_quoted_boundary(self) -> None: writer = aiohttp.MultipartWriter(boundary=R'\"') expected = {CONTENT_TYPE: R'multipart/mixed; boundary="\\\""'} assert expected == writer.headers - def test_bad_boundary(self): + def test_bad_boundary(self) -> None: with pytest.raises(ValueError): aiohttp.MultipartWriter(boundary='тест') with pytest.raises(ValueError): aiohttp.MultipartWriter(boundary='test\n') - def test_default_headers(self, writer): + def test_default_headers(self, writer) -> None: expected = {CONTENT_TYPE: 'multipart/mixed; boundary=":"'} assert expected == writer.headers - def test_iter_parts(self, writer): + def test_iter_parts(self, writer) -> None: writer.append('foo') writer.append('bar') writer.append('baz') assert 3 == len(list(writer)) - def test_append(self, writer): + def test_append(self, writer) -> None: assert 0 == len(writer) writer.append('hello, world!') assert 1 == len(writer) assert isinstance(writer._parts[0][0], payload.Payload) - def test_append_with_headers(self, writer): + def test_append_with_headers(self, writer) -> None: writer.append('hello, world!', {'x-foo': 'bar'}) assert 1 == len(writer) assert 'x-foo' in writer._parts[0][0].headers assert writer._parts[0][0].headers['x-foo'] == 'bar' - def test_append_json(self, writer): + def test_append_json(self, writer) -> None: writer.append_json({'foo': 'bar'}) assert 1 == len(writer) part = writer._parts[0][0] assert part.headers[CONTENT_TYPE] == 'application/json' - def test_append_part(self, writer): + def test_append_part(self, writer) -> None: part = payload.get_payload( 'test', headers={CONTENT_TYPE: 'text/plain'}) writer.append(part, {CONTENT_TYPE: 'test/passed'}) @@ -980,19 +985,19 @@ class TestMultipartWriter: part = writer._parts[0][0] assert part.headers[CONTENT_TYPE] == 'test/passed' - def test_append_json_overrides_content_type(self, writer): + def test_append_json_overrides_content_type(self, writer) -> None: writer.append_json({'foo': 'bar'}, {CONTENT_TYPE: 'test/passed'}) assert 1 == len(writer) part = writer._parts[0][0] assert part.headers[CONTENT_TYPE] == 'test/passed' - def test_append_form(self, writer): + def test_append_form(self, writer) -> None: writer.append_form({'foo': 'bar'}, {CONTENT_TYPE: 'test/passed'}) assert 1 == len(writer) part = writer._parts[0][0] assert part.headers[CONTENT_TYPE] == 'test/passed' - def test_append_multipart(self, writer): + def test_append_multipart(self, writer) -> None: subwriter = aiohttp.MultipartWriter(boundary=':') subwriter.append_json({'foo': 'bar'}) writer.append(subwriter, {CONTENT_TYPE: 'test/passed'}) @@ -1000,33 +1005,33 @@ class TestMultipartWriter: part = writer._parts[0][0] assert part.headers[CONTENT_TYPE] == 'test/passed' - async def test_write(self, writer, stream): + async def test_write(self, writer, stream) -> None: await writer.write(stream) - def test_with(self): + def test_with(self) -> None: with aiohttp.MultipartWriter(boundary=':') as writer: writer.append('foo') writer.append(b'bar') writer.append_json({'baz': True}) assert 3 == len(writer) - def test_append_int_not_allowed(self): + def test_append_int_not_allowed(self) -> None: with pytest.raises(TypeError): with aiohttp.MultipartWriter(boundary=':') as writer: writer.append(1) - def test_append_float_not_allowed(self): + def test_append_float_not_allowed(self) -> None: with pytest.raises(TypeError): with aiohttp.MultipartWriter(boundary=':') as writer: writer.append(1.1) - def test_append_none_not_allowed(self): + def test_append_none_not_allowed(self) -> None: with pytest.raises(TypeError): with aiohttp.MultipartWriter(boundary=':') as writer: writer.append(None) -async def test_async_for_reader(loop): +async def test_async_for_reader() -> None: data = [ {"test": "passed"}, 42, @@ -1086,7 +1091,7 @@ async def test_async_for_reader(loop): await check(reader) -async def test_async_for_bodypart(loop): +async def test_async_for_bodypart() -> None: part = aiohttp.BodyPartReader( boundary=b'--:', headers={}, diff --git a/tests/test_multipart_helpers.py b/tests/test_multipart_helpers.py index 8a9ee92..296eba3 100644 --- a/tests/test_multipart_helpers.py +++ b/tests/test_multipart_helpers.py @@ -7,419 +7,419 @@ from aiohttp import content_disposition_filename, parse_content_disposition class TestParseContentDisposition: # http://greenbytes.de/tech/tc2231/ - def test_parse_empty(self): + def test_parse_empty(self) -> None: disptype, params = parse_content_disposition(None) assert disptype is None assert {} == params - def test_inlonly(self): + def test_inlonly(self) -> None: disptype, params = parse_content_disposition('inline') assert 'inline' == disptype assert {} == params - def test_inlonlyquoted(self): + def test_inlonlyquoted(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition('"inline"') assert disptype is None assert {} == params - def test_semicolon(self): + def test_semicolon(self) -> None: disptype, params = parse_content_disposition( 'form-data; name="data"; filename="file ; name.mp4"') assert disptype == 'form-data' assert params == {'name': 'data', 'filename': 'file ; name.mp4'} - def test_inlwithasciifilename(self): + def test_inlwithasciifilename(self) -> None: disptype, params = parse_content_disposition( 'inline; filename="foo.html"') assert 'inline' == disptype assert {'filename': 'foo.html'} == params - def test_inlwithfnattach(self): + def test_inlwithfnattach(self) -> None: disptype, params = parse_content_disposition( 'inline; filename="Not an attachment!"') assert 'inline' == disptype assert {'filename': 'Not an attachment!'} == params - def test_attonly(self): + def test_attonly(self) -> None: disptype, params = parse_content_disposition('attachment') assert 'attachment' == disptype assert {} == params - def test_attonlyquoted(self): + def test_attonlyquoted(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition('"attachment"') assert disptype is None assert {} == params - def test_attonlyucase(self): + def test_attonlyucase(self) -> None: disptype, params = parse_content_disposition('ATTACHMENT') assert 'attachment' == disptype assert {} == params - def test_attwithasciifilename(self): + def test_attwithasciifilename(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="foo.html"') assert 'attachment' == disptype assert {'filename': 'foo.html'} == params - def test_inlwithasciifilenamepdf(self): + def test_inlwithasciifilenamepdf(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="foo.pdf"') assert 'attachment' == disptype assert {'filename': 'foo.pdf'} == params - def test_attwithasciifilename25(self): + def test_attwithasciifilename25(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="0000000000111111111122222"') assert 'attachment' == disptype assert {'filename': '0000000000111111111122222'} == params - def test_attwithasciifilename35(self): + def test_attwithasciifilename35(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="00000000001111111111222222222233333"') assert 'attachment' == disptype assert {'filename': '00000000001111111111222222222233333'} == params - def test_attwithasciifnescapedchar(self): + def test_attwithasciifnescapedchar(self) -> None: disptype, params = parse_content_disposition( r'attachment; filename="f\oo.html"') assert 'attachment' == disptype assert {'filename': 'foo.html'} == params - def test_attwithasciifnescapedquote(self): + def test_attwithasciifnescapedquote(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="\"quoting\" tested.html"') assert 'attachment' == disptype assert {'filename': '"quoting" tested.html'} == params @pytest.mark.skip('need more smart parser which respects quoted text') - def test_attwithquotedsemicolon(self): + def test_attwithquotedsemicolon(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="Here\'s a semicolon;.html"') assert 'attachment' == disptype assert {'filename': 'Here\'s a semicolon;.html'} == params - def test_attwithfilenameandextparam(self): + def test_attwithfilenameandextparam(self) -> None: disptype, params = parse_content_disposition( 'attachment; foo="bar"; filename="foo.html"') assert 'attachment' == disptype assert {'filename': 'foo.html', 'foo': 'bar'} == params - def test_attwithfilenameandextparamescaped(self): + def test_attwithfilenameandextparamescaped(self) -> None: disptype, params = parse_content_disposition( 'attachment; foo="\"\\";filename="foo.html"') assert 'attachment' == disptype assert {'filename': 'foo.html', 'foo': '"\\'} == params - def test_attwithasciifilenameucase(self): + def test_attwithasciifilenameucase(self) -> None: disptype, params = parse_content_disposition( 'attachment; FILENAME="foo.html"') assert 'attachment' == disptype assert {'filename': 'foo.html'} == params - def test_attwithasciifilenamenq(self): + def test_attwithasciifilenamenq(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename=foo.html') assert 'attachment' == disptype assert {'filename': 'foo.html'} == params - def test_attwithtokfncommanq(self): + def test_attwithtokfncommanq(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo,bar.html') assert disptype is None assert {} == params - def test_attwithasciifilenamenqs(self): + def test_attwithasciifilenamenqs(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo.html ;') assert disptype is None assert {} == params - def test_attemptyparam(self): + def test_attemptyparam(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; ;filename=foo') assert disptype is None assert {} == params - def test_attwithasciifilenamenqws(self): + def test_attwithasciifilenamenqws(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo bar.html') assert disptype is None assert {} == params - def test_attwithfntokensq(self): + def test_attwithfntokensq(self) -> None: disptype, params = parse_content_disposition( "attachment; filename='foo.html'") assert 'attachment' == disptype assert {'filename': "'foo.html'"} == params - def test_attwithisofnplain(self): + def test_attwithisofnplain(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="foo-ä.html"') assert 'attachment' == disptype assert {'filename': 'foo-ä.html'} == params - def test_attwithutf8fnplain(self): + def test_attwithutf8fnplain(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="foo-ä.html"') assert 'attachment' == disptype assert {'filename': 'foo-ä.html'} == params - def test_attwithfnrawpctenca(self): + def test_attwithfnrawpctenca(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="foo-%41.html"') assert 'attachment' == disptype assert {'filename': 'foo-%41.html'} == params - def test_attwithfnusingpct(self): + def test_attwithfnusingpct(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="50%.html"') assert 'attachment' == disptype assert {'filename': '50%.html'} == params - def test_attwithfnrawpctencaq(self): + def test_attwithfnrawpctencaq(self) -> None: disptype, params = parse_content_disposition( r'attachment; filename="foo-%\41.html"') assert 'attachment' == disptype assert {'filename': r'foo-%41.html'} == params - def test_attwithnamepct(self): + def test_attwithnamepct(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="foo-%41.html"') assert 'attachment' == disptype assert {'filename': 'foo-%41.html'} == params - def test_attwithfilenamepctandiso(self): + def test_attwithfilenamepctandiso(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="ä-%41.html"') assert 'attachment' == disptype assert {'filename': 'ä-%41.html'} == params - def test_attwithfnrawpctenclong(self): + def test_attwithfnrawpctenclong(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="foo-%c3%a4-%e2%82%ac.html"') assert 'attachment' == disptype assert {'filename': 'foo-%c3%a4-%e2%82%ac.html'} == params - def test_attwithasciifilenamews1(self): + def test_attwithasciifilenamews1(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename ="foo.html"') assert 'attachment' == disptype assert {'filename': 'foo.html'} == params - def test_attwith2filenames(self): + def test_attwith2filenames(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename="foo.html"; filename="bar.html"') assert disptype is None assert {} == params - def test_attfnbrokentoken(self): + def test_attfnbrokentoken(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo[1](2).html') assert disptype is None assert {} == params - def test_attfnbrokentokeniso(self): + def test_attfnbrokentokeniso(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo-ä.html') assert disptype is None assert {} == params - def test_attfnbrokentokenutf(self): + def test_attfnbrokentokenutf(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo-ä.html') assert disptype is None assert {} == params - def test_attmissingdisposition(self): + def test_attmissingdisposition(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'filename=foo.html') assert disptype is None assert {} == params - def test_attmissingdisposition2(self): + def test_attmissingdisposition2(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'x=y; filename=foo.html') assert disptype is None assert {} == params - def test_attmissingdisposition3(self): + def test_attmissingdisposition3(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( '"foo; filename=bar;baz"; filename=qux') assert disptype is None assert {} == params - def test_attmissingdisposition4(self): + def test_attmissingdisposition4(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'filename=foo.html, filename=bar.html') assert disptype is None assert {} == params - def test_emptydisposition(self): + def test_emptydisposition(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( '; filename=foo.html') assert disptype is None assert {} == params - def test_doublecolon(self): + def test_doublecolon(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( ': inline; attachment; filename=foo.html') assert disptype is None assert {} == params - def test_attandinline(self): + def test_attandinline(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'inline; attachment; filename=foo.html') assert disptype is None assert {} == params - def test_attandinline2(self): + def test_attandinline2(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; inline; filename=foo.html') assert disptype is None assert {} == params - def test_attbrokenquotedfn(self): + def test_attbrokenquotedfn(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename="foo.html".txt') assert disptype is None assert {} == params - def test_attbrokenquotedfn2(self): + def test_attbrokenquotedfn2(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename="bar') assert disptype is None assert {} == params - def test_attbrokenquotedfn3(self): + def test_attbrokenquotedfn3(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo"bar;baz"qux') assert disptype is None assert {} == params - def test_attmultinstances(self): + def test_attmultinstances(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo.html, attachment; filename=bar.html') assert disptype is None assert {} == params - def test_attmissingdelim(self): + def test_attmissingdelim(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; foo=foo filename=bar') assert disptype is None assert {} == params - def test_attmissingdelim2(self): + def test_attmissingdelim2(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=bar foo=foo') assert disptype is None assert {} == params - def test_attmissingdelim3(self): + def test_attmissingdelim3(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment filename=bar') assert disptype is None assert {} == params - def test_attreversed(self): + def test_attreversed(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'filename=foo.html; attachment') assert disptype is None assert {} == params - def test_attconfusedparam(self): + def test_attconfusedparam(self) -> None: disptype, params = parse_content_disposition( 'attachment; xfilename=foo.html') assert 'attachment' == disptype assert {'xfilename': 'foo.html'} == params - def test_attabspath(self): + def test_attabspath(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="/foo.html"') assert 'attachment' == disptype assert {'filename': 'foo.html'} == params - def test_attabspathwin(self): + def test_attabspathwin(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="\\foo.html"') assert 'attachment' == disptype assert {'filename': 'foo.html'} == params - def test_attcdate(self): + def test_attcdate(self) -> None: disptype, params = parse_content_disposition( 'attachment; creation-date="Wed, 12 Feb 1997 16:29:51 -0500"') assert 'attachment' == disptype assert {'creation-date': 'Wed, 12 Feb 1997 16:29:51 -0500'} == params - def test_attmdate(self): + def test_attmdate(self) -> None: disptype, params = parse_content_disposition( 'attachment; modification-date="Wed, 12 Feb 1997 16:29:51 -0500"') assert 'attachment' == disptype assert {'modification-date': 'Wed, 12 Feb 1997 16:29:51 -0500'} == params - def test_dispext(self): + def test_dispext(self) -> None: disptype, params = parse_content_disposition('foobar') assert 'foobar' == disptype assert {} == params - def test_dispextbadfn(self): + def test_dispextbadfn(self) -> None: disptype, params = parse_content_disposition( 'attachment; example="filename=example.txt"') assert 'attachment' == disptype assert {'example': 'filename=example.txt'} == params - def test_attwithisofn2231iso(self): + def test_attwithisofn2231iso(self) -> None: disptype, params = parse_content_disposition( "attachment; filename*=iso-8859-1''foo-%E4.html") assert 'attachment' == disptype assert {'filename*': 'foo-ä.html'} == params - def test_attwithfn2231utf8(self): + def test_attwithfn2231utf8(self) -> None: disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''foo-%c3%a4-%e2%82%ac.html") assert 'attachment' == disptype assert {'filename*': 'foo-ä-€.html'} == params - def test_attwithfn2231noc(self): + def test_attwithfn2231noc(self) -> None: disptype, params = parse_content_disposition( "attachment; filename*=''foo-%c3%a4-%e2%82%ac.html") assert 'attachment' == disptype assert {'filename*': 'foo-ä-€.html'} == params - def test_attwithfn2231utf8comp(self): + def test_attwithfn2231utf8comp(self) -> None: disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''foo-a%cc%88.html") assert 'attachment' == disptype assert {'filename*': 'foo-ä.html'} == params @pytest.mark.skip('should raise decoding error: %82 is invalid for latin1') - def test_attwithfn2231utf8_bad(self): + def test_attwithfn2231utf8_bad(self) -> None: with pytest.warns(aiohttp.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=iso-8859-1''foo-%c3%a4-%e2%82%ac.html") @@ -427,47 +427,47 @@ class TestParseContentDisposition: assert {} == params @pytest.mark.skip('should raise decoding error: %E4 is invalid for utf-8') - def test_attwithfn2231iso_bad(self): + def test_attwithfn2231iso_bad(self) -> None: with pytest.warns(aiohttp.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=utf-8''foo-%E4.html") assert 'attachment' == disptype assert {} == params - def test_attwithfn2231ws1(self): + def test_attwithfn2231ws1(self) -> None: with pytest.warns(aiohttp.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename *=UTF-8''foo-%c3%a4.html") assert 'attachment' == disptype assert {} == params - def test_attwithfn2231ws2(self): + def test_attwithfn2231ws2(self) -> None: disptype, params = parse_content_disposition( "attachment; filename*= UTF-8''foo-%c3%a4.html") assert 'attachment' == disptype assert {'filename*': 'foo-ä.html'} == params - def test_attwithfn2231ws3(self): + def test_attwithfn2231ws3(self) -> None: disptype, params = parse_content_disposition( "attachment; filename* =UTF-8''foo-%c3%a4.html") assert 'attachment' == disptype assert {'filename*': 'foo-ä.html'} == params - def test_attwithfn2231quot(self): + def test_attwithfn2231quot(self) -> None: with pytest.warns(aiohttp.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=\"UTF-8''foo-%c3%a4.html\"") assert 'attachment' == disptype assert {} == params - def test_attwithfn2231quot2(self): + def test_attwithfn2231quot2(self) -> None: with pytest.warns(aiohttp.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=\"foo%20bar.html\"") assert 'attachment' == disptype assert {} == params - def test_attwithfn2231singleqmissing(self): + def test_attwithfn2231singleqmissing(self) -> None: with pytest.warns(aiohttp.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8'foo-%c3%a4.html") @@ -475,7 +475,7 @@ class TestParseContentDisposition: assert {} == params @pytest.mark.skip('urllib.parse.unquote is tolerate to standalone % chars') - def test_attwithfn2231nbadpct1(self): + def test_attwithfn2231nbadpct1(self) -> None: with pytest.warns(aiohttp.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''foo%") @@ -483,75 +483,75 @@ class TestParseContentDisposition: assert {} == params @pytest.mark.skip('urllib.parse.unquote is tolerate to standalone % chars') - def test_attwithfn2231nbadpct2(self): + def test_attwithfn2231nbadpct2(self) -> None: with pytest.warns(aiohttp.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''f%oo.html") assert 'attachment' == disptype assert {} == params - def test_attwithfn2231dpct(self): + def test_attwithfn2231dpct(self) -> None: disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''A-%2541.html") assert 'attachment' == disptype assert {'filename*': 'A-%41.html'} == params - def test_attwithfn2231abspathdisguised(self): + def test_attwithfn2231abspathdisguised(self) -> None: disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''%5cfoo.html") assert 'attachment' == disptype assert {'filename*': '\\foo.html'} == params - def test_attfncont(self): + def test_attfncont(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename*0="foo."; filename*1="html"') assert 'attachment' == disptype assert {'filename*0': 'foo.', 'filename*1': 'html'} == params - def test_attfncontqs(self): + def test_attfncontqs(self) -> None: disptype, params = parse_content_disposition( r'attachment; filename*0="foo"; filename*1="\b\a\r.html"') assert 'attachment' == disptype assert {'filename*0': 'foo', 'filename*1': 'bar.html'} == params - def test_attfncontenc(self): + def test_attfncontenc(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename*0*=UTF-8''foo-%c3%a4; filename*1=".html"') assert 'attachment' == disptype assert {'filename*0*': 'UTF-8''foo-%c3%a4', 'filename*1': '.html'} == params - def test_attfncontlz(self): + def test_attfncontlz(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename*0="foo"; filename*01="bar"') assert 'attachment' == disptype assert {'filename*0': 'foo', 'filename*01': 'bar'} == params - def test_attfncontnc(self): + def test_attfncontnc(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename*0="foo"; filename*2="bar"') assert 'attachment' == disptype assert {'filename*0': 'foo', 'filename*2': 'bar'} == params - def test_attfnconts1(self): + def test_attfnconts1(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename*0="foo."; filename*2="html"') assert 'attachment' == disptype assert {'filename*0': 'foo.', 'filename*2': 'html'} == params - def test_attfncontord(self): + def test_attfncontord(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename*1="bar"; filename*0="foo"') assert 'attachment' == disptype assert {'filename*0': 'foo', 'filename*1': 'bar'} == params - def test_attfnboth(self): + def test_attfnboth(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="foo-ae.html";' " filename*=UTF-8''foo-%c3%a4.html") @@ -559,7 +559,7 @@ class TestParseContentDisposition: assert {'filename': 'foo-ae.html', 'filename*': 'foo-ä.html'} == params - def test_attfnboth2(self): + def test_attfnboth2(self) -> None: disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''foo-%c3%a4.html;" ' filename="foo-ae.html"') @@ -567,7 +567,7 @@ class TestParseContentDisposition: assert {'filename': 'foo-ae.html', 'filename*': 'foo-ä.html'} == params - def test_attfnboth3(self): + def test_attfnboth3(self) -> None: disptype, params = parse_content_disposition( "attachment; filename*0*=ISO-8859-15''euro-sign%3d%a4;" " filename*=ISO-8859-1''currency-sign%3d%a4") @@ -575,27 +575,27 @@ class TestParseContentDisposition: assert {'filename*': 'currency-sign=¤', 'filename*0*': "ISO-8859-15''euro-sign%3d%a4"} == params - def test_attnewandfn(self): + def test_attnewandfn(self) -> None: disptype, params = parse_content_disposition( 'attachment; foobar=x; filename="foo.html"') assert 'attachment' == disptype assert {'foobar': 'x', 'filename': 'foo.html'} == params - def test_attrfc2047token(self): + def test_attrfc2047token(self) -> None: with pytest.warns(aiohttp.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename==?ISO-8859-1?Q?foo-=E4.html?=') assert disptype is None assert {} == params - def test_attrfc2047quoted(self): + def test_attrfc2047quoted(self) -> None: disptype, params = parse_content_disposition( 'attachment; filename="=?ISO-8859-1?Q?foo-=E4.html?="') assert 'attachment' == disptype assert {'filename': '=?ISO-8859-1?Q?foo-=E4.html?='} == params - def test_bad_continuous_param(self): + def test_bad_continuous_param(self) -> None: with pytest.warns(aiohttp.BadContentDispositionParam): disptype, params = parse_content_disposition( 'attachment; filename*0=foo bar') @@ -606,57 +606,57 @@ class TestParseContentDisposition: class TestContentDispositionFilename: # http://greenbytes.de/tech/tc2231/ - def test_no_filename(self): + def test_no_filename(self) -> None: assert content_disposition_filename({}) is None assert content_disposition_filename({'foo': 'bar'}) is None - def test_filename(self): + def test_filename(self) -> None: params = {'filename': 'foo.html'} assert 'foo.html' == content_disposition_filename(params) - def test_filename_ext(self): + def test_filename_ext(self) -> None: params = {'filename*': 'файл.html'} assert 'файл.html' == content_disposition_filename(params) - def test_attfncont(self): + def test_attfncont(self) -> None: params = {'filename*0': 'foo.', 'filename*1': 'html'} assert 'foo.html' == content_disposition_filename(params) - def test_attfncontqs(self): + def test_attfncontqs(self) -> None: params = {'filename*0': 'foo', 'filename*1': 'bar.html'} assert 'foobar.html' == content_disposition_filename(params) - def test_attfncontenc(self): + def test_attfncontenc(self) -> None: params = {'filename*0*': "UTF-8''foo-%c3%a4", 'filename*1': '.html'} assert 'foo-ä.html' == content_disposition_filename(params) - def test_attfncontlz(self): + def test_attfncontlz(self) -> None: params = {'filename*0': 'foo', 'filename*01': 'bar'} assert 'foo' == content_disposition_filename(params) - def test_attfncontnc(self): + def test_attfncontnc(self) -> None: params = {'filename*0': 'foo', 'filename*2': 'bar'} assert 'foo' == content_disposition_filename(params) - def test_attfnconts1(self): + def test_attfnconts1(self) -> None: params = {'filename*1': 'foo', 'filename*2': 'bar'} assert content_disposition_filename(params) is None - def test_attfnboth(self): + def test_attfnboth(self) -> None: params = {'filename': 'foo-ae.html', 'filename*': 'foo-ä.html'} assert 'foo-ä.html' == content_disposition_filename(params) - def test_attfnboth3(self): + def test_attfnboth3(self) -> None: params = {'filename*0*': "ISO-8859-15''euro-sign%3d%a4", 'filename*': 'currency-sign=¤'} assert 'currency-sign=¤' == content_disposition_filename(params) - def test_attrfc2047quoted(self): + def test_attrfc2047quoted(self) -> None: params = {'filename': '=?ISO-8859-1?Q?foo-=E4.html?='} assert '=?ISO-8859-1?Q?foo-=E4.html?=' == content_disposition_filename( params) diff --git a/tests/test_payload.py b/tests/test_payload.py index bbb3e0f..b75bf49 100644 --- a/tests/test_payload.py +++ b/tests/test_payload.py @@ -1,3 +1,4 @@ +import asyncio from io import StringIO from unittest import mock @@ -21,7 +22,7 @@ class Payload(payload.Payload): pass -def test_register_type(registry): +def test_register_type(registry) -> None: class TestProvider: pass @@ -30,7 +31,7 @@ def test_register_type(registry): assert isinstance(p, Payload) -def test_register_unsupported_order(registry): +def test_register_unsupported_order(registry) -> None: class TestProvider: pass @@ -38,7 +39,7 @@ def test_register_unsupported_order(registry): payload.register_payload(Payload, TestProvider, order=object()) -def test_payload_ctor(): +def test_payload_ctor() -> None: p = Payload('test', encoding='utf-8', filename='test.txt') assert p._value == 'test' assert p._encoding == 'utf-8' @@ -47,27 +48,27 @@ def test_payload_ctor(): assert p.content_type == 'text/plain' -def test_payload_content_type(): +def test_payload_content_type() -> None: p = Payload('test', headers={'content-type': 'application/json'}) assert p.content_type == 'application/json' -def test_bytes_payload_default_content_type(): +def test_bytes_payload_default_content_type() -> None: p = payload.BytesPayload(b'data') assert p.content_type == 'application/octet-stream' -def test_bytes_payload_explicit_content_type(): +def test_bytes_payload_explicit_content_type() -> None: p = payload.BytesPayload(b'data', content_type='application/custom') assert p.content_type == 'application/custom' -def test_bytes_payload_bad_type(): +def test_bytes_payload_bad_type() -> None: with pytest.raises(TypeError): payload.BytesPayload(object()) -def test_string_payload(): +def test_string_payload() -> None: p = payload.StringPayload('test') assert p.encoding == 'utf-8' assert p.content_type == 'text/plain; charset=utf-8' @@ -82,7 +83,7 @@ def test_string_payload(): assert p.content_type == 'text/plain; charset=koi8-r' -def test_string_io_payload(): +def test_string_io_payload() -> None: s = StringIO('ű' * 5000) p = payload.StringIOPayload(s) assert p.encoding == 'utf-8' @@ -90,7 +91,7 @@ def test_string_io_payload(): assert p.size == 10000 -def test_async_iterable_payload_default_content_type(): +def test_async_iterable_payload_default_content_type() -> None: @async_generator async def gen(): pass @@ -99,7 +100,7 @@ def test_async_iterable_payload_default_content_type(): assert p.content_type == 'application/octet-stream' -def test_async_iterable_payload_explicit_content_type(): +def test_async_iterable_payload_explicit_content_type() -> None: @async_generator async def gen(): pass @@ -108,13 +109,14 @@ def test_async_iterable_payload_explicit_content_type(): assert p.content_type == 'application/custom' -def test_async_iterable_payload_not_async_iterable(): +def test_async_iterable_payload_not_async_iterable() -> None: with pytest.raises(TypeError): payload.AsyncIterablePayload(object()) -async def test_stream_reader_long_lines(loop): +async def test_stream_reader_long_lines() -> None: + loop = asyncio.get_event_loop() DATA = b'0' * 1024 ** 3 stream = streams.StreamReader(mock.Mock(), loop=loop) diff --git a/tests/test_proxy.py b/tests/test_proxy.py index 2269806..5a16a30 100644 --- a/tests/test_proxy.py +++ b/tests/test_proxy.py @@ -35,7 +35,7 @@ class TestProxy(unittest.TestCase): gc.collect() @mock.patch('aiohttp.connector.ClientRequest') - def test_connect(self, ClientRequestMock): + def test_connect(self, ClientRequestMock) -> None: req = ClientRequest( 'GET', URL('http://www.python.org'), proxy=URL('http://proxy.example.com'), @@ -44,7 +44,10 @@ class TestProxy(unittest.TestCase): self.assertEqual(str(req.proxy), 'http://proxy.example.com') # mock all the things! - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro([mock.MagicMock()]) proto = mock.Mock(**{ @@ -66,7 +69,7 @@ class TestProxy(unittest.TestCase): ssl=None) @mock.patch('aiohttp.connector.ClientRequest') - def test_proxy_headers(self, ClientRequestMock): + def test_proxy_headers(self, ClientRequestMock) -> None: req = ClientRequest( 'GET', URL('http://www.python.org'), proxy=URL('http://proxy.example.com'), @@ -75,7 +78,9 @@ class TestProxy(unittest.TestCase): self.assertEqual(str(req.proxy), 'http://proxy.example.com') # mock all the things! - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro([mock.MagicMock()]) proto = mock.Mock(**{ @@ -96,7 +101,7 @@ class TestProxy(unittest.TestCase): loop=self.loop, ssl=None) - def test_proxy_auth(self): + def test_proxy_auth(self) -> None: with self.assertRaises(ValueError) as ctx: ClientRequest( 'GET', URL('http://python.org'), @@ -108,8 +113,10 @@ class TestProxy(unittest.TestCase): "proxy_auth must be None or BasicAuth() tuple", ) - def test_proxy_dns_error(self): - connector = aiohttp.TCPConnector(loop=self.loop) + def test_proxy_dns_error(self) -> None: + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro( raise_exception=OSError('dont take it serious')) @@ -125,8 +132,10 @@ class TestProxy(unittest.TestCase): self.assertEqual(req.url.path, '/') self.assertEqual(dict(req.headers), expected_headers) - def test_proxy_connection_error(self): - connector = aiohttp.TCPConnector(loop=self.loop) + def test_proxy_connection_error(self) -> None: + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro([{ 'hostname': 'www.python.org', 'host': '127.0.0.1', 'port': 80, @@ -145,7 +154,7 @@ class TestProxy(unittest.TestCase): req, None, aiohttp.ClientTimeout())) @mock.patch('aiohttp.connector.ClientRequest') - def test_https_connect(self, ClientRequestMock): + def test_https_connect(self, ClientRequestMock) -> None: proxy_req = ClientRequest('GET', URL('http://proxy.example.com'), loop=self.loop) ClientRequestMock.return_value = proxy_req @@ -161,7 +170,9 @@ class TestProxy(unittest.TestCase): proxy_req.send = make_mocked_coro(proxy_resp) proxy_resp.start = make_mocked_coro(mock.Mock(status=200)) - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro( [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80, 'family': socket.AF_INET, 'proto': 0, 'flags': 0}]) @@ -188,7 +199,7 @@ class TestProxy(unittest.TestCase): self.loop.run_until_complete(req.close()) @mock.patch('aiohttp.connector.ClientRequest') - def test_https_connect_certificate_error(self, ClientRequestMock): + def test_https_connect_certificate_error(self, ClientRequestMock) -> None: proxy_req = ClientRequest('GET', URL('http://proxy.example.com'), loop=self.loop) ClientRequestMock.return_value = proxy_req @@ -204,7 +215,9 @@ class TestProxy(unittest.TestCase): proxy_req.send = make_mocked_coro(proxy_resp) proxy_resp.start = make_mocked_coro(mock.Mock(status=200)) - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro( [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80, 'family': socket.AF_INET, 'proto': 0, 'flags': 0}]) @@ -237,7 +250,7 @@ class TestProxy(unittest.TestCase): req, None, aiohttp.ClientTimeout())) @mock.patch('aiohttp.connector.ClientRequest') - def test_https_connect_ssl_error(self, ClientRequestMock): + def test_https_connect_ssl_error(self, ClientRequestMock) -> None: proxy_req = ClientRequest('GET', URL('http://proxy.example.com'), loop=self.loop) ClientRequestMock.return_value = proxy_req @@ -253,7 +266,9 @@ class TestProxy(unittest.TestCase): proxy_req.send = make_mocked_coro(proxy_resp) proxy_resp.start = make_mocked_coro(mock.Mock(status=200)) - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro( [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80, 'family': socket.AF_INET, 'proto': 0, 'flags': 0}]) @@ -286,7 +301,7 @@ class TestProxy(unittest.TestCase): req, None, aiohttp.ClientTimeout())) @mock.patch('aiohttp.connector.ClientRequest') - def test_https_connect_runtime_error(self, ClientRequestMock): + def test_https_connect_runtime_error(self, ClientRequestMock) -> None: proxy_req = ClientRequest('GET', URL('http://proxy.example.com'), loop=self.loop) ClientRequestMock.return_value = proxy_req @@ -302,7 +317,9 @@ class TestProxy(unittest.TestCase): proxy_req.send = make_mocked_coro(proxy_resp) proxy_resp.start = make_mocked_coro(mock.Mock(status=200)) - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro( [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80, 'family': socket.AF_INET, 'proto': 0, 'flags': 0}]) @@ -326,7 +343,7 @@ class TestProxy(unittest.TestCase): self.loop.run_until_complete(req.close()) @mock.patch('aiohttp.connector.ClientRequest') - def test_https_connect_http_proxy_error(self, ClientRequestMock): + def test_https_connect_http_proxy_error(self, ClientRequestMock) -> None: proxy_req = ClientRequest('GET', URL('http://proxy.example.com'), loop=self.loop) ClientRequestMock.return_value = proxy_req @@ -343,7 +360,9 @@ class TestProxy(unittest.TestCase): proxy_resp.start = make_mocked_coro( mock.Mock(status=400, reason='bad request')) - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro( [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80, 'family': socket.AF_INET, 'proto': 0, 'flags': 0}]) @@ -367,7 +386,7 @@ class TestProxy(unittest.TestCase): self.loop.run_until_complete(req.close()) @mock.patch('aiohttp.connector.ClientRequest') - def test_https_connect_resp_start_error(self, ClientRequestMock): + def test_https_connect_resp_start_error(self, ClientRequestMock) -> None: proxy_req = ClientRequest('GET', URL('http://proxy.example.com'), loop=self.loop) ClientRequestMock.return_value = proxy_req @@ -384,7 +403,9 @@ class TestProxy(unittest.TestCase): proxy_resp.start = make_mocked_coro( raise_exception=OSError("error message")) - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro( [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80, 'family': socket.AF_INET, 'proto': 0, 'flags': 0}]) @@ -403,12 +424,14 @@ class TestProxy(unittest.TestCase): req, None, aiohttp.ClientTimeout())) @mock.patch('aiohttp.connector.ClientRequest') - def test_request_port(self, ClientRequestMock): + def test_request_port(self, ClientRequestMock) -> None: proxy_req = ClientRequest('GET', URL('http://proxy.example.com'), loop=self.loop) ClientRequestMock.return_value = proxy_req - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro( [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80, 'family': socket.AF_INET, 'proto': 0, 'flags': 0}]) @@ -426,7 +449,7 @@ class TestProxy(unittest.TestCase): req, None, aiohttp.ClientTimeout())) self.assertEqual(req.url, URL('http://localhost:1234/path')) - def test_proxy_auth_property(self): + def test_proxy_auth_property(self) -> None: req = aiohttp.ClientRequest( 'GET', URL('http://localhost:1234/path'), proxy=URL('http://proxy.example.com'), @@ -434,7 +457,7 @@ class TestProxy(unittest.TestCase): loop=self.loop) self.assertEqual(('user', 'pass', 'latin1'), req.proxy_auth) - def test_proxy_auth_property_default(self): + def test_proxy_auth_property_default(self) -> None: req = aiohttp.ClientRequest( 'GET', URL('http://localhost:1234/path'), proxy=URL('http://proxy.example.com'), @@ -442,7 +465,7 @@ class TestProxy(unittest.TestCase): self.assertIsNone(req.proxy_auth) @mock.patch('aiohttp.connector.ClientRequest') - def test_https_connect_pass_ssl_context(self, ClientRequestMock): + def test_https_connect_pass_ssl_context(self, ClientRequestMock) -> None: proxy_req = ClientRequest('GET', URL('http://proxy.example.com'), loop=self.loop) ClientRequestMock.return_value = proxy_req @@ -458,7 +481,9 @@ class TestProxy(unittest.TestCase): proxy_req.send = make_mocked_coro(proxy_resp) proxy_resp.start = make_mocked_coro(mock.Mock(status=200)) - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro( [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80, 'family': socket.AF_INET, 'proto': 0, 'flags': 0}]) @@ -491,7 +516,7 @@ class TestProxy(unittest.TestCase): self.loop.run_until_complete(req.close()) @mock.patch('aiohttp.connector.ClientRequest') - def test_https_auth(self, ClientRequestMock): + def test_https_auth(self, ClientRequestMock) -> None: proxy_req = ClientRequest('GET', URL('http://proxy.example.com'), auth=aiohttp.helpers.BasicAuth('user', 'pass'), @@ -509,7 +534,9 @@ class TestProxy(unittest.TestCase): proxy_req.send = make_mocked_coro(proxy_resp) proxy_resp.start = make_mocked_coro(mock.Mock(status=200)) - connector = aiohttp.TCPConnector(loop=self.loop) + async def make_conn(): + return aiohttp.TCPConnector() + connector = self.loop.run_until_complete(make_conn()) connector._resolve_host = make_mocked_coro( [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80, 'family': socket.AF_INET, 'proto': 0, 'flags': 0}]) diff --git a/tests/test_proxy_functional.py b/tests/test_proxy_functional.py index 9504cfb..2ba29a9 100644 --- a/tests/test_proxy_functional.py +++ b/tests/test_proxy_functional.py @@ -75,7 +75,8 @@ def get_request(loop): return _request -async def test_proxy_http_absolute_path(proxy_test_server, get_request): +async def test_proxy_http_absolute_path(proxy_test_server, + get_request) -> None: url = 'http://aiohttp.io/path?query=yes' proxy = await proxy_test_server() @@ -87,7 +88,7 @@ async def test_proxy_http_absolute_path(proxy_test_server, get_request): assert proxy.request.path_qs == 'http://aiohttp.io/path?query=yes' -async def test_proxy_http_raw_path(proxy_test_server, get_request): +async def test_proxy_http_raw_path(proxy_test_server, get_request) -> None: url = 'http://aiohttp.io:2561/space sheep?q=can:fly' raw_url = 'http://aiohttp.io:2561/space%20sheep?q=can:fly' proxy = await proxy_test_server() @@ -98,7 +99,7 @@ async def test_proxy_http_raw_path(proxy_test_server, get_request): assert proxy.request.path_qs == raw_url -async def test_proxy_http_idna_support(proxy_test_server, get_request): +async def test_proxy_http_idna_support(proxy_test_server, get_request) -> None: url = 'http://éé.com/' raw_url = 'http://xn--9caa.com/' proxy = await proxy_test_server() @@ -109,7 +110,7 @@ async def test_proxy_http_idna_support(proxy_test_server, get_request): assert proxy.request.path_qs == raw_url -async def test_proxy_http_connection_error(get_request): +async def test_proxy_http_connection_error(get_request) -> None: url = 'http://aiohttp.io/path' proxy_url = 'http://localhost:2242/' @@ -117,7 +118,7 @@ async def test_proxy_http_connection_error(get_request): await get_request(url=url, proxy=proxy_url) -async def test_proxy_http_bad_response(proxy_test_server, get_request): +async def test_proxy_http_bad_response(proxy_test_server, get_request) -> None: url = 'http://aiohttp.io/path' proxy = await proxy_test_server() proxy.return_value = dict( @@ -130,7 +131,7 @@ async def test_proxy_http_bad_response(proxy_test_server, get_request): assert resp.headers['Proxy-Agent'] == 'TestProxy' -async def test_proxy_http_auth(proxy_test_server, get_request): +async def test_proxy_http_auth(proxy_test_server, get_request) -> None: url = 'http://aiohttp.io/path' proxy = await proxy_test_server() @@ -157,7 +158,7 @@ async def test_proxy_http_auth(proxy_test_server, get_request): assert 'Proxy-Authorization' in proxy.request.headers -async def test_proxy_http_auth_utf8(proxy_test_server, get_request): +async def test_proxy_http_auth_utf8(proxy_test_server, get_request) -> None: url = 'http://aiohttp.io/path' auth = aiohttp.BasicAuth('юзер', 'пасс', 'utf-8') proxy = await proxy_test_server() @@ -168,7 +169,8 @@ async def test_proxy_http_auth_utf8(proxy_test_server, get_request): assert 'Proxy-Authorization' not in proxy.request.headers -async def test_proxy_http_auth_from_url(proxy_test_server, get_request): +async def test_proxy_http_auth_from_url(proxy_test_server, + get_request) -> None: url = 'http://aiohttp.io/path' proxy = await proxy_test_server() @@ -185,7 +187,7 @@ async def test_proxy_http_auth_from_url(proxy_test_server, get_request): assert 'Proxy-Authorization' in proxy.request.headers -async def test_proxy_http_acquired_cleanup(proxy_test_server, loop): +async def test_proxy_http_acquired_cleanup(proxy_test_server, loop) -> None: url = 'http://aiohttp.io/path' conn = aiohttp.TCPConnector(loop=loop) @@ -203,7 +205,8 @@ async def test_proxy_http_acquired_cleanup(proxy_test_server, loop): @pytest.mark.skip('we need to reconsider how we test this') -async def test_proxy_http_acquired_cleanup_force(proxy_test_server, loop): +async def test_proxy_http_acquired_cleanup_force(proxy_test_server, + loop) -> None: url = 'http://aiohttp.io/path' conn = aiohttp.TCPConnector(force_close=True, loop=loop) @@ -227,7 +230,7 @@ async def test_proxy_http_acquired_cleanup_force(proxy_test_server, loop): @pytest.mark.skip('we need to reconsider how we test this') -async def test_proxy_http_multi_conn_limit(proxy_test_server, loop): +async def test_proxy_http_multi_conn_limit(proxy_test_server, loop) -> None: url = 'http://aiohttp.io/path' limit, multi_conn_num = 1, 5 @@ -319,7 +322,7 @@ async def xtest_proxy_https_idna_support(proxy_test_server, get_request): assert connect.host == 'xn--9caa.com' -async def test_proxy_https_connection_error(get_request): +async def test_proxy_https_connection_error(get_request) -> None: url = 'https://secure.aiohttp.io/path' proxy_url = 'http://localhost:2242/' @@ -327,7 +330,8 @@ async def test_proxy_https_connection_error(get_request): await get_request(url=url, proxy=proxy_url) -async def test_proxy_https_bad_response(proxy_test_server, get_request): +async def test_proxy_https_bad_response(proxy_test_server, + get_request) -> None: url = 'https://secure.aiohttp.io/path' proxy = await proxy_test_server() proxy.return_value = dict( @@ -490,7 +494,8 @@ def mock_is_file(self): return original_is_file(self) -async def test_proxy_from_env_http(proxy_test_server, get_request, mocker): +async def test_proxy_from_env_http(proxy_test_server, + get_request, mocker) -> None: url = 'http://aiohttp.io/path' proxy = await proxy_test_server() mocker.patch.dict(os.environ, {'http_proxy': str(proxy.url)}) @@ -634,7 +639,7 @@ async def xtest_proxy_from_env_https_with_auth(proxy_test_server, assert r2.headers['Proxy-Authorization'] == auth.encode() -async def test_proxy_auth(): +async def test_proxy_auth() -> None: async with aiohttp.ClientSession() as session: with pytest.raises( ValueError, diff --git a/tests/test_pytest_plugin.py b/tests/test_pytest_plugin.py index 4106cb2..8f82eb8 100644 --- a/tests/test_pytest_plugin.py +++ b/tests/test_pytest_plugin.py @@ -15,7 +15,7 @@ pytest_plugins = 'aiohttp.pytest_plugin' IS_PYPY = platform.python_implementation() == 'PyPy' -def test_aiohttp_plugin(testdir): +def test_aiohttp_plugin(testdir) -> None: testdir.makepyfile("""\ import pytest from unittest import mock @@ -33,7 +33,7 @@ def create_app(loop=None): return app -async def test_hello(aiohttp_client): +async def test_hello(aiohttp_client) -> None: client = await aiohttp_client(create_app) resp = await client.get('/') assert resp.status == 200 @@ -41,7 +41,7 @@ async def test_hello(aiohttp_client): assert 'Hello, world' in text -async def test_hello_from_app(aiohttp_client, loop): +async def test_hello_from_app(aiohttp_client, loop) -> None: app = web.Application() app.router.add_get('/', hello) client = await aiohttp_client(app) @@ -51,7 +51,7 @@ async def test_hello_from_app(aiohttp_client, loop): assert 'Hello, world' in text -async def test_hello_with_loop(aiohttp_client, loop): +async def test_hello_with_loop(aiohttp_client, loop) -> None: client = await aiohttp_client(create_app) resp = await client.get('/') assert resp.status == 200 @@ -59,19 +59,19 @@ async def test_hello_with_loop(aiohttp_client, loop): assert 'Hello, world' in text -async def test_set_args(aiohttp_client, loop): +async def test_set_args(aiohttp_client, loop) -> None: with pytest.raises(AssertionError): app = web.Application() await aiohttp_client(app, 1, 2, 3) -async def test_set_keyword_args(aiohttp_client, loop): +async def test_set_keyword_args(aiohttp_client, loop) -> None: app = web.Application() with pytest.raises(TypeError): await aiohttp_client(app, param=1) -async def test_noop(): +async def test_noop() -> None: pass @@ -96,7 +96,7 @@ def cli(loop, aiohttp_client): return loop.run_until_complete(aiohttp_client(create_stateful_app)) -async def test_set_value(cli): +async def test_set_value(cli) -> None: resp = await cli.post('/', data={'value': 'foo'}) assert resp.status == 200 text = await resp.text() @@ -104,7 +104,7 @@ async def test_set_value(cli): assert cli.server.app['value'] == 'foo' -async def test_get_value(cli): +async def test_get_value(cli) -> None: resp = await cli.get('/') assert resp.status == 200 text = await resp.text() @@ -117,11 +117,11 @@ async def test_get_value(cli): assert text == 'value: bar' -def test_noncoro(): +def test_noncoro() -> None: assert True -async def test_failed_to_create_client(aiohttp_client): +async def test_failed_to_create_client(aiohttp_client) -> None: def make_app(loop): raise RuntimeError() @@ -152,17 +152,17 @@ async def test_custom_port_test_server(aiohttp_server, aiohttp_unused_port): result.assert_outcomes(passed=12) -def test_warning_checks(testdir): +def test_warning_checks(testdir) -> None: testdir.makepyfile("""\ async def foobar(): return 123 -async def test_good(): +async def test_good() -> None: v = await foobar() assert v == 123 -async def test_bad(): +async def test_bad() -> None: foobar() """) testdir.makeconftest(CONFTEST) @@ -177,7 +177,7 @@ async def test_bad(): result.assert_outcomes(**expected_outcomes) -def test_aiohttp_plugin_async_fixture(testdir, capsys): +def test_aiohttp_plugin_async_fixture(testdir, capsys) -> None: testdir.makepyfile("""\ import pytest @@ -211,21 +211,21 @@ async def bar(request): return request.function -async def test_hello(cli): +async def test_hello(cli) -> None: resp = await cli.get('/') assert resp.status == 200 -def test_foo(loop, foo): +def test_foo(loop, foo) -> None: assert foo == 42 -def test_foo_without_loop(foo): +def test_foo_without_loop(foo) -> None: # will raise an error because there is no loop pass -def test_bar(loop, bar): +def test_bar(loop, bar) -> None: assert bar is test_bar """) testdir.makeconftest(CONFTEST) @@ -238,7 +238,7 @@ def test_bar(loop, bar): @pytest.mark.skipif(sys.version_info < (3, 6), reason='old python') -def test_aiohttp_plugin_async_gen_fixture(testdir): +def test_aiohttp_plugin_async_gen_fixture(testdir) -> None: testdir.makepyfile("""\ import pytest from unittest import mock @@ -265,12 +265,12 @@ async def cli(aiohttp_client): canary() -async def test_hello(cli): +async def test_hello(cli) -> None: resp = await cli.get('/') assert resp.status == 200 -def test_finalized(): +def test_finalized() -> None: assert canary.called is True """) testdir.makeconftest(CONFTEST) diff --git a/tests/test_resolver.py b/tests/test_resolver.py index f0eca1b..aa00785 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -47,7 +47,7 @@ def fake_addrinfo(hosts): @pytest.mark.skipif(not gethostbyname, reason="aiodns 1.1 required") -async def test_async_resolver_positive_lookup(loop): +async def test_async_resolver_positive_lookup(loop) -> None: with patch('aiodns.DNSResolver') as mock: mock().gethostbyname.return_value = fake_result(['127.0.0.1']) resolver = AsyncResolver(loop=loop) @@ -58,7 +58,7 @@ async def test_async_resolver_positive_lookup(loop): @pytest.mark.skipif(aiodns is None, reason="aiodns required") -async def test_async_resolver_query_positive_lookup(loop): +async def test_async_resolver_query_positive_lookup(loop) -> None: with patch('aiodns.DNSResolver') as mock: del mock().gethostbyname mock().query.return_value = fake_query_result(['127.0.0.1']) @@ -69,7 +69,7 @@ async def test_async_resolver_query_positive_lookup(loop): @pytest.mark.skipif(not gethostbyname, reason="aiodns 1.1 required") -async def test_async_resolver_multiple_replies(loop): +async def test_async_resolver_multiple_replies(loop) -> None: with patch('aiodns.DNSResolver') as mock: ips = ['127.0.0.1', '127.0.0.2', '127.0.0.3', '127.0.0.4'] mock().gethostbyname.return_value = fake_result(ips) @@ -80,7 +80,7 @@ async def test_async_resolver_multiple_replies(loop): @pytest.mark.skipif(aiodns is None, reason="aiodns required") -async def test_async_resolver_query_multiple_replies(loop): +async def test_async_resolver_query_multiple_replies(loop) -> None: with patch('aiodns.DNSResolver') as mock: del mock().gethostbyname ips = ['127.0.0.1', '127.0.0.2', '127.0.0.3', '127.0.0.4'] @@ -91,7 +91,7 @@ async def test_async_resolver_query_multiple_replies(loop): @pytest.mark.skipif(not gethostbyname, reason="aiodns 1.1 required") -async def test_async_resolver_negative_lookup(loop): +async def test_async_resolver_negative_lookup(loop) -> None: with patch('aiodns.DNSResolver') as mock: mock().gethostbyname.side_effect = aiodns.error.DNSError() resolver = AsyncResolver(loop=loop) @@ -100,7 +100,7 @@ async def test_async_resolver_negative_lookup(loop): @pytest.mark.skipif(aiodns is None, reason="aiodns required") -async def test_async_resolver_query_negative_lookup(loop): +async def test_async_resolver_query_negative_lookup(loop) -> None: with patch('aiodns.DNSResolver') as mock: del mock().gethostbyname mock().query.side_effect = aiodns.error.DNSError() @@ -110,7 +110,7 @@ async def test_async_resolver_query_negative_lookup(loop): @pytest.mark.skipif(aiodns is None, reason="aiodns required") -async def test_async_resolver_no_hosts_in_query(loop): +async def test_async_resolver_no_hosts_in_query(loop) -> None: with patch('aiodns.DNSResolver') as mock: del mock().gethostbyname mock().query.return_value = fake_query_result([]) @@ -120,7 +120,7 @@ async def test_async_resolver_no_hosts_in_query(loop): @pytest.mark.skipif(not gethostbyname, reason="aiodns 1.1 required") -async def test_async_resolver_no_hosts_in_gethostbyname(loop): +async def test_async_resolver_no_hosts_in_gethostbyname(loop) -> None: with patch('aiodns.DNSResolver') as mock: mock().gethostbyname.return_value = fake_result([]) resolver = AsyncResolver(loop=loop) @@ -128,7 +128,7 @@ async def test_async_resolver_no_hosts_in_gethostbyname(loop): await resolver.resolve('doesnotexist.bla') -async def test_threaded_resolver_positive_lookup(): +async def test_threaded_resolver_positive_lookup() -> None: loop = Mock() loop.getaddrinfo = fake_addrinfo(["127.0.0.1"]) resolver = ThreadedResolver(loop=loop) @@ -136,7 +136,7 @@ async def test_threaded_resolver_positive_lookup(): ipaddress.ip_address(real[0]['host']) -async def test_threaded_resolver_multiple_replies(): +async def test_threaded_resolver_multiple_replies() -> None: loop = Mock() ips = ['127.0.0.1', '127.0.0.2', '127.0.0.3', '127.0.0.4'] loop.getaddrinfo = fake_addrinfo(ips) @@ -146,7 +146,7 @@ async def test_threaded_resolver_multiple_replies(): assert len(ips) > 3, "Expecting multiple addresses" -async def test_threaded_negative_lookup(): +async def test_threaded_negative_lookup() -> None: loop = Mock() ips = [] loop.getaddrinfo = fake_addrinfo(ips) @@ -155,32 +155,32 @@ async def test_threaded_negative_lookup(): await resolver.resolve('doesnotexist.bla') -async def test_close_for_threaded_resolver(loop): +async def test_close_for_threaded_resolver(loop) -> None: resolver = ThreadedResolver(loop=loop) await resolver.close() @pytest.mark.skipif(aiodns is None, reason="aiodns required") -async def test_close_for_async_resolver(loop): +async def test_close_for_async_resolver(loop) -> None: resolver = AsyncResolver(loop=loop) await resolver.close() -def test_default_loop_for_threaded_resolver(loop): +async def test_default_loop_for_threaded_resolver(loop) -> None: asyncio.set_event_loop(loop) resolver = ThreadedResolver() assert resolver._loop is loop @pytest.mark.skipif(aiodns is None, reason="aiodns required") -def test_default_loop_for_async_resolver(loop): +async def test_default_loop_for_async_resolver(loop) -> None: asyncio.set_event_loop(loop) resolver = AsyncResolver() assert resolver._loop is loop @pytest.mark.skipif(not gethostbyname, reason="aiodns 1.1 required") -async def test_async_resolver_ipv6_positive_lookup(loop): +async def test_async_resolver_ipv6_positive_lookup(loop) -> None: with patch('aiodns.DNSResolver') as mock: mock().gethostbyname.return_value = fake_result(['::1']) resolver = AsyncResolver(loop=loop) @@ -192,7 +192,7 @@ async def test_async_resolver_ipv6_positive_lookup(loop): @pytest.mark.skipif(aiodns is None, reason="aiodns required") -async def test_async_resolver_query_ipv6_positive_lookup(loop): +async def test_async_resolver_query_ipv6_positive_lookup(loop) -> None: with patch('aiodns.DNSResolver') as mock: del mock().gethostbyname mock().query.return_value = fake_query_result(['::1']) @@ -203,13 +203,13 @@ async def test_async_resolver_query_ipv6_positive_lookup(loop): mock().query.assert_called_with('www.python.org', 'AAAA') -def test_async_resolver_aiodns_not_present(loop, monkeypatch): +async def test_async_resolver_aiodns_not_present(loop, monkeypatch) -> None: monkeypatch.setattr("aiohttp.resolver.aiodns", None) with pytest.raises(RuntimeError): AsyncResolver(loop=loop) -def test_default_resolver(): +def test_default_resolver() -> None: # if gethostbyname: # assert DefaultResolver is AsyncResolver # else: diff --git a/tests/test_route_def.py b/tests/test_route_def.py index 56afe51..412ae32 100644 --- a/tests/test_route_def.py +++ b/tests/test_route_def.py @@ -12,7 +12,7 @@ def router(): return UrlDispatcher() -def test_get(router): +def test_get(router) -> None: async def handler(request): pass @@ -29,7 +29,7 @@ def test_get(router): assert route2.method == 'HEAD' -def test_head(router): +def test_head(router) -> None: async def handler(request): pass @@ -42,7 +42,7 @@ def test_head(router): assert str(route.url_for()) == '/' -def test_options(router): +def test_options(router) -> None: async def handler(request): pass @@ -55,7 +55,7 @@ def test_options(router): assert str(route.url_for()) == '/' -def test_post(router): +def test_post(router) -> None: async def handler(request): pass @@ -67,7 +67,7 @@ def test_post(router): assert str(route.url_for()) == '/' -def test_put(router): +def test_put(router) -> None: async def handler(request): pass @@ -80,7 +80,7 @@ def test_put(router): assert str(route.url_for()) == '/' -def test_patch(router): +def test_patch(router) -> None: async def handler(request): pass @@ -93,7 +93,7 @@ def test_patch(router): assert str(route.url_for()) == '/' -def test_delete(router): +def test_delete(router) -> None: async def handler(request): pass @@ -106,7 +106,7 @@ def test_delete(router): assert str(route.url_for()) == '/' -def test_route(router): +def test_route(router) -> None: async def handler(request): pass @@ -119,7 +119,7 @@ def test_route(router): assert str(route.url_for()) == '/' -def test_static(router): +def test_static(router) -> None: folder = pathlib.Path(__file__).parent router.add_routes([web.static('/prefix', folder)]) assert len(router.resources()) == 1 # 2 routes: for HEAD and GET @@ -132,7 +132,7 @@ def test_static(router): assert url == URL('/prefix/sample.key') -def test_head_deco(router): +def test_head_deco(router) -> None: routes = web.RouteTableDef() @routes.head('/path') @@ -148,7 +148,7 @@ def test_head_deco(router): assert str(route.url_for()) == '/path' -def test_get_deco(router): +def test_get_deco(router) -> None: routes = web.RouteTableDef() @routes.get('/path') @@ -168,7 +168,7 @@ def test_get_deco(router): assert str(route2.url_for()) == '/path' -def test_post_deco(router): +def test_post_deco(router) -> None: routes = web.RouteTableDef() @routes.post('/path') @@ -184,7 +184,7 @@ def test_post_deco(router): assert str(route.url_for()) == '/path' -def test_put_deco(router): +def test_put_deco(router) -> None: routes = web.RouteTableDef() @routes.put('/path') @@ -200,7 +200,7 @@ def test_put_deco(router): assert str(route.url_for()) == '/path' -def test_patch_deco(router): +def test_patch_deco(router) -> None: routes = web.RouteTableDef() @routes.patch('/path') @@ -216,7 +216,7 @@ def test_patch_deco(router): assert str(route.url_for()) == '/path' -def test_delete_deco(router): +def test_delete_deco(router) -> None: routes = web.RouteTableDef() @routes.delete('/path') @@ -232,7 +232,7 @@ def test_delete_deco(router): assert str(route.url_for()) == '/path' -def test_route_deco(router): +def test_route_deco(router) -> None: routes = web.RouteTableDef() @routes.route('OTHER', '/path') @@ -248,7 +248,7 @@ def test_route_deco(router): assert str(route.url_for()) == '/path' -def test_routedef_sequence_protocol(): +def test_routedef_sequence_protocol() -> None: routes = web.RouteTableDef() @routes.delete('/path') @@ -263,7 +263,7 @@ def test_routedef_sequence_protocol(): assert list(routes)[0] is info -def test_repr_route_def(): +def test_repr_route_def() -> None: routes = web.RouteTableDef() @routes.get('/path') @@ -274,7 +274,7 @@ def test_repr_route_def(): assert repr(rd) == "<RouteDef GET /path -> 'handler'>" -def test_repr_route_def_with_extra_info(): +def test_repr_route_def_with_extra_info() -> None: routes = web.RouteTableDef() @routes.get('/path', extra='info') @@ -285,7 +285,7 @@ def test_repr_route_def_with_extra_info(): assert repr(rd) == "<RouteDef GET /path -> 'handler', extra='info'>" -def test_repr_static_def(): +def test_repr_static_def() -> None: routes = web.RouteTableDef() routes.static('/prefix', '/path', name='name') @@ -294,7 +294,7 @@ def test_repr_static_def(): assert repr(rd) == "<StaticDef /prefix -> /path, name='name'>" -def test_repr_route_table_def(): +def test_repr_route_table_def() -> None: routes = web.RouteTableDef() @routes.get('/path') diff --git a/tests/test_run_app.py b/tests/test_run_app.py index ce95fd8..4d8fa12 100644 --- a/tests/test_run_app.py +++ b/tests/test_run_app.py @@ -1,5 +1,6 @@ import asyncio import contextlib +import logging import os import platform import signal @@ -13,6 +14,7 @@ from uuid import uuid4 import pytest from aiohttp import web +from aiohttp.helpers import PY_37 from aiohttp.test_utils import make_mocked_coro @@ -86,7 +88,7 @@ def stopper(loop): return f -def test_run_app_http(patched_loop): +def test_run_app_http(patched_loop) -> None: app = web.Application() startup_handler = make_mocked_coro() app.on_startup.append(startup_handler) @@ -103,7 +105,7 @@ def test_run_app_http(patched_loop): cleanup_handler.assert_called_once_with(app) -def test_run_app_close_loop(patched_loop): +def test_run_app_close_loop(patched_loop) -> None: app = web.Application() web.run_app(app, print=stopper(patched_loop)) @@ -308,7 +310,7 @@ def test_run_app_mixed_bindings(run_app_kwargs, expected_server_calls, expected_server_calls) -def test_run_app_https(patched_loop): +def test_run_app_https(patched_loop) -> None: app = web.Application() ssl_context = ssl.create_default_context() @@ -319,7 +321,8 @@ def test_run_app_https(patched_loop): reuse_address=None, reuse_port=None) -def test_run_app_nondefault_host_port(patched_loop, aiohttp_unused_port): +def test_run_app_nondefault_host_port(patched_loop, + aiohttp_unused_port) -> None: port = aiohttp_unused_port() host = '127.0.0.1' @@ -332,7 +335,7 @@ def test_run_app_nondefault_host_port(patched_loop, aiohttp_unused_port): reuse_port=None) -def test_run_app_custom_backlog(patched_loop): +def test_run_app_custom_backlog(patched_loop) -> None: app = web.Application() web.run_app(app, backlog=10, print=stopper(patched_loop)) @@ -341,7 +344,7 @@ def test_run_app_custom_backlog(patched_loop): reuse_address=None, reuse_port=None) -def test_run_app_custom_backlog_unix(patched_loop): +def test_run_app_custom_backlog_unix(patched_loop) -> None: app = web.Application() web.run_app(app, path='/tmp/tmpsock.sock', backlog=10, print=stopper(patched_loop)) @@ -351,7 +354,7 @@ def test_run_app_custom_backlog_unix(patched_loop): @skip_if_no_unix_socks -def test_run_app_http_unix_socket(patched_loop, shorttmpdir): +def test_run_app_http_unix_socket(patched_loop, shorttmpdir) -> None: app = web.Application() sock_path = str(shorttmpdir / 'socket.sock') @@ -364,7 +367,7 @@ def test_run_app_http_unix_socket(patched_loop, shorttmpdir): @skip_if_no_unix_socks -def test_run_app_https_unix_socket(patched_loop, shorttmpdir): +def test_run_app_https_unix_socket(patched_loop, shorttmpdir) -> None: app = web.Application() sock_path = str(shorttmpdir / 'socket.sock') @@ -379,7 +382,7 @@ def test_run_app_https_unix_socket(patched_loop, shorttmpdir): @skip_if_no_unix_socks @skip_if_no_abstract_paths -def test_run_app_abstract_linux_socket(patched_loop): +def test_run_app_abstract_linux_socket(patched_loop) -> None: sock_path = b"\x00" + uuid4().hex.encode('ascii') app = web.Application() web.run_app( @@ -394,7 +397,7 @@ def test_run_app_abstract_linux_socket(patched_loop): ) -def test_run_app_preexisting_inet_socket(patched_loop, mocker): +def test_run_app_preexisting_inet_socket(patched_loop, mocker) -> None: app = web.Application() sock = socket.socket() @@ -412,7 +415,7 @@ def test_run_app_preexisting_inet_socket(patched_loop, mocker): @pytest.mark.skipif(not HAS_IPV6, reason="IPv6 is not available") -def test_run_app_preexisting_inet6_socket(patched_loop): +def test_run_app_preexisting_inet6_socket(patched_loop) -> None: app = web.Application() sock = socket.socket(socket.AF_INET6) @@ -430,7 +433,7 @@ def test_run_app_preexisting_inet6_socket(patched_loop): @skip_if_no_unix_socks -def test_run_app_preexisting_unix_socket(patched_loop, mocker): +def test_run_app_preexisting_unix_socket(patched_loop, mocker) -> None: app = web.Application() sock_path = '/tmp/test_preexisting_sock1' @@ -448,7 +451,7 @@ def test_run_app_preexisting_unix_socket(patched_loop, mocker): assert "http://unix:{}:".format(sock_path) in printer.call_args[0][0] -def test_run_app_multiple_preexisting_sockets(patched_loop): +def test_run_app_multiple_preexisting_sockets(patched_loop) -> None: app = web.Application() sock1 = socket.socket() @@ -478,7 +481,7 @@ web.run_app(app, host=()) """ -def test_sigint(): +def test_sigint() -> None: skip_if_on_windows() proc = subprocess.Popen([sys.executable, "-u", "-c", _script_test_signal], @@ -490,7 +493,7 @@ def test_sigint(): assert proc.wait() == 0 -def test_sigterm(): +def test_sigterm() -> None: skip_if_on_windows() proc = subprocess.Popen([sys.executable, "-u", "-c", _script_test_signal], @@ -502,7 +505,7 @@ def test_sigterm(): assert proc.wait() == 0 -def test_startup_cleanup_signals_even_on_failure(patched_loop): +def test_startup_cleanup_signals_even_on_failure(patched_loop) -> None: patched_loop.create_server = mock.Mock(side_effect=RuntimeError()) app = web.Application() @@ -518,7 +521,7 @@ def test_startup_cleanup_signals_even_on_failure(patched_loop): cleanup_handler.assert_called_once_with(app) -def test_run_app_coro(patched_loop): +def test_run_app_coro(patched_loop) -> None: startup_handler = cleanup_handler = None async def make_app(): @@ -538,3 +541,184 @@ def test_run_app_coro(patched_loop): reuse_port=None) startup_handler.assert_called_once_with(mock.ANY) cleanup_handler.assert_called_once_with(mock.ANY) + + +def test_run_app_default_logger(monkeypatch, patched_loop): + patched_loop.set_debug(True) + logger = web.access_logger + attrs = { + 'hasHandlers.return_value': False, + 'level': logging.NOTSET, + 'name': 'aiohttp.access', + } + mock_logger = mock.create_autospec(logger, name='mock_access_logger') + mock_logger.configure_mock(**attrs) + + app = web.Application() + web.run_app(app, + print=stopper(patched_loop), + access_log=mock_logger) + mock_logger.setLevel.assert_any_call(logging.DEBUG) + mock_logger.hasHandlers.assert_called_with() + assert isinstance(mock_logger.addHandler.call_args[0][0], + logging.StreamHandler) + + +def test_run_app_default_logger_setup_requires_debug(patched_loop): + patched_loop.set_debug(False) + logger = web.access_logger + attrs = { + 'hasHandlers.return_value': False, + 'level': logging.NOTSET, + 'name': 'aiohttp.access', + } + mock_logger = mock.create_autospec(logger, name='mock_access_logger') + mock_logger.configure_mock(**attrs) + + app = web.Application() + web.run_app(app, + print=stopper(patched_loop), + access_log=mock_logger) + mock_logger.setLevel.assert_not_called() + mock_logger.hasHandlers.assert_not_called() + mock_logger.addHandler.assert_not_called() + + +def test_run_app_default_logger_setup_requires_default_logger(patched_loop): + patched_loop.set_debug(True) + logger = web.access_logger + attrs = { + 'hasHandlers.return_value': False, + 'level': logging.NOTSET, + 'name': None, + } + mock_logger = mock.create_autospec(logger, name='mock_access_logger') + mock_logger.configure_mock(**attrs) + + app = web.Application() + web.run_app(app, + print=stopper(patched_loop), + access_log=mock_logger) + mock_logger.setLevel.assert_not_called() + mock_logger.hasHandlers.assert_not_called() + mock_logger.addHandler.assert_not_called() + + +def test_run_app_default_logger_setup_only_if_unconfigured(patched_loop): + patched_loop.set_debug(True) + logger = web.access_logger + attrs = { + 'hasHandlers.return_value': True, + 'level': None, + 'name': 'aiohttp.access', + } + mock_logger = mock.create_autospec(logger, name='mock_access_logger') + mock_logger.configure_mock(**attrs) + + app = web.Application() + web.run_app(app, + print=stopper(patched_loop), + access_log=mock_logger) + mock_logger.setLevel.assert_not_called() + mock_logger.hasHandlers.assert_called_with() + mock_logger.addHandler.assert_not_called() + + +def test_run_app_cancels_all_pending_tasks(patched_loop): + app = web.Application() + task = None + + async def on_startup(app): + nonlocal task + loop = asyncio.get_event_loop() + task = loop.create_task(asyncio.sleep(1000)) + + app.on_startup.append(on_startup) + + web.run_app(app, print=stopper(patched_loop)) + assert task.cancelled() + + +def test_run_app_cancels_done_tasks(patched_loop): + app = web.Application() + task = None + + async def coro(): + return 123 + + async def on_startup(app): + nonlocal task + loop = asyncio.get_event_loop() + task = loop.create_task(coro()) + + app.on_startup.append(on_startup) + + web.run_app(app, print=stopper(patched_loop)) + assert task.done() + + +def test_run_app_cancels_failed_tasks(patched_loop): + app = web.Application() + task = None + + exc = RuntimeError("FAIL") + + async def fail(): + try: + await asyncio.sleep(1000) + except asyncio.CancelledError: + raise exc + + async def on_startup(app): + nonlocal task + loop = asyncio.get_event_loop() + task = loop.create_task(fail()) + await asyncio.sleep(0.01) + + app.on_startup.append(on_startup) + + exc_handler = mock.Mock() + patched_loop.set_exception_handler(exc_handler) + web.run_app(app, print=stopper(patched_loop)) + assert task.done() + + msg = { + 'message': 'unhandled exception during asyncio.run() shutdown', + 'exception': exc, + 'task': task, + } + exc_handler.assert_called_with(patched_loop, msg) + + +@pytest.mark.skipif(not PY_37, + reason="contextvars support is required") +def test_run_app_context_vars(patched_loop): + from contextvars import ContextVar + + count = 0 + VAR = ContextVar('VAR', default='default') + + async def on_startup(app): + nonlocal count + assert 'init' == VAR.get() + VAR.set('on_startup') + count += 1 + + async def on_cleanup(app): + nonlocal count + assert 'on_startup' == VAR.get() + count += 1 + + async def init(): + nonlocal count + assert 'default' == VAR.get() + VAR.set('init') + app = web.Application() + + app.on_startup.append(on_startup) + app.on_cleanup.append(on_cleanup) + count += 1 + return app + + web.run_app(init(), print=stopper(patched_loop)) + assert count == 3 diff --git a/tests/test_signals.py b/tests/test_signals.py index 12478a8..0b625d0 100644 --- a/tests/test_signals.py +++ b/tests/test_signals.py @@ -18,7 +18,7 @@ def make_request(app, method, path, headers=CIMultiDict()): return make_mocked_request(method, path, headers, app=app) -async def test_add_signal_handler_not_a_callable(app): +async def test_add_signal_handler_not_a_callable(app) -> None: callback = True app.on_response_prepare.append(callback) app.on_response_prepare.freeze() @@ -26,7 +26,7 @@ async def test_add_signal_handler_not_a_callable(app): await app.on_response_prepare(None, None) -async def test_function_signal_dispatch(app): +async def test_function_signal_dispatch(app) -> None: signal = Signal(app) kwargs = {'foo': 1, 'bar': 2} @@ -42,7 +42,7 @@ async def test_function_signal_dispatch(app): callback_mock.assert_called_once_with(**kwargs) -async def test_function_signal_dispatch2(app): +async def test_function_signal_dispatch2(app) -> None: signal = Signal(app) args = {'a', 'b'} kwargs = {'foo': 1, 'bar': 2} @@ -59,7 +59,7 @@ async def test_function_signal_dispatch2(app): callback_mock.assert_called_once_with(*args, **kwargs) -async def test_response_prepare(app): +async def test_response_prepare(app) -> None: callback = mock.Mock() async def cb(*args, **kwargs): @@ -75,7 +75,7 @@ async def test_response_prepare(app): callback.assert_called_once_with(request, response) -async def test_non_coroutine(app): +async def test_non_coroutine(app) -> None: signal = Signal(app) kwargs = {'foo': 1, 'bar': 2} @@ -88,7 +88,7 @@ async def test_non_coroutine(app): await signal.send(**kwargs) -def test_setitem(app): +def test_setitem(app) -> None: signal = Signal(app) m1 = mock.Mock() signal.append(m1) @@ -98,7 +98,7 @@ def test_setitem(app): assert signal[0] is m2 -def test_delitem(app): +def test_delitem(app) -> None: signal = Signal(app) m1 = mock.Mock() signal.append(m1) @@ -107,7 +107,7 @@ def test_delitem(app): assert len(signal) == 0 -def test_cannot_append_to_frozen_signal(app): +def test_cannot_append_to_frozen_signal(app) -> None: signal = Signal(app) m1 = mock.Mock() m2 = mock.Mock() @@ -119,7 +119,7 @@ def test_cannot_append_to_frozen_signal(app): assert list(signal) == [m1] -def test_cannot_setitem_in_frozen_signal(app): +def test_cannot_setitem_in_frozen_signal(app) -> None: signal = Signal(app) m1 = mock.Mock() m2 = mock.Mock() @@ -131,7 +131,7 @@ def test_cannot_setitem_in_frozen_signal(app): assert list(signal) == [m1] -def test_cannot_delitem_in_frozen_signal(app): +def test_cannot_delitem_in_frozen_signal(app) -> None: signal = Signal(app) m1 = mock.Mock() signal.append(m1) @@ -142,7 +142,7 @@ def test_cannot_delitem_in_frozen_signal(app): assert list(signal) == [m1] -async def test_cannot_send_non_frozen_signal(app): +async def test_cannot_send_non_frozen_signal(app) -> None: signal = Signal(app) callback = make_mocked_coro() @@ -155,7 +155,7 @@ async def test_cannot_send_non_frozen_signal(app): assert not callback.called -async def test_repr(app): +async def test_repr(app) -> None: signal = Signal(app) callback = make_mocked_coro() diff --git a/tests/test_streams.py b/tests/test_streams.py index 3d7b8b3..0f0a9fa 100644 --- a/tests/test_streams.py +++ b/tests/test_streams.py @@ -17,7 +17,8 @@ def chunkify(seq, n): yield seq[i:i+n] -def create_stream(loop): +async def create_stream(): + loop = asyncio.get_event_loop() protocol = mock.Mock(_reading_paused=False) stream = streams.StreamReader(protocol, loop=loop) stream.feed_data(DATA) @@ -38,20 +39,21 @@ class TestStreamReader: return streams.StreamReader(mock.Mock(_reading_paused=False), *args, **kwargs) - async def test_create_waiter(self, loop): + async def test_create_waiter(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one(loop=loop) stream._waiter = loop.create_future with pytest.raises(RuntimeError): await stream._wait('test') - def test_ctor_global_loop(self): + def test_ctor_global_loop(self) -> None: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) stream = streams.StreamReader(mock.Mock(_reading_paused=False)) assert stream._loop is loop - async def test_at_eof(self): + async def test_at_eof(self) -> None: stream = self._make_one() assert not stream.at_eof() @@ -66,7 +68,8 @@ class TestStreamReader: await stream.readline() assert stream.at_eof() - async def test_wait_eof(self, loop): + async def test_wait_eof(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one() wait_task = loop.create_task(stream.wait_eof()) @@ -79,7 +82,8 @@ class TestStreamReader: assert stream.is_eof() assert stream._eof_waiter is None - async def test_wait_eof_eof(self, loop): + async def test_wait_eof_eof(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one() stream.feed_eof() @@ -87,7 +91,7 @@ class TestStreamReader: await wait_task assert stream.is_eof() - async def test_feed_empty_data(self): + async def test_feed_empty_data(self) -> None: stream = self._make_one() stream.feed_data(b'') stream.feed_eof() @@ -95,7 +99,7 @@ class TestStreamReader: data = await stream.read() assert b'' == data - async def test_feed_nonempty_data(self): + async def test_feed_nonempty_data(self) -> None: stream = self._make_one() stream.feed_data(self.DATA) stream.feed_eof() @@ -103,7 +107,7 @@ class TestStreamReader: data = await stream.read() assert self.DATA == data - async def test_read_zero(self): + async def test_read_zero(self) -> None: # Read zero bytes. stream = self._make_one() stream.feed_data(self.DATA) @@ -115,7 +119,8 @@ class TestStreamReader: data = await stream.read() assert self.DATA == data - async def test_read(self, loop): + async def test_read(self) -> None: + loop = asyncio.get_event_loop() # Read bytes. stream = self._make_one() read_task = loop.create_task(stream.read(30)) @@ -131,7 +136,7 @@ class TestStreamReader: data = await stream.read() assert b'' == data - async def test_read_line_breaks(self): + async def test_read_line_breaks(self) -> None: # Read bytes without line breaks. stream = self._make_one() stream.feed_data(b'line1') @@ -143,7 +148,7 @@ class TestStreamReader: data = await stream.read(5) assert b'line2' == data - async def test_read_all(self): + async def test_read_all(self) -> None: # Read all available buffered bytes stream = self._make_one() stream.feed_data(b'line1') @@ -153,7 +158,7 @@ class TestStreamReader: data = await stream.read() assert b'line1line2' == data - async def test_read_up_to(self): + async def test_read_up_to(self) -> None: # Read available buffered bytes up to requested amount stream = self._make_one() stream.feed_data(b'line1') @@ -165,7 +170,8 @@ class TestStreamReader: data = await stream.read(8) assert b'e2' == data - async def test_read_eof(self, loop): + async def test_read_eof(self) -> None: + loop = asyncio.get_event_loop() # Read bytes, stop at eof. stream = self._make_one() read_task = loop.create_task(stream.read(1024)) @@ -180,7 +186,7 @@ class TestStreamReader: data = await stream.read() assert data == b'' - async def test_read_eof_infinit(self): + async def test_read_eof_infinite(self) -> None: # Read bytes. stream = self._make_one() stream.feed_eof() @@ -194,7 +200,7 @@ class TestStreamReader: await stream.read() assert internal_logger.warning.called - async def test_read_eof_unread_data_no_warning(self): + async def test_read_eof_unread_data_no_warning(self) -> None: # Read bytes. stream = self._make_one() stream.feed_eof() @@ -205,12 +211,14 @@ class TestStreamReader: await stream.read() await stream.read() await stream.read() - stream.unread_data(b'data') + with pytest.warns(DeprecationWarning): + stream.unread_data(b'data') await stream.read() await stream.read() assert not internal_logger.warning.called - async def test_read_until_eof(self, loop): + async def test_read_until_eof(self) -> None: + loop = asyncio.get_event_loop() # Read all bytes until eof. stream = self._make_one() read_task = loop.create_task(stream.read(-1)) @@ -227,7 +235,7 @@ class TestStreamReader: data = await stream.read() assert b'' == data - async def test_read_exception(self): + async def test_read_exception(self) -> None: stream = self._make_one() stream.feed_data(b'line\n') @@ -238,7 +246,8 @@ class TestStreamReader: with pytest.raises(ValueError): await stream.read(2) - async def test_readline(self, loop): + async def test_readline(self) -> None: + loop = asyncio.get_event_loop() # Read one line. 'readline' will need to wait for the data # to come from 'cb' stream = self._make_one() @@ -258,7 +267,7 @@ class TestStreamReader: data = await stream.read() assert b' chunk4' == data - async def test_readline_limit_with_existing_data(self): + async def test_readline_limit_with_existing_data(self) -> None: # Read one line. The data is in StreamReader's buffer # before the event loop is run. @@ -273,7 +282,8 @@ class TestStreamReader: data = await stream.read() assert b'line2\n' == data - async def test_readline_limit(self, loop): + async def test_readline_limit(self) -> None: + loop = asyncio.get_event_loop() # Read one line. StreamReaders are fed with data after # their 'readline' methods are called. stream = self._make_one(limit=4) @@ -290,7 +300,7 @@ class TestStreamReader: data = await stream.read() assert b'chunk3\n' == data - async def test_readline_nolimit_nowait(self): + async def test_readline_nolimit_nowait(self) -> None: # All needed data for the first 'readline' call will be # in the buffer. stream = self._make_one() @@ -304,7 +314,7 @@ class TestStreamReader: data = await stream.read() assert b'line2\nline3\n' == data - async def test_readline_eof(self): + async def test_readline_eof(self) -> None: stream = self._make_one() stream.feed_data(b'some data') stream.feed_eof() @@ -312,14 +322,14 @@ class TestStreamReader: line = await stream.readline() assert b'some data' == line - async def test_readline_empty_eof(self): + async def test_readline_empty_eof(self) -> None: stream = self._make_one() stream.feed_eof() line = await stream.readline() assert b'' == line - async def test_readline_read_byte_count(self): + async def test_readline_read_byte_count(self) -> None: stream = self._make_one() stream.feed_data(self.DATA) @@ -332,7 +342,7 @@ class TestStreamReader: data = await stream.read() assert b'ine3\n' == data - async def test_readline_exception(self): + async def test_readline_exception(self) -> None: stream = self._make_one() stream.feed_data(b'line\n') @@ -343,7 +353,7 @@ class TestStreamReader: with pytest.raises(ValueError): await stream.readline() - async def test_readexactly_zero_or_less(self): + async def test_readexactly_zero_or_less(self) -> None: # Read exact number of bytes (zero or less). stream = self._make_one() stream.feed_data(self.DATA) @@ -363,7 +373,8 @@ class TestStreamReader: data = await stream.read() assert self.DATA == data - async def test_readexactly(self, loop): + async def test_readexactly(self) -> None: + loop = asyncio.get_event_loop() # Read exact number of bytes. stream = self._make_one() @@ -383,7 +394,8 @@ class TestStreamReader: data = await stream.read() assert self.DATA == data - async def test_readexactly_eof(self, loop): + async def test_readexactly_eof(self) -> None: + loop = asyncio.get_event_loop() # Read exact number of bytes (eof). stream = self._make_one(loop=loop) n = 2 * len(self.DATA) @@ -403,7 +415,7 @@ class TestStreamReader: data = await stream.read() assert b'' == data - async def test_readexactly_exception(self): + async def test_readexactly_exception(self) -> None: stream = self._make_one() stream.feed_data(b'line\n') @@ -414,7 +426,7 @@ class TestStreamReader: with pytest.raises(ValueError): await stream.readexactly(2) - async def test_unread_data(self): + async def test_unread_data(self) -> None: stream = self._make_one() stream.feed_data(b'line1') stream.feed_data(b'line2') @@ -423,7 +435,8 @@ class TestStreamReader: data = await stream.read(5) assert b'line1' == data - stream.unread_data(data) + with pytest.warns(DeprecationWarning): + stream.unread_data(data) data = await stream.read(5) assert b'line1' == data @@ -431,7 +444,8 @@ class TestStreamReader: data = await stream.read(4) assert b'line' == data - stream.unread_data(b'line1line') + with pytest.warns(DeprecationWarning): + stream.unread_data(b'line1line') data = b'' while len(data) < 10: @@ -441,23 +455,26 @@ class TestStreamReader: data = await stream.read(7) assert b'onemore' == data - stream.unread_data(data) + with pytest.warns(DeprecationWarning): + stream.unread_data(data) data = b'' while len(data) < 11: data += await stream.read(11) assert b'onemoreline' == data - stream.unread_data(b'line') + with pytest.warns(DeprecationWarning): + stream.unread_data(b'line') data = await stream.read(4) assert b'line' == data stream.feed_eof() - stream.unread_data(b'at_eof') + with pytest.warns(DeprecationWarning): + stream.unread_data(b'at_eof') data = await stream.read(6) assert b'at_eof' == data - async def test_exception(self): + async def test_exception(self) -> None: stream = self._make_one() assert stream.exception() is None @@ -465,7 +482,8 @@ class TestStreamReader: stream.set_exception(exc) assert stream.exception() is exc - async def test_exception_waiter(self, loop): + async def test_exception_waiter(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one() async def set_err(): @@ -478,7 +496,8 @@ class TestStreamReader: with pytest.raises(ValueError): t1.result() - async def test_exception_cancel(self, loop): + async def test_exception_cancel(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one() async def read_a_line(): @@ -493,7 +512,8 @@ class TestStreamReader: await asyncio.sleep(0) assert stream._waiter is None - async def test_readany_eof(self, loop): + async def test_readany_eof(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one() read_task = loop.create_task(stream.readany()) loop.call_soon(stream.feed_data, b'chunk1\n') @@ -504,7 +524,8 @@ class TestStreamReader: data = await stream.read() assert b'' == data - async def test_readany_empty_eof(self, loop): + async def test_readany_empty_eof(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one() stream.feed_eof() read_task = loop.create_task(stream.readany()) @@ -513,7 +534,7 @@ class TestStreamReader: assert b'' == data - async def test_readany_exception(self): + async def test_readany_exception(self) -> None: stream = self._make_one() stream.feed_data(b'line\n') @@ -524,7 +545,7 @@ class TestStreamReader: with pytest.raises(ValueError): await stream.readany() - async def test_read_nowait(self): + async def test_read_nowait(self) -> None: stream = self._make_one() stream.feed_data(b'line1\nline2\n') @@ -534,7 +555,7 @@ class TestStreamReader: data = await stream.read() assert b'' == data - async def test_read_nowait_n(self): + async def test_read_nowait_n(self) -> None: stream = self._make_one() stream.feed_data(b'line1\nline2\n') @@ -545,7 +566,7 @@ class TestStreamReader: data = await stream.read() assert b'' == data - async def test_read_nowait_exception(self): + async def test_read_nowait_exception(self) -> None: stream = self._make_one() stream.feed_data(b'line\n') stream.set_exception(ValueError()) @@ -553,7 +574,8 @@ class TestStreamReader: with pytest.raises(ValueError): stream.read_nowait() - async def test_read_nowait_waiter(self, loop): + async def test_read_nowait_waiter(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one() stream.feed_data(b'line\n') stream._waiter = loop.create_future() @@ -561,7 +583,8 @@ class TestStreamReader: with pytest.raises(RuntimeError): stream.read_nowait() - async def test_readchunk(self, loop): + async def test_readchunk(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one() def cb(): @@ -582,7 +605,8 @@ class TestStreamReader: assert b'' == data assert not end_of_chunk - async def test_readchunk_wait_eof(self, loop): + async def test_readchunk_wait_eof(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one() async def cb(): @@ -595,7 +619,7 @@ class TestStreamReader: assert not end_of_chunk assert stream.is_eof() - async def test_begin_and_end_chunk_receiving(self): + async def test_begin_and_end_chunk_receiving(self) -> None: stream = self._make_one() stream.begin_http_chunk_receiving() @@ -626,12 +650,12 @@ class TestStreamReader: assert b'' == data assert not end_of_chunk - async def test_end_chunk_receiving_without_begin(self): + async def test_end_chunk_receiving_without_begin(self) -> None: stream = self._make_one() with pytest.raises(RuntimeError): stream.end_http_chunk_receiving() - async def test_readchunk_with_unread(self): + async def test_readchunk_with_unread(self) -> None: """Test that stream.unread does not break controlled chunk receiving. """ stream = self._make_one() @@ -648,7 +672,8 @@ class TestStreamReader: data, end_of_chunk = await stream.readchunk() # Try to unread a part of the first chunk - stream.unread_data(b'rt1') + with pytest.warns(DeprecationWarning): + stream.unread_data(b'rt1') # The end_of_chunk signal was already received for the first chunk, # so we receive up to the second one @@ -657,7 +682,8 @@ class TestStreamReader: assert end_of_chunk # Unread a part of the second chunk - stream.unread_data(b'rt2') + with pytest.warns(DeprecationWarning): + stream.unread_data(b'rt2') data, end_of_chunk = await stream.readchunk() assert b'rt2' == data @@ -669,7 +695,7 @@ class TestStreamReader: assert b'' == data assert not end_of_chunk - async def test_readchunk_with_other_read_calls(self): + async def test_readchunk_with_other_read_calls(self) -> None: """Test that stream.readchunk works when other read calls are made on the stream. """ @@ -694,52 +720,117 @@ class TestStreamReader: assert b'' == data assert not end_of_chunk - async def test___repr__(self): + async def test_readchunk_separate_http_chunk_tail(self) -> None: + """Test that stream.readchunk returns (b'', True) when end of + http chunk received after body + """ + loop = asyncio.get_event_loop() + stream = self._make_one() + + stream.begin_http_chunk_receiving() + stream.feed_data(b'part1') + + data, end_of_chunk = await stream.readchunk() + assert b'part1' == data + assert not end_of_chunk + + async def cb(): + await asyncio.sleep(0.1) + stream.end_http_chunk_receiving() + + loop.create_task(cb()) + data, end_of_chunk = await stream.readchunk() + assert b'' == data + assert end_of_chunk + + stream.begin_http_chunk_receiving() + stream.feed_data(b'part2') + data, end_of_chunk = await stream.readchunk() + assert b'part2' == data + assert not end_of_chunk + + stream.end_http_chunk_receiving() + stream.begin_http_chunk_receiving() + stream.feed_data(b'part3') + stream.end_http_chunk_receiving() + + data, end_of_chunk = await stream.readchunk() + assert b'' == data + assert end_of_chunk + + data, end_of_chunk = await stream.readchunk() + assert b'part3' == data + assert end_of_chunk + + stream.begin_http_chunk_receiving() + stream.feed_data(b'part4') + data, end_of_chunk = await stream.readchunk() + assert b'part4' == data + assert not end_of_chunk + + async def cb(): + await asyncio.sleep(0.1) + stream.end_http_chunk_receiving() + stream.feed_eof() + + loop.create_task(cb()) + data, end_of_chunk = await stream.readchunk() + assert b'' == data + assert end_of_chunk + + data, end_of_chunk = await stream.readchunk() + assert b'' == data + assert not end_of_chunk + + async def test___repr__(self) -> None: stream = self._make_one() assert "<StreamReader>" == repr(stream) - async def test___repr__nondefault_limit(self): + async def test___repr__nondefault_limit(self) -> None: stream = self._make_one(limit=123) assert "<StreamReader low=123 high=246>" == repr(stream) - async def test___repr__eof(self): + async def test___repr__eof(self) -> None: stream = self._make_one() stream.feed_eof() assert "<StreamReader eof>" == repr(stream) - async def test___repr__data(self): + async def test___repr__data(self) -> None: stream = self._make_one() stream.feed_data(b'data') assert "<StreamReader 4 bytes>" == repr(stream) - def test___repr__exception(self, loop): + async def test___repr__exception(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one(loop=loop) exc = RuntimeError() stream.set_exception(exc) assert "<StreamReader e=RuntimeError()>" == repr(stream) - async def test___repr__waiter(self, loop): + async def test___repr__waiter(self) -> None: + loop = asyncio.get_event_loop() stream = self._make_one() stream._waiter = loop.create_future() - assert re.search("<StreamReader w=<Future pending[\S ]*>>", + assert re.search(r"<StreamReader w=<Future pending[\S ]*>>", repr(stream)) stream._waiter.set_result(None) await stream._waiter stream._waiter = None assert "<StreamReader>" == repr(stream) - async def test_unread_empty(self): + async def test_unread_empty(self) -> None: stream = self._make_one() stream.feed_data(b'line1') stream.feed_eof() - stream.unread_data(b'') + with pytest.warns(DeprecationWarning): + stream.unread_data(b'') data = await stream.read(5) assert b'line1' == data assert stream.at_eof() -async def test_empty_stream_reader(): +async def test_empty_stream_reader() -> None: s = streams.EmptyStreamReader() assert s.set_exception(ValueError()) is None assert s.exception() is None @@ -750,41 +841,42 @@ async def test_empty_stream_reader(): assert await s.read() == b'' assert await s.readline() == b'' assert await s.readany() == b'' - assert await s.readchunk() == (b'', False) + assert await s.readchunk() == (b'', True) with pytest.raises(asyncio.IncompleteReadError): await s.readexactly(10) assert s.read_nowait() == b'' @pytest.fixture -def buffer(loop): - return streams.DataQueue(loop=loop) +async def buffer(loop): + return streams.DataQueue(loop) class TestDataQueue: - def test_is_eof(self, buffer): + def test_is_eof(self, buffer) -> None: assert not buffer.is_eof() buffer.feed_eof() assert buffer.is_eof() - def test_at_eof(self, buffer): + def test_at_eof(self, buffer) -> None: assert not buffer.at_eof() buffer.feed_eof() assert buffer.at_eof() buffer._buffer.append(object()) assert not buffer.at_eof() - def test_feed_data(self, buffer): + def test_feed_data(self, buffer) -> None: item = object() buffer.feed_data(item, 1) assert [(item, 1)] == list(buffer._buffer) - def test_feed_eof(self, buffer): + def test_feed_eof(self, buffer) -> None: buffer.feed_eof() assert buffer._eof - async def test_read(self, buffer, loop): + async def test_read(self, buffer) -> None: + loop = asyncio.get_event_loop() item = object() def cb(): @@ -794,7 +886,9 @@ class TestDataQueue: data = await buffer.read() assert item is data - async def test_read_eof(self, buffer, loop): + async def test_read_eof(self, buffer) -> None: + loop = asyncio.get_event_loop() + def cb(): buffer.feed_eof() loop.call_soon(cb) @@ -802,7 +896,8 @@ class TestDataQueue: with pytest.raises(streams.EofStream): await buffer.read() - async def test_read_cancelled(self, buffer, loop): + async def test_read_cancelled(self, buffer) -> None: + loop = asyncio.get_event_loop() read_task = loop.create_task(buffer.read()) await asyncio.sleep(0) waiter = buffer._waiter @@ -817,7 +912,7 @@ class TestDataQueue: buffer.feed_data(b'test', 4) assert buffer._waiter is None - async def test_read_until_eof(self, buffer): + async def test_read_until_eof(self, buffer) -> None: item = object() buffer.feed_data(item, 1) buffer.feed_eof() @@ -828,7 +923,7 @@ class TestDataQueue: with pytest.raises(streams.EofStream): await buffer.read() - async def test_read_exc(self, buffer): + async def test_read_exc(self, buffer) -> None: item = object() buffer.feed_data(item) buffer.set_exception(ValueError) @@ -839,13 +934,13 @@ class TestDataQueue: with pytest.raises(ValueError): await buffer.read() - async def test_read_exception(self, buffer): + async def test_read_exception(self, buffer) -> None: buffer.set_exception(ValueError()) with pytest.raises(ValueError): await buffer.read() - async def test_read_exception_with_data(self, buffer): + async def test_read_exception_with_data(self, buffer) -> None: val = object() buffer.feed_data(val, 1) buffer.set_exception(ValueError()) @@ -854,7 +949,8 @@ class TestDataQueue: with pytest.raises(ValueError): await buffer.read() - async def test_read_exception_on_wait(self, buffer, loop): + async def test_read_exception_on_wait(self, buffer) -> None: + loop = asyncio.get_event_loop() read_task = loop.create_task(buffer.read()) await asyncio.sleep(0) assert asyncio.isfuture(buffer._waiter) @@ -865,14 +961,15 @@ class TestDataQueue: with pytest.raises(ValueError): await read_task - def test_exception(self, buffer): + def test_exception(self, buffer) -> None: assert buffer.exception() is None exc = ValueError() buffer.set_exception(exc) assert buffer.exception() is exc - async def test_exception_waiter(self, buffer, loop): + async def test_exception_waiter(self, buffer) -> None: + loop = asyncio.get_event_loop() async def set_err(): buffer.set_exception(ValueError()) @@ -886,7 +983,8 @@ class TestDataQueue: t1.result() -def test_feed_data_waiters(loop, protocol): +async def test_feed_data_waiters(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) waiter = reader._waiter = loop.create_future() eof_waiter = reader._eof_waiter = loop.create_future() @@ -902,7 +1000,8 @@ def test_feed_data_waiters(loop, protocol): assert reader._eof_waiter is eof_waiter -def test_feed_data_completed_waiters(loop, protocol): +async def test_feed_data_completed_waiters(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) waiter = reader._waiter = loop.create_future() @@ -912,7 +1011,8 @@ def test_feed_data_completed_waiters(loop, protocol): assert reader._waiter is None -def test_feed_eof_waiters(loop, protocol): +async def test_feed_eof_waiters(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) waiter = reader._waiter = loop.create_future() eof_waiter = reader._eof_waiter = loop.create_future() @@ -926,7 +1026,8 @@ def test_feed_eof_waiters(loop, protocol): assert reader._eof_waiter is None -def test_feed_eof_cancelled(loop, protocol): +async def test_feed_eof_cancelled(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) waiter = reader._waiter = loop.create_future() eof_waiter = reader._eof_waiter = loop.create_future() @@ -942,7 +1043,8 @@ def test_feed_eof_cancelled(loop, protocol): assert reader._eof_waiter is None -def test_on_eof(loop, protocol): +async def test_on_eof(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) on_eof = mock.Mock() @@ -953,7 +1055,7 @@ def test_on_eof(loop, protocol): assert on_eof.called -def test_on_eof_empty_reader(loop): +async def test_on_eof_empty_reader() -> None: reader = streams.EmptyStreamReader() on_eof = mock.Mock() @@ -962,7 +1064,8 @@ def test_on_eof_empty_reader(loop): assert on_eof.called -def test_on_eof_exc_in_callback(loop, protocol): +async def test_on_eof_exc_in_callback(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) on_eof = mock.Mock() @@ -975,7 +1078,7 @@ def test_on_eof_exc_in_callback(loop, protocol): assert not reader._eof_callbacks -def test_on_eof_exc_in_callback_empty_stream_reader(loop): +async def test_on_eof_exc_in_callback_empty_stream_reader() -> None: reader = streams.EmptyStreamReader() on_eof = mock.Mock() @@ -985,7 +1088,8 @@ def test_on_eof_exc_in_callback_empty_stream_reader(loop): assert on_eof.called -def test_on_eof_eof_is_set(loop, protocol): +async def test_on_eof_eof_is_set(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) reader.feed_eof() @@ -995,7 +1099,8 @@ def test_on_eof_eof_is_set(loop, protocol): assert not reader._eof_callbacks -def test_on_eof_eof_is_set_exception(loop, protocol): +async def test_on_eof_eof_is_set_exception(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) reader.feed_eof() @@ -1007,7 +1112,8 @@ def test_on_eof_eof_is_set_exception(loop, protocol): assert not reader._eof_callbacks -def test_set_exception(loop, protocol): +async def test_set_exception(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) waiter = reader._waiter = loop.create_future() eof_waiter = reader._eof_waiter = loop.create_future() @@ -1021,7 +1127,8 @@ def test_set_exception(loop, protocol): assert reader._eof_waiter is None -def test_set_exception_cancelled(loop, protocol): +async def test_set_exception_cancelled(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) waiter = reader._waiter = loop.create_future() eof_waiter = reader._eof_waiter = loop.create_future() @@ -1038,7 +1145,8 @@ def test_set_exception_cancelled(loop, protocol): assert reader._eof_waiter is None -def test_set_exception_eof_callbacks(loop, protocol): +async def test_set_exception_eof_callbacks(protocol) -> None: + loop = asyncio.get_event_loop() reader = streams.StreamReader(protocol, loop=loop) on_eof = mock.Mock() @@ -1049,43 +1157,45 @@ def test_set_exception_eof_callbacks(loop, protocol): assert not reader._eof_callbacks -async def test_stream_reader_lines(loop): +async def test_stream_reader_lines() -> None: line_iter = iter(DATA.splitlines(keepends=True)) - async for line in create_stream(loop): + async for line in await create_stream(): assert line == next(line_iter, None) pytest.raises(StopIteration, next, line_iter) -async def test_stream_reader_chunks_complete(loop): +async def test_stream_reader_chunks_complete() -> None: """Tests if chunked iteration works if the chunking works out (i.e. the data is divisible by the chunk size) """ chunk_iter = chunkify(DATA, 9) - async for data in create_stream(loop).iter_chunked(9): + async for data in (await create_stream()).iter_chunked(9): assert data == next(chunk_iter, None) pytest.raises(StopIteration, next, chunk_iter) -async def test_stream_reader_chunks_incomplete(loop): +async def test_stream_reader_chunks_incomplete() -> None: """Tests if chunked iteration works if the last chunk is incomplete""" chunk_iter = chunkify(DATA, 8) - async for data in create_stream(loop).iter_chunked(8): + async for data in (await create_stream()).iter_chunked(8): assert data == next(chunk_iter, None) pytest.raises(StopIteration, next, chunk_iter) -async def test_data_queue_empty(loop): +async def test_data_queue_empty() -> None: """Tests that async looping yields nothing if nothing is there""" - buffer = streams.DataQueue(loop=loop) + loop = asyncio.get_event_loop() + buffer = streams.DataQueue(loop) buffer.feed_eof() async for _ in buffer: # NOQA assert False -async def test_data_queue_items(loop): +async def test_data_queue_items() -> None: """Tests that async looping yields objects identically""" - buffer = streams.DataQueue(loop=loop) + loop = asyncio.get_event_loop() + buffer = streams.DataQueue(loop) items = [object(), object()] buffer.feed_data(items[0], 1) @@ -1098,30 +1208,31 @@ async def test_data_queue_items(loop): pytest.raises(StopIteration, next, item_iter) -async def test_stream_reader_iter_any(loop): +async def test_stream_reader_iter_any() -> None: it = iter([b'line1\nline2\nline3\n']) - async for raw in create_stream(loop).iter_any(): + async for raw in (await create_stream()).iter_any(): assert raw == next(it) pytest.raises(StopIteration, next, it) -async def test_stream_reader_iter(loop): +async def test_stream_reader_iter() -> None: it = iter([b'line1\n', b'line2\n', b'line3\n']) - async for raw in create_stream(loop): + async for raw in await create_stream(): assert raw == next(it) pytest.raises(StopIteration, next, it) -async def test_stream_reader_iter_chunks_no_chunked_encoding(loop): +async def test_stream_reader_iter_chunks_no_chunked_encoding() -> None: it = iter([b'line1\nline2\nline3\n']) - async for data, end_of_chunk in create_stream(loop).iter_chunks(): + async for data, end_of_chunk in (await create_stream()).iter_chunks(): assert (data, end_of_chunk) == (next(it), False) pytest.raises(StopIteration, next, it) -async def test_stream_reader_iter_chunks_chunked_encoding(loop, protocol): +async def test_stream_reader_iter_chunks_chunked_encoding(protocol) -> None: + loop = asyncio.get_event_loop() stream = streams.StreamReader(protocol, loop=loop) for line in DATA.splitlines(keepends=True): stream.begin_http_chunk_receiving() diff --git a/tests/test_tcp_helpers.py b/tests/test_tcp_helpers.py index 70f7357..f23da27 100644 --- a/tests/test_tcp_helpers.py +++ b/tests/test_tcp_helpers.py @@ -19,7 +19,7 @@ if has_ipv6: # nodelay -def test_tcp_nodelay_exception(): +def test_tcp_nodelay_exception() -> None: transport = mock.Mock() s = mock.Mock() s.setsockopt = mock.Mock() @@ -34,7 +34,7 @@ def test_tcp_nodelay_exception(): ) -def test_tcp_nodelay_enable(): +def test_tcp_nodelay_enable() -> None: transport = mock.Mock() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: transport.get_extra_info.return_value = s @@ -42,7 +42,7 @@ def test_tcp_nodelay_enable(): assert s.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY) -def test_tcp_nodelay_enable_and_disable(): +def test_tcp_nodelay_enable_and_disable() -> None: transport = mock.Mock() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: transport.get_extra_info.return_value = s @@ -53,7 +53,7 @@ def test_tcp_nodelay_enable_and_disable(): @pytest.mark.skipif(not has_ipv6, reason="IPv6 is not available") -def test_tcp_nodelay_enable_ipv6(): +def test_tcp_nodelay_enable_ipv6() -> None: transport = mock.Mock() with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s: transport.get_extra_info.return_value = s @@ -63,7 +63,7 @@ def test_tcp_nodelay_enable_ipv6(): @pytest.mark.skipif(not hasattr(socket, 'AF_UNIX'), reason="requires unix sockets") -def test_tcp_nodelay_enable_unix(): +def test_tcp_nodelay_enable_unix() -> None: # do not set nodelay for unix socket transport = mock.Mock() s = mock.Mock(family=socket.AF_UNIX, type=socket.SOCK_STREAM) @@ -72,7 +72,7 @@ def test_tcp_nodelay_enable_unix(): assert not s.setsockopt.called -def test_tcp_nodelay_enable_no_socket(): +def test_tcp_nodelay_enable_no_socket() -> None: transport = mock.Mock() transport.get_extra_info.return_value = None tcp_nodelay(transport, True) @@ -82,7 +82,7 @@ def test_tcp_nodelay_enable_no_socket(): @pytest.mark.skipif(CORK is None, reason="TCP_CORK or TCP_NOPUSH required") -def test_tcp_cork_enable(): +def test_tcp_cork_enable() -> None: transport = mock.Mock() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: transport.get_extra_info.return_value = s @@ -91,7 +91,7 @@ def test_tcp_cork_enable(): @pytest.mark.skipif(CORK is None, reason="TCP_CORK or TCP_NOPUSH required") -def test_set_cork_enable_and_disable(): +def test_set_cork_enable_and_disable() -> None: transport = mock.Mock() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: transport.get_extra_info.return_value = s @@ -103,7 +103,7 @@ def test_set_cork_enable_and_disable(): @pytest.mark.skipif(not has_ipv6, reason="IPv6 is not available") @pytest.mark.skipif(CORK is None, reason="TCP_CORK or TCP_NOPUSH required") -def test_set_cork_enable_ipv6(): +def test_set_cork_enable_ipv6() -> None: transport = mock.Mock() with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s: transport.get_extra_info.return_value = s @@ -114,7 +114,7 @@ def test_set_cork_enable_ipv6(): @pytest.mark.skipif(not hasattr(socket, 'AF_UNIX'), reason="requires unix sockets") @pytest.mark.skipif(CORK is None, reason="TCP_CORK or TCP_NOPUSH required") -def test_set_cork_enable_unix(): +def test_set_cork_enable_unix() -> None: transport = mock.Mock() s = mock.Mock(family=socket.AF_UNIX, type=socket.SOCK_STREAM) transport.get_extra_info.return_value = s @@ -123,14 +123,14 @@ def test_set_cork_enable_unix(): @pytest.mark.skipif(CORK is None, reason="TCP_CORK or TCP_NOPUSH required") -def test_set_cork_enable_no_socket(): +def test_set_cork_enable_no_socket() -> None: transport = mock.Mock() transport.get_extra_info.return_value = None tcp_cork(transport, True) @pytest.mark.skipif(CORK is None, reason="TCP_CORK or TCP_NOPUSH required") -def test_set_cork_exception(): +def test_set_cork_exception() -> None: transport = mock.Mock() s = mock.Mock() s.setsockopt = mock.Mock() diff --git a/tests/test_test_utils.py b/tests/test_test_utils.py index a45e7ca..bf899dc 100644 --- a/tests/test_test_utils.py +++ b/tests/test_test_utils.py @@ -12,7 +12,6 @@ from aiohttp.test_utils import RawTestServer as _RawTestServer from aiohttp.test_utils import TestClient as _TestClient from aiohttp.test_utils import TestServer as _TestServer from aiohttp.test_utils import (loop_context, make_mocked_request, - setup_test_loop, teardown_test_loop, unittest_run_loop) @@ -63,38 +62,40 @@ def app(): @pytest.fixture -def test_client(loop, app): - client = _TestClient(_TestServer(app, loop=loop), loop=loop) +def test_client(loop, app) -> None: + async def make_client(): + return _TestClient(_TestServer(app, loop=loop), loop=loop) + + client = loop.run_until_complete(make_client()) + loop.run_until_complete(client.start_server()) yield client loop.run_until_complete(client.close()) -def test_with_test_server_fails(loop): +def test_with_test_server_fails(loop) -> None: app = _create_example_app() with pytest.raises(TypeError): with _TestServer(app, loop=loop): pass -def test_with_client_fails(loop): +async def test_with_client_fails(loop) -> None: app = _create_example_app() with pytest.raises(TypeError): with _TestClient(_TestServer(app, loop=loop), loop=loop): pass -def test_aiohttp_client_close_is_idempotent(): +async def test_aiohttp_client_close_is_idempotent() -> None: """ a test client, called multiple times, should not attempt to close the server again. """ - loop = setup_test_loop() app = _create_example_app() - client = _TestClient(_TestServer(app, loop=loop), loop=loop) - loop.run_until_complete(client.close()) - loop.run_until_complete(client.close()) - teardown_test_loop(loop) + client = _TestClient(_TestServer(app)) + await client.close() + await client.close() class TestAioHTTPTestCase(AioHTTPTestCase): @@ -103,14 +104,14 @@ class TestAioHTTPTestCase(AioHTTPTestCase): return _create_example_app() @unittest_run_loop - async def test_example_with_loop(self): + async def test_example_with_loop(self) -> None: request = await self.client.request("GET", "/") assert request.status == 200 text = await request.text() assert _hello_world_str == text - def test_example(self): - async def test_get_route(): + def test_example(self) -> None: + async def test_get_route() -> None: resp = await self.client.request("GET", "/") assert resp.status == 200 text = await resp.text() @@ -119,8 +120,8 @@ class TestAioHTTPTestCase(AioHTTPTestCase): self.loop.run_until_complete(test_get_route()) -def test_get_route(loop, test_client): - async def test_get_route(): +def test_get_route(loop, test_client) -> None: + async def test_get_route() -> None: resp = await test_client.request("GET", "/") assert resp.status == 200 text = await resp.text() @@ -129,7 +130,7 @@ def test_get_route(loop, test_client): loop.run_until_complete(test_get_route()) -async def test_client_websocket(loop, test_client): +async def test_client_websocket(loop, test_client) -> None: resp = await test_client.ws_connect("/websocket") await resp.send_str("foo") msg = await resp.receive() @@ -140,7 +141,7 @@ async def test_client_websocket(loop, test_client): assert msg.type == aiohttp.WSMsgType.CLOSE -async def test_client_cookie(loop, test_client): +async def test_client_cookie(loop, test_client) -> None: assert not test_client.session.cookie_jar await test_client.get("/cookie") cookies = list(test_client.session.cookie_jar) @@ -151,21 +152,21 @@ async def test_client_cookie(loop, test_client): @pytest.mark.parametrize("method", [ "get", "post", "options", "post", "put", "patch", "delete" ]) -async def test_test_client_methods(method, loop, test_client): +async def test_test_client_methods(method, loop, test_client) -> None: resp = await getattr(test_client, method)("/") assert resp.status == 200 text = await resp.text() assert _hello_world_str == text -async def test_test_client_head(loop, test_client): +async def test_test_client_head(loop, test_client) -> None: resp = await test_client.head("/") assert resp.status == 200 @pytest.mark.parametrize( "headers", [{'token': 'x'}, CIMultiDict({'token': 'x'}), {}]) -def test_make_mocked_request(headers): +def test_make_mocked_request(headers) -> None: req = make_mocked_request('GET', '/', headers=headers) assert req.method == "GET" assert req.path == "/" @@ -173,40 +174,46 @@ def test_make_mocked_request(headers): assert isinstance(req.headers, CIMultiDictProxy) -def test_make_mocked_request_sslcontext(): +def test_make_mocked_request_sslcontext() -> None: req = make_mocked_request('GET', '/') assert req.transport.get_extra_info('sslcontext') is None -def test_make_mocked_request_unknown_extra_info(): +def test_make_mocked_request_unknown_extra_info() -> None: req = make_mocked_request('GET', '/') assert req.transport.get_extra_info('unknown_extra_info') is None -def test_make_mocked_request_app(): +def test_make_mocked_request_app() -> None: app = mock.Mock() req = make_mocked_request('GET', '/', app=app) assert req.app is app -def test_make_mocked_request_match_info(): +def test_make_mocked_request_app_can_store_values() -> None: + req = make_mocked_request('GET', '/') + req.app['a_field'] = 'a_value' + assert req.app['a_field'] == 'a_value' + + +def test_make_mocked_request_match_info() -> None: req = make_mocked_request('GET', '/', match_info={'a': '1', 'b': '2'}) assert req.match_info == {'a': '1', 'b': '2'} -def test_make_mocked_request_content(): +def test_make_mocked_request_content() -> None: payload = mock.Mock() req = make_mocked_request('GET', '/', payload=payload) assert req.content is payload -def test_make_mocked_request_transport(): +def test_make_mocked_request_transport() -> None: transport = mock.Mock() req = make_mocked_request('GET', '/', transport=transport) assert req.transport is transport -async def test_test_client_props(loop): +async def test_test_client_props(loop) -> None: app = _create_example_app() client = _TestClient(_TestServer(app, host='127.0.0.1', loop=loop), loop=loop) @@ -219,7 +226,7 @@ async def test_test_client_props(loop): assert client.port is None -async def test_test_client_raw_server_props(loop): +async def test_test_client_raw_server_props(loop) -> None: async def hello(request): return web.Response(body=_hello_world_bytes) @@ -235,7 +242,7 @@ async def test_test_client_raw_server_props(loop): assert client.port is None -async def test_test_server_context_manager(loop): +async def test_test_server_context_manager(loop) -> None: app = _create_example_app() async with _TestServer(app, loop=loop) as server: client = aiohttp.ClientSession(loop=loop) @@ -245,7 +252,7 @@ async def test_test_server_context_manager(loop): await client.close() -def test_client_unsupported_arg(): +def test_client_unsupported_arg() -> None: with pytest.raises(TypeError) as e: _TestClient('string') @@ -253,7 +260,7 @@ def test_client_unsupported_arg(): "server must be TestServer instance, found type: <class 'str'>" -async def test_server_make_url_yarl_compatibility(loop): +async def test_server_make_url_yarl_compatibility(loop) -> None: app = _create_example_app() async with _TestServer(app, loop=loop) as server: make_url = server.make_url @@ -264,21 +271,21 @@ async def test_server_make_url_yarl_compatibility(loop): make_url(URL('http://foo.com')) -def test_testcase_no_app(testdir, loop): +def test_testcase_no_app(testdir, loop) -> None: testdir.makepyfile( """ from aiohttp.test_utils import AioHTTPTestCase class InvalidTestCase(AioHTTPTestCase): - def test_noop(self): + def test_noop(self) -> None: pass """) result = testdir.runpytest() result.stdout.fnmatch_lines(["*RuntimeError*"]) -async def test_server_context_manager(app, loop): +async def test_server_context_manager(app, loop) -> None: async with _TestServer(app, loop=loop) as server: async with aiohttp.ClientSession(loop=loop) as client: async with client.head(server.make_url('/')) as resp: @@ -288,7 +295,7 @@ async def test_server_context_manager(app, loop): @pytest.mark.parametrize("method", [ "head", "get", "post", "options", "post", "put", "patch", "delete" ]) -async def test_client_context_manager_response(method, app, loop): +async def test_client_context_manager_response(method, app, loop) -> None: async with _TestClient(_TestServer(app), loop=loop) as client: async with getattr(client, method)('/') as resp: assert resp.status == 200 @@ -297,7 +304,7 @@ async def test_client_context_manager_response(method, app, loop): assert "Hello, world" in text -async def test_custom_port(loop, app, aiohttp_unused_port): +async def test_custom_port(loop, app, aiohttp_unused_port) -> None: port = aiohttp_unused_port() client = _TestClient(_TestServer(app, loop=loop, port=port), loop=loop) await client.start_server() diff --git a/tests/test_tracing.py b/tests/test_tracing.py index cdb22b9..68f4e79 100644 --- a/tests/test_tracing.py +++ b/tests/test_tracing.py @@ -23,22 +23,22 @@ from aiohttp.tracing import (Trace, TraceConfig, class TestTraceConfig: - def test_trace_config_ctx_default(self): + def test_trace_config_ctx_default(self) -> None: trace_config = TraceConfig() assert isinstance(trace_config.trace_config_ctx(), SimpleNamespace) - def test_trace_config_ctx_factory(self): + def test_trace_config_ctx_factory(self) -> None: trace_config = TraceConfig(trace_config_ctx_factory=dict) assert isinstance(trace_config.trace_config_ctx(), dict) - def test_trace_config_ctx_request_ctx(self): + def test_trace_config_ctx_request_ctx(self) -> None: trace_request_ctx = Mock() trace_config = TraceConfig() trace_config_ctx = trace_config.trace_config_ctx( trace_request_ctx=trace_request_ctx) assert trace_config_ctx.trace_request_ctx is trace_request_ctx - def test_freeze(self): + def test_freeze(self) -> None: trace_config = TraceConfig() trace_config.freeze() @@ -138,7 +138,7 @@ class TestTrace: TraceDnsCacheMissParams ) ]) - async def test_send(self, loop, signal, params, param_obj): + async def test_send(self, signal, params, param_obj) -> None: session = Mock() trace_request_ctx = Mock() callback = Mock(side_effect=asyncio.coroutine(Mock())) diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py index f3cdde4..670d8da 100644 --- a/tests/test_urldispatch.py +++ b/tests/test_urldispatch.py @@ -11,17 +11,13 @@ import aiohttp from aiohttp import hdrs, web from aiohttp.test_utils import make_mocked_request from aiohttp.web import HTTPMethodNotAllowed, HTTPNotFound, Response -from aiohttp.web_urldispatcher import (PATH_SEP, AbstractResource, - DynamicResource, PlainResource, - ResourceRoute, StaticResource, - SystemRoute, View, +from aiohttp.web_urldispatcher import (PATH_SEP, AbstractResource, Domain, + DynamicResource, MaskDomain, + PlainResource, ResourceRoute, + StaticResource, SystemRoute, View, _default_expect_handler) -def make_request(method, path): - return make_mocked_request(method, path) - - def make_handler(): async def handler(request): @@ -31,10 +27,8 @@ def make_handler(): @pytest.fixture -def app(loop): - app = web.Application() - app._set_loop(loop) - return app +def app(): + return web.Application() @pytest.fixture @@ -54,7 +48,7 @@ def fill_routes(router): return go -def test_register_uncommon_http_methods(router): +def test_register_uncommon_http_methods(router) -> None: uncommon_http_methods = { 'PROPFIND', 'PROPPATCH', @@ -71,10 +65,10 @@ def test_register_uncommon_http_methods(router): router.add_route(method, '/handler/to/path', make_handler()) -async def test_add_route_root(router): +async def test_add_route_root(router) -> None: handler = make_handler() router.add_route('GET', '/', handler) - req = make_request('GET', '/') + req = make_mocked_request('GET', '/') info = await router.resolve(req) assert info is not None assert 0 == len(info) @@ -82,10 +76,10 @@ async def test_add_route_root(router): assert info.route.name is None -async def test_add_route_simple(router): +async def test_add_route_simple(router) -> None: handler = make_handler() router.add_route('GET', '/handler/to/path', handler) - req = make_request('GET', '/handler/to/path') + req = make_mocked_request('GET', '/handler/to/path') info = await router.resolve(req) assert info is not None assert 0 == len(info) @@ -93,10 +87,10 @@ async def test_add_route_simple(router): assert info.route.name is None -async def test_add_with_matchdict(router): +async def test_add_with_matchdict(router) -> None: handler = make_handler() router.add_route('GET', '/handler/{to}', handler) - req = make_request('GET', '/handler/tail') + req = make_mocked_request('GET', '/handler/tail') info = await router.resolve(req) assert info is not None assert {'to': 'tail'} == info @@ -104,10 +98,10 @@ async def test_add_with_matchdict(router): assert info.route.name is None -async def test_add_with_matchdict_with_colon(router): +async def test_add_with_matchdict_with_colon(router) -> None: handler = make_handler() router.add_route('GET', '/handler/{to}', handler) - req = make_request('GET', '/handler/1:2:3') + req = make_mocked_request('GET', '/handler/1:2:3') info = await router.resolve(req) assert info is not None assert {'to': '1:2:3'} == info @@ -115,10 +109,10 @@ async def test_add_with_matchdict_with_colon(router): assert info.route.name is None -async def test_add_route_with_add_get_shortcut(router): +async def test_add_route_with_add_get_shortcut(router) -> None: handler = make_handler() router.add_get('/handler/to/path', handler) - req = make_request('GET', '/handler/to/path') + req = make_mocked_request('GET', '/handler/to/path') info = await router.resolve(req) assert info is not None assert 0 == len(info) @@ -126,10 +120,10 @@ async def test_add_route_with_add_get_shortcut(router): assert info.route.name is None -async def test_add_route_with_add_post_shortcut(router): +async def test_add_route_with_add_post_shortcut(router) -> None: handler = make_handler() router.add_post('/handler/to/path', handler) - req = make_request('POST', '/handler/to/path') + req = make_mocked_request('POST', '/handler/to/path') info = await router.resolve(req) assert info is not None assert 0 == len(info) @@ -137,10 +131,10 @@ async def test_add_route_with_add_post_shortcut(router): assert info.route.name is None -async def test_add_route_with_add_put_shortcut(router): +async def test_add_route_with_add_put_shortcut(router) -> None: handler = make_handler() router.add_put('/handler/to/path', handler) - req = make_request('PUT', '/handler/to/path') + req = make_mocked_request('PUT', '/handler/to/path') info = await router.resolve(req) assert info is not None assert 0 == len(info) @@ -148,10 +142,10 @@ async def test_add_route_with_add_put_shortcut(router): assert info.route.name is None -async def test_add_route_with_add_patch_shortcut(router): +async def test_add_route_with_add_patch_shortcut(router) -> None: handler = make_handler() router.add_patch('/handler/to/path', handler) - req = make_request('PATCH', '/handler/to/path') + req = make_mocked_request('PATCH', '/handler/to/path') info = await router.resolve(req) assert info is not None assert 0 == len(info) @@ -159,10 +153,10 @@ async def test_add_route_with_add_patch_shortcut(router): assert info.route.name is None -async def test_add_route_with_add_delete_shortcut(router): +async def test_add_route_with_add_delete_shortcut(router) -> None: handler = make_handler() router.add_delete('/handler/to/path', handler) - req = make_request('DELETE', '/handler/to/path') + req = make_mocked_request('DELETE', '/handler/to/path') info = await router.resolve(req) assert info is not None assert 0 == len(info) @@ -170,10 +164,10 @@ async def test_add_route_with_add_delete_shortcut(router): assert info.route.name is None -async def test_add_route_with_add_head_shortcut(router): +async def test_add_route_with_add_head_shortcut(router) -> None: handler = make_handler() router.add_head('/handler/to/path', handler) - req = make_request('HEAD', '/handler/to/path') + req = make_mocked_request('HEAD', '/handler/to/path') info = await router.resolve(req) assert info is not None assert 0 == len(info) @@ -181,100 +175,100 @@ async def test_add_route_with_add_head_shortcut(router): assert info.route.name is None -async def test_add_with_name(router): +async def test_add_with_name(router) -> None: handler = make_handler() router.add_route('GET', '/handler/to/path', handler, name='name') - req = make_request('GET', '/handler/to/path') + req = make_mocked_request('GET', '/handler/to/path') info = await router.resolve(req) assert info is not None assert 'name' == info.route.name -async def test_add_with_tailing_slash(router): +async def test_add_with_tailing_slash(router) -> None: handler = make_handler() router.add_route('GET', '/handler/to/path/', handler) - req = make_request('GET', '/handler/to/path/') + req = make_mocked_request('GET', '/handler/to/path/') info = await router.resolve(req) assert info is not None assert {} == info assert handler is info.handler -def test_add_invalid_path(router): +def test_add_invalid_path(router) -> None: handler = make_handler() with pytest.raises(ValueError): router.add_route('GET', '/{/', handler) -def test_add_url_invalid1(router): +def test_add_url_invalid1(router) -> None: handler = make_handler() with pytest.raises(ValueError): router.add_route('post', '/post/{id', handler) -def test_add_url_invalid2(router): +def test_add_url_invalid2(router) -> None: handler = make_handler() with pytest.raises(ValueError): router.add_route('post', '/post/{id{}}', handler) -def test_add_url_invalid3(router): +def test_add_url_invalid3(router) -> None: handler = make_handler() with pytest.raises(ValueError): router.add_route('post', '/post/{id{}', handler) -def test_add_url_invalid4(router): +def test_add_url_invalid4(router) -> None: handler = make_handler() with pytest.raises(ValueError): router.add_route('post', '/post/{id"}', handler) -async def test_add_url_escaping(router): +async def test_add_url_escaping(router) -> None: handler = make_handler() router.add_route('GET', '/+$', handler) - req = make_request('GET', '/+$') + req = make_mocked_request('GET', '/+$') info = await router.resolve(req) assert info is not None assert handler is info.handler -async def test_any_method(router): +async def test_any_method(router) -> None: handler = make_handler() route = router.add_route(hdrs.METH_ANY, '/', handler) - req = make_request('GET', '/') + req = make_mocked_request('GET', '/') info1 = await router.resolve(req) assert info1 is not None assert route is info1.route - req = make_request('POST', '/') + req = make_mocked_request('POST', '/') info2 = await router.resolve(req) assert info2 is not None assert info1.route is info2.route -async def test_match_second_result_in_table(router): +async def test_match_second_result_in_table(router) -> None: handler1 = make_handler() handler2 = make_handler() router.add_route('GET', '/h1', handler1) router.add_route('POST', '/h2', handler2) - req = make_request('POST', '/h2') + req = make_mocked_request('POST', '/h2') info = await router.resolve(req) assert info is not None assert {} == info assert handler2 is info.handler -async def test_raise_method_not_allowed(router): +async def test_raise_method_not_allowed(router) -> None: handler1 = make_handler() handler2 = make_handler() router.add_route('GET', '/', handler1) router.add_route('POST', '/', handler2) - req = make_request('PUT', '/') + req = make_mocked_request('PUT', '/') match_info = await router.resolve(req) assert isinstance(match_info.route, SystemRoute) @@ -289,10 +283,10 @@ async def test_raise_method_not_allowed(router): assert {'POST', 'GET'} == exc.allowed_methods -async def test_raise_method_not_found(router): +async def test_raise_method_not_found(router) -> None: handler = make_handler() router.add_route('GET', '/a', handler) - req = make_request('GET', '/b') + req = make_mocked_request('GET', '/b') match_info = await router.resolve(req) assert isinstance(match_info.route, SystemRoute) @@ -305,7 +299,7 @@ async def test_raise_method_not_found(router): assert 404 == exc.status -def test_double_add_url_with_the_same_name(router): +def test_double_add_url_with_the_same_name(router) -> None: handler1 = make_handler() handler2 = make_handler() router.add_route('GET', '/get', handler1, name='name') @@ -316,7 +310,7 @@ def test_double_add_url_with_the_same_name(router): assert re.match(regexp, str(ctx.value)) -def test_route_plain(router): +def test_route_plain(router) -> None: handler = make_handler() route = router.add_route('GET', '/get', handler, name='name') route2 = next(iter(router['name'])) @@ -325,12 +319,12 @@ def test_route_plain(router): assert route is route2 -def test_route_unknown_route_name(router): +def test_route_unknown_route_name(router) -> None: with pytest.raises(KeyError): router['unknown'] -def test_route_dynamic(router): +def test_route_dynamic(router) -> None: handler = make_handler() route = router.add_route('GET', '/get/{name}', handler, name='name') @@ -341,7 +335,7 @@ def test_route_dynamic(router): assert route is route2 -def test_add_static(router): +def test_add_static(router) -> None: resource = router.add_static('/st', os.path.dirname(aiohttp.__file__), name='static') @@ -351,7 +345,7 @@ def test_add_static(router): assert len(resource) == 2 -def test_add_static_append_version(router): +def test_add_static_append_version(router) -> None: resource = router.add_static('/st', os.path.dirname(__file__), name='static') @@ -362,7 +356,7 @@ def test_add_static_append_version(router): assert expect_url == str(url) -def test_add_static_append_version_set_from_constructor(router): +def test_add_static_append_version_set_from_constructor(router) -> None: resource = router.add_static('/st', os.path.dirname(__file__), append_version=True, @@ -373,7 +367,7 @@ def test_add_static_append_version_set_from_constructor(router): assert expect_url == str(url) -def test_add_static_append_version_override_constructor(router): +def test_add_static_append_version_override_constructor(router) -> None: resource = router.add_static('/st', os.path.dirname(__file__), append_version=True, @@ -384,7 +378,7 @@ def test_add_static_append_version_override_constructor(router): assert expect_url == str(url) -def test_add_static_append_version_filename_without_slash(router): +def test_add_static_append_version_filename_without_slash(router) -> None: resource = router.add_static('/st', os.path.dirname(__file__), name='static') @@ -395,7 +389,7 @@ def test_add_static_append_version_filename_without_slash(router): assert expect_url == str(url) -def test_add_static_append_version_non_exists_file(router): +def test_add_static_append_version_non_exists_file(router) -> None: resource = router.add_static('/st', os.path.dirname(__file__), name='static') @@ -403,7 +397,8 @@ def test_add_static_append_version_non_exists_file(router): assert '/st/non_exists_file' == str(url) -def test_add_static_append_version_non_exists_file_without_slash(router): +def test_add_static_append_version_non_exists_file_without_slash( + router) -> None: resource = router.add_static('/st', os.path.dirname(__file__), name='static') @@ -411,7 +406,7 @@ def test_add_static_append_version_non_exists_file_without_slash(router): assert '/st/non_exists_file' == str(url) -def test_add_static_append_version_follow_symlink(router, tmpdir): +def test_add_static_append_version_follow_symlink(router, tmpdir) -> None: """ Tests the access to a symlink, in static folder with apeend_version """ @@ -432,7 +427,7 @@ def test_add_static_append_version_follow_symlink(router, tmpdir): assert expect_url == str(url) -def test_add_static_append_version_not_follow_symlink(router, tmpdir): +def test_add_static_append_version_not_follow_symlink(router, tmpdir) -> None: """ Tests the access to a symlink, in static folder with apeend_version """ @@ -450,21 +445,21 @@ def test_add_static_append_version_not_follow_symlink(router, tmpdir): assert '/st/append_version_symlink/data.unknown_mime_type' == str(url) -def test_plain_not_match(router): +def test_plain_not_match(router) -> None: handler = make_handler() router.add_route('GET', '/get/path', handler, name='name') route = router['name'] assert route._match('/another/path') is None -def test_dynamic_not_match(router): +def test_dynamic_not_match(router) -> None: handler = make_handler() router.add_route('GET', '/get/{name}', handler, name='name') route = router['name'] assert route._match('/another/path') is None -async def test_static_not_match(router): +async def test_static_not_match(router) -> None: router.add_static('/pre', os.path.dirname(aiohttp.__file__), name='name') resource = router['name'] @@ -473,28 +468,28 @@ async def test_static_not_match(router): assert (None, set()) == ret -def test_dynamic_with_trailing_slash(router): +def test_dynamic_with_trailing_slash(router) -> None: handler = make_handler() router.add_route('GET', '/get/{name}/', handler, name='name') route = router['name'] assert {'name': 'John'} == route._match('/get/John/') -def test_len(router): +def test_len(router) -> None: handler = make_handler() router.add_route('GET', '/get1', handler, name='name1') router.add_route('GET', '/get2', handler, name='name2') assert 2 == len(router) -def test_iter(router): +def test_iter(router) -> None: handler = make_handler() router.add_route('GET', '/get1', handler, name='name1') router.add_route('GET', '/get2', handler, name='name2') assert {'name1', 'name2'} == set(iter(router)) -def test_contains(router): +def test_contains(router) -> None: handler = make_handler() router.add_route('GET', '/get1', handler, name='name1') router.add_route('GET', '/get2', handler, name='name2') @@ -502,59 +497,59 @@ def test_contains(router): assert 'name3' not in router -def test_static_repr(router): +def test_static_repr(router) -> None: router.add_static('/get', os.path.dirname(aiohttp.__file__), name='name') assert re.match(r"<StaticResource 'name' /get", repr(router['name'])) -def test_static_adds_slash(router): +def test_static_adds_slash(router) -> None: route = router.add_static('/prefix', os.path.dirname(aiohttp.__file__)) assert '/prefix' == route._prefix -def test_static_remove_trailing_slash(router): +def test_static_remove_trailing_slash(router) -> None: route = router.add_static('/prefix/', os.path.dirname(aiohttp.__file__)) assert '/prefix' == route._prefix -async def test_add_route_with_re(router): +async def test_add_route_with_re(router) -> None: handler = make_handler() router.add_route('GET', r'/handler/{to:\d+}', handler) - req = make_request('GET', '/handler/1234') + req = make_mocked_request('GET', '/handler/1234') info = await router.resolve(req) assert info is not None assert {'to': '1234'} == info router.add_route('GET', r'/handler/{name}.html', handler) - req = make_request('GET', '/handler/test.html') + req = make_mocked_request('GET', '/handler/test.html') info = await router.resolve(req) assert {'name': 'test'} == info -async def test_add_route_with_re_and_slashes(router): +async def test_add_route_with_re_and_slashes(router) -> None: handler = make_handler() router.add_route('GET', r'/handler/{to:[^/]+/?}', handler) - req = make_request('GET', '/handler/1234/') + req = make_mocked_request('GET', '/handler/1234/') info = await router.resolve(req) assert info is not None assert {'to': '1234/'} == info router.add_route('GET', r'/handler/{to:.+}', handler) - req = make_request('GET', '/handler/1234/5/6/7') + req = make_mocked_request('GET', '/handler/1234/5/6/7') info = await router.resolve(req) assert info is not None assert {'to': '1234/5/6/7'} == info -async def test_add_route_with_re_not_match(router): +async def test_add_route_with_re_not_match(router) -> None: handler = make_handler() router.add_route('GET', r'/handler/{to:\d+}', handler) - req = make_request('GET', '/handler/tail') + req = make_mocked_request('GET', '/handler/tail') match_info = await router.resolve(req) assert isinstance(match_info.route, SystemRoute) assert {} == match_info @@ -562,16 +557,16 @@ async def test_add_route_with_re_not_match(router): await match_info.handler(req) -async def test_add_route_with_re_including_slashes(router): +async def test_add_route_with_re_including_slashes(router) -> None: handler = make_handler() router.add_route('GET', r'/handler/{to:.+}/tail', handler) - req = make_request('GET', '/handler/re/with/slashes/tail') + req = make_mocked_request('GET', '/handler/re/with/slashes/tail') info = await router.resolve(req) assert info is not None assert {'to': 're/with/slashes'} == info -def test_add_route_with_invalid_re(router): +def test_add_route_with_invalid_re(router) -> None: handler = make_handler() with pytest.raises(ValueError) as ctx: router.add_route('GET', r'/handler/{to:+++}', handler) @@ -584,25 +579,25 @@ def test_add_route_with_invalid_re(router): assert ctx.value.__cause__ is None -def test_route_dynamic_with_regex_spec(router): +def test_route_dynamic_with_regex_spec(router) -> None: handler = make_handler() - route = router.add_route('GET', '/get/{num:^\d+}', handler, + route = router.add_route('GET', r'/get/{num:^\d+}', handler, name='name') url = route.url_for(num='123') assert '/get/123' == str(url) -def test_route_dynamic_with_regex_spec_and_trailing_slash(router): +def test_route_dynamic_with_regex_spec_and_trailing_slash(router) -> None: handler = make_handler() - route = router.add_route('GET', '/get/{num:^\d+}/', handler, + route = router.add_route('GET', r'/get/{num:^\d+}/', handler, name='name') url = route.url_for(num='123') assert '/get/123/' == str(url) -def test_route_dynamic_with_regex(router): +def test_route_dynamic_with_regex(router) -> None: handler = make_handler() route = router.add_route('GET', r'/{one}/{two:.+}', handler) @@ -610,7 +605,7 @@ def test_route_dynamic_with_regex(router): assert '/1/2' == str(url) -def test_route_dynamic_quoting(router): +def test_route_dynamic_quoting(router) -> None: handler = make_handler() route = router.add_route('GET', r'/{arg}', handler) @@ -618,50 +613,50 @@ def test_route_dynamic_quoting(router): assert '/1%202/%D1%82%D0%B5%D0%BA%D1%81%D1%82' == str(url) -async def test_regular_match_info(router): +async def test_regular_match_info(router) -> None: handler = make_handler() router.add_route('GET', '/get/{name}', handler) - req = make_request('GET', '/get/john') + req = make_mocked_request('GET', '/get/john') match_info = await router.resolve(req) assert {'name': 'john'} == match_info assert re.match("<MatchInfo {'name': 'john'}: .+<Dynamic.+>>", repr(match_info)) -async def test_match_info_with_plus(router): +async def test_match_info_with_plus(router) -> None: handler = make_handler() router.add_route('GET', '/get/{version}', handler) - req = make_request('GET', '/get/1.0+test') + req = make_mocked_request('GET', '/get/1.0+test') match_info = await router.resolve(req) assert {'version': '1.0+test'} == match_info -async def test_not_found_repr(router): - req = make_request('POST', '/path/to') +async def test_not_found_repr(router) -> None: + req = make_mocked_request('POST', '/path/to') match_info = await router.resolve(req) assert "<MatchInfoError 404: Not Found>" == repr(match_info) -async def test_not_allowed_repr(router): +async def test_not_allowed_repr(router) -> None: handler = make_handler() router.add_route('GET', '/path/to', handler) handler2 = make_handler() router.add_route('POST', '/path/to', handler2) - req = make_request('PUT', '/path/to') + req = make_mocked_request('PUT', '/path/to') match_info = await router.resolve(req) assert "<MatchInfoError 405: Method Not Allowed>" == repr(match_info) -def test_default_expect_handler(router): +def test_default_expect_handler(router) -> None: route = router.add_route('GET', '/', make_handler()) assert route._expect_handler is _default_expect_handler -def test_custom_expect_handler_plain(router): +def test_custom_expect_handler_plain(router) -> None: async def handler(request): pass @@ -672,7 +667,7 @@ def test_custom_expect_handler_plain(router): assert isinstance(route, ResourceRoute) -def test_custom_expect_handler_dynamic(router): +def test_custom_expect_handler_dynamic(router) -> None: async def handler(request): pass @@ -683,7 +678,7 @@ def test_custom_expect_handler_dynamic(router): assert isinstance(route, ResourceRoute) -def test_expect_handler_non_coroutine(router): +def test_expect_handler_non_coroutine(router) -> None: def handler(request): pass @@ -693,37 +688,37 @@ def test_expect_handler_non_coroutine(router): expect_handler=handler) -async def test_dynamic_match_non_ascii(router): +async def test_dynamic_match_non_ascii(router) -> None: handler = make_handler() router.add_route('GET', '/{var}', handler) - req = make_request( + req = make_mocked_request( 'GET', '/%D1%80%D1%83%D1%81%20%D1%82%D0%B5%D0%BA%D1%81%D1%82') match_info = await router.resolve(req) assert {'var': 'рус текст'} == match_info -async def test_dynamic_match_with_static_part(router): +async def test_dynamic_match_with_static_part(router) -> None: handler = make_handler() router.add_route('GET', '/{name}.html', handler) - req = make_request('GET', '/file.html') + req = make_mocked_request('GET', '/file.html') match_info = await router.resolve(req) assert {'name': 'file'} == match_info -async def test_dynamic_match_two_part2(router): +async def test_dynamic_match_two_part2(router) -> None: handler = make_handler() router.add_route('GET', '/{name}.{ext}', handler) - req = make_request('GET', '/file.html') + req = make_mocked_request('GET', '/file.html') match_info = await router.resolve(req) assert {'name': 'file', 'ext': 'html'} == match_info -async def test_dynamic_match_unquoted_path(router): +async def test_dynamic_match_unquoted_path(router) -> None: handler = make_handler() router.add_route('GET', '/{path}/{subpath}', handler) resource_id = 'my%2Fpath%7Cwith%21some%25strange%24characters' - req = make_request('GET', '/path/{0}'.format(resource_id)) + req = make_mocked_request('GET', '/path/{0}'.format(resource_id)) match_info = await router.resolve(req) assert match_info == { 'path': 'path', @@ -731,13 +726,13 @@ async def test_dynamic_match_unquoted_path(router): } -def test_add_route_not_started_with_slash(router): +def test_add_route_not_started_with_slash(router) -> None: with pytest.raises(ValueError): handler = make_handler() router.add_route('GET', 'invalid_path', handler) -def test_add_route_invalid_method(router): +def test_add_route_invalid_method(router) -> None: sample_bad_methods = { 'BAD METHOD', @@ -754,34 +749,34 @@ def test_add_route_invalid_method(router): router.add_route(bad_method, '/path', handler) -def test_routes_view_len(router, fill_routes): +def test_routes_view_len(router, fill_routes) -> None: fill_routes() assert 4 == len(router.routes()) -def test_routes_view_iter(router, fill_routes): +def test_routes_view_iter(router, fill_routes) -> None: routes = fill_routes() assert list(routes) == list(router.routes()) -def test_routes_view_contains(router, fill_routes): +def test_routes_view_contains(router, fill_routes) -> None: routes = fill_routes() for route in routes: assert route in router.routes() -def test_routes_abc(router): +def test_routes_abc(router) -> None: assert isinstance(router.routes(), Sized) assert isinstance(router.routes(), Iterable) assert isinstance(router.routes(), Container) -def test_named_resources_abc(router): +def test_named_resources_abc(router) -> None: assert isinstance(router.named_resources(), Mapping) assert not isinstance(router.named_resources(), MutableMapping) -def test_named_resources(router): +def test_named_resources(router) -> None: route1 = router.add_route('GET', '/plain', make_handler(), name='route1') route2 = router.add_route('GET', '/variable/{name}', @@ -799,7 +794,7 @@ def test_named_resources(router): AbstractResource) -def test_resource_iter(router): +def test_resource_iter(router) -> None: async def handler(request): pass resource = router.add_resource('/path') @@ -809,7 +804,7 @@ def test_resource_iter(router): assert [r1, r2] == list(resource) -def test_deprecate_bare_generators(router): +def test_deprecate_bare_generators(router) -> None: resource = router.add_resource('/path') def gen(request): @@ -819,14 +814,14 @@ def test_deprecate_bare_generators(router): resource.add_route('GET', gen) -def test_view_route(router): +def test_view_route(router) -> None: resource = router.add_resource('/path') route = resource.add_route('GET', View) assert View is route.handler -def test_resource_route_match(router): +def test_resource_route_match(router) -> None: async def handler(request): pass resource = router.add_resource('/path') @@ -834,7 +829,7 @@ def test_resource_route_match(router): assert {} == route.resource._match('/path') -def test_error_on_double_route_adding(router): +def test_error_on_double_route_adding(router) -> None: async def handler(request): pass resource = router.add_resource('/path') @@ -844,7 +839,7 @@ def test_error_on_double_route_adding(router): resource.add_route('GET', handler) -def test_error_on_adding_route_after_wildcard(router): +def test_error_on_adding_route_after_wildcard(router) -> None: async def handler(request): pass resource = router.add_resource('/path') @@ -854,44 +849,44 @@ def test_error_on_adding_route_after_wildcard(router): resource.add_route('GET', handler) -async def test_http_exception_is_none_when_resolved(router): +async def test_http_exception_is_none_when_resolved(router) -> None: handler = make_handler() router.add_route('GET', '/', handler) - req = make_request('GET', '/') + req = make_mocked_request('GET', '/') info = await router.resolve(req) assert info.http_exception is None -async def test_http_exception_is_not_none_when_not_resolved(router): +async def test_http_exception_is_not_none_when_not_resolved(router) -> None: handler = make_handler() router.add_route('GET', '/', handler) - req = make_request('GET', '/abc') + req = make_mocked_request('GET', '/abc') info = await router.resolve(req) assert info.http_exception.status == 404 -async def test_match_info_get_info_plain(router): +async def test_match_info_get_info_plain(router) -> None: handler = make_handler() router.add_route('GET', '/', handler) - req = make_request('GET', '/') + req = make_mocked_request('GET', '/') info = await router.resolve(req) assert info.get_info() == {'path': '/'} -async def test_match_info_get_info_dynamic(router): +async def test_match_info_get_info_dynamic(router) -> None: handler = make_handler() router.add_route('GET', '/{a}', handler) - req = make_request('GET', '/value') + req = make_mocked_request('GET', '/value') info = await router.resolve(req) assert info.get_info() == { 'pattern': re.compile(PATH_SEP+'(?P<a>[^{}/]+)'), 'formatter': '/{a}'} -async def test_match_info_get_info_dynamic2(router): +async def test_match_info_get_info_dynamic2(router) -> None: handler = make_handler() router.add_route('GET', '/{a}/{b}', handler) - req = make_request('GET', '/path/to') + req = make_mocked_request('GET', '/path/to') info = await router.resolve(req) assert info.get_info() == { 'pattern': re.compile(PATH_SEP + @@ -901,35 +896,35 @@ async def test_match_info_get_info_dynamic2(router): 'formatter': '/{a}/{b}'} -def test_static_resource_get_info(router): +def test_static_resource_get_info(router) -> None: directory = pathlib.Path(aiohttp.__file__).parent resource = router.add_static('/st', directory) assert resource.get_info() == {'directory': directory, 'prefix': '/st'} -async def test_system_route_get_info(router): +async def test_system_route_get_info(router) -> None: handler = make_handler() router.add_route('GET', '/', handler) - req = make_request('GET', '/abc') + req = make_mocked_request('GET', '/abc') info = await router.resolve(req) assert info.get_info()['http_exception'].status == 404 -def test_resources_view_len(router): +def test_resources_view_len(router) -> None: router.add_resource('/plain') router.add_resource('/variable/{name}') assert 2 == len(router.resources()) -def test_resources_view_iter(router): +def test_resources_view_iter(router) -> None: resource1 = router.add_resource('/plain') resource2 = router.add_resource('/variable/{name}') resources = [resource1, resource2] assert list(resources) == list(router.resources()) -def test_resources_view_contains(router): +def test_resources_view_contains(router) -> None: resource1 = router.add_resource('/plain') resource2 = router.add_resource('/variable/{name}') resources = [resource1, resource2] @@ -937,13 +932,13 @@ def test_resources_view_contains(router): assert resource in router.resources() -def test_resources_abc(router): +def test_resources_abc(router) -> None: assert isinstance(router.resources(), Sized) assert isinstance(router.resources(), Iterable) assert isinstance(router.resources(), Container) -def test_static_route_user_home(router): +def test_static_route_user_home(router) -> None: here = pathlib.Path(aiohttp.__file__).parent home = pathlib.Path(os.path.expanduser('~')) if not str(here).startswith(str(home)): # pragma: no cover @@ -953,13 +948,13 @@ def test_static_route_user_home(router): assert here == route.get_info()['directory'] -def test_static_route_points_to_file(router): +def test_static_route_points_to_file(router) -> None: here = pathlib.Path(aiohttp.__file__).parent / '__init__.py' with pytest.raises(ValueError): router.add_static('/st', here) -async def test_404_for_static_resource(router): +async def test_404_for_static_resource(router) -> None: resource = router.add_static('/st', os.path.dirname(aiohttp.__file__)) ret = await resource.resolve( @@ -967,7 +962,7 @@ async def test_404_for_static_resource(router): assert (None, set()) == ret -async def test_405_for_resource_adapter(router): +async def test_405_for_resource_adapter(router) -> None: resource = router.add_static('/st', os.path.dirname(aiohttp.__file__)) ret = await resource.resolve( @@ -975,7 +970,7 @@ async def test_405_for_resource_adapter(router): assert (None, {'HEAD', 'GET'}) == ret -async def test_check_allowed_method_for_found_resource(router): +async def test_check_allowed_method_for_found_resource(router) -> None: handler = make_handler() resource = router.add_resource('/') resource.add_route('GET', handler) @@ -984,46 +979,142 @@ async def test_check_allowed_method_for_found_resource(router): assert {'GET'} == ret[1] -def test_url_for_in_static_resource(router): +def test_url_for_in_static_resource(router) -> None: resource = router.add_static('/static', os.path.dirname(aiohttp.__file__)) assert URL('/static/file.txt') == resource.url_for(filename='file.txt') -def test_url_for_in_static_resource_pathlib(router): +def test_url_for_in_static_resource_pathlib(router) -> None: resource = router.add_static('/static', os.path.dirname(aiohttp.__file__)) assert URL('/static/file.txt') == resource.url_for( filename=pathlib.Path('file.txt')) -def test_url_for_in_resource_route(router): +def test_url_for_in_resource_route(router) -> None: route = router.add_route('GET', '/get/{name}', make_handler(), name='name') assert URL('/get/John') == route.url_for(name='John') -def test_subapp_get_info(app, loop): +def test_subapp_get_info(app) -> None: subapp = web.Application() resource = subapp.add_subapp('/pre', subapp) assert resource.get_info() == {'prefix': '/pre', 'app': subapp} -def test_subapp_url_for(app, loop): +@pytest.mark.parametrize('domain,error', [ + (None, TypeError), + ('', ValueError), + ('http://dom', ValueError), + ('*.example.com', ValueError), + ('example$com', ValueError), +]) +def test_domain_validation_error(domain, error): + with pytest.raises(error): + Domain(domain) + + +def test_domain_valid(): + assert Domain('example.com:81').canonical == 'example.com:81' + assert MaskDomain('*.example.com').canonical == r'.*\.example\.com' + assert Domain('пуни.код').canonical == 'xn--h1ajfq.xn--d1alm' + + +@pytest.mark.parametrize('a,b,result', [ + ('example.com', 'example.com', True), + ('example.com:81', 'example.com:81', True), + ('example.com:81', 'example.com', False), + ('пуникод', 'xn--d1ahgkhc2a', True), + ('*.example.com', 'jpg.example.com', True), + ('*.example.com', 'a.example.com', True), + ('*.example.com', 'example.com', False), +]) +def test_match_domain(a, b, result): + if '*' in a: + rule = MaskDomain(a) + else: + rule = Domain(a) + assert rule.match_domain(b) is result + + +def test_add_subapp_errors(app): + with pytest.raises(TypeError): + app.add_subapp(1, web.Application()) + + +def test_subapp_rule_resource(app): + subapp = web.Application() + subapp.router.add_get('/', make_handler()) + rule = Domain('example.com') + assert rule.get_info() == {'domain': 'example.com'} + resource = app.add_domain('example.com', subapp) + assert resource.canonical == 'example.com' + assert resource.get_info() == {'rule': resource._rule, 'app': subapp} + resource.add_prefix('/a') + resource.raw_match('/b') + assert len(resource) + assert list(resource) + assert repr(resource).startswith('<MatchedSubAppResource') + with pytest.raises(RuntimeError): + resource.url_for() + + +async def test_add_domain_not_str(app, loop): + app = web.Application() + with pytest.raises(TypeError): + app.add_domain(1, app) + + +async def test_add_domain(app, loop): + subapp1 = web.Application() + h1 = make_handler() + subapp1.router.add_get('/', h1) + app.add_domain('example.com', subapp1) + + subapp2 = web.Application() + h2 = make_handler() + subapp2.router.add_get('/', h2) + app.add_domain('*.example.com', subapp2) + + subapp3 = web.Application() + h3 = make_handler() + subapp3.router.add_get('/', h3) + app.add_domain('*', subapp3) + + request = make_mocked_request('GET', '/', {'host': 'example.com'}) + match_info = await app.router.resolve(request) + assert match_info.route.handler is h1 + + request = make_mocked_request('GET', '/', {'host': 'a.example.com'}) + match_info = await app.router.resolve(request) + assert match_info.route.handler is h2 + + request = make_mocked_request('GET', '/', {'host': 'example2.com'}) + match_info = await app.router.resolve(request) + assert match_info.route.handler is h3 + + request = make_mocked_request('POST', '/', {'host': 'example.com'}) + match_info = await app.router.resolve(request) + assert isinstance(match_info.http_exception, HTTPMethodNotAllowed) + + +def test_subapp_url_for(app) -> None: subapp = web.Application() resource = app.add_subapp('/pre', subapp) with pytest.raises(RuntimeError): resource.url_for() -def test_subapp_repr(app, loop): +def test_subapp_repr(app) -> None: subapp = web.Application() resource = app.add_subapp('/pre', subapp) assert repr(resource).startswith( '<PrefixedSubAppResource /pre -> <Application') -def test_subapp_len(app, loop): +def test_subapp_len(app) -> None: subapp = web.Application() subapp.router.add_get('/', make_handler(), allow_head=False) subapp.router.add_post('/', make_handler()) @@ -1031,7 +1122,7 @@ def test_subapp_len(app, loop): assert len(resource) == 2 -def test_subapp_iter(app, loop): +def test_subapp_iter(app) -> None: subapp = web.Application() r1 = subapp.router.add_get('/', make_handler(), allow_head=False) r2 = subapp.router.add_post('/', make_handler()) @@ -1039,32 +1130,32 @@ def test_subapp_iter(app, loop): assert list(resource) == [r1, r2] -def test_invalid_route_name(router): +def test_invalid_route_name(router) -> None: with pytest.raises(ValueError): router.add_get('/', make_handler(), name='invalid name') -def test_frozen_router(router): +def test_frozen_router(router) -> None: router.freeze() with pytest.raises(RuntimeError): router.add_get('/', make_handler()) -def test_frozen_router_subapp(app, loop): +def test_frozen_router_subapp(app) -> None: subapp = web.Application() subapp.freeze() with pytest.raises(RuntimeError): - app.add_subapp('/', subapp) + app.add_subapp('/pre', subapp) -def test_frozen_app_on_subapp(app, loop): +def test_frozen_app_on_subapp(app) -> None: app.freeze() subapp = web.Application() with pytest.raises(RuntimeError): - app.add_subapp('/', subapp) + app.add_subapp('/pre', subapp) -def test_set_options_route(router): +def test_set_options_route(router) -> None: resource = router.add_static('/static', os.path.dirname(aiohttp.__file__)) options = None @@ -1082,24 +1173,24 @@ def test_set_options_route(router): resource.set_options_route(make_handler()) -def test_dynamic_url_with_name_started_from_undescore(router): +def test_dynamic_url_with_name_started_from_underscore(router) -> None: route = router.add_route('GET', '/get/{_name}', make_handler()) assert URL('/get/John') == route.url_for(_name='John') -def test_cannot_add_subapp_with_empty_prefix(app, loop): +def test_cannot_add_subapp_with_empty_prefix(app) -> None: subapp = web.Application() with pytest.raises(ValueError): app.add_subapp('', subapp) -def test_cannot_add_subapp_with_slash_prefix(app, loop): +def test_cannot_add_subapp_with_slash_prefix(app) -> None: subapp = web.Application() with pytest.raises(ValueError): app.add_subapp('/', subapp) -async def test_convert_empty_path_to_slash_on_freezing(router): +async def test_convert_empty_path_to_slash_on_freezing(router) -> None: handler = make_handler() route = router.add_get('', handler) resource = route.resource @@ -1108,7 +1199,7 @@ async def test_convert_empty_path_to_slash_on_freezing(router): assert resource.get_info() == {'path': '/'} -def test_deprecate_non_coroutine(router): +def test_deprecate_non_coroutine(router) -> None: def handler(request): pass @@ -1116,16 +1207,16 @@ def test_deprecate_non_coroutine(router): router.add_route('GET', '/handler', handler) -def test_plain_resource_canonical(): +def test_plain_resource_canonical() -> None: canonical = '/plain/path' res = PlainResource(path=canonical) assert res.canonical == canonical -def test_dynamic_resource_canonical(): +def test_dynamic_resource_canonical() -> None: canonicals = { '/get/{name}': '/get/{name}', - '/get/{num:^\d+}': '/get/{num}', + r'/get/{num:^\d+}': '/get/{num}', r'/handler/{to:\d+}': r'/handler/{to}', r'/{one}/{two:.+}': r'/{one}/{two}', } @@ -1134,7 +1225,7 @@ def test_dynamic_resource_canonical(): assert res.canonical == canonical -def test_static_resource_canonical(): +def test_static_resource_canonical() -> None: prefix = '/prefix' directory = str(os.path.dirname(aiohttp.__file__)) canonical = prefix @@ -1142,7 +1233,7 @@ def test_static_resource_canonical(): assert res.canonical == canonical -def test_prefixed_subapp_resource_canonical(app, loop): +def test_prefixed_subapp_resource_canonical(app) -> None: canonical = '/prefix' subapp = web.Application() res = subapp.add_subapp(canonical, subapp) diff --git a/tests/test_web_app.py b/tests/test_web_app.py index 1bd7c34..95ced98 100644 --- a/tests/test_web_app.py +++ b/tests/test_web_app.py @@ -10,77 +10,92 @@ from aiohttp.helpers import DEBUG, PY_36 from aiohttp.test_utils import make_mocked_coro -def test_app_ctor(loop): +async def test_app_ctor() -> None: + loop = asyncio.get_event_loop() with pytest.warns(DeprecationWarning): app = web.Application(loop=loop) - assert loop is app.loop + with pytest.warns(DeprecationWarning): + assert loop is app.loop assert app.logger is log.web_logger -def test_app_call(): +def test_app_call() -> None: app = web.Application() assert app is app() -def test_app_default_loop(): +def test_app_default_loop() -> None: app = web.Application() - assert app.loop is None + with pytest.warns(DeprecationWarning): + assert app.loop is None -def test_set_loop(loop): +async def test_set_loop() -> None: + loop = asyncio.get_event_loop() app = web.Application() app._set_loop(loop) - assert app.loop is loop + with pytest.warns(DeprecationWarning): + assert app.loop is loop -def test_set_loop_default_loop(loop): +def test_set_loop_default_loop() -> None: + loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) app = web.Application() app._set_loop(None) - assert app.loop is loop + with pytest.warns(DeprecationWarning): + assert app.loop is loop + asyncio.set_event_loop(None) -def test_set_loop_with_different_loops(loop): +def test_set_loop_with_different_loops() -> None: + loop = asyncio.new_event_loop() app = web.Application() app._set_loop(loop) - assert app.loop is loop + with pytest.warns(DeprecationWarning): + assert app.loop is loop with pytest.raises(RuntimeError): app._set_loop(loop=object()) @pytest.mark.parametrize('debug', [True, False]) -def test_app_make_handler_debug_exc(loop, mocker, debug): - app = web.Application(debug=debug) +async def test_app_make_handler_debug_exc(mocker, debug) -> None: + with pytest.warns(DeprecationWarning): + app = web.Application(debug=debug) srv = mocker.patch('aiohttp.web_app.Server') - app._make_handler(loop=loop) + with pytest.warns(DeprecationWarning): + assert app.debug == debug + + app._make_handler() srv.assert_called_with(app._handle, request_factory=app._make_request, access_log_class=mock.ANY, - loop=loop, + loop=asyncio.get_event_loop(), debug=debug) -def test_app_make_handler_args(loop, mocker): +async def test_app_make_handler_args(mocker) -> None: app = web.Application(handler_args={'test': True}) srv = mocker.patch('aiohttp.web_app.Server') - app._make_handler(loop=loop) + app._make_handler() srv.assert_called_with(app._handle, request_factory=app._make_request, access_log_class=mock.ANY, - loop=loop, debug=mock.ANY, test=True) + loop=asyncio.get_event_loop(), + debug=mock.ANY, test=True) -def test_app_make_handler_access_log_class(loop, mocker): +async def test_app_make_handler_access_log_class(mocker) -> None: class Logger: pass app = web.Application() with pytest.raises(TypeError): - app._make_handler(access_log_class=Logger, loop=loop) + app._make_handler(access_log_class=Logger) class Logger(AbstractAccessLogger): @@ -89,21 +104,30 @@ def test_app_make_handler_access_log_class(loop, mocker): srv = mocker.patch('aiohttp.web_app.Server') - app._make_handler(access_log_class=Logger, loop=loop) + app._make_handler(access_log_class=Logger) srv.assert_called_with(app._handle, access_log_class=Logger, request_factory=app._make_request, - loop=loop, debug=mock.ANY) + loop=asyncio.get_event_loop(), + debug=mock.ANY) + + app = web.Application(handler_args={'access_log_class': Logger}) + app._make_handler(access_log_class=Logger) + srv.assert_called_with(app._handle, + access_log_class=Logger, + request_factory=app._make_request, + loop=asyncio.get_event_loop(), + debug=mock.ANY) -def test_app_make_handler_raises_deprecation_warning(loop): +async def test_app_make_handler_raises_deprecation_warning() -> None: app = web.Application() with pytest.warns(DeprecationWarning): - app.make_handler(loop=loop) + app.make_handler() -async def test_app_register_on_finish(): +async def test_app_register_on_finish() -> None: app = web.Application() cb1 = make_mocked_coro(None) cb2 = make_mocked_coro(None) @@ -115,12 +139,12 @@ async def test_app_register_on_finish(): cb2.assert_called_once_with(app) -async def test_app_register_coro(loop): +async def test_app_register_coro() -> None: app = web.Application() - fut = loop.create_future() + fut = asyncio.get_event_loop().create_future() async def cb(app): - await asyncio.sleep(0.001, loop=loop) + await asyncio.sleep(0.001) fut.set_result(123) app.on_cleanup.append(cb) @@ -130,21 +154,21 @@ async def test_app_register_coro(loop): assert 123 == fut.result() -def test_non_default_router(): +def test_non_default_router() -> None: router = mock.Mock(spec=AbstractRouter) with pytest.warns(DeprecationWarning): app = web.Application(router=router) assert router is app.router -def test_logging(): +def test_logging() -> None: logger = mock.Mock() app = web.Application() app.logger = logger assert app.logger is logger -async def test_on_shutdown(): +async def test_on_shutdown() -> None: app = web.Application() called = False @@ -159,9 +183,8 @@ async def test_on_shutdown(): assert called -async def test_on_startup(loop): +async def test_on_startup() -> None: app = web.Application() - app._set_loop(loop) long_running1_called = False long_running2_called = False @@ -182,8 +205,7 @@ async def test_on_startup(loop): assert app is app_param all_long_running_called = True return await asyncio.gather(long_running1(app_param), - long_running2(app_param), - loop=app_param.loop) + long_running2(app_param)) app.on_startup.append(on_startup_all_long_running) app.freeze() @@ -194,7 +216,7 @@ async def test_on_startup(loop): assert all_long_running_called -def test_app_delitem(): +def test_app_delitem() -> None: app = web.Application() app['key'] = 'value' assert len(app) == 1 @@ -202,7 +224,7 @@ def test_app_delitem(): assert len(app) == 0 -def test_app_freeze(): +def test_app_freeze() -> None: app = web.Application() subapp = mock.Mock() subapp._middlewares = () @@ -215,7 +237,7 @@ def test_app_freeze(): assert len(subapp.freeze.call_args_list) == 1 -def test_equality(): +def test_equality() -> None: app1 = web.Application() app2 = web.Application() @@ -223,7 +245,7 @@ def test_equality(): assert app1 != app2 -def test_app_run_middlewares(): +def test_app_run_middlewares() -> None: root = web.Application() sub = web.Application() @@ -248,7 +270,7 @@ def test_app_run_middlewares(): assert root._run_middlewares is True -def test_subapp_pre_frozen_after_adding(): +def test_subapp_pre_frozen_after_adding() -> None: app = web.Application() subapp = web.Application() @@ -259,7 +281,7 @@ def test_subapp_pre_frozen_after_adding(): @pytest.mark.skipif(not PY_36, reason="Python 3.6+ required") -def test_app_inheritance(): +def test_app_inheritance() -> None: with pytest.warns(DeprecationWarning): class A(web.Application): pass @@ -267,13 +289,13 @@ def test_app_inheritance(): @pytest.mark.skipif(not DEBUG, reason="The check is applied in DEBUG mode only") -def test_app_custom_attr(): +def test_app_custom_attr() -> None: app = web.Application() with pytest.warns(DeprecationWarning): app.custom = None -async def test_cleanup_ctx(): +async def test_cleanup_ctx() -> None: app = web.Application() out = [] @@ -294,7 +316,7 @@ async def test_cleanup_ctx(): assert out == ['pre_1', 'pre_2', 'post_2', 'post_1'] -async def test_cleanup_ctx_exception_on_startup(): +async def test_cleanup_ctx_exception_on_startup() -> None: app = web.Application() out = [] @@ -322,7 +344,7 @@ async def test_cleanup_ctx_exception_on_startup(): assert out == ['pre_1', 'pre_2', 'post_1'] -async def test_cleanup_ctx_exception_on_cleanup(): +async def test_cleanup_ctx_exception_on_cleanup() -> None: app = web.Application() out = [] @@ -350,7 +372,7 @@ async def test_cleanup_ctx_exception_on_cleanup(): assert out == ['pre_1', 'pre_2', 'pre_3', 'post_3', 'post_2', 'post_1'] -async def test_cleanup_ctx_exception_on_cleanup_multiple(): +async def test_cleanup_ctx_exception_on_cleanup_multiple() -> None: app = web.Application() out = [] @@ -379,7 +401,7 @@ async def test_cleanup_ctx_exception_on_cleanup_multiple(): assert out == ['pre_1', 'pre_2', 'pre_3', 'post_3', 'post_2', 'post_1'] -async def test_cleanup_ctx_multiple_yields(): +async def test_cleanup_ctx_multiple_yields() -> None: app = web.Application() out = [] @@ -402,7 +424,7 @@ async def test_cleanup_ctx_multiple_yields(): assert out == ['pre_1', 'post_1'] -async def test_subapp_chained_config_dict_visibility(aiohttp_client): +async def test_subapp_chained_config_dict_visibility(aiohttp_client) -> None: async def main_handler(request): assert request.config_dict['key1'] == 'val1' @@ -431,7 +453,7 @@ async def test_subapp_chained_config_dict_visibility(aiohttp_client): assert resp.status == 201 -async def test_subapp_chained_config_dict_overriding(aiohttp_client): +async def test_subapp_chained_config_dict_overriding(aiohttp_client) -> None: async def main_handler(request): assert request.config_dict['key'] == 'val1' @@ -458,7 +480,7 @@ async def test_subapp_chained_config_dict_overriding(aiohttp_client): assert resp.status == 201 -async def test_subapp_on_startup(aiohttp_client): +async def test_subapp_on_startup(aiohttp_client) -> None: subapp = web.Application() @@ -531,3 +553,10 @@ async def test_subapp_on_startup(aiohttp_client): assert ctx_post_called assert shutdown_called assert cleanup_called + + +def test_app_iter(): + app = web.Application() + app['a'] = '1' + app['b'] = '2' + assert sorted(list(app)) == ['a', 'b'] diff --git a/tests/test_web_cli.py b/tests/test_web_cli.py index 5d954f8..cba64f7 100644 --- a/tests/test_web_cli.py +++ b/tests/test_web_cli.py @@ -3,7 +3,7 @@ import pytest from aiohttp import web -def test_entry_func_empty(mocker): +def test_entry_func_empty(mocker) -> None: error = mocker.patch("aiohttp.web.ArgumentParser.error", side_effect=SystemExit) argv = [""] @@ -16,7 +16,7 @@ def test_entry_func_empty(mocker): ) -def test_entry_func_only_module(mocker): +def test_entry_func_only_module(mocker) -> None: argv = ["test"] error = mocker.patch("aiohttp.web.ArgumentParser.error", side_effect=SystemExit) @@ -29,7 +29,7 @@ def test_entry_func_only_module(mocker): ) -def test_entry_func_only_function(mocker): +def test_entry_func_only_function(mocker) -> None: argv = [":test"] error = mocker.patch("aiohttp.web.ArgumentParser.error", side_effect=SystemExit) @@ -42,7 +42,7 @@ def test_entry_func_only_function(mocker): ) -def test_entry_func_only_seperator(mocker): +def test_entry_func_only_separator(mocker) -> None: argv = [":"] error = mocker.patch("aiohttp.web.ArgumentParser.error", side_effect=SystemExit) @@ -55,7 +55,7 @@ def test_entry_func_only_seperator(mocker): ) -def test_entry_func_relative_module(mocker): +def test_entry_func_relative_module(mocker) -> None: argv = [".a.b:c"] error = mocker.patch("aiohttp.web.ArgumentParser.error", @@ -66,7 +66,7 @@ def test_entry_func_relative_module(mocker): error.assert_called_with("relative module names not supported") -def test_entry_func_non_existent_module(mocker): +def test_entry_func_non_existent_module(mocker) -> None: argv = ["alpha.beta:func"] mocker.patch("aiohttp.web.import_module", @@ -80,7 +80,7 @@ def test_entry_func_non_existent_module(mocker): error.assert_called_with('unable to import alpha.beta: Test Error') -def test_entry_func_non_existent_attribute(mocker): +def test_entry_func_non_existent_attribute(mocker) -> None: argv = ["alpha.beta:func"] import_module = mocker.patch("aiohttp.web.import_module") error = mocker.patch("aiohttp.web.ArgumentParser.error", @@ -96,7 +96,7 @@ def test_entry_func_non_existent_attribute(mocker): ) -def test_path_when_unsupported(mocker, monkeypatch): +def test_path_when_unsupported(mocker, monkeypatch) -> None: argv = "--path=test_path.sock alpha.beta:func".split() mocker.patch("aiohttp.web.import_module") monkeypatch.delattr("socket.AF_UNIX", raising=False) @@ -110,7 +110,7 @@ def test_path_when_unsupported(mocker, monkeypatch): " operating environment") -def test_entry_func_call(mocker): +def test_entry_func_call(mocker) -> None: mocker.patch("aiohttp.web.run_app") import_module = mocker.patch("aiohttp.web.import_module") argv = ("-H testhost -P 6666 --extra-optional-eins alpha.beta:func " @@ -126,7 +126,7 @@ def test_entry_func_call(mocker): ) -def test_running_application(mocker): +def test_running_application(mocker) -> None: run_app = mocker.patch("aiohttp.web.run_app") import_module = mocker.patch("aiohttp.web.import_module") exit = mocker.patch("aiohttp.web.ArgumentParser.exit", diff --git a/tests/test_web_exceptions.py b/tests/test_web_exceptions.py index bfab0fb..e82a907 100644 --- a/tests/test_web_exceptions.py +++ b/tests/test_web_exceptions.py @@ -15,7 +15,7 @@ def buf(): @pytest.fixture -def request(buf): +def http_request(buf): method = 'GET' path = '/' writer = mock.Mock() @@ -44,7 +44,7 @@ def request(buf): return req -def test_all_http_exceptions_exported(): +def test_all_http_exceptions_exported() -> None: assert 'HTTPException' in web.__all__ for name in dir(web): if name.startswith('_'): @@ -54,9 +54,9 @@ def test_all_http_exceptions_exported(): assert name in web.__all__ -async def test_HTTPOk(buf, request): +async def test_HTTPOk(buf, http_request) -> None: resp = web.HTTPOk() - await resp.prepare(request) + await resp.prepare(http_request) await resp.write_eof() txt = buf.decode('utf8') assert re.match(('HTTP/1.1 200 OK\r\n' @@ -67,7 +67,7 @@ async def test_HTTPOk(buf, request): '200: OK'), txt) -def test_terminal_classes_has_status_code(): +def test_terminal_classes_has_status_code() -> None: terminals = set() for name in dir(web): obj = getattr(web, name) @@ -87,11 +87,11 @@ def test_terminal_classes_has_status_code(): assert 1 == codes.most_common(1)[0][1] -async def test_HTTPFound(buf, request): +async def test_HTTPFound(buf, http_request) -> None: resp = web.HTTPFound(location='/redirect') assert '/redirect' == resp.location assert '/redirect' == resp.headers['location'] - await resp.prepare(request) + await resp.prepare(http_request) await resp.write_eof() txt = buf.decode('utf8') assert re.match('HTTP/1.1 302 Found\r\n' @@ -103,7 +103,7 @@ async def test_HTTPFound(buf, request): '302: Found', txt) -def test_HTTPFound_empty_location(): +def test_HTTPFound_empty_location() -> None: with pytest.raises(ValueError): web.HTTPFound(location='') @@ -111,12 +111,12 @@ def test_HTTPFound_empty_location(): web.HTTPFound(location=None) -async def test_HTTPMethodNotAllowed(buf, request): +async def test_HTTPMethodNotAllowed(buf, http_request) -> None: resp = web.HTTPMethodNotAllowed('get', ['POST', 'PUT']) assert 'GET' == resp.method - assert ['POST', 'PUT'] == resp.allowed_methods + assert {'POST', 'PUT'} == resp.allowed_methods assert 'POST,PUT' == resp.headers['allow'] - await resp.prepare(request) + await resp.prepare(http_request) await resp.write_eof() txt = buf.decode('utf8') assert re.match('HTTP/1.1 405 Method Not Allowed\r\n' @@ -128,7 +128,7 @@ async def test_HTTPMethodNotAllowed(buf, request): '405: Method Not Allowed', txt) -def test_override_body_with_text(): +def test_override_body_with_text() -> None: resp = web.HTTPNotFound(text="Page not found") assert 404 == resp.status assert "Page not found".encode('utf-8') == resp.body @@ -137,10 +137,11 @@ def test_override_body_with_text(): assert "utf-8" == resp.charset -def test_override_body_with_binary(): +def test_override_body_with_binary() -> None: txt = "<html><body>Page not found</body></html>" - resp = web.HTTPNotFound(body=txt.encode('utf-8'), - content_type="text/html") + with pytest.warns(DeprecationWarning): + resp = web.HTTPNotFound(body=txt.encode('utf-8'), + content_type="text/html") assert 404 == resp.status assert txt.encode('utf-8') == resp.body assert txt == resp.text @@ -148,34 +149,34 @@ def test_override_body_with_binary(): assert resp.charset is None -def test_default_body(): +def test_default_body() -> None: resp = web.HTTPOk() assert b'200: OK' == resp.body -def test_empty_body_204(): +def test_empty_body_204() -> None: resp = web.HTTPNoContent() assert resp.body is None -def test_empty_body_205(): +def test_empty_body_205() -> None: resp = web.HTTPNoContent() assert resp.body is None -def test_empty_body_304(): +def test_empty_body_304() -> None: resp = web.HTTPNoContent() resp.body is None -def test_link_header_451(buf, request): +def test_link_header_451(buf) -> None: resp = web.HTTPUnavailableForLegalReasons(link='http://warning.or.kr/') assert 'http://warning.or.kr/' == resp.link assert '<http://warning.or.kr/>; rel="blocked-by"' == resp.headers['Link'] -def test_HTTPException_retains_cause(): +def test_HTTPException_retains_cause() -> None: with pytest.raises(web.HTTPException) as ei: try: raise Exception('CustomException') diff --git a/tests/test_web_functional.py b/tests/test_web_functional.py index b46467b..642ea2f 100644 --- a/tests/test_web_functional.py +++ b/tests/test_web_functional.py @@ -14,7 +14,6 @@ from yarl import URL import aiohttp from aiohttp import (FormData, HttpVersion10, HttpVersion11, TraceConfig, multipart, web) -from aiohttp.helpers import DEBUG try: @@ -33,7 +32,7 @@ def fname(here): return here / 'sample.key' -async def test_simple_get(aiohttp_client): +async def test_simple_get(aiohttp_client) -> None: async def handler(request): body = await request.read() @@ -50,7 +49,7 @@ async def test_simple_get(aiohttp_client): assert 'OK' == txt -async def test_simple_get_with_text(aiohttp_client): +async def test_simple_get_with_text(aiohttp_client) -> None: async def handler(request): body = await request.read() @@ -67,9 +66,9 @@ async def test_simple_get_with_text(aiohttp_client): assert 'OK' == txt -@pytest.mark.skipif(not DEBUG, - reason="The check is enabled in debug mode only") -async def test_handler_returns_not_response(aiohttp_server, aiohttp_client): +async def test_handler_returns_not_response(aiohttp_server, + aiohttp_client) -> None: + asyncio.get_event_loop().set_debug(True) logger = mock.Mock() async def handler(request): @@ -80,13 +79,35 @@ async def test_handler_returns_not_response(aiohttp_server, aiohttp_client): server = await aiohttp_server(app, logger=logger) client = await aiohttp_client(server) - resp = await client.get('/') - assert 500 == resp.status + with pytest.raises(aiohttp.ServerDisconnectedError): + await client.get('/') + + logger.exception.assert_called_with('Unhandled runtime exception', + exc_info=mock.ANY) + + +async def test_handler_returns_none(aiohttp_server, + aiohttp_client) -> None: + asyncio.get_event_loop().set_debug(True) + logger = mock.Mock() + + async def handler(request): + return None + + app = web.Application() + app.router.add_get('/', handler) + server = await aiohttp_server(app, logger=logger) + client = await aiohttp_client(server) + + with pytest.raises(aiohttp.ServerDisconnectedError): + await client.get('/') - assert logger.exception.called + # Actual error text is placed in exc_info + logger.exception.assert_called_with('Unhandled runtime exception', + exc_info=mock.ANY) -async def test_head_returns_empty_body(aiohttp_client): +async def test_head_returns_empty_body(aiohttp_client) -> None: async def handler(request): return web.Response(body=b'test') @@ -101,7 +122,7 @@ async def test_head_returns_empty_body(aiohttp_client): assert '' == txt -async def test_response_before_complete(aiohttp_client): +async def test_response_before_complete(aiohttp_client) -> None: async def handler(request): return web.Response(body=b'OK') @@ -118,7 +139,7 @@ async def test_response_before_complete(aiohttp_client): assert 'OK' == text -async def test_post_form(aiohttp_client): +async def test_post_form(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -135,7 +156,7 @@ async def test_post_form(aiohttp_client): assert 'OK' == txt -async def test_post_text(aiohttp_client): +async def test_post_text(aiohttp_client) -> None: async def handler(request): data = await request.text() @@ -154,7 +175,7 @@ async def test_post_text(aiohttp_client): assert 'русский' == txt -async def test_post_json(aiohttp_client): +async def test_post_json(aiohttp_client) -> None: dct = {'key': 'текст'} @@ -179,7 +200,7 @@ async def test_post_json(aiohttp_client): assert dct == data -async def test_multipart(aiohttp_client): +async def test_multipart(aiohttp_client) -> None: with multipart.MultipartWriter() as writer: writer.append('test') writer.append_json({'passed': True}) @@ -213,7 +234,7 @@ async def test_multipart(aiohttp_client): await resp.release() -async def test_multipart_content_transfer_encoding(aiohttp_client): +async def test_multipart_content_transfer_encoding(aiohttp_client) -> None: """For issue #1168""" with multipart.MultipartWriter() as writer: writer.append(b'\x00' * 10, @@ -243,7 +264,7 @@ async def test_multipart_content_transfer_encoding(aiohttp_client): await resp.release() -async def test_render_redirect(aiohttp_client): +async def test_render_redirect(aiohttp_client) -> None: async def handler(request): raise web.HTTPMovedPermanently(location='/path') @@ -259,7 +280,7 @@ async def test_render_redirect(aiohttp_client): assert '/path' == resp.headers['location'] -async def test_post_single_file(aiohttp_client): +async def test_post_single_file(aiohttp_client) -> None: here = pathlib.Path(__file__).parent @@ -289,7 +310,7 @@ async def test_post_single_file(aiohttp_client): assert 200 == resp.status -async def test_files_upload_with_same_key(aiohttp_client): +async def test_files_upload_with_same_key(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -322,7 +343,7 @@ async def test_files_upload_with_same_key(aiohttp_client): assert 200 == resp.status -async def test_post_files(aiohttp_client): +async def test_post_files(aiohttp_client) -> None: here = pathlib.Path(__file__).parent @@ -352,7 +373,7 @@ async def test_post_files(aiohttp_client): assert 200 == resp.status -async def test_release_post_data(aiohttp_client): +async def test_release_post_data(aiohttp_client) -> None: async def handler(request): await request.release() @@ -368,7 +389,8 @@ async def test_release_post_data(aiohttp_client): assert 200 == resp.status -async def test_POST_DATA_with_content_transfer_encoding(aiohttp_client): +async def test_POST_DATA_with_content_transfer_encoding( + aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -387,7 +409,7 @@ async def test_POST_DATA_with_content_transfer_encoding(aiohttp_client): assert 200 == resp.status -async def test_post_form_with_duplicate_keys(aiohttp_client): +async def test_post_form_with_duplicate_keys(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -403,12 +425,12 @@ async def test_post_form_with_duplicate_keys(aiohttp_client): assert 200 == resp.status -def test_repr_for_application(): +def test_repr_for_application() -> None: app = web.Application() assert "<Application 0x{:x}>".format(id(app)) == repr(app) -async def test_expect_default_handler_unknown(aiohttp_client): +async def test_expect_default_handler_unknown(aiohttp_client) -> None: """Test default Expect handler for unknown Expect value. A server that does not understand or is unable to comply with any of @@ -433,7 +455,7 @@ async def test_expect_default_handler_unknown(aiohttp_client): assert 417 == resp.status -async def test_100_continue(aiohttp_client): +async def test_100_continue(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -452,7 +474,7 @@ async def test_100_continue(aiohttp_client): assert 200 == resp.status -async def test_100_continue_custom(aiohttp_client): +async def test_100_continue_custom(aiohttp_client) -> None: expect_received = False @@ -480,7 +502,7 @@ async def test_100_continue_custom(aiohttp_client): assert expect_received -async def test_100_continue_custom_response(aiohttp_client): +async def test_100_continue_custom_response(aiohttp_client) -> None: async def handler(request): data = await request.post() @@ -511,7 +533,7 @@ async def test_100_continue_custom_response(aiohttp_client): assert 403 == resp.status -async def test_100_continue_for_not_found(aiohttp_client): +async def test_100_continue_for_not_found(aiohttp_client) -> None: app = web.Application() client = await aiohttp_client(app) @@ -520,7 +542,7 @@ async def test_100_continue_for_not_found(aiohttp_client): assert 404 == resp.status -async def test_100_continue_for_not_allowed(aiohttp_client): +async def test_100_continue_for_not_allowed(aiohttp_client) -> None: async def handler(request): return web.Response() @@ -533,7 +555,7 @@ async def test_100_continue_for_not_allowed(aiohttp_client): assert 405 == resp.status -async def test_http11_keep_alive_default(aiohttp_client): +async def test_http11_keep_alive_default(aiohttp_client) -> None: async def handler(request): return web.Response() @@ -549,7 +571,7 @@ async def test_http11_keep_alive_default(aiohttp_client): @pytest.mark.xfail -async def test_http10_keep_alive_default(aiohttp_client): +async def test_http10_keep_alive_default(aiohttp_client) -> None: async def handler(request): return web.Response() @@ -564,7 +586,7 @@ async def test_http10_keep_alive_default(aiohttp_client): assert resp.headers['Connection'] == 'keep-alive' -async def test_http10_keep_alive_with_headers_close(aiohttp_client): +async def test_http10_keep_alive_with_headers_close(aiohttp_client) -> None: async def handler(request): await request.read() @@ -581,7 +603,7 @@ async def test_http10_keep_alive_with_headers_close(aiohttp_client): assert 'Connection' not in resp.headers -async def test_http10_keep_alive_with_headers(aiohttp_client): +async def test_http10_keep_alive_with_headers(aiohttp_client) -> None: async def handler(request): await request.read() @@ -598,7 +620,7 @@ async def test_http10_keep_alive_with_headers(aiohttp_client): assert resp.headers['Connection'] == 'keep-alive' -async def test_upload_file(aiohttp_client): +async def test_upload_file(aiohttp_client) -> None: here = pathlib.Path(__file__).parent fname = here / 'aiohttp.png' @@ -619,7 +641,7 @@ async def test_upload_file(aiohttp_client): assert 200 == resp.status -async def test_upload_file_object(aiohttp_client): +async def test_upload_file_object(aiohttp_client) -> None: here = pathlib.Path(__file__).parent fname = here / 'aiohttp.png' with fname.open('rb') as f: @@ -640,7 +662,7 @@ async def test_upload_file_object(aiohttp_client): assert 200 == resp.status -async def test_empty_content_for_query_without_body(aiohttp_client): +async def test_empty_content_for_query_without_body(aiohttp_client) -> None: async def handler(request): assert not request.body_exists @@ -657,7 +679,7 @@ async def test_empty_content_for_query_without_body(aiohttp_client): assert 200 == resp.status -async def test_empty_content_for_query_with_body(aiohttp_client): +async def test_empty_content_for_query_with_body(aiohttp_client) -> None: async def handler(request): assert request.body_exists @@ -675,7 +697,7 @@ async def test_empty_content_for_query_with_body(aiohttp_client): assert 200 == resp.status -async def test_get_with_empty_arg(aiohttp_client): +async def test_get_with_empty_arg(aiohttp_client) -> None: async def handler(request): assert 'arg' in request.query @@ -690,7 +712,7 @@ async def test_get_with_empty_arg(aiohttp_client): assert 200 == resp.status -async def test_large_header(aiohttp_client): +async def test_large_header(aiohttp_client) -> None: async def handler(request): return web.Response() @@ -704,7 +726,7 @@ async def test_large_header(aiohttp_client): assert 400 == resp.status -async def test_large_header_allowed(aiohttp_client, aiohttp_server): +async def test_large_header_allowed(aiohttp_client, aiohttp_server) -> None: async def handler(request): return web.Response() @@ -719,7 +741,7 @@ async def test_large_header_allowed(aiohttp_client, aiohttp_server): assert 200 == resp.status -async def test_get_with_empty_arg_with_equal(aiohttp_client): +async def test_get_with_empty_arg_with_equal(aiohttp_client) -> None: async def handler(request): assert 'arg' in request.query @@ -734,7 +756,7 @@ async def test_get_with_empty_arg_with_equal(aiohttp_client): assert 200 == resp.status -async def test_response_with_async_gen(aiohttp_client, fname): +async def test_response_with_async_gen(aiohttp_client, fname) -> None: with fname.open('rb') as f: data = f.read() @@ -764,7 +786,7 @@ async def test_response_with_async_gen(aiohttp_client, fname): assert resp.headers.get('Content-Length') == str(len(resp_data)) -async def test_response_with_streamer(aiohttp_client, fname): +async def test_response_with_streamer(aiohttp_client, fname) -> None: with fname.open('rb') as f: data = f.read() @@ -795,7 +817,8 @@ async def test_response_with_streamer(aiohttp_client, fname): assert resp.headers.get('Content-Length') == str(len(resp_data)) -async def test_response_with_async_gen_no_params(aiohttp_client, fname): +async def test_response_with_async_gen_no_params(aiohttp_client, + fname) -> None: with fname.open('rb') as f: data = f.read() @@ -825,7 +848,7 @@ async def test_response_with_async_gen_no_params(aiohttp_client, fname): assert resp.headers.get('Content-Length') == str(len(resp_data)) -async def test_response_with_streamer_no_params(aiohttp_client, fname): +async def test_response_with_streamer_no_params(aiohttp_client, fname) -> None: with fname.open('rb') as f: data = f.read() @@ -856,7 +879,7 @@ async def test_response_with_streamer_no_params(aiohttp_client, fname): assert resp.headers.get('Content-Length') == str(len(resp_data)) -async def test_response_with_file(aiohttp_client, fname): +async def test_response_with_file(aiohttp_client, fname) -> None: with fname.open('rb') as f: data = f.read() @@ -879,7 +902,7 @@ async def test_response_with_file(aiohttp_client, fname): 'attachment; filename="sample.key"; filename*=utf-8\'\'sample.key') -async def test_response_with_file_ctype(aiohttp_client, fname): +async def test_response_with_file_ctype(aiohttp_client, fname) -> None: with fname.open('rb') as f: data = f.read() @@ -902,7 +925,7 @@ async def test_response_with_file_ctype(aiohttp_client, fname): 'attachment; filename="sample.key"; filename*=utf-8\'\'sample.key') -async def test_response_with_payload_disp(aiohttp_client, fname): +async def test_response_with_payload_disp(aiohttp_client, fname) -> None: with fname.open('rb') as f: data = f.read() @@ -927,7 +950,7 @@ async def test_response_with_payload_disp(aiohttp_client, fname): 'inline; filename="test.txt"; filename*=utf-8\'\'test.txt') -async def test_response_with_payload_stringio(aiohttp_client, fname): +async def test_response_with_payload_stringio(aiohttp_client, fname) -> None: async def handler(request): return web.Response(body=io.StringIO('test')) @@ -942,7 +965,7 @@ async def test_response_with_payload_stringio(aiohttp_client, fname): assert resp_data == b'test' -async def test_response_with_precompressed_body_gzip(aiohttp_client): +async def test_response_with_precompressed_body_gzip(aiohttp_client) -> None: async def handler(request): headers = {'Content-Encoding': 'gzip'} @@ -961,7 +984,8 @@ async def test_response_with_precompressed_body_gzip(aiohttp_client): assert resp.headers.get('Content-Encoding') == 'gzip' -async def test_response_with_precompressed_body_deflate(aiohttp_client): +async def test_response_with_precompressed_body_deflate( + aiohttp_client) -> None: async def handler(request): headers = {'Content-Encoding': 'deflate'} @@ -980,7 +1004,7 @@ async def test_response_with_precompressed_body_deflate(aiohttp_client): assert resp.headers.get('Content-Encoding') == 'deflate' -async def test_bad_request_payload(aiohttp_client): +async def test_bad_request_payload(aiohttp_client) -> None: async def handler(request): assert request.method == 'POST' @@ -999,7 +1023,7 @@ async def test_bad_request_payload(aiohttp_client): assert 200 == resp.status -async def test_stream_response_multiple_chunks(aiohttp_client): +async def test_stream_response_multiple_chunks(aiohttp_client) -> None: async def handler(request): resp = web.StreamResponse() @@ -1020,7 +1044,7 @@ async def test_stream_response_multiple_chunks(aiohttp_client): assert b'xyz' == data -async def test_start_without_routes(aiohttp_client): +async def test_start_without_routes(aiohttp_client) -> None: app = web.Application() client = await aiohttp_client(app) @@ -1029,7 +1053,7 @@ async def test_start_without_routes(aiohttp_client): assert 404 == resp.status -async def test_requests_count(aiohttp_client): +async def test_requests_count(aiohttp_client) -> None: async def handler(request): return web.Response() @@ -1052,7 +1076,7 @@ async def test_requests_count(aiohttp_client): assert client.server.handler.requests_count == 3 -async def test_redirect_url(aiohttp_client): +async def test_redirect_url(aiohttp_client) -> None: async def redirector(request): raise web.HTTPFound(location=URL('/redirected')) @@ -1069,7 +1093,7 @@ async def test_redirect_url(aiohttp_client): assert resp.status == 200 -async def test_simple_subapp(aiohttp_client): +async def test_simple_subapp(aiohttp_client) -> None: async def handler(request): return web.Response(text="OK") @@ -1086,7 +1110,7 @@ async def test_simple_subapp(aiohttp_client): assert 'OK' == txt -async def test_subapp_reverse_url(aiohttp_client): +async def test_subapp_reverse_url(aiohttp_client) -> None: async def handler(request): raise web.HTTPMovedPermanently( @@ -1109,7 +1133,7 @@ async def test_subapp_reverse_url(aiohttp_client): assert resp.url.path == '/path/final' -async def test_subapp_reverse_variable_url(aiohttp_client): +async def test_subapp_reverse_variable_url(aiohttp_client) -> None: async def handler(request): raise web.HTTPMovedPermanently( @@ -1132,7 +1156,7 @@ async def test_subapp_reverse_variable_url(aiohttp_client): assert resp.url.path == '/path/final' -async def test_subapp_reverse_static_url(aiohttp_client): +async def test_subapp_reverse_static_url(aiohttp_client) -> None: fname = 'aiohttp.png' async def handler(request): @@ -1155,7 +1179,7 @@ async def test_subapp_reverse_static_url(aiohttp_client): assert body == f.read() -async def test_subapp_app(aiohttp_client): +async def test_subapp_app(aiohttp_client) -> None: async def handler(request): assert request.app is subapp @@ -1173,7 +1197,7 @@ async def test_subapp_app(aiohttp_client): assert 'OK' == txt -async def test_subapp_not_found(aiohttp_client): +async def test_subapp_not_found(aiohttp_client) -> None: async def handler(request): return web.Response(text='OK') @@ -1188,7 +1212,7 @@ async def test_subapp_not_found(aiohttp_client): assert resp.status == 404 -async def test_subapp_not_found2(aiohttp_client): +async def test_subapp_not_found2(aiohttp_client) -> None: async def handler(request): return web.Response(text='OK') @@ -1203,7 +1227,7 @@ async def test_subapp_not_found2(aiohttp_client): assert resp.status == 404 -async def test_subapp_not_allowed(aiohttp_client): +async def test_subapp_not_allowed(aiohttp_client) -> None: async def handler(request): return web.Response(text='OK') @@ -1219,7 +1243,7 @@ async def test_subapp_not_allowed(aiohttp_client): assert resp.headers['Allow'] == 'GET,HEAD' -async def test_subapp_cannot_add_app_in_handler(aiohttp_client): +async def test_subapp_cannot_add_app_in_handler(aiohttp_client) -> None: async def handler(request): request.match_info.add_app(app) @@ -1235,7 +1259,7 @@ async def test_subapp_cannot_add_app_in_handler(aiohttp_client): assert resp.status == 500 -async def test_subapp_middlewares(aiohttp_client): +async def test_subapp_middlewares(aiohttp_client) -> None: order = [] async def handler(request): @@ -1266,7 +1290,7 @@ async def test_subapp_middlewares(aiohttp_client): (2, subapp2), (2, subapp1), (2, app)] == order -async def test_subapp_on_response_prepare(aiohttp_client): +async def test_subapp_on_response_prepare(aiohttp_client) -> None: order = [] async def handler(request): @@ -1295,7 +1319,7 @@ async def test_subapp_on_response_prepare(aiohttp_client): assert [app, subapp1, subapp2] == order -async def test_subapp_on_startup(aiohttp_server): +async def test_subapp_on_startup(aiohttp_server) -> None: order = [] async def on_signal(app): @@ -1315,7 +1339,7 @@ async def test_subapp_on_startup(aiohttp_server): assert [app, subapp1, subapp2] == order -async def test_subapp_on_shutdown(aiohttp_server): +async def test_subapp_on_shutdown(aiohttp_server) -> None: order = [] async def on_signal(app): @@ -1336,7 +1360,7 @@ async def test_subapp_on_shutdown(aiohttp_server): assert [app, subapp1, subapp2] == order -async def test_subapp_on_cleanup(aiohttp_server): +async def test_subapp_on_cleanup(aiohttp_server) -> None: order = [] async def on_signal(app): @@ -1406,7 +1430,7 @@ async def test_subapp_middleware_context(aiohttp_client, assert expected == values -async def test_custom_date_header(aiohttp_client): +async def test_custom_date_header(aiohttp_client) -> None: async def handler(request): return web.Response(headers={'Date': 'Sun, 30 Oct 2016 03:13:52 GMT'}) @@ -1420,7 +1444,7 @@ async def test_custom_date_header(aiohttp_client): assert resp.headers['Date'] == 'Sun, 30 Oct 2016 03:13:52 GMT' -async def test_response_prepared_with_clone(aiohttp_client): +async def test_response_prepared_with_clone(aiohttp_client) -> None: async def handler(request): cloned = request.clone() @@ -1436,7 +1460,7 @@ async def test_response_prepared_with_clone(aiohttp_client): assert 200 == resp.status -async def test_app_max_client_size(aiohttp_client): +async def test_app_max_client_size(aiohttp_client) -> None: async def handler(request): await request.post() @@ -1455,7 +1479,7 @@ async def test_app_max_client_size(aiohttp_client): 'actual body size 1048591' in resp_text -async def test_app_max_client_size_adjusted(aiohttp_client): +async def test_app_max_client_size_adjusted(aiohttp_client) -> None: async def handler(request): await request.post() @@ -1481,7 +1505,7 @@ async def test_app_max_client_size_adjusted(aiohttp_client): 'actual body size 2097166' in resp_text -async def test_app_max_client_size_none(aiohttp_client): +async def test_app_max_client_size_none(aiohttp_client) -> None: async def handler(request): await request.post() @@ -1506,7 +1530,7 @@ async def test_app_max_client_size_none(aiohttp_client): assert resp_text == 'ok' -async def test_post_max_client_size(aiohttp_client): +async def test_post_max_client_size(aiohttp_client) -> None: async def handler(request): await request.post() @@ -1525,7 +1549,7 @@ async def test_post_max_client_size(aiohttp_client): 'actual body size 1024' in resp_text -async def test_post_max_client_size_for_file(aiohttp_client): +async def test_post_max_client_size_for_file(aiohttp_client) -> None: async def handler(request): await request.post() @@ -1541,7 +1565,7 @@ async def test_post_max_client_size_for_file(aiohttp_client): assert 413 == resp.status -async def test_response_with_bodypart(aiohttp_client): +async def test_response_with_bodypart(aiohttp_client) -> None: async def handler(request): reader = await request.multipart() @@ -1565,7 +1589,7 @@ async def test_response_with_bodypart(aiohttp_client): {'name': 'file', 'filename': 'file', 'filename*': 'file'}) -async def test_response_with_bodypart_named(aiohttp_client, tmpdir): +async def test_response_with_bodypart_named(aiohttp_client, tmpdir) -> None: async def handler(request): reader = await request.multipart() @@ -1593,7 +1617,7 @@ async def test_response_with_bodypart_named(aiohttp_client, tmpdir): ) -async def test_response_with_bodypart_invalid_name(aiohttp_client): +async def test_response_with_bodypart_invalid_name(aiohttp_client) -> None: async def handler(request): reader = await request.multipart() @@ -1615,7 +1639,7 @@ async def test_response_with_bodypart_invalid_name(aiohttp_client): assert 'content-disposition' not in resp.headers -async def test_request_clone(aiohttp_client): +async def test_request_clone(aiohttp_client) -> None: async def handler(request): r2 = request.clone(method='POST') @@ -1631,7 +1655,7 @@ async def test_request_clone(aiohttp_client): assert 200 == resp.status -async def test_await(aiohttp_server): +async def test_await(aiohttp_server) -> None: async def handler(request): resp = web.StreamResponse(headers={'content-length': str(4)}) @@ -1657,7 +1681,7 @@ async def test_await(aiohttp_server): assert resp.connection is None -async def test_response_context_manager(aiohttp_server): +async def test_response_context_manager(aiohttp_server) -> None: async def handler(request): return web.Response() @@ -1672,7 +1696,7 @@ async def test_response_context_manager(aiohttp_server): assert resp.connection is None -async def test_response_context_manager_error(aiohttp_server): +async def test_response_context_manager_error(aiohttp_server) -> None: async def handler(request): return web.Response(text='some text') @@ -1709,7 +1733,8 @@ async def aiohttp_client_api_context_manager(aiohttp_server): assert resp.connection is None -async def test_context_manager_close_on_release(aiohttp_server, mocker): +async def test_context_manager_close_on_release(aiohttp_server, + mocker) -> None: async def handler(request): resp = web.StreamResponse() @@ -1734,7 +1759,7 @@ async def test_context_manager_close_on_release(aiohttp_server, mocker): assert proto.close.called -async def test_iter_any(aiohttp_server): +async def test_iter_any(aiohttp_server) -> None: data = b'0123456789' * 1024 @@ -1754,7 +1779,7 @@ async def test_iter_any(aiohttp_server): assert resp.status == 200 -async def test_request_tracing(aiohttp_server): +async def test_request_tracing(aiohttp_server) -> None: on_request_start = mock.Mock(side_effect=asyncio.coroutine(mock.Mock())) on_request_end = mock.Mock(side_effect=asyncio.coroutine(mock.Mock())) @@ -1829,7 +1854,7 @@ async def test_request_tracing(aiohttp_server): await client.close() -async def test_return_http_exception_deprecated(aiohttp_client): +async def test_return_http_exception_deprecated(aiohttp_client) -> None: async def handler(request): return web.HTTPForbidden() @@ -1842,7 +1867,7 @@ async def test_return_http_exception_deprecated(aiohttp_client): await client.get('/') -async def test_request_path(aiohttp_client): +async def test_request_path(aiohttp_client) -> None: async def handler(request): assert request.path_qs == '/path%20to?a=1' @@ -1860,7 +1885,7 @@ async def test_request_path(aiohttp_client): assert 'OK' == txt -async def test_app_add_routes(aiohttp_client): +async def test_app_add_routes(aiohttp_client) -> None: async def handler(request): return web.Response() @@ -1873,7 +1898,7 @@ async def test_app_add_routes(aiohttp_client): assert resp.status == 200 -async def test_request_headers_type(aiohttp_client): +async def test_request_headers_type(aiohttp_client) -> None: async def handler(request): assert isinstance(request.headers, CIMultiDictProxy) @@ -1887,7 +1912,7 @@ async def test_request_headers_type(aiohttp_client): assert resp.status == 200 -async def test_signal_on_error_handler(aiohttp_client): +async def test_signal_on_error_handler(aiohttp_client) -> None: async def on_prepare(request, response): response.headers['X-Custom'] = 'val' diff --git a/tests/test_web_log.py b/tests/test_web_log.py new file mode 100644 index 0000000..8261eb8 --- /dev/null +++ b/tests/test_web_log.py @@ -0,0 +1,159 @@ +import datetime +import platform +from unittest import mock + +import pytest + +from aiohttp.abc import AbstractAccessLogger +from aiohttp.web_log import AccessLogger + + +IS_PYPY = platform.python_implementation() == 'PyPy' + + +def test_access_logger_format() -> None: + log_format = '%T "%{ETag}o" %X {X} %%P' + mock_logger = mock.Mock() + access_logger = AccessLogger(mock_logger, log_format) + expected = '%s "%s" %%X {X} %%%s' + assert expected == access_logger._log_format + + +@pytest.mark.skip( + IS_PYPY, + """ + Because of patching :py:class:`datetime.datetime`, under PyPy it + fails in :py:func:`isinstance` call in + :py:meth:`datetime.datetime.__sub__` (called from + :py:meth:`aiohttp.AccessLogger._format_t`): + + *** TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types + + (Pdb) from datetime import datetime + (Pdb) isinstance(now, datetime) + *** TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types + (Pdb) datetime.__class__ + <class 'unittest.mock.MagicMock'> + (Pdb) isinstance(now, datetime.__class__) + False + + Ref: https://bitbucket.org/pypy/pypy/issues/1187/call-to-isinstance-in-__sub__-self-other + Ref: https://github.com/celery/celery/issues/811 + Ref: https://stackoverflow.com/a/46102240/595220 + """, # noqa: E501 +) +def test_access_logger_atoms(mocker) -> None: + utcnow = datetime.datetime(1843, 1, 1, 0, 30) + mock_datetime = mocker.patch("aiohttp.datetime.datetime") + mock_getpid = mocker.patch("os.getpid") + mock_datetime.utcnow.return_value = utcnow + mock_getpid.return_value = 42 + log_format = '%a %t %P %r %s %b %T %Tf %D "%{H1}i" "%{H2}i"' + mock_logger = mock.Mock() + access_logger = AccessLogger(mock_logger, log_format) + request = mock.Mock(headers={'H1': 'a', 'H2': 'b'}, + method="GET", path_qs="/path", + version=(1, 1), + remote="127.0.0.2") + response = mock.Mock(headers={}, body_length=42, status=200) + access_logger.log(request, response, 3.1415926) + assert not mock_logger.exception.called + expected = ('127.0.0.2 [01/Jan/1843:00:29:56 +0000] <42> ' + 'GET /path HTTP/1.1 200 42 3 3.141593 3141593 "a" "b"') + extra = { + 'first_request_line': 'GET /path HTTP/1.1', + 'process_id': '<42>', + 'remote_address': '127.0.0.2', + 'request_start_time': '[01/Jan/1843:00:29:56 +0000]', + 'request_time': 3, + 'request_time_frac': '3.141593', + 'request_time_micro': 3141593, + 'response_size': 42, + 'response_status': 200, + 'request_header': {'H1': 'a', 'H2': 'b'}, + } + + mock_logger.info.assert_called_with(expected, extra=extra) + + +def test_access_logger_dicts() -> None: + log_format = '%{User-Agent}i %{Content-Length}o %{None}i' + mock_logger = mock.Mock() + access_logger = AccessLogger(mock_logger, log_format) + request = mock.Mock(headers={"User-Agent": "Mock/1.0"}, version=(1, 1), + remote="127.0.0.2") + response = mock.Mock(headers={"Content-Length": 123}) + access_logger.log(request, response, 0.0) + assert not mock_logger.error.called + expected = 'Mock/1.0 123 -' + extra = { + 'request_header': {"User-Agent": "Mock/1.0", 'None': '-'}, + 'response_header': {'Content-Length': 123} + } + + mock_logger.info.assert_called_with(expected, extra=extra) + + +def test_access_logger_unix_socket() -> None: + log_format = '|%a|' + mock_logger = mock.Mock() + access_logger = AccessLogger(mock_logger, log_format) + request = mock.Mock(headers={"User-Agent": "Mock/1.0"}, version=(1, 1), + remote="") + response = mock.Mock() + access_logger.log(request, response, 0.0) + assert not mock_logger.error.called + expected = '||' + mock_logger.info.assert_called_with(expected, extra={'remote_address': ''}) + + +def test_logger_no_message() -> None: + mock_logger = mock.Mock() + access_logger = AccessLogger(mock_logger, + "%r %{content-type}i") + extra_dict = { + 'first_request_line': '-', + 'request_header': {'content-type': '(no headers)'} + } + + access_logger.log(None, None, 0.0) + mock_logger.info.assert_called_with("- (no headers)", extra=extra_dict) + + +def test_logger_internal_error() -> None: + mock_logger = mock.Mock() + access_logger = AccessLogger(mock_logger, "%D") + access_logger.log(None, None, 'invalid') + mock_logger.exception.assert_called_with("Error in logging") + + +def test_logger_no_transport() -> None: + mock_logger = mock.Mock() + access_logger = AccessLogger(mock_logger, "%a") + access_logger.log(None, None, 0) + mock_logger.info.assert_called_with("-", extra={'remote_address': '-'}) + + +def test_logger_abc() -> None: + class Logger(AbstractAccessLogger): + def log(self, request, response, time): + 1 / 0 + + mock_logger = mock.Mock() + access_logger = Logger(mock_logger, None) + + with pytest.raises(ZeroDivisionError): + access_logger.log(None, None, None) + + class Logger(AbstractAccessLogger): + def log(self, request, response, time): + self.logger.info(self.log_format.format( + request=request, + response=response, + time=time + )) + + mock_logger = mock.Mock() + access_logger = Logger(mock_logger, '{request} {response} {time}') + access_logger.log('request', 'response', 1) + mock_logger.info.assert_called_with('request response 1') diff --git a/tests/test_web_middleware.py b/tests/test_web_middleware.py index e107cc1..2eba995 100644 --- a/tests/test_web_middleware.py +++ b/tests/test_web_middleware.py @@ -1,11 +1,12 @@ import re import pytest +from yarl import URL from aiohttp import web -async def test_middleware_modifies_response(loop, aiohttp_client): +async def test_middleware_modifies_response(loop, aiohttp_client) -> None: async def handler(request): return web.Response(body=b'OK') @@ -27,7 +28,7 @@ async def test_middleware_modifies_response(loop, aiohttp_client): assert 'OK[MIDDLEWARE]' == txt -async def test_middleware_handles_exception(loop, aiohttp_client): +async def test_middleware_handles_exception(loop, aiohttp_client) -> None: async def handler(request): raise RuntimeError('Error text') @@ -48,7 +49,7 @@ async def test_middleware_handles_exception(loop, aiohttp_client): assert 'Error text[MIDDLEWARE]' == txt -async def test_middleware_chain(loop, aiohttp_client): +async def test_middleware_chain(loop, aiohttp_client) -> None: async def handler(request): return web.Response(text='OK') @@ -115,6 +116,7 @@ class TestNormalizePathMiddleware: resp = await client.get(path) assert resp.status == status + assert resp.url.query == URL(path).query @pytest.mark.parametrize("path, status", [ ('/resource1', 200), @@ -128,7 +130,8 @@ class TestNormalizePathMiddleware: ('/resource2/a/b%2Fc', 404), ('/resource2/a/b%2Fc/', 200) ]) - async def test_remove_trailing_when_necessary(self, path, status, cli): + async def test_remove_trailing_when_necessary(self, path, + status, cli) -> None: extra_middlewares = [ web.normalize_path_middleware( append_slash=False, remove_slash=True, merge_slashes=False)] @@ -136,6 +139,7 @@ class TestNormalizePathMiddleware: resp = await client.get(path) assert resp.status == status + assert resp.url.query == URL(path).query @pytest.mark.parametrize("path, status", [ ('/resource1', 200), @@ -158,6 +162,7 @@ class TestNormalizePathMiddleware: resp = await client.get(path) assert resp.status == status + assert resp.url.query == URL(path).query @pytest.mark.parametrize("path, status", [ ('/resource1/a/b', 200), @@ -173,13 +178,14 @@ class TestNormalizePathMiddleware: ('/////resource1/a///b?p=1', 200), ('/////resource1/a//b/?p=1', 404), ]) - async def test_merge_slash(self, path, status, cli): + async def test_merge_slash(self, path, status, cli) -> None: extra_middlewares = [ web.normalize_path_middleware(append_slash=False)] client = await cli(extra_middlewares) resp = await client.get(path) assert resp.status == status + assert resp.url.query == URL(path).query @pytest.mark.parametrize("path, status", [ ('/resource1/a/b', 200), @@ -213,13 +219,14 @@ class TestNormalizePathMiddleware: ('/////resource2/a///b?p=1', 200), ('/////resource2/a///b/?p=1', 200) ]) - async def test_append_and_merge_slash(self, path, status, cli): + async def test_append_and_merge_slash(self, path, status, cli) -> None: extra_middlewares = [ web.normalize_path_middleware()] client = await cli(extra_middlewares) resp = await client.get(path) assert resp.status == status + assert resp.url.query == URL(path).query @pytest.mark.parametrize("path, status", [ ('/resource1/a/b', 200), @@ -254,7 +261,7 @@ class TestNormalizePathMiddleware: ('/////resource2/a///b?p=1', 404), ('/////resource2/a///b/?p=1', 200) ]) - async def test_remove_and_merge_slash(self, path, status, cli): + async def test_remove_and_merge_slash(self, path, status, cli) -> None: extra_middlewares = [ web.normalize_path_middleware( append_slash=False, remove_slash=True)] @@ -262,13 +269,14 @@ class TestNormalizePathMiddleware: client = await cli(extra_middlewares) resp = await client.get(path) assert resp.status == status + assert resp.url.query == URL(path).query - async def test_cannot_remove_and_add_slash(self): + async def test_cannot_remove_and_add_slash(self) -> None: with pytest.raises(AssertionError): web.normalize_path_middleware(append_slash=True, remove_slash=True) -async def test_old_style_middleware(loop, aiohttp_client): +async def test_old_style_middleware(loop, aiohttp_client) -> None: async def handler(request): return web.Response(body=b'OK') @@ -301,7 +309,7 @@ async def test_old_style_middleware(loop, aiohttp_client): msg) -async def test_mixed_middleware(loop, aiohttp_client): +async def test_mixed_middleware(loop, aiohttp_client) -> None: async def handler(request): return web.Response(body=b'OK') @@ -354,7 +362,7 @@ async def test_mixed_middleware(loop, aiohttp_client): assert re.match(p1, str(w.list[1].message)) -async def test_old_style_middleware_class(loop, aiohttp_client): +async def test_old_style_middleware_class(loop, aiohttp_client) -> None: async def handler(request): return web.Response(body=b'OK') @@ -386,7 +394,7 @@ async def test_old_style_middleware_class(loop, aiohttp_client): 'at 0x[0-9a-fA-F]+>" deprecated, see #2252$', msg) -async def test_new_style_middleware_class(loop, aiohttp_client): +async def test_new_style_middleware_class(loop, aiohttp_client) -> None: async def handler(request): return web.Response(body=b'OK') @@ -412,7 +420,7 @@ async def test_new_style_middleware_class(loop, aiohttp_client): assert len(warning_checker) == 0 -async def test_new_style_middleware_method(loop, aiohttp_client): +async def test_new_style_middleware_method(loop, aiohttp_client) -> None: async def handler(request): return web.Response(body=b'OK') diff --git a/tests/test_web_protocol.py b/tests/test_web_protocol.py index bd721c5..829d1ec 100644 --- a/tests/test_web_protocol.py +++ b/tests/test_web_protocol.py @@ -30,7 +30,9 @@ def make_srv(loop, manager): @pytest.fixture def manager(request_handler, loop): - return web.Server(request_handler, loop=loop) + async def maker(): + return web.Server(request_handler) + return loop.run_until_complete(maker()) @pytest.fixture @@ -98,7 +100,8 @@ def ceil(mocker): mocker.patch('aiohttp.helpers.ceil').side_effect = ceil -async def test_shutdown(srv, loop, transport): +async def test_shutdown(srv, transport) -> None: + loop = asyncio.get_event_loop() assert transport is srv.transport srv._keepalive = True @@ -117,11 +120,11 @@ async def test_shutdown(srv, loop, transport): assert srv.transport is None assert not srv._task_handler - await asyncio.sleep(0.1, loop=loop) + await asyncio.sleep(0.1) assert task_handler.done() -async def test_double_shutdown(srv, transport): +async def test_double_shutdown(srv, transport) -> None: await srv.shutdown() assert transport.close.called assert srv.transport is None @@ -132,7 +135,8 @@ async def test_double_shutdown(srv, transport): assert srv.transport is None -async def test_shutdown_wait_error_handler(loop, srv, transport): +async def test_shutdown_wait_error_handler(srv, transport) -> None: + loop = asyncio.get_event_loop() async def _error_handle(): pass @@ -142,14 +146,14 @@ async def test_shutdown_wait_error_handler(loop, srv, transport): assert srv._error_handler.done() -async def test_close_after_response(srv, loop, transport): +async def test_close_after_response(srv, transport) -> None: srv.data_received( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n' b'Content-Length: 0\r\n\r\n') h = srv._task_handler - await asyncio.sleep(0.1, loop=loop) + await asyncio.sleep(0.1) assert srv._waiter is None assert srv._task_handler is None @@ -159,13 +163,13 @@ async def test_close_after_response(srv, loop, transport): assert h.done() -def test_connection_made(make_srv): +def test_connection_made(make_srv) -> None: srv = make_srv() srv.connection_made(mock.Mock()) assert not srv._force_close -def test_connection_made_with_tcp_keepaplive(make_srv, transport): +def test_connection_made_with_tcp_keepaplive(make_srv, transport) -> None: srv = make_srv() sock = mock.Mock() @@ -175,7 +179,7 @@ def test_connection_made_with_tcp_keepaplive(make_srv, transport): socket.SO_KEEPALIVE, 1) -def test_connection_made_without_tcp_keepaplive(make_srv): +def test_connection_made_without_tcp_keepaplive(make_srv) -> None: srv = make_srv(tcp_keepalive=False) sock = mock.Mock() @@ -185,14 +189,14 @@ def test_connection_made_without_tcp_keepaplive(make_srv): assert not sock.setsockopt.called -def test_eof_received(make_srv): +def test_eof_received(make_srv) -> None: srv = make_srv() srv.connection_made(mock.Mock()) srv.eof_received() # assert srv.reader._eof -async def test_connection_lost(srv, loop): +async def test_connection_lost(srv) -> None: srv.data_received( b'GET / HTTP/1.1\r\n' b'Host: example.com\r\n' @@ -200,7 +204,7 @@ async def test_connection_lost(srv, loop): srv._keepalive = True handle = srv._task_handler - await asyncio.sleep(0, loop=loop) # wait for .start() starting + await asyncio.sleep(0) # wait for .start() starting srv.connection_lost(None) assert srv._force_close @@ -210,7 +214,7 @@ async def test_connection_lost(srv, loop): assert not srv._task_handler -def test_srv_keep_alive(srv): +def test_srv_keep_alive(srv) -> None: assert not srv._keepalive srv.keep_alive(True) @@ -220,7 +224,7 @@ def test_srv_keep_alive(srv): assert not srv._keepalive -def test_srv_keep_alive_disable(srv): +def test_srv_keep_alive_disable(srv) -> None: handle = srv._keepalive_handle = mock.Mock() srv.keep_alive(False) @@ -229,24 +233,24 @@ def test_srv_keep_alive_disable(srv): handle.cancel.assert_called_with() -async def test_simple(srv, loop, buf): +async def test_simple(srv, buf) -> None: srv.data_received( b'GET / HTTP/1.1\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0.05) assert buf.startswith(b'HTTP/1.1 200 OK\r\n') -async def test_bad_method(srv, loop, buf): +async def test_bad_method(srv, buf) -> None: srv.data_received( - b'!@#$ / HTTP/1.0\r\n' + b':BAD; / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert buf.startswith(b'HTTP/1.0 400 Bad Request\r\n') -async def test_data_received_error(srv, loop, buf): +async def test_data_received_error(srv, buf) -> None: transport = srv.transport srv._request_parser = mock.Mock() srv._request_parser.feed_data.side_effect = TypeError @@ -255,31 +259,31 @@ async def test_data_received_error(srv, loop, buf): b'!@#$ / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert buf.startswith(b'HTTP/1.0 500 Internal Server Error\r\n') assert transport.close.called assert srv._error_handler is None -async def test_line_too_long(srv, loop, buf): +async def test_line_too_long(srv, buf) -> None: srv.data_received(b''.join([b'a' for _ in range(10000)]) + b'\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert buf.startswith(b'HTTP/1.0 400 Bad Request\r\n') -async def test_invalid_content_length(srv, loop, buf): +async def test_invalid_content_length(srv, buf) -> None: srv.data_received( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n' b'Content-Length: sdgg\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert buf.startswith(b'HTTP/1.0 400 Bad Request\r\n') async def test_handle_error__utf( - make_srv, buf, transport, loop, request_handler + make_srv, buf, transport, request_handler ): request_handler.side_effect = RuntimeError('что-то пошло не так') @@ -292,7 +296,7 @@ async def test_handle_error__utf( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n' b'Content-Length: 0\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert b'HTTP/1.0 500 Internal Server Error' in buf assert b'Content-Type: text/html; charset=utf-8' in buf @@ -305,7 +309,7 @@ async def test_handle_error__utf( async def test_unhandled_runtime_error( - make_srv, loop, transport, request_handler + make_srv, transport, request_handler ): async def handle(request): @@ -332,7 +336,7 @@ async def test_unhandled_runtime_error( async def test_handle_uncompleted( - make_srv, loop, transport, handle_with_error, request_handler): + make_srv, transport, handle_with_error, request_handler): closed = False def close(): @@ -359,7 +363,7 @@ async def test_handle_uncompleted( async def test_handle_uncompleted_pipe( - make_srv, loop, transport, request_handler, handle_with_error): + make_srv, transport, request_handler, handle_with_error): closed = False normal_completed = False @@ -376,7 +380,7 @@ async def test_handle_uncompleted_pipe( async def handle(request): nonlocal normal_completed normal_completed = True - await asyncio.sleep(0.05, loop=loop) + await asyncio.sleep(0.05) return web.Response() # normal @@ -385,7 +389,7 @@ async def test_handle_uncompleted_pipe( b'GET / HTTP/1.1\r\n' b'Host: example.com\r\n' b'Content-Length: 0\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) # with exception request_handler.side_effect = handle_with_error() @@ -396,7 +400,7 @@ async def test_handle_uncompleted_pipe( assert srv._task_handler - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) await srv._task_handler assert normal_completed @@ -406,7 +410,7 @@ async def test_handle_uncompleted_pipe( "Error handling request", exc_info=mock.ANY) -async def test_lingering(srv, loop, transport): +async def test_lingering(srv, transport) -> None: assert not transport.close.called async def handle(message, request, writer): @@ -418,64 +422,65 @@ async def test_lingering(srv, loop, transport): b'Host: example.com\r\n' b'Content-Length: 3\r\n\r\n') - await asyncio.sleep(0.05, loop=loop) + await asyncio.sleep(0.05) assert not transport.close.called srv.data_received(b'123') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) transport.close.assert_called_with() -async def test_lingering_disabled(make_srv, loop, transport, request_handler): +async def test_lingering_disabled(make_srv, + transport, request_handler) -> None: async def handle_request(request): - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) srv = make_srv(lingering_time=0) srv.connection_made(transport) request_handler.side_effect = handle_request - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert not transport.close.called srv.data_received( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n' b'Content-Length: 50\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert not transport.close.called - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0.05) transport.close.assert_called_with() async def test_lingering_timeout( - make_srv, loop, transport, ceil, request_handler + make_srv, transport, ceil, request_handler ): async def handle_request(request): - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) srv = make_srv(lingering_time=1e-30) srv.connection_made(transport) request_handler.side_effect = handle_request - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0.05) assert not transport.close.called srv.data_received( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n' b'Content-Length: 50\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert not transport.close.called - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0.05) transport.close.assert_called_with() async def test_handle_payload_access_error( - make_srv, loop, transport, request_handler + make_srv, transport, request_handler ): srv = make_srv(lingering_time=0) srv.connection_made(transport) @@ -485,20 +490,20 @@ async def test_handle_payload_access_error( b'some data' ) # start request_handler task - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0.05) with pytest.raises(web.PayloadAccessError): await request_handler.call_args[0][0].content.read() -def test_handle_cancel(make_srv, loop, transport): +async def test_handle_cancel(make_srv, transport) -> None: log = mock.Mock() srv = make_srv(logger=log, debug=True) srv.connection_made(transport) async def handle_request(message, payload, writer): - await asyncio.sleep(10, loop=loop) + await asyncio.sleep(10) srv.handle_request = handle_request @@ -510,12 +515,11 @@ def test_handle_cancel(make_srv, loop, transport): b'Content-Length: 10\r\n' b'Host: example.com\r\n\r\n') - loop.run_until_complete( - asyncio.gather(srv._task_handler, cancel(), loop=loop)) + await asyncio.gather(srv._task_handler, cancel()) assert log.debug.called -def test_handle_cancelled(make_srv, loop, transport): +async def test_handle_cancelled(make_srv, transport) -> None: log = mock.Mock() srv = make_srv(logger=log, debug=True) @@ -523,35 +527,47 @@ def test_handle_cancelled(make_srv, loop, transport): srv.handle_request = mock.Mock() # start request_handler task - loop.run_until_complete(asyncio.sleep(0, loop=loop)) + await asyncio.sleep(0) srv.data_received( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') r_handler = srv._task_handler - assert loop.run_until_complete(r_handler) is None + assert (await r_handler) is None -async def test_handle_400(srv, loop, buf, transport): +async def test_handle_400(srv, buf, transport) -> None: srv.data_received(b'GET / HT/asd\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert b'400 Bad Request' in buf -def test_handle_500(srv, loop, buf, transport, request_handler): +async def test_handle_500(srv, buf, transport, request_handler) -> None: request_handler.side_effect = ValueError srv.data_received( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') - loop.run_until_complete(srv._task_handler) + await srv._task_handler assert b'500 Internal Server Error' in buf -async def test_keep_alive(make_srv, loop, transport, ceil): +async def test_handle_504(srv, buf, request_handler) -> None: + request_handler.side_effect = asyncio.TimeoutError + + srv.data_received( + b'GET / HTTP/1.0\r\n' + b'Host: example.com\r\n\r\n') + await srv._task_handler + + assert b'504 Gateway Timeout' in buf + + +async def test_keep_alive(make_srv, transport, ceil) -> None: + loop = asyncio.get_event_loop() srv = make_srv(keepalive_timeout=0.05) srv.KEEPALIVE_RESCHEDULE_DELAY = 0.1 srv.connection_made(transport) @@ -566,18 +582,20 @@ async def test_keep_alive(make_srv, loop, transport, ceil): b'Host: example.com\r\n' b'Content-Length: 0\r\n\r\n') - await asyncio.sleep(0, loop=loop) - waiter = srv._waiter - assert waiter + waiter = None + while waiter is None: + await asyncio.sleep(0) + waiter = srv._waiter assert srv._keepalive_handle is not None assert not transport.close.called - await asyncio.sleep(0.2, loop=loop) + await asyncio.sleep(0.2) assert transport.close.called assert waiter.cancelled -def test_srv_process_request_without_timeout(make_srv, loop, transport): +async def test_srv_process_request_without_timeout(make_srv, + transport) -> None: srv = make_srv() srv.connection_made(transport) @@ -585,24 +603,25 @@ def test_srv_process_request_without_timeout(make_srv, loop, transport): b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') - loop.run_until_complete(srv._task_handler) + await srv._task_handler assert transport.close.called -def test_keep_alive_timeout_default(srv): +def test_keep_alive_timeout_default(srv) -> None: assert 75 == srv.keepalive_timeout -def test_keep_alive_timeout_nondefault(make_srv): +def test_keep_alive_timeout_nondefault(make_srv) -> None: srv = make_srv(keepalive_timeout=10) assert 10 == srv.keepalive_timeout -async def test_supports_connect_method(srv, loop, transport, request_handler): +async def test_supports_connect_method(srv, + transport, request_handler) -> None: srv.data_received( b'CONNECT aiohttp.readthedocs.org:80 HTTP/1.0\r\n' b'Content-Length: 0\r\n\r\n') - await asyncio.sleep(0.1, loop=loop) + await asyncio.sleep(0.1) assert request_handler.called assert isinstance( @@ -610,18 +629,18 @@ async def test_supports_connect_method(srv, loop, transport, request_handler): streams.StreamReader) -async def test_content_length_0(srv, loop, request_handler): +async def test_content_length_0(srv, request_handler) -> None: srv.data_received( b'GET / HTTP/1.1\r\n' b'Host: example.org\r\n' b'Content-Length: 0\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert request_handler.called assert request_handler.call_args[0][0].content == streams.EMPTY_PAYLOAD -def test_rudimentary_transport(srv, loop): +def test_rudimentary_transport(srv) -> None: transport = mock.Mock() srv.connection_made(transport) @@ -644,10 +663,10 @@ def test_rudimentary_transport(srv, loop): assert not srv._reading_paused -async def test_close(srv, loop, transport): +async def test_close(srv, transport) -> None: transport.close.side_effect = partial(srv.connection_lost, None) srv.connection_made(transport) - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) srv.handle_request = mock.Mock() srv.handle_request.side_effect = helpers.noop @@ -663,19 +682,19 @@ async def test_close(srv, loop, transport): b'Host: example.com\r\n' b'Content-Length: 0\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0.05) assert srv._task_handler assert srv._waiter srv.close() - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert srv._task_handler is None assert srv.transport is None assert transport.close.called async def test_pipeline_multiple_messages( - srv, loop, transport, request_handler + srv, transport, request_handler ): transport.close.side_effect = partial(srv.connection_lost, None) @@ -703,14 +722,14 @@ async def test_pipeline_multiple_messages( assert len(srv._messages) == 2 assert srv._waiter is not None - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0.05) assert srv._task_handler is not None assert srv._waiter is not None assert processed == 2 async def test_pipeline_response_order( - srv, loop, buf, transport, request_handler + srv, buf, transport, request_handler ): transport.close.side_effect = partial(srv.connection_lost, None) srv._keepalive = True @@ -719,7 +738,7 @@ async def test_pipeline_response_order( async def handle1(request): nonlocal processed - await asyncio.sleep(0.01, loop=loop) + await asyncio.sleep(0.01) resp = web.StreamResponse() await resp.prepare(request) await resp.write(b'test1') @@ -732,7 +751,7 @@ async def test_pipeline_response_order( b'GET / HTTP/1.1\r\n' b'Host: example.com\r\n' b'Content-Length: 0\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) # second @@ -750,15 +769,15 @@ async def test_pipeline_response_order( b'GET / HTTP/1.1\r\n' b'Host: example.com\r\n' b'Content-Length: 0\r\n\r\n') - await asyncio.sleep(0, loop=loop) + await asyncio.sleep(0) assert srv._task_handler is not None - await asyncio.sleep(0.1, loop=loop) + await asyncio.sleep(0.1) assert processed == [1, 2] -def test_data_received_close(srv): +def test_data_received_close(srv) -> None: srv.close() srv.data_received( b'GET / HTTP/1.1\r\n' @@ -768,7 +787,7 @@ def test_data_received_close(srv): assert not srv._messages -def test_data_received_force_close(srv): +def test_data_received_force_close(srv) -> None: srv.force_close() srv.data_received( b'GET / HTTP/1.1\r\n' @@ -778,7 +797,8 @@ def test_data_received_force_close(srv): assert not srv._messages -async def test__process_keepalive(loop, srv): +async def test__process_keepalive(srv) -> None: + loop = asyncio.get_event_loop() # wait till the waiter is waiting await asyncio.sleep(0) @@ -793,7 +813,8 @@ async def test__process_keepalive(loop, srv): assert srv._force_close -async def test__process_keepalive_schedule_next(loop, srv): +async def test__process_keepalive_schedule_next(srv) -> None: + loop = asyncio.get_event_loop() # wait till the waiter is waiting await asyncio.sleep(0) @@ -810,16 +831,17 @@ async def test__process_keepalive_schedule_next(loop, srv): ) -def test__process_keepalive_force_close(loop, srv): +async def test__process_keepalive_force_close(srv) -> None: + loop = asyncio.get_event_loop() srv._force_close = True with mock.patch.object(loop, "call_at") as call_at_patched: srv._process_keepalive() assert not call_at_patched.called -def test_two_data_received_without_waking_up_start_task(srv, loop): +async def test_two_data_received_without_waking_up_start_task(srv) -> None: # make a chance to srv.start() method start waiting for srv._waiter - loop.run_until_complete(asyncio.sleep(0.01)) + await asyncio.sleep(0.01) assert srv._waiter is not None srv.data_received( @@ -835,3 +857,4 @@ def test_two_data_received_without_waking_up_start_task(srv, loop): assert len(srv._messages) == 2 assert srv._waiter.done() + await asyncio.sleep(0.01) diff --git a/tests/test_web_request.py b/tests/test_web_request.py index 27e8354..e4ac8ec 100644 --- a/tests/test_web_request.py +++ b/tests/test_web_request.py @@ -1,5 +1,6 @@ +import asyncio import socket -from collections import MutableMapping +from collections.abc import MutableMapping from unittest import mock import pytest @@ -18,7 +19,7 @@ def protocol(): return mock.Mock(_reading_paused=False) -def test_ctor(): +def test_ctor() -> None: req = make_mocked_request('GET', '/path/to?a=1&b=2') assert 'GET' == req.method @@ -53,31 +54,31 @@ def test_ctor(): assert req.task is req._task -def test_deprecated_message(): +def test_deprecated_message() -> None: req = make_mocked_request('GET', '/path/to?a=1&b=2') with pytest.warns(DeprecationWarning): assert req.message == req._message -def test_doubleslashes(): +def test_doubleslashes() -> None: # NB: //foo/bar is an absolute URL with foo netloc and /bar path req = make_mocked_request('GET', '/bar//foo/') assert '/bar//foo/' == req.path -def test_content_type_not_specified(): +def test_content_type_not_specified() -> None: req = make_mocked_request('Get', '/') assert 'application/octet-stream' == req.content_type -def test_content_type_from_spec(): +def test_content_type_from_spec() -> None: req = make_mocked_request('Get', '/', CIMultiDict([('CONTENT-TYPE', 'application/json')])) assert 'application/json' == req.content_type -def test_content_type_from_spec_with_charset(): +def test_content_type_from_spec_with_charset() -> None: req = make_mocked_request( 'Get', '/', CIMultiDict([('CONTENT-TYPE', 'text/html; charset=UTF-8')])) @@ -85,7 +86,7 @@ def test_content_type_from_spec_with_charset(): assert 'UTF-8' == req.charset -def test_calc_content_type_on_getting_charset(): +def test_calc_content_type_on_getting_charset() -> None: req = make_mocked_request( 'Get', '/', CIMultiDict([('CONTENT-TYPE', 'text/html; charset=UTF-8')])) @@ -93,30 +94,30 @@ def test_calc_content_type_on_getting_charset(): assert 'text/html' == req.content_type -def test_urlencoded_querystring(): +def test_urlencoded_querystring() -> None: req = make_mocked_request( 'GET', '/yandsearch?text=%D1%82%D0%B5%D0%BA%D1%81%D1%82') assert {'text': 'текст'} == req.query -def test_non_ascii_path(): +def test_non_ascii_path() -> None: req = make_mocked_request('GET', '/путь') assert '/путь' == req.path -def test_non_ascii_raw_path(): +def test_non_ascii_raw_path() -> None: req = make_mocked_request('GET', '/путь') assert '/путь' == req.raw_path -def test_content_length(): +def test_content_length() -> None: req = make_mocked_request('Get', '/', CIMultiDict([('CONTENT-LENGTH', '123')])) assert 123 == req.content_length -def test_range_to_slice_head(): +def test_range_to_slice_head() -> None: def bytes_gen(size): for i in range(size): yield i % 256 @@ -129,7 +130,7 @@ def test_range_to_slice_head(): assert req.content[req.http_range] == payload[:500] -def test_range_to_slice_mid(): +def test_range_to_slice_mid() -> None: def bytes_gen(size): for i in range(size): yield i % 256 @@ -142,7 +143,7 @@ def test_range_to_slice_mid(): assert req.content[req.http_range] == payload[500:1000] -def test_range_to_slice_tail_start(): +def test_range_to_slice_tail_start() -> None: def bytes_gen(size): for i in range(size): yield i % 256 @@ -155,7 +156,7 @@ def test_range_to_slice_tail_start(): assert req.content[req.http_range] == payload[-500:] -def test_range_to_slice_tail_stop(): +def test_range_to_slice_tail_stop() -> None: def bytes_gen(size): for i in range(size): yield i % 256 @@ -168,24 +169,24 @@ def test_range_to_slice_tail_stop(): assert req.content[req.http_range] == payload[-500:] -def test_non_keepalive_on_http10(): +def test_non_keepalive_on_http10() -> None: req = make_mocked_request('GET', '/', version=HttpVersion(1, 0)) assert not req.keep_alive -def test_non_keepalive_on_closing(): +def test_non_keepalive_on_closing() -> None: req = make_mocked_request('GET', '/', closing=True) assert not req.keep_alive -async def test_call_POST_on_GET_request(): +async def test_call_POST_on_GET_request() -> None: req = make_mocked_request('GET', '/') ret = await req.post() assert CIMultiDict() == ret -async def test_call_POST_on_weird_content_type(): +async def test_call_POST_on_weird_content_type() -> None: req = make_mocked_request( 'POST', '/', headers=CIMultiDict({'CONTENT-TYPE': 'something/weird'})) @@ -194,7 +195,7 @@ async def test_call_POST_on_weird_content_type(): assert CIMultiDict() == ret -async def test_call_POST_twice(): +async def test_call_POST_twice() -> None: req = make_mocked_request('GET', '/') ret1 = await req.post() @@ -202,7 +203,7 @@ async def test_call_POST_twice(): assert ret1 is ret2 -def test_no_request_cookies(): +def test_no_request_cookies() -> None: req = make_mocked_request('GET', '/') assert req.cookies == {} @@ -211,7 +212,7 @@ def test_no_request_cookies(): assert cookies is req.cookies -def test_request_cookie(): +def test_request_cookie() -> None: headers = CIMultiDict(COOKIE='cookie1=value1; cookie2=value2') req = make_mocked_request('GET', '/', headers=headers) @@ -219,7 +220,7 @@ def test_request_cookie(): 'cookie2': 'value2'} -def test_request_cookie__set_item(): +def test_request_cookie__set_item() -> None: headers = CIMultiDict(COOKIE='name=value') req = make_mocked_request('GET', '/', headers=headers) @@ -229,19 +230,19 @@ def test_request_cookie__set_item(): req.cookies['my'] = 'value' -def test_match_info(): +def test_match_info() -> None: req = make_mocked_request('GET', '/') assert req._match_info is req.match_info -def test_request_is_mutable_mapping(): +def test_request_is_mutable_mapping() -> None: req = make_mocked_request('GET', '/') assert isinstance(req, MutableMapping) req['key'] = 'value' assert 'value' == req['key'] -def test_request_delitem(): +def test_request_delitem() -> None: req = make_mocked_request('GET', '/') req['key'] = 'value' assert 'value' == req['key'] @@ -249,44 +250,44 @@ def test_request_delitem(): assert 'key' not in req -def test_request_len(): +def test_request_len() -> None: req = make_mocked_request('GET', '/') assert len(req) == 0 req['key'] = 'value' assert len(req) == 1 -def test_request_iter(): +def test_request_iter() -> None: req = make_mocked_request('GET', '/') req['key'] = 'value' req['key2'] = 'value2' assert set(req) == {'key', 'key2'} -def test___repr__(): +def test___repr__() -> None: req = make_mocked_request('GET', '/path/to') assert "<Request GET /path/to >" == repr(req) -def test___repr___non_ascii_path(): +def test___repr___non_ascii_path() -> None: req = make_mocked_request('GET', '/path/\U0001f415\U0001f308') assert "<Request GET /path/\\U0001f415\\U0001f308 >" == repr(req) -def test_http_scheme(): +def test_http_scheme() -> None: req = make_mocked_request('GET', '/', headers={'Host': 'example.com'}) assert "http" == req.scheme assert req.secure is False -def test_https_scheme_by_ssl_transport(): +def test_https_scheme_by_ssl_transport() -> None: req = make_mocked_request('GET', '/', headers={'Host': 'example.com'}, sslcontext=True) assert "https" == req.scheme assert req.secure is True -def test_single_forwarded_header(): +def test_single_forwarded_header() -> None: header = 'by=identifier;for=identifier;host=identifier;proto=identifier' req = make_mocked_request('GET', '/', headers=CIMultiDict({'Forwarded': header})) @@ -304,14 +305,14 @@ def test_single_forwarded_header(): ('"[2001:db8:cafe::17]:1234"', '[2001:db8:cafe::17]:1234'), ('"[2001:db8:cafe::17]"', '[2001:db8:cafe::17]'), ]) -def test_forwarded_node_identifier(forward_for_in, forward_for_out): +def test_forwarded_node_identifier(forward_for_in, forward_for_out) -> None: header = 'for={}'.format(forward_for_in) req = make_mocked_request('GET', '/', headers=CIMultiDict({'Forwarded': header})) assert req.forwarded == ({'for': forward_for_out},) -def test_single_forwarded_header_camelcase(): +def test_single_forwarded_header_camelcase() -> None: header = 'bY=identifier;fOr=identifier;HOst=identifier;pRoTO=identifier' req = make_mocked_request('GET', '/', headers=CIMultiDict({'Forwarded': header})) @@ -321,14 +322,14 @@ def test_single_forwarded_header_camelcase(): assert req.forwarded[0]['proto'] == 'identifier' -def test_single_forwarded_header_single_param(): +def test_single_forwarded_header_single_param() -> None: header = 'BY=identifier' req = make_mocked_request('GET', '/', headers=CIMultiDict({'Forwarded': header})) assert req.forwarded[0]['by'] == 'identifier' -def test_single_forwarded_header_multiple_param(): +def test_single_forwarded_header_multiple_param() -> None: header = 'By=identifier1,BY=identifier2, By=identifier3 , BY=identifier4' req = make_mocked_request('GET', '/', headers=CIMultiDict({'Forwarded': header})) @@ -339,15 +340,15 @@ def test_single_forwarded_header_multiple_param(): assert req.forwarded[3]['by'] == 'identifier4' -def test_single_forwarded_header_quoted_escaped(): - header = 'BY=identifier;pROTO="\lala lan\d\~ 123\!&"' +def test_single_forwarded_header_quoted_escaped() -> None: + header = r'BY=identifier;pROTO="\lala lan\d\~ 123\!&"' req = make_mocked_request('GET', '/', headers=CIMultiDict({'Forwarded': header})) assert req.forwarded[0]['by'] == 'identifier' assert req.forwarded[0]['proto'] == 'lala land~ 123!&' -def test_single_forwarded_header_custom_param(): +def test_single_forwarded_header_custom_param() -> None: header = r'BY=identifier;PROTO=https;SOME="other, \"value\""' req = make_mocked_request('GET', '/', headers=CIMultiDict({'Forwarded': header})) @@ -357,7 +358,7 @@ def test_single_forwarded_header_custom_param(): assert req.forwarded[0]['some'] == 'other, "value"' -def test_single_forwarded_header_empty_params(): +def test_single_forwarded_header_empty_params() -> None: # This is allowed by the grammar given in RFC 7239 header = ';For=identifier;;PROTO=https;;;' req = make_mocked_request('GET', '/', @@ -366,14 +367,14 @@ def test_single_forwarded_header_empty_params(): assert req.forwarded[0]['proto'] == 'https' -def test_single_forwarded_header_bad_separator(): +def test_single_forwarded_header_bad_separator() -> None: header = 'BY=identifier PROTO=https' req = make_mocked_request('GET', '/', headers=CIMultiDict({'Forwarded': header})) assert 'proto' not in req.forwarded[0] -def test_single_forwarded_header_injection1(): +def test_single_forwarded_header_injection1() -> None: # We might receive a header like this if we're sitting behind a reverse # proxy that blindly appends a forwarded-element without checking # the syntax of existing field-values. We should be able to recover @@ -386,7 +387,7 @@ def test_single_forwarded_header_injection1(): assert req.forwarded[1]['for'] == '_real' -def test_single_forwarded_header_injection2(): +def test_single_forwarded_header_injection2() -> None: header = 'very bad syntax, for=_real' req = make_mocked_request('GET', '/', headers=CIMultiDict({'Forwarded': header})) @@ -395,14 +396,14 @@ def test_single_forwarded_header_injection2(): assert req.forwarded[1]['for'] == '_real' -def test_single_forwarded_header_long_quoted_string(): +def test_single_forwarded_header_long_quoted_string() -> None: header = 'for="' + '\\\\' * 5000 + '"' req = make_mocked_request('GET', '/', headers=CIMultiDict({'Forwarded': header})) assert req.forwarded[0]['for'] == '\\' * 5000 -def test_multiple_forwarded_headers(): +def test_multiple_forwarded_headers() -> None: headers = CIMultiDict() headers.add('Forwarded', 'By=identifier1;for=identifier2, BY=identifier3') headers.add('Forwarded', 'By=identifier4;fOr=identifier5') @@ -415,7 +416,7 @@ def test_multiple_forwarded_headers(): assert req.forwarded[2]['for'] == 'identifier5' -def test_multiple_forwarded_headers_bad_syntax(): +def test_multiple_forwarded_headers_bad_syntax() -> None: headers = CIMultiDict() headers.add('Forwarded', 'for=_1;by=_2') headers.add('Forwarded', 'invalid value') @@ -429,7 +430,7 @@ def test_multiple_forwarded_headers_bad_syntax(): assert req.forwarded[3]['by'] == '_4' -def test_multiple_forwarded_headers_injection(): +def test_multiple_forwarded_headers_injection() -> None: headers = CIMultiDict() # This could be sent by an attacker, hoping to "shadow" the second header. headers.add('Forwarded', 'for=_injected;by="') @@ -442,77 +443,77 @@ def test_multiple_forwarded_headers_injection(): assert req.forwarded[1]['by'] == '_actual_proxy' -def test_host_by_host_header(): +def test_host_by_host_header() -> None: req = make_mocked_request('GET', '/', headers=CIMultiDict({'Host': 'example.com'})) assert req.host == 'example.com' -def test_raw_headers(): +def test_raw_headers() -> None: req = make_mocked_request('GET', '/', headers=CIMultiDict({'X-HEADER': 'aaa'})) assert req.raw_headers == ((b'X-HEADER', b'aaa'),) -def test_rel_url(): +def test_rel_url() -> None: req = make_mocked_request('GET', '/path') assert URL('/path') == req.rel_url -def test_url_url(): +def test_url_url() -> None: req = make_mocked_request('GET', '/path', headers={'HOST': 'example.com'}) assert URL('http://example.com/path') == req.url -def test_clone(): +def test_clone() -> None: req = make_mocked_request('GET', '/path') req2 = req.clone() assert req2.method == 'GET' assert req2.rel_url == URL('/path') -def test_clone_client_max_size(): +def test_clone_client_max_size() -> None: req = make_mocked_request('GET', '/path', client_max_size=1024) req2 = req.clone() assert req._client_max_size == req2._client_max_size assert req2._client_max_size == 1024 -def test_clone_method(): +def test_clone_method() -> None: req = make_mocked_request('GET', '/path') req2 = req.clone(method='POST') assert req2.method == 'POST' assert req2.rel_url == URL('/path') -def test_clone_rel_url(): +def test_clone_rel_url() -> None: req = make_mocked_request('GET', '/path') req2 = req.clone(rel_url=URL('/path2')) assert req2.rel_url == URL('/path2') -def test_clone_rel_url_str(): +def test_clone_rel_url_str() -> None: req = make_mocked_request('GET', '/path') req2 = req.clone(rel_url='/path2') assert req2.rel_url == URL('/path2') -def test_clone_headers(): +def test_clone_headers() -> None: req = make_mocked_request('GET', '/path', headers={'A': 'B'}) req2 = req.clone(headers=CIMultiDict({'B': 'C'})) assert req2.headers == CIMultiDict({'B': 'C'}) assert req2.raw_headers == ((b'B', b'C'),) -def test_clone_headers_dict(): +def test_clone_headers_dict() -> None: req = make_mocked_request('GET', '/path', headers={'A': 'B'}) req2 = req.clone(headers={'B': 'C'}) assert req2.headers == CIMultiDict({'B': 'C'}) assert req2.raw_headers == ((b'B', b'C'),) -async def test_cannot_clone_after_read(loop, protocol): - payload = StreamReader(protocol, loop=loop) +async def test_cannot_clone_after_read(protocol) -> None: + payload = StreamReader(protocol) payload.feed_data(b'data') payload.feed_eof() req = make_mocked_request('GET', '/path', payload=payload) @@ -521,8 +522,8 @@ async def test_cannot_clone_after_read(loop, protocol): req.clone() -async def test_make_too_big_request(loop, protocol): - payload = StreamReader(protocol, loop=loop) +async def test_make_too_big_request(protocol) -> None: + payload = StreamReader(protocol) large_file = 1024 ** 2 * b'x' too_large_file = large_file + b'x' payload.feed_data(too_large_file) @@ -534,8 +535,8 @@ async def test_make_too_big_request(loop, protocol): assert err.value.status_code == 413 -async def test_make_too_big_request_adjust_limit(loop, protocol): - payload = StreamReader(protocol, loop=loop) +async def test_make_too_big_request_adjust_limit(protocol) -> None: + payload = StreamReader(protocol) large_file = 1024 ** 2 * b'x' too_large_file = large_file + b'x' payload.feed_data(too_large_file) @@ -547,8 +548,8 @@ async def test_make_too_big_request_adjust_limit(loop, protocol): assert len(txt) == 1024**2 + 1 -async def test_multipart_formdata(loop, protocol): - payload = StreamReader(protocol, loop=loop) +async def test_multipart_formdata(protocol) -> None: + payload = StreamReader(protocol) payload.feed_data(b"""-----------------------------326931944431359\r Content-Disposition: form-data; name="a"\r \r @@ -568,8 +569,8 @@ d\r assert dict(result) == {'a': 'b', 'c': 'd'} -async def test_make_too_big_request_limit_None(loop, protocol): - payload = StreamReader(protocol, loop=loop) +async def test_make_too_big_request_limit_None(protocol) -> None: + payload = StreamReader(protocol) large_file = 1024 ** 2 * b'x' too_large_file = large_file + b'x' payload.feed_data(too_large_file) @@ -581,21 +582,21 @@ async def test_make_too_big_request_limit_None(loop, protocol): assert len(txt) == 1024**2 + 1 -def test_remote_peername_tcp(): +def test_remote_peername_tcp() -> None: transp = mock.Mock() transp.get_extra_info.return_value = ('10.10.10.10', 1234) req = make_mocked_request('GET', '/', transport=transp) assert req.remote == '10.10.10.10' -def test_remote_peername_unix(): +def test_remote_peername_unix() -> None: transp = mock.Mock() transp.get_extra_info.return_value = '/path/to/sock' req = make_mocked_request('GET', '/', transport=transp) assert req.remote == '/path/to/sock' -def test_save_state_on_clone(): +def test_save_state_on_clone() -> None: req = make_mocked_request('GET', '/') req['key'] = 'val' req2 = req.clone() @@ -604,19 +605,19 @@ def test_save_state_on_clone(): assert req2['key'] == 'val2' -def test_clone_scheme(): +def test_clone_scheme() -> None: req = make_mocked_request('GET', '/') req2 = req.clone(scheme='https') assert req2.scheme == 'https' -def test_clone_host(): +def test_clone_host() -> None: req = make_mocked_request('GET', '/') req2 = req.clone(host='example.com') assert req2.host == 'example.com' -def test_clone_remote(): +def test_clone_remote() -> None: req = make_mocked_request('GET', '/') req2 = req.clone(remote='11.11.11.11') assert req2.remote == '11.11.11.11' @@ -624,20 +625,41 @@ def test_clone_remote(): @pytest.mark.skipif(not DEBUG, reason="The check is applied in DEBUG mode only") -def test_request_custom_attr(): +def test_request_custom_attr() -> None: req = make_mocked_request('GET', '/') with pytest.warns(DeprecationWarning): req.custom = None -def test_remote_with_closed_transport(): +def test_remote_with_closed_transport() -> None: + transp = mock.Mock() + transp.get_extra_info.return_value = ('10.10.10.10', 1234) + req = make_mocked_request('GET', '/', transport=transp) + req._protocol = None + assert req.remote == '10.10.10.10' + + +def test_url_http_with_closed_transport() -> None: req = make_mocked_request('GET', '/') req._protocol = None - assert req.remote is None + assert str(req.url).startswith('http://') -def test_eq(): +def test_url_https_with_closed_transport() -> None: + req = make_mocked_request('GET', '/', sslcontext=True) + req._protocol = None + assert str(req.url).startswith('https://') + + +def test_eq() -> None: req1 = make_mocked_request('GET', '/path/to?a=1&b=2') req2 = make_mocked_request('GET', '/path/to?a=1&b=2') assert req1 != req2 assert req1 == req1 + + +async def test_loop_prop() -> None: + loop = asyncio.get_event_loop() + req = make_mocked_request('GET', '/path', loop=loop) + with pytest.warns(DeprecationWarning): + assert req.loop is loop diff --git a/tests/test_web_request_handler.py b/tests/test_web_request_handler.py index 7b60ada..403aeff 100644 --- a/tests/test_web_request_handler.py +++ b/tests/test_web_request_handler.py @@ -8,8 +8,8 @@ async def serve(request): return web.Response() -def test_repr(loop): - manager = web.Server(serve, loop=loop) +async def test_repr() -> None: + manager = web.Server(serve) handler = manager() assert '<RequestHandler disconnected>' == repr(handler) @@ -18,8 +18,8 @@ def test_repr(loop): assert '<RequestHandler connected>' == repr(handler) -def test_connections(loop): - manager = web.Server(serve, loop=loop) +async def test_connections() -> None: + manager = web.Server(serve) assert manager.connections == [] handler = object() @@ -31,8 +31,8 @@ def test_connections(loop): assert manager.connections == [] -async def test_shutdown_no_timeout(loop): - manager = web.Server(serve, loop=loop) +async def test_shutdown_no_timeout() -> None: + manager = web.Server(serve) handler = mock.Mock() handler.shutdown = make_mocked_coro(mock.Mock()) @@ -46,8 +46,8 @@ async def test_shutdown_no_timeout(loop): handler.shutdown.assert_called_with(None) -async def test_shutdown_timeout(loop): - manager = web.Server(serve, loop=loop) +async def test_shutdown_timeout() -> None: + manager = web.Server(serve) handler = mock.Mock() handler.shutdown = make_mocked_coro(mock.Mock()) diff --git a/tests/test_web_response.py b/tests/test_web_response.py index da414e8..42ccfe7 100644 --- a/tests/test_web_response.py +++ b/tests/test_web_response.py @@ -1,11 +1,13 @@ import collections import datetime +import gzip import json import re +from concurrent.futures import ThreadPoolExecutor from unittest import mock import pytest -from multidict import CIMultiDict +from multidict import CIMultiDict, CIMultiDictProxy from aiohttp import HttpVersion, HttpVersion10, HttpVersion11, hdrs, signals from aiohttp.payload import BytesPayload @@ -65,7 +67,7 @@ def writer(buf): return writer -def test_stream_response_ctor(): +def test_stream_response_ctor() -> None: resp = StreamResponse() assert 200 == resp.status assert resp.keep_alive is None @@ -77,12 +79,12 @@ def test_stream_response_ctor(): assert resp.task is req.task -def test_stream_response_hashable(): +def test_stream_response_hashable() -> None: # should not raise exception hash(StreamResponse()) -def test_stream_response_eq(): +def test_stream_response_eq() -> None: resp1 = StreamResponse() resp2 = StreamResponse() @@ -90,47 +92,47 @@ def test_stream_response_eq(): assert not resp1 == resp2 -def test_stream_response_is_mutable_mapping(): +def test_stream_response_is_mutable_mapping() -> None: resp = StreamResponse() assert isinstance(resp, collections.MutableMapping) resp['key'] = 'value' assert 'value' == resp['key'] -def test_stream_response_delitem(): +def test_stream_response_delitem() -> None: resp = StreamResponse() resp['key'] = 'value' del resp['key'] assert 'key' not in resp -def test_stream_response_len(): +def test_stream_response_len() -> None: resp = StreamResponse() assert len(resp) == 0 resp['key'] = 'value' assert len(resp) == 1 -def test_request_iter(): +def test_request_iter() -> None: resp = StreamResponse() resp['key'] = 'value' resp['key2'] = 'value2' assert set(resp) == {'key', 'key2'} -def test_content_length(): +def test_content_length() -> None: resp = StreamResponse() assert resp.content_length is None -def test_content_length_setter(): +def test_content_length_setter() -> None: resp = StreamResponse() resp.content_length = 234 assert 234 == resp.content_length -def test_content_length_setter_with_enable_chunked_encoding(): +def test_content_length_setter_with_enable_chunked_encoding() -> None: resp = StreamResponse() resp.enable_chunked_encoding() @@ -138,7 +140,7 @@ def test_content_length_setter_with_enable_chunked_encoding(): resp.content_length = 234 -def test_drop_content_length_header_on_setting_len_to_None(): +def test_drop_content_length_header_on_setting_len_to_None() -> None: resp = StreamResponse() resp.content_length = 1 @@ -147,7 +149,7 @@ def test_drop_content_length_header_on_setting_len_to_None(): assert 'Content-Length' not in resp.headers -def test_set_content_length_to_None_on_non_set(): +def test_set_content_length_to_None_on_non_set() -> None: resp = StreamResponse() resp.content_length = None @@ -156,14 +158,14 @@ def test_set_content_length_to_None_on_non_set(): assert 'Content-Length' not in resp.headers -def test_setting_content_type(): +def test_setting_content_type() -> None: resp = StreamResponse() resp.content_type = 'text/html' assert 'text/html' == resp.headers['content-type'] -def test_setting_charset(): +def test_setting_charset() -> None: resp = StreamResponse() resp.content_type = 'text/html' @@ -171,13 +173,13 @@ def test_setting_charset(): assert 'text/html; charset=koi8-r' == resp.headers['content-type'] -def test_default_charset(): +def test_default_charset() -> None: resp = StreamResponse() assert resp.charset is None -def test_reset_charset(): +def test_reset_charset() -> None: resp = StreamResponse() resp.content_type = 'text/html' @@ -185,7 +187,7 @@ def test_reset_charset(): assert resp.charset is None -def test_reset_charset_after_setting(): +def test_reset_charset_after_setting() -> None: resp = StreamResponse() resp.content_type = 'text/html' @@ -194,19 +196,19 @@ def test_reset_charset_after_setting(): assert resp.charset is None -def test_charset_without_content_type(): +def test_charset_without_content_type() -> None: resp = StreamResponse() with pytest.raises(RuntimeError): resp.charset = 'koi8-r' -def test_last_modified_initial(): +def test_last_modified_initial() -> None: resp = StreamResponse() assert resp.last_modified is None -def test_last_modified_string(): +def test_last_modified_string() -> None: resp = StreamResponse() dt = datetime.datetime(1990, 1, 2, 3, 4, 5, 0, datetime.timezone.utc) @@ -214,7 +216,7 @@ def test_last_modified_string(): assert resp.last_modified == dt -def test_last_modified_timestamp(): +def test_last_modified_timestamp() -> None: resp = StreamResponse() dt = datetime.datetime(1970, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) @@ -226,7 +228,7 @@ def test_last_modified_timestamp(): assert resp.last_modified == dt -def test_last_modified_datetime(): +def test_last_modified_datetime() -> None: resp = StreamResponse() dt = datetime.datetime(2001, 2, 3, 4, 5, 6, 0, datetime.timezone.utc) @@ -234,7 +236,7 @@ def test_last_modified_datetime(): assert resp.last_modified == dt -def test_last_modified_reset(): +def test_last_modified_reset() -> None: resp = StreamResponse() resp.last_modified = 0 @@ -242,7 +244,7 @@ def test_last_modified_reset(): assert resp.last_modified is None -async def test_start(): +async def test_start() -> None: req = make_request('GET', '/') resp = StreamResponse() assert resp.keep_alive is None @@ -261,7 +263,7 @@ async def test_start(): assert msg is msg3 -async def test_chunked_encoding(): +async def test_chunked_encoding() -> None: req = make_request('GET', '/') resp = StreamResponse() assert not resp.chunked @@ -273,7 +275,7 @@ async def test_chunked_encoding(): assert msg.chunked -def test_enable_chunked_encoding_with_content_length(): +def test_enable_chunked_encoding_with_content_length() -> None: resp = StreamResponse() resp.content_length = 234 @@ -281,7 +283,7 @@ def test_enable_chunked_encoding_with_content_length(): resp.enable_chunked_encoding() -async def test_chunk_size(): +async def test_chunk_size() -> None: req = make_request('GET', '/') resp = StreamResponse() assert not resp.chunked @@ -296,7 +298,7 @@ async def test_chunk_size(): assert msg.filter is not None -async def test_chunked_encoding_forbidden_for_http_10(): +async def test_chunked_encoding_forbidden_for_http_10() -> None: req = make_request('GET', '/', version=HttpVersion10) resp = StreamResponse() resp.enable_chunked_encoding() @@ -307,7 +309,7 @@ async def test_chunked_encoding_forbidden_for_http_10(): str(ctx.value)) -async def test_compression_no_accept(): +async def test_compression_no_accept() -> None: req = make_request('GET', '/') resp = StreamResponse() assert not resp.chunked @@ -320,13 +322,14 @@ async def test_compression_no_accept(): assert not msg.enable_compression.called -async def test_force_compression_no_accept_backwards_compat(): +async def test_force_compression_no_accept_backwards_compat() -> None: req = make_request('GET', '/') resp = StreamResponse() assert not resp.chunked assert not resp.compression - resp.enable_compression(force=True) + with pytest.warns(DeprecationWarning): + resp.enable_compression(force=True) assert resp.compression msg = await resp.prepare(req) @@ -334,19 +337,20 @@ async def test_force_compression_no_accept_backwards_compat(): assert msg.filter is not None -async def test_force_compression_false_backwards_compat(): +async def test_force_compression_false_backwards_compat() -> None: req = make_request('GET', '/') resp = StreamResponse() assert not resp.compression - resp.enable_compression(force=False) + with pytest.warns(DeprecationWarning): + resp.enable_compression(force=False) assert resp.compression msg = await resp.prepare(req) assert not msg.enable_compression.called -async def test_compression_default_coding(): +async def test_compression_default_coding() -> None: req = make_request( 'GET', '/', headers=CIMultiDict({hdrs.ACCEPT_ENCODING: 'gzip, deflate'})) @@ -364,7 +368,7 @@ async def test_compression_default_coding(): assert msg.filter is not None -async def test_force_compression_deflate(): +async def test_force_compression_deflate() -> None: req = make_request( 'GET', '/', headers=CIMultiDict({hdrs.ACCEPT_ENCODING: 'gzip, deflate'})) @@ -378,7 +382,7 @@ async def test_force_compression_deflate(): assert 'deflate' == resp.headers.get(hdrs.CONTENT_ENCODING) -async def test_force_compression_no_accept_deflate(): +async def test_force_compression_no_accept_deflate() -> None: req = make_request('GET', '/') resp = StreamResponse() @@ -390,7 +394,7 @@ async def test_force_compression_no_accept_deflate(): assert 'deflate' == resp.headers.get(hdrs.CONTENT_ENCODING) -async def test_force_compression_gzip(): +async def test_force_compression_gzip() -> None: req = make_request( 'GET', '/', headers=CIMultiDict({hdrs.ACCEPT_ENCODING: 'gzip, deflate'})) @@ -404,7 +408,7 @@ async def test_force_compression_gzip(): assert 'gzip' == resp.headers.get(hdrs.CONTENT_ENCODING) -async def test_force_compression_no_accept_gzip(): +async def test_force_compression_no_accept_gzip() -> None: req = make_request('GET', '/') resp = StreamResponse() @@ -416,7 +420,33 @@ async def test_force_compression_no_accept_gzip(): assert 'gzip' == resp.headers.get(hdrs.CONTENT_ENCODING) -async def test_change_content_length_if_compression_enabled(): +async def test_change_content_threaded_compression_enabled() -> None: + req = make_request('GET', '/') + body_thread_size = 1024 + body = b'answer' * body_thread_size + resp = Response(body=body, + zlib_executor_size=body_thread_size) + resp.enable_compression(ContentCoding.gzip) + + await resp.prepare(req) + assert gzip.decompress(resp._compressed_body) == body + + +async def test_change_content_threaded_compression_enabled_explicit() -> None: + req = make_request('GET', '/') + body_thread_size = 1024 + body = b'answer' * body_thread_size + with ThreadPoolExecutor(1) as executor: + resp = Response(body=body, + zlib_executor_size=body_thread_size, + zlib_executor=executor) + resp.enable_compression(ContentCoding.gzip) + + await resp.prepare(req) + assert gzip.decompress(resp._compressed_body) == body + + +async def test_change_content_length_if_compression_enabled() -> None: req = make_request('GET', '/') resp = Response(body=b'answer') resp.enable_compression(ContentCoding.gzip) @@ -426,7 +456,7 @@ async def test_change_content_length_if_compression_enabled(): resp.content_length != len(b'answer') -async def test_set_content_length_if_compression_enabled(): +async def test_set_content_length_if_compression_enabled() -> None: writer = mock.Mock() async def write_headers(status_line, headers): @@ -445,7 +475,7 @@ async def test_set_content_length_if_compression_enabled(): assert resp.content_length == 26 -async def test_remove_content_length_if_compression_enabled_http11(): +async def test_remove_content_length_if_compression_enabled_http11() -> None: writer = mock.Mock() async def write_headers(status_line, headers): @@ -461,7 +491,7 @@ async def test_remove_content_length_if_compression_enabled_http11(): assert resp.content_length is None -async def test_remove_content_length_if_compression_enabled_http10(): +async def test_remove_content_length_if_compression_enabled_http10() -> None: writer = mock.Mock() async def write_headers(status_line, headers): @@ -478,7 +508,7 @@ async def test_remove_content_length_if_compression_enabled_http10(): assert resp.content_length is None -async def test_force_compression_identity(): +async def test_force_compression_identity() -> None: writer = mock.Mock() async def write_headers(status_line, headers): @@ -495,7 +525,7 @@ async def test_force_compression_identity(): assert resp.content_length == 123 -async def test_force_compression_identity_response(): +async def test_force_compression_identity_response() -> None: writer = mock.Mock() async def write_headers(status_line, headers): @@ -511,7 +541,7 @@ async def test_force_compression_identity_response(): assert resp.content_length == 6 -async def test_rm_content_length_if_compression_enabled_on_payload_http11(): +async def test_rm_content_length_if_compression_http11() -> None: writer = mock.Mock() async def write_headers(status_line, headers): @@ -529,7 +559,7 @@ async def test_rm_content_length_if_compression_enabled_on_payload_http11(): assert resp.content_length is None -async def test_rm_content_length_if_compression_enabled_on_payload_http10(): +async def test_rm_content_length_if_compression_http10() -> None: writer = mock.Mock() async def write_headers(status_line, headers): @@ -545,7 +575,7 @@ async def test_rm_content_length_if_compression_enabled_on_payload_http10(): assert resp.content_length is None -async def test_content_length_on_chunked(): +async def test_content_length_on_chunked() -> None: req = make_request('GET', '/') resp = Response(body=b'answer') assert resp.content_length == 6 @@ -554,7 +584,7 @@ async def test_content_length_on_chunked(): await resp.prepare(req) -async def test_write_non_byteish(): +async def test_write_non_byteish() -> None: resp = StreamResponse() await resp.prepare(make_request('GET', '/')) @@ -562,14 +592,14 @@ async def test_write_non_byteish(): await resp.write(123) -async def test_write_before_start(): +async def test_write_before_start() -> None: resp = StreamResponse() with pytest.raises(RuntimeError): await resp.write(b'data') -async def test_cannot_write_after_eof(): +async def test_cannot_write_after_eof() -> None: resp = StreamResponse() req = make_request('GET', '/') await resp.prepare(req) @@ -583,7 +613,7 @@ async def test_cannot_write_after_eof(): assert not req.writer.write.called -async def test___repr___after_eof(): +async def test___repr___after_eof() -> None: resp = StreamResponse() await resp.prepare(make_request('GET', '/')) @@ -596,14 +626,14 @@ async def test___repr___after_eof(): assert resp_repr == '<StreamResponse OK eof>' -async def test_cannot_write_eof_before_headers(): +async def test_cannot_write_eof_before_headers() -> None: resp = StreamResponse() with pytest.raises(AssertionError): await resp.write_eof() -async def test_cannot_write_eof_twice(): +async def test_cannot_write_eof_twice() -> None: resp = StreamResponse() writer = mock.Mock() resp_impl = await resp.prepare(make_request('GET', '/')) @@ -620,7 +650,7 @@ async def test_cannot_write_eof_twice(): assert not writer.write.called -def test_force_close(): +def test_force_close() -> None: resp = StreamResponse() assert resp.keep_alive is None @@ -628,14 +658,14 @@ def test_force_close(): assert resp.keep_alive is False -async def test_response_output_length(): +async def test_response_output_length() -> None: resp = StreamResponse() await resp.prepare(make_request('GET', '/')) with pytest.warns(DeprecationWarning): assert resp.output_length -def test_response_cookies(): +def test_response_cookies() -> None: resp = StreamResponse() assert resp.cookies == {} @@ -661,7 +691,7 @@ def test_response_cookies(): assert str(resp.cookies) == expected -def test_response_cookie_path(): +def test_response_cookie_path() -> None: resp = StreamResponse() assert resp.cookies == {} @@ -684,7 +714,7 @@ def test_response_cookie_path(): 'version=2.0') -def test_response_cookie__issue_del_cookie(): +def test_response_cookie__issue_del_cookie() -> None: resp = StreamResponse() assert resp.cookies == {} @@ -696,7 +726,7 @@ def test_response_cookie__issue_del_cookie(): assert re.match(expected, str(resp.cookies)) -def test_cookie_set_after_del(): +def test_cookie_set_after_del() -> None: resp = StreamResponse() resp.del_cookie('name') @@ -706,7 +736,7 @@ def test_cookie_set_after_del(): assert str(resp.cookies) == expected -def test_set_status_with_reason(): +def test_set_status_with_reason() -> None: resp = StreamResponse() resp.set_status(200, "Everithing is fine!") @@ -714,7 +744,7 @@ def test_set_status_with_reason(): assert "Everithing is fine!" == resp.reason -async def test_start_force_close(): +async def test_start_force_close() -> None: req = make_request('GET', '/') resp = StreamResponse() resp.force_close() @@ -724,26 +754,26 @@ async def test_start_force_close(): assert not resp.keep_alive -async def test___repr__(): +async def test___repr__() -> None: req = make_request('GET', '/path/to') resp = StreamResponse(reason=301) await resp.prepare(req) assert "<StreamResponse 301 GET /path/to >" == repr(resp) -def test___repr___not_prepared(): +def test___repr___not_prepared() -> None: resp = StreamResponse(reason=301) assert "<StreamResponse 301 not prepared>" == repr(resp) -async def test_keep_alive_http10_default(): +async def test_keep_alive_http10_default() -> None: req = make_request('GET', '/', version=HttpVersion10) resp = StreamResponse() await resp.prepare(req) assert not resp.keep_alive -async def test_keep_alive_http10_switched_on(): +async def test_keep_alive_http10_switched_on() -> None: headers = CIMultiDict(Connection='keep-alive') req = make_request('GET', '/', version=HttpVersion10, headers=headers) req._message = req._message._replace(should_close=False) @@ -752,7 +782,7 @@ async def test_keep_alive_http10_switched_on(): assert resp.keep_alive -async def test_keep_alive_http09(): +async def test_keep_alive_http09() -> None: headers = CIMultiDict(Connection='keep-alive') req = make_request('GET', '/', version=HttpVersion(0, 9), headers=headers) resp = StreamResponse() @@ -760,7 +790,7 @@ async def test_keep_alive_http09(): assert not resp.keep_alive -async def test_prepare_twice(): +async def test_prepare_twice() -> None: req = make_request('GET', '/') resp = StreamResponse() @@ -769,7 +799,7 @@ async def test_prepare_twice(): assert impl1 is impl2 -async def test_prepare_calls_signal(): +async def test_prepare_calls_signal() -> None: app = mock.Mock() sig = make_mocked_coro() on_response_prepare = signals.Signal(app) @@ -786,7 +816,7 @@ async def test_prepare_calls_signal(): # Response class -def test_response_ctor(): +def test_response_ctor() -> None: resp = Response() assert 200 == resp.status @@ -796,7 +826,7 @@ def test_response_ctor(): assert 'CONTENT-LENGTH' not in resp.headers -async def test_ctor_with_headers_and_status(): +async def test_ctor_with_headers_and_status() -> None: resp = Response(body=b'body', status=201, headers={'Age': '12', 'DATE': 'date'}) @@ -810,7 +840,7 @@ async def test_ctor_with_headers_and_status(): assert resp.headers['CONTENT-LENGTH'] == '4' -def test_ctor_content_type(): +def test_ctor_content_type() -> None: resp = Response(content_type='application/json') assert 200 == resp.status @@ -820,12 +850,12 @@ def test_ctor_content_type(): resp.headers) -def test_ctor_text_body_combined(): +def test_ctor_text_body_combined() -> None: with pytest.raises(ValueError): Response(body=b'123', text='test text') -async def test_ctor_text(): +async def test_ctor_text() -> None: resp = Response(text='test text') assert 200 == resp.status @@ -843,31 +873,31 @@ async def test_ctor_text(): assert resp.headers['CONTENT-LENGTH'] == '9' -def test_ctor_charset(): +def test_ctor_charset() -> None: resp = Response(text='текст', charset='koi8-r') assert 'текст'.encode('koi8-r') == resp.body assert 'koi8-r' == resp.charset -def test_ctor_charset_default_utf8(): +def test_ctor_charset_default_utf8() -> None: resp = Response(text='test test', charset=None) assert 'utf-8' == resp.charset -def test_ctor_charset_in_content_type(): +def test_ctor_charset_in_content_type() -> None: with pytest.raises(ValueError): Response(text='test test', content_type='text/plain; charset=utf-8') -def test_ctor_charset_without_text(): +def test_ctor_charset_without_text() -> None: resp = Response(content_type='text/plain', charset='koi8-r') assert 'koi8-r' == resp.charset -def test_ctor_content_type_with_extra(): +def test_ctor_content_type_with_extra() -> None: resp = Response(text='test test', content_type='text/plain; version=0.0.4') assert resp.content_type == 'text/plain' @@ -875,31 +905,31 @@ def test_ctor_content_type_with_extra(): 'text/plain; version=0.0.4; charset=utf-8' -def test_ctor_both_content_type_param_and_header_with_text(): +def test_ctor_both_content_type_param_and_header_with_text() -> None: with pytest.raises(ValueError): Response(headers={'Content-Type': 'application/json'}, content_type='text/html', text='text') -def test_ctor_both_charset_param_and_header_with_text(): +def test_ctor_both_charset_param_and_header_with_text() -> None: with pytest.raises(ValueError): Response(headers={'Content-Type': 'application/json'}, charset='koi8-r', text='text') -def test_ctor_both_content_type_param_and_header(): +def test_ctor_both_content_type_param_and_header() -> None: with pytest.raises(ValueError): Response(headers={'Content-Type': 'application/json'}, content_type='text/html') -def test_ctor_both_charset_param_and_header(): +def test_ctor_both_charset_param_and_header() -> None: with pytest.raises(ValueError): Response(headers={'Content-Type': 'application/json'}, charset='koi8-r') -async def test_assign_nonbyteish_body(): +async def test_assign_nonbyteish_body() -> None: resp = Response(body=b'data') with pytest.raises(ValueError): @@ -914,7 +944,7 @@ async def test_assign_nonbyteish_body(): assert 4 == resp.content_length -def test_assign_nonstr_text(): +def test_assign_nonstr_text() -> None: resp = Response(text='test') with pytest.raises(AssertionError): @@ -923,13 +953,13 @@ def test_assign_nonstr_text(): assert 4 == resp.content_length -def test_response_set_content_length(): +def test_response_set_content_length() -> None: resp = Response() with pytest.raises(RuntimeError): resp.content_length = 1 -async def test_send_headers_for_empty_body(buf, writer): +async def test_send_headers_for_empty_body(buf, writer) -> None: req = make_request('GET', '/', writer=writer) resp = Response() @@ -943,7 +973,7 @@ async def test_send_headers_for_empty_body(buf, writer): 'Server: .+\r\n\r\n', txt) -async def test_render_with_body(buf, writer): +async def test_render_with_body(buf, writer) -> None: req = make_request('GET', '/', writer=writer) resp = Response(body=b'data') @@ -959,7 +989,7 @@ async def test_render_with_body(buf, writer): 'data', txt) -async def test_send_set_cookie_header(buf, writer): +async def test_send_set_cookie_header(buf, writer) -> None: resp = Response() resp.cookies['name'] = 'value' req = make_request('GET', '/', writer=writer) @@ -976,7 +1006,7 @@ async def test_send_set_cookie_header(buf, writer): 'Server: .+\r\n\r\n', txt) -async def test_consecutive_write_eof(): +async def test_consecutive_write_eof() -> None: writer = mock.Mock() writer.write_eof = make_mocked_coro() writer.write_headers = make_mocked_coro() @@ -990,7 +1020,7 @@ async def test_consecutive_write_eof(): writer.write_eof.assert_called_once_with(data) -def test_set_text_with_content_type(): +def test_set_text_with_content_type() -> None: resp = Response() resp.content_type = "text/html" resp.text = "text" @@ -1000,7 +1030,7 @@ def test_set_text_with_content_type(): assert "text/html" == resp.content_type -def test_set_text_with_charset(): +def test_set_text_with_charset() -> None: resp = Response() resp.content_type = 'text/plain' resp.charset = "KOI8-R" @@ -1011,62 +1041,62 @@ def test_set_text_with_charset(): assert "koi8-r" == resp.charset -def test_default_content_type_in_stream_response(): +def test_default_content_type_in_stream_response() -> None: resp = StreamResponse() assert resp.content_type == 'application/octet-stream' -def test_default_content_type_in_response(): +def test_default_content_type_in_response() -> None: resp = Response() assert resp.content_type == 'application/octet-stream' -def test_content_type_with_set_text(): +def test_content_type_with_set_text() -> None: resp = Response(text='text') assert resp.content_type == 'text/plain' -def test_content_type_with_set_body(): +def test_content_type_with_set_body() -> None: resp = Response(body=b'body') assert resp.content_type == 'application/octet-stream' -def test_started_when_not_started(): +def test_started_when_not_started() -> None: resp = StreamResponse() assert not resp.prepared -async def test_started_when_started(): +async def test_started_when_started() -> None: resp = StreamResponse() await resp.prepare(make_request('GET', '/')) assert resp.prepared -async def test_drain_before_start(): +async def test_drain_before_start() -> None: resp = StreamResponse() with pytest.raises(AssertionError): await resp.drain() -async def test_changing_status_after_prepare_raises(): +async def test_changing_status_after_prepare_raises() -> None: resp = StreamResponse() await resp.prepare(make_request('GET', '/')) with pytest.raises(AssertionError): resp.set_status(400) -def test_nonstr_text_in_ctor(): +def test_nonstr_text_in_ctor() -> None: with pytest.raises(TypeError): Response(text=b'data') -def test_text_in_ctor_with_content_type(): +def test_text_in_ctor_with_content_type() -> None: resp = Response(text='data', content_type='text/html') assert 'data' == resp.text assert 'text/html' == resp.content_type -def test_text_in_ctor_with_content_type_header(): +def test_text_in_ctor_with_content_type_header() -> None: resp = Response(text='текст', headers={'Content-Type': 'text/html; charset=koi8-r'}) assert 'текст'.encode('koi8-r') == resp.body @@ -1074,7 +1104,7 @@ def test_text_in_ctor_with_content_type_header(): assert 'koi8-r' == resp.charset -def test_text_in_ctor_with_content_type_header_multidict(): +def test_text_in_ctor_with_content_type_header_multidict() -> None: headers = CIMultiDict({'Content-Type': 'text/html; charset=koi8-r'}) resp = Response(text='текст', headers=headers) @@ -1083,7 +1113,7 @@ def test_text_in_ctor_with_content_type_header_multidict(): assert 'koi8-r' == resp.charset -def test_body_in_ctor_with_content_type_header_multidict(): +def test_body_in_ctor_with_content_type_header_multidict() -> None: headers = CIMultiDict({'Content-Type': 'text/html; charset=koi8-r'}) resp = Response(body='текст'.encode('koi8-r'), headers=headers) @@ -1092,28 +1122,35 @@ def test_body_in_ctor_with_content_type_header_multidict(): assert 'koi8-r' == resp.charset -def test_text_with_empty_payload(): +def test_text_with_empty_payload() -> None: resp = Response(status=200) assert resp.body is None assert resp.text is None -def test_response_with_content_length_header_without_body(): +def test_response_with_content_length_header_without_body() -> None: resp = Response(headers={'Content-Length': 123}) assert resp.content_length == 123 +def test_response_with_immutable_headers() -> None: + resp = Response(text='text', + headers=CIMultiDictProxy(CIMultiDict({'Header': 'Value'}))) + assert resp.headers == {'Header': 'Value', + 'Content-Type': 'text/plain; charset=utf-8'} + + class TestJSONResponse: - def test_content_type_is_application_json_by_default(self): + def test_content_type_is_application_json_by_default(self) -> None: resp = json_response('') assert 'application/json' == resp.content_type - def test_passing_text_only(self): + def test_passing_text_only(self) -> None: resp = json_response(text=json.dumps('jaysawn')) assert resp.text == json.dumps('jaysawn') - def test_data_and_text_raises_value_error(self): + def test_data_and_text_raises_value_error(self) -> None: with pytest.raises(ValueError) as excinfo: json_response(data='foo', text='bar') expected_message = ( @@ -1121,7 +1158,7 @@ class TestJSONResponse: ) assert expected_message == excinfo.value.args[0] - def test_data_and_body_raises_value_error(self): + def test_data_and_body_raises_value_error(self) -> None: with pytest.raises(ValueError) as excinfo: json_response(data='foo', body=b'bar') expected_message = ( @@ -1129,11 +1166,11 @@ class TestJSONResponse: ) assert expected_message == excinfo.value.args[0] - def test_text_is_json_encoded(self): + def test_text_is_json_encoded(self) -> None: resp = json_response({'foo': 42}) assert json.dumps({'foo': 42}) == resp.text - def test_content_type_is_overrideable(self): + def test_content_type_is_overrideable(self) -> None: resp = json_response({'foo': 42}, content_type='application/vnd.json+api') assert 'application/vnd.json+api' == resp.content_type diff --git a/tests/test_web_runner.py b/tests/test_web_runner.py index 60ec189..3b76b7a 100644 --- a/tests/test_web_runner.py +++ b/tests/test_web_runner.py @@ -1,11 +1,11 @@ import asyncio import platform import signal -from unittest import mock import pytest from aiohttp import web +from aiohttp.test_utils import get_unused_port_socket @pytest.fixture @@ -27,7 +27,7 @@ def make_runner(loop, app): loop.run_until_complete(runner.cleanup()) -async def test_site_for_nonfrozen_app(make_runner): +async def test_site_for_nonfrozen_app(make_runner) -> None: runner = make_runner() with pytest.raises(RuntimeError): web.TCPSite(runner) @@ -36,7 +36,7 @@ async def test_site_for_nonfrozen_app(make_runner): @pytest.mark.skipif(platform.system() == "Windows", reason="the test is not valid for Windows") -async def test_runner_setup_handle_signals(make_runner): +async def test_runner_setup_handle_signals(make_runner) -> None: runner = make_runner(handle_signals=True) await runner.setup() assert signal.getsignal(signal.SIGTERM) is not signal.SIG_DFL @@ -46,7 +46,7 @@ async def test_runner_setup_handle_signals(make_runner): @pytest.mark.skipif(platform.system() == "Windows", reason="the test is not valid for Windows") -async def test_runner_setup_without_signal_handling(make_runner): +async def test_runner_setup_without_signal_handling(make_runner) -> None: runner = make_runner(handle_signals=False) await runner.setup() assert signal.getsignal(signal.SIGTERM) is signal.SIG_DFL @@ -54,10 +54,11 @@ async def test_runner_setup_without_signal_handling(make_runner): assert signal.getsignal(signal.SIGTERM) is signal.SIG_DFL -async def test_site_double_added(make_runner): +async def test_site_double_added(make_runner) -> None: + _sock = get_unused_port_socket('127.0.0.1') runner = make_runner() await runner.setup() - site = web.TCPSite(runner) + site = web.SockSite(runner, _sock) await site.start() with pytest.raises(RuntimeError): await site.start() @@ -65,7 +66,7 @@ async def test_site_double_added(make_runner): assert len(runner.sites) == 1 -async def test_site_stop_not_started(make_runner): +async def test_site_stop_not_started(make_runner) -> None: runner = make_runner() await runner.setup() site = web.TCPSite(runner) @@ -75,13 +76,13 @@ async def test_site_stop_not_started(make_runner): assert len(runner.sites) == 0 -async def test_custom_log_format(make_runner): +async def test_custom_log_format(make_runner) -> None: runner = make_runner(access_log_format='abc') await runner.setup() assert runner.server._kwargs['access_log_format'] == 'abc' -async def test_unreg_site(make_runner): +async def test_unreg_site(make_runner) -> None: runner = make_runner() await runner.setup() site = web.TCPSite(runner) @@ -89,25 +90,27 @@ async def test_unreg_site(make_runner): runner._unreg_site(site) -async def test_app_property(make_runner, app): +async def test_app_property(make_runner, app) -> None: runner = make_runner() assert runner.app is app -def test_non_app(): +def test_non_app() -> None: with pytest.raises(TypeError): web.AppRunner(object()) @pytest.mark.skipif(platform.system() == "Windows", reason="Unix socket support is required") -async def test_addresses(make_runner, shorttmpdir): +async def test_addresses(make_runner, shorttmpdir) -> None: + _sock = get_unused_port_socket('127.0.0.1') runner = make_runner() await runner.setup() - tcp = web.TCPSite(runner) + tcp = web.SockSite(runner, _sock) await tcp.start() path = str(shorttmpdir / 'tmp.sock') unix = web.UnixSite(runner, path) await unix.start() - addrs = runner.addresses - assert addrs == [('0.0.0.0', mock.ANY), path] + actual_addrs = runner.addresses + expected_host, expected_post = _sock.getsockname()[:2] + assert actual_addrs == [(expected_host, expected_post), path] diff --git a/tests/test_web_sendfile.py b/tests/test_web_sendfile.py index c8868c0..f0849f1 100644 --- a/tests/test_web_sendfile.py +++ b/tests/test_web_sendfile.py @@ -2,76 +2,10 @@ from unittest import mock from aiohttp import hdrs from aiohttp.test_utils import make_mocked_coro, make_mocked_request -from aiohttp.web_fileresponse import FileResponse, SendfileStreamWriter - - -def test_static_handle_eof(loop): - fake_loop = mock.Mock() - with mock.patch('aiohttp.web_fileresponse.os') as m_os: - out_fd = 30 - in_fd = 31 - fut = loop.create_future() - m_os.sendfile.return_value = 0 - writer = SendfileStreamWriter(mock.Mock(), mock.Mock(), fake_loop) - writer._sendfile_cb(fut, out_fd, in_fd, 0, 100, fake_loop, False) - m_os.sendfile.assert_called_with(out_fd, in_fd, 0, 100) - assert fut.done() - assert fut.result() is None - assert not fake_loop.add_writer.called - assert not fake_loop.remove_writer.called - - -def test_static_handle_again(loop): - fake_loop = mock.Mock() - with mock.patch('aiohttp.web_fileresponse.os') as m_os: - out_fd = 30 - in_fd = 31 - fut = loop.create_future() - m_os.sendfile.side_effect = BlockingIOError() - writer = SendfileStreamWriter(mock.Mock(), mock.Mock(), fake_loop) - writer._sendfile_cb(fut, out_fd, in_fd, 0, 100, fake_loop, False) - m_os.sendfile.assert_called_with(out_fd, in_fd, 0, 100) - assert not fut.done() - fake_loop.add_writer.assert_called_with(out_fd, - writer._sendfile_cb, - fut, out_fd, in_fd, 0, 100, - fake_loop, True) - assert not fake_loop.remove_writer.called - - -def test_static_handle_exception(loop): - fake_loop = mock.Mock() - with mock.patch('aiohttp.web_fileresponse.os') as m_os: - out_fd = 30 - in_fd = 31 - fut = loop.create_future() - exc = OSError() - m_os.sendfile.side_effect = exc - writer = SendfileStreamWriter(mock.Mock(), mock.Mock(), fake_loop) - writer._sendfile_cb(fut, out_fd, in_fd, 0, 100, fake_loop, False) - m_os.sendfile.assert_called_with(out_fd, in_fd, 0, 100) - assert fut.done() - assert exc is fut.exception() - assert not fake_loop.add_writer.called - assert not fake_loop.remove_writer.called - - -def test__sendfile_cb_return_on_cancelling(loop): - fake_loop = mock.Mock() - with mock.patch('aiohttp.web_fileresponse.os') as m_os: - out_fd = 30 - in_fd = 31 - fut = loop.create_future() - fut.cancel() - writer = SendfileStreamWriter(mock.Mock(), mock.Mock(), fake_loop) - writer._sendfile_cb(fut, out_fd, in_fd, 0, 100, fake_loop, False) - assert fut.done() - assert not fake_loop.add_writer.called - assert not fake_loop.remove_writer.called - assert not m_os.sendfile.called - - -def test_using_gzip_if_header_present_and_file_available(loop): +from aiohttp.web_fileresponse import FileResponse + + +def test_using_gzip_if_header_present_and_file_available(loop) -> None: request = make_mocked_request( 'GET', 'http://python.org/logo.png', headers={ hdrs.ACCEPT_ENCODING: 'gzip' @@ -98,7 +32,7 @@ def test_using_gzip_if_header_present_and_file_available(loop): assert gz_filepath.open.called -def test_gzip_if_header_not_present_and_file_available(loop): +def test_gzip_if_header_not_present_and_file_available(loop) -> None: request = make_mocked_request( 'GET', 'http://python.org/logo.png', headers={ } @@ -124,7 +58,7 @@ def test_gzip_if_header_not_present_and_file_available(loop): assert not gz_filepath.open.called -def test_gzip_if_header_not_present_and_file_not_available(loop): +def test_gzip_if_header_not_present_and_file_not_available(loop) -> None: request = make_mocked_request( 'GET', 'http://python.org/logo.png', headers={ } @@ -150,7 +84,7 @@ def test_gzip_if_header_not_present_and_file_not_available(loop): assert not gz_filepath.open.called -def test_gzip_if_header_present_and_file_not_available(loop): +def test_gzip_if_header_present_and_file_not_available(loop) -> None: request = make_mocked_request( 'GET', 'http://python.org/logo.png', headers={ hdrs.ACCEPT_ENCODING: 'gzip' diff --git a/tests/test_web_sendfile_functional.py b/tests/test_web_sendfile_functional.py index 5ce8890..3d71de9 100644 --- a/tests/test_web_sendfile_functional.py +++ b/tests/test_web_sendfile_functional.py @@ -1,6 +1,7 @@ import asyncio import os import pathlib +import socket import zlib import pytest @@ -25,7 +26,7 @@ def sender(request): return maker -async def test_static_file_ok(aiohttp_client, sender): +async def test_static_file_ok(aiohttp_client, sender) -> None: filepath = pathlib.Path(__file__).parent / 'data.unknown_mime_type' async def handler(request): @@ -44,7 +45,7 @@ async def test_static_file_ok(aiohttp_client, sender): await resp.release() -async def test_static_file_ok_string_path(aiohttp_client, sender): +async def test_static_file_ok_string_path(aiohttp_client, sender) -> None: filepath = pathlib.Path(__file__).parent / 'data.unknown_mime_type' async def handler(request): @@ -63,7 +64,7 @@ async def test_static_file_ok_string_path(aiohttp_client, sender): await resp.release() -async def test_static_file_not_exists(aiohttp_client): +async def test_static_file_not_exists(aiohttp_client) -> None: app = web.Application() client = await aiohttp_client(app) @@ -73,7 +74,7 @@ async def test_static_file_not_exists(aiohttp_client): await resp.release() -async def test_static_file_name_too_long(aiohttp_client): +async def test_static_file_name_too_long(aiohttp_client) -> None: app = web.Application() client = await aiohttp_client(app) @@ -83,7 +84,7 @@ async def test_static_file_name_too_long(aiohttp_client): await resp.release() -async def test_static_file_upper_directory(aiohttp_client): +async def test_static_file_upper_directory(aiohttp_client) -> None: app = web.Application() client = await aiohttp_client(app) @@ -93,7 +94,7 @@ async def test_static_file_upper_directory(aiohttp_client): await resp.release() -async def test_static_file_with_content_type(aiohttp_client, sender): +async def test_static_file_with_content_type(aiohttp_client, sender) -> None: filepath = (pathlib.Path(__file__).parent / 'aiohttp.jpg') async def handler(request): @@ -114,7 +115,7 @@ async def test_static_file_with_content_type(aiohttp_client, sender): resp.close() -async def test_static_file_custom_content_type(aiohttp_client, sender): +async def test_static_file_custom_content_type(aiohttp_client, sender) -> None: filepath = (pathlib.Path(__file__).parent / 'hello.txt.gz') async def handler(request): @@ -159,7 +160,8 @@ async def test_static_file_custom_content_type_compress(aiohttp_client, resp.close() -async def test_static_file_with_content_encoding(aiohttp_client, sender): +async def test_static_file_with_content_encoding(aiohttp_client, + sender) -> None: filepath = pathlib.Path(__file__).parent / 'hello.txt.gz' async def handler(request): @@ -180,7 +182,7 @@ async def test_static_file_with_content_encoding(aiohttp_client, sender): resp.close() -async def test_static_file_if_modified_since(aiohttp_client, sender): +async def test_static_file_if_modified_since(aiohttp_client, sender) -> None: filename = 'data.unknown_mime_type' filepath = pathlib.Path(__file__).parent / filename @@ -205,7 +207,8 @@ async def test_static_file_if_modified_since(aiohttp_client, sender): resp.close() -async def test_static_file_if_modified_since_past_date(aiohttp_client, sender): +async def test_static_file_if_modified_since_past_date(aiohttp_client, + sender) -> None: filename = 'data.unknown_mime_type' filepath = pathlib.Path(__file__).parent / filename @@ -265,7 +268,7 @@ async def test_static_file_if_modified_since_future_date(aiohttp_client, @pytest.mark.skipif(not ssl, reason="ssl not supported") -async def test_static_file_ssl(aiohttp_server, aiohttp_client): +async def test_static_file_ssl(aiohttp_server, aiohttp_client) -> None: dirname = os.path.dirname(__file__) filename = 'data.unknown_mime_type' ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) @@ -288,7 +291,7 @@ async def test_static_file_ssl(aiohttp_server, aiohttp_client): assert resp.headers.get('CONTENT-ENCODING') is None -async def test_static_file_directory_traversal_attack(loop, aiohttp_client): +async def test_static_file_directory_traversal_attack(aiohttp_client) -> None: dirname = os.path.dirname(__file__) relpath = '../README.rst' assert os.path.isfile(os.path.join(dirname, relpath)) @@ -310,7 +313,7 @@ async def test_static_file_directory_traversal_attack(loop, aiohttp_client): assert 403 == resp.status -def test_static_route_path_existence_check(): +def test_static_route_path_existence_check() -> None: directory = os.path.dirname(__file__) web.StaticResource("/", directory) @@ -319,10 +322,10 @@ def test_static_route_path_existence_check(): web.StaticResource("/", nodirectory) -async def test_static_file_huge(loop, aiohttp_client, tmpdir): +async def test_static_file_huge(aiohttp_client, tmpdir) -> None: filename = 'huge_data.unknown_mime_type' - # fill 100MB file + # fill 20MB file with tmpdir.join(filename).open('w') as f: for i in range(1024*20): f.write(chr(i % 64 + 0x20) * 1024) @@ -352,7 +355,7 @@ async def test_static_file_huge(loop, aiohttp_client, tmpdir): f.close() -async def test_static_file_range(loop, aiohttp_client, sender): +async def test_static_file_range(aiohttp_client, sender) -> None: filepath = (pathlib.Path(__file__).parent.parent / 'LICENSE.txt') filesize = filepath.stat().st_size @@ -362,7 +365,7 @@ async def test_static_file_range(loop, aiohttp_client, sender): app = web.Application() app.router.add_get('/', handler) - client = await aiohttp_client(lambda loop: app) + client = await aiohttp_client(app) with filepath.open('rb') as f: content = f.read() @@ -372,7 +375,6 @@ async def test_static_file_range(loop, aiohttp_client, sender): client.get('/', headers={'Range': 'bytes=0-999'}), client.get('/', headers={'Range': 'bytes=1000-1999'}), client.get('/', headers={'Range': 'bytes=2000-'}), - loop=loop ) assert len(responses) == 3 assert responses[0].status == 206, \ @@ -391,7 +393,6 @@ async def test_static_file_range(loop, aiohttp_client, sender): body = await asyncio.gather( *(resp.read() for resp in responses), - loop=loop ) assert len(body[0]) == 1000, \ @@ -406,7 +407,6 @@ async def test_static_file_range(loop, aiohttp_client, sender): async def test_static_file_range_end_bigger_than_size( - loop, aiohttp_client, sender ): @@ -417,28 +417,28 @@ async def test_static_file_range_end_bigger_than_size( app = web.Application() app.router.add_get('/', handler) - client = await aiohttp_client(lambda loop: app) + client = await aiohttp_client(app) with filepath.open('rb') as f: content = f.read() # Ensure the whole file requested in parts is correct response = await client.get( - '/', headers={'Range': 'bytes=61000-62000'}) + '/', headers={'Range': 'bytes=54000-55000'}) assert response.status == 206, \ - "failed 'bytes=61000-62000': %s" % response.reason + "failed 'bytes=54000-55000': %s" % response.reason assert response.headers['Content-Range'] == \ - 'bytes 61000-61107/61108', 'failed: Content-Range Error' + 'bytes 54000-54996/54997', 'failed: Content-Range Error' body = await response.read() - assert len(body) == 108, \ - "failed 'bytes=61000-62000', received %d bytes" % len(body) + assert len(body) == 997, \ + "failed 'bytes=54000-55000', received %d bytes" % len(body) - assert content[61000:] == body + assert content[54000:] == body -async def test_static_file_range_beyond_eof(loop, aiohttp_client, sender): +async def test_static_file_range_beyond_eof(aiohttp_client, sender) -> None: filepath = (pathlib.Path(__file__).parent / 'aiohttp.png') async def handler(request): @@ -446,7 +446,7 @@ async def test_static_file_range_beyond_eof(loop, aiohttp_client, sender): app = web.Application() app.router.add_get('/', handler) - client = await aiohttp_client(lambda loop: app) + client = await aiohttp_client(app) # Ensure the whole file requested in parts is correct response = await client.get( @@ -456,7 +456,7 @@ async def test_static_file_range_beyond_eof(loop, aiohttp_client, sender): "failed 'bytes=1000000-1200000': %s" % response.reason -async def test_static_file_range_tail(loop, aiohttp_client, sender): +async def test_static_file_range_tail(aiohttp_client, sender) -> None: filepath = (pathlib.Path(__file__).parent / 'aiohttp.png') async def handler(request): @@ -464,7 +464,7 @@ async def test_static_file_range_tail(loop, aiohttp_client, sender): app = web.Application() app.router.add_get('/', handler) - client = await aiohttp_client(lambda loop: app) + client = await aiohttp_client(app) with filepath.open('rb') as f: content = f.read() @@ -472,7 +472,7 @@ async def test_static_file_range_tail(loop, aiohttp_client, sender): # Ensure the tail of the file is correct resp = await client.get('/', headers={'Range': 'bytes=-500'}) assert resp.status == 206, resp.reason - assert resp.headers['Content-Range'] == 'bytes 60608-61107/61108', \ + assert resp.headers['Content-Range'] == 'bytes 54497-54996/54997', \ 'failed: Content-Range Error' body4 = await resp.read() resp.close() @@ -481,11 +481,11 @@ async def test_static_file_range_tail(loop, aiohttp_client, sender): # Ensure out-of-range tails could be handled resp2 = await client.get('/', headers={'Range': 'bytes=-99999999999999'}) assert resp2.status == 206, resp.reason - assert resp2.headers['Content-Range'] == 'bytes 0-61107/61108', \ + assert resp2.headers['Content-Range'] == 'bytes 0-54996/54997', \ 'failed: Content-Range Error' -async def test_static_file_invalid_range(loop, aiohttp_client, sender): +async def test_static_file_invalid_range(aiohttp_client, sender) -> None: filepath = (pathlib.Path(__file__).parent / 'aiohttp.png') async def handler(request): @@ -493,7 +493,7 @@ async def test_static_file_invalid_range(loop, aiohttp_client, sender): app = web.Application() app.router.add_get('/', handler) - client = await aiohttp_client(lambda loop: app) + client = await aiohttp_client(app) # range must be in bytes resp = await client.get('/', headers={'Range': 'blocks=0-10'}) @@ -732,7 +732,7 @@ async def test_static_file_if_range_invalid_date(aiohttp_client, resp.close() -async def test_static_file_compression(aiohttp_client, sender): +async def test_static_file_compression(aiohttp_client, sender) -> None: filepath = pathlib.Path(__file__).parent / 'data.unknown_mime_type' async def handler(request): @@ -752,3 +752,68 @@ async def test_static_file_compression(aiohttp_client, sender): assert 'application/octet-stream' == resp.headers['Content-Type'] assert resp.headers.get('Content-Encoding') == 'deflate' await resp.release() + + +async def test_static_file_huge_cancel(aiohttp_client, tmpdir) -> None: + filename = 'huge_data.unknown_mime_type' + + # fill 100MB file + with tmpdir.join(filename).open('w') as f: + for i in range(1024*20): + f.write(chr(i % 64 + 0x20) * 1024) + + task = None + + async def handler(request): + nonlocal task + task = request.task + # reduce send buffer size + tr = request.transport + sock = tr.get_extra_info('socket') + sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1024) + ret = web.FileResponse(pathlib.Path(str(tmpdir.join(filename)))) + return ret + + app = web.Application() + + app.router.add_get('/', handler) + client = await aiohttp_client(app) + + resp = await client.get('/') + assert resp.status == 200 + task.cancel() + await asyncio.sleep(0) + data = b'' + while True: + try: + data += await resp.content.read(1024) + except aiohttp.ClientPayloadError: + break + assert len(data) < 1024 * 1024 * 20 + + +async def test_static_file_huge_error(aiohttp_client, tmpdir) -> None: + filename = 'huge_data.unknown_mime_type' + + # fill 20MB file + with tmpdir.join(filename).open('wb') as f: + f.seek(20*1024*1024) + f.write(b'1') + + async def handler(request): + # reduce send buffer size + tr = request.transport + sock = tr.get_extra_info('socket') + sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1024) + ret = web.FileResponse(pathlib.Path(str(tmpdir.join(filename)))) + return ret + + app = web.Application() + + app.router.add_get('/', handler) + client = await aiohttp_client(app) + + resp = await client.get('/') + assert resp.status == 200 + # raise an exception on server side + resp.close() diff --git a/tests/test_web_server.py b/tests/test_web_server.py index 6544624..7fe714b 100644 --- a/tests/test_web_server.py +++ b/tests/test_web_server.py @@ -6,7 +6,7 @@ import pytest from aiohttp import client, web -async def test_simple_server(aiohttp_raw_server, aiohttp_client): +async def test_simple_server(aiohttp_raw_server, aiohttp_client) -> None: async def handler(request): return web.Response(text=str(request.rel_url)) @@ -39,7 +39,8 @@ async def test_raw_server_not_http_exception(aiohttp_raw_server, exc_info=exc) -async def test_raw_server_handler_timeout(aiohttp_raw_server, aiohttp_client): +async def test_raw_server_handler_timeout(aiohttp_raw_server, + aiohttp_client) -> None: exc = asyncio.TimeoutError("error") async def handler(request): @@ -52,7 +53,7 @@ async def test_raw_server_handler_timeout(aiohttp_raw_server, aiohttp_client): assert resp.status == 504 await resp.text() - logger.debug.assert_called_with("Request handler timed out.") + logger.debug.assert_called_with("Request handler timed out.", exc_info=exc) async def test_raw_server_do_not_swallow_exceptions(aiohttp_raw_server, @@ -108,13 +109,3 @@ async def test_raw_server_not_http_exception_debug(aiohttp_raw_server, logger.exception.assert_called_with( "Error handling request", exc_info=exc) - - -def test_create_web_server_with_implicit_loop(loop): - asyncio.set_event_loop(loop) - - async def handler(request): - return web.Response() # pragma: no cover - - srv = web.Server(handler) - assert srv._loop is loop diff --git a/tests/test_web_urldispatcher.py b/tests/test_web_urldispatcher.py index 9a83dad..c3d759a 100644 --- a/tests/test_web_urldispatcher.py +++ b/tests/test_web_urldispatcher.py @@ -46,8 +46,12 @@ def tmp_dir_path(request): b'<li><a href="/static/my_file">my_file</a></li>\n' b'</ul>\n</body>\n</html>', id="index_static")]) -async def test_access_root_of_static_handler(tmp_dir_path, aiohttp_client, - show_index, status, prefix, data): +async def test_access_root_of_static_handler(tmp_dir_path, + aiohttp_client, + show_index, + status, + prefix, + data) -> None: """ Tests the operation of static file server. Try to access the root of static file server, and make @@ -82,7 +86,7 @@ async def test_access_root_of_static_handler(tmp_dir_path, aiohttp_client, assert read_ == data -async def test_follow_symlink(tmp_dir_path, aiohttp_client): +async def test_follow_symlink(tmp_dir_path, aiohttp_client) -> None: """ Tests the access to a symlink, in static folder """ @@ -142,7 +146,8 @@ async def test_access_to_the_file_with_spaces(tmp_dir_path, aiohttp_client, assert (await r.text()) == data -async def test_access_non_existing_resource(tmp_dir_path, aiohttp_client): +async def test_access_non_existing_resource(tmp_dir_path, + aiohttp_client) -> None: """ Tests accessing non-existing resource Try to access a non-exiting resource and make sure that 404 HTTP status @@ -164,7 +169,9 @@ async def test_access_non_existing_resource(tmp_dir_path, aiohttp_client): ('/a@b', '/a@b'), ('/a:b', '/a%3Ab'), ]) -async def test_url_escaping(aiohttp_client, registered_path, request_url): +async def test_url_escaping(aiohttp_client, + registered_path, + request_url) -> None: """ Tests accessing a resource with """ @@ -179,7 +186,7 @@ async def test_url_escaping(aiohttp_client, registered_path, request_url): assert r.status == 200 -async def test_handler_metadata_persistence(): +async def test_handler_metadata_persistence() -> None: """ Tests accessing metadata of a handler after registering it on the app router. @@ -203,7 +210,8 @@ async def test_handler_metadata_persistence(): assert route.handler.__doc__ == 'Doc' -async def test_unauthorized_folder_access(tmp_dir_path, aiohttp_client): +async def test_unauthorized_folder_access(tmp_dir_path, + aiohttp_client) -> None: """ Tests the unauthorized access to a folder of static file server. Try to list a folder content of static file server when server does not @@ -230,7 +238,7 @@ async def test_unauthorized_folder_access(tmp_dir_path, aiohttp_client): assert r.status == 403 -async def test_access_symlink_loop(tmp_dir_path, aiohttp_client): +async def test_access_symlink_loop(tmp_dir_path, aiohttp_client) -> None: """ Tests the access to a looped symlink, which could not be resolved. """ @@ -248,7 +256,7 @@ async def test_access_symlink_loop(tmp_dir_path, aiohttp_client): assert r.status == 404 -async def test_access_special_resource(tmp_dir_path, aiohttp_client): +async def test_access_special_resource(tmp_dir_path, aiohttp_client) -> None: """ Tests the access to a resource that is neither a file nor a directory. Checks that if a special resource is accessed (f.e. named pipe or UNIX @@ -278,7 +286,7 @@ async def test_access_special_resource(tmp_dir_path, aiohttp_client): assert r.status == 403 -async def test_partially_applied_handler(aiohttp_client): +async def test_partially_applied_handler(aiohttp_client) -> None: app = web.Application() async def handler(data, request): @@ -293,7 +301,7 @@ async def test_partially_applied_handler(aiohttp_client): assert data == b'hello' -def test_system_route(): +def test_system_route() -> None: route = SystemRoute(web.HTTPCreated(reason='test')) with pytest.raises(RuntimeError): route.url_for() @@ -304,7 +312,7 @@ def test_system_route(): assert 'test' == route.reason -async def test_412_is_returned(aiohttp_client): +async def test_412_is_returned(aiohttp_client) -> None: class MyRouter(abc.AbstractRouter): @@ -321,7 +329,7 @@ async def test_412_is_returned(aiohttp_client): assert resp.status == 412 -async def test_allow_head(aiohttp_client): +async def test_allow_head(aiohttp_client) -> None: """ Test allow_head on routes. """ @@ -354,7 +362,7 @@ async def test_allow_head(aiohttp_client): '/a', '/{a}', ]) -def test_reuse_last_added_resource(path): +def test_reuse_last_added_resource(path) -> None: """ Test that adding a route with the same name and path of the last added resource doesn't create a new resource. @@ -370,7 +378,7 @@ def test_reuse_last_added_resource(path): assert len(app.router.resources()) == 1 -def test_resource_raw_match(): +def test_resource_raw_match() -> None: app = web.Application() async def handler(request): @@ -386,7 +394,7 @@ def test_resource_raw_match(): assert not resource.raw_match("/static") -async def test_add_view(aiohttp_client): +async def test_add_view(aiohttp_client) -> None: app = web.Application() class MyView(web.View): @@ -413,7 +421,7 @@ async def test_add_view(aiohttp_client): await r.release() -async def test_decorate_view(aiohttp_client): +async def test_decorate_view(aiohttp_client) -> None: routes = web.RouteTableDef() @routes.view("/a") @@ -442,7 +450,7 @@ async def test_decorate_view(aiohttp_client): await r.release() -async def test_web_view(aiohttp_client): +async def test_web_view(aiohttp_client) -> None: app = web.Application() class MyView(web.View): @@ -471,7 +479,7 @@ async def test_web_view(aiohttp_client): await r.release() -async def test_static_absolute_url(aiohttp_client, tmpdir): +async def test_static_absolute_url(aiohttp_client, tmpdir) -> None: # requested url is an absolute name like # /static/\\machine_name\c$ or /static/D:\path # where the static dir is totally different diff --git a/tests/test_web_websocket.py b/tests/test_web_websocket.py index ad5b7f5..b7d2f80 100644 --- a/tests/test_web_websocket.py +++ b/tests/test_web_websocket.py @@ -51,61 +51,61 @@ def make_request(app, protocol): return maker -async def test_nonstarted_ping(): +async def test_nonstarted_ping() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.ping() -async def test_nonstarted_pong(): +async def test_nonstarted_pong() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.pong() -async def test_nonstarted_send_str(): +async def test_nonstarted_send_str() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.send_str('string') -async def test_nonstarted_send_bytes(): +async def test_nonstarted_send_bytes() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.send_bytes(b'bytes') -async def test_nonstarted_send_json(): +async def test_nonstarted_send_json() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.send_json({'type': 'json'}) -async def test_nonstarted_close(): +async def test_nonstarted_close() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.close() -async def test_nonstarted_receive_str(): +async def test_nonstarted_receive_str() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.receive_str() -async def test_nonstarted_receive_bytes(): +async def test_nonstarted_receive_bytes() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.receive_bytes() -async def test_nonstarted_receive_json(): +async def test_nonstarted_receive_json() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.receive_json() -async def test_receive_str_nonstring(make_request): +async def test_receive_str_nonstring(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -119,7 +119,7 @@ async def test_receive_str_nonstring(make_request): await ws.receive_str() -async def test_receive_bytes_nonsbytes(make_request): +async def test_receive_bytes_nonsbytes(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -133,7 +133,7 @@ async def test_receive_bytes_nonsbytes(make_request): await ws.receive_bytes() -async def test_send_str_nonstring(make_request): +async def test_send_str_nonstring(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -141,7 +141,7 @@ async def test_send_str_nonstring(make_request): await ws.send_str(b'bytes') -async def test_send_bytes_nonbytes(make_request): +async def test_send_bytes_nonbytes(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -149,7 +149,7 @@ async def test_send_bytes_nonbytes(make_request): await ws.send_bytes('string') -async def test_send_json_nonjson(make_request): +async def test_send_json_nonjson(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -157,66 +157,66 @@ async def test_send_json_nonjson(make_request): await ws.send_json(set()) -async def test_write_non_prepared(): +async def test_write_non_prepared() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.write(b'data') -def test_websocket_ready(): +def test_websocket_ready() -> None: websocket_ready = WebSocketReady(True, 'chat') assert websocket_ready.ok is True assert websocket_ready.protocol == 'chat' -def test_websocket_not_ready(): +def test_websocket_not_ready() -> None: websocket_ready = WebSocketReady(False, None) assert websocket_ready.ok is False assert websocket_ready.protocol is None -def test_websocket_ready_unknown_protocol(): +def test_websocket_ready_unknown_protocol() -> None: websocket_ready = WebSocketReady(True, None) assert websocket_ready.ok is True assert websocket_ready.protocol is None -def test_bool_websocket_ready(): +def test_bool_websocket_ready() -> None: websocket_ready = WebSocketReady(True, None) assert bool(websocket_ready) is True -def test_bool_websocket_not_ready(): +def test_bool_websocket_not_ready() -> None: websocket_ready = WebSocketReady(False, None) assert bool(websocket_ready) is False -def test_can_prepare_ok(make_request): +def test_can_prepare_ok(make_request) -> None: req = make_request('GET', '/', protocols=True) ws = WebSocketResponse(protocols=('chat',)) assert WebSocketReady(True, 'chat') == ws.can_prepare(req) -def test_can_prepare_unknown_protocol(make_request): +def test_can_prepare_unknown_protocol(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() assert WebSocketReady(True, None) == ws.can_prepare(req) -def test_can_prepare_invalid_method(make_request): +def test_can_prepare_invalid_method(make_request) -> None: req = make_request('POST', '/') ws = WebSocketResponse() assert WebSocketReady(False, None) == ws.can_prepare(req) -def test_can_prepare_without_upgrade(make_request): +def test_can_prepare_without_upgrade(make_request) -> None: req = make_request('GET', '/', headers=CIMultiDict({})) ws = WebSocketResponse() assert WebSocketReady(False, None) == ws.can_prepare(req) -async def test_can_prepare_started(make_request): +async def test_can_prepare_started(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -226,13 +226,13 @@ async def test_can_prepare_started(make_request): assert 'Already started' in str(ctx.value) -def test_closed_after_ctor(): +def test_closed_after_ctor() -> None: ws = WebSocketResponse() assert not ws.closed assert ws.close_code is None -async def test_send_str_closed(make_request, mocker): +async def test_send_str_closed(make_request, mocker) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -244,7 +244,7 @@ async def test_send_str_closed(make_request, mocker): assert ws_logger.warning.called -async def test_send_bytes_closed(make_request, mocker): +async def test_send_bytes_closed(make_request, mocker) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -256,7 +256,7 @@ async def test_send_bytes_closed(make_request, mocker): assert ws_logger.warning.called -async def test_send_json_closed(make_request, mocker): +async def test_send_json_closed(make_request, mocker) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -268,7 +268,7 @@ async def test_send_json_closed(make_request, mocker): assert ws_logger.warning.called -async def test_ping_closed(make_request, mocker): +async def test_ping_closed(make_request, mocker) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -280,7 +280,7 @@ async def test_ping_closed(make_request, mocker): assert ws_logger.warning.called -async def test_pong_closed(make_request, mocker): +async def test_pong_closed(make_request, mocker) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -292,7 +292,7 @@ async def test_pong_closed(make_request, mocker): assert ws_logger.warning.called -async def test_close_idempotent(make_request): +async def test_close_idempotent(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -302,14 +302,14 @@ async def test_close_idempotent(make_request): assert not (await ws.close(code=2, message='message2')) -async def test_prepare_invalid_method(make_request): +async def test_prepare_invalid_method(make_request) -> None: req = make_request('POST', '/') ws = WebSocketResponse() with pytest.raises(HTTPMethodNotAllowed): await ws.prepare(req) -async def test_prepare_without_upgrade(make_request): +async def test_prepare_without_upgrade(make_request) -> None: req = make_request('GET', '/', headers=CIMultiDict({})) ws = WebSocketResponse() @@ -317,19 +317,19 @@ async def test_prepare_without_upgrade(make_request): await ws.prepare(req) -async def test_wait_closed_before_start(): +async def test_wait_closed_before_start() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.close() -async def test_write_eof_not_started(): +async def test_write_eof_not_started() -> None: ws = WebSocketResponse() with pytest.raises(RuntimeError): await ws.write_eof() -async def test_write_eof_idempotent(make_request): +async def test_write_eof_idempotent(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -341,7 +341,7 @@ async def test_write_eof_idempotent(make_request): await ws.write_eof() -async def test_receive_eofstream_in_reader(make_request, loop): +async def test_receive_eofstream_in_reader(make_request, loop) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -360,7 +360,7 @@ async def test_receive_eofstream_in_reader(make_request, loop): assert ws.closed -async def test_receive_exc_in_reader(make_request, loop): +async def test_receive_exc_in_reader(make_request, loop) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -380,7 +380,7 @@ async def test_receive_exc_in_reader(make_request, loop): assert ws.exception() is exc -async def test_receive_cancelled(make_request, loop): +async def test_receive_cancelled(make_request, loop) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -394,7 +394,7 @@ async def test_receive_cancelled(make_request, loop): await ws.receive() -async def test_receive_timeouterror(make_request, loop): +async def test_receive_timeouterror(make_request, loop) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -408,7 +408,7 @@ async def test_receive_timeouterror(make_request, loop): await ws.receive() -async def test_multiple_receive_on_close_connection(make_request): +async def test_multiple_receive_on_close_connection(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -424,7 +424,7 @@ async def test_multiple_receive_on_close_connection(make_request): await ws.receive() -async def test_concurrent_receive(make_request): +async def test_concurrent_receive(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) @@ -434,7 +434,7 @@ async def test_concurrent_receive(make_request): await ws.receive() -async def test_close_exc(make_request, loop, mocker): +async def test_close_exc(make_request, loop, mocker) -> None: req = make_request('GET', '/') ws = WebSocketResponse() @@ -460,7 +460,7 @@ async def test_close_exc(make_request, loop, mocker): assert ws.close_code == 1006 -async def test_close_exc2(make_request): +async def test_close_exc2(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() @@ -479,7 +479,7 @@ async def test_close_exc2(make_request): await ws.close() -async def test_prepare_twice_idempotent(make_request): +async def test_prepare_twice_idempotent(make_request) -> None: req = make_request('GET', '/') ws = WebSocketResponse() @@ -488,7 +488,7 @@ async def test_prepare_twice_idempotent(make_request): assert impl1 is impl2 -async def test_send_with_per_message_deflate(make_request, mocker): +async def test_send_with_per_message_deflate(make_request, mocker) -> None: req = make_request('GET', '/') ws = WebSocketResponse() await ws.prepare(req) diff --git a/tests/test_web_websocket_functional.py b/tests/test_web_websocket_functional.py index 74a2908..2cc8309 100644 --- a/tests/test_web_websocket_functional.py +++ b/tests/test_web_websocket_functional.py @@ -17,7 +17,7 @@ def ceil(mocker): mocker.patch('aiohttp.helpers.ceil').side_effect = ceil -async def test_websocket_can_prepare(loop, aiohttp_client): +async def test_websocket_can_prepare(loop, aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -34,7 +34,7 @@ async def test_websocket_can_prepare(loop, aiohttp_client): assert resp.status == 426 -async def test_websocket_json(loop, aiohttp_client): +async def test_websocket_json(loop, aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -64,7 +64,7 @@ async def test_websocket_json(loop, aiohttp_client): assert resp.data == expected_value -async def test_websocket_json_invalid_message(loop, aiohttp_client): +async def test_websocket_json_invalid_message(loop, aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -91,7 +91,7 @@ async def test_websocket_json_invalid_message(loop, aiohttp_client): assert 'ValueError was raised' in data -async def test_websocket_send_json(loop, aiohttp_client): +async def test_websocket_send_json(loop, aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -115,7 +115,7 @@ async def test_websocket_send_json(loop, aiohttp_client): assert data['test'] == expected_value -async def test_websocket_receive_json(loop, aiohttp_client): +async def test_websocket_receive_json(loop, aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() @@ -141,7 +141,7 @@ async def test_websocket_receive_json(loop, aiohttp_client): assert resp.data == expected_value -async def test_send_recv_text(loop, aiohttp_client): +async def test_send_recv_text(loop, aiohttp_client) -> None: closed = loop.create_future() @@ -175,7 +175,7 @@ async def test_send_recv_text(loop, aiohttp_client): await closed -async def test_send_recv_bytes(loop, aiohttp_client): +async def test_send_recv_bytes(loop, aiohttp_client) -> None: closed = loop.create_future() @@ -210,7 +210,7 @@ async def test_send_recv_bytes(loop, aiohttp_client): await closed -async def test_send_recv_json(loop, aiohttp_client): +async def test_send_recv_json(loop, aiohttp_client) -> None: closed = loop.create_future() async def handler(request): @@ -244,7 +244,7 @@ async def test_send_recv_json(loop, aiohttp_client): await closed -async def test_close_timeout(loop, aiohttp_client): +async def test_close_timeout(loop, aiohttp_client) -> None: aborted = loop.create_future() async def handler(request): @@ -297,7 +297,7 @@ async def test_close_timeout(loop, aiohttp_client): await ws.close() -async def test_concurrent_close(loop, aiohttp_client): +async def test_concurrent_close(loop, aiohttp_client) -> None: srv_ws = None @@ -337,7 +337,7 @@ async def test_concurrent_close(loop, aiohttp_client): assert msg.type == WSMsgType.CLOSED -async def test_auto_pong_with_closing_by_peer(loop, aiohttp_client): +async def test_auto_pong_with_closing_by_peer(loop, aiohttp_client) -> None: closed = loop.create_future() @@ -367,7 +367,7 @@ async def test_auto_pong_with_closing_by_peer(loop, aiohttp_client): await closed -async def test_ping(loop, aiohttp_client): +async def test_ping(loop, aiohttp_client) -> None: closed = loop.create_future() @@ -420,7 +420,7 @@ async def aiohttp_client_ping(loop, aiohttp_client): await ws.close() -async def test_pong(loop, aiohttp_client): +async def test_pong(loop, aiohttp_client) -> None: closed = loop.create_future() @@ -455,7 +455,7 @@ async def test_pong(loop, aiohttp_client): await closed -async def test_change_status(loop, aiohttp_client): +async def test_change_status(loop, aiohttp_client) -> None: closed = loop.create_future() @@ -480,7 +480,7 @@ async def test_change_status(loop, aiohttp_client): await ws.close() -async def test_handle_protocol(loop, aiohttp_client): +async def test_handle_protocol(loop, aiohttp_client) -> None: closed = loop.create_future() @@ -502,7 +502,7 @@ async def test_handle_protocol(loop, aiohttp_client): await closed -async def test_server_close_handshake(loop, aiohttp_client): +async def test_server_close_handshake(loop, aiohttp_client) -> None: closed = loop.create_future() @@ -591,7 +591,7 @@ async def test_server_close_handshake_server_eats_client_messages( await closed -async def test_receive_timeout(loop, aiohttp_client): +async def test_receive_timeout(loop, aiohttp_client) -> None: raised = False async def handler(request): @@ -617,7 +617,7 @@ async def test_receive_timeout(loop, aiohttp_client): assert raised -async def test_custom_receive_timeout(loop, aiohttp_client): +async def test_custom_receive_timeout(loop, aiohttp_client) -> None: raised = False async def handler(request): @@ -643,7 +643,7 @@ async def test_custom_receive_timeout(loop, aiohttp_client): assert raised -async def test_heartbeat(loop, aiohttp_client, ceil): +async def test_heartbeat(loop, aiohttp_client, ceil) -> None: async def handler(request): ws = web.WebSocketResponse(heartbeat=0.05) @@ -664,7 +664,7 @@ async def test_heartbeat(loop, aiohttp_client, ceil): await ws.close() -async def test_heartbeat_no_pong(loop, aiohttp_client, ceil): +async def test_heartbeat_no_pong(loop, aiohttp_client, ceil) -> None: cancelled = False async def handler(request): @@ -692,7 +692,7 @@ async def test_heartbeat_no_pong(loop, aiohttp_client, ceil): assert cancelled -async def test_server_ws_async_for(loop, aiohttp_server): +async def test_server_ws_async_for(loop, aiohttp_server) -> None: closed = loop.create_future() async def handler(request): @@ -724,7 +724,7 @@ async def test_server_ws_async_for(loop, aiohttp_server): await closed -async def test_closed_async_for(loop, aiohttp_client): +async def test_closed_async_for(loop, aiohttp_client) -> None: closed = loop.create_future() @@ -760,7 +760,7 @@ async def test_closed_async_for(loop, aiohttp_client): await closed -async def test_websocket_disable_keepalive(loop, aiohttp_client): +async def test_websocket_disable_keepalive(loop, aiohttp_client) -> None: async def handler(request): ws = web.WebSocketResponse() if not ws.can_prepare(request): diff --git a/tests/test_websocket_handshake.py b/tests/test_websocket_handshake.py index 7082e8a..0dc934e 100644 --- a/tests/test_websocket_handshake.py +++ b/tests/test_websocket_handshake.py @@ -32,21 +32,21 @@ def gen_ws_headers(protocols='', compress=0, extension_text='', return hdrs, key -async def test_not_get(): +async def test_not_get() -> None: ws = web.WebSocketResponse() req = make_mocked_request('POST', '/') with pytest.raises(web.HTTPMethodNotAllowed): await ws.prepare(req) -async def test_no_upgrade(): +async def test_no_upgrade() -> None: ws = web.WebSocketResponse() req = make_mocked_request('GET', '/') with pytest.raises(web.HTTPBadRequest): await ws.prepare(req) -async def test_no_connection(): +async def test_no_connection() -> None: ws = web.WebSocketResponse() req = make_mocked_request('GET', '/', headers={'Upgrade': 'websocket', 'Connection': 'keep-alive'}) @@ -54,7 +54,7 @@ async def test_no_connection(): await ws.prepare(req) -async def test_protocol_version_unset(): +async def test_protocol_version_unset() -> None: ws = web.WebSocketResponse() req = make_mocked_request('GET', '/', headers={'Upgrade': 'websocket', 'Connection': 'upgrade'}) @@ -62,7 +62,7 @@ async def test_protocol_version_unset(): await ws.prepare(req) -async def test_protocol_version_not_supported(): +async def test_protocol_version_not_supported() -> None: ws = web.WebSocketResponse() req = make_mocked_request('GET', '/', headers={'Upgrade': 'websocket', @@ -72,7 +72,7 @@ async def test_protocol_version_not_supported(): await ws.prepare(req) -async def test_protocol_key_not_present(): +async def test_protocol_key_not_present() -> None: ws = web.WebSocketResponse() req = make_mocked_request('GET', '/', headers={'Upgrade': 'websocket', @@ -82,7 +82,7 @@ async def test_protocol_key_not_present(): await ws.prepare(req) -async def test_protocol_key_invalid(): +async def test_protocol_key_invalid() -> None: ws = web.WebSocketResponse() req = make_mocked_request('GET', '/', headers={'Upgrade': 'websocket', @@ -93,7 +93,7 @@ async def test_protocol_key_invalid(): await ws.prepare(req) -async def test_protocol_key_bad_size(): +async def test_protocol_key_bad_size() -> None: ws = web.WebSocketResponse() sec_key = base64.b64encode(os.urandom(2)) val = sec_key.decode() @@ -106,7 +106,7 @@ async def test_protocol_key_bad_size(): await ws.prepare(req) -async def test_handshake_ok(): +async def test_handshake_ok() -> None: hdrs, sec_key = gen_ws_headers() ws = web.WebSocketResponse() req = make_mocked_request('GET', '/', headers=hdrs) @@ -116,7 +116,7 @@ async def test_handshake_ok(): assert ws.ws_protocol is None -async def test_handshake_protocol(): +async def test_handshake_protocol() -> None: # Tests if one protocol is returned by handshake proto = 'chat' @@ -128,7 +128,7 @@ async def test_handshake_protocol(): assert ws.ws_protocol == proto -async def test_handshake_protocol_agreement(): +async def test_handshake_protocol_agreement() -> None: # Tests if the right protocol is selected given multiple best_proto = 'worse_proto' wanted_protos = ['best', 'chat', 'worse_proto'] @@ -143,7 +143,7 @@ async def test_handshake_protocol_agreement(): assert ws.ws_protocol == best_proto -async def test_handshake_protocol_unsupported(caplog): +async def test_handshake_protocol_unsupported(caplog) -> None: # Tests if a protocol mismatch handshake warns and returns None proto = 'chat' req = make_mocked_request('GET', '/', @@ -157,7 +157,7 @@ async def test_handshake_protocol_unsupported(caplog): assert ws.ws_protocol is None -async def test_handshake_compress(): +async def test_handshake_compress() -> None: hdrs, sec_key = gen_ws_headers(compress=15) req = make_mocked_request('GET', '/', headers=hdrs) @@ -168,7 +168,7 @@ async def test_handshake_compress(): assert ws.compress == 15 -def test_handshake_compress_server_notakeover(): +def test_handshake_compress_server_notakeover() -> None: hdrs, sec_key = gen_ws_headers(compress=15, server_notakeover=True) req = make_mocked_request('GET', '/', headers=hdrs) @@ -183,7 +183,7 @@ def test_handshake_compress_server_notakeover(): 'permessage-deflate; server_no_context_takeover') -def test_handshake_compress_client_notakeover(): +def test_handshake_compress_client_notakeover() -> None: hdrs, sec_key = gen_ws_headers(compress=15, client_notakeover=True) req = make_mocked_request('GET', '/', headers=hdrs) @@ -198,7 +198,7 @@ def test_handshake_compress_client_notakeover(): assert compress == 15 -def test_handshake_compress_wbits(): +def test_handshake_compress_wbits() -> None: hdrs, sec_key = gen_ws_headers(compress=9) req = make_mocked_request('GET', '/', headers=hdrs) @@ -212,7 +212,7 @@ def test_handshake_compress_wbits(): assert compress == 9 -def test_handshake_compress_wbits_error(): +def test_handshake_compress_wbits_error() -> None: hdrs, sec_key = gen_ws_headers(compress=6) req = make_mocked_request('GET', '/', headers=hdrs) @@ -224,7 +224,7 @@ def test_handshake_compress_wbits_error(): assert compress == 0 -def test_handshake_compress_bad_ext(): +def test_handshake_compress_bad_ext() -> None: hdrs, sec_key = gen_ws_headers(compress=15, extension_text='bad') req = make_mocked_request('GET', '/', headers=hdrs) @@ -236,7 +236,7 @@ def test_handshake_compress_bad_ext(): assert compress == 0 -def test_handshake_compress_multi_ext_bad(): +def test_handshake_compress_multi_ext_bad() -> None: hdrs, sec_key = gen_ws_headers(compress=15, extension_text='bad, permessage-deflate') @@ -249,7 +249,7 @@ def test_handshake_compress_multi_ext_bad(): assert headers['Sec-Websocket-Extensions'] == 'permessage-deflate' -def test_handshake_compress_multi_ext_wbits(): +def test_handshake_compress_multi_ext_wbits() -> None: hdrs, sec_key = gen_ws_headers(compress=6, extension_text=', permessage-deflate') diff --git a/tests/test_websocket_parser.py b/tests/test_websocket_parser.py index e16b42d..6dcd560 100644 --- a/tests/test_websocket_parser.py +++ b/tests/test_websocket_parser.py @@ -73,7 +73,7 @@ def build_close_frame(code=1000, message=b'', noheader=False): @pytest.fixture() def out(loop): - return aiohttp.DataQueue(loop=loop) + return aiohttp.DataQueue(loop) @pytest.fixture() @@ -81,7 +81,7 @@ def parser(out): return WebSocketReader(out, 4*1024*1024) -def test_parse_frame(parser): +def test_parse_frame(parser) -> None: parser.parse_frame(struct.pack('!BB', 0b00000001, 0b00000001)) res = parser.parse_frame(b'1') fin, opcode, payload, compress = res[0] @@ -89,14 +89,14 @@ def test_parse_frame(parser): assert (0, 1, b'1', False) == (fin, opcode, payload, not not compress) -def test_parse_frame_length0(parser): +def test_parse_frame_length0(parser) -> None: fin, opcode, payload, compress = parser.parse_frame( struct.pack('!BB', 0b00000001, 0b00000000))[0] assert (0, 1, b'', False) == (fin, opcode, payload, not not compress) -def test_parse_frame_length2(parser): +def test_parse_frame_length2(parser) -> None: parser.parse_frame(struct.pack('!BB', 0b00000001, 126)) parser.parse_frame(struct.pack('!H', 4)) res = parser.parse_frame(b'1234') @@ -105,7 +105,7 @@ def test_parse_frame_length2(parser): assert (0, 1, b'1234', False) == (fin, opcode, payload, not not compress) -def test_parse_frame_length4(parser): +def test_parse_frame_length4(parser) -> None: parser.parse_frame(struct.pack('!BB', 0b00000001, 127)) parser.parse_frame(struct.pack('!Q', 4)) fin, opcode, payload, compress = parser.parse_frame(b'1234')[0] @@ -113,7 +113,7 @@ def test_parse_frame_length4(parser): assert (0, 1, b'1234', False) == (fin, opcode, payload, not not compress) -def test_parse_frame_mask(parser): +def test_parse_frame_mask(parser) -> None: parser.parse_frame(struct.pack('!BB', 0b00000001, 0b10000001)) parser.parse_frame(b'0001') fin, opcode, payload, compress = parser.parse_frame(b'1')[0] @@ -121,13 +121,13 @@ def test_parse_frame_mask(parser): assert (0, 1, b'\x01', False) == (fin, opcode, payload, not not compress) -def test_parse_frame_header_reversed_bits(out, parser): +def test_parse_frame_header_reversed_bits(out, parser) -> None: with pytest.raises(WebSocketError): parser.parse_frame(struct.pack('!BB', 0b01100000, 0b00000000)) raise out.exception() -def test_parse_frame_header_control_frame(out, parser): +def test_parse_frame_header_control_frame(out, parser) -> None: with pytest.raises(WebSocketError): parser.parse_frame(struct.pack('!BB', 0b00001000, 0b00000000)) raise out.exception() @@ -139,13 +139,13 @@ def _test_parse_frame_header_new_data_err(out, parser): raise out.exception() -def test_parse_frame_header_payload_size(out, parser): +def test_parse_frame_header_payload_size(out, parser) -> None: with pytest.raises(WebSocketError): parser.parse_frame(struct.pack('!BB', 0b10001000, 0b01111110)) raise out.exception() -def test_ping_frame(out, parser): +def test_ping_frame(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [(1, WSMsgType.PING, b'data', False)] @@ -154,7 +154,7 @@ def test_ping_frame(out, parser): assert res == ((WSMsgType.PING, b'data', ''), 4) -def test_pong_frame(out, parser): +def test_pong_frame(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [(1, WSMsgType.PONG, b'data', False)] @@ -163,7 +163,7 @@ def test_pong_frame(out, parser): assert res == ((WSMsgType.PONG, b'data', ''), 4) -def test_close_frame(out, parser): +def test_close_frame(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [(1, WSMsgType.CLOSE, b'', False)] @@ -172,7 +172,7 @@ def test_close_frame(out, parser): assert res == ((WSMsgType.CLOSE, 0, ''), 0) -def test_close_frame_info(out, parser): +def test_close_frame_info(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [(1, WSMsgType.CLOSE, b'0112345', False)] @@ -181,7 +181,7 @@ def test_close_frame_info(out, parser): assert res == (WSMessage(WSMsgType.CLOSE, 12337, '12345'), 0) -def test_close_frame_invalid(out, parser): +def test_close_frame_invalid(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [(1, WSMsgType.CLOSE, b'1', False)] parser.feed_data(b'') @@ -190,7 +190,7 @@ def test_close_frame_invalid(out, parser): assert out.exception().code == WSCloseCode.PROTOCOL_ERROR -def test_close_frame_invalid_2(out, parser): +def test_close_frame_invalid_2(out, parser) -> None: data = build_close_frame(code=1) with pytest.raises(WebSocketError) as ctx: @@ -199,7 +199,7 @@ def test_close_frame_invalid_2(out, parser): assert ctx.value.code == WSCloseCode.PROTOCOL_ERROR -def test_close_frame_unicode_err(parser): +def test_close_frame_unicode_err(parser) -> None: data = build_close_frame( code=1000, message=b'\xf4\x90\x80\x80') @@ -209,7 +209,7 @@ def test_close_frame_unicode_err(parser): assert ctx.value.code == WSCloseCode.INVALID_TEXT -def test_unknown_frame(out, parser): +def test_unknown_frame(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [(1, WSMsgType.CONTINUATION, b'', False)] @@ -218,14 +218,14 @@ def test_unknown_frame(out, parser): raise out.exception() -def test_simple_text(out, parser): +def test_simple_text(out, parser) -> None: data = build_frame(b'text', WSMsgType.TEXT) parser._feed_data(data) res = out._buffer[0] assert res == ((WSMsgType.TEXT, 'text', ''), 4) -def test_simple_text_unicode_err(parser): +def test_simple_text_unicode_err(parser) -> None: data = build_frame(b'\xf4\x90\x80\x80', WSMsgType.TEXT) with pytest.raises(WebSocketError) as ctx: @@ -234,7 +234,7 @@ def test_simple_text_unicode_err(parser): assert ctx.value.code == WSCloseCode.INVALID_TEXT -def test_simple_binary(out, parser): +def test_simple_binary(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [(1, WSMsgType.BINARY, b'binary', False)] @@ -243,7 +243,7 @@ def test_simple_binary(out, parser): assert res == ((WSMsgType.BINARY, b'binary', ''), 6) -def test_fragmentation_header(out, parser): +def test_fragmentation_header(out, parser) -> None: data = build_frame(b'a', WSMsgType.TEXT) parser._feed_data(data[:1]) parser._feed_data(data[1:]) @@ -252,7 +252,7 @@ def test_fragmentation_header(out, parser): assert res == (WSMessage(WSMsgType.TEXT, 'a', ''), 1) -def test_continuation(out, parser): +def test_continuation(out, parser) -> None: data1 = build_frame(b'line1', WSMsgType.TEXT, is_fin=False) parser._feed_data(data1) @@ -263,7 +263,7 @@ def test_continuation(out, parser): assert res == (WSMessage(WSMsgType.TEXT, 'line1line2', ''), 10) -def test_continuation_with_ping(out, parser): +def test_continuation_with_ping(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [ (0, WSMsgType.TEXT, b'line1', False), @@ -286,7 +286,7 @@ def test_continuation_with_ping(out, parser): assert res == (WSMessage(WSMsgType.TEXT, 'line1line2', ''), 10) -def test_continuation_err(out, parser): +def test_continuation_err(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [ (0, WSMsgType.TEXT, b'line1', False), @@ -296,7 +296,7 @@ def test_continuation_err(out, parser): parser._feed_data(b'') -def test_continuation_with_close(out, parser): +def test_continuation_with_close(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [ (0, WSMsgType.TEXT, b'line1', False), @@ -312,7 +312,7 @@ def test_continuation_with_close(out, parser): assert res == (WSMessage(WSMsgType.TEXT, 'line1line2', ''), 10) -def test_continuation_with_close_unicode_err(out, parser): +def test_continuation_with_close_unicode_err(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [ (0, WSMsgType.TEXT, b'line1', False), @@ -326,7 +326,7 @@ def test_continuation_with_close_unicode_err(out, parser): assert ctx.value.code == WSCloseCode.INVALID_TEXT -def test_continuation_with_close_bad_code(out, parser): +def test_continuation_with_close_bad_code(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [ (0, WSMsgType.TEXT, b'line1', False), @@ -340,7 +340,7 @@ def test_continuation_with_close_bad_code(out, parser): assert ctx.value.code == WSCloseCode.PROTOCOL_ERROR -def test_continuation_with_close_bad_payload(out, parser): +def test_continuation_with_close_bad_payload(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [ (0, WSMsgType.TEXT, b'line1', False), @@ -353,7 +353,7 @@ def test_continuation_with_close_bad_payload(out, parser): assert ctx.value.code, WSCloseCode.PROTOCOL_ERROR -def test_continuation_with_close_empty(out, parser): +def test_continuation_with_close_empty(out, parser) -> None: parser.parse_frame = mock.Mock() parser.parse_frame.return_value = [ (0, WSMsgType.TEXT, b'line1', False), @@ -374,7 +374,7 @@ websocket_mask_masked = (b'B]^Q\x11DVFH\x12_[_U\x13PPFR\x14W]A\x14\\S@_X' b'\\T\x14SK\x13CTP@[RYV@') -def test_websocket_mask_python(): +def test_websocket_mask_python() -> None: message = bytearray(websocket_mask_data) http_websocket._websocket_mask_python( websocket_mask_mask, message) @@ -383,14 +383,14 @@ def test_websocket_mask_python(): @pytest.mark.skipif(not hasattr(http_websocket, '_websocket_mask_cython'), reason='Requires Cython') -def test_websocket_mask_cython(): +def test_websocket_mask_cython() -> None: message = bytearray(websocket_mask_data) http_websocket._websocket_mask_cython( websocket_mask_mask, message) assert message == websocket_mask_masked -def test_websocket_mask_python_empty(): +def test_websocket_mask_python_empty() -> None: message = bytearray() http_websocket._websocket_mask_python( websocket_mask_mask, message) @@ -399,14 +399,14 @@ def test_websocket_mask_python_empty(): @pytest.mark.skipif(not hasattr(http_websocket, '_websocket_mask_cython'), reason='Requires Cython') -def test_websocket_mask_cython_empty(): +def test_websocket_mask_cython_empty() -> None: message = bytearray() http_websocket._websocket_mask_cython( websocket_mask_mask, message) assert message == bytearray() -def test_msgtype_aliases(): +def test_msgtype_aliases() -> None: assert aiohttp.WSMsgType.TEXT == aiohttp.WSMsgType.text assert aiohttp.WSMsgType.BINARY == aiohttp.WSMsgType.binary assert aiohttp.WSMsgType.PING == aiohttp.WSMsgType.ping @@ -416,7 +416,7 @@ def test_msgtype_aliases(): assert aiohttp.WSMsgType.ERROR == aiohttp.WSMsgType.error -def test_parse_compress_frame_single(parser): +def test_parse_compress_frame_single(parser) -> None: parser.parse_frame(struct.pack('!BB', 0b11000001, 0b00000001)) res = parser.parse_frame(b'1') fin, opcode, payload, compress = res[0] @@ -424,7 +424,7 @@ def test_parse_compress_frame_single(parser): assert (1, 1, b'1', True) == (fin, opcode, payload, not not compress) -def test_parse_compress_frame_multi(parser): +def test_parse_compress_frame_multi(parser) -> None: parser.parse_frame(struct.pack('!BB', 0b01000001, 126)) parser.parse_frame(struct.pack('!H', 4)) res = parser.parse_frame(b'1234') @@ -444,7 +444,7 @@ def test_parse_compress_frame_multi(parser): assert (1, 1, b'1234', False) == (fin, opcode, payload, not not compress) -def test_parse_compress_error_frame(parser): +def test_parse_compress_error_frame(parser) -> None: parser.parse_frame(struct.pack('!BB', 0b01000001, 0b00000001)) parser.parse_frame(b'1') @@ -455,7 +455,7 @@ def test_parse_compress_error_frame(parser): assert ctx.value.code == WSCloseCode.PROTOCOL_ERROR -def test_parse_no_compress_frame_single(): +def test_parse_no_compress_frame_single() -> None: parser_no_compress = WebSocketReader(out, 0, compress=False) with pytest.raises(WebSocketError) as ctx: parser_no_compress.parse_frame(struct.pack( @@ -465,7 +465,7 @@ def test_parse_no_compress_frame_single(): assert ctx.value.code == WSCloseCode.PROTOCOL_ERROR -def test_msg_too_large(out): +def test_msg_too_large(out) -> None: parser = WebSocketReader(out, 256, compress=False) data = build_frame(b'text'*256, WSMsgType.TEXT) with pytest.raises(WebSocketError) as ctx: @@ -473,7 +473,7 @@ def test_msg_too_large(out): assert ctx.value.code == WSCloseCode.MESSAGE_TOO_BIG -def test_msg_too_large_not_fin(out): +def test_msg_too_large_not_fin(out) -> None: parser = WebSocketReader(out, 256, compress=False) data = build_frame(b'text'*256, WSMsgType.TEXT, is_fin=False) with pytest.raises(WebSocketError) as ctx: @@ -481,7 +481,7 @@ def test_msg_too_large_not_fin(out): assert ctx.value.code == WSCloseCode.MESSAGE_TOO_BIG -def test_compressed_msg_too_large(out): +def test_compressed_msg_too_large(out) -> None: parser = WebSocketReader(out, 256, compress=True) data = build_frame(b'aaa'*256, WSMsgType.TEXT, compress=True) with pytest.raises(WebSocketError) as ctx: diff --git a/tests/test_websocket_writer.py b/tests/test_websocket_writer.py index 946cf7a..2a25ab1 100644 --- a/tests/test_websocket_writer.py +++ b/tests/test_websocket_writer.py @@ -24,39 +24,39 @@ def writer(protocol, transport): return WebSocketWriter(protocol, transport, use_mask=False) -async def test_pong(writer): +async def test_pong(writer) -> None: await writer.pong() writer.transport.write.assert_called_with(b'\x8a\x00') -async def test_ping(writer): +async def test_ping(writer) -> None: await writer.ping() writer.transport.write.assert_called_with(b'\x89\x00') -async def test_send_text(writer): +async def test_send_text(writer) -> None: await writer.send(b'text') writer.transport.write.assert_called_with(b'\x81\x04text') -async def test_send_binary(writer): +async def test_send_binary(writer) -> None: await writer.send('binary', True) writer.transport.write.assert_called_with(b'\x82\x06binary') -async def test_send_binary_long(writer): +async def test_send_binary_long(writer) -> None: await writer.send(b'b' * 127, True) assert writer.transport.write.call_args[0][0].startswith(b'\x82~\x00\x7fb') -async def test_send_binary_very_long(writer): +async def test_send_binary_very_long(writer) -> None: await writer.send(b'b' * 65537, True) assert (writer.transport.write.call_args_list[0][0][0] == b'\x82\x7f\x00\x00\x00\x00\x00\x01\x00\x01') assert writer.transport.write.call_args_list[1][0][0] == b'b' * 65537 -async def test_close(writer): +async def test_close(writer) -> None: await writer.close(1001, 'msg') writer.transport.write.assert_called_with(b'\x88\x05\x03\xe9msg') @@ -68,7 +68,7 @@ async def test_close(writer): writer.transport.write.assert_called_with(b'\x88\x05\x03\xf4msg') -async def test_send_text_masked(protocol, transport): +async def test_send_text_masked(protocol, transport) -> None: writer = WebSocketWriter(protocol, transport, use_mask=True, @@ -77,7 +77,7 @@ async def test_send_text_masked(protocol, transport): writer.transport.write.assert_called_with(b'\x81\x84\rg\xb3fy\x02\xcb\x12') -async def test_send_compress_text(protocol, transport): +async def test_send_compress_text(protocol, transport) -> None: writer = WebSocketWriter(protocol, transport, compress=15) await writer.send(b'text') writer.transport.write.assert_called_with(b'\xc1\x06*I\xad(\x01\x00') @@ -85,7 +85,7 @@ async def test_send_compress_text(protocol, transport): writer.transport.write.assert_called_with(b'\xc1\x05*\x01b\x00\x00') -async def test_send_compress_text_notakeover(protocol, transport): +async def test_send_compress_text_notakeover(protocol, transport) -> None: writer = WebSocketWriter(protocol, transport, compress=15, @@ -96,7 +96,7 @@ async def test_send_compress_text_notakeover(protocol, transport): writer.transport.write.assert_called_with(b'\xc1\x06*I\xad(\x01\x00') -async def test_send_compress_text_per_message(protocol, transport): +async def test_send_compress_text_per_message(protocol, transport) -> None: writer = WebSocketWriter(protocol, transport) await writer.send(b'text', compress=15) writer.transport.write.assert_called_with(b'\xc1\x06*I\xad(\x01\x00') diff --git a/tests/test_worker.py b/tests/test_worker.py index d385d03..f665243 100644 --- a/tests/test_worker.py +++ b/tests/test_worker.py @@ -63,7 +63,7 @@ def worker(request, loop): return ret -def test_init_process(worker): +def test_init_process(worker) -> None: with mock.patch('aiohttp.worker.asyncio') as m_asyncio: try: worker.init_process() @@ -75,7 +75,7 @@ def test_init_process(worker): assert m_asyncio.set_event_loop.called -def test_run(worker, loop): +def test_run(worker, loop) -> None: worker.log = mock.Mock() worker.cfg = mock.Mock() worker.cfg.access_log_format = ACCEPTABLE_LOG_FORMAT @@ -88,7 +88,7 @@ def test_run(worker, loop): assert loop.is_closed() -def test_run_async_factory(worker, loop): +def test_run_async_factory(worker, loop) -> None: worker.log = mock.Mock() worker.cfg = mock.Mock() worker.cfg.access_log_format = ACCEPTABLE_LOG_FORMAT @@ -106,7 +106,7 @@ def test_run_async_factory(worker, loop): assert loop.is_closed() -def test_handle_quit(worker, loop): +def test_handle_quit(worker, loop) -> None: worker.loop = mock.Mock() worker.handle_quit(object(), object()) assert not worker.alive @@ -115,7 +115,7 @@ def test_handle_quit(worker, loop): 0.1, worker._notify_waiter_done) -def test_handle_abort(worker): +def test_handle_abort(worker) -> None: with mock.patch('aiohttp.worker.sys') as m_sys: worker.handle_abort(object(), object()) assert not worker.alive @@ -123,7 +123,7 @@ def test_handle_abort(worker): m_sys.exit.assert_called_with(1) -def test__wait_next_notify(worker): +def test__wait_next_notify(worker) -> None: worker.loop = mock.Mock() worker._notify_waiter_done = mock.Mock() fut = worker._wait_next_notify() @@ -134,7 +134,7 @@ def test__wait_next_notify(worker): fut) -def test__notify_waiter_done(worker): +def test__notify_waiter_done(worker) -> None: worker._notify_waiter = None worker._notify_waiter_done() assert worker._notify_waiter is None @@ -147,7 +147,7 @@ def test__notify_waiter_done(worker): waiter.set_result.assert_called_with(True) -def test__notify_waiter_done_explicit_waiter(worker): +def test__notify_waiter_done_explicit_waiter(worker) -> None: worker._notify_waiter = None assert worker._notify_waiter is None @@ -161,7 +161,7 @@ def test__notify_waiter_done_explicit_waiter(worker): assert not waiter2.set_result.called -def test_init_signals(worker): +def test_init_signals(worker) -> None: worker.loop = mock.Mock() worker.init_signals() assert worker.loop.add_signal_handler.called @@ -172,17 +172,18 @@ def test_init_signals(worker): (AsyncioWorker.DEFAULT_GUNICORN_LOG_FORMAT, AsyncioWorker.DEFAULT_AIOHTTP_LOG_FORMAT), ]) -def test__get_valid_log_format_ok(worker, source, result): +def test__get_valid_log_format_ok(worker, source, result) -> None: assert result == worker._get_valid_log_format(source) -def test__get_valid_log_format_exc(worker): +def test__get_valid_log_format_exc(worker) -> None: with pytest.raises(ValueError) as exc: worker._get_valid_log_format(WRONG_LOG_FORMAT) assert '%(name)s' in str(exc) -async def test__run_ok_parent_changed(worker, loop, aiohttp_unused_port): +async def test__run_ok_parent_changed(worker, loop, + aiohttp_unused_port) -> None: skip_if_no_dict(loop) worker.ppid = 0 @@ -208,7 +209,7 @@ async def test__run_ok_parent_changed(worker, loop, aiohttp_unused_port): assert worker._runner.server is None -async def test__run_exc(worker, loop, aiohttp_unused_port): +async def test__run_exc(worker, loop, aiohttp_unused_port) -> None: skip_if_no_dict(loop) worker.ppid = os.getppid() @@ -268,7 +269,7 @@ async def test__run_ok_max_requests_exceeded(worker, loop, assert worker._runner.server is None -def test__create_ssl_context_without_certs_and_ciphers(worker): +def test__create_ssl_context_without_certs_and_ciphers(worker) -> None: here = pathlib.Path(__file__).parent worker.cfg.ssl_version = ssl.PROTOCOL_SSLv23 worker.cfg.cert_reqs = ssl.CERT_OPTIONAL @@ -280,7 +281,7 @@ def test__create_ssl_context_without_certs_and_ciphers(worker): assert isinstance(crt, ssl.SSLContext) -def test__create_ssl_context_with_ciphers(worker): +def test__create_ssl_context_with_ciphers(worker) -> None: here = pathlib.Path(__file__).parent worker.cfg.ssl_version = ssl.PROTOCOL_SSLv23 worker.cfg.cert_reqs = ssl.CERT_OPTIONAL @@ -292,7 +293,7 @@ def test__create_ssl_context_with_ciphers(worker): assert isinstance(ctx, ssl.SSLContext) -def test__create_ssl_context_with_ca_certs(worker): +def test__create_ssl_context_with_ca_certs(worker) -> None: here = pathlib.Path(__file__).parent worker.cfg.ssl_version = ssl.PROTOCOL_SSLv23 worker.cfg.cert_reqs = ssl.CERT_OPTIONAL diff --git a/tools/gen.py b/tools/gen.py index 28cf6c3..64e7709 100644 --- a/tools/gen.py +++ b/tools/gen.py @@ -5,7 +5,6 @@ import pathlib from aiohttp import hdrs from collections import defaultdict import io -from pprint import pprint headers = [getattr(hdrs, name) for name in dir(hdrs) @@ -31,7 +30,7 @@ dct = build(headers) HEADER = """\ -/* The file is autogenerated from aiohtt/hdrs.py +/* The file is autogenerated from aiohttp/hdrs.py Run ./tools/gen.py to update it after the origin changing. */ #include "_find_header.h" @@ -136,8 +135,9 @@ def gen(dct): def gen_headers(headers): out = io.StringIO() - out.write("# The file is autogenerated from aiohtt/hdrs.py") + out.write("# The file is autogenerated from aiohttp/hdrs.py\n") out.write("# Run ./tools/gen.py to update it after the origin changing.") + out.write("\n\n") out.write("from . import hdrs\n") out.write("cdef tuple headers = (\n") for hdr in headers: @@ -7,6 +7,7 @@ envlist = check, {py35,py36}-{debug,release}-{cython,pure}, report deps = pytest pytest-mock + pytest-xdist # pytest-cov coverage gunicorn |
