aiohttp-0.20.2/0000775000175000017500000000000012643555674014050 5ustar andrewandrew00000000000000aiohttp-0.20.2/Makefile0000664000175000017500000000331212615252546015476 0ustar andrewandrew00000000000000# Some simple testing tasks (sorry, UNIX only). .install-deps: requirements-dev.txt pip install -U -r requirements-dev.txt touch .install-deps flake: .install-deps # python setup.py check -rms flake8 aiohttp if python -c "import sys; sys.exit(sys.version_info < (3,5))"; then \ flake8 examples tests; \ fi .develop: .install-deps $(shell find aiohttp -type f) pip install -e . touch .develop test: flake .develop py.test -q ./tests/ vtest: flake .develop py.test -s -v ./tests/ cov cover coverage: tox cov-dev: .develop py.test --cov=aiohttp --cov-report=term --cov-report=html tests @echo "open file://`pwd`/coverage/index.html" cov-dev-full: .develop AIOHTTP_NO_EXTENSIONS=1 py.test --cov=aiohttp --cov-append tests PYTHONASYNCIODEBUG=1 py.test --cov=aiohttp --cov-append tests py.test --cov=aiohttp --cov-report=term --cov-report=html tests @echo "open file://`pwd`/coverage/index.html" clean: rm -rf `find . -name __pycache__` rm -f `find . -type f -name '*.py[co]' ` rm -f `find . -type f -name '*~' ` rm -f `find . -type f -name '.*~' ` rm -f `find . -type f -name '@*' ` rm -f `find . -type f -name '#*#' ` rm -f `find . -type f -name '*.orig' ` rm -f `find . -type f -name '*.rej' ` rm -f .coverage rm -rf coverage rm -rf build rm -rf cover make -C docs clean python setup.py clean rm -f aiohttp/_multidict.html rm -f aiohttp/_multidict.c rm -f aiohttp/_multidict.*.so rm -f aiohttp/_multidict.*.pyd rm -rf .tox doc: make -C docs html @echo "open file://`pwd`/docs/_build/html/index.html" doc-spelling: make -C docs spelling install: pip install -U pip pip install -Ur requirements-dev.txt .PHONY: all build venv flake test vtest testloop cov clean doc aiohttp-0.20.2/docs/0000775000175000017500000000000012643555674015000 5ustar andrewandrew00000000000000aiohttp-0.20.2/docs/make.bat0000664000175000017500000001505712552474754016413 0ustar andrewandrew00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\aiohttp.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\aiohttp.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %BUILDDIR%/.. echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %BUILDDIR%/.. echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) :end aiohttp-0.20.2/docs/api.rst0000664000175000017500000000272312617541154016274 0ustar andrewandrew00000000000000.. _aiohttp-api: Helpers API =========== All public names from submodules ``errors``, ``multipart``, ``parsers``, ``protocol``, ``utils``, ``websocket`` and ``wsgi`` are exported into ``aiohttp`` namespace. aiohttp.errors module --------------------- .. automodule:: aiohttp.errors :members: :undoc-members: :show-inheritance: aiohttp.helpers module ---------------------- .. automodule:: aiohttp.helpers :members: :undoc-members: :exclude-members: BasicAuth :show-inheritance: aiohttp.multipart module ------------------------ .. automodule:: aiohttp.multipart :members: :undoc-members: :show-inheritance: aiohttp.parsers module ---------------------- .. automodule:: aiohttp.parsers :members: :undoc-members: :show-inheritance: aiohttp.protocol module ----------------------- .. automodule:: aiohttp.protocol :members: :undoc-members: :show-inheritance: aiohttp.signals module ---------------------- .. automodule:: aiohttp.signals :members: :undoc-members: :show-inheritance: aiohttp.streams module ---------------------- .. automodule:: aiohttp.streams :members: :undoc-members: :show-inheritance: aiohttp.websocket module ------------------------ .. automodule:: aiohttp.websocket :members: :undoc-members: :show-inheritance: aiohttp.wsgi module ------------------- .. automodule:: aiohttp.wsgi :members: :undoc-members: :show-inheritance: .. disqus:: aiohttp-0.20.2/docs/Makefile0000664000175000017500000001533312552474754016443 0ustar andrewandrew00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/aiohttp.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/aiohttp.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/aiohttp" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/aiohttp" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." spelling: $(SPHINXBUILD) -b spelling $(ALLSPHINXOPTS) $(BUILDDIR)/spelling @echo @echo "Build finished." aiohttp-0.20.2/docs/contributing.rst0000664000175000017500000000011212557422311020214 0ustar andrewandrew00000000000000.. _aiohttp-contributing: .. include:: ../CONTRIBUTING.rst .. disqus:: aiohttp-0.20.2/docs/client_reference.rst0000664000175000017500000011004312640010667021006 0ustar andrewandrew00000000000000.. _aiohttp-client-reference: HTTP Client Reference ===================== .. module:: aiohttp .. currentmodule:: aiohttp Client Session -------------- Client session is the recommended interface for making HTTP requests. Session encapsulates *connection pool* (*connector* instance) and supports keepalives by default. Usage example:: import aiohttp import asyncio async def fetch(client): async with client.get('http://python.org') as resp: assert resp.status == 200 print(await resp.text()) with aiohttp.ClientSession() as client: asyncio.get_event_loop().run_until_complete(fetch(client)) .. versionadded:: 0.17 The client session supports context manager protocol for self closing. .. class:: ClientSession(*, connector=None, loop=None, cookies=None,\ headers=None, skip_auto_headers=None, \ auth=None, request_class=ClientRequest,\ response_class=ClientResponse, \ ws_response_class=ClientWebSocketResponse) The class for creating client sessions and making requests. :param aiohttp.connector.BaseConnector connector: BaseConnector sub-class instance to support connection pooling. :param loop: :ref:`event loop` used for processing HTTP requests. If *loop* is ``None`` the constructor borrows it from *connector* if specified. :func:`asyncio.get_event_loop` is used for getting default event loop otherwise. :param dict cookies: Cookies to send with the request (optional) :param headers: HTTP Headers to send with the request (optional). May be either *iterable of key-value pairs* or :class:`~collections.abc.Mapping` (e.g. :class:`dict`, :class:`~aiohttp.CIMultiDict`). :param skip_auto_headers: set of headers for which autogeneration should be skipped. *aiohttp* autogenerates headers like ``User-Agent`` or ``Content-Type`` if these headers are not explicitly passed. Using ``skip_auto_headers`` parameter allows to skip that generation. Note that ``Content-Length`` autogeneration can't be skipped. Iterable of :class:`str` or :class:`~aiohttp.upstr` (optional) :param aiohttp.BasicAuth auth: an object that represents HTTP Basic Authorization (optional) :param request_class: Request class implementation. ``ClientRequest`` by default. :param response_class: Response class implementation. :class:`ClientResponse` by default. :param ws_response_class: WebSocketResponse class implementation. ``ClientWebSocketResponse`` by default. .. versionadded:: 0.16 .. versionchanged:: 0.16 *request_class* default changed from ``None`` to ``ClientRequest`` .. versionchanged:: 0.16 *response_class* default changed from ``None`` to :class:`ClientResponse` .. attribute:: closed ``True`` if the session has been closed, ``False`` otherwise. A read-only property. .. attribute:: connector :class:`aiohttp.connector.BaseConnector` derived instance used for the session. A read-only property. .. attribute:: cookies The session cookies, :class:`http.cookies.SimpleCookie` instance. A read-only property. Overriding `session.cookies = new_val` is forbidden, but you may modify the object in-place if needed. .. coroutinemethod:: request(method, url, *, params=None, data=None,\ headers=None, skip_auto_headers=None, \ auth=None, allow_redirects=True,\ max_redirects=10, encoding='utf-8',\ version=HttpVersion(major=1, minor=1),\ compress=None, chunked=None, expect100=False,\ read_until_eof=True) Performs an asynchronous HTTP request. Returns a response object. :param str method: HTTP method :param str url: Request URL :param params: Mapping, iterable of tuple of *key*/*value* pairs or string to be sent as parameters in the query string of the new request (optional) Allowed values are: - :class:`collections.abc.Mapping` e.g. :class:`dict`, :class:`aiohttp.MultiDict` or :class:`aiohttp.MultiDictProxy` - :class:`collections.abc.Iterable` e.g. :class:`tuple` or :class:`list` - :class:`str` with preferably url-encoded content (**Warning:** content will not be encoded by *aiohttp*) :param data: Dictionary, bytes, or file-like object to send in the body of the request (optional) :param dict headers: HTTP Headers to send with the request (optional) :param skip_auto_headers: set of headers for which autogeneration should be skipped. *aiohttp* autogenerates headers like ``User-Agent`` or ``Content-Type`` if these headers are not explicitly passed. Using ``skip_auto_headers`` parameter allows to skip that generation. Iterable of :class:`str` or :class:`~aiohttp.upstr` (optional) :param aiohttp.BasicAuth auth: an object that represents HTTP Basic Authorization (optional) :param bool allow_redirects: If set to ``False``, do not follow redirects. ``True`` by default (optional). :param aiohttp.protocol.HttpVersion version: Request HTTP version (optional) :param bool compress: Set to ``True`` if request has to be compressed with deflate encoding. ``None`` by default (optional). :param int chunked: Set to chunk size for chunked transfer encoding. ``None`` by default (optional). :param bool expect100: Expect 100-continue response from server. ``False`` by default (optional). :param bool read_until_eof: Read response until EOF if response does not have Content-Length header. ``True`` by default (optional). :return ClientResponse: a :class:`client response ` object. .. coroutinemethod:: get(url, *, allow_redirects=True, **kwargs) Perform a ``GET`` request. In order to modify inner :meth:`request` parameters, provide `kwargs`. :param str url: Request URL :param bool allow_redirects: If set to ``False``, do not follow redirects. ``True`` by default (optional). :return ClientResponse: a :class:`client response ` object. .. coroutinemethod:: post(url, *, data=None, **kwargs) Perform a ``POST`` request. In order to modify inner :meth:`request` parameters, provide `kwargs`. :param str url: Request URL :param data: Dictionary, bytes, or file-like object to send in the body of the request (optional) :return ClientResponse: a :class:`client response ` object. .. coroutinemethod:: put(url, *, data=None, **kwargs) Perform a ``PUT`` request. In order to modify inner :meth:`request` parameters, provide `kwargs`. :param str url: Request URL :param data: Dictionary, bytes, or file-like object to send in the body of the request (optional) :return ClientResponse: a :class:`client response ` object. .. coroutinemethod:: delete(url, **kwargs) Perform a ``DELETE`` request. In order to modify inner :meth:`request` parameters, provide `kwargs`. :param str url: Request URL :return ClientResponse: a :class:`client response ` object. .. coroutinemethod:: head(url, *, allow_redirects=False, **kwargs) Perform a ``HEAD`` request. In order to modify inner :meth:`request` parameters, provide `kwargs`. :param str url: Request URL :param bool allow_redirects: If set to ``False``, do not follow redirects. ``False`` by default (optional). :return ClientResponse: a :class:`client response ` object. .. coroutinemethod:: options(url, *, allow_redirects=True, **kwargs) Perform an ``OPTIONS`` request. In order to modify inner :meth:`request` parameters, provide `kwargs`. :param str url: Request URL :param bool allow_redirects: If set to ``False``, do not follow redirects. ``True`` by default (optional). :return ClientResponse: a :class:`client response ` object. .. coroutinemethod:: patch(url, *, data=None, **kwargs) Perform a ``PATCH`` request. In order to modify inner :meth:`request` parameters, provide `kwargs`. :param str url: Request URL :param data: Dictionary, bytes, or file-like object to send in the body of the request (optional) :return ClientResponse: a :class:`client response ` object. .. coroutinemethod:: ws_connect(url, *, protocols=(), timeout=10.0,\ auth=None,\ autoclose=True,\ autoping=True,\ origin=None) Create a websocket connection. Returns a :class:`ClientWebSocketResponse` object. :param str url: Websocket server url :param tuple protocols: Websocket protocols :param float timeout: Timeout for websocket read. 10 seconds by default :param aiohttp.BasicAuth auth: an object that represents HTTP Basic Authorization (optional) :param bool autoclose: Automatically close websocket connection on close message from server. If `autoclose` is False them close procedure has to be handled manually :param bool autoping: automatically send `pong` on `ping` message from server :param str origin: Origin header to send to server .. versionadded:: 0.16 Add :meth:`ws_connect`. .. versionadded:: 0.18 Add *auth* parameter. .. versionadded:: 0.19 Add *origin* parameter. .. method:: close() Close underlying connector. Release all acquired resources. .. method:: detach() Detach connector from session without closing the former. Session is switched to closed state anyway. Basic API --------- While we encourage :class:`ClientSession` usage we also provide simple coroutines for making HTTP requests. Basic API is good for performing simple HTTP requests without keepaliving, cookies and complex connection stuff like properly configured SSL certification chaining. .. coroutinefunction:: request(method, url, *, params=None, data=None, \ headers=None, cookies=None, auth=None, \ allow_redirects=True, max_redirects=10, \ encoding='utf-8', \ version=HttpVersion(major=1, minor=1), \ compress=None, chunked=None, expect100=False, \ connector=None, loop=None,\ read_until_eof=True, request_class=None,\ response_class=None) Perform an asynchronous HTTP request. Return a response object (:class:`ClientResponse` or derived from). :param str method: HTTP method :param str url: Requested URL :param dict params: Parameters to be sent in the query string of the new request (optional) :param data: Dictionary, bytes, or file-like object to send in the body of the request (optional) :param dict headers: HTTP Headers to send with the request (optional) :param dict cookies: Cookies to send with the request (optional) :param aiohttp.BasicAuth auth: an object that represents HTTP Basic Authorization (optional) :param bool allow_redirects: If set to ``False``, do not follow redirects. ``True`` by default (optional). :param aiohttp.protocol.HttpVersion version: Request HTTP version (optional) :param bool compress: Set to ``True`` if request has to be compressed with deflate encoding. ``False`` instructs aiohttp to not compress data even if the Content-Encoding header is set. Use it when sending pre-compressed data. ``None`` by default (optional). :param int chunked: Set to chunk size for chunked transfer encoding. ``None`` by default (optional). :param bool expect100: Expect 100-continue response from server. ``False`` by default (optional). :param aiohttp.connector.BaseConnector connector: BaseConnector sub-class instance to support connection pooling. :param bool read_until_eof: Read response until EOF if response does not have Content-Length header. ``True`` by default (optional). :param request_class: Custom Request class implementation (optional) :param response_class: Custom Response class implementation (optional) :param loop: :ref:`event loop` used for processing HTTP requests. If param is ``None``, :func:`asyncio.get_event_loop` is used for getting default event loop, but we strongly recommend to use explicit loops everywhere. (optional) :return ClientResponse: a :class:`client response ` object. Usage:: import aiohttp async def fetch(): async with aiohttp.request('GET', 'http://python.org/') as resp: assert resp.status == 200 print(await resp.text()) .. coroutinefunction:: get(url, **kwargs) Perform a GET request. :param str url: Requested URL. :param \*\*kwargs: Optional arguments that :func:`request` takes. :return: :class:`ClientResponse` or derived from .. coroutinefunction:: options(url, **kwargs) Perform a OPTIONS request. :param str url: Requested URL. :param \*\*kwargs: Optional arguments that :func:`request` takes. :return: :class:`ClientResponse` or derived from .. coroutinefunction:: head(url, **kwargs) Perform a HEAD request. :param str url: Requested URL. :param \*\*kwargs: Optional arguments that :func:`request` takes. :return: :class:`ClientResponse` or derived from .. coroutinefunction:: delete(url, **kwargs) Perform a DELETE request. :param str url: Requested URL. :param \*\*kwargs: Optional arguments that :func:`request` takes. :return: :class:`ClientResponse` or derived from .. coroutinefunction:: post(url, *, data=None, **kwargs) Perform a POST request. :param str url: Requested URL. :param \*\*kwargs: Optional arguments that :func:`request` takes. :return: :class:`ClientResponse` or derived from .. coroutinefunction:: put(url, *, data=None, **kwargs) Perform a PUT request. :param str url: Requested URL. :param \*\*kwargs: Optional arguments that :func:`request` takes. :return: :class:`ClientResponse` or derived from .. coroutinefunction:: patch(url, *, data=None, **kwargs) Perform a PATCH request. :param str url: Requested URL. :param \*\*kwargs: Optional arguments that :func:`request` takes. :return: :class:`ClientResponse` or derived from .. coroutinefunction:: ws_connect(url, *, protocols=(), \ timeout=10.0, connector=None, auth=None,\ ws_response_class=ClientWebSocketResponse,\ autoclose=True, autoping=True, loop=None,\ origin=None, headers=None) This function creates a websocket connection, checks the response and returns a :class:`ClientWebSocketResponse` object. In case of failure it may raise a :exc:`~aiohttp.errors.WSServerHandshakeError` exception. :param str url: Websocket server url :param tuple protocols: Websocket protocols :param float timeout: Timeout for websocket read. 10 seconds by default :param obj connector: object :class:`TCPConnector` :param ws_response_class: WebSocketResponse class implementation. ``ClientWebSocketResponse`` by default. .. versionadded:: 0.16 :param bool autoclose: Automatically close websocket connection on close message from server. If `autoclose` is False them close procedure has to be handled manually :param bool autoping: Automatically send `pong` on `ping` message from server :param aiohttp.helpers.BasicAuth auth: BasicAuth named tuple that represents HTTP Basic Authorization (optional) :param loop: :ref:`event loop` used for processing HTTP requests. If param is ``None`` :func:`asyncio.get_event_loop` used for getting default event loop, but we strongly recommend to use explicit loops everywhere. :param str origin: Origin header to send to server :param headers: :class:`dict`, :class:`CIMultiDict` or :class:`CIMultiDictProxy` for providing additional headers for websocket handshake request. .. versionadded:: 0.18 Add *auth* parameter. .. versionadded:: 0.19 Add *origin* parameter. .. versionadded:: 0.20 Add *headers* parameter. Connectors ---------- Connectors are transports for aiohttp client API. There are standard connectors: 1. :class:`TCPConnector` for regular *TCP sockets* (both *HTTP* and *HTTPS* schemes supported). 2. :class:`ProxyConnector` for connecting via HTTP proxy. 3. :class:`UnixConnector` for connecting via UNIX socket (it's used mostly for testing purposes). All connector classes should be derived from :class:`BaseConnector`. By default all *connectors* except :class:`ProxyConnector` support *keep-alive connections* (behavior is controlled by *force_close* constructor's parameter). BaseConnector ^^^^^^^^^^^^^ .. class:: BaseConnector(*, conn_timeout=None, keepalive_timeout=30, \ limit=None, \ share_cookies=False, force_close=False, loop=None) Base class for all connectors. :param float conn_timeout: timeout for connection establishing (optional). Values ``0`` or ``None`` mean no timeout. :param float keepalive_timeout: timeout for connection reusing after releasing (optional). Values ``0`` or ``None`` mean no timeout. :param int limit: limit for simultaneous connections to the same endpoint. Endpoints are the same if they are have equal ``(host, port, is_ssl)`` triple. If *limit* is ``None`` the connector has no limit. :param bool share_cookies: update :attr:`cookies` on connection processing (optional, deprecated). :param bool force_close: do close underlying sockets after connection releasing (optional). :param loop: :ref:`event loop` used for handling connections. If param is ``None``, :func:`asyncio.get_event_loop` is used for getting default event loop, but we strongly recommend to use explicit loops everywhere. (optional) .. deprecated:: 0.15.2 *share_cookies* parameter is deprecated, use :class:`~aiohttp.client.ClientSession` for handling cookies for client connections. .. attribute:: closed Read-only property, ``True`` if connector is closed. .. attribute:: force_close Read-only property, ``True`` if connector should ultimately close connections on releasing. .. versionadded:: 0.16 .. attribute:: limit The limit for simultaneous connections to the same endpoint. Endpoints are the same if they are have equal ``(host, port, is_ssl)`` triple. If *limit* is ``None`` the connector has no limit (default). Read-only property. .. versionadded:: 0.16 .. method:: close() Close all opened connections. .. coroutinemethod:: connect(request) Get a free connection from pool or create new one if connection is absent in the pool. The call may be paused if :attr:`limit` is exhausted until used connections returns to pool. :param aiohttp.client.ClientRequest request: request object which is connection initiator. :return: :class:`Connection` object. .. coroutinemethod:: _create_connection(req) Abstract method for actual connection establishing, should be overridden in subclasses. TCPConnector ^^^^^^^^^^^^ .. class:: TCPConnector(*, verify_ssl=True, fingerprint=None,\ use_dns_cache=False, \ family=0, \ ssl_context=None, conn_timeout=None, \ keepalive_timeout=30, limit=None, share_cookies=False, \ force_close=False, loop=None) Connector for working with *HTTP* and *HTTPS* via *TCP* sockets. The most common transport. When you don't know what connector type to use, use a :class:`TCPConnector` instance. :class:`TCPConnector` inherits from :class:`BaseConnector`. Constructor accepts all parameters suitable for :class:`BaseConnector` plus several TCP-specific ones: :param bool verify_ssl: Perform SSL certificate validation for *HTTPS* requests (enabled by default). May be disabled to skip validation for sites with invalid certificates. :param bytes fingerprint: Pass the binary MD5, SHA1, or SHA256 digest of the expected certificate in DER format to verify that the certificate the server presents matches. Useful for `certificate pinning `_. .. versionadded:: 0.16 :param bool use_dns_cache: use internal cache for DNS lookups, ``False`` by default. Enabling an option *may* speedup connection establishing a bit but may introduce some *side effects* also. .. versionadded:: 0.17 :param bool resolve: alias for *use_dns_cache* parameter. .. deprecated:: 0.17 :param int family: TCP socket family, both IPv4 and IPv6 by default. For *IPv4* only use :const:`socket.AF_INET`, for *IPv6* only -- :const:`socket.AF_INET6`. .. versionchanged:: 0.18 *family* is `0` by default, that means both IPv4 and IPv6 are accepted. To specify only concrete version please pass :const:`socket.AF_INET` or :const:`socket.AF_INET6` explicitly. :param ssl.SSLContext ssl_context: ssl context used for processing *HTTPS* requests (optional). *ssl_context* may be used for configuring certification authority channel, supported SSL options etc. .. attribute:: verify_ssl Check *ssl certifications* if ``True``. Read-only :class:`bool` property. .. attribute:: ssl_context :class:`ssl.SSLContext` instance for *https* requests, read-only property. .. attribute:: family *TCP* socket family e.g. :const:`socket.AF_INET` or :const:`socket.AF_INET6` Read-only property. .. attribute:: dns_cache Use quick lookup in internal *DNS* cache for host names if ``True``. Read-only :class:`bool` property. .. versionadded:: 0.17 .. attribute:: resolve Alias for :attr:`dns_cache`. .. deprecated:: 0.17 .. attribute:: cached_hosts The cache of resolved hosts if :attr:`dns_cache` is enabled. Read-only :class:`types.MappingProxyType` property. .. versionadded:: 0.17 .. attribute:: resolved_hosts Alias for :attr:`cached_hosts` .. deprecated:: 0.17 .. attribute:: fingerprint MD5, SHA1, or SHA256 hash of the expected certificate in DER format, or ``None`` if no certificate fingerprint check required. Read-only :class:`bytes` property. .. versionadded:: 0.16 .. method:: clear_dns_cache(self, host=None, port=None) Clear internal *DNS* cache. Remove specific entry if both *host* and *port* are specified, clear all cache otherwise. .. versionadded:: 0.17 .. method:: clear_resolved_hosts(self, host=None, port=None) Alias for :meth:`clear_dns_cache`. .. deprecated:: 0.17 ProxyConnector ^^^^^^^^^^^^^^ .. class:: ProxyConnector(proxy, *, proxy_auth=None, \ conn_timeout=None, \ keepalive_timeout=30, limit=None, \ share_cookies=False, \ force_close=True, loop=None) HTTP Proxy connector. Use :class:`ProxyConnector` for sending *HTTP/HTTPS* requests through *HTTP proxy*. :class:`ProxyConnector` is inherited from :class:`TCPConnector`. Usage:: conn == ProxyConnector(proxy="http://some.proxy.com") session = ClientSession(connector=conn) async with session.get('http://python.org') as resp: assert resp.status == 200 Constructor accepts all parameters suitable for :class:`TCPConnector` plus several proxy-specific ones: :param str proxy: URL for proxy, e.g. ``"http://some.proxy.com"``. :param aiohttp.BasicAuth proxy_auth: basic authentication info used for proxies with authorization. .. note:: :class:`ProxyConnector` in opposite to all other connectors **doesn't** support *keep-alives* by default (:attr:`force_close` is ``True``). .. versionchanged:: 0.16 *force_close* parameter changed to ``True`` by default. .. attribute:: proxy Proxy *URL*, read-only :class:`str` property. .. attribute:: proxy_auth Proxy authentication info, read-only :class:`BasicAuth` property or ``None`` for proxy without authentication. .. versionadded:: 0.16 UnixConnector ^^^^^^^^^^^^^ .. class:: UnixConnector(path, *, \ conn_timeout=None, \ keepalive_timeout=30, limit=None, \ share_cookies=False, \ force_close=False, loop=None) Unix socket connector. Use :class:`ProxyConnector` for sending *HTTP/HTTPS* requests through *UNIX Sockets* as underlying transport. UNIX sockets are handy for writing tests and making very fast connections between processes on the same host. :class:`UnixConnector` is inherited from :class:`BaseConnector`. Usage:: conn = UnixConnector(path='/path/to/socket') session = ClientSession(connector=conn) async with session.get('http://python.org') as resp: ... Constructor accepts all parameters suitable for :class:`BaseConnector` plus UNIX-specific one: :param str path: Unix socket path .. attribute:: path Path to *UNIX socket*, read-only :class:`str` property. Connection ^^^^^^^^^^ .. class:: Connection Encapsulates single connection in connector object. End user should never create :class:`Connection` instances manually but get it by :meth:`BaseConnector.connect` coroutine. .. attribute:: closed :class:`bool` read-only property, ``True`` if connection was closed, released or detached. .. attribute:: loop Event loop used for connection .. method:: close() Close connection with forcibly closing underlying socket. .. method:: release() Release connection back to connector. Underlying socket is not closed, the connection may be reused 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 --------------- .. class:: ClientResponse Client response returned be :meth:`ClientSession.request` and family. User never creates the instance of ClientResponse class but gets it from API calls. :class:`ClientResponse` supports async context manager protocol, e.g.:: resp = await client_session.get(url) async with resp: assert resp.status == 200 After exiting from ``async with`` block response object will be *released* (see :meth:`release` coroutine). .. versionadded:: 0.18 Support for ``async with``. .. attribute:: version Response's version, :class:`HttpVersion` instance. .. attribute:: status HTTP status code of response (:class:`int`), e.g. ``200``. .. attribute:: reason HTTP status reason of response (:class:`str`), e.g. ``"OK"``. .. attribute:: connection :class:`Connection` used for handling response. .. attribute:: content Payload stream, contains response's BODY (:class:`StreamReader` compatible instance, most likely :class:`FlowControlStreamReader` one). .. attribute:: cookies HTTP cookies of response (*Set-Cookie* HTTP header, :class:`~http.cookies.SimpleCookie`). .. attribute:: headers HTTP headers of response, :class:`CIMultiDictProxy`. .. attribute:: history A :class:`~collections.abc.Sequence` of :class:`ClientResponse` objects of preceding requests if there were redirects, an empty sequence otherwise. .. method:: close() Close response and underlying connection. For :term:`keep-alive` support see :meth:`release`. .. coroutinemethod:: read() Read the whole response's body as :class:`bytes`. Close underlying connection if data reading gets an error, release connection otherwise. :return bytes: read *BODY*. .. seealso:: :meth:`close`, :meth:`release`. .. coroutinemethod:: release() Finish response processing, release underlying connection and return it into free connection pool for re-usage by next upcoming request. .. coroutinemethod:: text(encoding=None) Read response's body and return decoded :class:`str` using specified *encoding* parameter. If *encoding* is ``None`` content encoding is autocalculated using :term:`cchardet` or :term:`chardet` as fallback if *cchardet* is not available. Close underlying connection if data reading gets an error, release connection otherwise. :param str encoding: text encoding used for *BODY* decoding, or ``None`` for encoding autodetection (default). :return str: decoded *BODY* .. coroutinemethod:: json(encoding=None, loads=json.loads) Read response's body as *JSON*, return :class:`dict` using specified *encoding* and *loader*. If *encoding* is ``None`` content encoding is autocalculated using :term:`cchardet` or :term:`chardet` as fallback if *cchardet* is not available. Close underlying connection if data reading gets an error, release connection otherwise. :param str encoding: text encoding used for *BODY* decoding, or ``None`` for encoding autodetection (default). :param callable loads: :func:`callable` used for loading *JSON* data, :func:`json.loads` by default. :return: *BODY* as *JSON* data parsed by *loads* parameter or ``None`` if *BODY* is empty or contains white-spaces only. ClientWebSocketResponse ----------------------- To connect to a websocket server :func:`aiohttp.ws_connect` or :meth:`aiohttp.ClientSession.ws_connect` coroutines should be used, do not create an instance of class :class:`ClientWebSocketResponse` manually. .. class:: ClientWebSocketResponse() Class for handling client-side websockets. .. attribute:: closed Read-only property, ``True`` if :meth:`close` has been called of :const:`~aiohttp.websocket.MSG_CLOSE` message has been received from peer. .. attribute:: protocol Websocket *subprotocol* chosen after :meth:`start` call. May be ``None`` if server and client protocols are not overlapping. .. method:: exception() Returns exception if any occurs or returns None. .. method:: ping(message=b'') Send :const:`~aiohttp.websocket.MSG_PING` to peer. :param message: optional payload of *ping* message, :class:`str` (converted to *UTF-8* encoded bytes) or :class:`bytes`. .. method:: send_str(data) Send *data* to peer as :const:`~aiohttp.websocket.MSG_TEXT` message. :param str data: data to send. :raise TypeError: if data is not :class:`str` .. method:: send_bytes(data) Send *data* to peer as :const:`~aiohttp.websocket.MSG_BINARY` message. :param data: data to send. :raise TypeError: if data is not :class:`bytes`, :class:`bytearray` or :class:`memoryview`. .. coroutinemethod:: close(*, code=1000, message=b'') A :ref:`coroutine` that initiates closing handshake by sending :const:`~aiohttp.websocket.MSG_CLOSE` message. It waits for close response from server. It add timeout to `close()` call just wrap call with `asyncio.wait()` or `asyncio.wait_for()`. :param int code: closing code :param message: optional payload of *pong* message, :class:`str` (converted to *UTF-8* encoded bytes) or :class:`bytes`. .. coroutinemethod:: receive() A :ref:`coroutine` that waits upcoming *data* message from peer and returns it. The coroutine implicitly handles :const:`~aiohttp.websocket.MSG_PING`, :const:`~aiohttp.websocket.MSG_PONG` and :const:`~aiohttp.websocket.MSG_CLOSE` without returning the message. It process *ping-pong game* and performs *closing handshake* internally. :return: :class:`~aiohttp.websocket.Message`, `tp` is types of `~aiohttp.MsgType` Utilities --------- BasicAuth ^^^^^^^^^ .. class:: BasicAuth(login, password='', encoding='latin1') HTTP basic authentication helper. :param str login: login :param str password: password :param str encoding: encoding (`'latin1'` by default) Should be used for specifying authorization data in client API, e.g. *auth* parameter for :meth:`ClientSession.request`. .. method:: encode() Encode credentials into string suitable for ``Authorization`` header etc. :return: encoded authentication data, :class:`str`. .. disqus:: aiohttp-0.20.2/docs/spelling_wordlist.txt0000664000175000017500000000104412622021727021264 0ustar andrewandrew00000000000000aiohttp async autocalculated autodetection autogeneration autogenerates basename cchardet cChardet charset charsetdetect criterias css ctor Ctrl Dict dict eof fallback github google gunicorn Gunicorn Indices IP IPv ish iterable iterables javascript json keepalive keepalives keepaliving middleware middlewares multidict Multidicts multipart Multipart Nikolay param params pre proxied pyenv refactored regex regexs repo subprotocol subprotocols Svetlov toolbar un upstr url urlencoded urls utf websocket websockets Websockets wildcard Workflow wsgi aiohttp-0.20.2/docs/changes.rst0000664000175000017500000000007112552474754017136 0ustar andrewandrew00000000000000.. include:: ../CHANGES.txt .. include:: ../HISTORY.rst aiohttp-0.20.2/docs/multidict.rst0000664000175000017500000002310312627010435017506 0ustar andrewandrew00000000000000.. _aiohttp-multidict: ============ Multidicts ============ .. module:: aiohttp *HTTP Headers* and *URL query string* require specific data structure: *multidict*. It behaves mostly like a :class:`dict` but it can have several *values* for the same *key*. :mod:`aiohttp` has four multidict classes: :class:`MultiDict`, :class:`MultiDictProxy`, :class:`CIMultiDict` and :class:`CIMultiDictProxy`. Immutable proxies (:class:`MultiDictProxy` and :class:`CIMultiDictProxy`) provide a dynamic view on the proxied multidict, the view reflects the multidict changes. They implement the :class:`~collections.abc.Mapping` interface. Regular mutable (:class:`MultiDict` and :class:`CIMultiDict`) classes implement :class:`~collections.abc.MutableMapping` and allows to change their own content. *Case insensitive* (:class:`CIMultiDict` and :class:`CIMultiDictProxy`) ones assumes the *keys* are case insensitive, e.g.:: >>> dct = CIMultiDict(a='val') >>> 'A' in dct True >>> dct['A'] 'val' *Keys* should be a :class:`str`. MultiDict ========= .. class:: MultiDict(**kwargs) MultiDict(mapping, **kwargs) MultiDict(iterable, **kwargs) Creates a mutable multidict instance. Accepted parameters are the same as for :class:`dict`. If the same key appears several times it will be added, e.g.:: >>> d = MultiDict[('a', 1), ('b', 2), ('a', 3)]) >>> d .. method:: len(d) Return the number of items in multidict *d*. .. method:: d[key] Return the **first** item of *d* with key *key*. Raises a :exc:`KeyError` if key is not in the multidict. .. method:: d[key] = value Set ``d[key]`` to *value*. Replace all items where key is equal to *key* with single item ``(key, value)``. .. method:: del d[key] Remove all items where key is equal to *key* from *d*. Raises a :exc:`KeyError` if *key* is not in the map. .. method:: key in d Return ``True`` if d has a key *key*, else ``False``. .. method:: key not in d Equivalent to ``not (key in d)`` .. method:: iter(d) Return an iterator over the keys of the dictionary. This is a shortcut for ``iter(d.keys())``. .. method:: add(key, value) Append ``(key, value)`` pair to the dictionary. .. method:: clear() Remove all items from the dictionary. .. method:: copy() Return a shallow copy of the dictionary. .. method:: extend([other]) Extend the dictionary with the key/value pairs from *other*, overwriting existing keys. Return ``None``. :meth:`extend` accepts either another dictionary object or an iterable of key/value pairs (as tuples or other iterables of length two). If keyword arguments are specified, the dictionary is then extended with those key/value pairs: ``d.extend(red=1, blue=2)``. .. method:: getone(key[, default]) Return the **first** value for *key* if *key* is in the dictionary, else *default*. Raises :exc:`KeyError` if *default* is not given and *key* is not found. ``d[key]`` is equivalent to ``d.getone(key)``. .. method:: getall(key[, default]) Return a list of all values for *key* if *key* is in the dictionary, else *default*. Raises :exc:`KeyError` if *default* is not given and *key* is not found. .. method:: get(key[, default]) Return the **first** value for *key* if *key* is in the dictionary, else *default*. If *default* is not given, it defaults to ``None``, so that this method never raises a :exc:`KeyError`. ``d.get(key)`` is equivalent to ``d.getone(key, None)``. .. method:: keys() Return a new view of the dictionary's keys. View contains all keys, possibly with duplicates. .. method:: items() Return a new view of the dictionary's items (``(key, value)`` pairs). View contains all items, multiple items can have the same key. .. method:: values() Return a new view of the dictionary's values. View contains all values. .. method:: pop(key[, default]) If *key* is in the dictionary, remove it and return its the **first** value, else return *default*. If *default* is not given and *key* is not in the dictionary, a :exc:`KeyError` is raised. .. method:: popitem() Remove and return an arbitrary ``(key, value)`` pair from the dictionary. :meth:`popitem` is useful to destructively iterate over a dictionary, as often used in set algorithms. If the dictionary is empty, calling :meth:`popitem` raises a :exc:`KeyError`. .. method:: setdefault(key[, default]) If *key* is in the dictionary, return its the **first** value. If not, insert *key* with a value of *default* and return *default*. *default* defaults to ``None``. .. method:: update([other]) Update the dictionary with the key/value pairs from *other*, overwriting existing keys. Return ``None``. :meth:`update` accepts either another dictionary object or an iterable of key/value pairs (as tuples or other iterables of length two). If keyword arguments are specified, the dictionary is then updated with those key/value pairs: ``d.update(red=1, blue=2)``. .. seealso:: :class:`MultiDictProxy` can be used to create a read-only view of a :class:`MultiDict`. CIMultiDict =========== .. class:: CIMultiDict(**kwargs) CIMultiDict(mapping, **kwargs) CIMultiDict(iterable, **kwargs) Create a case insensitive multidict instance. The behavior is the same as of :class:`MultiDict` but key comparisons are case insensitive, e.g.:: >>> dct = CIMultiDict(a='val') >>> 'A' in dct True >>> dct['A'] 'val' >>> dct['a'] 'val' >>> dct['b'] = 'new val' >>> dct['B'] 'new val' The class is inherited from :class:`MultiDict`. .. seealso:: :class:`CIMultiDictProxy` can be used to create a read-only view of a :class:`CIMultiDict`. MultiDictProxy ============== .. class:: MultiDictProxy(multidict) Create an immutable multidict proxy. It provides a dynamic view on the multidict’s entries, which means that when the multidict changes, the view reflects these changes. Raises :exc:`TypeError` is *multidict* is not :class:`MultiDict` instance. .. method:: len(d) Return number of items in multidict *d*. .. method:: d[key] Return the **first** item of *d* with key *key*. Raises a :exc:`KeyError` if key is not in the multidict. .. method:: key in d Return ``True`` if d has a key *key*, else ``False``. .. method:: key not in d Equivalent to ``not (key in d)`` .. method:: iter(d) Return an iterator over the keys of the dictionary. This is a shortcut for ``iter(d.keys())``. .. method:: copy() Return a shallow copy of the underlying multidict. .. method:: getone(key[, default]) Return the **first** value for *key* if *key* is in the dictionary, else *default*. Raises :exc:`KeyError` if *default* is not given and *key* is not found. ``d[key]`` is equivalent to ``d.getone(key)``. .. method:: getall(key[, default]) Return a list of all values for *key* if *key* is in the dictionary, else *default*. Raises :exc:`KeyError` if *default* is not given and *key* is not found. .. method:: get(key[, default]) Return the **first** value for *key* if *key* is in the dictionary, else *default*. If *default* is not given, it defaults to ``None``, so that this method never raises a :exc:`KeyError`. ``d.get(key)`` is equivalent to ``d.getone(key, None)``. .. method:: keys() Return a new view of the dictionary's keys. View contains all keys, possibly with duplicates. .. method:: items() Return a new view of the dictionary's items (``(key, value)`` pairs). View contains all items, multiple items can have the same key. .. method:: values() Return a new view of the dictionary's values. View contains all values. CIMultiDictProxy ================ .. class:: CIMultiDictProxy(multidict) Case insensitive version of :class:`MultiDictProxy`. Raises :exc:`TypeError` is *multidict* is not :class:`CIMultiDict` instance. The class is inherited from :class:`MultiDict`. upstr ===== :class:`CIMultiDict` accepts :class:`str` as *key* argument for dict lookups but converts it to upper case internally. For more effective processing it should know if the *key* is already upper cased. To skip the :meth:`~str.upper()` call you may want to create upper cased strings by hand, e.g:: >>> key = upstr('Key') >>> key 'KEY' >>> mdict = CIMultiDict(key='value') >>> key in mdict True >>> mdict[key] 'value' For performance you should create :class:`upstr` strings once and store them globally, like :mod:`aiohttp.hdrs` does. .. class:: upstr(object='') upstr(bytes_or_buffer[, encoding[, errors]]) Create a new **upper cased** string object from the given *object*. If *encoding* or *errors* are specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of ``object.__str__()`` (if defined) or ``repr(object)``. *encoding* defaults to ``sys.getdefaultencoding()``. *errors* defaults to ``'strict'``. The class is inherited from :class:`str` and has all regular string methods. .. disqus:: aiohttp-0.20.2/docs/gunicorn.rst0000664000175000017500000000605512613146237017350 0ustar andrewandrew00000000000000Deployment using Gunicorn ========================= aiohttp can be deployed using `Gunicorn `_, which is based on a pre-fork worker model. Gunicorn launches your app as worker processes for handling incoming requests. Prepare environment ------------------- You firstly need to setup your deployment environment. This example is based on Ubuntu 14.04. Create a directory for your application:: >> mkdir myapp >> cd myapp Ubuntu has a bug in pyenv, so to create virtualenv you need to do some extra manipulation:: >> pyvenv-3.4 --without-pip venv >> source venv/bin/activate >> curl https://bootstrap.pypa.io/get-pip.py | python >> deactivate >> source venv/bin/activate Now that the virtual environment is ready, we'll proceed to install aiohttp and gunicorn:: >> pip install gunicorn >> pip install -e git+https://github.com/KeepSafe/aiohttp.git#egg=aiohttp Application ----------- Lets write a simple application, which we will save to file. We'll name this file *my_app_module.py*: .. code-block:: python from aiohttp import web def index(request): return web.Response(text="Welcome home!") my_web_app = web.Application() my_web_app.router.add_route('GET', '/', index) Start Gunicorn -------------- When `Running Gunicorn `_, you provide the name of the module, i.e. *my_app_module*, and the name of the app, i.e. *my_web_app*, along with other `Gunicorn Settings `_ provided as command line flags or in your config file. In this case, we will use: * the *'--bind'* flag to set the server's socket address; * the *'--worker-class'* flag to tell Gunicorn that we want to use a custom worker subclass instead of one of the Gunicorn default worker types; * you may also want to use the *'--workers'* flag to tell Gunicorn how many worker processes to use for handling requests. (See the documentation for recommendations on `How Many Workers? `_) The custom worker subclass is defined in *aiohttp.worker.GunicornWebWorker* and should be used instead of the *gaiohttp* worker provided by Gunicorn, which supports only aiohttp.wsgi applications:: >> gunicorn my_app_module:my_web_app --bind localhost:8080 --worker-class aiohttp.worker.GunicornWebWorker [2015-03-11 18:27:21 +0000] [1249] [INFO] Starting gunicorn 19.3.0 [2015-03-11 18:27:21 +0000] [1249] [INFO] Listening at: http://127.0.0.1:8080 (1249) [2015-03-11 18:27:21 +0000] [1249] [INFO] Using worker: aiohttp.worker.GunicornWebWorker [2015-03-11 18:27:21 +0000] [1253] [INFO] Booting worker with pid: 1253 Gunicorn is now running and ready to serve requests to your app's worker processes. More information ---------------- The Gunicorn documentation recommends deploying Gunicorn behind a Nginx proxy server. See the `official documentation `_ for more information about suggested nginx configuration. .. disqus:: aiohttp-0.20.2/docs/logging.rst0000664000175000017500000000744312641572325017156 0ustar andrewandrew00000000000000.. _aiohttp-logging: Logging ======= .. currentmodule:: aiohttp *aiohttp* uses standard :mod:`logging` for tracking the library activity. We have the following loggers enumerated by names: - ``'aiohttp.client'`` - ``'aiohttp.internal'`` - ``'aiohttp.server'`` - ``'aiohttp.web'`` - ``'aiohttp.websocket'`` You may subscribe to these loggers for getting logging messages. The page does not provide instructions for logging subscribing while the most friendly method is :func:`logging.config.dictConfig` for configuring whole loggers in your application. Access logs ----------- Access log is enabled by specifying *access_log* parameter (:class:`logging.Logger` instance) on :meth:`aiohttp.web.Application.make_handler` call. Optional *access_log_format* parameter may be used for specifying log format (see below). .. note:: Access log is disabled by default. Format specification. The library provides custom micro-language to specifying info about request and response: +--------------+---------------------------------------------------------+ | Option | Meaning | +==============+=========================================================+ | ``%%`` | 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, excluding HTTP headers | +--------------+---------------------------------------------------------+ | ``%O`` | Bytes sent, including headers | +--------------+---------------------------------------------------------+ | ``%T`` | The time taken to serve the request, in seconds | +--------------+---------------------------------------------------------+ | ``%Tf`` | The time taken to serve the request, in seconds | | | with fraction in %.06f format | +--------------+---------------------------------------------------------+ | ``%D`` | The time taken to serve the request, in microseconds | +--------------+---------------------------------------------------------+ | ``%{FOO}i`` | ``request.headers['FOO']`` | +--------------+---------------------------------------------------------+ | ``%{FOO}o`` | ``response.headers['FOO']`` | +--------------+---------------------------------------------------------+ | ``%{FOO}e`` | ``os.environ['FOO']`` | +--------------+---------------------------------------------------------+ Default access log format is:: '%a %l %u %t "%r" %s %b "%{Referrer}i" "%{User-Agent}i"' Error logs ---------- *aiohttp.web* uses logger named ``'aiohttp.server'`` to store errors given on web requests handling. The log is always enabled. To use different logger name please specify *logger* parameter (:class:`logging.Logger` instance) on performing :meth:`aiohttp.web.Application.make_handler` call. aiohttp-0.20.2/docs/web_reference.rst0000664000175000017500000012774112643552137020330 0ustar andrewandrew00000000000000.. _aiohttp-web-reference: HTTP Server Reference ===================== .. module:: aiohttp.web .. currentmodule:: aiohttp.web .. _aiohttp-web-request: Request ------- The Request object contains all the information about an incoming HTTP request. Every :ref:`handler` accepts a request instance as the first positional parameter. A :class:`Request` is a :obj:`dict`-like object, allowing it to be used for :ref:`sharing data` among :ref:`aiohttp-web-middlewares` and :ref:`aiohttp-web-signals` handlers. Although :class:`Request` is :obj:`dict`-like object, it can't be duplicated like one using :meth:`Request.copy`. .. note:: You should never create the :class:`Request` instance manually -- :mod:`aiohttp.web` does it for you. .. class:: Request .. attribute:: scheme A string representing the scheme of the request. The scheme is ``'https'`` if transport for request handling is *SSL* or ``secure_proxy_ssl_header`` is matching. ``'http'`` otherwise. Read-only :class:`str` property. .. attribute:: method *HTTP method*, read-only property. The value is upper-cased :class:`str` like ``"GET"``, ``"POST"``, ``"PUT"`` etc. .. attribute:: version *HTTP version* of request, Read-only property. Returns :class:`aiohttp.protocol.HttpVersion` instance. .. attribute:: host *HOST* header of request, Read-only property. Returns :class:`str` or ``None`` if HTTP request has no *HOST* header. .. attribute:: path_qs The URL including PATH_INFO and the query string. e.g, ``/app/blog?id=10`` Read-only :class:`str` property. .. attribute:: path The URL including *PATH INFO* without the host or scheme. e.g., ``/app/blog``. The path is URL-unquoted. For raw path info see :attr:`raw_path`. Read-only :class:`str` property. .. attribute:: raw_path The URL including raw *PATH INFO* without the host or scheme. Warning, the path may be quoted and may contains non valid URL characters, e.g. ``/my%2Fpath%7Cwith%21some%25strange%24characters``. For unquoted version please take a look on :attr:`path`. Read-only :class:`str` property. .. attribute:: query_string The query string in the URL, e.g., ``id=10`` Read-only :class:`str` property. .. attribute:: GET A multidict with all the variables in the query string. Read-only :class:`~aiohttp.MultiDictProxy` lazy property. .. versionchanged:: 0.17 A multidict contains empty items for query string like ``?arg=``. .. attribute:: POST A multidict with all the variables in the POST parameters. POST property available only after :meth:`Request.post` coroutine call. Read-only :class:`~aiohttp.MultiDictProxy`. :raises RuntimeError: if :meth:`Request.post` was not called \ before accessing the property. .. attribute:: headers A case-insensitive multidict proxy with all headers. Read-only :class:`~aiohttp.CIMultiDictProxy` property. .. attribute:: keep_alive ``True`` if keep-alive connection enabled by HTTP client and protocol version supports it, otherwise ``False``. Read-only :class:`bool` property. .. attribute:: match_info Read-only property with :class:`~aiohttp.abc.AbstractMatchInfo` instance for result of route resolving. .. note:: Exact type of property depends on used router. If ``app.router`` is :class:`UrlDispatcher` the property contains :class:`UrlMappingMatchInfo` instance. .. attribute:: app An :class:`Application` instance used to call :ref:`request handler `, Read-only property. .. attribute:: transport An :ref:`transport` used to process request, Read-only property. The property can be used, for example, for getting IP address of client's peer:: peername = request.transport.get_extra_info('peername') if peername is not None: host, port = peername .. attribute:: cookies A multidict of all request's cookies. Read-only :class:`~aiohttp.MultiDictProxy` lazy property. .. attribute:: content A :class:`~aiohttp.streams.FlowControlStreamReader` instance, input stream for reading request's *BODY*. Read-only property. .. versionadded:: 0.15 .. attribute:: has_body Return ``True`` if request has *HTTP BODY*, ``False`` otherwise. Read-only :class:`bool` property. .. versionadded:: 0.16 .. attribute:: payload A :class:`~aiohttp.streams.FlowControlStreamReader` instance, input stream for reading request's *BODY*. Read-only property. .. deprecated:: 0.15 Use :attr:`~Request.content` instead. .. attribute:: content_type Read-only property with *content* part of *Content-Type* header. Returns :class:`str` like ``'text/html'`` .. note:: Returns value is ``'application/octet-stream'`` if no Content-Type header present in HTTP headers according to :rfc:`2616` .. attribute:: charset Read-only property that specifies the *encoding* for the request's BODY. The value is parsed from the *Content-Type* HTTP header. Returns :class:`str` like ``'utf-8'`` or ``None`` if *Content-Type* has no charset information. .. attribute:: content_length Read-only property that returns length of the request's BODY. The value is parsed from the *Content-Length* HTTP header. Returns :class:`int` or ``None`` if *Content-Length* is absent. .. attribute:: if_modified_since Read-only property that returns the date specified in the *If-Modified-Since* header. Returns :class:`datetime.datetime` or ``None`` if *If-Modified-Since* header is absent or is not a valid HTTP date. .. coroutinemethod:: read() Read request body, returns :class:`bytes` object with body content. .. note:: The method **does** store read data internally, subsequent :meth:`~Request.read` call will return the same value. .. coroutinemethod:: text() Read request body, decode it using :attr:`charset` encoding or ``UTF-8`` if no encoding was specified in *MIME-type*. Returns :class:`str` with body content. .. note:: The method **does** store read data internally, subsequent :meth:`~Request.text` call will return the same value. .. coroutinemethod:: json(*, loader=json.loads) Read request body decoded as *json*. The method is just a boilerplate :ref:`coroutine ` implemented as:: async def json(self, *, loader=json.loads): body = await self.text() return loader(body) :param callable loader: any :term:`callable` that accepts :class:`str` and returns :class:`dict` with parsed JSON (:func:`json.loads` by default). .. note:: The method **does** store read data internally, subsequent :meth:`~Request.json` call will return the same value. .. coroutinemethod:: post() A :ref:`coroutine ` that reads POST parameters from request body. Returns :class:`~aiohttp.MultiDictProxy` instance filled with parsed data. If :attr:`method` is not *POST*, *PUT* or *PATCH* or :attr:`content_type` is not empty or *application/x-www-form-urlencoded* or *multipart/form-data* returns empty multidict. .. note:: The method **does** store read data internally, subsequent :meth:`~Request.post` call will return the same value. .. coroutinemethod:: release() Release request. Eat unread part of HTTP BODY if present. .. note:: User code may never call :meth:`~Request.release`, all required work will be processed by :mod:`aiohttp.web` internal machinery. .. _aiohttp-web-response: Response classes ---------------- For now, :mod:`aiohttp.web` has two classes for the *HTTP response*: :class:`StreamResponse` and :class:`Response`. Usually you need to use the second one. :class:`StreamResponse` is intended for streaming data, while :class:`Response` contains *HTTP BODY* as an attribute and sends own content as single piece with the correct *Content-Length HTTP header*. For sake of design decisions :class:`Response` is derived from :class:`StreamResponse` parent class. The response supports *keep-alive* handling out-of-the-box if *request* supports it. You can disable *keep-alive* by :meth:`~StreamResponse.force_close` though. The common case for sending an answer from :ref:`web-handler` is returning a :class:`Response` instance:: def handler(request): return Response("All right!") StreamResponse ^^^^^^^^^^^^^^ .. class:: StreamResponse(*, status=200, reason=None) The base class for the *HTTP response* handling. Contains methods for setting *HTTP response headers*, *cookies*, *response status code*, writing *HTTP response BODY* and so on. The most important thing you should know about *response* --- it is *Finite State Machine*. That means you can do any manipulations with *headers*, *cookies* and *status code* only before :meth:`prepare` coroutine is called. Once you call :meth:`prepare` any change of the *HTTP header* part will raise :exc:`RuntimeError` exception. Any :meth:`write` call after :meth:`write_eof` is also forbidden. :param int status: HTTP status code, ``200`` by default. :param str reason: HTTP reason. If param is ``None`` reason will be calculated basing on *status* parameter. Otherwise pass :class:`str` with arbitrary *status* explanation.. .. attribute:: prepared Read-only :class:`bool` property, ``True`` if :meth:`prepare` has been called, ``False`` otherwise. .. versionadded:: 0.18 .. attribute:: started Deprecated alias for :attr:`prepared`. .. deprecated:: 0.18 .. attribute:: status Read-only property for *HTTP response status code*, :class:`int`. ``200`` (OK) by default. .. attribute:: reason Read-only property for *HTTP response reason*, :class:`str`. .. method:: set_status(status, reason=None) Set :attr:`status` and :attr:`reason`. *reason* value is auto calculated if not specified (``None``). .. attribute:: keep_alive Read-only property, copy of :attr:`Request.keep_alive` by default. Can be switched to ``False`` by :meth:`force_close` call. .. method:: force_close Disable :attr:`keep_alive` for connection. There are no ways to enable it back. .. attribute:: compression Read-only :class:`bool` property, ``True`` if compression is enabled. ``False`` by default. .. versionadded:: 0.14 .. seealso:: :meth:`enable_compression` .. method:: enable_compression(force=None) Enable compression. When *force* is unset compression encoding is selected based on the request's *Accept-Encoding* header. *Accept-Encoding* is not checked if *force* is set to a :class:`ContentCoding`. .. versionadded:: 0.14 .. seealso:: :attr:`compression` .. attribute:: chunked Read-only property, indicates if chunked encoding is on. Can be enabled by :meth:`enable_chunked_encoding` call. .. versionadded:: 0.14 .. seealso:: :attr:`enable_chunked_encoding` .. method:: enable_chunked_encoding Enables :attr:`chunked` encoding for response. There are no ways to disable it back. With enabled :attr:`chunked` encoding each `write()` operation encoded in separate chunk. .. versionadded:: 0.14 .. warning:: chunked encoding can be enabled for ``HTTP/1.1`` only. Setting up both :attr:`content_length` and chunked encoding is mutually exclusive. .. seealso:: :attr:`chunked` .. attribute:: headers :class:`~aiohttp.CIMultiDict` instance for *outgoing* *HTTP headers*. .. attribute:: cookies An instance of :class:`http.cookies.SimpleCookie` for *outgoing* cookies. .. warning:: Direct setting up *Set-Cookie* header may be overwritten by explicit calls to cookie manipulation. We are encourage using of :attr:`cookies` and :meth:`set_cookie`, :meth:`del_cookie` for cookie manipulations. .. method:: set_cookie(name, value, *, path='/', expires=None, \ domain=None, max_age=None, \ secure=None, httponly=None, version=None) Convenient way for setting :attr:`cookies`, allows to specify some additional properties like *max_age* in a single call. :param str name: cookie name :param str value: cookie value (will be converted to :class:`str` if value has another type). :param expires: expiration date (optional) :param str domain: cookie domain (optional) :param int max_age: defines the lifetime of the cookie, in seconds. The delta-seconds value is a decimal non- negative integer. After delta-seconds seconds elapse, the client should discard the cookie. A value of zero means the cookie should be discarded immediately. (optional) :param str path: specifies the subset of URLs to which this cookie applies. (optional, ``'/'`` by default) :param bool secure: attribute (with no value) directs the user agent to use only (unspecified) secure means to contact the origin server whenever it sends back this cookie. The user agent (possibly under the user's control) may determine what level of security it considers appropriate for "secure" cookies. The *secure* should be considered security advice from the server to the user agent, indicating that it is in the session's interest to protect the cookie contents. (optional) :param bool httponly: ``True`` if the cookie HTTP only (optional) :param int version: a decimal integer, identifies to which version of the state management specification the cookie conforms. (Optional, *version=1* by default) .. versionchanged:: 0.14.3 Default value for *path* changed from ``None`` to ``'/'``. .. method:: del_cookie(name, *, path='/', domain=None) Deletes cookie. :param str name: cookie name :param str domain: optional cookie domain :param str path: optional cookie path, ``'/'`` by default .. versionchanged:: 0.14.3 Default value for *path* changed from ``None`` to ``'/'``. .. attribute:: content_length *Content-Length* for outgoing response. .. attribute:: content_type *Content* part of *Content-Type* for outgoing response. .. attribute:: charset *Charset* aka *encoding* part of *Content-Type* for outgoing response. The value converted to lower-case on attribute assigning. .. attribute:: last_modified *Last-Modified* header for outgoing response. This property accepts raw :class:`str` values, :class:`datetime.datetime` objects, Unix timestamps specified as an :class:`int` or a :class:`float` object, and the value ``None`` to unset the header. .. attribute:: tcp_cork :const:`~socket.TCP_CORK` (linux) or :const:`~socket.TCP_NOPUSH` (FreeBSD and MacOSX) is applied to underlying transport if the property is ``True``. Use :meth:`set_tcp_cork` to assign new value to the property. Default value is ``False``. .. method:: set_tcp_cork(value) Set :attr:`tcp_cork` property to *value*. Clear :attr:`tcp_nodelay` if *value* is ``True``. .. attribute:: tcp_nodelay :const:`~socket.TCP_NODELAY` is applied to underlying transport if the property is ``True``. Use :meth:`set_tcp_nodelay` to assign new value to the property. Default value is ``True``. .. method:: set_tcp_nodelay(value) Set :attr:`tcp_nodelay` property to *value*. Clear :attr:`tcp_cork` if *value* is ``True``. .. method:: start(request) :param aiohttp.web.Request request: HTTP request object, that the response answers. Send *HTTP header*. You should not change any header data after calling this method. .. deprecated:: 0.18 Use :meth:`prepare` instead. .. warning:: The method doesn't call :attr:`web.Application.on_response_prepare` signal, use :meth:`prepare` instead. .. coroutinemethod:: prepare(request) :param aiohttp.web.Request request: HTTP request object, that the response answers. Send *HTTP header*. You should not change any header data after calling this method. The coroutine calls :attr:`web.Application.on_response_prepare` signal handlers. .. versionadded:: 0.18 .. method:: write(data) Send byte-ish data as the part of *response BODY*. :meth:`prepare` must be called before. Raises :exc:`TypeError` if data is not :class:`bytes`, :class:`bytearray` or :class:`memoryview` instance. Raises :exc:`RuntimeError` if :meth:`prepare` has not been called. Raises :exc:`RuntimeError` if :meth:`write_eof` has been called. .. coroutinemethod:: drain() A :ref:`coroutine` to let the write buffer of the underlying transport a chance to be flushed. The intended use is to write:: resp.write(data) await resp.drain() Yielding from :meth:`drain` gives the opportunity for the loop to schedule the write operation and flush the buffer. It should especially be used when a possibly large amount of data is written to the transport, and the coroutine does not yield-from between calls to :meth:`write`. .. versionadded:: 0.14 .. coroutinemethod:: write_eof() A :ref:`coroutine` *may* be called as a mark of the *HTTP response* processing finish. *Internal machinery* will call this method at the end of the request processing if needed. After :meth:`write_eof` call any manipulations with the *response* object are forbidden. Response ^^^^^^^^ .. class:: Response(*, status=200, headers=None, content_type=None, \ charset=None, \ body=None, text=None) The most usable response class, inherited from :class:`StreamResponse`. Accepts *body* argument for setting the *HTTP response BODY*. The actual :attr:`body` sending happens in overridden :meth:`~StreamResponse.write_eof`. :param bytes body: response's BODY :param int status: HTTP status code, 200 OK by default. :param collections.abc.Mapping headers: HTTP headers that should be added to response's ones. :param str text: response's BODY :param str content_type: response's content type. ``'text/plain'`` if *text* is passed also, ``'application/octet-stream'`` otherwise. :param str charset: response's charset. ``'utf-8'`` if *text* is passed also, ``None`` otherwise. .. attribute:: body Read-write attribute for storing response's content aka BODY, :class:`bytes`. Setting :attr:`body` also recalculates :attr:`~StreamResponse.content_length` value. Resetting :attr:`body` (assigning ``None``) sets :attr:`~StreamResponse.content_length` to ``None`` too, dropping *Content-Length* HTTP header. .. attribute:: text Read-write attribute for storing response's content, represented as str, :class:`str`. Setting :attr:`str` also recalculates :attr:`~StreamResponse.content_length` value and :attr:`~StreamResponse.body` value Resetting :attr:`body` (assigning ``None``) sets :attr:`~StreamResponse.content_length` to ``None`` too, dropping *Content-Length* HTTP header. WebSocketResponse ^^^^^^^^^^^^^^^^^ .. class:: WebSocketResponse(*, timeout=10.0, autoclose=True, \ autoping=True, protocols=()) Class for handling server-side websockets, inherited from :class:`StreamResponse`. After starting (by :meth:`prepare` call) the response you cannot use :meth:`~StreamResponse.write` method but should to communicate with websocket client by :meth:`send_str`, :meth:`receive` and others. .. versionadded:: 0.19 The class supports ``async for`` statement for iterating over incoming messages:: ws = web.WebSocketResponse() await ws.prepare(request) async for msg in ws: print(msg.data) .. coroutinemethod:: prepare(request) Starts websocket. After the call you can use websocket methods. :param aiohttp.web.Request request: HTTP request object, that the response answers. :raises HTTPException: if websocket handshake has failed. .. versionadded:: 0.18 .. method:: start(request) Starts websocket. After the call you can use websocket methods. :param aiohttp.web.Request request: HTTP request object, that the response answers. :raises HTTPException: if websocket handshake has failed. .. deprecated:: 0.18 Use :meth:`prepare` instead. .. method:: can_prepare(request) Performs checks for *request* data to figure out if websocket can be started on the request. If :meth:`can_prepare` call is success then :meth:`prepare` will success too. :param aiohttp.web.Request request: HTTP request object, that the response answers. :return: ``(ok, protocol)`` pair, *ok* is ``True`` on success, *protocol* is websocket subprotocol which is passed by client and accepted by server (one of *protocols* sequence from :class:`WebSocketResponse` ctor). *protocol* may be ``None`` if client and server subprotocols are nit overlapping. .. note:: The method never raises exception. .. method:: can_start(request) Deprecated alias for :meth:`can_prepare` .. deprecated:: 0.18 .. attribute:: closed Read-only property, ``True`` if connection has been closed or in process of closing. :const:`~aiohttp.websocket.MSG_CLOSE` message has been received from peer. .. attribute:: close_code Read-only property, close code from peer. It is set to ``None`` on opened connection. .. attribute:: protocol Websocket *subprotocol* chosen after :meth:`start` call. May be ``None`` if server and client protocols are not overlapping. .. method:: exception() Returns last occurred exception or None. .. method:: ping(message=b'') Send :const:`~aiohttp.websocket.MSG_PING` to peer. :param message: optional payload of *ping* message, :class:`str` (converted to *UTF-8* encoded bytes) or :class:`bytes`. :raise RuntimeError: if connections is not started or closing. .. method:: pong(message=b'') Send *unsolicited* :const:`~aiohttp.websocket.MSG_PONG` to peer. :param message: optional payload of *pong* message, :class:`str` (converted to *UTF-8* encoded bytes) or :class:`bytes`. :raise RuntimeError: if connections is not started or closing. .. method:: send_str(data) Send *data* to peer as :const:`~aiohttp.websocket.MSG_TEXT` message. :param str data: data to send. :raise RuntimeError: if connection is not started or closing :raise TypeError: if data is not :class:`str` .. method:: send_bytes(data) Send *data* to peer as :const:`~aiohttp.websocket.MSG_BINARY` message. :param data: data to send. :raise RuntimeError: if connection is not started or closing :raise TypeError: if data is not :class:`bytes`, :class:`bytearray` or :class:`memoryview`. .. coroutinemethod:: close(*, code=1000, message=b'') A :ref:`coroutine` that initiates closing handshake by sending :const:`~aiohttp.websocket.MSG_CLOSE` message. :param int code: closing code :param message: optional payload of *pong* message, :class:`str` (converted to *UTF-8* encoded bytes) or :class:`bytes`. :raise RuntimeError: if connection is not started or closing .. coroutinemethod:: receive() A :ref:`coroutine` that waits upcoming *data* message from peer and returns it. The coroutine implicitly handles :const:`~aiohttp.websocket.MSG_PING`, :const:`~aiohttp.websocket.MSG_PONG` and :const:`~aiohttp.websocket.MSG_CLOSE` without returning the message. It process *ping-pong game* and performs *closing handshake* internally. After websocket closing raises :exc:`~aiohttp.errors.WSClientDisconnectedError` with connection closing data. :return: :class:`~aiohttp.websocket.Message` :raise RuntimeError: if connection is not started :raise: :exc:`~aiohttp.errors.WSClientDisconnectedError` on closing. .. coroutinemethod:: receive_str() A :ref:`coroutine` that calls :meth:`receive_mgs` but also asserts the message type is :const:`~aiohttp.websocket.MSG_TEXT`. :return str: peer's message content. :raise TypeError: if message is :const:`~aiohttp.websocket.MSG_BINARY`. .. coroutinemethod:: receive_bytes() A :ref:`coroutine` that calls :meth:`receive_mgs` but also asserts the message type is :const:`~aiohttp.websocket.MSG_BINARY`. :return bytes: peer's message content. :raise TypeError: if message is :const:`~aiohttp.websocket.MSG_TEXT`. .. versionadded:: 0.14 .. seealso:: :ref:`WebSockets handling` json_response ------------- .. function:: json_response([data], *, text=None, body=None, \ status=200, reason=None, headers=None, \ content_type='application/json', \ dumps=json.dumps) Return :class:`Response` with predefined ``'application/json'`` content type and *data* encoded by *dumps* parameter (:func:`json.dumps` by default). .. _aiohttp-web-app-and-router: Application and Router ---------------------- Application ^^^^^^^^^^^ Application is a synonym for web-server. To get fully working example, you have to make *application*, register supported urls in *router* and create a *server socket* with :class:`aiohttp.RequestHandlerFactory` as a *protocol factory*. *RequestHandlerFactory* could be constructed with :meth:`make_handler`. *Application* contains a *router* instance and a list of callbacks that will be called during application finishing. :class:`Application` is a :obj:`dict`-like object, so you can use it for :ref:`sharing data` globally by storing arbitrary properties for later access from a :ref:`handler` via the :attr:`Request.app` property:: app = Application(loop=loop) app['database'] = await aiopg.create_engine(**db_config) async def handler(request): with (await request.app['database']) as conn: conn.execute("DELETE * FROM table") Although :class:`Application` is a :obj:`dict`-like object, it can't be duplicated like one using :meth:`Application.copy`. .. class:: Application(*, loop=None, router=None, logger=, \ middlewares=(), **kwargs) The class inherits :class:`dict`. :param loop: :ref:`event loop` used for processing HTTP requests. If param is ``None`` :func:`asyncio.get_event_loop` used for getting default event loop, but we strongly recommend to use explicit loops everywhere. :param router: :class:`aiohttp.abc.AbstractRouter` instance, the system creates :class:`UrlDispatcher` by default if *router* is ``None``. :param logger: :class:`logging.Logger` instance for storing application logs. By default the value is ``logging.getLogger("aiohttp.web")`` :param middlewares: :class:`list` of middleware factories, see :ref:`aiohttp-web-middlewares` for details. .. versionadded:: 0.13 .. attribute:: router Read-only property that returns *router instance*. .. attribute:: logger :class:`logging.Logger` instance for storing application logs. .. attribute:: loop :ref:`event loop` used for processing HTTP requests. .. attribute:: on_response_prepare A :class:`~aiohttp.signals.Signal` that is fired at the beginning of :meth:`StreamResponse.prepare` with parameters *request* and *response*. It can be used, for example, to add custom headers to each response before sending. Signal handlers should have the following signature:: async def handler(request, response): pass .. method:: make_handler(**kwargs) Creates HTTP protocol factory for handling requests. :param kwargs: additional parameters for :class:`RequestHandlerFactory` constructor. You should pass result of the method as *protocol_factory* to :meth:`~BaseEventLoop.create_server`, e.g.:: loop = asyncio.get_event_loop() app = Application(loop=loop) # setup route table # app.router.add_route(...) await loop.create_server(app.make_handler(), '0.0.0.0', 8080) .. coroutinemethod:: finish() A :ref:`coroutine` that should be called after server stopping. This method executes functions registered by :meth:`register_on_finish` in LIFO order. If callback raises an exception, the error will be stored by :meth:`~asyncio.BaseEventLoop.call_exception_handler` with keys: *message*, *exception*, *application*. .. method:: register_on_finish(self, func, *args, **kwargs): Register *func* as a function to be executed at termination. Any optional arguments that are to be passed to *func* must be passed as arguments to :meth:`register_on_finish`. It is possible to register the same function and arguments more than once. During the call of :meth:`finish` all functions registered are called in last in, first out order. *func* may be either regular function or :ref:`coroutine`, :meth:`finish` will un-yield (`await`) the later. .. note:: Application object has :attr:`router` attribute but has no ``add_route()`` method. The reason is: we want to support different router implementations (even maybe not url-matching based but traversal ones). For sake of that fact we have very trivial ABC for :class:`AbstractRouter`: it should have only :meth:`AbstractRouter.resolve` coroutine. No methods for adding routes or route reversing (getting URL by route name). All those are router implementation details (but, sure, you need to deal with that methods after choosing the router for your application). RequestHandlerFactory ^^^^^^^^^^^^^^^^^^^^^ RequestHandlerFactory is responsible for creating HTTP protocol objects that can handle HTTP connections. .. attribute:: connections List of all currently opened connections. .. method:: finish_connections(timeout) A :ref:`coroutine` that should be called to close all opened connections. Router ^^^^^^ For dispatching URLs to :ref:`handlers` :mod:`aiohttp.web` uses *routers*. Router is any object that implements :class:`AbstractRouter` interface. :mod:`aiohttp.web` provides an implementation called :class:`UrlDispatcher`. :class:`Application` uses :class:`UrlDispatcher` as :meth:`router` by default. .. class:: UrlDispatcher() Straightforward url-matching router, implements :class:`collections.abc.Mapping` for access to *named routes*. Before running :class:`Application` you should fill *route table* first by calling :meth:`add_route` and :meth:`add_static`. :ref:`Handler` lookup is performed by iterating on added *routes* in FIFO order. The first matching *route* will be used to call corresponding *handler*. If on route creation you specify *name* parameter the result is *named route*. *Named route* can be retrieved by ``app.router[name]`` call, checked for existence by ``name in app.router`` etc. .. seealso:: :ref:`Route classes ` .. method:: add_route(method, path, handler, *, \ name=None, expect_handler=None) Append :ref:`handler` to the end of route table. *path* may be either *constant* string like ``'/a/b/c'`` or *variable rule* like ``'/a/{var}'`` (see :ref:`handling variable pathes`) Pay attention please: *handler* is converted to coroutine internally when it is a regular function. :param str method: HTTP method for route. Should be one of ``'GET'``, ``'POST'``, ``'PUT'``, ``'DELETE'``, ``'PATCH'``, ``'HEAD'``, ``'OPTIONS'`` or ``'*'`` for any method. The parameter is case-insensitive, e.g. you can push ``'get'`` as well as ``'GET'``. :param str path: route path. Should be started with slash (``'/'``). :param callable handler: route handler. :param str name: optional route name. :param coroutine expect_handler: optional *expect* header handler. :returns: new :class:`PlainRoute` or :class:`DynamicRoute` instance. .. method:: add_static(prefix, path, *, name=None, expect_handler=None, \ chunk_size=256*1024, response_factory=StreamResponse) Adds a router and a handler for returning static files. Useful for serving static content like images, javascript and css files. On platforms that support it, the handler will transfer files more efficiently using the ``sendfile`` system call. In some situations it might be necessary to avoid using the ``sendfile`` system call even if the platform supports it. This can be accomplished by by setting environment variable ``AIOHTTP_NOSENDFILE=1``. .. warning:: Use :meth:`add_static` for development only. In production, static content should be processed by web servers like *nginx* or *apache*. .. versionchanged:: 0.18.0 Transfer files using the ``sendfile`` system call on supported platforms. .. versionchanged:: 0.19.0 Disable ``sendfile`` by setting environment variable ``AIOHTTP_NOSENDFILE=1`` :param str prefix: URL path prefix for handled static files :param str path: path to the folder in file system that contains handled static files. :param str name: optional route name. :param coroutine expect_handler: optional *expect* header handler. :param int chunk_size: size of single chunk for file downloading, 256Kb by default. Increasing *chunk_size* parameter to, say, 1Mb may increase file downloading speed but consumes more memory. .. versionadded:: 0.16 :param callable response_factory: factory to use to generate a new response, defaults to :class:`StreamResponse` and should expose a compatible API. .. versionadded:: 0.17 :returns: new :class:`StaticRoute` instance. .. coroutinemethod:: resolve(requst) A :ref:`coroutine` that returns :class:`AbstractMatchInfo` for *request*. The method never raises exception, but returns :class:`AbstractMatchInfo` instance with: 1. :attr:`~AbstractMatchInfo.route` assigned to :class:`SystemRoute` instance 2. :attr:`~AbstractMatchInfo.handler` which raises :exc:`HTTPNotFound` or :exc:`HTTPMethodNotAllowed` on handler's execution if there is no registered route for *request*. *Middlewares* can process that exceptions to render pretty-looking error page for example. Used by internal machinery, end user unlikely need to call the method. .. note:: The method uses :attr:`Request.raw_path` for pattern matching against registered routes. .. versionchanged:: 0.14 The method don't raise :exc:`HTTPNotFound` and :exc:`HTTPMethodNotAllowed` anymore. .. method:: routes() The method returns a *view* for *all* registered routes. The view is an object that allows to: 1. Get size of the router table:: len(app.router.routes()) 2. Iterate over registered routes:: for route in app.router.routes(): print(route) 3. Make a check if the route is registered in the router table:: route in app.router.routes() .. versionadded:: 0.18 .. method:: named_routes() Returns a :obj:`dict`-like :class:`types.MappingProxyType` *view* over *all* named routes. The view maps every named route's :attr:`Route.name` attribute to the :class:`Route`. It supports the usual :obj:`dict`-like operations, except for any mutable operations (i.e. it's **read-only**):: len(app.router.named_routes()) for name, route in app.router.named_routes().items(): print(name, route) "route_name" in app.router.named_routes() app.router.named_routes()["route_name"] .. versionadded:: 0.19 .. _aiohttp-web-route: Route ^^^^^ Default router :class:`UrlDispatcher` operates with *routes*. User should not instantiate route classes by hand but can give *named route instance* by ``router[name]`` if he have added route by :meth:`UrlDispatcher.add_route` or :meth:`UrlDispatcher.add_static` calls with non-empty *name* parameter. The main usage of *named routes* is constructing URL by route name for passing it into *template engine* for example:: url = app.router['route_name'].url(query={'a': 1, 'b': 2}) There are three concrete route classes: * :class:`PlainRoute` for urls without :ref:`variable pathes` spec. * :class:`DynamicRoute` for urls with :ref:`variable pathes` spec. * :class:`StaticRoute` for static file handlers. .. class:: Route Base class for routes served by :class:`UrlDispatcher`. .. attribute:: method HTTP method handled by the route, e.g. *GET*, *POST* etc. .. attribute:: handler :ref:`handler` that processes the route. .. attribute:: name Name of the route. .. method:: match(path) Abstract method, accepts *URL path* and returns :class:`dict` with parsed *path parts* for :class:`UrlMappingMatchInfo` or ``None`` if the route cannot handle given *path*. The method exists for internal usage, end user unlikely need to call it. .. method:: url(*, query=None, **kwargs) Abstract method for constructing url handled by the route. *query* is a mapping or list of *(name, value)* pairs for specifying *query* part of url (parameter is processed by :func:`~urllib.parse.urlencode`). Other available parameters depends on concrete route class and described in descendant classes. .. class:: PlainRoute The route class for handling plain *URL path*, e.g. ``"/a/b/c"`` .. method:: url(*, parts, query=None) Construct url, doesn't accepts extra parameters:: >>> route.url(query={'d': 1, 'e': 2}) '/a/b/c/?d=1&e=2' .. class:: DynamicRoute The route class for handling :ref:`variable path`, e.g. ``"/a/{name1}/{name2}"`` .. method:: url(*, parts, query=None) Construct url with given *dynamic parts*:: >>> route.url(parts={'name1': 'b', 'name2': 'c'}, query={'d': 1, 'e': 2}) '/a/b/c/?d=1&e=2' .. class:: StaticRoute The route class for handling static files, created by :meth:`UrlDispatcher.add_static` call. .. method:: url(*, filename, query=None) Construct url for given *filename*:: >>> route.url(filename='img/logo.png', query={'param': 1}) '/path/to/static/img/logo.png?param=1' .. class:: SystemRoute The route class for internal purposes. Now it has used for handling *404: Not Found* and *405: Method Not Allowed*. .. method:: url() Always raises :exc:`RuntimeError`, :class:`SystemRoute` should not be used in url construction expressions. MatchInfo ^^^^^^^^^ After route matching web application calls found handler if any. Matching result can be accessible from handler as :attr:`Request.match_info` attribute. In general the result may be any object derived from :class:`AbstractMatchInfo` (:class:`UrlMappingMatchInfo` for default :class:`UrlDispatcher` router). .. class:: UrlMappingMatchInfo Inherited from :class:`dict` and :class:`AbstractMatchInfo`. Dict items are given from :meth:`Route.match` call return value. .. attribute:: route :class:`Route` instance for url matching. View ^^^^ .. class:: View(request) Inherited from :class:`AbstractView`. Base class for class based views. Implementations should derive from :class:`View` and override methods for handling HTTP verbs like ``get()`` or ``post()``:: class MyView(View): async def get(self): resp = await get_response(self.request) return resp async def post(self): resp = await post_response(self.request) return resp app.router.add_route('*', '/view', MyView) The view raises *405 Method Not allowed* (:class:`HTTPMEthodNowAllowed`) if requested web verb is not supported. :param request: instance of :class:`Request` that has initiated a view processing. .. attribute:: request Request sent to view's constructor, read-only property. Overridable coroutine methods: ``connect()``, ``delete()``, ``get()``, ``head()``, ``options()``, ``patch()``, ``post()``, ``put()``, ``trace()``. .. seealso:: :ref:`aiohttp-web-class-based-views` Utilities --------- .. class:: FileField A :class:`~collections.namedtuple` instance that is returned as multidict value by :meth:`Request.POST` if field is uploaded file. .. attribute:: name Field name .. attribute:: filename File name as specified by uploading (client) side. .. attribute:: file An :class:`io.IOBase` instance with content of uploaded file. .. attribute:: content_type *MIME type* of uploaded file, ``'text/plain'`` by default. .. seealso:: :ref:`aiohttp-web-file-upload` Constants --------- .. class:: ContentCoding An :class:`enum.Enum` class of available Content Codings. .. attribute:: deflate *DEFLATE compression* .. attribute:: gzip *GZIP comression* .. attribute:: identity *no comression* .. disqus:: aiohttp-0.20.2/docs/conf.py0000664000175000017500000002364512642247712016277 0ustar andrewandrew00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # aiohttp documentation build configuration file, created by # sphinx-quickstart on Wed Mar 5 12:35:35 2014. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys import os import codecs import re _docs_path = os.path.dirname(__file__) _version_path = os.path.abspath(os.path.join(_docs_path, '..', 'aiohttp', '__init__.py')) with codecs.open(_version_path, 'r', 'latin1') as fp: try: _version_info = re.search(r"^__version__ = '" r"(?P\d+)" r"\.(?P\d+)" r"\.(?P\d+)" r"(?P.*)?'$", fp.read(), re.M).groupdict() except IndexError: raise RuntimeError('Unable to determine version.') # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('..')) sys.path.insert(0, os.path.abspath('.')) import alabaster # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.intersphinx', 'alabaster', 'aiohttp_doctools', 'sphinxcontrib.spelling', 'sphinxcontrib.newsfeed', ] intersphinx_mapping = { 'python': ('http://docs.python.org/3', None), 'aiohttpjinja2': ('http://aiohttp-jinja2.readthedocs.org/en/stable/', None), 'aiohttpsession': ('http://aiohttp-session.readthedocs.org/en/stable/', None)} # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = 'aiohttp' copyright = '2013-2016, KeepSafe' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '{major}.{minor}'.format(**_version_info) # The full version, including alpha/beta/rc tags. release = '{major}.{minor}.{patch}-{tag}'.format(**_version_info) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # today = '' # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all # documents. # default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). # add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. # show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # The default language to highlight source code in. highlight_language = 'python3' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. # keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. html_theme_options = { 'logo': 'aiohttp-icon-128x128.png', 'description': 'http client/server for asyncio', 'github_user': 'KeepSafe', 'github_repo': 'aiohttp', 'github_button': True, 'github_banner': True, 'travis_button': True, 'pre_bg': '#FFF6E5', 'note_bg': '#E5ECD1', 'note_border': '#BFCF8C', 'body_text': '#482C0A', 'sidebar_text': '#49443E', 'sidebar_header': '#4B4032', } # Add any paths that contain custom themes here, relative to this directory. html_theme_path = [alabaster.get_path()] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". # html_title = None # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. # html_logo = 'aiohttp-icon.svg' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. html_favicon = 'aiohttp-icon.ico' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. # html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. # html_use_smartypants = True # Custom sidebar templates, maps document names to template names. html_sidebars = { '**': [ 'about.html', 'navigation.html', 'searchbox.html', ] } # Additional templates that should be rendered to pages, maps page names to # template names. # html_additional_pages = {} # If false, no module index is generated. # html_domain_indices = True # If false, no index is generated. # html_use_index = True # If true, the index is split into individual pages for each letter. # html_split_index = False # If true, links to the reST sources are added to the pages. # html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. # html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). # html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'aiohttpdoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # 'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'aiohttp.tex', 'aiohttp Documentation', 'KeepSafe', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. # latex_use_parts = False # If true, show page references after internal links. # latex_show_pagerefs = False # If true, show URL addresses after external links. # latex_show_urls = False # Documents to append as an appendix to all manuals. # latex_appendices = [] # If false, no module index is generated. # latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'aiohttp', 'aiohttp Documentation', ['KeepSafe'], 1) ] # If true, show URL addresses after external links. # man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'aiohttp', 'aiohttp Documentation', 'KeepSafe', 'aiohttp', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. # texinfo_appendices = [] # If false, no module index is generated. # texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. # texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. # texinfo_no_detailmenu = False disqus_shortname = 'aiohttp' disqus_developer = True aiohttp-0.20.2/docs/aiohttp_doctools.py0000664000175000017500000000156112552474754020731 0ustar andrewandrew00000000000000from sphinx.domains.python import PyModulelevel, PyClassmember from sphinx import addnodes class PyCoroutineMixin(object): def handle_signature(self, sig, signode): ret = super(PyCoroutineMixin, self).handle_signature(sig, signode) signode.insert(0, addnodes.desc_annotation('coroutine ', 'coroutine ')) return ret class PyCoroutineFunction(PyCoroutineMixin, PyModulelevel): def run(self): self.name = 'py:function' return PyModulelevel.run(self) class PyCoroutineMethod(PyCoroutineMixin, PyClassmember): def run(self): self.name = 'py:method' return PyClassmember.run(self) def setup(app): app.add_directive_to_domain('py', 'coroutinefunction', PyCoroutineFunction) app.add_directive_to_domain('py', 'coroutinemethod', PyCoroutineMethod) return {'version': '1.0', 'parallel_read_safe': True} aiohttp-0.20.2/docs/_static/0000775000175000017500000000000012643555674016426 5ustar andrewandrew00000000000000aiohttp-0.20.2/docs/_static/aiohttp-icon-32x32.png0000664000175000017500000001312612552474754022312 0ustar andrewandrew00000000000000‰PNG  IHDR #ꦷgAMA± üasRGB®Îé cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk>øIDAThÞ½™÷w×UžÆ_÷~>ßšJ! BB' M@Q@iRD”ŽÒQQ)"ÊŠ‹€‚"‚)" ÅÈ©Ò!J ½'ßö)wX÷¬gvܙݙ³¯¿àyžûÜ÷9÷}…ú þY,,, >õI;ÓβóÁnoÏ´€z„Sb›6ÄìÌV?Ü­i±?½?ˆ*ŒWALwE§±Žg¼›§Å^YLóÞˆ«üdÔ­xH(™yq:¨ââoô ºåLˆ¶W«­íš†X êŠUÕ— تw É´ ˆG5§g$ØI•J[Ÿù]ƒäA»/ÔI£ÈÇïÝ=Ú„ ì-èÖÁüW²@%«¹æ›@Ž®Âõö7¾éÀ~ÝáÞ4³Õ1Á鈽zËÈ^`M ³C ÚÔÔ'´kõ÷ñ€Z«žc 8Ú9âÅ@Úò?Ìs¿yÀ< —İã³wŸiâÀ•ú›.€v98¦4ÔUϱˆ¹€e”æ¦øL51&ìXÍT`´Ú ‚huoÔÁž`×É®{. Dow³ˆ W3çç@Hý¥|9ˆaÖð€p†—Ö9 ²—º¦_z9æU~9£"ƒÊÒZÚù ü¡ÕûAm %ä%€ú³ÐÀ>ãmQy˜çÃëÞ%º~Ó0PçtÞÚfØ××€5jÛÙÃAs—®÷Õ!áí”Ö`· ïT³=¨Kb§z´Áe —ÂÀìw§eÚ× zËD<˜Ì­æîßÁ d XG¬Nv:ˆˆà·…É gtßù.ÈBg¶k/Z[)@(´¬ø.ˆ^zO[à­ŽVÄqãû²<ÇõšÎrIŽêbª5 °õç @sÚ".íi$°9Æ °^r4 €Ø_ó]°g]h}c!˜¿¦>} ìÚ·?¹ýXƹ“*ÀxkçÊ}+@îwñݨª·ÅlࣨsÕ>Ù:ìßbV2?îte`@ൢçÁ~ÒNSýµ¬e-H«§ÕÓê 4çåq°›ärñaÐ'f.ö¢¾†zd¥= êñƒ(Æ9טLªHÍON¨Qæ, À»œ.+*úÊ í„8ãþPÚq5 .Qu_ê’¬+.OȈ°›`çßxm·¦ÕeUi­µ í0¨…yUò*Ÿ•µ< ª‘zÎX ªÄˆ*Ö—Œše—@få}zbØsÏœEª8 vÐÚAÖŸ­¥Ö* ÄNõ¨©yWÏüò†9²ì¨×‚¯G"ÊJúDAÍq]—‹Bý ?•*ßÓ^{«yçƒ]z­t*¨Bÿë…óÍìüÖX_uÀ¶€i+ãu ‘Õ18ÄsqY¨K|f~bsÍÍ5fÛ´Ríg@ÚWí n%ÛýA܈+s‚çE×¢à„‚ŽÀ3²Â2Ô_Ìq /Z—ʇƒ•.BQKùÁzÌêg ÝzÚšgí­Bܵ—}Ð×»è9 èèRå2ˆ&Ztøc 2ªzäq9εa›@=•Ýíì Úè㛟ö¶€/gðº¶ÌÈTh±1T¹}(Ð °Äa»Ð\…ñ Ds$`²Â^ "‰…a@–ygÄ-{ÆU©ªaÙØ»1 oËkz<Ìzj­ñ)È´¿k²dǶyI3€6Ò–XÙ±¾Ú ÂsÊN?Z3ßÒûçA¾îªÝÄDÇWaÁN÷/)b…U£b20ÙêØj¯Ì { tê©^L*©Ûf4ÐѨZÖD}»ûyâ+O­¡ÿç¬ Øͽ¥û@E‰OœÓ\ Äh@˜oÛ).ŠgiËŸlÒôh ‚ö|`¯órdˆnµªíõA`xqˆ¦·¬èˆ?È/ Û XŠSw΂½ˆ**Ä{·¹´ê¡™¥@¬Öƒœz¶è O‡Ïª~Ä[Ú Çuûô‰®\ ½}7¸ÈR3­P=IVï€TŸ²Z-uK%À]ûñ10WSÎ ƒ#vSP)þì€ËÖõ*à™ž·¥^7—è÷õ®—#Ó¥2c‚÷+FÎà+ÖYÀåž3 ԺЯeû÷ƒÁâsÀ—je½@DÚÅòÐ}Ö™ 78+´8¶\g‹vœÎÑëzϼäýA~à[\´èª5ñ¶5Ò~ßp€ºª[w€1E‡,;G ŸCÚ<`»úŒy éŒ X¢p~ ¤y“«ô5Y¿æî öÇe=2?õµÿ‹‚ë@®¹'¤ƒpZe~(û¦¯/`ÛŸ‡–º5'4°U5k1`k[¬ žÛ;Ø#÷ËAM(¿ù"¨•þ¯ tPËÌuá *[1¡ÊÀD5 Ô ÄÕPVQo½ÊVlb.*[¼*{ÛCæ·e7€¶žã±ëAí1Ž–;A}X]ô¨@°Ji*²õq@š¼£íç<èr®x\8@—˃€6Þ¢˜’7é§?* \¾7À98º XäÊò¶Tм„õª|b„âÐ@\Õ÷»g}FúŠ|½—ëàQ×Ìè,`Eá_o€*QOûgÒÑÊspzGTÚĨ]ÁÛ€O¼åZT8²ã§‚¨ç0< A%›}‚Oå7['ÕôPW`”™Hfù;Í’Å–Ô+îQ‘'9QÓëdƒŠ•û§AtQáœ]ë«uÒ€eÛÛT&hñ•ӛƀœ9bß.sTRi!ˆ0çkñ¯¹ZŒš ªÜÚWl‚ˆÓbÝ_ƒXàí·Äý²§ˆEOü`¥I=Œ2 ö‚]ñÓ~TI°Þe@·»Û¥}® Īþ@®î; ìv¬ñ:A„{†Çî*¶ÞÐ¥B?¨rõ¼bŽrúó€ÎŽh­PNNè¨&žû±7At‰«ÛÌ v¦º+Ûö¶\Ì]o£·Ö[Cè’¿q`èC£Êj¾Ö}g±ó+Ð+¢w\òã¦5§îrCsËÆ½ùJú߯®ƒ¸î‰_∾ÄÆê1]Y©YƒÀ5Èš¤$,kÙ„'ëVA(—ièÆˆâK@”ènÌBkAdëy>1]vÕ&ô:Î^ Ú2]=¢¶nEž>vÿ)zˆ5‘µÕŸž•öLµÀ.y%*±ÎBùì¬àÌp>ér‚®]Õ®jWAHFª ¾ônN\ ê^•)yÀ¹*g›q4*«A ð½:k¿ìtÙ‰‡A .)8uÔ>ù‹œ "Vú\&X/ß*þ®Ð ¼Iõk Îøf…ªW1<ãGõ¢2ë½b‚±½¢.°¾tÓ­›@5õRÄ/À%}md[Pµì.þù 6©ÞÆjP¡Ëë±Ú¨¨@ Oa´ü»?Ôzõ³w¨mŠüT°ß‰µÛbƒ·câ@Qj‚Ì•Çä{ ÓntgCç}ç}. u0V‚«e§ú_#÷öóûÇ‚(}?c;àóŸÈ] J”|{£àçµ$Pçƒ)¥‹˳ f/¿Ö’àâÂfÀ}_xÆ0a¡Ã9€YzZøày÷ÑØ=@£Øï›ÕÑ ±[ÏXǶn>TvÁ‹׺“;át#P¯êó-`P ¥à$° T/X*`.Ù âŠþvMÖí¨E Ý¬µ¶¯ŒŽö·ò0¸œÎ–Ž/€0ÂûÝ>À9Þ9Þ9‚©A¬ Jh“4ı¨¸ú%`­¾Xýã9 ^òEdÑÖL(< è¡Á! ¾RC­% ”c¥h ¢sا՛ƒ˜(Jü;€VâSû.¨<×Âê‹AèŽ}Þþ Z°DU¯Y»s¯ÕYØ'ˆ^‘óÕsÁ~G¼*ôKÁŽ+À™¡-œâQ9D¼–Pu>¨^ú¯U¯7«uë`ƒêW)²Y °Ûêný!½Pè÷¯Áÿd{Øž®žºø/‡Þ6 ÅÖìÚ³غ{v\}C¬se£@< ÿB'@é¿Ê†€”?…ËÞR> ð°5X¸*Þ7 î‹¡æ%Ó4¡ýâeW—È 2Ý?Æn±5bz­äߌÿžx2hç¹Yù{à¢Õ©ôyn9Ñ\"Nô0wƒjFc˜M#ß«´@­ ½„Ð Fºeƒûºû ûC` có·ø ý€þý¸v8Ÿqæ?94T|Zÿw‡,cXäù&‹@…â¾¢‘c¶ó9Wºû€ë™È[€PgHõŒÀ¦àÃÀ(5K•OÊöú>ûø7ëY°û{Ó/Ò\ù Ù*ÅÌ5¾d÷Íö@œÐ­;@ƒàµÒTP!_b <®zMA_·Ç“Ï‚?ÝtÉîàŒs¦9zƒö¡¶\[Éã×âžO®'¬sV¿ò)àŸ¯D%€§oÓÇ&cùõ_ ­EvÞþæ Õ—Aó5 KK {hlµ«("d†;ï žoÐÔ-{I@€ˆÉît`÷íé߯‚‘H.hbTìà w¹%]ë ¬Ê}¬9ˆ>j¢‘Ök©ºÖO±-º]=¡¹þüBV’{££A»%{‹ÆàzÒ•àºÀò÷?F’H" Êw•ï,ÿ Ì_¬7íàíãègõ»ðvÉÎþÀ¼Ì¹û/‚ö–9°ôQ=(²yü €Ç*jäWuGÔÖoƒøÉÝ0¦Ä0DZ𱠬’mêUtëy ÷fåXoª† TKýÏl0‹ƒi¾uÀ5V>¶´áµúýü ¬ÅŽ‹ ?¡-“o‚7Õûïa`9ËYþÇHþ餓á_†o ß.Ë9Ø1Êgá{V-ÇÐÚ e¶K:ƒ=¼^æØ0J"²[µÜS¥9Ø#Ä«vð¢q?X L³ 8À~«|ôÍö j;Ýž) .r*Xvõ¬øŒ‡#_j™Vq÷­¼Ý›K^Õ¦öõ¡@ÅðЙ®]Î Ç]ðú½!¯õ÷ÿã økB„yÈ¡&«e`²º[.PSÕ ûKpÌÒÛêÁ}Ê}Ô}ôIú$}20’‘Œü?«ÿð×Üáwþkçf1˜GÀ\j.5—‚u˺cÝ{•½ÖÞT£ÕA~"WÈwAë¢uÒ:€cŠcŠc è±z¬ âgñ³ø¨Le*ÿËÔòïpTÅêovþ%tEXtdate:create2014-12-31T13:30:38+02:00d·QÛ%tEXtdate:modify2014-10-17T01:10:21+03:00¢BÙaGtEXtsvg:base-urifile:///home/andrew/projects/aiohttp/docs/aiohttp-icon.svg!hËïIEND®B`‚aiohttp-0.20.2/docs/_static/aiohttp-icon-64x64.png0000664000175000017500000001765612552474754022340 0ustar andrewandrew00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEß 1 ÔìÐ;IDATxÚÍ›i°]Õuçkïsî=w|ó¤§YI !æÁ€! ›2¶»c“Äv•ƒ»â´ó¡»c:©$åTñTWÒIèꊡOI<¤ÁÝv $¤Ó8Ž˜BB€,K€„†7O÷¾;žsöÞýaŸ§÷ä`L»Ä¯êâÖ{ûî½öZÿõ_ÿµŽðOð300 7ß|³ (cŒÄq¬”R8爢ÈÅqŒÖÚvxxØþÙŸý™[\\t+klÙ²…'NüÄ÷&ÿX‡þÈG>¢o¸á†¨^¯çvíÚ5¸gϞݽ½½»s¹ÜÖ GµV}"’pÎu1‹Æ˜©8Ž_¯Õj¯>|øðÙ³gç+•JüÄOÄ_üâÓŒ}þ¤ _ûÚ׊}}}ýããã T*ÿ\.Ÿ»ð¼/rç¸ì‚E}ÞbÝn|¼ÕjþíÌÌÌ£Ç?T«ÕjÿøÇ[€û©3À#<Ò?22²eãÆÿ¢··÷£¹\n‹?k‚K:8ÓÅ¥]ls ÓšÁÆmœÁyTG—†ÐÅa H¾QÑI’œZZZúòÔÔÔ#ÇŽ;þáxé§ÂŸûÜçª×_ýî 6|¼§·÷.­T„5¤Íylcštþ8ÉÜ1ìÒ ¨¿‰îž!‰úz‡° ¶51 “ß‚ ìD¯¿• †.@Ñ…>DiŒµz­ö§³³³ñÈ#ºûî»ÿlØ¿ÿ%7nüHÿ¿ ‚ âLBZ› =Büý¿ÂM ¤C®ÒÊ ]„´æC@ WñaÐ]@¢$,Ce$3ý !±.#Ã{Èmº‘`hº:†Ò!ijækµ¥Ï={ö{÷î}ùŸÄÎ9D„O}êS•ßþíß¾}ddä7 …ÂÝÙã¤gžÃL¼€ž9HÎ4P™ûº°‚x\ÊNP‚|¡0 "0õ<®+PBrEpk ±‹0Åqôèeë¯"?rˆ¢Ýî<³°0ÿŸ>ñ‰O<üøã·ÿÑ °rø‡zhãM7Ýô«ÿN)ULj$I§Ô^#*DÐZÀ6§¿gllìÂ[o½õ¥í۷ϼ“ËÕïäðO>ùäå{÷^òû¥Ré=6éÒ8øyäõo™T@b@ ‰¿EÓ†öt›P݈ÚòTX<íÎ2°ˆ qI° ÿ JüáS *•d˜‚*€h¢“ÌüQ:%r£—æòÛGFFvÝpà Ï}õ«_û± °rø‡~øÂk¯½æ÷J¥òûlÓxñôéG‰h{U™‹ºHš¹°q 4._B†.CúÏ_¿v ™;ìo^þÏl ÄøÀ@) Ú ™‡…E AYD  ná{´ÃQòÛ Ãpóøøø…###ßùë¿þëå·3€ú¡à Â=÷Ü3ø®w½ë×Ëåʬ³4}…àô>òh=aŠeˆúWŸ°i×jbZ ç>¡1Œ\:Î"X X]“Hä×.ôBqŠÃ>[ Úuh¶ Ù…zhì]ä^ÿKê/| €¨P¸å®»îú@îÇÁðÔ©S¿¶~ýú?‘\ã{£‰\2…êÚê {ÆÇl®’!·ó(_Ý º—töuìøÈúëÀt3ûÓe$È#»pí9ÌÑoA÷k¯ ¿°u\XeÔY i IbÝjó-¸ö,®»@’ë#ÙtÕK~kmsqqñïyÇðÐCpðàÁwŒŒ|FDrÍ7ŸC^{”\<iìŸû¥K`H»`²zEd`7¨7õ$º;KpâQôþ?@¿òyÔÂ+Ð]‚x7sלCmÿ€_#A¸°„#Å¢±ù!lÏLÿ%ØÊV\~«.M?‹K¸æˆ&5‰}4N>ƒRªT­V?~äÈ‘÷½c x衇øú׿¾ñòË/ÿr¹|CwáMìño“[x I[>æM aäo(žõñ.¾È!WE/îöòË/wÞIGŽù…»v}Å¥]Z/ÿúØCä’ΦþOœƒ\¤¶½Zœ©2~4'pó‡WÃÄ) ¬ž÷*WÁ5fpÝ §‚lyHDá C8’ïA—†Ç¥mLs—4‘ê&©ç‘ù#Þ°qÝ_‚(¬.Ñ,l£ï–{0Ö.ÏÍÎÞ3::úÇÿà°?øÁ£>ºu||üWèœ~wäë„AWê[c/´ªß36 #W i ×jCá‚Õß qšçg%+“õAeP¸\W?Aºñ½Øü $MòC»Ð…^çKh€aÁXC‹] ý›ÇQƒƒ„?sº²Û­Ãæ÷@ge—2jíâ„nã ÖY¢¨pÍ•W^ypò`ÀoýÖoUvìØq»fù,vúÂR Wé¿©lÀµ=1sÎ{qÿ…H4Œ=ý8z`Ï*ŸD…HâÒFæh~„dtwMÒyH븠ä)nu 3;‹yz?ªðÖDÉßí#¸æ‚ò8qc Ó™GÎþo¬iøCVPILçÌE7\5P.—¯êééùV­Vk{ ÎåÔÀÀ@u``ðý8‹Y|OBÔ J#A*!¼[§”.DzöbOì]ÌÐW2›…@Ò—)ƒ²Ç…0ç׎ú êÅEý8I@p6@eÌr57ŸÑá·b0 71…k7¥qÆâr\TÒ”†¡8Œ!jþEìä~Ï£èªÇ{ìÂsËÄq  7lذ¾X,ì4í%’ÉgÈKgº lý„gyA¶úQ×`OþÿY®„k¸y s:®9ïÉM&|B ¦I#Ç,œãĬÖÎâ”zûJ&“ÕýLÇßüš ïlŠ2uX~´]#÷ n=/ |ðƒ wïÞ}5€‹k˜™ý(%^¼p’eÿï|/ú‘Ñݸ©þ–óÁÙ—´²j°‹kÍúƒ¤±gŠ¢À,ƒízC™Îª·$¦¤ËˆÒ¸îíà €1o}xc`lU,bâØ¤ ÄH³}` m£´N‘,'ÐÒEѶ•T€ 毰ÍiTëTæÆ‰/mMg ²ý—P×Ü‹Áug!WÈ¡x#¤-H»¸æ¼7&¤ã7•.{£á|11¤-$i XTã{IÛ‹è!¸öjœ1™.°–@Xœµ7߈K¤µS@ŠjñkÇ5oè´ 6ö†nÅ-Ÿ"ËzÜÿý+ (J©|©X¼ÈÙ„´~–\®ß&8ÏçÓ6ôíEoù¢¦ö&Ìã|Í¿R ؤ3)DÕµz–?¸.{ù‹ H%BœÁéÑ=èêfŸ%›Ó$Å¢›n¤S«áö¿ˆjw@+0W© n¸ŽÜ»®#í.bÛóhkQqtŒ"ÏDÃÈCœà:5Ãa¸å¢‹.êf@Ò4ÍGQ´Ù™Óœ' ႜCÂ*爓eº(UÀvÛH˜÷é0^«CºL냠’eÉR^ ®˜¹¦7€Šz½‡X c× :‹0sé¿xæù‘Ý?üóÄ;wbNžÀµZ¨j•`Ëfr—\†IëijGѨúIDŠjÂõú~DÚ‰ ]Œ‰Û8“„¹u¥R©z΂ ȇaØc»-lgYQcT€„%/:¸6ÉÑo I5ó¸ä¤²ê¢*õr–©C°rXëc‘4ËpH!A…(oÀ-CºË„Až$ÔPÙFwò%‚þ­„×^Eî²=ÇH¾€Ñޏ1éÔÁtÐõWQí³LmŠÊ•¼Ò¬´rJ &­aâe‚ : ”*ù|^vîÜÙãÓàâED%@€ óˆòz4wæ;Hu¸Æ*âG¡%”•!¾íxý?XCzœg„N É• , C—ÀÜ+°<è­»Pÿ‰éBÏŘå)Lí¤¯Bu6A¬à¬A•‡Qµ#èåc(› iê‹¢\ÙY‡¨\ ÛõàŠYÆ%T®¯†aäë¯BA†††Ê+.,¦ƒHꎌ˜ëAâšòE¬¬)é´‚\¦™¥/¼qÒ¦×ît–¦|½ ÄHØè<2|%nþUHZ¨|›. ‰EG±¦í»Û­e‡ÊR¬IPÝ9ôìã=[ ÞEÒ:CrƒkÄAÂ"bÚ^…²1Î&(%yç\x.Â0 ÎS§ëŸÈ"JCu#Ø.®=ãoå¥*IWÙ]®›Ú¤ª´ ±œ‡ˆABu×ãBRÏn7€Dy´JQ¦ 퓘ÙqA §ÄÆþ¶E’6*ŵ;w@;¤\<¢¼äîrÙ“éÌÎ)ðÿpív;]Ce»DçpIv»­9úNg¶ |\§K>Æu~õ ®™¥#iêu~wã–OøtµÂ…ê™Òú›Ö‚Z‘¯VuaÓj–c\÷ ®1é ž|Â<äKPèƒî¬Ã\em3Ác†ÄúŸ#îþ iIh-xÝ®»è×.ôþÕí Á¯ óãUàé¶JW'K/ª$]ÜüQ$¬àê§2/˜÷Uj±Áau•1Diâ¸{vvv¶¾b^Ûh4âz½þ*Jôl Ñ=–q³¯ø<îêÞÚ:ôˆª°u°MP‘Owª€è2ª4†Š†²Ï#{ ߇Œ]­)\ý´¿å4» ¶á×Óa¶>¾9š¯xýA•üÚù>TiV×|gä?ÜÔ¤wWæ™]¿gÚ„~ýâ0R Óéœxæ™gæÏUƒݳgÏPÅA\ÿ…¸¸îoQÏúLÝCðîéº~ó¶™ÉÑÎw{•B2å ƒÈ–÷£.»ÙüA¨®÷‡|³SÙlVæÕ.Ã<¶&@ ž5ê #¯HF¬$…PAøPRÚ÷(I3€î`UÊPåu4ãôG´x.À8?ýôÓœsHq=vfî•ÌSóJ 4êc-]ò±è,$~èA‚B& ä¼¼]Ù€\ø 迈¾5têÒ¯ê„+nœÌg4¶ëKfÑÞ ñ´« ¸ÚB ‹ˆÎgL4>G/ˆB\ó4TFý͇U¤8‚䋨â(nà"ÂÞMtãd¶^¯ŸRçÖcLzúôé™Z­þbooÏåA±K!P8§q½;P›?€ ìE$@:“¸¹Cž(!ô¡ª[ü-e”šÒ8jÝõçËX…adx/®þÊ [%H6“±œöiÓ—–ÆOŠˆóŸ‰gwÎ5Àª•(öøÐ:ƒÚø³¸)ù~$¬ÓXÂ¥t±¼´tø7Þx}¥ÿ/8¸7ÞxcéôéSööî¹<èÙB\Ýæ .?Žºø×ÐëÞ½Ê~¯ø]Ìáÿ µcÀâwKÓöÁ9œ³ˆ¼Eó¹²ú·CóÍ,7g8œ¶}ë `óàBÏÜóÚˆø”h¬W“ƒh‰ú=xGp•͸Ö®vg-6¿‰päò•!ŠwÞyç‰ì ¸‡~¸qàÀï¦ÆÆº2F0z-q{zwøç<)*ÄGqÓ‡q³‡pKG±s/ãZ3¸Îtæp3I'ž?ÜãeÜÂa޾ÝHß®Lx±Ç0¾‹ä”÷UÀ‰Î˜èJªM}zkÌ!ùA¤7RBw·t7wÐó— „!‡­l'?º—nONOO¿4Vš, àÖ[ou@rèС3ÓS¨°„¾’¤´ŠëAåßb€Àwƒ(ô‚q6Å¥Œw[˜?‚yå tO=A²ŽmÝ뉹’Ÿõ+ øù@±«š .‚ŠP…a$¨àLŠM,Á•¿ã³‰ ×ì0D*ý4éô>hMzÔó^Õ©]ñëêÒ³“Äģý}ÄI2{üøñ?ùÔ§>õw?8g|LÑh4ììììâõ×_ßÓß?p¥*Ž=ÈÒ÷ÐËo€iûÃKZ|5æ2-_ßõºŒD}q­“žôó7•U{*êñü!mc‡®"Üøso3¯R„™§¡y‚òj“Vbÿ_¢,5ô^@+(_ú¯P:daaáÑíÛ·ÿ˜·™™œœ°=öØôO<ñ?–––¥‚Á=¤ºŠee¢;Îr¯' ««­‘ÄL-#4YtEÃ7?T®r;$_žmo?ÐX†Â.]Ìd6•íÃ?]&BË•)\ô‹è°@»ÝþþW¾ò•?jŸýìgÝ‘éééq€¹ë®»ö¿òÊ+Ÿãx1êÛã7“„#Ù—®Ý´—Åtœ.›I—³Úì†$c€qÆæV 'AáGÎl:n¥Ì6M {þ>ˆA,m© ‡/#×·…4M_zé¥û>ó™Ïܽ÷Þû£g„jµJ)to¼ñƇNœ8ñyk-m¼3~ ]UÆùÕ'*x.–½Ž–|b–!‰¡›B¼òt|¯QôZÙ »tüí Ð8Ýy$ßã›4 NÖ¬khwº°ý)ïÄZÛ=}úô×®»îº??çvïtLÎZ‹Ö:ê·ÝvÛŸLLœý:@eç¤cï#¦'HÞ?¦áÑøœÊ^³Ye¶²É®W›½TmWµR=ñÝÉ?Ôvúilý5È÷eâKk í¶Ã]p•-7ãœKçççÛºuëgXDÌ5(944ä&&&Ú/¼ðÂK·ß~û¦R©ta4²G:Fcj'HÓôyØ™l€"›!J[ˆŽ|ƒ¤9_èyƒ3~D.£Á®SGŠ£˜Å×H%$¨nÈ„‡³†ôôßà^ûSÔJa–fÃ8дú²ÏPÙù~œsfiiéï? Ô£(JÓ4ýñFe[­›7o¶‡n<ùä“ÏßqÇ›ŠÅâ¶hh§2Ñ8…×ÐÝ“¨sf³râªAÁOŒ$Ë^”Œ*ä2>Ÿ"aÁÿ[{5GM?…›z†ÎôAÒæ$éÂˤ‡þjù(:ê¤v^¿ÏЦ¡ÖQ¸îŠ›®Ç9—ÌÏÏ?>88ø `aݺuÉÚ¯~ìiñÑÑQ555ŠÈè›o¾ù{ccc ‚ œ4ghìÿ}ò— ÌJ)ÈUý8iCPF*› ½ŒëÔ!ï…˕ފâz\·z&+Œ¢"¢RÞˆÛT¶Ca·ôŠg€Æ’¨2ÝÞ+©\ñ›ÅŒ1ÍÉÉÉomذá×ÚæÍ›““'OþÈw‹Þñû;vìïÿû9 tøðáÁ|<Š¢ ËǾ=ýùtåTæ¾8‹T·ùÕÂÑLò>ǧ‘¾Ha;õìù/L¹Ø +å^X> ½;°EÒÖ<84t}¥\¹H) :³ÇH[ÓЙ‚å£HwKHßŰø¬²_ E}%é:¸\D#г‹``/ùÞõˆÖº´Ñh™ŸŸÛ÷Ío~óÁ»ï¾ûÅŒ™÷]Âÿß׿$¦©¢ûï¿ÿêo¼ñæ¡¡¡«ªÕžÝ…B´îœ0Þ©‘¶f±qÃKfíÉl\&¨Ì a„ÊUÐ¥‚¨ïÜ—´Û‰ååúËsssû÷íÛ÷ø§?ýéƒ^:Æ~ìc³_ýêWÿÙ_œ”5³pÑ'?ùÉMwÞyç¥ëÖ­ÛÕÛÛ»³\.o-KëóùÜàúBt»É\§Ý<Ól6__ZZ::11qä›ßüæK<ðÀ‰•`Û¶möõ×_w?‰ÿÄ~òù¼t»Ý•– ýèGGo¹å–õ££££åry X,ö …¾0 KZëÐ9'ÖÚnš¦Ív»½Øn·ÆÜôôôôw¿ûÝ3_úÒ—&³*ÎnllÌMNNþô½:ûƒ?…BAÚí¶Z3°"áæ×­[]|ñÅùžžž@kíÓW_}5>{öl+ë‚Ú5qíúúúÜ"4?uø!x!kh©¼…÷£”ÂZë~’/H¿ÝÏÿýú$X4ß°ûIEND®B`‚aiohttp-0.20.2/docs/_static/aiohttp-icon-96x96.png0000664000175000017500000011332412552474754022337 0ustar andrewandrew00000000000000‰PNG  IHDR``²«{gAMA± üasRGB®Îé cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk>€IDATxÚì½w˜ÕÒöý«îÞi"3 9ç$(I "D’€¢ ÀœsDL˜  ‚‚ DPQAP•,9g˜†I;u÷ªï=çèyžóÄó¾ïõÕu ûš¡{íµª«Vתu×½Ðÿ_þ9qÕUWU·ëvÝ®ªïé{úžªöÖÞÚ[Õ¬3ëÌ:UÓÑt4Uý—ü—ü—T½ÝÞno·ª×ßëïõWu÷»ûÝýªîîîªîRw©»TÕ-uKÝRUïVïVïVUßò-ßRõ?÷?÷?W5W™«ÌUª&nâ&®ª7éMz“ªÎÓy:OUó5_óUÕ¨Qó¯VÖÿ=âðÿKJ lcÛ€wy—wA/Ò‹ô"Ð%ºD—€ifš™f`Ö›õf=˜"SdŠÀ¼f^3¯j¡BÊQ€nt£PJ)¥ÀyœÇy@5ªQ ppp€(Q¢@€`ƒtâÿ¥¾Ô—ú dƒl«›ÕÍêV+«•Õ ìv »ÈY"KÀjj5µšžr!•¨D¥µ²ÿÏ9î ÿêŽü¯‰¢(°–µ¬îænî]®Ëu9øùù?ÉŸäOï5ï5ï50Q5Q`5«Y Ö(k”5 ¬V«Xƒ¬AÖ °ò¬<+¬‡­‡­‡Ar%WrAæÉ<™ÜÈÜ´¢­Nê×ñþLd"A{jOí Õ¨FÁŒ1cÌHMð`–™ef˜ýf¿Ù:Kgé, '=é V5«šU œ+++Áîbw±»€ÕÜjn5É’,Énâ&nªR•ªÿê‡ó¿/ÿï;@ %”¯ò*¯‚îÔºüëýëýëÁ[è-ô‚—ïå{ù ku­®ëTëTëTpÂNØ ƒ3×™ëÌk¤5Ò ÒDšH  Mhò/ß&6± t—îÒ]`&›Éf2x÷x÷x÷€¦¦&˜ª¦ª© r‰\"—€cãp‚NÐ ‚5Ðh )).à.àÄêÿQùÏ ( ¸¸L/ÓËô¯’WÉ«îlw¶;üÇýÇýÇÁ^d/²AàìÀÙ³!Ð5Ð5ÐäùF¾jS›Úÿ‰~ÅÃÏÒM÷€^eøq`´Î3Ÿ_j s#@/Yg½<,X}AÞµ>±#À|'5\¬ÿD?v³›Ý ƒtO=õÜ:n·øïúïúï‚=Þo‡@^ /ÎXg¬3äZ¹V®F0‚@ˆ¡õCþï“ÿûà(G9 cÃÀä™<“î`w°;’­“­“­ù#ܸ-pwww€5Ôj åß7ôXêC7C¼ÁO‹/+þün¥/L¯CéùW‚¿±¤dßà¯.¹|Ïi o&?*éZÃßâUÞ3õ’ëÍæAïS@Ë×M¬çÀPkG°%È^»¡sä–`—Œ±`·ŠRíMp–eeVo ö—V¥,°K#‰ìGAN·§¯ÂÿŽÞÊÃ|o¾7߃û’û’û¸µÜZn-˜Ä$ñññhhhòœ<'Ï×r-×rbÍò©üßç...ð Ï𠘦‡éÞ%Þ%Þ%›› Ìd&3!´,´,´ sss@šI3iöo´ÿ ômð?Œ6, C2|øÑí÷@2r¤×–wÁ«}dè¶ËAµdÀ¾} ’ïýöõþÓñ‡Áï~{hXíÍ%ãÁúT{AN =šõÈ'ÖgºÀµ4e# å?o³‘f L_w'èšÄѨÓu!˜e¦S0Ì0ÿŒÈð§:_¦vÌ»¹Å-`}\ok÷`·Þú ‚·¤åçT‚ ÉZÿ °/ìÊî ÜÌorþ?¾îÓ}ºÜÜÜ ¹'¹'¹äKùR¾„`ã`ã`cpê;õú }¥¯ôÎå\ÎýWÇ\þïq€å,g9è2]¦ËÀëêuõºBb[b[b¤Òêêê ¡sBç„Î’$IþE{GðLëÄ¥“ þæç׆Ä;CKG‚_xà­Uwƒ•½úÀppÞV LÀ à‘`>Ø!™I{¯¤†ÌÙh—Né“l˜ÿ6P]ï7Ù@˜•¼íÅÁ÷/¸;k*àqŸ”œÔ‡4°“5‹®V²?PȽfP(EN WÆ &ÖUÜö§¹UNwòÁ‹¬²ö^p Šãû§€wnð³ì À§WyììJÃ[Ü¡±µžk7 Â×Uþ¼Ùµ`­ 9éÛ€\Òþ2Ī@*@²m²m²-$&'&'&ƒ}½}½}=ß¾|œVN+§'óyä‘÷¯6š_þÏu±üT3ÕL=1Ã'[$[$[@ðáàÃÁ‡!\1\1\d–Ì’YÑÞG\G¸g–<“?âÍöZ+/€¤·½ÑÂ+@Zl¹üf›ÏbS PÏÃ×`" õm Ènx¤i䫬;2 Y+€2­æç‰ä‡ž-3¿Ä> uåA@ñˆBkžq7g®M:ã•Ôü„¼;ãGAK“Éâ_! ÈĬ—ë$A*T{¡Ã žukh&hÕÖÍúµ¶m õ{/èž´¶¹[€L;=XüKt°>îV¿.s YJ×Ðc ësÊš„!¬}ùY™þ½fý6eø9óÎʧƒx•=V£Þ 7è x'ñNâpototo„à¼à¼à<ÌÌÌëëë ?ýéÿ¯6¦,ÿç9À^ö²t“nÒMའ„ø®ø®ø.àAäAˆLLL§½ÓÞi <©…Œælp(úaßyP6bk¿ïŠÀ?;äï!øyüÍ‚©¨[òêŽßÀîåOнVei¤Í€<ýŒ #ìcPJšªœuƒÕÒnloα2Àsë}€(›°ˆ×2ûu`[³ÚÁ{+dÓµ H޹'âTº¤Võo;þœX’Õ”C ~]œ]¸r“zÄÛhÅ n · ‡¦}Úš1È ŒT$J@œË»`é:Y þ—¬srÁÝx§â¥¼È9·B.ØK*Zc>¥ ç¿ çröÔ¾èÎ(~9I¿qâÄÁ¯í×ökCì†Ø ±@‚” „ =zœ³³³¯ùš¯ù?nýŽ,` ÀœaÎ0g€ÛÈmä6‚x¿x¿x?NNN†ðÎðÎðNêR]ªÿ¹ÿ\÷’øB(½eóžù?Cò¼Mf÷„P¥øõûOƒð¡È˜Ì\p*{Fëæ•>~èzàI,Ðb,r›´”ŽÊ x+ÇÚd_ ’¾?íi áÞ[PzÄœš<HOù$ÄD94A+n µØõe µ{…›œÜ”¹$»ÒÑÓ.^ͺ©övмüoVÝÔ9¼vM t‡Ÿ–褋ZU€ã¬ !½.£h"œ‘ó)àY_YŸ°—5åJQÀÆ'’…PdS GƒofÎ?m ±ªÅ·~k"gT Á MôZ¯7[zÑ…`ïO¯VñÌ?ë]cÓÄݸwO¤aCýCýCý!$ vÒNÚ5¨AµÑñŸJ¬ý÷ÊÆ0R[ýŸŸŸ ñp<CäöÈí‘Û!²/²/²ïφ¯Ëý5î+P6Ûµ‹¯‚ÂËS.ÙTtß®« BÚ×ò¤֘ߦØñ`·PcÐKåyÝ º!òVötÐ]áhf.ˆÌÎ~ ÎîI«Ðp"­*¼ ø¡éóAOãyÍó{ÆÆ‹€Ö•9k8pinÍv»@oKí³€=)UüÀÑ*Bªçƒ•[eÆY³ÀÚÙ¤Õ÷Πœ5 }¶?ù}oP¿°ÿž> ùÎ輌Дß|»ÚÇ€l^ùV@ƒ·…æ&-y ¶¦èQ€X´hvùç—€K--ŒÅ‹~Ýû©è ÐÚÅßîQ°:™ù%ïAڔ̑™ ë{oé çm6ã=(,þöÐè  lþ³t èÓÊëxâ9HD"H<Ä!ì…½°‰>‰>‰>X—X—XÚ\›ks`+Xñ¯6¾å <æ—ùe~ĆĆĆ€égú™~~SúMé7ý²ý²ýòŸo÷Î)épp-ùÛ—ïïýhû¶oÆBÚ2<ê@àÜÀ„`}ìp‹ AîÏtªîÏέ4è‘ÛXjnµ‚^YÒb_+`HÉø=£Ag&êßĵ‰i’f2´]`]úNkÝØë>°·ÖÊï¶dOhM…¦ÀjÓ3y=˜©Gm™ ¦tã3Ÿ2.Z;¿;È»5w˜ Ö%Ý‘ÓA›¬¸b'˜å…?mkºƒÚ22ˆÅø·ˆ÷¥ HH®v¿ ¢ HìŽDhÒ›ïï uÿRó.aÀ榀Xö¤x:€3(Ô÷T¹¨$ÏÉÐ>t³:‚»Ù?S·Bô }9Ò¬kj=ßåÈìÙê»+À™“1£r×?™¿À_à/€¨‰š¨»†]îáÂ…?ë,ë,ë,Nl¼ý/Ëÿ¾”çã½±ÞXo,ÄÞ½{xxÒ·¤oIßV=«žUï¤û¦s™îƒØÆ}£Wì…ÒG–š”¡ë >û= ‘YÖFs,‘z& (Õ—´&è½EkjUu¯ÛI‚´K[<ýk‹KA>ÊÒâ(poäÒŠåÞŽø@ÐE÷îhþo¥5=ÖÜ–±«>熺÷vÿhÄ`–ÿãájQì¡#ÀìÛ›ÿÓ È¥Ëò@ªGôÊhaÎmŸP¼ÌZ×^ ¤ÑL.þ›¦ ‹*Z âÈÑ{@“Üà ú+M;P?f%?|Ý©ÕÈ£Âß´SFs 5ßûÔ³Î_À¹ÜâGUúÔµïÌ´A2ØÅã@Dºó$ôkë=ˆõònÕ¦x/ã©ZgBƳ­k^€Hýϵi\ÊrRHCÒ”)S6¤•´’VÖsÖsÖsÀå\ÎåÿkÖø¿èåî]í]í] ѦѦѦ'À]û3ögì¹Gî‘{NRÜ&Ç]¥×lêôÕ[h´®àý6Ø|Zø#y–;äÉä‹É,Ф IêŽLÒ•ÖŽØxÀ“ÉæÀð±^ørjà)À Ö®:¤Ià­ôG€ é]ª.öd®WüÕy;N=Áºw[ |b rnýç‡o>90ê·ƒ«LZ ÖH©+K(§óè-æ^7Ì®Øo…—ƒ¾kîô‚T§- ê‚ä¾äw ./Æ[J€Ý€PD$˜ˆ¹—€&“G½W¥*éĨ8òºn.×Ç›€'ï›ÔÌ»Yƒ¬ßBóA5xYUð$×É, ˜ R 4}ˆÞLHfúe‰[ ú±Õ+§ „v¶h0tdLjòEÏóAβògœô}0ú P‘ŠT„ðoáß¿=ÓžiÏ.åR.ý·Êÿ(u¼'¼'¼' Z-ˆ€¼'ïÉ{Ñ;£wFo®ÒUNz…š•î£Ñ(?¸ÚžÖÌÛfÌzÒÏ·_Jüö ëfs=HŽ¿ÙÔJcË’³A]3×t„VÒ $l—¬·%~”²ãÏbì îÉÙšpžÊiRC¯ÖÉà7Ö.þ@÷6Ënû‚5ô8ó?¨€ª‰E€éðË¡1 °¾Žî=84Êtë.‡,j—œ^º ÌM‰³J¢€Á¥.Hˆ6þb™KMRÏß›R•Ô ¹€£gkˆDN¼ êšÌé€ÐRZ€„­³“-AãÖÒÄ@‰bÊõa!ÊV`àúœ™ IçÓÜ÷EhÀ7{€,4úèa¹Lׂ©ùÒúÊæû†:ƒÕ­Á5¿ YÏŸšòXÍwGŸP‡nÔºÊê•Õ+«2L†É°k½ã˜+ºÓîÿcÖù?¸._ÜúŽïøÄfÄfÄf?ò#?BF•Œ*UþÂð›%Þ/= ŽeÿúÛĦ ÷o­üñ1ȘåôO„ÁY,õL€>Á• …Öë6@‚Ÿ9çÂ92 °¤Øß š°îtûJ©4 )gàJ—Ôß©êy·•, ˜3“×ÕdŸå‚–0ÓÜ ìqƇvýô‘k]°A¯³Î .’ú+Ûˆ“2P8¤i /Í™fÿÄÙ¨ï*7ºõA“Ô4©$@\†¤ÆCÊ!·Ñðä¹àç\@¸@>,9j AÖ=î€R&õþNS§1¨çÝ[²Ä1¹ ò¸Tq“cAài_ ¾Ã8p~ú¦dÌr.JÄ@ïÙšññïp¬ê¯Ÿ½ñ3˜&‰>%WŸP‡4•¦ÒÒ?Kÿ,ý3PK-µ ¾-¾-¾íÌœu¬cÝÿ˜•þ¼¾ã;¾s¹Î\ÑõÑõÑõàŸæŸæŸ™s3çfΫ¶UÛ: {cNKZemáX»_î™8¬¡{oœ÷ ¤<ϯÖgÄÌ~Ðýº‹-€9žg—ìÔ¢N;è[ ÁØGIT¿ˆ¾—‹Ý»(þ‡ˆTšs—>²ÏÊœ\Ÿ»¼ïͨèQ0ß4}z˜‘A-_9ø?®mQ¶:¿Ì€_~Óì É— [È.+¥}ÅIã.õܧâ/ƒ©o}x(è¼²sI…4MʯÏùËÁd•룛¾Œ}–ÌT'G'ƒÆåR÷êr}4ýwôñ,HÈn•Ѱƒ?æ&@rCâyÀ'©éå×W,|â ÕhH+0èÕòD?ɹL·æ÷]w9d—6Ðίƒµ(p,òÆIúÉÒ,Í‚Ò&¥MJ›€s¾s¾s>„—†—†—‚|"ŸÈ'@.¹äþ·Yë#Ðõ 9¦½ioÚCBšPp§¹ÓÜiÕ!«CV‡¿0üUî®øåPôéªofl»ï¾‹€´3‚ÃÁú”IVèò)ŒÌú;ðÕÛ(àK]9Pý ÔÕâP+À£mxQZÿ›#ó>¨ÏT6d»óІ}¦ÿ׃×õXïÝ? ùRt;ØN°WZýB/ßqŠŽxi½ƒíÀº±òo§ü|~dÀºo?öÊÑ]€%ÏJ#Àe̾²;·ËämÄèzS·þÍoœ\®zr:`‡ÎÖ/WW‡ÖB^(›ThU ø„¥&`“Ôƒ€…Ë@ùVN,7Pœøš-) ]:»OúVƒCt‡4·‚5<´3ë1ÈZÏéö”MÛ5iÁ¥P´¶äõ}Ÿ@öÚÓ6^~X-MÃ_ƒK±CÚ¼´yió lpÙà²Á`ÝfÝfÝÁ#Á#Á# 9’#9¤vgä¿n¶ÿmp<¦scnÌAü@ü@ü¤¦¦‚ý¶ý¶ýöI×/4m¼þPòÆú¾¼ ¬Š;§~½Ò®ð.*z¬G3<ÐýÒÀ9Dj±÷×!H6G+ù®÷yÙËé˜êڵŸÊ>þêÐ ð=»;auyÍZl†@%ëŠÀ¹óó¼W_€H»¶Ë‡€}vú¨¼2þL¶2ŸxKÁ½tïôeÈÛ[|î‚õ~zí¼L gµÛNÿ d@ÙU‡î¾>R¸~ þ’äg âí]¼›V2x8\+ë ÀHS+@[ÿ¦ÿàIÒOÅ¿ t³ß96Øå̦’€½²ÅJ d”Ü8T¤)§ïé =LWÐ5îEe¿ÕÜ%ûË»$x?#˜(Mä4 ¡š= gë¦/y½öÍ=:—ÞðDî*.Ýa ::úhA[(ñƒÕ2¿…¬«Zvì7¤«µÔyìv»DZEZEZAththt(XùV¾•çÏžÞâ­g"ø§ä¿¾¸žë¹üÛüÛüÛ öMì›Ø7:3tfèLÞ¼#xÇI×ÏàA:Biú¶U‹.=eç¥ó‡´ÃîÑüÕ`=ëU‹õ ÜD<• rØRþˆ×—·ñ{ùï0¬±ýgJ¾õÌ»ñ—õJ¢s[§øQŽ”ÇÜ›øüo>‹9¸f‹×¤ƒ³zƒŒmØ£opØ~Hz‚ýøö‹¿|œš[õÓ !ºçëÚwÏ…èk+~z·;$.Ý^ë»0Ä‹·$¿îÑ™?/û˜9+WìS’¯Í6¶mðêžu‹*!yÌî Ü]ë³c ¿Eêä]:£lB> »½¼DHÀ Çï@Y[þì66%Ì!Ur¹øZzÛ9ÀݲÛï´p$¸Ô·›·€8µÂ/‚î°[GÖƒî³F†Úƒî²®…@7Û¥‘¾ Ûí_Â;AK­eêÀ©áæ™W/…/Ÿ¬· ¾ ĨM¤¡Ó?4 ä±w÷ಢwv<fÇ‘më—‚5Î>Å™iGä™Ò õv…¿½ Jó¶­\Ôø˜ÇNF“¾|ø‚3ƒ3ƒ3!þiüÓø§àßéßéß ,e)Kÿ•P¾81KÍR³âÛãÛãÛAÖÉ:Yi‹Ò¥-úóm±Õ&­}ÜÊ[Ï]iC“½ë¯y,ô0¾,Mº“c/Ž™î/ ¤0ù*ßPMªŽLÞ êz=‹SY ›i ®¹Õ/¯s< öÉs©1Ë÷eÓ„¹dx ,£5È› òú¿Ü[zxß`^ÙµyöK ‡ôºäb°pùA@‚ùé.èQšJC°¾5»û!m?/7mË}sˆm=0ç÷ÿl/‘—"/E^âºDÅDÅDEÐ×õu}ŒöýŸv]¬‹u1$ïOÞŸ¼’’’ ýâô‹Ó/æn¿\ÜÃ¥Uó7Bô†õg}¾ÒopÏ+˜öÐxÝ£c@²PjɃ€1Ýü^ v²}ôYÀb’¦B¨4†_j Çó‹ëF×yÛÈ‘gÊ¥3¨ñÇÆkƒÌQw5x(Ó†æÒÿ%'Ò.¨2ôH"RÚ ˜ mí9 =3/­f_ÚÂë\ÒôˆT•ÏÀ\’öqÍ0˜±•úœS•¯ïºª¯t>^›ªºœÞ©U½.AðFT}ºóJð£Õ®ê²L~Õ: ³)«MßA;;3ÃëA«J¾×¨WSÏz´WÀOÌÈý±_ö<’v€|l×"‚V=œÊéØWøÑ~•é|l>D‡­}ö,¸±ÒÖ'ó”Wø¥MK›–6 Ü~n?·¸ïºïºï—q—ýçà?žz–gyRtP:©tRé$†ƒá`ÒJÒJÒN¹ë‹þ÷8ÖsEÙÔvÜpÈýy„·G/Ý5ô®ØŠc+•Áå3»–ç¥K8XÌ’V€y=ë9Àsê‡;Ž/+L²ú¡Ù€aŒ¦vN#ßAN-’vêÀ±á@±“Ÿ>dFvN½AúUùôŒ= óv3¯;h¯¢v[F"öÀr‡Àb'KË4ÒðÌ•và‡ª&|cV'ÀÈ+’ ŒÃ'õ£Œuú>H™ýC¤ X‰p2§ 7jL¨pÚÎA#ñÙÇ*°ä×Ü»›Ü R«†uæ!Бe¿Os}Ü=2¸-ðFøeÐAþCñÏ@Ÿ ܘ¦U…ïš¾æªð핯K¿ÀÀh®Ô\ÐïyÓšl±ûz> Ê€šþ¤ä è§µgØ C@ڱƄÁ $—ö×úLòR°®«4tõ¶ëçmÆ0Ï<òKàŠÀV I$kyP‚dÂ:ò‚#i-!^Ã:µB=Hvª|÷C…/Ú$‡L¹Ý¾,0õ„=Å®Š]» ¼£ÞQï(¤ÿšþkú¯`-¶[‹Æ4¦ñ?ïÿü"¸œÖà 4Í@Hü’ø%ñ è¯ú«þ ‘Ó"§ENûómeÍw]:°¼öÓ…~Iß)îäÇcE•ÛåZÎ,ÎÑ¿ßùÀp¯Î±“E¶ÕÎúð½-…ÕA]¦˜† ç™ã^÷7­$x(ñ®‹uù!G›¶é]eñéIÐ ;žü|èí%kvÒe¸•‚ýªž´#!ƒ'@l++ñ9`Ëéé/~ð»´kA]ë é  ëøêor·LÊg@ sn"t£mü( nåX6Ð8Q»¸8*kåwÀ&\ÐSŽÜx:èšÄÚÂ7A²ëÏíé‚|åÎ(Ës´P6M¿WÆkUç©‘yc½ S­³ƒoƒ6ÕeæðŒöõ'÷[ß…z€, ÌM«²7¸7½ p¥1p›÷zì~ÐNîªè>аß:¾tŸÙaNý-mm­ goªû1ØLù±È}öcÁ1 gÚk¬ÏAç8­ƒÏÌ’EÒà}¿ pà>®,ÞòûÄkA¸¢S”èÉ»û}Ÿe§gmª>2hÂÉlá&á&á&P|AñÅ@rNrNr„ì²ÿãÉ¡þ Ћ^ôw‹»ÅÝ%¹%¹%¹'býp0 Ÿ„Ç÷º—brø÷Ǧvÿ’ÒQúƒø*«>0!ÖèðÛÀüä±¢OÀé‘謬ÎíWy'ùEÑD`w“²ÁÝVj€3Í5ɶ€RS:.ÛuÈ3VOç,pñ—ê«P2-t¤NSÈzîmOÖgNÆ•üªLìMìMì…øwñïâßAÆèŒÑ£Áž`O°'çpN¹]ý |ña&š‰f"D¿Š~ý ÜÏÜÏÜÏ §oNßœ¾À–°˜Ÿºí˜µÂý°dûªû_oéñPH³ªim‚4>´rùÐç£# ns{2Y¶ð()ÇÔØSXs²#6 HOó`)e ÀD7Æu͓ڑmTžWçO£±‹´TAˆuFb ÁZéýؘÛ°Êë~#Êy Mפ÷úÙÉàO ?èò5øR¡°É40gW^Óz;衹¹/‚iU:'¿98]Ó+Wú ‚’³¶v?°$P/ò Ö=r胺G§™þ³ðªÃýÖ9Ö7 OX­­@C 2t5d ø­csŽ­‚äõ‡­}´“Û6š’' ÿ9pF—œ±ÿ°ºíÿvéO 3¼Á1 D5Ó«ÌLÎ-© TÕ,ÿHêùJKLëÔÄO Ï†FfŒ„2G/¨x6h´¡ô?š´©xEèÍ`îälYqõâêÅÕ!àÜ€ á¾á¾á¾'è_þëЇ>ôä‡É“BÉä’É%“!cMÆšŒ5ššštâòdÓ£_íê%OoÞ¹ d.ÙŸ?»ØÓâmm@Y_;÷XÁîU–ƒ&­ìð÷ìá•ã½À)ßa\¯Ã@‚ÉY‡‚&üNÅ @‚öÙ P7ðIÞݤfàñ@©V1 òuÖeu2@:V«tº÷_¶tÈdì½ „d™õ9˜±Go=ß/JÖÒh.þÆ• `âG ¼û4Áón »Î_ êÆÛ&o óø€Ðß9R1 A‚R×ÔØÓâ*Õ¬í vðì*‹@c–þ¸Xpú‚žì”a¶ÔE| þ±ô«k<þМs›@ë$o"h½ðƪ>«U~³ÕXy2ózr·tÓ<~Ibø¶—ìxüo7Ù:¸¨ Óá[×Ô7ïg5Í<¬õÕ ÎÀf‹›Öë´Üú‹½NÉÉàgÇ;¶ #󧯋€–¹—ÛÖS:@^gÓ‘í?ù&øÊóA¾¥¦®I÷Þ- ó¾ˆM‰Hkÿ[ÀØÅûµ¤•µ ¼5‹«Ý %ì÷ª?YE]®x¤&÷äÞX·è${ëžìžì±±±q8ãpÆa°gÛ³íÙ@Wºò0íãò×å%oæVs«¹’ “ “ A®+ä 5 5 5&1‰IÀcÔÑ¡ìôuòéAžyô–µßSP§RÇPëë»>’¦KªÂ;µèÀ ~š .‘óHyÕåFÀ2Ææƒ&MÓÒÛÃ=œêšûK»8æšôö …rø5É™õª'A.¯¾ñŒŠ ³÷Î^üÈNZ¢!HZ MZª$ïlzƒe‚3®“ÿð˜‚îÐkÔlÒË‹º=šý<4Ik¯`¨N{P7ð€µÄñríÖ I¯ºŸz“Z¾÷géK Æšã¾x¼­«tµ÷9`{U‹–? %@Ÿ´½P5à —Ù`nµ—…ºƒ™œ9ªn _kCÐ;ô )g\äåìË!X¹<+¸ÙÙüܧvïÙõx÷}õÊ×10?¯»C>p8þD`†ÖÔZü,;›À?öï?½ þ±š×Õ|œÒ nïþ8çŸZý”1`~'{1+Wº«I5Hv8ôðêOÁlôW'Lö•õ®§mé {×Õ¢-5\{t¨p¡ß0>Pk¹{?¨Ë;úHHWxï}Ì~ì 1³ ìâ­ëçÁÇO?uÄ2`«åŒô6±Q±Q±Q'hp–°üûk‚œ}…Wxü†~C¿!$‡'‡'‡CäÊÈ•‘+Ãæ$t_rÑA;ƃ¿{÷KfBè’’ë»o}é- E•ÎnÓ(ÓÆ¦)¨çwÎ øÍËRQyå8ð0§癋@lwû±»£#L*O\AúFïô'ƼŽvù>÷«jÜÒé:Ðöeýø3È݉+‹æƒ ̈œÄXË, ÆF¾ö8CƒÄªác@‚-ššÁ]r‡<=bË݉×Cz9æ(!À°Tî:5[ª²€|ŽPJ} 5Ü¿0òšPHÊð*ËU€ï·+›L5eñ_€/¬êõ 7r•fƒÙÙSåUЄÓ:œzž¹ÉßÜWô!øRîí ²@7Ém¦$Þ^{ÛzpïzwÚÔSÀ|·|úÊJ@n¢8q.ÐÄʲʀzöhû& žý°u5ÐÈ~ȺÈÑÑú.˜i»^Ûu¸ß|0xz.¸Î³~ºt„~i.§K$#ç)pf/©³ÇA–‚©ãœÚ æÖ¬ë¾ ú†¾ÎjÐñd5ð½=ŽS@‹)L¼”è^èa-3߃œâ}R¼B•YW|ø‹÷}õÓPHn(\³ë8ž`;ÛÙ¡=¡=¡=,K–%ËÀ$LÂ$€ì,ÿ±7€îÖݺÜ*n· ˜fY¡¡¡“KÙÊsýÑ›¶ùö%Žt_*¸¬ ¡P¢è3ûËGl­ÿàÅ5@..t6 :7yVQwÀx—Ø–YøRݱ@Ä[PÚÔ7‹ CMy¿Üiß<Áx¾Î²ð) ïÔœ}æý ËÞ±¢0·ì”ƒ­A®NËË[ RƒYV¨a³Ot_"Œ–MÀ°`÷Œm ƒýï’‚Î0cýÇ@r¯WÔçE30ø S˜¤X ®ÝØò@ìÀÊ Éd-÷À’OÕ|k»;0ÜY>%•ñ! „Ð#E¿‚J“uR…5øå°êã’ÊM(m¨hà§$èýêï„Z‰Ñ .Eþ{¬øc±o lçƒ.`«)®ñ?,-374½jМná(èe6÷¿ÏlÛÓ~Îû´ùÜÒU=~÷ý[¾ÝÖèbUµR8¡ÿ,ƒ[‚)WI/ÐqEO–Ü^ñ¢µKƒÓ¦á'çƒå†¶dþ¶“uoÝgÁßZúâþ Á¬´Ûùçƒv³Æ'ÝJŸÚúp@‹f-Ü‹¿è½ Ȱ†Ûçµ­VÁÁ »hd,„ê„–GâPòQá;ž?-öó±z`Ç#*<V#«‘Õœ¡ÎPg(¸#Ý‘îH...øÇ¡ÐŸàfnæfð+øü 'Èc³Ò³Ò³ÒÿB;ŽÿýR°Ïvxìœ Ë À,ÁŸ4æS Ô>Òí žwIÈ-é=kœúf|Ãáw£3ã!w—Wðý):€' (Ûi’&Û¤=È£µ[\Xx¶tyAÐvr–My!d*¶Õ°éÈ*örਟ¥³@¿×5z+X}¬´à9`uuOÏèñõyýê¿é4ø6DôÔô°HZ[?é…~1àX+íØÀ²ãV÷wfk‡¸\Œ÷ÎŒ¹€›¼7¶p‚¥i3¸+ë×þJ’X,Ð0äê²» ö _`Ô`7_ŸÔÁP 쥜 $½³®jcí/“dð ogÝÌͦÈåN"ÃyP–YÓÀŸTÚ2:ø¤àµÃ7€ c¯¬=Ìõ4ü/þßr®Ìý ¬W4fAþ¸‚3€ÍµÞ¯ù8ÈCöi¿?ËŒðàkš= /*„.~ÖLï $­Ÿíó¬1v1¡3½º€O%RlÍèXŒçlõ¦¹wïJ¶.ý «w]øÓíÞªÁ€îƒ5ò‰5 cccO “óJ9g9g9g;ØÁŽ¿r€òÅ‚éoú›þàÎpg¸3 p~àüÀù ãdœŒ;q£ûYéÈ‚»ÀÜq¸xõ|Ê¥MÇkhO$¸1k4·Ë! ]Xc@k–n¨ òh½}¾¹,xfÖÑí^Hó¾Šw*ÒÓ§¥RK<}YÆP¥í!^Ö€€wJt>±Ó½ ÄÎ:2mî„’Q‡ºB€,ªr—Ü%wó«ó«ó+x·{·{·ƒÖÃzøÏ¡Ð‰,Л¼É›`¦™ifx+½•ÞJ û³’Ïž¾i ع±Š;¿ëÞ3[þÕɽ –¯‰TVM›¶òèwî‘Ò2àæÒéû ÈÆ¬yõŽEÞüÄ…€¡›Þ •¦‰0ÈÍi‹+îiYckÇ™ oïzzÁó ?¹+Ê €|oŸê÷¥‚|'—§x&~õ¼±†@œò‚˜DyÔžú J †€&b÷{h™<­¤ò’öõ“Ñ­€¥¿™TìžAµòûS!MˆSKú¿ƒzÞÖ¢Ãkf ¨ë?˜ ƒX~4‘W®V%JÊâÄâ¶_)Ѩä¯v'3Ík De‚šÓƒÇ@óýç½R ˜1:è°Ÿ£ƒYÁé@Hßcú³é»Ø D­‹­¶@÷H22¨F”hs¿¹ ôÝî÷ÒM—äG€¥C¼·€ˆ™˜Ì,Ó,q Öí: å¨ÎãzIÙøn¢pÀ¿$¹¬6ÖEZvnbËþLH¾R0{C›?w38$8$8¼ /ÃËs¡¹Ð\ÈY£?9@ê¬+ðÖxk¼5`>4š!P7P7P÷¤–ËãèäÙ/_~EÚ¼ô.÷åZÖ€–R)åÁÞàXe w2IÒ*mZøñúǯ3®¬Õ¤¡}E P¦j©g?éTV÷Ên ;4Eè¨Òe¿Ò¤uH x]$ð6~€%gs1h>é,ýØÍ+ ƒNÔï| $(Ë· !yC AßôýdôÓh¿‚Ë@ tº¦òþdà›Áî€wo¼ r}j¦’á<ˆ\+@¾[ú9àk¯øLyB\@©š¢Mñ†Æj´½){ø P¹¹@ ÍöGÏuºÉ-t®÷¿‹ æ~o?ÈBëó˜eɪeAo6=Í`÷ÉÈÎx´KÕîUr—¦šJ·ÚØÿ`i{íÄ3¾OoÖý•Ï«ÔhÅ¥<¦¾{vì`Ÿÿd<èÀµÞcÀ@¯_4u Èv•¼1ÈÕUþ&@åá’ÜÍ,]Œ"Þ•±ê ¥Tf-ÈT.d  ¬¦ñU<+Õªû€CÛMçVçVçV0#Ì3üGüGüG€÷yŸ÷Oºî°ÕVü6~¿ X—[—[—ƒ]b—Ø'żf‹ûXô7ðƒG·®3©k½ÍÀ4Œ|'A=ú_‚¼hüf@sÓ¯B—B`bi£½‹A»W<+ÚôΪç5x ÚâÐL`Rö)õšo'+^ úî‘ knÔzÔ> °¬7Õ ~ÈË€Çbù€}¬Âòô^ó”·ôïýè§@"øLVª¶¶Œƒ Ã¢EG}Ãk¿ ÈAIiåCž”Xê»Ëâ¹N×Ð|À³®t*–ž—œêû[‹·Ï”yò"€,ÄõÔõ§‚ü¢x_@¬—Ó¯5åY ýÕñý€ÏV¹äB§adÈj¯riÐý¾ Rä Nü€Û¨äN0µT Á™—60óaà…–GZ\ºï÷yëïÒÍ9æN Œ~ôú/™¾ƒ ÖºäÉFÜÖ—•¬¼ ¶émªƒß$¶úèDtR"üľ2.YãØ>d¶Ì™³Ý¥À!½Ö­༑– %CTÄëo êê{þõåv• äp3•À©cÝÉ#—£s6³Ó}%ZV•Àmi•À~Ã~Ã~ä1yL•¿Ê_z³Þ¬7Ÿ…¬?NYªKu)xÕ½ê^up¦:S©üqÂqño,»¼ ¨SÖ~_°§XéO@ ¿kªT®P§J¾¾êû7Æú¶ÉuïÉ3…n˜þ£I̹iój~Îsn=8eÝ?žœÖ°&ñ«‡€9ýÈ…«w"]’—ù± Vð@Zðä7Û.W\j‡·>íhÀé4äLÐÍî˜èÀP3Ý] q‡– º%Ú÷È]厓ÚߨÍÏì$µè÷‰žÉòÞ±’­¢­‡¾ÚÄòü¢y€§»©l¡€#šJ{Õi€rXßõüÛc×¶‰¸Ã@Ä„Ü@#ÿÑXG ¥©í6QÄÇ`MôEóAƆAÖŸÊzäÑô׫T…d¤lý±. ÷š‰îVO¹¦Ù0ðë7ÜäZ@Ísà_¾qù­¥M‘g˜áæAàŠœ*,»A—3Ïš v­àÈ@ü1Ék£Á¯S?Þc¤^²Äû­l ÈÆÄ™G·ÀS ­M÷J Ï«½ Ä6Ž;pL®û ¨çß»¸ÜŽÆŸdWÅ);³'[ê÷@•²&{ À¿±lØá“Ï8+/زwÛ»íÝà¿æ¿æ¿´¡ '…L‹YÌbЗõe}¼åÞro9„Ÿ ?~òÏÚp——¬~“A²ý¸WÈÄÂ*1ΙÒ™¬‰  9h½ ÖVÄÞVegvd9ðvº_óØß–~¹o$¾Œ~xäl.ŽT9ãb-Îr³Æ€¿¡×¹=îbÙî²Ê`_´ýΣ@ZÈYz@–ÉRH§`ù¸õ$‰0“Y !ÓÖô e­Íj²¤ÏÊž—C`YýÚu¾o:’o]°»: ^ÒkAž–›AžŠõ84$a²Ü'Ž’¨4Óz±³€lnt.Òý wHŽ‚a˜ó R‡åúÛã³dLµÆ‚UÇ{,v:xëJî ThòA?Î8gœ3Ü 7ÃÍMjR“ ¥R*¥à0•©L3È 2ƒÀ,6‹Íbp¶;Ûí~†~Òsœögά܊À¸àX¼§¹ú[¹dtC‚Ã:Ä,K; ø\ïñë‚©ŽÕù¸Ü9%ýÓãŸt_n`=pQ¤Y-rƒÅÕ^”ýÉçâû‹.P›ShÈÅüc‰P™Z@cË÷FVðƒ´@,­sNª¸|Ëɱá_JÅ”Áhà2$ù €}G•Nz›õH¹}þo´‘ @瀘À’H¥r§PФÛ'vp;9 0§³3Á ×hÛé[°»Hëà§à~Wðõº@z‡dÕëiß„èï‡.ÜT2²ª iñ;DFÕêZ£b;?{Ioð6,ÌXÔìn¿^Ÿ²°´WÙ:~:[×6Eƒn`$·‚77ƒÉ©ûyí&`ÛÌ=ÿ^×ôF_ƒÕÙÚ&çBòË’ÌüËÁ{°øê}›Àjl—¤ÏyÕßßÖ{±oKÞù4®¼X ù_‡µgxàêsfH2ðY¤¦¶´M¸gF×arå¿џO10Vêˆ{=ãä|ðê”u>’²ƒ“œŽŸŸŸxâTMk“µÉÚbV›Õfµjbkbkb+í)ÚS´rå.Ê]OŸ>=Ñà±æ¿mšr8ƒv==ç ˆ¼øè.­£Hñõ„€$ûX2Üoç€Õ,rYn1`x^=ˆ[ì¶íïº+ ¡@Õù§¦0@˜IÑi‡§Ûý—ß^,»´è—µ[@N•«“1ÀJ¬p]Ðd2ÝûPª‘yÒ vB¢T È$]ˆµ$ÖPûuç>P ¬š"” 9)^ÿ£|ûwF+å?µAÂl š$‘Øâp_xhRŸ ¶ù#Ëp2Æ6É~V€\m=g»`5‰ È=T~}ÌÚhîá¹À§,­9ðp-ûìÕ »Ü*ÑE`~̯¾úH>ìt¯ðh^•î­€g½m·¯ur«_ ìœìꆴUU~m¼ä{k‰sÜ¥îX¿$wíÚ¹ë,0û·ÎÛzh~ø¼#ûÁ~;ÿû³gg¯+¿î–:S PÔ`\ý-¸§B¯Üc Y”ñ($×90^Áæu[ÁªeÅj‚äÉoö°Î(¼óPp^,™µýJn¡)ÈjïÁ²Ï¹þˆd#¬÷ìZ`5ŽôÉÝ ¨Á`6Æ>>š :ÅÜìAjаR°y©-½å ˆ]é" ¼oë¼wÑgPáçvrÍIÅõ©È¡xuñêâÕ5+kVÖ,Ô Ô Ô‡Gx„GÀ¼b^1¯³˜Å¬¿ §½[‡€9%>õÐ%`µ°~óÏÒ¹Õò•çIÅþ),I‡ È™Ái»ì NK ‡ZŒ„мp7 ‰õù-ÖfCôÊ¢´Ý§‚Õ!}OÕ«A·nÝ0k58ÛŠdã= “¬#Þ8P—edN°¥“à/ñWžyGÏ-wT/7¿”#„ɰ®s;ºÖp³@$ƒXþéÅ nàÍÜ'ËûŸJwš?Š­ë˜oA]pGG@}Ê’g0ÏùðXi¥~·Ù (>.L9¦œXŸ–¹ß¾Ö¹ÔÕa:duæðêY€Sù—v‚®8vxk:è΢­­ËÒ~'Óýè°nþ±5ëê-rÛœr8]¼ÛÕÞ‚/92Z Ò¶V©Öx Ûet¬ô®o¼­Ák`~nxsÝÁ 4¯ûßÅÚ_°Î´:—€•mr®)à1>³(Ùº¬ħ&&ÆÞoä‘YÛc`çïŒÆ@6XXg€ÜQ¶~çp°Ÿ-={‡Ù"‹éLõ/w×»Ì/îé@EY@ ößÒ€9pxÙ»öÍéÖu®;÷Èê’·¶Þ ò«Õ3YzˆWÊóðÙ€g5–Ú ¡à^ÇMÆG»=å—r¶æ8Í@‚’c>5ַϭå‹ÔÝ jü%OƒˆýZzÔµ¢¡ìebÊðùÄ䣠 0«Ë•Òð°ÍV¼™LMêCá¹€âÒ¢\Ÿƒ|açÞ9%øJÚHÀ¯Aª‡ffµé[uÔcÀ:øÑo6è¤ÃM×õyVvØÅ õÌ)v«È<º·ìômãÁ{Y*ZO—W8¯Ù+ଠ>í\¾WV}ÿ PöéþRï1°eÇjîƒàùÍÎL°¿ˆ<“ÑìÇí–Ö@IÈ™ —y$º€÷¼×©d ¸££}Þw%{Ú oI!—ýbÚäÜO€oK’…¯ƒË*ìž ö–Â-kæƒ57MàE½1ð ÈÿçØÇÀkDL[÷ìVÁÏAZßH—³X§òšÚ¥}2Ã;ô"?ì^¤ÑŒK¡1À#÷»;A%ËŽ} ZËÿÞÛ‚M°:Z­ŽÀ]ÜÅ] ïè;úèl­³Áá9žã90ãÍx3äf¹Yn¹Oî“ûø£ÈX«™Iî5 wyD;‚\*܆€È™öU€¯ãœ@ÉÒ¬Â`÷ŒA Ž\gÍMÐ_Ÿ©¾³bàšÈi•ž«Á¡F+œŽìó.yÅ‚A÷…*¤wý"AaIyôw\A©’Ã}ìõœ§mÄv.ö_MzMLSÀâz]ˆ5#Ù ðé£Ã("E ˜!Ox/â>ö `§UîzJ/‡¤÷¨¯3àÇáüò³A=º¥ 6ç9€Æ™ê¬i(/Ku° ‚g¦_‘Ê@v IÆ=À5U{Ÿñ ðó±][Û_•Þ_ ¤®u™] ú›^­ÍÛ«]âCßÚÓÁÉûíM uJ¯ÛÒÜó¼÷b€9º6ÛÎKi4ˆ¤gÔÿÚcgl›±’»Mu¶7¯Zï6ƒ\.3­O€ÓÀôÒ<óX§ËÚÀ•`×—ñò.Hš(wƒ4ÐE™IåîÈ¢í`={tóÊÁºŒñ^cRÙ§AÞðjÅ'_ëúH#™jÝr Ø,}!H¦ÆVrƒNiX@ê;Ùáž ž[=p¹%¹xSîÑÞ@¡©”| ôRÓ×±¼Á 7ÉMrÈA9(AoÒ›ô¦Žáü“>~ø*V± èLg:ŸÔ¡1ú“ùnÚù·ƒ ÑÊ´Êz?€ 15@® nÏH©ËlùÔ¥¦ñAÚd¼_[–A)q÷d€„¥§=¬žîé MÜZeC@ú…fݺ“‹$…Ý©o=Í_Éúr<~w+ t3Ëäŧ*óå6¢c>!ÕÃK<àg•”€D¬3Ý QnñS0â$W—_ýíÔÑÎË$¶9 ru໌ïAK±ó=0¸Ê²öíÑ•‡>]r¬Ã¶1€ð •R—6| 6̨ r™ÿsYÐõS ²U·ë@ÐÙî-eï—8×Eꃵͺ'8÷˜—Kö€>ë?zä(øw-ùýð¿:2eM5`rä´¼€ÍÁ™À¥ÖÁB Kd5PUÏõö¶;·ìà‘d¸¸¬W½ÑKÁjæ-9ò)X;t•7 dpziåg€’¬Zõ?>´ð§©À*M7_õ© KÜ,¹&°7£"H}J­Å †õ?Õó¤ä…¢(H„gù¸:Ø.cÈ•þïe=€¨v5çƒ ¤‚U˜ª Ípà-Í4¿O–oûu €•¬d%è¡#€+¸‚+Àa3›Ù :Wçê\Nl|ýýi~¥zš¶¬Ä·î@z"™Ì|ùÖtª‡^´”vÖ,ÀÏA4ëÍ`Uàöœ[u>)±z9à멦`¤tÚÑE–Æ;zèžÞ­òÇ€Ð8-UlžcÍýK³KÁ+=H|çïNPŸÓ†žÕÅþ€#'Âü…Tä|P£ëüg@œÄuÇÖÆ\l§Bž@y†Jþ{…)§ûØÃ@µÐÃá'€f’ÆF 8ï™SJ€¸éæÖýêÈËëÓåGI%î*Ó0Ò˜º@bnÖú“½ aé4¦ RÄ·©“[¼ŽúèÅÖRÓä«~ðQ°îÌ8RÏkCéÖkÀ$ŸØ[ÔrçêºOt.í#{ì ÁRî™ÉaSä ½Ë{ät/ 2ÉkæolÞ°kôE? ü¸ççŸÆU¯VÕ®5A%ñš®mèŸ(R‰ ZèÚÐC@Kk¤>`iyaQ¥VÿwÕr}ÔZëÚXë¿èÝøÖù‘ 4jˀ˶л@¹ô;© ø•_ùø™ŸùŽÛ½óÇñ¢Õ¨F5þyÈ$³<­˜’++«äÐ/M¡¹8ÕþÞ^:Öªjßzµ7¬lP8˜‘Ò#»F½0p0¹§´è–øi‡ol¹[Î-£ €ö^|øÐÁî‰Avgu­ä,çly]Žï/ü- ³:Ã@‚¦WòiPãÝV±íÁëA]ëÐPÀ¦K¹¡þ-m‰•Z-¥@Xb»õmA}í{ÄÒ—#O‚&µŠ• º2ÿDÒ›êÏ&ý$Ãú*ð9h©u¬]œ6¾Ò‚H˼ ð¾³–tÞ‘k´1 t’v€°tÐ(7qèÑ.‡ß}?6²xH0í’ UA]ë^g#ÉN~ù—úÀ}:Û?ø\wy@:w€†‹ó6| ÖëºÝ­XÂû€$8ø’–þñl× ¯è d“o_|æ6Mê˜áe‡±îV>È=þwÞ Àë±~G®>‹ÎÉ? d~ÎMº€ÊYþ#HEûãÐЄÕÀ)äÞWvPz)ûz@¨F;R+»øßè4Dh”;¹ôšèU‡+NŽ]Yü È×iWVÈýZš9‹£2Ù¹._”Ÿ’™’òƒ»oôþaçå¼E+ZÑ äyD­ªUµ*è+úоrRÞ¶¾°Ò¬Û뀇xAò;Ô!Í|k«ý5è6÷†²Ë¥Àª œõyêÀüÂcSÄUgR$"Ê@ä¥o€î‰5,üXïµˆß ÔåT«‘@ûrHƩ夸í(„© 8ÿ´¢ïOKÜ‹A=ÿ«øNÀ2™n •zZ¹¡æ•/ŠŽž–rƒ›êùÆ~<ùœ¨ÕÊ= O—ÿÀòÃç‘¢?éK ¬} Éà÷äâðÐÜÑ@÷œuMg€V8xÞ²±€o&$óá–r®Ò–x yD^.J^Uú3èŽØÞ£u_ð @òÎh5@øU[J{ö€º´e/p5õÓƒWeÚ Ý½½%ïƒl-«µç-5ñ)ù>0.QõèàVï÷Ò!À5^Û²‹€k½óËîõœ²·}Ž^ òkì´CÕA"îÇ][\ X¤Ÿù™@'™ÃG Áü/W—¿åVjR ¤±ã„‹@M0™øVÔ>ºÛ›ë\è_˜ø$ÂÀò ÌSË'´Vˆ<,¯}“”ÅA·ÆV¾>ê‡;yG´ðˆÞªU,Ë œò–Œ²gžô™¬“u2h7í¦Ý@®“ëä: ÍhŽô–ÞÒ¤›t“nüQ ¬mµ­¶=’íÖ«Î,ÞÎÞÈ6Оvv° NëPàp„"ÐÙ¦—ú~úÔjõ@~Ž×8úè¾dëc“A,´>Ýl:øMÁ„ËË7 a3É« rŸ)qÛÌs^ML¿¥÷h‰]+bŽ[Ç<ª1$àß»ÔõŸ/}PjHÀWÇßð¶ÆÚ€šàLç6Àgøo›G´D¼ÆÑG@]m`R˜O:ƒúrš» ıNwê‚&Í«vŠp)«ü¾Vçƒ8N \TëÃ;@έš}FcÐdá—›jö/Þ±kXý"ë+†AllŽ·“ºÕŒõÏ“^öT¾ 6Ǽw‡Þ2Ô÷&&‚8ÞØÐÓ I'#t6«™”é­º x$¼.§>ðX|à¡|àes¡›ò˜ì³¶-ÜÍŨ,K²nŽRPκ‚Bä2PÑíZÜØ®ÕÜ›öòèr»×IJú8hÒ<ïÜútôåC§¼åö‹ÖfçþÚä 8ÖûÀ@h ºPKüE`JÜÊrÁŠÛ‡‚ÕAl¦È ÒÉÝnÞö¯“YölþPǬpzÉ}Þç‰Æ ™V³dH_§^ø û'…éJÌåùþã!8âˆÃDoÎYŸ<É“<ø#+ô~ CÊPƒö}[Aö„Ϫ:!1(m1+X»£¢5Aº>O¿˜“¹°ÖÅ SóóW>æ2«;”‡¤¨Äº 4M´-YäËR(Ö2sB)‚îòØaÀ²Ÿwe#`k's6€¿îØ"@u®¶ )ñ¤ŒõÍÙIÄñÇ$ç€&œËCÓN®,í¯‡A'&EGƒHKïRÃèœÄSe–›åf9h_í«}A–ËrYÎÄZì[5­šVMÐ{ô½Ì³Æ¬IÉm€Åò¾õÈw™3ªÝæÊÒŽ¿wâüÆë@”ïu ÈîœÌÆÍ‡b ¦_Yó}õÀz4rWÞ7€ëO45A§G;Œ=Àiº °d³üĹX_ùÂj ³Ï«b»nümP/¸#m þêÒtP×X‰‡•µR€õ'SMq‹Ó žÿIìû«àñrÔóÇÇN|®Õwdt;þþ,oÅuyÉ< bYÇü¨gæ¶&8.< ¤}8½ÂpÏ+Þ}JSПö°d4h?˜3åN©Lp{Fêä†Ä^Ðt/1-,©-Kùã(&btç^0Çü¿ È}éG€³ä+뤓€4Gs4t‡îÐüQ1&½¤—ôGFËh ò‘|$ÅS þŠ?ÇɲË#†o2ºVm þ0µÅ}‘º¤±Ý!tðsVµzé ãö÷ZRôSì>ú;½lLT)ëú²;®œ,µvjCŠ©šzC¼.!À#¦+O7é>PuÄj€„쯬–  ÿ‹â€ò2)¶†æ¼ð7ê¸4–oc:y@@¼Üô ¨gfy©šáPù #ŒâÏ¢„Ù ªÖ­î6\ºôˆ3>üHzÅWN¹¸µ¬Óè‡Ñ6WaYeÙ圽ÃLKî½Ãý¼ì^ÀJ\Pv=è÷¡Ø\À¦š¤0I6ýÿ²»øTÝűž {ŒlZ`¹.PÝ긘“´‹:Oó¢õMÊÇÕXÆtô.qü¾±S¦ÔõÌ4/Åúoÿ)}Üé® IÏÐÕ Ö» Èi¥=ö ©’½©þ} ñXŸ‚; l³/"©¬™Þe>w]ÐÛÜiec€HbKÙ Ï»¿ÅF6•dË }ˆG1¨+Ãd-ø·ë)2ì¯Ò¢yûàäh¹ø­üV~+«ä*¹ äv¹]nçÃvx’'y¬[­[­[AÞ7ä p»¹ÝÜn&ü7œ³ÎéçVz÷ÆÏ] Œö†Ç eßiqx­´í¡gA_.ÌÚþ;àð†Õt^âÝâQösæ€D®ÌNA v° Pæè +œW¡7wº†À\–uðµžyPÓ<þ4`ì-¹SœS%•=ðyž¿’Ô"&¦ët:ð¼½'˜ZDÇØ ÄHË<K‹òô‘ô¦(}ªë, iŒ?dˆHà<à“ð¸¼s@m3³m äRv ½ä“¿iç ƒÎO¬,z{D`7@äêìT·™Õôü¯Ä!ðY¢ÏƒºfQ¬Èi_Õl¥‘­ÀF+­Bjg{tvZ¹½ðwúøxÖÞÜ8dð;ƒŒØ?©@¹>fª÷›³PòËè ÐN‡F¬n r[mºOiœ¿ô€Ùè¥H†«–ŸŽyK@¿MüRô0`Ù]ŸÏG†e×+ïïÉúâsËÇ2 üúö¤À<½YáÛÚÿÜI¯³×Ùë ÒCzH°úX}¬>Àd&3¹Cî;@ÆËxâ b7êFÝ(œóû‡öOÉø¨juˆ½ÍùWA{ùË^koö'õ3@+¸ìçGãŽMÜ%*ýA·Øñ€|ÎLpqå€a ô ›ôk zðƒô2 HÆXŸÆI¡;A‚~ý²“ìYü.ˆx»òFФõsZ .»WŸJÞWv=ðD胜F@¼¸âîÆ@DÞ‘ øØfWU™~0Áß+§((‡JŠ'Î^ ‡Ã ;™gÝf±5's8§d®®¾š?‰ûˆûˆûØCí¡öPÓåt9hO{ÚƒÃ0¬'¬'¬'ÀÙèlt6‚+®¸Â‰±ò7…ó[ÆôJ÷‚^žŸÓÛY‘ñ9خӮÀÝ¥5÷¿Ü"»¬,Ûšïý êËe¾¨ŸýÄñ“e·ƒ&í-.àëXm4µ†ú{Ív·Hš‡Ü,6 ®VqO z# ìà9¡×ŸÑÖkDÿæ\Ù¿ó1HÌñÂÝ­Î;ÁT,œ`9H}'špçF÷éœ*C@2Ù¬ãAg©¯µA»Im«9P&¯™‘Àáë* †e^X½è3ûŸúl& ­kÛòs|K)-@lk²gú2Ô7€úÕ£ï8~QYŸr}¤@»˜ò7žâ(Õ*P•˜yæ|m:<Ô,¯)8o¤ª˜¤v38¾¶õ^À @ð²àeÁË@>—Ïås >õ©gpg€4–ÆÒœ»»»!Ö?Ö?Öü£þQÿè‰Å°õhÈÍ|¬¹ï4,¿ªý¹w+½}ãE …æ)o0°Þ·ú€úÖéÉw_^%ÅŸ‹Y¨gŠû¢ÈjÀ—¸ô:GFOø$²¤"hÒ´‰Ý¨Ì”×@]ý5æƒ8þ;%/€&œë²S…TZ/ÉV\!wZA. HRM¾*‡V¤B«‚ÓÏâïHln,_ÀŒ³&¦V¥ÛÛü Ö³U«´²9ü]æ³Àžù yE·ídýfî,š3@,_7•’8¼¨[AuFr:àÉk¤J—n5ßê•õ»OøqÀ“R'åHÇXB*dh âxKŸuÍÆØs@ŸË7@÷ÀóéqÐg §#åñ¹HrU —˵ö:AÁAéç€T—¥’Úà+ã0<Ø/½3Èþ†ÄG Óu¨é©Æi€àS ÄáN7êÊÞP@™ÇjP×9hy€/ 4RÒc× ·ä–ž»¤¾ýmh4h¡Îw Æ:3¹ðd|¹¾n3ßê:Öpì‹Ã‡Röá´Ø,ï ÓÄ$Àê’5¤æ/`e;ggõþüþøëýõþzpîqîqîi ¤'­rÈ!¬V«8A'èyÌc$·&·&·B„HŠÆÿ6žá3öª½ø¬‘àå¼z<˜usÿRÑz̺ëf÷jи¬2©EÖiåM*×–ÎJ$ArüõÅ•@Øu2é•q)H¶-\¨wvÑ,@ùDSµœU$õ{vŒ_¹hHÀ¾*m'hRZú’:bèHÇà„´‡ì~Ô§~ù>BÊ ,;¨ 2&x{Ú#à“<=a@.o\kÐ*ÜUÿ {“¬¢à+Àitûãæ¾ÀÔŠïµ| ü§¬ªÁÉ 7¯úéõ—€×ÝVрϵ²$`µuoË:“ ‰Ú—ëÃÈpPOç$‚ ¶ï•<štžË‰J6—‚8ú»bÑ¥€ò‚öBVCi´Iûø¾xàŽƒÀ%ú¡;PI„:{Èéf@FÙ—j‚ú´æ$ˆ‰Øv(Pä©à”´ Ð@âýÒ:€bQ$À©¦™“LÊx>KƒF€R‡Š€¬˜ |/.j\aÆøÅÀi-+^ hìÔÝ{#wš”F;ÒPs:h™6”yÅÇfƒT¼›·t_àƒôàÕt†g½Á²*]O­Ìã‚“™!þáMª>Ånm·¶[ƒ,”…rÒq¹'xÊÙžífv3»Ø!;d‡ ~0~0~?IpbÕ_N ‚Û=Z·`.˜*ÞÃñÅ@i¢íA“ÖH×”;øãàIcžv}Lößu57ù P#`e\ú|ø÷ŠÃ@/ˆ6Üý"àj÷ä À¢š .Wt ÊPAú‚&õÅd1¨ë5:–Ó¨?äMkµÝ ¤©Ó=ü#¨Ñšfài¦ùé¤ÏLmfŽu¬Á4àÂj:•@ ýpÏ3Ë ¿6ÿX†XWV‚=¯½ÛOÕ¹îüOôAõ@‚’oV&­ÇÝ2@qË}=AT˜Â2ërPÏ»¦ø\ÇtL\…üª^ý¢a IóBò r¥.Gí@=kq(üâ.( üÍÅ ¾ÔIö[ H«@‡4l²ËÙ©='}ZdR¤U mZ È{Z g›> 7'4I3«ü¾zåãIÁÃwxV¡t-p~b9ðDô“Cß‚¼‘ùnõSbY¸ˆ1ÐtŠu—ߤ²5+Ðä™´Í5JÀj‘7ïÔ… k/:`gIçÜ~V…XÓÃ|±rnóì??–Da¢0QvU»ª]¬g¬g¬gà8üÿ¸üA‹"ïÈ;òX¯Y¯Y¯A`V`V`Ä‹ãÅñbP_}õAl±Å†À[Áµa|f¹ä€wµ\k×;ËÚ†Îæ:Àâ LŠxF·€écŸ—6x¸öÌ‹Vƒ¬ùÈyK@ŠÓ^¨:Øe~Ì=¡ÍãþÁOûb0@.§s )ííu -œ‰‘}@·@ÇH- WZjƒ5+£´f>Hz¨eö“Àë.'°ä[+5S$)nÒ³üù`Úz?¹¬›k.ëþ60Èš¸Š^zÊö8°žªÝ­Ûƒ`^ÜÝð›4 Ûÿª°+àóœ^ Àš”ßãÿmÒðu«7°þ¿òÎ<^§rýÿïû^Ã3ígÏöf˼%TfŠ”™“ ‘JJ Q¢N)u’’4Ph¥©¨DÆdJ† ™ÙØóÞÏü¬uÿþxžÍn:çtNßï9çûûü³^/öºŸ{]ë¾Ö=\×õùDËŠ³@¸ôa ׃ Y—•ÅØ*®ÈmD“A$‹µÀù¨þ>°ß –uEéF õ{¼7‚Øm^œª@¤‹g´º Âä°#>ڜĸ#„[<¬¥‚(2{%l. ’Ÿ *Ê‘­ŒŒ×EÒ~Ó"…(@Q]‚º/0þÄ y©íëNQ9‚^xÂÝ6k6ˆI™uï¾òXU÷ùªuÔ |ê ? *”Û~MeˆthÁõ .v¿P«  ƒ½¯ ?—ã–a–`î1÷˜{@–ÈY¹ð¯€Þô¦7H)¥”`.1—˜KÀßÇßÇßç}(¶EøzÀR·Ùwà$¨& åPíµ¯][Avq]—6 èËvFÿ(Ä“]k*zÀUâÅp¢ï61ÓûRù~–ôõMð>(‹Ï™ ©Q:°ì¯ŒØéÔ^‹;Ò×@ Mc‡zÇxȵÆHÙšñ2p‡²¬Ú ÖëiŽ­@DÌ1MµÜxüä·á{lkµ{ŒPwŠe4øÌy1ë‰nç†z¬ßPÅŽ—ÕÍö_)¶‹•@ž†v%ˆCi®Kk;ߦ?rݘX¶ÿHP/ŸN[÷ðnðÕülPeªcô`kŸ@èÝ`KýI0çd{ÛŒ1AûÊÜZ¡ÛfÄŒ˜`5°X À†4$È r‚œ,d! ËÊ÷OÈ'ä   Ú0m˜6 ü©þT*ç’GËἬrFãéPVÛàº>ÓcŒ;ÀÁ¿ñ ºè)ƒª2‹Ûý=JÞrvJÜ Ø¢|°ÙÈs€O]e·QUžÒ?ÞLhPõjÇ’ªs¸Vîá`Ÿhʳ ´’ûöÛ :=¾·'pXaU\âSy=0[¯êZ¢¦HàI°ddk¤D/4ÞIîžVYMZ•;`þùn²ÙlжkÛµíçÙM~ýW 1"(‚"úãúãúãàøÎñã;ðo÷o÷oç…b9ŒäĶUÊ@Û—!›) ÝHP^ÛV^ýog¤´ÒOåão ü_"îmâ{ç¨äõ`w/j¿¿¨±e?ojSt–?°ôÛ;Aåj Ìñ >Ž ÷÷õ½ÕW ÜÂ’7º8(“+\£²™Ü rWt¸D\Ç›oø˜ÏDîþýü‘9VÍÓo}×ä# gÕ±¸Æ{=ÞÙªRF‹û@t4¾Ipe*dÿ°˜¡bª<~4µØ¾PÑíûAE˜de‚ÐÄ'Ñ—Hå( ©w$ÑZ X|¨ª~u¹aUw€:ªÍ0R@}~¾¬#¨™ª¯u?™\@ô\ª… ¤ C@ÍŠ® }jÏ:û¨#QgÈ B‹”Z¥*Á~D9Ô":®þ >¯q´Kvꙹ ÚîÜy¨+ö|»-¨œÜÝkW‰âG­ PªBÖ( Q„µGƒÎâ@§€½ Ž*ÍNƒÐáЀ€´Ÿ*Ÿh™ †3éÚ¬ l%j¨ª†BàŽÀ;Àh4‚¶D[¢-žæi~£ ê×IcÃÐÞ×Þ×Þó„yÂ<ÖQë¨u+üýãì½ÀÕ¢V»ÎU TMívûªÈÇ¡A½ÃZñ*ð˜yr„w˜Ù‰s€ GB:­Ä4À”¯Š˜ƒ]ÕíxÔ;'ÚÔšˆò5â'¾„s*">ìQóòÅàé‚é ªïoûñ:yüƒïNþN¿â'Ñ™gF¿ìu{ú½¾ ÔS‡Ç/¾ÔCGªz¸ÐþÐ~ÄìjWwõì©ZWÑFoæyð)Ýž¨hÓ@sP»O4(.@€ŠÊ™áM€.vØŠ\$àëÄg€Å›ª ä>í0¨ˆ9ÜÕpÐ  ÆÙ‡£w€Z ú²AØÇ'q{8âöHb5Ï€Zí_WÔý‘^?VÉö! ¦=Óž25õ‰._ÕÌìrÄëžïªtõÝÿ–‘ ™ñÙ… êæoÛ:ÔAëºÐÕ fªùÄ8ÇÍÉO’¸ eœÃT¢È ÈPM#ûBQ×VG<~pµ­Õ´³ÏQAü.xoðÞà½`'Ú‰v"˜Éf²™ òŒ<#Ïð»Ú¿ÈH#4ëÄ:±Ì*f³ s¹Æ\(õ•úJ}à^á^á^t À18cHÃnàËÌhØê2ÏÌ[ºfèý*5¸¸7¨4m—»þ™u5€*yŠšIö–‹¢Ý,su µ˜Lêžøæ¨½‘»ý:ˆ›ôîÎú >—GÌËDCÑT°^ö(ø²p5˜m¢¾p/mÚøÐ³7u¼ˆ~íÀ¼ v•knù¢l ƒ½#¼Âw¢ig¿ß ÌÙßáíAïÚpº3ˆê"[6U\{ö6PÖñZ_ѻȷ»Dbú©fmAÌ®~Iw'à*ì̼§|{?¨Ó9Î}xt—ÿKAÞk$9Ú€ÊsMJšؼ'b”Œ¥œ9ïøØÍ\†._,tnO9 Øj¬J;±èð Á7ŠÊ@Ôa¤ø Ôeê"kD‡zÌê5À>‘y×eO€z"¿÷Î;Aô]ÕÐ. yNu-+22÷>·Ð… J°F GcUÚvsà3š$1Ò¹0ýMS/»ôK ºxVNµì¤ã›¨ÉþÕ§Wƒ¨"v‹–;ì÷Ëü zºŸHökì¾ÅÉÀâ^.áÆû矕0ýiw ’Ô‚èHPoøŸ9u+(½øèþWAü˜òxƒ@´¬Þ´ûÛ€7¿û÷+Áöç_¼³!‘înºäu· ¥¤-l¬€ ÍE oþruÄ>êж¢§AU;ÓeK_°v|ö ¨ñþq§îeFg:‚¥îé¢gV^ÛI@}³ãCP{rûm< jdi£7Qõ¾j ˜¢hˆ¼hHm«þ4`GK‹ÞỀxŸ‡IPLöX7‹€Ruƒuh"O @˜Ö¡á ‹ƒÒÁ¼ðëá ¾Î_gÓÊvãX(öý+½”Ö*­UZ Œ½Æ^c/˜ãÍñæxŸËÏåçÀ˼ÌË¿ÿ}ýûBÙ/ò"/Bô­è[Ñ· Ì(3Ê (Z<´x(döÉì“Ùœ©ÎTgêùÛBùùïî{J»­Sㇷ†œY$ÀꬖéGÀÞ‘5­Ó0ž¨èµd„ª3P;âó5èÆÓmÚ bè±=ŸýšÈä‚$/‰'% òÄõæÇ€M“¸²uŽÉíWO „8ÄvÉöúƒvzt¨'­§"ãMâ©´±ìÇuÚ~äð j¶[jRàÓ³ƒJË&gˆJƺ”OMÆd\¿PÐ~ëKs®Qöóˆ6Ú]Æpb‡‡Ô:kJd P­l Äçü´6€^åÁ«¯ûBו>=­Zߎ.·9oO{ñ˜ƒº«ä¥Ãn°jìôθ䣋{/ˆhòâì×Ážuöí£¬¼Ow] ê”}6Òp‹­2ÆýZ~Š&zŠÙ <ú4ñ&(¿š·Çgê ôŸÕ–‡yIùAήѷÇ1PäOþ!øÌß2wDVhÛ t¤½#¹x7]Ñê¯np8ÓÒêî©0¾æ„æ„æ@^£¼Fy ©sRç¤Îà:æ:æ:ÚíŒv¨A¸Ëü&~(ÇHF2´çµçµçÁ1Ú1Ú1Ìáæps8):Rt*¯©¼¦ò(g›vä¥u»p¿¨ûLÿ©ÜtëÒúð½Q=úØÉÖ¼ÒN`¥íùÁtò\»ÈØk½Ú[jwèGoIŸ>Ä%Ž.•t hçøJAh£e^PûÕ8O‰øKÄ(xð‚zNúµáhîv¶óýTPXÄôbÔˆ.>S7íÜGÒGK‚Owº.Iˆ•ß¹„¦v§Õ!G¶Š;ÀÖßì…M0¨L:ˆ¾Ž½·ÄÂe„ê”váÁ‡Ô0ëëu°šù×íóxƒÔ!@ܦßîzø ürÄE2ÄìÄQ5ý =иÒ}‚ÝèÀØùZsÈýawPÊ~E;9–xŽ‚ âÉ…é¿ ÜQ ÐXg@„h¨6MíJKa—lÿ劲ºA5Ô^lT…z5àWÍêݯ:k€ ®ª Æ5Vv]ŽŸÒœu³áœÎY\ä®ä@É’`Ž3Ç™ãÀli¶4[‚–¦¥ii€ÿïÒ×ü!ˆgÁ•3Å•O5î[Ü·¸o¢ùEó‹æCÙ¢²Ee‹*,µê‘àMÊ^|Í¥P4´¤äØGYzíp8²RË®ò…cV¾ F]QX$ñ†ÌòeUívPÏRÊ1 ÄŒPTXë®*ƒ0Í—ôZ€½é(µ9nhór %Ôaˆû#@É…‘ö ìèæÒ‰ t­‡Ç‘EŽ>ê“A$ —öð©la¬æFëû%0o$TX ˆÆŽ k„cÅêCŸJ…‰á‹r åXþ}ìÜ^,Ö/‚hi¼ä>w ļèŽ` Ñ2ÂY`½ k:-¹Æµ7ƒðé“\ÿšÀÅÏ F{vUy¨'§k“@MòG} "Ó9¦ê\P>p< Ž[B”¤Ç)çY€ð۠¢g´aÜ©q{,” Å“ cö°ÉUKõÑUþÙ Ö;OvAxD oÑ­`NmzÑ«|S¶vÍY ŸAûí{Ó÷¦ïMÏÏχäqÉã’Çž¤'éIÀö°çï=};üÝ%Ð/ Fª‘j$„z…z…zAqÍâšÅ5!<'<'<²J³J³JA›¦MÓ*°J„®Ëÿþ ¾Q‡óVï!Çvc/ŸöõvP[YElŠõ:ˆÒÐéõ¶ø0ð"`SM]@Lªg.=Ø5œ*miÇ(/ç¦Äòï%ÍÕ€Ô> -¢¢e4fÒêS¦v­÷PQsv¥€E+qDMÙÈhâãê#;¯uÿñG¾êjUtCþ€àRÆ’Ra‚ÐU_×xPaÇiåu¶6~ @Tˆý N:›%­™¤ÏvÅ@Øþè=,°Oöv€hgwýýÁ¼ìècƒ8hnôîþó öòüú?Œ«í·ŸŽ\2“ODP…桌dÀ¦‡ˆ¥n„ÏÉÌ^èi¡lØå$eŠÛãPaéÅìQª„õÈôÔ} Ž‚äé[-Jn?[|øðœiôÁÕÁ17õ‰ÚXž­÷¬÷¬÷àtÕÓUOWç½Î{÷‚×åuy]`h†fhÀ6°á~ùÿi âzq½¸Œ•ÆJc%xyyó™Ï|(Y0²`$°žõ¬?ŸcZÚá:ƒÀ‘¯{œ_޳"öÿ¬Qª»«A´Õj™S@½èšS¹Dc¶ç7 =þ,ˆ÷Œ¬ÁÀ\Ç«©E€ßZWÖ„a]ã‹é%Ô V3[ûë˜*„†NlLù™=ÒcïIü%njÊqþ½Š,ºˆñ`ßhµvƒ¯µÕ¹LU³Nç1àx6u|ÅÏjV³Š./º¼èr»Ä.± \—».w]~>^õ{JðØÊ×`åLæBs¡¹'N8 ¾&¾&¾&Pf•Ye׌չž9à©‘þ`͉@ZZãKB@W«=mA5}õtÉñŠ%!F*Špu4ÆcÅžÊ'â=Õn’‚ÐŒùzìË~7 Ås*°äæÈ_› âü3åÜ .l5ÕØÑ¼¢g©Œh Y\¬e–Fo TýÈç¸Ï`Ê#¨ÇûyMÜÉ"ä’âz1X{DóxBoµxEÔ"Fý—wþ*êòºÈQf¼âIvèÛ\µfbµœúgù_ –Œ˜/O3@Õh;°£Å/šJ¶†D¢ãAEÀ*?þ®ÿ3{Xq{\í·G%)ñçm,Ÿ7Þ‚À¡èlq-P9M4z<]«—ß dý|Yî3|†Ï€@×@×@Wð4ô4ô4c¬1Ö r¹\.—ók"·x tñây[ÙÊVÒCzH‡’×J^+y ‚‡‚‡‚‡ ëõ¬×³^#bDŒ ‘`»jx²ïV(Öwî˜?ŒJy«¾;ÎxJSA|Æhß0Pg¨cÅsfÄ…¿Ù“Z1 û¨ý ߆cߌÐP!©B±¢ðEñ;~®šÛô ¼€4K â:·^mˆqUÎ^~'¨k5ú$Tý¹«9rVT|$û½r€jâÞ r¬#=1ijæJïnbî«s~S\þ"“ UW\e0È9rŽœò„9Öó6xçÖ÷÷Y%÷¿Vfµ š|[œƒŒòi©j¹˜ ª€H<Šüˬ¦ý(P™¦å‚H0û¨@ØžŠ%K=§ýÅõ}g$PDŒ=b|àAÀi½ìó¶ªl] ¨èJ{>€zËŽ-휿ª•ð³ÃJ1A˱ˆÆFMw“Lz sì7רAJÀ!Ù^q{h~-°ó‚s AîW‰?ÖŽ’ÎÑ!Z³ôYÀ%¿u &v¼°í6ApZkô›‹B{süæ“ñ멟5ã[JŤÔítRû x̾Ôú ÂÇÓ^¸äqH|ù¢×½ r€Ž£óù›í§í§í§!EþŠü`Ì6f³Á½Ñ½Ñ½ô:z½ˆ‘ þÞÓý}üóPŽxõ¹cÒÛ·9no¦7Ó› E¹E¹E¹pö±³} 2dÈ8"[d‹lÐoq»Sû‚×}±£{(>³©ô¬êî`öÁ÷ÀUh¬»ATb•=ÔYüñSÿ’1Eqµ^Õ"⎀PÆíî¹2Ýè”§Çîü9bóßÅŒ°W†;ÅáÅM±¬¥€\é (û‚h HŒS$–#H) 3/°ÑµI} ä¨=¶ Ðå=€½¬úu?”…ÂÑšbÈ×ý‹OL„ðÃG¾ýf¸zÖç&€¿UœóGh­ íëûS¯¬™Zcã}W°U¤i±ú€Ê\ JÙ‡#-Ô®¤ ¬\3V‘wœŸÉb•pÕ[ –ŸBàùÈhaBhFÚÓ~I·]rWÿG@ïé^Zaà«\•«r!pþàüÁ`Õ°jX5 ù±äÇ’ó ó ó ue]Y—_©=þ³øã{€ßÃ*V± ôMú&}¸†»†»†CâºÄu‰ëÀ¿Ú¿Ú¿ n)¸¥àà!â¡ó·}¼Ã+¯„¤½-Æßû„>IèÓ E|¬UÂí^YÌkÁDË|GTaªÔà ¢ÖÜÒ @Z;‚Ÿší…" @œ®Ÿ] EU@÷"AèÖÁo€|uS `Š*êuÀ#~±@›¥ñþ}üË«ÿQ=Â¥ottõ¹ÖÝXö›‘³e‰ rØ£ƒÐ˜FìÅOŠNâo2ÔbUË~´ñþQ¹•ÀzøðÈ/¹¾ôêÜëþ„÷´”'¹ÂËŽ.Ä_ò÷o> â#YCk*$N‹ @£ð‚Ь ÁÙ "bFx-C^kí   ˆ²D©ìU,zËX©-ò ´&åå&C!éhË-#¶‚Ñ3a¹2GjIDATAæ½úóð+$¿Ý<}˜Â¤¨æ7€¯ex߀]•yòY´àZY&(+²¿h`©§íÊ ÂÖÍ¡¯@H+#4/±<ø@\Z£üšÀE€°<¡k@E¬{Ãg€3j^ô€Xjw2äa½ ÈU{ãO›Š8HÑBºAYfИ∘ԉN þ”»ˆÉ@ÇÒ­s 3àWˆq  ¢à> 6Ù¹œYU›%BÈýã3n„кÜÛ*cTTµúÇ_ÊWµ·A¸Ç‘˾»Á7ß¶@>͸È@PùdŠ»+ØIXi¡þ ÂV·Ð\À¦£º”%ö„'€pŠûUMY\ÌM`g’W‚¯yxµ¼ÂOVZÕf$¿ÑzǘÀ˜œØ!ë³ z›·yŠöí)Úe9e9e9à­é­é­ ®Q®Q®Q ÍÕæjs%,‰*ÿTüëK _"“L2+d“>g>g>Ç¹Ü »¹ÝÜnEýŠúõ±D,K å@Ê”À“<É“ /òŒ©t7$l6yèL(qä\ôáp(­yòø7—ƒç+ã‰èÐfÙZÉZ^û@ð2P…\$¶ŠE1Öèh(ð Ë€¹ ˆŠÊ²E¼¯„¡Jì×¢v`;¨0ëÕx ÏaÕÊèõêõå€9ÌB@қ؎ÄÂ0θºƒ k•ª€ä$[@äf„?ö%z[ï Âi-DuZ€ší4@¥Ø7©& zVoÔ©-xæµ­‡ÁáËî¾BÇŠåÞ0DúTk×a(v•]­¼ ·ö,ª|+Ÿñ×] Ž†û—¾ Ñïó;ì öã…gw7m¾êzôÖg%Wh$žÔ2A…°q€0TÐþ  䂊ðI¬˜ª¢¯øÑÊ–!ë8XC¢gÍçÁ×Ác^âTÍ{º¾É75vº´±Îד2+Œ L`­.Z]´Š—/)^‰sç$Î÷÷÷Ðêõ REªHå÷+ZþEüy3À/јÆ4ÙH6’À¬iÖ4kBÂK /%¼Þ«¼Wy¯‚Â&…M ›@þÒü¥ùKA¨Up¾­Žc¬w$ëßrŒ)õÔRaµt;  ]Qz¨¶âˆxDu±Ú ±I\*ªÎD?ŠÍ÷ÄJÄ|òa%^UeÑ5€»D/Pܶ›†6MÌzÆV@‰ËìwÄÄØ—_+Ó¶‚²ÌK\m%ÅrŠÄ"‚€Käp-¨jL$ Ô·Ñï|7ƒŠˆw8ªT±ë€ªm¶žQ5áÊ‹AåŸ]¶u(½ðʽ¹ i5õáà¬u¶'NŸw«Ò¶¬gBàµo'Žû¶My¾„õœ‰¯t5ôûù^úGºÍô‹çŒ v¸§U>ªˆB;«‚]„•˜[Án†Ø$.QMl¥*¨+„K®†ßþ4ú”J91µ³. -dÙbÿP@«îlQqà+Ÿò)dddAñ”â)ÅS ±fbÍÄšàîêîêî F¾‘oäsNÚž_HZý©øóg€_"NO-ódžÌÇŽ¯ð ¯€È™"Š«W)®ÑÑÑP)§RN¥Ãä09 Ä­³q¼õëN¹ö0–$ŽÉê esvNžQ"Ó‹_ùpUÓß¶Í'jØ @d0Gm”õNð @ׯ9’(㨨õzp)`ÓLÅ)ÉÔüª½=Ø}Ô§CÍn i€-_;±ÐÔ÷îO@Hó>w>¨ˆÖFë ~<'ÊV¡ØE»@íŒ4ðW1H¯ë,®‘'ß‚W©´Å °×ž9øýBP|¸7ðˆ£Ò ê$Y¸@˜j³õWÐëÛGÂ@¯a´3·‚Êo?a€[¶¸è ³Ò·Èõ¨6^]ôV™v#PkòïÙÖ„?eÄÅP þÄ“¡FÛíeÍ ~"ƒÖj.¨‹`9ÔO2'¢who@t^’Õ8 <—¸†>Î3»5êtezÅÜ{±½Ø^ ùËò—å/ÿTÿTÿTH\œ¸8q1¸×»×»×ƒÙÞlo¶±Z¬«9—]ü?>ðÏ"^”lÏ´gÚ3! ‡Â!ð=ï{Þ÷<”¬+YW²ŒÎFg£3d¾ùBæ `Ì2f³~ÝœõVpDa”ÍùqÐÇÃ!Òâ𳟼ΆvÛÂÚàØ¤g¨@¾Çv Y;ê8 Æ•Ñó­3¡™€ :+4\¬Y™ ëeT½ MÞ¥] öÆÜfëGƒ¨,Ê× ˜%‰€%‹X³øÇ‚åè@©z^…@VwÌLÊ1#«U»u`÷=ûÅŽÛ@Î<ñýAÀ%¾ŸàˆeUCÇM„åIn3߬*`emÑXKsÜâÝ-{w5àH΢/@mŠ&û# 2åVcˆ/k~xÕ VžyùÛŽÀ´ÀÊܾ@Àš¾쾬‘‡!Ô‡’*%UJª€µÑÚhm„Œ2nȸ<“<“<“€ö´§}…ö^$Yµ†Ð‡y‹÷uƒ²Ïö~¾ ø!Ú»ÁÙJ,|ŽùÎD÷ ÷‹ÛÔ1P2rKàPF:ƒ !ð>:ÙWXé­Tsˆ]‰Ïב`ßâÃKA$©„PP‘Л¡‹K…U¬?©åLÚç­ Øj?ïƒðˆÃ²ˆ§jÌî8XÁkáwÀþäléãê›’ãr®¿¬+H ©:[½@˜Öä’Ê "Z†÷z È@ÙäÛÕfvT Ü…e{æê]æ:Öj1A^”þV£wAÔqŽHU`]wºÅÆÉÜ\ ÁÍêFW+ mÚÄÆ=!¡{ÝÄnÁÑ5ýŠ ŸF‘/VWèÕ×|Í×à«ê«ê« ù/濘ÿ"hµµÚZmðöñöñöW;W;W;ÐoÕoÕo1BŒ#8/]ô¿Œÿù%Ðï¡#ér—Ü%w9ÅœbNáw£tJ§tBÙ]ew•ݹ¥¹¥¹¥x ñ@âHm”Ú(µQ…ô×щoÁ1:z€ùlʆÚ ÐâtöÎO 0æååjvª8Â% ¿.g«A 6ó±U¢žÊU=€³Ü­*Â;JG£\ï4uµNzUPaµ?X„®e‹] Âá¶Ö;€¢z¼ §|Ó¤ˆn烸¬J»‹ƒ5A­9ùåò­€Ãx#£3`‹ =VìW£X¬*ó‡}aÙHP‘艒­ tñ q¨<ÙÍ;x(p_Þ³ :{öV¯p#›ž¼bsO°'ç]µ=ôJÁù߃¹Sï):‚þ² f¸3ú“¿?a; j.4ïáÝ >ts‹~ „}ÞúTØ>¥blÚu©”©TûGyi{ö&'ÜR)Tÿ#[&ƒ*¶® > B—ï”6ÑǦž8;´Š3·U¢7]Í|˜ÑÚÅ Yb_Ô°OÑ\f¹‚jçûèTG š±¹eˆäó¤1B)áöiˆö•‰®Ñ ;k¯¦ÍçþKÏܵœ“—]pDG-ß‘tfWx_·s;·ƒïVß­¾[¡ Aÿ‚þ Z«Öª5$^•xUâUàêäêäê¦2•©@Û mÐ6Õ¨F5Ϋ7þ›ñÐ…8ÒI'DŠH) §éizˆKÄ%âмšWó‚ÑÉèdt‚²e=ÊzÀ©§vœÚžç<ÏyžƒÔ/S¿Lý555€‹¸ˆ‹@¬Ò¾3—‚‹ ®”Jmê…!üPÉÛºAÀ<¹gKð}z¦ÑAäø2Ž/ý¬ýfÙàèï_–ÿ.h‡œ_e JCæßbŸ–*èêXhLqIðáð£€OU²ÓGÒ*çƒ|0ÓnTöÝÇêìòíG—¸@<%ºU¬ä’} êh¦»:€<åÐ>¾4Ž2¨½²ävPKUïè\ ©Ø¦ý¶Ã]Ñ·ÂMJçAäk+¬½{íÎ`¿ë]Þ´!y)/×.oIÖÓÍ«Ù(qX•©@8¥u…Ÿ-+v³›Ýªªª … ;v‚À‚À‚Àp>í|Úù4$|™ðe—àHq¤8R@ëa= ²ž¬'ëóøo mü›ñïÛü£XËZÖ‚š &¨ íííáááÈ d²À7Ù7Ù7¢)Ñ”h $lNØœ°RîL¹3åN0o7o7oZÓšÖ¿ñ;Å”{sDD Ò«ä¢ã@hÔÙœÝ ! ?Pü-¨äȥׂ˜|ºè›4Ð ;@ËâZ» ÈgC{B=AºÄ%æFÐŽÖJì–¬/œ¶QÞ*Ù¿{ÐYX2¦%¬cSA½ª¥{gºHß”^Ô:žÙ`gGG’ÀÚ~æU°N© âE°lÑË•öX³rÚ z'.Ê> ÆâJ¶¼WžÝ4Æ+Þ¯+wY[{Áx H¦¿H‹çÓ‡w…w…wAÑ¢!ECÀw¯ï^ß½ ÓÇéã ኄ+®gwgwgw0†ÃŒa š¡ E¢H²ÈúJ½ÿüç;@9ÊKÜzÒ“ž`o°7Ø ²<²<²Â/‡_¿ H ˆ€oºoºo:Ø]í®vWðÔöÔöÔ†¤þIý“úƒ³ƒ³ƒ³ˆd‘×û›P¨Qö_Á:þºì:ˆ>UrDZ' º¤ôšãOAt¢oôÉã`¿UzäÔ= fé]RB|j¿*xúÆoꀸVõŒöª«ö‡±†QÀ1ñƒì j…üÂ\³ª\ â£0Å"[Ÿ§ŸÙ×Ù7y è¼eÕ»Þ5ñXõKA¿ÓûIÖÐ.uHuÐe--ô_Úª¥kéZ:1 Èl²ÏªÿãÿŽ”£|I±‚¬¥)Mi`Gìˆ+Çʱr º>º>º"[#[#[!45454B¡‚PD†D†D†€=Îg­¡ÖPkf³¿ÙœqþÅùp¼çxÏñŽFGÐîÐîÐî8¿ù“­ekÙx—wyhF3šýþoa [€ d Ø›ìMö&°Ù‡ìC`}`}`}‘=‘=‘=¡M¡M¡M‡Ãá0Xu­ºV]›ä&¹ Ìæ s8Ü·Ã f/³—Ù Œ2B —è%z h´Ú_˯åל+Iü¿2à‰ÿ{ð{ØÏ~öÀ°çÙóìy`´ÚÁJ°¬°n·n·n‡èÁèÁèAˆ4‰4‰4ðÚðÚðZˆ„#áHøˆz¢ž¨Çù¥ßé’æâÿø%"DˆßÄ™ÔúÑ~`ï´wÚ;AõWýUÿóK ëYëYëY°ÙƒìA`µ·Ú[íÁʶ²­l°*[•­Ê`µ³ÚYíÀžnO·§ƒí²]¶ ì)ö{ ¨D•¨ñŒg<ç¹Xã%å•Nbš˜&¦L“i2 ´‰ÚDmâyÚoͧù4hG´#Ú_Ê/å—çkµå`9XiIKZçR„K¸„ ˜Ìd& hKþïØ´þÙøÿ×~V€IDATxÚìuœVU×÷¿ûœsåôCwwKƒ”"" ˆb‰ˆˆJ™H‡4R"‚tÃôÌ'ÖûÇ5Þ‚·¾w=ÏûÞ¿?<~øÌY×ÞkïµÎÞ+•äÿâà—¸æ0‡­le+°šÕ¬–±Œe ‹e±,V²’•ÀR–²8ÈA‚¬—õ²8ÏyÎðãÇT£Õ@5P T õ¨ÜÎíÜ´£í@µUmUÛëþ½ÍhÔ¦6µR”¢K,±ÿifþ7ƒñŸÀÿ·¸*€8À® ì'|Â' ¯Ê«ò*Hé#}€§xЧ@$A@ŽÉ19Î~g¿³d¹,—å WäŠ\©(¥"H i!-@‚” ð?ñpœã皨JUª•©LeP¨Ô ’U²J•_åWùA)¥”ÍÐ ÍåVnåu^WçAíSûÔ>P«ÕjµøŒÏø ÔËêeõ2ð ò Д¦4ŠSœâ×ã¿ø·â¿ à_A®}q¿ç{¾^á^¹N05ÑDç+ç+ç+pžvžvž¾ö´“ì$; œ$'ÉIç%ç%ç% è¼È‹¼LcÓ@T@@«¤UÒ*]PÞå]Þ½N0Ÿæiž¾nœÛØÆ¶ëG?é'ýÀ ;a' ’*©’ R\ŠKqwå]y—_˜Z©Vª• &ª‰j"è;ôúЪkÕµê 7Ôê AûQûQûT!UHµAmP@MWÓÕôëÆu ·p M4ÑÿéÅüê¿W€.r‘‹Àt¦3¤³t–Î nq‹d²L–ÉàÌrf9³ÀúÚúÚúìÖvk»5Ø=ìvÒCz€ö„ö„öè¦nê&èUõªzUÐz@€v«v«v+hóµùÚ|P¢D 0–±ŒåÚÑýŸ…ílg;ð<Ïó<ˆ!†àÜïÜïÜÎ^g¯³ìòvy»<Ø©vª v3»™Ý d¬‘5×…¶X[¬-c®1ט z½‰Þôúz}½>¨6ªjê¸:®Ž£Íh®]5|øðý§ý?þ«þ*LLL`=ëYô¦7½A8O9O9OÝÔnj7k³µÙÚ Ök‡µœ²NY§,h µ…ÚB0:ŒNàšîšîšú }>´l-[ˆ0„!ÿéIÿÁF€SÂ)á”{¶=Ûž æXs¬9¬²B oËÛò6hº¦k:åŒrF90¢Œ(# ôôô@õU}Ußëë¼Ê«@ÊPæ?=Ùÿ}ø¯ø{È&›l`*S™ RBJH q2NÆý¥ý¥ý%Xß[ß[߃yÜ+öAÐ7ØMÓ_­¿/}ËgùÀÕÓÕÓÕܵܵܵ@¯¢WÑ«€6Tª ±ˆE@iJSú?½9ÿýøÿGœä$'Æ4¦18ÝœnN7°/Øì z;ôvèm0™ƒÌA`ÜmÜmÜ ¾:¾:¾:`x ¯áÊSžòáwÇ%O•žÝ e+œ{joq&ªºµX§.Þ· Ôwfvæí`¬0š¨÷À¥Õ–!`XúVíaÐÏjií²*¢îUÕ™2@Í />ÿ>ÐWÖ˜Ј+ÌÊÈFéª°Ž·6àvÏŽ‰àn&n„Ó×3Œ¢8sy…ïÉL¹hë¡}À ÕX-6QC ÆË›êÈv/o1®´¸Ö % ½Sg8U ÚµkA`Hú®qjÉÖ¦`}“›šj‚tŒ­_l2U Œ­xx“‹î®=¼û ­¼Œ˜¨Å‰ƒþœTÏý~çLÙuì:v k 5ÐîQîQîQà¶Ý¶Û}º>]Ÿª‹ê¢ºð«›öÿ/Ãÿ» ÀÂÂÆ1Žq ÓdšLûMûMûM0G›£ÍÑœœœÚm‰¶üAÐWUWUWU®¹þ$œífVðs5»Tì`/ȽåpËU…À¬zfÄöLÐvæxΗ×›êMÓ÷ózWFš«¿Ñ´j¾bëƒ*¤Õöo2O‚ªÈNyH”…‘Õ2ßMdX}3ŸLЍþ€Âbc’JSíØ¸]ŸÇÞÐÛzzB2K®¸¢$í@ùì•¡™ !³wæT@d9-Ø$¯AÉrÆjã¾ÓT±ÂÞ¦ƒ*\¸Gãl`Bp\Ú`p&œZþã3 ÛÒª¯ ²‡ŽZ9pŽû*%ü V<¯éƒ <ƪìó-Ùc§–¯zÁà:\¸}ÏÁ¿±ô⦂秔ïZmWQïëaä>™UͪfU\ \ \9#gä x’d_s_s_sð.õ.õ.v±‹]âwÎqŒ]` tOÿmÎôÛ]‚WN5ܺœ%ç^Üš®‚¹ÝϯÏ£†zŒ;õ¹ ´¢´”Û@c’ÓTk#ç÷:ÿ@š§T´  U‡’ å¶ëå>b…ó]œX¼+ðQöoW7ÂY Ê£¥º~±Ý]ãæ–ÊÒ¢®û[CüN(#œéÉç–ÇU¯~y$Ý™dïüê‚hÄ«ö ¼N¶Ç,Ùí~Ð}Ëãæ€õî¡‘ù±à7ó½úÿ‚ÊÀ&ˆÆ‡ä2qTu›±×ç€Lõ>šo „¢2ë_~r/§»° ì1Ñ/”h¾Ô*“îšÑÅ*.¾½#èø &<ú'¸ó)Ÿò)„2B¡Œk©®Ÿ\?¹~OOO“knÝ_“¡nåVnýwlø þ÷)€«n¶JT¢Ø[ì-ö°îµîµî½vÇc7»Ù 1b:Åt}¾F_ó÷ÉËh(wA¶ç?…ì'~ywÎ*ÐÖ_8³u5ø6:ÏeNw²jfm›>Hû´ª¢î™™Ýór{dz;›ˆ§ÔUnÿ©†È4T{At·ñ=(ÇH?rÊ9~ ¸Â ¦q4a ¨|ê[u;`ÑE- ãü‚Ñq6Ó¤¨hm »<ð‚¿lÁù º—¸¿u>PïÄì-ydÍéök&ƒ„/´Ü²ä˜Š¢”G¿Pä§f„eØx8ÊÍ ÚIÀÏáÉtïŽöŽº—'“û—V¢v”®Øx¨‘ú÷ÿGí‘öH{$ä89NŽ\æ2—Áûº÷uïë`¤éF:h3´Ú ®ådü/s+þïQÉ$“ rNÎÉ9pz;½Þ׎ø= tpssƒ¨6Qm¢Ú€ºOݧîûCº{Y áú)#޶‚Œƒ?9Ï 2Òê˜þ„ÄaÅ&wRt¹„8ÐÆØzà4–õÂé9 w¤:²x>pþ\ÈûkÒÅåt|j®öàV#Ui@‘ Πƣa*FHsâ„>1u+Úlÿk…¾º¸¿ŽÔ´f†Åo^žjlø‰ì§Áj¹Àá^µÈ–x'TEc†çKPÏ]ÕèCPu =Y»Èꔟ.Yqæí A–‡Çe¾ D«¢Ú[€FUõæ 9iSÐUG§)(Ý>p;H0Ôȼp˜,óðâùK+oç)²ÂÌ•¨·pÞ,÷ˆ8? «n®Ò /1@Ýv3æk] ´Èì$í pÈ9áv@{¹ØÐFŸC\ŸÏv­î[–:§Êy¯æ0änÏÝž»Ìâfq³8ø>ô}èû\I®$WÒµìÈ«£¸páú׊Ä?ÿó³æg~™+se.Øb‹-êêêÁZÁZÁZà·ý¶ßŸá3|Ð….t¹9Y©mÅ?„¬FûS–öÜ’»/O]îÃ¥ç[‚²«;+À(xá• ª†kˆ¿HÅèãI¯€š?ºthõŠ¥6ì4öX1ïÑv{H³ŒO-¹%}Û±À{¹ËS¶€œv›±€OÍ×^ÜŒV•ƒJ™|+ÁNW hÌNšÚäiЛ—ÝÓi hção/[Ôã%ï` óœÙ$%ëËóÀ>œ|dmŸì¬.2“r>µ?1£|SÐ:—ê{ë¤&¥Üv¨?øÇU=Ü¥Ĭ-_®õ P›ža¿ÿqÕJµR­ *+*+* ‚ÛƒÛƒÛ!w]îºÜuàëë îêîêîê×â ®îÛ_ë,üÅÿÜÀF6²ñZÚ©5ËšeÍ‚P\(.¡9¡9¡9Ó/¦_L?pŸqŸqŸùûdÍq™+Îôû¶=ðÅEpä輨‘ÆTËž/ô²ôuˆçí JÊXÉÉ`–<äJ3Y ¸ÔVëPqÆ“ÖÓ@[oŸØ_€¹q+\õs¡ž ƒ}±hà˜µ-T¤NúëǤD꧇2€¹‰—¯€¤; ­àÜ­R÷‘Æuž î>UÖÞw 8` ôý‰£+›ä=§8íO]úqH·ÔØ#›\ô5 ê¥;÷lõfæ‡É{@Br™24œ–=œWBd4|中ⷰ©ÊO[{*`©Y¹@B4“à|ö§`â³@LI•HèpÄ6rs„ˆ墿 \ú/Á’ ¹j»%€¡êÑ \îz…Ÿ h­¼/Š“¼* ä÷¨} UTm„úXýÙ 9C¬»µ¦ %ý¹ayˆÿ¢Î¶^#ÀõXìCE>ýûlÏÏφœÛrn˹ <ƒ<ƒ<ƒÀå‰òD>YŸ¬ONsšÓ@ $ü ääÄÿ¼À*V± d€ ` ±†XC X6X6Xöší/öbìÅØ‹à:ã:ãú#Á_ÄcbB®ïL÷ ³àŽÙïWBÖSÇ~˜»}'ä30ÎPA^vò”\΃dᢠýÔ. F»› \úç°êaŸ¬àûi-œ@Üæ UScŽœuØ;%©/ðMŒ]ì=P—ò½SéÐ&UHì|¨l^Ìùìç/íÞ{ œ/ì Ú=ª”zý¨« (*¨³\ãý…@M°Ž…’A´o7·>U‘y´û™¢Eœ´,Їš€„Õ rõÊU$¤§hg@¹]gôvY£!)ï t³;³É1Д• ÔêÙ‘ÐeS­,9a¿ØVZúÓ€î>T0?`«ZEL‚œ zIÐ,ŠØËÁ›idhÙ`ôÔÇØË çû³9+›Â•BÛŽÞ±;êÞÞïð_(övÝ@{>½ÑðÜ]Ý]Ý]A‹×âµxÈ®˜]1»âµtno9o9o9ÐlÍÖlPWÔuÈG¾<Åú?ÿsNW¿øÉCòX[[C :ˆë=ë=ë=ˆíÛ;¶7C¡Æ†vn1MÈêupÞ’9›³·ç7À·IÞÏ( ¾Ñî·”´f‰ð6P¥£B5A2™Ì\ü¿)D¡È¥(¯¶Ã: Ôš;‚Á˜ÈOæõ.Ê P5Èý,ˆí©QxÎWú$@ØÇ Z¹F•VÅ7/½¬uù¬UÁèQú§ÛŸ=U)ÿÙ.þ$dS ã•gÁ¾uã˜dÐæ) sU¤ Hdz~ªÑœsf±ÀÇ e‚vúT‹Lã.@Ãû›/¶Â¦&(¯zÔ\ bbàaÀÁÍçyüˆDÒ• ”Ç©&9€~ M ;?åÅ/”ý›d¢l’@yÔNgà臃/˜<ãD¼Á¼x“@§)GAyÜC ¬ÉÕŸÏ‹x<ÍÇ¿e¨8Ó@«¡Xp>¦¸SχgHk4WoÇàÏWcQïîóUÅ¦í«ƒ*§­1²nÎgë¨uÔ: Ù½³{g÷W–+Ë•Þ\o®7´]Ú.m×µŠJÄCÌ?¾¾ÿ(þó `{Øòº¼.¯ƒÕËêeõ‚€+à ¸À¬`V0+@ܱ¸cqÇÀè`t0:Üœœ³Ã’{ÒÕîJÓƒùÖ‘çæî¨i®,ëð,Ó»Ê~кË») ´“¾€ ,2‡€¬¬ˆ¯zžõ>GååQ³œS€¦ ~àC»!¹TüÛAŠKDÜy¸8+¾"€C!Õ ”—-2¤¬3Þ aì̲ðUoýÂÈž ¾qíŠúêŸÀ߃lâ{°Þ{fÊ/ <;n½Ô«ê5ý  ”F4ANÑ_.‚S00)ý(HÈú>°ðSCÝŸ7»" <”wšZ”[$@u; [U½Á8å) ÊkN²> 5_l6KÄ[bàtŠâ€ò鯅ç€ä¨×Âõ!ƒÄ_i]ÿ<Ç$PmƒçG@Ü= [ aUÀˆ(ðTVæý}MPQ`]+Ðp¨ÁRp¦«·õºÓž£ª@N/³k#¸†–ŸÐ¹+Äëµvôü´j®W|öÍÙmÇÚ±v,d¦g¦g¦ƒûa÷Ãî‡Á{Å{Å{åº4ðSœâÿqÁNä1@¾’¯ä+°^·^·^‡àÐàÐàPo o oƒ¸@\ .ÆÆÆ7'g'‡´Ì÷!íâ¶“Ê€£%ûV¬€è’›‰à¾W;kµ]^pŽƒdr…ó€CuʃòاˆÈ  زQ"GÔ²”åÑ{…뀄ÕÌð@ÈäêF¸qzi6{CÍÐ^¥¹Ë*ÖóU•ŸTVÓÖ:ájf×9QK›' 3Ÿ4—¾…ì·Ž$}¿´ŽÉ÷5@ÕLý9l¿Zõ”Ÿªtig Ÿçb@O[²Rö9{W$2QyÔèÐ!0/„¼D|W7òù‡0¤±|J Þc– [•íÈ—°mA¹TO».ˆèã‚S‹òr*2òß®`9¡åq=?$dÌNœ™E G.ƒrA ÿ€=а) *Žüi¢ÆjU ü“_ Ù'C:Ï€V²d³;6B‚»þè¾_€žàÙ[åæü¶f[³­ÙU,«XV1ð<äyÈóxú{ú{úƒ>UŸªOåZÆÿPÝ‚ft:餃\ rl˶l BãBãBã T3T3TbÏÄž‰=ó'¿G`Xú.Hݽqí'ÏÍ’«. ±wygó¸gk;¬c ¶È£Î é\⑬Àˆ›æ’AÂú~m5(ËÒ?iDjêiÎ –zÈôüȆ4óî°f^¤Ýß>=T,ia×tëHÆ“€A?ç`à’V€›¤pKŸíÞÁ0ÈkßöOäwÞ±UÚY£Ãý€\9̺›ŒÛ °—ùÀLýŠ{6¨*®_¤"Q¥A¹©cǃXô3/ýùïñ#…lÀR'Õ`@w_1ІÊd? ÓV”¶ÃXT“Mó®7£ù¯+Ûœ5”ljý( ð8(¦™Æ´Ïæ½_6o i\ä¨uÒÇY‘·oŽClïL&e“³—©[6üd<Ø}ƒí3»ßœíFW£«Ñ¢Ó£Ó£Ó!T&T&TÂ3Â3Â3ÀÞ`o°7ÈÀâzÿEüûN666¿¦]Úº­Û:„¢BQ¡(È-[ ·Ä$Å$Å$gšgšgÚ¬—©ç6ùôPÍÎYÑU½§9 F–šfÕŽ÷9 9 "_š›ŠÊåt•¢€;P*ô OArTs³™¿;òÿ1,ÒMUU3Ay]åïÄi¾ Må`n{$?úü3ZO;ôÔ˜g‹|ûOà{k§£¥À|}{çq?‚±9uØ/çA½¦ÙÆR0ê׬·ëvrSœ† _:-íà\¸RÝ Ï:U2{–êo–ˆ,…ªý—FäB4ÙG”7ô™ÙЭ:> ¹ZÕÐã€!SòFåý“”#ëšÌ» ¼zÅèâ€á¾˜ÿÀT¯o r®Æ!”¸!É; AÈbªö`¹åíaÈ™ã[ñ4HÍrïo )%2j¤‚þ¢·MÌù›-œ/œ/œrŒ#Çßxßxßxpïqïqï­¤VR+ɵªÉÿ&üû¼yÅ$íö {„K„K„K@î”Ü)¹SÀ¿Å¿Å¿<_x¾ð|qs2N•pÅœ®~nçƒÓK‚æ\8¹å6ˆúÀ7Àý8‡Õ{9¨;åm/H€Ï)”÷òß ™ ˜ZåAÅ{8»€ùÞºÛùò[œç¯AŸ`@0 È1ïs‚úAê:£Aw‚ç/êzõR׃cÁO Eþ l·ë¦Wu$±W…b X[3¶ƒ„²Ož‹„8JŠ~êX„Ř a„Í üZ }¨Áºnô J{U 0øÂÓó/ßapÔîp+í< zÇpCÀa©ï>@ã KóV%€ ‘)åññª"7òÖÕKS_a‹¢RT´åÎì’##ñ‚ÎÕÜŒ?bn^…-—ìúàZX°U]{®ÄÚ;êCf‡ƒ-g$Aúà”¿œ„©õöêÚ÷þ¨|¸ÜWÜWÜWÀ~É~É~ €\3º>r}äúTMUSÕäZ…1þõ ¯´“SÛ©íÔë”uÊ:>>>ànãnãnþzþzþ?¨b+…­¡¡ ýÖ=Qs»Ï¹²þyˆj+É9Á8,ó¼E@5â>½3H4ZE^ý“#£! K1{ ëL ¸e˜îZZ]wÄÈu-öÏ…|Füè*Ï­e™—s¶‚d‡ËdŽu›öfüYðì(ÿp§È=±àüÇ.xþàž[À})©Rÿ‹ˆ2g|î§W€uËÞºSÁý¬«ŸQx·Ä®–;A=“ýÁ…~ÀÔ s·Ýr!”y0Ôm(·1d©3Úª’ž;óJ_@Ó~6j)îeìeá_äGÄØ·‡³€c÷Ë)¦'Ý€T×±è@†z]9@6ƒT# ƒÇ” „TU5 pãpˆ•õÒˆçI¢™-å»vè RY›@Ö»žE &«È:F‘óë•%ûí@íËÿs•Ç@;PbpÛo€¦‡GÌ=Q%ƒ®”†œQfׇôm{ŠùëAB©ZŸt{ÔIc€ç^*_)_)_)°Ÿ³Ÿ³ŸƒÀÝ»wƒzW½«Þc±ÇتŒ*£ÊqÄ÷××ÿÏâ_§.p óe¾Ìû²}Ù¾ ÁÁÁ@zÐbÆ,ŒYȯހߡŒ±@Æ€÷.}œ‡N×þ©5Dï·R/±Õœê!mž| r—ð·%’ã– Ü,äöT^$›”Ç—uÄ´ËåŽåaƒý0(—»ë ˆÉ(q[åréïð ¢zŠÓ”×¹b>’i=³ÔQ¹·€–YÑzøýš©GÁ=ô—#S wÞ¡ù?{d½QOï±Ò5›ú@M2~ñ޼Áoµtl{ ˜­RÞ=Ø ¬9Ï;îʹÃO—•©Þ£#ðDæÊ“Ù@÷­ë6F–{ý®S :^ZñóJ`Å•ØÅ‘~ö2¹#® érg=Êm4ö}­ë>SÅ«®¤ÿáÉH'È%"…Gš—œæ¡¶ ó LFi%íÀ)ÝôÖ~Ñy¢3êU¸À9uu\]™@¼\’2@YL©T·]¨ïœ±f‚,ÑÖoj‰áŒl»‘þ `°W^„âêj:u~ [ÎØ³A-JØ\v-h;*þpœ~‡§ÎsÕ3>8ÙŒbÞ[ãJ@T’¶#в‡œé·á dÔñäÆÎ„ø ÕÊtè VÇõë¯ó8CÔʨ•Q+!£]F»Œvz:ôtèiÐÎjgµ³ ÑÇèc€MlbÓ¿B@ó6ÿ¿ÌDI`}g}g}A JP H¸7áÞ„{ÁÈ6²ì¼ŸŸ¬´c+׆àì_JÌì1?ÛÝ/ßF³ìN§‚zVLûÀÔ6Å|Mâ&€˜Zwã GYu¶ó‘YáaP.鞨ÐWR@BrÈüйE-åv·‹ù$¨/óFbâϲú9ñ›k|.€p¨bz P³b¶–hÚÚŠÓzÎQGï: 2åxñuÓ°|í”;Á^î<Á)¬ð.™_àDR ,|g-ziñü€¼àì —'~úØRP'S2ö>9#Áx2jM) Fjºê€ä0T²a=@U.Q¤&ðp‘®·ì,g¥é‰?Ùö‡×ÀYt6u«ò³Í2?#•”Ûû~ÌÏ A×K¾HRÐ~¼nö:¹@ˆdv?«¡ê`¹ºb°Ù™õ*È‘ÐÀ"5^ûج}ëq€Ÿ]Yѧ€ Tâ- ‡£ll²¹h耋ü”ò©f< T±Ž„Æõ­Ù €»8A4¨e½ôº˜ºÖhl®4_J;鿀-[œ ÞŽ~¨H hY5®<ØœO´X~?HàâÆÝ=AÅDÝ‘xÐÕXý#±ê]m%XëÒñç «¾Ó9z&xªV½›bTÙ|ÍZÁ¯.Ì¿5Ìf ƒÌ²™e3Ë‚/è ú‚à™ï™ï™­2=éIϺ”þ N_ò%_^+½gõ°zX= °#°#°¢~ˆú!ê‡?ü<k]Š:ô ¸ü} ˆ™§õ ¤1){åå8P}åuç H˜FÊà`OåßÈ4ïÔ˜â€C3µø}š‹D@c©ø,•1$,¿XŸPLy‡$XV\ €¶Ü} °T+=b¸,{CW)ȹ#Yw†€ÊÎ÷h¡ í.Û»Ó,/Nl\ü:8ÙÝ2˜¬nó}8ò²«èIú&møáQ³ØC.ßµµ؉óoý$ZS.¨³þq±÷‚{‡þˆ¾´Çô~úTPóÕ§ôùÜœ’S8çÉßJ§·6 Ä¡+ñ {³ÛŸëÊ´Ç÷ÃVÏÔ˜|Rªço€+´ý@üÙ’›†ƒd8EíT+Ü+R@/îXZX/hü,Óý$ª—€)Ú}®w€¹Fa߃ Så`6p ÚSŠôÕ¾NK5ºƒœµïýÓ‚®ûŸõáÞRÀYµT‹då=¥br8”ãy™ ”uZ˜e€2VûÜײ^†*ÊÇjHµL{Hp•5F€ê¬½éôµÞõ¹±Ì“ZåjÃ{| rñÌÇü ¹ç÷îü ˆöí‹ÛVßÃØÇ2Pniç¬ã[»sv¢îsUs'@öN|¿ \bZô€wWÁuß@_3^3^ßßß~ü0ø!èíõöz{pÍwÍwÍç×F)¢Ð¯6­þy'€sœãH/é%½Àb1‡@Î’œ%9K€^ô¢$ K–0 ˜ÃæüžŒ58gï•tHm·iß„ãàï|ótiðÎ ~ráYP rÖ^x$@Õ=/»,“ €®V¨ ÜÞñqS@FÀ= €=ÌÿÍO•âP>»VîC a3ßňÿÿ=‰äwûòMH^`OÇ@y2¾ ëJtsÀ!.ÏMÑxgXè²Ë~´Æîª]T½"Ë›Ô§í¡—¦§ƒ4I›zð,­Šk]@yég$b—óv Ë“*ÊG<é@¢p€DjÐpyûż]Ó|C+`3pt ¹¤sT5F5-dz=á¨\ã¼wHû‰XÙFžÿ¿-ˆ/Ø5­&8ß:½éÚ‹å7uLYÞšòÐáœù³A¦îL= ªÇŒé’å)ÌUû´VÀÆNïÉz¬g+0Jnu†+Ù—º€ìuæï&Ò]{ä9ãÿ0ØS;a0Þ—RðÈ_ÍB%úóÞá@ŽV[ßäãˆ|ôp^²R@ OÍxx't)Ô`‡+ G¨gú& µs[¨$¨ª”PA ¡³Éó 0^+á ú˜Êƒï.f~wj8ÓÕ™¨†ížöM› ØLV‘ÏfvžqÒÁå#ÌIMî§cFB°3Uc€Ü™Þ·‹+H\uKõÇò1$*6ñà ä'ïJœ12cdÆHP–²”þËþËþË`ô4z=£åè?OüóâÚІ6`¿f¿f¿á%á%á%`­±ÖXk æX̱˜c7|Yç4¶€Ìû'/^®Ú¹½NWo{ô€ê±ÀÚ” 9yþ{w^à„žç N `Kç]@Âñ9]r&äÏ3«ÇS0hf'X§ÒlyÙ‰\¢)ùº¿:£Ä´¿ ¦r9—ÍHDb)Z6e (¬ü ½T¼Ê­}A%ÞÀNü/='i’6÷`£ÊèŸ —jf†]ÐÕ*ó5"þkH äd°×¨ïl7Æ{ƒìd?û@’I%$„CЉ¥È^éî çstvä’ó9(ƒ”ePæ «Ã*ÎÔœwR :é;Ž'}×¾XWʃV°ö¹~gAÈß³êc §Â rNo;EÊ@_×3ѱ ÝõÖÞŽ@;YGA/¬œÌOAj;ÂCAº{ýïçx.õ»ƒóD±·õ{_’Õò!°I¸T}Xm}ýŠÆ‚ÕÆ;µÐ7`Õsß—ïs°jº?*P¬XOÇB€%QO—Êv›üêoÛ_ô[ׂS¬Xç[Û„‹V» äqWlÔdYšeå€Ê)ýÀmÈyk^ð]p¶n±AfºÆ4I÷¬‹>8ÌRoC€ ¿Ù.H!‚ 7GåLo;½¬Õ\esO} ™K÷/X|d“s§uµ‚ÓõÈëí]'ºNt°··s¹¹Ü\N#§‘ÓXÈÂ_®ÿüãW€5¬a 8·;·;·ƒeZ¦eBàõÀë×Á¿Ë¿Ë¿ Œ{Œ{Œ{nN&giò'[Ç‚ýÝùÛ·-¸oÝCÕ' šft¾Ð䧤µÐTOqíþ‘È9ÆTm@BÎKfcPºÕ=ø,HØýƒ¿ È"(eÝ—ý8ˆ%Â¥Q©ê}¶ÞÔ]X°8éä޽9÷)@´R1û@Åj)ÆPŸ•¼ØîVP“}£ó 8%öþ0¾<È‹Á®ÔüZ¦¹3[¿ÒÕÁÅa°ÞǼ J£¥a˜rJsšÚ¯±Üóü…K›£EröüZÝ÷F6¶ê ÒÎIW™f•ÍmJw-€PŒÒ '‚ÓR €ô4ëç| ˜Ú9}>ÈQ§Wè óÈ„…ÍA¥d ;q ´!ŠuÊç©‹ KxÀyõòæ½—ãjž ¼D5ùäiú¤—ÖS›΂]êÏù8&±tKô¡Þ4Òò¨tY!CäI $Ç牢ÝÀÝÌ ÈTéZU@c¹óm76Y,Eíb€‹VLUNM2ún÷‚W@{,ßêü£A+;¤Lh.ãAÏ7€ò,'ù—¶Ó? ÊP»1p»¯\|yPO¹Ö½¬ÛsE¥©S©rŸ5  ÈzöÚãA-¶öe~Q_zWæK‡ŒQçÓ¶~ 9?&¯/Û¢o)Í nè)zŠžÞ÷¼ïy߃`L0&Æ"c‘±ˆk]˜sU®Êå%þ¿¿äUÝ•m²M¶uÒ:i„ÜE¹‹r9ÅœbN|ƒó Î7Ôûêý<û Ì2kχԸõ¯¾? bjs‚-Àû­Õ)µ(ˆ?ãçäm gämÊÑþS#<)[A¹4ŒÇåë™òDçG@B/bÊ3"ðTçëôæ° Çe¨âž;›ú®ü‘{ºWïã=N¹ýi_,ù!œy ðª ÚÖÈ”oâ~ºŠ89Ê+ë]é –ÝÔ“Êp5ô?öN984âàÏVØ q–  jÓôI Uò­ËwÐì­Vkpö§?> ä#{@¨2ࡱz&°¼ÿ¸\’ï퀣ÑÞ"A5­Rêþb@#kIð#pbNÏZ7$G¶Z“ÁiâéÕœ—ãï¯0 ¤¡ûtBH®dIÈAù\º!vó0Nî/ðs]{ÞxxLë= ´7^òÜ ä—5vg`«Õ5¸Xîì7Ë>YiŸºR€¥@C†« €õò hqÞZ‰Y k‰e*®õÞ™«Š‚:tjÄÆRÀ0«v®ª‘¯VÜ[ÀwÚ½ú ¾·[‡×Y·æt Ék²„HNdÉëöC˜,PÅhÄS ²½O'†`OIóU‡¬ãÁì…ÄôÖM^ž ®ñÛ‹øýrÉGò‘|é1é1é1àªëªëª ¾|?ø~¸®ãÔp†3üOÉà ñ¯&1‰I`7¶Û!Ü>Ü>ܲîϺ?ë~ˆ½3öÎØ;ÁÛÂÛÂÛâïçsŽØÝኳ)s|_`Õ©?샸±1i1aP ³:Ÿ›òÕ"°ðp£òØügGù»Síè« (-’ewËŒ”äçªàÿ±[ÇXò•ÔUToæ ƒZUÑÛs¨Ö®gc–‚SdÿêÏc@¶˜ms®õ­ñ[²–F ËA>#éþ=@г:aHPïfÌcòÓŸ÷oä4ë@«ïZêo ¨ðϹ-÷ü•¯Í”Gõ·tS8ŒP‹´;Az¸jF>uÕ¾ªy©ø6QÑ5’.€å¾’pà28Ǽu[ƒs§toM%ù°å0ß )!:È8­¶ëcÐÂÞuùZÞ(êóõAáý8î0¨‡Œ|ÞÓ >×:E€ é.™ :{ÌÝ ¬qÁÛÁþ8˜™~ œj9#/M§GÐÖè¥}kô­W¾~ÕJƒ<‘UúT?Pf¨ÿ•6 WÉú´9©ŸLÆš/f} ª™z[Vñ ŸƒúÞ~#(ÀƒæªÀÝ@ ÇäK"'¸«'G„8Î"P_è/¸nY£†zŸ‡Œ.W87 èQ6ÔáNÈh^ä™êÀy-A¿"}ú$ô äŒÎ3¢¶GmÚîÛÝ·»oµL-SË€‚ÌK[ÿKøëW€rȹ$—äØ%í’vIööö¿Ö@ûллhA n rï8Ýq[0?¿ä4Ľe´ ~ |—ÝþJ) Ñõž1ð¸[KˆåæJß¿8ÖˆHT÷aç•Àã€F9c5€»x‘L®ä¥ÿÞL´<ÁŸ&ÍAÕ*»¾µ¸ÜA tuŠÙRïøúÅÍÔ»ñ]·§[ÂÕ£yÔß<ÿ’›Ú<„¥‡y°ÃvvO) wW|üU¸¹L"È…à¼Ô%€æÊñ àöŸIˆ”*›/W‹h*À@ÈpI=ò’ñš?xYÄ› |Hig8ŸŸKÜМWJN¿c%ÈGeJwê ÎóÓ’Ç<ŠËPÀWt§ÈZÐÏ‚~"ºVÁLp­Ž^l ènïâ¸6 ^Óvé µ(¬bßc2XD7Þ%‡:@ uxŒ†ÑFáó µª•­öŽÀâ´º`¥Ú™vup¢ƒÕÒ;ƒ´ ÎM)¥ÍñTó]ðWêhãÍ­û¹"[ŠlÊ} e¨»Õh• àYéT6_Êí´²?= h‘Ðé_á!—X`#å} Å5Eþ.±#ãÚBÆÄóã¶V…ÜÙçìN?Å–Õ½Áry’=Éžäk^´p»p»p;0ŽG£ ÔêïøŽïþúvøë'€1Œa Øùíüv~­ ­ ­¬aYò†AB“„& MÀìNv'ÿþug¼SÂ)_­l9¬xÒÎØ?,ÿ Ou'ZuírÎ4 à*—4î‰ rˆ¸ÛäºÛó!šê \ôt>´ðº ýM¶«m ¦ûÂI€Å­#¹ìûÍû‘ˆ0‹yÜ*I»lµºì›…ôn?°òÔm?lURëd'702=¤©½1¼ÈË®ËùŸ•—g»ý`óenÀî.=nÞÂyãüs¦ÜÑ \<Γ€ÒWçÊçvƒØî"…:_kÝEû€ËìäG ±ÖÌ}äMw먞ÀÓ²—º Ý(,{À¾Åשpp*$¯\äoóÄn fŹʕ§_öî ÍAf˜UYக¯a¹®àJŒYà$¨/ÔZp†ùÜ8JÔq•j/€R“'A=#Ý(2ŸÒ8¬ò©Þê{5Tag—sÈ¡ õ×µÙ®ûAzÓBUsBêÇ¿³ZjãEœ÷ÃP—·íé ÝBŽlý©Üw/ß ÚŠ³µ7Ü L2_ÎîjÊUñ ÎH>«;0*ôRæI ‚l²oòQ Pèª$(¯V*ü:à×wY]ÁÙå9\´ äÞa…<ŸAðH¼Q}ÒrÒ‹Ù  w—ôß@Ã{Â{Â{ ëǬ³~„èmÑÛ¢·{{{¨_Ô/ê Å(ö§¥ù/œB„„%,ákGÿС'BO\ë¤ã~Ûý¶û훓ɹãl¹=eAõ¬´Þîé#cgƒVÆ^zaˆ© 9³@évNæK 1?BÖ™'‡‰²6O€iÌXÊÐø˜ª£+R½vµÜʧ<ÚP_•zñöË :z^Šýœª‡‹Ì½Ô,#Æó ¨2Zo£9à0o'žû@Usóž ™µs¿üTVP¤°)(õ¤õ"HϬ¾€NQSmQ@y<5Œò€L·y*O!ún’5—M ©ÎÓ@H;`ž$ÂdÙ˜ö3™A¹ô'üå@Nª®² ojÕ]·´ÝÆv`?EX2Ÿzœò±uÊgˆñ±·'H+»nèià1L\à4±‹›À·Õ»Ó;Œ*þŸ–í*æ ëœÖ0°:_XxqX ×{7f¸~Þ´÷ HlÚçéÑ@¬ýŒ= (#ä"wn7ÐV}«Z©®°Ë«fÁÊùo½|Ö*‚ëö[Ž7èjSÌÝþf %‹TpU‰^P`ð-]¬m^wùÒ¾ö@a§ˆ9 äÕŽ>`ÿsGñ/A?ŸÝüÜýÀÞ¬VÉ{@õÅRpYÊ“4° ù€:rÒ8Úr³#H˜g$RÊì’ŠÜvãœ- ß¡ÈÚÞÁƈ˜·!÷¡#—­Ýâë-½“·Rì×­búÐüüü «IV“¬&`·Æ[ãA£ÑÆ€JU©*H$ñfч×ãOÇHY)+eÁãŒqÆ@øÍð›á7Ao¬7Öƒg‹g‹ç Xät;ñòúñ îO›vh,¸Í^u/¨û⪖üØšøJÕ“@ŽØvÄÏ™¨:X¶™=”Ç~>ð‰ÜQ­<¿z!bÒ”a%et1åÓðyô"¯î1eN¸ à²Çeäk¤zž‰5¤øØ–i FF½Zð[p 3¯(°­2TØ5×WrˆU Ù¤ƒJâYuTw÷ƨª Ö>2â0§Øù›ñ^}†) ÊEqç.@x"´°Ñx5ïï"éºG8b ú— <úqý¸xº Q’ó  m£é1èìÈS ‘n¸ùÔ= ¦3&üೊe< Ì"•À}š»°Ûi 2ƒ^g§k}< ¹~½Ð3@G§Zøà"»X βU?îæ²+/c¿7!æ[ §œ ²\­Ñoƒð…}ùí‡ð{“Þþª8w¯j·ö)³WÞN}('¯É œVFó¥õ‘úS@}˜þPV;¡m<öL{Hå³#ÏŸ+kþ !T_å€=ê´}æ!ªJÒ™é £AôˆB•Àè7´T+` ‡˜²™±èà\ÑC®£ cî)ïFjÇÜ¿eˆ<ò‘ÊÑ?6ê+ܽ¥šÚALUÜ\©y‚¨Q$“Ùr ÔrkTZxÖéÝœ îÍ\{ÜœN§VlùƒŽCn¿Ûïöƒ–¨%j‰nnn N=§žS_{aþYü}°…-l)#e$Xc¬1Öíííÿ!$‚k3›Ùüûצ¡™Ùõ 0àPµ¥ÓÁ[]Ëžú³ý¥ _žztñ,О/åë°Tm£­¿8`³I†¶ v€cK ”‹v¤7[ 5ò~$RѦ‚ò9kƒ¯Ž½!;ÒãÏÿkþ~¤‚ÊKòP$dKV"àØæ¦ƒÖ±ÈÅ[ªƒÚ•еl;pŠ8o5g—ôíI÷+Ñ_‚ªÈ uˆMg¯Ñ—GX êí5×~PÍ\·ù« Sl¿ª¬ˆ¥á<àQϘ}@,j:­ó¨•ûHçl¾¡#à¸/q \ê À%.ÿæï³(Ê§êØ½Gµ·zäý»ý~Ç?¥AÒíñÙ¯_ÊOæ{À.m¿«:LŸ¬”‰j-8S£|EûƒÔPǨ âÈÙrŸÓÇy´:ÑùŠT÷ÂØ¨"s,–ÃàLä~û!åßÝx×°FO{jÆ ðÙ1çÎ¥µ‘Ú`@WMUd}Kç•fûcï¢ €Xím,Pˆãìç…—]‚ðãSžù.ìågÞ8{+Hªê¬^U„ÔW‘¸áÅç€zÁûIÂb`1I.PKeó%8µ|çòÅ‚´ôO/xd—¼l›ÀûÎÇÎ`žÔúUJèM MfXS€tùÈZ¤Ë7ÖO@ºpI·%ð蛬⩵À[\O´ûAàñc•Vw§MøÞœÅþ¯f5«ÁÛÉÛÉÛ ÂIá¤pØíŽvGI®5Çý;øûW€ÇxŒÇÀ‰sâœ80ç˜sÌ9 ^V/«—Á;Þ;Þ;þæ¯NŸ9´ãcàÙTçÐ{àà)Æ P9šÏª¢._Ü5X\ðëúO‚êYôB‹¹ ¹ÉU–öbTq}1ˆéœ>ÊmÍÊ^`xâ'F¶¯œ4ú:aÀ¶ôŒ± ¦tv"_ÈhuµÕoý¥Qjáô6ûƒ–”oVÙ¨‡ m©ÝãàœYû@^ åfŒíϱ¯ôËî> Š …ó„ø·Ýc¯Öºõ«j ª¸Êú_õ­µ1ô6Hg;_øiÀO^¥ÓÌN Ŭ—·ÍGåQJº!KEz êa- ”ÛUÑØ ¨°aö„ 1€F?Þlm§©˜Ô‘Ndr£š}:±j!°GÊÚ‹@–9{s¼À`n•M Çù^Íg¾¾Û; ¸ÛÛ'¾p@~°Êqñ 8uµ>n/øj$š¥£@-P/èÏ|D ™ æ çbÎgmÍ·¿÷w¤f§-];þ¼ÏŸw÷þN^èv*Eµ9{jØiÌäõ•Ó§o! ›Q¿øK€ÖD?áš .Wl³â_A˜PíÌ8 Z½¬5Ye|ëÿØTÀU³=¨Ž® þn oy>…ñ™r€x'&ë1PH“@¦¬‘Ë@¦¬²5à‚ó]x;Èakxð4ðŒSÂ|Ìú\Õ]Õ]Õ!n^ܼ¸y¿',G»­'!å¥ ®Ïm^“Ñ]}‹C‚Òé|ä‚T— >ŽÙ^"´“•ï|¨(8©{ï÷%È7ÁÃWnžà (—ºÛuÐ<. R_x*‚òØu#É<á¥)1€pþSÞÀdKºý¨- Í+mMÅÖ=v‚S÷hËÅ—@šewHij’ÞÎýh%ýõç€zD}¯ß æ påù•Á~ªs/8¹Ö€@ BÁŸ2Úƒœ“Oi Üj^° H˜nfĨiQëOmô¢‘ Fò ´Ümá© !ç çP-ÚZ Ö*‡æ‰Óô<Áº­@¹Ñ°@>b U@ʹî-¼éµ“^i¢Õ‹z¬ Þw 4ç­ü3ªÔi-ëXò¡´u¤›oBáhˆ~£xÉÃ@mÔÑ¢ÁzߪlµƒÐ£s¦/l¬_»pCA °ö©öFÞ¨þlåŸÿëØ\PÕ `dÝ÷E—¸«´¼Ô¼¨OÙ¨j€,wâí0Lõ\WL™i-õíT-Ðqî Ï£YFÎñÒÀeË•ý¨ÉÄ[‚úÑžx èã¬Û@4ð «JéS€|Z¬ë ¨²úz÷P Ž~Å3$¿Þ*jd®ä: áɞɅÚ@¾‡ËkÔTA5NkòûieuÎêœÕùZi½è]Ñ»¢wa†a'9ÉÉ›³åæ'€ùÌg>8ýþN°ZZ-­–`¥YiVÄî‹Ý»ïæ„ÃcÓVxìr)ãö< ы݇¤p…—ÂEAü, `«õêQY¥’ÓA–¥÷<´TV±Z­›ƒ˜Gî˜ñàVgµË –¼eÎåµr3?å7^Š+(«|†„½9’æjÒED½Ê¤ŠSÔ[QûŠè …+¼Ð}8¯¿0ï èÔi¿X Êº¿-vÔ&÷Ѝ{@UQ+õ0‡Xü6^ìuÑÈñr¨P:ˆa¶Éb“k> Ø„%Ò÷^ÔŸ‹8 –š¥Jò¸W!PþPñÐÏ€RO„kÂ(© @ OÜtɸl¤ºö"àS—µDà²ý`Öã µîK ™Æ1o ð-¥Ô:Pwã—¢`/—\²Áõ}TÙ‚ÃA¥i‡õf “˜#CÁjq!xi-HÚžÆû– ÞRÉ ™”ø¿øŠÖ4<ö‡ö°Ën+´«%Èm Ž40A5öçxË‚2Ù¡‚zÃî—3 œ73Jœ¼˜ÂXg48ç ³د$^³T(wcòdP'µ+æ{ t«Un] ²5"{K gEy5Ðh×@†ú@+ *^å×^\Z ÷Hp-ó´-±rëÉ…Ä%þ8á‹üÙà–?¯£Üoqµ­}Æ«¯f¼z­W¦ÐzTºJWé@<ñ7jÄrS ÷ʽr/899¹Î\g®íqíqíqpåºr]Ù–ûæ™ÀöNà*¦­ ¬#ÉXË; ¦c»G‚¤ð@Þ‘\¡/8+AŸÏ·ácТª®zԵ瓛»ƒŒ,¿˜ xxS›XŒ3¢ÍäôÍ éö-2»Žp„H`$',oH9P­Ý£bUéó>AÜgwoâ»øåÞ×QߨQÀxº™…@e»öûj&Ûyà¯u‡!T´:¢ž¸R¼¨ÊÖéÝÜbœ ’Zrµà„¿òÄØ®Þ€O¾3ïIgk- tqÉûÛ?¨:+&)üTVk[€*Fmßó@®Z¢€$Ye²÷‚ŒÕ«º“€FrF;rŽéò5.½ è­¼;ã¾v0— ñ a°Nœø9y ¨ù1™?d«zêNÀù 5ÿþ1DjR&¨ÑjHÚٷΆÁÎ>½ÿÔ› *¿´ìã@™!ïæÓW{«¯-vxUmÃù^Źvû›ÄÍ:™«õ-ÀiUÍà‚vÞPl“>@9ô&ÒœýªbÀ Êdd<¨|dH0›û/Íã|ö© 5 pÛÉí?ý§îøý¤ŒsÆ9㨣bÀT¦2EŒ"FÐê õ…@ozÓûïÿî_RI%D]tpF;£Ñ`†Ìï»Þw½ï‚:­N«Ó¿'èôÿ›áŒsŸþœþ/ôÃvP¦QŽÙ@?ýµØwä¥5F4¿›f”ùÀ63@¦f~|¢¨„;nbžè¶À<ê ÞÀ©`zÜ'g 9Oyö6 UÄ?î!8l“AåWõxPÉå3{UÙœùÊÅÅà´;µkãÀfŸï+ië€ *Õè ÄÊEó;À­tGÜŽ‡8ž7Ù?‚IWòK@:‹e™§­ÏݽËY…tVåñÃùSt¯žlŠEªÊ:o‡¹êVk? ¹$z6`«ñZ$é+™œ’ÀYå_)î¡1Ÿ&U,È-¡UÊÀJ­´¯*pIF3€eÒÉ> ¼‡Û=´òÆLß $u¹œhûIG@v­¡¨NömvYÀÑŠhêºõÿwA©WÔsÀÉ`ÕPp/¶¿4dQ…­å.ƒ&oÚë®Áþf@uõ¤ûi †ãoSTyC_j N¸Z{“óÚ:÷9à‚ó“ÙÈQ‡¸Plçͼ}}ã¡€Q< jŒu!8<_ë÷Ú¥!·÷éÔíµÁy¢†sßFÐ>soŒÚpÝˉ*Q%^«9h6›‡ÁÓÌÓÌÓ ô;õ;õ;ù `%+Y rRNÊI°æ[ó­ù`³ŠYÅ ÖëŽýƒo`hpZÇ“õz™ŽÝ®»¹”5ÔSæ³3 ZCc€š”×ÙçÂoîÒõ–v/ÈÞ‹]¶| šYñÜA-ðó}25xê€nM Ì #æ PmšöHÀ)ì:HDŒÖa!PýJ/lST-£¿ïEpÔϾ{8ÊB©¸h¢:ƒò¹Vy׃\Ñ*èàèá³Ï‚–â}!a(aªˆCnžûífˆT—õ©v¼ ò¬Y9°d}î-)‡Arä[»(¯ñ˜[ jéÀõ•uþXÁx( Ì¡€nµÌè¶çæƒòèóAúï³€pþ†Œ®FüÑU%“4Wù€¡Ä+€m„¾ž—wÍ@!m˜Z d°Bf°d‡ÖUêkí¨þ¦GÁùÀiè¼ ôÉNÎ9ê~¶Rä2%ÿÆxúïB¤#î´qz€dd9ÙW€o¥-£›4iÉÆóÀI5BõlyˆL`Ÿ¬0‡3™ç¼É'ù@e«l• D}½"ú½ðU^åUp:;Î`-³–YË@ë¡õÐz€»®»®».7E0íüý{Ž‚ñŒ™téMпÇ2\2Éš`Å"Vûy'o Fòû#G47¯ªÊ ïò_þ ä‘죧A%ØYç À´ n1펡÷›Ò²°´Yæg  µNfYrÔ^*§àÆš“Ae\Pó9pš´f69h½|0¸E½ ÊÐ èÃÛõ±ÿQÀCo5(j v‰±Êç^Šçå6\ýnÝð©4b)rNjË™9/Oùܾ.(g ý Â·åv4¾’ÈÕ—Þyõ$ðûgÄ}Wˆû@¹ìª9]AL»]îZÀæ¸üXVlî"P†,±«üš¾jç½ÿÛ§é @ƒÀ-»íGËz#8Ø/ŸI3à(MÀG­•@$ĘÏå3F‡e'+ˆ4ºp³d§lù\½ÂÓDRªþ'´ÍŠPd­šª>RÈ$ÐóêMg«Ìp”S€›AŽ$è´oŽóTÒœOÃ%—=È,8yŠ9L6‘\ç†ü¾ºï5Öñ ,_ààvFXσ¾\`W£?d,‚`ÖÙ˜Wn>×g®Ï\Ÿ£Íh°:Z­Žàlv6;›ùÕÿ·¸¦®¦÷Ö—úRœ'Ɖ³’Yɬ®¢®¢®¢×ò‘ÇÏá{!|Ë…”w€{”š˜›ªir"$dŸ½ Jw> Gî¦I4ÏcL8arQrìÒùm]A]LH©ô,¨ÚÜ®–&Ïȧ€ÂT5AÂŒp¾ * = jXÔȤ{AQve»×ÀyàÈšùÕAÆf¥¸¯š«½(Zò€û ÿpÔ;ç8rŠQâ€L5ÇgßòŒ±¯€r“Ÿêyã4ó´>u‡” ÍìB`nz à¡¾Š´Ù.¬Êƒ„¬BO€Ò­ç‘Q>OÁ\åÇßÒ¡1 KȪbZ©_6Ÿ;Š¢ª#HØyÑn(«N ) 8ÊO\=‰ÁG~ 8S¥:`ZÏ¿4ùÁþèÅ»ò,pÖ‰7£QÙÎi ¹ÇIà¹Í^rÜYfõâ)F]Pçõ{ô†@¿˜pt]ót§Sžü•,ÆWHÒ´ÒšÔ“1¿Ä”ÚЇž€—Bª*H–=É:ì—NÀí<n *‘[ìF€×>j~ “oå8¶ܲѮ ÄÈ‹‹qòæym#ëZ˜æ tglx$HÐ>zçšœ¨Æ’’àm”´ÙàâAZXŸ†&Þ`Z?©ŸÔO`T4*ÁœlN6'ƒ¼#ïÈ;À'|Â'¿ïÚ ¯Ô8âˆÎ"g‘³¬+ÁJ€˜ù1ócæßœ¯f¿ìúVŒOû怌¡Ú`yDoÙ ò-Ô(À‘²r Ь—É \î!®2 &STÄ žÍyÀ§NiÇG³ žù(jMÈM¶Æ/,÷"`_Z¾ã.P~U\/`¹´UÞ•n´-ªÒ¨.¥A*œ_°5¤ö• ‡Òh¥éËØG!Pã 7 ŽkŸ·9`Sšˆ±%j€Zj.H?»ƒy È03”{”å.);^"/ ,RÊPåÔí ë°Uœôìí—Ÿi*ߨ;{U3àêÝבò= ™wƒréÝ&ˆ© ©HsËÔ¼‚W¿ÞH.ƒýVÖ óx(’%©ç9µ¼HÉ,N€8ö¡n  ½¦g*HPk는™>ÅòëÐMsJƒJt^6ïé VÀÃõ¨)TvÞÎØŸå¾D±L>ºiµ˜¼eö5¿û9óû@ 06x{Ç´-¨}¬½ØEûi ¼fhÆ‹À»Ni' 0©ø­ücÐe€<ˆªî_ ª{Ò¡B† c°ˆÂ'× ü@iç!s# Ë ³Еõ²Ȱâr£€2êž✋V.`e"õÂræubºª¢IåâAYhV¾ÀqÀ‘Q QLc¤"¸^×ãÈý ³Ú‘ÇÀŒË’ Qà&’ý~?=÷Wî¯Ü_A`E`E`8ƒÁÎ`¯xÅѺ×ëÝk'€«m¹wÊNÙ vi»´]ä>¹Oî×a×a×anŠðþ”­½ùJÊ3 oÕêò¨B¼pÔj&€:ªNƒ˜Î³ à²ß 5PÛÔµV}(uY ©vþ`]|ßÜ:Ô™‚v½}À#”ÂÒ“NN~`3ImP¯–z ]{­V—l?ȊӫוüÚ8í5õ½Ú ­  ¹—G­lµ:’¨æ«×õ£šXj±zd‡EîÝ ÊVGP>uZ]PëÔT@ck@’ƒRW‚´3åt|*Fk Ö¨¯òè  .¨s ¦=ʬ¸,ü@íT+3ŽÃÊå–Üð9À¶Kf¥¢ñ|Þ8¿ûÍßïP?Î瀲¿ ĺjéf¬¶¨ÅמʧÚñ-PÛªž³ðI¬ýàR‡ÕPÖÉ€n’ò«žÒTE5ÇiêNµØÖØÜZéuQ+Ô' =áêï­Ú°²­ÊϧbÂÖ¨’r@"mÝÿ]'°e„LR‹½ZÐ_*ô}¡·@Õ’€øA&J+g;Ø Á”Œe >–M¡Èø†ˆ —cÖ$àq뉬X ’Òµ8 ´Z IVµÜ™@!Ùo7DQÉ¿Y—È>wÛ¯‡š€˜Î›f¥<¹8sMNTÞÃýg­Akd-Jû ÂR;ü}\ñ®xW<8…œBN!p¾u¾u¾©%µ¤FZ^+·¿Qñ]{Áo·ÇƒŠVÑ*Œ‹ÆEãŒ^áø”1º‚‘À·f7P¨GdÆ"’›/Ï UàpNÞ Yõ¿†Ì±Ó¨As@±Hn•ß>N eÃÏ%ÀYX:x´Æèg*‚ Õè÷lPÝ*Ž{pp4þhÅGAº+ñÝ4,b··¨aXr”2&{猷]‘ØøËyVøÄ¼ y5•"òtS‰Z ßÉJ» ÈÔðÔìÛ@’+) üªcA†Xƒ‡@–çMYä°X:Ф¼¿¥ ‰T>Äg !sD`(`8Ø#é-Ü(VÈbËòd, ‹fEŽ’eU«ÒMÌ»JUWÍA‚öÛáŸAév‘PK*ЀòÔ4»dèN ŽÝ,´Ðäk!à'ž(P.µÛ€×ƒŸ\Ù˜NœùI1±@ë®×ã2˜ïšO†¿‰Òº¸ Pk¤ƒL—?qXÜ—`7©¹©Z]ùLf<àâÜ_î´ô×Q0nùHÆ“]Ó\÷‚êÕ §îfЖû¿ò®âø…Xp°V„V‚Ý/ðÕåÞÀ\Ríõ ª©Á*Ôdël7¨oÌY~PÅxŽ­@u.ò5Ïy#< ˆ¶¼¹/Š%Òöº}­ËLû2HЪØ 8œ‘×ÉÅU9 a² Ô(ÕS>£ÓÍ.ÎyÅþ¡7Ÿì¯YC°ãíx;Ä-nq{ÙËuU¬Uò¼U°åëUP†U< s‰dPìátpö[iÁs`±+”ý³Â; F«ªõ½úwU<œúœÚ­ž¿ ¤ƒ–î’l.ÊÞ*VËoFºÎwF‚ri{ŒÖî¹¾i€ÐME’'ì¼Øé«U†oüôRVµ‰µ[OÅ­þÁ– ¹ò&A¾Ïñ_¶A>¶î%ê©Ç0óZZ™„nø,J Àvlk<(Ãì‘û* ³‹K .ÊBg!ÈbË£Jûéw£€¿ˆ¯ P’Õ$ƒ=Î\Ø æŠôûOìmƒzËž4Wšö6¨ÃÎøpqàDÎ’3ÑÀê0x‘[ÔY º”±:Y²ÔI±ÙÉPºU=Д—ÅT±ì`(ÈÖHE"U£ÙðûIˆ™×ù(• @߯½¡ÎcÙçÏ;=›Œ4F,p} UÐŒõÆzc=X­ƒÖAé2]¦“™Ìd`£JvËnÙ-â<ê<ê< ¡K¡K¡K>!}BúˆÙ³%f D¿ýzôë¿hËi‡CFãÕ§‡¼q³\Z`¸ª©ÅÖ )üÌ,@ò"ò~”‡¢ÔÎúU,WЂàOzÍØÀ;ªåÚÑuAÿ:¶N±úÜ9Íe0¿Ú>|L[PÁä[–Î5^Û¡½XVk HЙ$MXô×î¸B.P1ŒåE ¦1Qò“j牉ܖ7¿ð_¤­å±ö,¨(­ŠóHHÞ—.€Å:51o£þÕÈ1È/2Ô7zYÏ]DÊŸH/ûhè{P±TU÷‚t”ITÉçjàØlÔò%s ÞU瘅ã÷W_Γæí¡t`–U'·0ÈxFHC?N´êƒ»ZþÌÊu *µ@Ù2 @23ä!0+YíÙóí‘SGG‚:µ¤ÎÊ`œ<1ë䇠>tò;ÍcZ[­ H&ݸ<\ÕÈ"T¬ “wD+_ƒÜå*îºÎC5«Ô( Æ¡ößܾ< ±§cOÇžW7W7W7PªGÕ£`°‹]ìi$¤8çóÎyäyŒVF+£ÕÍw•“³ïÊ' Î²[=Ú{Æ@ÿ @—3Ö0@hËàë6ào' ±§/u5m½ï¹„hZá-Ù‰@­Pm»Ø[ƒK3C [‡3°Í{Ù©á3àli9O€þ±¾+j €Ö*|PrÖ|ÐÍáLÀ–^ò1ºf_dÙ U 0µGÌÈfûûGP†ç™ÂÅ@BÚJO?9'Ÿ_7ß?ƒ  <øœþ€°% ƒró¬ûQ€Œö¼ºú ãÍk©¥ª©Iª*h¶÷ã„.Wýçà“iµ@Âò´¬6ˆW>‚Ú¤¨A ­(Ý»ý$ ¯»\l1Ð:ž(¿´7ØÇ]ï%U!ßĪ٠žQoKqpµwMwÖA°ëå*‡F€þ²{°ï xÛÆ=Qø!p-7’´G!zJ…ÌrÙHÍW-±8˜?ìxaÏ÷ =º«Þîö Ýyù³”¦ Ö†ë…ßšÊf9 )L!`™6_ûœµ¾'½A¾Eú'õ2¯×ÜëIýMà¾5ÌïÕÒ©o.ÙIqÌNM;½¬ƒ™é§O€ž¤­Ð+€ŠWΠwüáá ªfµ=³T%íS÷ÃÀ~ÐwÈ}VÀTï†÷ Ú = Èá[A%ºçE5µÞý\ÔHpÆ ¦e»³¹ðQ‰yktýINò®DˆmM ˜“¹¬êÙSš‚‡ü”¿Ár}Œ>Fprr'Þ‰wâ¹V£3¯QÁZÖ²¤•´’Vàlw¶;ÛA“Çä1зê[õ­7ßWÖC9'/-ýüöFPõ¨ EòÖwäÕ ß0Ò!H:¨Òª?€:åöF½ª¨ÖGS\»¢€þNpïå¬|4¸,\1‰›Êî•eÜâ©~½_"íÌÜsÏn{ èzö`uP[Õl;RZë¸ù à[õá ÜÆh}HÐVèûM %ZQÁý µoË©N–/Xà+P«¢žÍ7´ÙÚíZ&¸sÑVcÈyðì»{*ƒt”€4ßúø&I³Àؤ·×AôÑ‚¼ Ìám?¾c„îª7©æ2°ì³ú¹ÀÚKÛ.ßTÏ™“SÔýj¼š Ž[×´ÉI¡ÂÙ` .rw‘VàÓ5z1èóôjzpVû@¯RËÁ Á™©³Oõ€ð©%ŽôCiÅíí@EÖ¨÷ÝlqnõVæÉ“ó@kz7­¨nê„J†0CòƒjiͶÉÎ —,õšÐ÷jçzÄ¿ÔZk½ ¨Ón=jP:85ý=sò%·¾F Ú$“ ÊVÏKô޼äô«_NÆ¥Û(”GóèKô%ú~­ Å¥¸yJž’§@]TÕE0XÊR–‚ –Á2œd'ÙIõŒzF=s­ÔÐÍ`—|{Ñ­†–ß²@½Ì×(ÀTÏrµÌñß*Åÿáí=ã¬(¶öíkUwï4™8äœs$¨€‚EŠŠ9¢âQ1 ¨bFs"ƒ€HTrΙ˜¼S‡z?ì ‚‚á<çÿ®´?§÷êêªUÕU+Ü7Dô:ý#°×ü48ä¸98PÈç%ž¹ÆxÒl¾ºÁ½©ç‚·#6íXc(>Ïâ_>«’ï ÿ z§_Qõ¸ïï{na6èÅ»gÏê¾[½Î%%€£Zǯª'±ójq>àún1óÃ]í]8Þ5z:€T: ¼²‹Uqyõ”íŽÉOÞJ@ó¤Ìw)þÄ4†:€Ž¯¤$ˆ@v'3Ͼ¨ ¢ÀéÚ{à€tmcxÇAü´'Îîšx0C’‰&œøY 2Dž7*€\꫟R¤œ¼)«’ H¸Ñ7%ôÈZkqJ.(·–Õç&Ðå î)oÀ¾›½|n¶ ö¹G]g„À|Ùû® ñ ò¾X›º‹Õ¸å[}w¦ßêk³—ùø.ñZÚ/@xëÖ¿V7-æ/ƒPnéw«ÍµÈ?=õfð`¢ÜÖ‹eš”þx–ñ•¾ ¼^4÷ªvôqýˆŸ¼RUeÇ@ óŒOAº°„6 Ÿ³Ž@c}‡nn^܈ €èÅEÇî§Ú±È¶J`Þ£û1àC~Aþ#kd3HÓð§{U¡èÒeAºI.ÚÈtú»ßÛÝÓû0þ5PU&a€4`Èw¾‹Sf€ô3žO"Bµc,Hyw@ƒÞgN "ö€È@Š4‘«’cvêNÀ¢ ð‚~Ô£ê#çApÝÈ¢#‰ð;g2%U¤ŠTЂ´¯¿×ß뺟î§û›ÙÌfo™·Ì[¦µÓËéåô‚âw‹ß-~¢#£#£#!;3;3;dµ¬–Õ§è£ÜKIvkZr¢$y¥È Æç9% #±ÚvÐØä''Æég³êƒøåJ· hÛx+ú.àQGç$ˆVá^ýý㣒Ï'¯*ÙŽ«l1`[–q9ˆÏؤ_êIà À¬¡dæÖHÀTìÿM’¬ÀqJ'ïO¬ÜÙr3踷)Z˜ÎäâÁ$¼í T`/ÙŽD¿.A®Ý´‹ë:É¿×;M¯CiÀ!U¯´ŒŠOLJë:É¿§Ÿ¢7Â&¾™n,°®if•m~ʽg@jøŸ.Õx®ZQ72ù5·ßºï‘ÊËE¬×Ó€‰¼#oï»círnQì{ í7A]ª7ÀʰßÊ鼚“¿òkÐ#b}ò§åÕj¨ÍÏŒ‘à_c)c=˜™O‡ègõÞ ƒ¶^< ›X±¦„ËÿÏî+)®uô=ˆ_^’WâݯŸ ± EŽÔ‡p½c3wN‡¢¢ƒSÖ‚¢5{­ vûœO¶ôã§IÑ·`äD»m’’Ò8»3Èg ójé%÷µ¥Ž5X†ãeGÖ\ÆÛNGà>¾w¿z¹U£¯ëIN) •r”9GÖªw@Ýh¤>rž¤ªLйìø}\t4içÓŒ=¾AY…Á‰€œ‚qé2Ž'æQg.¿ê-èVýN¼EÑ {{ýÜõžŸ²VÖÊÚß篞¨'ꉠÖë‡Mlb(æ0‡9 ëÁz0x“¼IÞ$¦ÒTšãÏø??€s¼\Ç]ÍιPŠh T—¡ñ¯E+ïÇä‹T"ìàGçÕæ# í}ÃBW‚ø©Íù$J]¢€Ë ÞF¡ß²?꥞[yHÛÜåkŠ@vš=ƒ}A¯ôš:™ _‰vÈ[2$´ ¬t>FìkÐq*è{“S½l²Í§Ãf%´-—Ë@ùŽ›õ%$!¹J(Jþ¾`ªWœº £rÐ @ÑIJ¨Óõ&òæc ¨â®pW¸+´Ž—Š—Š—‚´´Â4 ,e){vÊ1OâªXAÎÃs^¿÷zH½)>p—šy¡·¤”~tD7 69n¾ò2¨¢àø¬ó@êòµ LžE®®í¥ƒ\XêåúË€Þ¥ßnظç9ßÜ :î t;øhÃÝà½Ë/lú¢”‰j€jRþ¹&ܼ-³¦î„LI$ÿq¦>Aü^+ï*€H$þ)`r úè°šOTÏžÔ÷Ï@ÕÃlLy^•1}©å µÓ?tŒc‘C€úæ[Æ?Ò›8ÆGƒ1¾Ç@úʧ¡¨rA¯Ô ï©/¬ ÀU/¯T}´[Yà˜S2ôkz, hfð*Wçb èz›m/'*ÇÇßéfá%€Ç³±Ç@ÿÌlv€v©ÀýÆãÁ›€˜±Ü°òò,è/yEßÞ,ïmï2p ƒc*wýLå½r@_x¤ãê¯ûKSÆ—šå‚6H¹Ãèøe¸ì<²éXÉ£°i@@ÒÓÓË´/ Ý çu ݾ«¤Hq8uwOPcâÍs›‚ñ…NP/W»¶×}@žû`ä.Ð+öOš×èç]ýd¦{l-0š¶< âc½Ñ °ô%¡ SüsÒg‚ºÎW)u2èxÂÇÿ ØE Ò©z+ëÁ EFå-í\^ÒÄ'K³@çÊPÄ;?çBñg¾õ5ºAÙ±>ùÜÏ "¾c©g`â:¦écÔ'êõ ¤êTªÁºÍºÍº ÌÞ@|øð YÈÂß·'¢²½¹Úô.¾r—:m@úzc½ À2gŸûè(/èß@Ë·±² Ò}–Õ (”™ ]–3ЬÐãA2ÌÂ`=`\ÙšÞ9ôÖ/wޏì]²@]™4ú4VÃPià|gwÑf ±9/t¤Šª¼ô>o·] ÊŸÆÙvvÙ‚W“ŒR Y¾½.@±÷”$Ðv¯õ%Œœ“GŠ*8´Òï¦[\Ü ½Û}pXá%ò, ¶ýK½ 3Ó¢ÔŒ)ã?˜Y dŠZk íp„Ï@nÉþ¬]. üBxëÐèŸë¯²]W„vrÅ#lfˆaìµböòu/lW+(s9`q>åAv³žbàg·m,twÝ‹¦@ªqoàëåIóP;¤¿û1nFvÕÅ ·E6ïM§Ε?-o¯±%° ô³VAzèV¹´0Ph^ eÔ«P…ùº ÐÞ[Ï;Ë¿,o+Üê!÷¢’W@ÕÓ¬ jƒì÷¾Ëbù äN½’«@›‡û/;Æe5‡õ{¼ ¥æÂí@ýØî’ pŸÌQƒ‡_H]À w ÈÇFçÀjJÖ®Pp¥âɪБX¦]òÉIe·ÌÕвC{À+vW> :FšÑˆ£ÅéG{u.ÐDÏE@£kyÏÿ…éeK¶dÕ¨F5àb.æbлô.½ Lö°‡=@Yd[ØÂ` kXó-ÏÐàN¬«³8ëŸxjºû`0^oúŠÍó@¿ç­pƒ ç$ )Ê`ž¾U?ô.=½áBàplEAôÊ¢¼}ÈR•¨B̤`Ê ¾wŒ/ýTxLÑQäßVÀo<™Yð¼¥Å%€AFý£±H9oè±@˜GJºÚòB½Ô—f¢håð?A>ƒd³ˆ;—Dg»¦(àÍÄ(˜„Hûç’ØZna ÕƒfeÐ}wºÇA?¤»¹@z—Ú¸#pQÊž Ÿïªý]eÐQ¯—„^òð;pEBµ¢,µAïÕ¼  ËG»m<ùƼõ°õ:à°]ÿT¥ (¡ E {¯2tuÏvÚ3ŒF}sQÁ• Âiãk}$g׊¹`0¢ÀÛF†zô…4):úÞø ¢w€KãŸÓô ØÒˆ,Ê æ‚¼ÌíôY%ŸË|`šñƒ<rŽ=ªäFÀïv1/ú²žlà]Çì.ºyëc ¤Å6µõPæÄæeÁëu¬Û7ߎTR‰"²br‹Gäq`~h˜×ج¯wïL©¦eÛëOŸ6Ž®T"zB|[Éã@w»’Û PVÕ`Â'TZÞŽ¡Ô …¾þ«€2KÁÙUë¥z©^ ÒRZJK #éìd';Á$H ‰p‘²É&t#ÝH7ú‹6ß ÍU;àfõcè‹ùM?àèž •TãÐEVÍÀ ÀÃÎ×%~Éá¯âSÏi¾sÒ4ðLVõºðܾ§æ®—7õÒ¼ çƒ(Ò¨ú8GôM ‡·ä<Lo.i4uëÙ£€fV¿ÀÀuv D&ð×’ØJWã¿+Iw7õñˈÀ*À0®H»pi”ô‰8ÿ0·,MAüz¦[ÐnÓH€|­_ñI'u'è¸>_%Vò”¿;!Ñ8÷3ÄïË Ý „¼‚Ø‹@š¿VfGॲ‹[ŒØ™Ýt®“Rr> ¤~2¿cîŸ$4`€<:5º¿ ½'¯¤À¼Ë?´¸Æ¸t—›%€/aöòBrAØÂuº;ð¡{kä&ГŒé¾EÀ¯Æ^³)èHÁ²MÃ@:y[¢ˆ˜ ý£@ÆÉ:c*àqË͕ձù…D0×®ÆJPŸá£"FCüÀ0»\¤=Ðo¢û¦:ËX Ôq¾ö¹Ñ¯ ¼¬g9Aà±=m)iôöàÞ ƒt\Ü ô'±·ó§>ºòHª5"0 t¾ÚkT]ÇÎ/®\šQô—,бd8ù/íNü´çÐÜÆñÚ ¿ßuôKÐ9Þvç!€y¯o1èý²Ã, úu¹‹A@‘jk\r“ÔU%pÖÒ£<Ê£@MjR“D¥„ 'æ½I-jQë”?ÜÍÝÜ z¬«Ç{ÙË^ *UO#¡§®Tƒ€:êóz “^Í6`¹ —"ÀôB/†ºÇ4A?â-q^}S¥¤PdM›rG™ÿ4ý Ø~âp1è-‘º9€bžt2ÈÕò"P'Z£` èP4«à —¦ô¹oÇF»ã—;u‚¤´µ<Å_IALtj†³³`*àr@Ÿ Úv+Æfƒ˜ÆOþG@GÕ=¾ÄÙ÷ɪª3¯ô H,!ŸÓ¹tXàVê‰<pšâ^ã« hŽ&} ê¬gÈÄóÖéA|¦h:f¶õMid އŸ{.ðHÎÓ«»€Þ^t$ ¿¨D”£Å©_ü“飃@O÷zųA\rëÑž wëK¼%@º³%öˆé¼ï tÔôü ßÅZ¾âÄbŠ>‘”¤h•¤÷®¡—ú&´¯ìW %±Ú9WýŠÞØÕ 8,Ï©ÍÀ&¯µ=ˆù«¥'àÝ ŒÑ@L–n€Agy°ˆë#€Á—œ”Ñ/yó î“Ñå@Vìé¼@¯Ÿý ÈýÞíÔZ¹BÀn>– À'­Õë {–Ô:\ô–¢*ûžy#»æ9Ï‚ïΙ 2æYŸ¦¯vh?`Ê:Ém¸C£€Ôu–ÅöA3/(þÚpåùLö!øÉ]ÂV.=¨äËœ §:ÏD€¢¡¬ {F8ˆú¥·FÒ˜¾À µÃhT“ûÕÒ3èOîäuŠNÑ)À­ÜÊ­ÀAr¤žÔ“z h@ÝèF7äù¼§½§½§wxçL¹FòµÊ7ïyÉ\Ø:®ëë»#Æ­¾ý@Ìœê_ hrÙ ø( z—]?|0ÄÌ­:¦¿R­ ðyÎCkÖB•$"Ʊ¨ÅE g¹óìOÀ›RüâQ?èõúu÷RÐamxËÎ#±C@S}™üxúnLêI$ôü™+1A [o÷¦¢»@Ǽº±D1O ypôÞÀëì _t× |Æ3é=™@WÀð¶Ù炎¸ïE£ÉÖM16è¨\i·1¥Šû ùIJ°?ëMÈvJZ¥AÛ¾C¡(•'e>ÈèJ};_úîèÇêƒwõáwV„‘oÔÉ÷VgÔ+‡üzy8~l>èavA¤b€|8º‰÷àÆSÂ;Cçz ŒÈŒdXôt½63M÷Y“6®r Š‹÷,1õÕñþ —é}ö ÄUþ¯ ™q³`(ÈFgdÑÓ ³íÂÂQÀ;ö’ÂJÀ§öꢆ Ëì2…³@Ù?5 D;ç*¦n$²¤œné¼ò¹ìuß¹@•²µhD /1ûXzõÁ_—¾r¼ìMt¶îL= ÚµÜÀ £ê³/ öä­ 7è+¼WÁ›j?^\ô,½Í›b‘Iƒ3ö³ƒ”‹epQ¼BñÇ wEÞ;žØ‰§%?´©”l»u4a߻탠cúV‚¼aŒtùF-6΄љ$óÕËô2½ äCùP>ä÷Z€äN_ ’Çåqyœ“øâú:}¾tÝCŸ\«Úæe]ZÞ{ª:À&_qh SÇ^˜¨5AÏö>uÓA¿œ5½Þl`YÑØ}½AïŽ=t|& )ѤA&eRɽ/2õ¸€¾$^®d6ä™ĸMϽÏ{Îþ ¨é}é¾ X^;ÁR\‹ŽÉ…À=íZ! >ïœX;ÐÚ¹®°? )Ò'2õ G%é ÚqçØÿñ9s¢ã’Ó¥ZRßé ²“ûõâ2èJmJIDATAÃÙ¾ðt+ÏKlulÊíõG€¡ÖÙ÷&—ëLj'Nèõp!NÄo\ ¨F-5}kÙ ³ÒëU?ôˆ}ÎÍý“=±¸)0Ì{Í^¤f2|©ONQ$(=z¸}<|èßÂÑck‡zI²7í©/€vÜ_í×@|Nûh—:.Ò§µÛ  PJ¾\ Á–¥îÝ»ÐØñ-`p‘|Ô§· Î{Þ@OœëÂoìb¿žbÓ‡k@2i¢DÑD§€ìgÏ‚ÌvkGïã5·W¸K^R©%m@DZÙÚV·Û;A|õ;ŒBªY¨>=¬ðå½ã€ïbw~r´ü¸æ•€b³¡ II:Ø~AjKÐ}Üóâ€ÞíŒ ×!qD9½úUãdÓôzï9·x”üçh è9Þ\çÀ¤Ž$ªH³ Þë•6ÙµÂWƒ7ÕkáukQh-ÈB•kÞÿçùy"±ï´Ÿ¤HФ€ ‘!2„“ìÁ&}èCN¢K‘IxÅ^±WÌIˆ0i'í¤Ý)O˜!³ÕvPÎÏø¼qfž¿p½¹ßß 0ô^‡¼õ8ÏéBÑÁ”ÒW˜é «>ú·=#f ð¸LmSŽº ¹@žýˆý]äjÐsÂ/æ–} ê‡?í%pô](öJœö •ä*U:¯® Áw}ý—+¥(iðAÀ`ŽÞ˜Îí%€£SœD{«Êˆä;žŠU§9Ê€ëöŒñ#|™ cr‹‘Èá>B"·¾ øÝ ± ÷ùxÂ\–'Á@­?P¼UAÇE9Ã@|j‚9tØki&| Á$‚ËvøÕ`ÓíX‘à2zV›àJPÕ+¿×å^ð>;0dÑÐvìò—S6¨ÏAgÇŸ(¾Øx&3Dqc2L ô]Iw]«d[N=ÐÜöñÏÝäñdKëžÖÛY¸ñ'"µA|†çÿtLµ1eã»ø…Äþ(Hgy‚é@W£–Ux$|Û¡7WÄS)€Çýɧ (÷†øË ÷îØ0жÑ<°—Ä—úGÀ¥­Ñ¯»…@ÄQ c¼Å—É¿ÿ1úSp¸E? ê;0Ü~;1>\ äëO\?x‡ïY¾TëjCÎ?R¦hÿ®k@—èã^M@(G=~ßÞ—p€ŸAϱ˔ ý°áî ¨6æ; £ìâGÀ/}åÐ*Ò/0P7æ½ãzIDÒOëg“Nr#0Çiaïïuù%ÖÔCþyi_Éuï€|¯óA£¿Ñ߀ԗúRhIKZrа'=é 2M¦É4P[Ôµôúýxã¼qÞ¸ß}„'%Yƒ¨F¤ÜYîZðÖ™U‚@¿ }åBoY ý’¦Rˆëþ:¤MùÏ[Wmæî~t¹¢Þ{Wº34 l€´R7€Î¥¦~t§ð†Ü™ ¹Íã•¿ÄUs~JxO™Ål ˆ=È”ŒÑ@ÄÙrÙ­@Ûæa¢ÍÔQnvøeЮ·'\ ðd³d°[qfÑ ãúZ÷RŸ{0z Ök©‰³oâlfèÝ® cî‚hSÀ‘û’à›eÍïzþ$AÝt\=h'òÜk™#W_"‰#ÉE \ÿC!€|u“Êé™=¼]-Ð÷ÅÏÏ’wûæ‡W­5¶:yÖLwØ Ü ±Æ@ÀÜLÀ'|(å£} Ž€.ÛTЈH"Åù'þ—ý±Ã â³oŒl$pOj_@s®l¯u¼ p­ïíÀJà=ýº]Xošÿ0QŠ$–|Ή<ˆD ì 踻8ÚÐÆßÀ•*Æt@˜Î€ëì‹^ÚÖƒÜÖáæ$¸ìfÎ<ŽŠ"ÐQÉsf€(j›¥AÛÞ`ói E¾5Þ=±çv ¾5"˜ <šújÅ%@¤¨Æ¾Ï|¥^?Ek£@¿ª+¸õAwrÆ”\äú+dd‚¸MZžâNŒ¿zZøšœlЩ¬¿”¬‘YÉ^ÝyŠ^Mè§åuV‚÷k|{ôiP·øw¥÷jeh.Ó—éË@Ö£õh¡2T†u©K]à)žâ)0OÄå6¹Mnõ«úUý ú}‰¾ÜÎng·óï>Â?ŠÑ<ýÓ S þŽŒ³Æ 8(‰¢†6Ôl&èÚ 7¾Í¼$+£GÍà…¶œQôSºµ[ôv›’ ÊUÆ­@›è—…Ç@»Ñ‹órHâe«$±ìNH ¥M9€’ å*Àç5 ñçÃ]Ó0­Kä:½À™žÿ&àñƒ—ïµ>¹Ãùë²àêÒ´ë¾}Ä2|þ¹ ãªµuˆå Œ¾:êÕpް”d|]ÎÂö{R¤ àÊ<¿:j_:îVò= b™3|¥A‡ÍʾkA ÝWÖ±KMnøxÏngúd`,éW€/IO8µ¥·2EÞ·öìâ~ *øoDÏó€·¿dÉÑQ {ë^â(Ö_¦$ ò¯û£²´í:ÏF±Üíþ@ÇG|Uí.8ræÒJ>пÅJò>徟ˆ,SyÉþ9ý9ä Àõ:86ˆß:nmNébyóíù =77z9àÒ;I'žBþ^6ãOö‘`Ì PèBÉï<ï~¯ øn,˼=yßÂ?¿žû¤û¤û$p/÷r/¨yjžšwÊN>¹˜ÒWúJ_NâýË\™+s9YGì6r¹€]ì:Sݹ¹6åér³!ºI7[€÷«þ;T%*±ˆè«½[Aª–éÐÌ= ¸Âª ›Gëæ4L^W×€Þl· w]Aù­ûÁû¸dRÎù kzç¸R€‚“W0¨$ç©2[Æùº¢×²¹´í·×ƒì²Ñ¯QOÄhÇ‹Äzš¬$ÅYøf ªÄÎCwõJÚ™¾Äg¶ îí¸wD¿*êDüVIݤ÷Ä;ÙúhG.µ‚„T¶5P¾…¡€H¥@†UøðÜ} §æuÚt>èûÃßæLR¤®Ij:5Ф)׃¾Òmmß úu§Cx) bÛJÞ}sÜ\ŽKbœóÿ!@ŠÀ¸+ò:ÄSÃ… ©¾ nèCîEݧSŽUj<^òùÁ{q ñ €CÔ¿ì"½ ´ã>=Ä4^µú8í#×®>ßKY‰ØÉqÜñÚÆm˧îùÆÙ4«¤: ™½|ÍA‡ŽíÝô ¨Ïkí;äEktJkÐ?9³ÃûƒŽòŸS´„(z¥îª/o»ýxñ{ .w³ï½%üø±7àÓ$ò[J%\xÂGS™zà­Ñ“e,x½ä2ë8˜ËR”»þð1<)î$w’; Å(Ft‘.Òd€ À7|Ã7`Òƒôîàîõ–zK½2JFÉ(°_¶_¶_>{/š%¡ÌÒëÁûÎ55 ëE®.ªÊ.§4HkWÊ(éÇj^ ÞªmK>?h-Sô `ÑH­ý#ź€#ÜpÚ£nèëõ* Óz8” :×\æËt -} e‡š8|í¾ó¤ ­;ËöÀþ‡q÷?ô0ùŒêH{UxBÕõU<3Í—ØÊgtòzÉ¿Ô=p8'±Ö—ëz  ì‘W@>ž›ýÈÿجµàmÙvÁ5€ =³$a0}å Ä'Ϫ6tèâwÕDµ1ž†¦] ˜¤ÿK¨±R‘¥ m"z-HЛÿXÑ2W€Ü’RP­#x‡þökwÀ´Ú—Ë]ÆßõÏÝ€G窫>à1£\`7àªãÞ}€GŸÿ¢Õ:Y¼eó‹¾PÞt¯+`Eß/úôÓÑ”âK€ôðÈcOÇ‚Ÿdoжþu.åŒÉ'uý.AÒð€®Ò­èvð.6~UA¿ï{5˜8 – &xŽ2ì íRxÄ€j1tmý´Ù¼Ýf©´`¾–æd¯ç¬bnnª®ª«ê‚šª¦ª©À¼Áœ ë›t 8Yï¯&¨ jq#nÄ!>*>*þ™tÆ¡*™ A:›W¥¼n‡HìðS`Þ®–Û A -3´ùÐï…3Ž>ÚÈ»kû6@HOÂAã>Ÿ¬ÐC@»ºmìGŸopé»1ÿ“ö*€Þ«_8íÑ6àãARÖçÁÐ Õ ¹¨é#x.`ðT´ýzŽˆ÷•Ø€²•{ðh,?àè¿Cì9Uâlä+ǪZ²Æ·(å(x?GZæµý”g;ÕÕéô¯LÒ•š –´tÂá± ™n«h‚ìamÊ€žzð¢_~ýuẸ́ߦXê{^KV3þQLÀO^f¼KDq*g~ë¢2Ÿ.m$ù{£ÓDªÊ] ¦óBQ {ŠÆƒÔó_¥ÐÅ÷yé¡À›v4¶¸Ë\™à@|!‰Ê|f‰²›E *¿¹TJÐÈZÚ‹ŸWⳆoB4LWýSÑøITŠ| s£·8G#`ÆÒã㺩³t™£sÛr4ëç:÷ƒ.uàŠ¥Íä‰$N†qV¡P,"õ‘=ôG:ÇÛbø¿È¶@ÇÕM¾!ú¨þôäo~ÿ¹K!èM2H¾÷Aç2ÙraàîìWÀ˜ô•Zuö—sÚ;íö žRO©§@öÈÙòм"¯p²ÈϤ! i2U¦ÊT×åuyŒjF5£Ø—Û—Û—oñoÁ Áb óMNÝêùô¢*+À9\òúö‹Àÿ½ï…€RºüM-g€·u_Õy ªnì…€TñÃÊĿڟh:9Cí|[Ðħfö‚ŽËÆ$ðE `»•4Ù¥< –Úm}ltvÇÚuh(CAnËð; ]÷XÉ/ ý´ñy=S¦€Ž¨ÇSÑý\ÿçø“Ä9È*Õx#r™¯Yèc Æçf ¾ ¡o¬è×…›A‡ÙD‚ÂÌ:cŽx)Q|I aêl Ýâ}AdS ä‹ÒÖJ¬Xº%xG·<0½.*{Ts±½ 毤F õ‚û蘌ræ‚vݧŠÛƒøT‹ :bìN9‘èôö?èÈ¢+ˆßûÑ~PÎôü2 ‹¼xt;ȹ'þ,Gš?ØûŠ¿î£ ¼üíØÙ˜ž6RÔäB™¾ËBÕ@ú{Ík€›|½C[Ant7Ä®=Å»Ë}ðQ‘Vüqi «œÏA»|_ h³½‘ â3wƒ.t tЭóîÝšêŽJßvädVýEÌ_0 0œ\8ÔñËdÝ0Tiû\ÀÕ_ºß†³«À(ë2%€Ç/|šlOñ)­óãq xž½² œžnªžª}Vù Ï€q½o}ÊàC*ñî)¿kK[Ú‚=Ôj«¢UѪR]ªKuà2.ã2p7(*Q‰J ßÊ·òíïGóóópª;Õêàw»ÇÏÐÓå2Õ¬U¥g×n Î 7WÌÊøµv !Jèš÷ØöÙ¯¼äD® bJk·“nÎÕ€&$Ã@ǽ&±ª€áÞT4”DÂÎÆdG%âщª«²êic-+ÍúÀZ÷ÃèÍ€¥»—®³³àvÀÑOxW?ã  Ëóµ—¸ád—' çôêûßDbÉG9Z´·z„Z€<¯F[³b½œ© ¥ÍyÁrÀ³½¯fƒþ&©G~¿J&sƒ7ôõú!÷ð øÄù¼}Üá| \¬?æApù¡m[€6s?Y“ z¡ývño€Á †¡³´ŠI yT×\Y¿p¨M¢?îñÊÚÙŸÀ2¤¹› µ þe€—‡¥A|¤‚6Ø/¥À™ç=BE°Öe}YãWàCi#á3¬jmݶn[p»‡ÝÃ`´3Úí@Γó䥿¯×¡¼ÅÍ€½ÆxÕ¤©W] mêýÁ+­“m×”1ÔÎ/ m ¹ÐtM†rÏ“ c:+ÚÄï÷±*d¼h—ŒÿþîTLðWfˆå¥Å&ƒv ï`ú¾õOyJÕD—°‰„ëø|ðJéG¹œËÑÖFÖ,Õ¢æ_8«íªvU»*'y>Œ<#ÏÈÕIuR8™êÿûp¢ož’§ä©ßÁO`†É^Ù+{!º+º+ºë/€eY#«Õž(sKƒ²àòÝŸu;¨ßr·®k d¨7ÕR@ˆP$¨:;ÍA{2Ô¹‡D¢äÇòõ‰“.€Ã^çE@œw Þ ß[e·1¹Ÿ@[ëÊà·ÀJ ½4`ŸS®h'ˆáV*¬Ú–WuѨŒœêlÒŒ×wŽÛ´ *ˆe”„R@Çe©/QŸÃ$ÅrAêËÒTŽ¿cêu ¦zQÍmó6Ÿün`:‚o"s¾oHg«j°)´Ÿ/ù¼ªº„2 +gÏk·Ìwë7»ª¨hš®\xŠ0«S몟ë_Ý¥À±&½nÏïüõ#Þj úÇ£Õ6ä‚X\¥.mãKf Q$ ‡¼‹QçÛ‰²Õ/“ 4±“ †/ÙOŽ»»`ˆeÖÖ—e¾D†ßádn» €Éeú-Àç\Ÿ$,ù<”$Õ¤3àò‰žr©¿EÖàÁغ£kÎn—Âɀ߼5« åkN§Ûla H¦Õ-8˜o¶÷­Jg4ñ“µëAB*U}*î“Ú¼rÑ_ò‚Þ£ŸÕ¹€"t²­ˆŸ–Þ÷€H•x ù–Ÿ“Ë}¢Jõ 4 e5 p|¦9Hw:@Ÿ_0eûP÷TXÜö½¾ñ©ó@¯´,é øŒ#ñ7WZëDtbÆIÜîä^F€Ž{]#oƒX^¯âKAG¹éÛ-7éZ —àg*8uÝAnEÐ?úÊHߊÌ*_Ô$ΪcÍcÍcÍÁho´7ÚƒÑÌhf4)/å¥

çsþï÷ÿžÛs-×r-È¥r©\ Æ3Æ3Æ3`ccÑ¢D?æ3ÿTðÁ“+ÉÁãYãÀXXëíÞ@¼UÞÜ]ýAÇcñ‚Æ i\+‡@LY¬'ŽúÞ~pIK:­¬dÎwŠY‚A5¹zÍJj‚”s«—4úïm`°ïÓôRÀw|ôe`|onh[o±ï ¢ôNêÓ§]+HжÞ`o ç…‚€b³N`†È¢ì×óA Ì!pÐôüS(û˜“Ô'§´WE e.߀ ó­O €w„òj¸ Ë4huX£šm¹i1¨žiïVÎêr÷_âô—A]]ö‚VãÀ¨Ø20z&èêéVoz¿nž¤Ø²ðBÖ¢öØûAǹË'[Xíýœè$­¸žcW §bA @±:‰9JÂVWãZËíþtÌmQÒ€ªIT[ßɽG!ÐÏ×9c,ðMlFÞ Àq.ÉÏ1u¡ˆ–dÓˆq”_@nU+ŒÛAúúæ¦hÒ •o~ï×ÓÚ-§ŒÃ!Óò¿Rh–öÏ"ì×s“÷%ú#ƒ/%Äs@Çià%œœfrâŸnwC>è¸|% ¯¿¯%ðvdÑ1Øâ>½x9µn¥n€+?Ú @Ǥš“ÇÙ§éó£HìlW%º‚7ôñøòã›@Lýƒ È@ßÂô›@ÚgúëÖ÷Þò+:N3TëÝKƃùaðÙRgâéHâvÄÄÄ€YÎ,g–•©2U&H‰”H P›ÚÉZ“?,IJ!©%µ¤¨+Õ•êJ°ŽXG¬#ÏŒgÆ3Á9Ç9Ç93ÏbÕÇœ þé¥+×ñsÛo˜ ÞÊ©B‹D‚†Zf×å /±òG©™Ô‘¨$$ ½À|]ì.o«÷¥·¼õçkЭQ©o]CºBÐ^¸ÓÁ×@/·Íâ'-™Ê+'ßRÿášøïTi :î5-þÄçŽ,bì¦ärilT¹Ìz$åJ˜,mÓÛ ¸\ìõ\zz}—K¼k@Géêõ.‘®ª;xÓƒ=³€U¿îÖ7€ÜßÌ-²&c]óAM¨wååw UM³ H ¿±ÄT]Ü: £ÒÖyÐýiëv¦þ€Li :îî*©âóÞ$N¥ä]ÀÐYî} mçpþÓ€ÃKÞÕI¯tŠ>ƒn2èhå¥õæØ?¸ž×€á~Y80Ñ€Ë@ºX£C7<¦úš7‚޲#¹Ðž±ÝÚKîЪò²”è;Úd Ün|ØÀ1éæ$Æ¥¿àJtOҨ꿼îe?è˜u‘ :G]ã½ zPaß½KAæe>]ëE ,×ÇÇÙ´/˜òMü:À#ä%úyÇ“ý½ã/¯yX€«Ïw°çô±hïžp_/Š®—K,à5$±ø’_h‹B ïÉ}@s³T(ô»nñ@q®<¸nIÑG€ë¥G‚üh¤ùZÔ±Ž„^#áÌK؉„HsÈ:˵ Té_@¦¨Ï¬þ ­|eCut À”;âO’ðQIê=]ð—×|r9\ ˜¾.ÖJЗöÛyäýtUq ¢6²È×_º¥Aªªþ¾ ³3öÖ ú°Æ#úƒjÚäŽÛ§€ú¡VøÊÒÀ5þ—Jooß¡‚ùýÁÛ±¹ø½À¾~ÓŠ÷ºsï¡s—®ÿè´¥ÙÁ1‹Çâ±8'1ÿÌcæ1óÈ ™!3N ÿýAþ”Ý+_Èò¨jªšªæds²9ÌŠfE³"”ÜTrSÉMBÊŬö© Ê7ãÁ¬ûÜñ rÎ;¾ ¬‹U×èvÀ¢±JdB-4©›’¨‹ç¨žîL]F ¼ZmMŸ‡ÁjÜøçAºÜ2§ÒH_y’óÉ„’JtÄ-ý}“§À·¡êWƒÞ¼ûµ¯¶€”‘æ²èî{.ã àþЮòËAžO¹§òÏÀ¡+Ì)í«’ypµï‹R—‚üæËM« ÜÃéÄô¯n] ªk¸é€Ö7éD®1Óä\b@ ©š ?÷"Œ® ]Uµ2ðŠªgVå&²'Ð5«)0?ý‰ÊÅÀÆ’F{ꀶÕM’ ¡,mÝ–¼9û_©vx,áŶ׃d9  Ä)î h&'3Kszµ¨Mb¬ñHeãÁ@è©ÎøØ*à ›@Çô.í©ã./Þª0ÅWñ9¸Z`<Úa' ®þ)²€IEZ‚´¶&¤ý²ó[ñ Ðýõ«RÅ(IÞ»æ_è“u€kv•¯€{bãŽtÚ[­S—‚ì)E“Π省®^¤qÖ« ²—ñÑt‚ضûÁ¶§ò7{‹{íº£{Ad"ÎÇ@q8ýÄÏÇ@0V”ÖmõPÆwUîà¶35.<;<;<Ì^f/³A#hAÝ¥îRwñ;0ÈŸ^ê2’‘ŒÕGõQ}À(c”1Ê€ï°ï°ï0DºGºGºƒ»Ê]宣•ÑêÔzd©ª›ý 0¨RøÜç rõ‘›~Y ÁþÉÁ2`øŒ¯BSÑ˨Rš RÀ»ÑËrÓÁ •›Ô©øi»³H+kQêþ±ˆX\f˜ÿi²úŽ ¸+BÅÕÏ™)mñ@^2sƒW=ì%qÐãÃfNu oþ³~ïõȸµ“€jÆ·r ¨ñ™•A†±–Z@XotÛ¶õÝz"?è+’†Ÿˆã~‚¤©¼"ô&÷gï.ÐïTy÷â€2Oÿ›Ìà¿•,>SÕ@ß#¿Z«@Ö˜ƒõ ¡5$£3ÝD%ÛþWšOä-¬Õ…@Ä^ Úu›÷ŽþÔJL¨&ò+­ ôNTõ ùPWÖV[íÊm½•¡ €ð¦ŒŠæ¾: ·JªnR•IbŒ5gKs=«$ޏ8¤{:{€v÷Ø«æåÁ„¾oå0@Áè &”\p"äîð>\ýW€\ꛟ¶¤$ã¾j&ÈæRê_ ê·Pý2­@Wú˜·ÎÞ ÚÕõ<æëë!…t@Ȥ" ”°ˆêõR`nâî/.ÉÙ¼ÏX®û?¼×m~€.§7ÝC ÊyÇz3õ^ñZ8(‘&œ hÙ öHŽJ UÙg¹–K] â×¹Ë@ǽ]Ñ Kvï³µz’´Г¥/©²@º|mLÒ)2*{Ü^Î{€ÒŸÈµ >ÕÒ<ú ååžf—-é ú#ýŒ»ÄG%š`$sâÿú*¤ º„÷éznɸÜÍ Ÿˆ¾Qø.HšóŽØ©5”$§¢$‘Léhr¥ P¬è„Ó8KF€L í®´ ÔwÕö÷ܪZŸ¯X|[®t™Ü~ûôêœÇWúÁë±§ñ×@÷*.·ëNЇôv×2Uc«-’ïÌ,@IºqˆO"ª!è/è®úÝ4¾+ZÞ/)cÊ]Áƒ•–·:•óù9òsägNX1+fÅ@µT-UKßä7ù3”ó&äÏ;€d^€rŒÆc˜o˜o˜o€u‡u‡uÏ,žY<RÏI='õ 5¨qŠâgRz•)ß[Ë´ßÑwvtÙ9|·øvÅûT0s}qÐïo%è·Ó7Õì Æ%™ÕNæþkÌ3ˆ´ô7Ï(Õ÷y&ðx|ZÁÀ“€ÙÈ”ŽÆ1K®U>ÀòoM- º@Ú© ÷9³"߃\l¶ ä,1êúW&3ü>>ñÓ @.6é "ê'õ0xÿ9üÛ¯¿€Û©úžîƒqmj’(èÿ&nÆñg7¬IOý ZÕ¿wXwПÅ~:žlÏËZç:VÞµô~OÇ©²ÆÈ„ÊÉŒ2tÇØ{E³@Dæžnç}…wXÆa«&蘨ù@‰®ìƒTQ]¬"`iF¥ÚE õÊÒBƒ,ó×K_ºN~xëð*l¾vÒÐFñ¤]£A¾/S³ÕL”Š£»¤¢Z›£‹/$±à¨d}ÁŠ”v’F€º Ÿqž‹÷†è”x={ø>¯îø*˜÷§xeÏT>ždö)ÙS²§dXë¬uÖ:0ß1ß1ßµP-T wy÷´LÁ?ÈÙ‘íÇ1Žq ö«ýj?˜“ÌIæ$ð—øKü%y0ò`äAˆWŒWŒŸ©\4{%å­U»=ö#˜ù8ûí‘Ñ·<ý…Ûô<Ñ=€A3ûã]ÿÿ`⟔'͆#@Ù”Y7ŸèåÄA,‚'©´l«0p5舷,޲ô\íºËÁ›j?Z’ z-]ôÍ ©'½Þ4H ØržŒy×™ ªIî®ßvB¤ÑÖÁ_n×?xÿºpâ!ׯÿSԜΛҧ¬ºlÛðÎ+àíÚ¸}âƒÀEù5¶Üêžò?ušªr]÷:Ä+Ý·Ù¹ eÔhcP¬ëz›HD uè¡D˜È™}tÄ[l¿Ù2p訿\µÝ~P Ôãˆ'øÅ‚²EL†Ê& È›àLµÊ\:bÕ ~ hÒ(xsô*»kÉ oð²ß Pûd‘Ï&‚T èµÞ³n𦔼zÔ=Û[î,,úÊK #îö ‹âÕÂ7‚TV»Ía J•No<Tõz®šꦊƒÎ}hP0m» Þ¶-÷~ô>x÷î^úuЗ¬ÝÛ ÉNÕx!òÕ‘@.5;¥Ø ŒýÀãð™ÊtOŠIYƒÞ¥ßu[€³Ç}ìiFͬŸ!åÃe/|’ŽÎ?‰ý¾ý¾ý>IJbY±,ð½ê{Õ÷*FQr­\+×íhG»³7ãì À‰°àp.ÃÁÈ2²Œ,ð-ò-ò-I•TI…âêÅÕ‹«Ÿý~¯LãºÙ`NÏîÑþ D‡ÅÆ;ÓÀ›í”‹m¦éÜÁ +R,Í€’3’‰ÿ÷RÂn~}«n¨öq,yVÜÉŸêaì­}·ƒ ’N-‡ ȧK€úÎgÑÅ Å)ŠœG"æ gTQ”¢&è:æ…@Ï(YóXÊmö[ànµ>k%6MýâeÐÜ_íêÿôeÀ[û¥pD«¬{îÍŠ Ͻ÷ç* .T}Ì"ÐSããòwƒ÷õÁ×çmoËúØ+ëÁ[¤ÕÒM Ú•ëÜ®-¨ u¶ydofZýq€ÁVžgÛ׃ÖNÍÈn@³Q'œq'VЍ Ú•<§5ˆO=äö‡Ú$uŠ‹å€Ô”~@œbÞ,ßPpå6•pga3`QŽf ?Õ_º5A¥¸ èÝܯwƒ(‚IòÕ?˜´‘›A«èù~ Aì@ÑÝ@6Üë¨ûH9õ©±TVÖÞ @Õ¯»ûªž õËoQ¼%G6¬Œ€·mKÓ·üh§UåA¯²'ôÒ½ÚÅó—ò0`q»dŸÇ'äçÊë—Àá[ÝýŒChIg¶¾ôLçœX£ä¼ø̙ٗµÏqé`ݼ³ÛAñcÅ?j…Z¡V€UêaÕ5BP#@öË~I”+ÿ‘äö49ûü¡–ÃrŒGGGÁiŽ4G‚¿»¿»¿;5)jRÔÜ îwÃôì‘cÆ8H¹ªŽqI_ˆÕ’!©ÕÁ±ÝO½r ª•ÝÓú07ëÕfß‚žîfØóùŸ‰nàôŸú×â‡Ì®Çå@s5“Ë7+ô-àÈr#ÑûNcïUøÈ}ˆh úÓø×Å€ž¢oq_ñ$„H¤Ê¤‡< TŠŽ-˜Úfåïuž<¤¾€à\¶„ß·õo·¾^…wZAìæÜ7¶­wD´UAmðºÄʼΡ"ïÐùýuÏÞ…= ÒqÙ5O¿ê™Ýïö ½Ô`¯ èÊKoÀäjÙ dJ£è]î”Ès ½£/,k^Ζwß©z[n÷oƒSéú >UP+ïªK@žöy™‹|oz¼%àq$™)wãN$Qž{ Õ·ñ§@2C/ÉH€R†b½põ;º-°×xÎì5|Öc€¦½×$•mzˆ…ªË… ÓÜžÑ@Eg`´< ÆI°Øzqk†‚žâ¬‹í=½dçÑAïð®q^ É\õ>Èñ2ëš< ªb=Ü©U~qëŠà}¹÷®ù#Á;°uÅÇ/ƒvoÙx è^9ç ”ìQkAÎàÂ"Àñ^‹¿@9(êȵ 78S¢Ï‹ìíE`„9$õïj'‘qW: šØÁ˜”§èÃÞb§8ÅÎuö"ˆ5’Cé@Ê%uòû´¶Énã U¸^ª—ê¥BI´$Z†?ßæ÷æ÷æ÷ öª½j/0†1Œùûùñ÷äVÉÜaÙ'ûd˜óÍùæ|ðgù³üYàŽqǸc ø¹â犟;»šÀeå¿nÒÌ«=Ù{ Ä?«ÚóªW@RJÕlºt=ó¾| âOæ®\ûß-î’Üö›î¶æÿgÇ· Ã业hóYŸ:jÝHÀ‡Jfâé¤gä÷«©N/Ðwyk‹A/²Í’ ’™ì @|4æÐ_¹صÀ›ZòÉѦ ·êŸ½Ï@CQÔF5W½¡Œ:v-ð—?øÑÜàìÓ/»âÕŠ\&K'‰¾û{»½$ zC¹ðy³â_‚Îw/Š\^Nî'¿5oû–{¦|ÜWòö¾i ŽÕùôšÖ n¨ìëÞ ¤¼ÚnM¢\î LÚL*‰”îÆ@*¯z@ÿ" beÀ[¦0¼ÆæiŸ‚çúnÉø ¼ŸËku!è¬] —‚ÞÜPñnð"ª®ÿ;ÐãõoÞÏ€Éd]ô.}¯ÞÞ{ö‹ÅA­gz½’ nGÐ1–ñèÙá¹ÍAß_Þ 23ã—õAYVi jxÕ—Ï¿¼_¾³T·ý˜·‚6L^Ut¡óVt .Õ£€¢?â-Œ¼ :êÎ,þ€ 4Löï‰Õt P¯sË‚~'zqî wÞ*]°xä@8ÊAÒ© ’AGïrЯ9 c!º.ö›[Œn6ž[W–÷7ý#\û)R¼¤xIñÐ3ô =ü÷ùïó߆eX†'~NÂýÿ˜{G’DPÕQuT0J¥Òà»ÀwïðÿäÿÉÿl.Ø\°Ò&¥MJ›j¸®NÁ’“:ê¸5 Rk¼|p%(X¼2ør]°žÙ[铇Á\&Ÿxéݳmܧ«À:7S×HµÓ_ùïêéÖïE·ÿ ì”Í/¿÷1˜íÜEKÓ(´¦øžOY¸’•$}ádNú_Å5ÇôFЛœr‘A®2óƒY@À˜å+½9rôxзإÃõ-%ákx‹‹A'ÑŒÄÏ—Ò¬ÛBõ3¾ÿ¼”çSîw[ñØ-¯ƒ+c¼7AÞò×K­ò†:Kд_É]"™ò! Rð/ÿ¦3؉ô· >gFt$hÏçK€Þèî‹>:¶gÐ7‚Œ=z÷²KAÍ­>¨ï+ VæÈú?€÷È®Çf”ýDøƒ-‹·dŽë߼͠±_» §/Ý_¼ÎG6®ˆƒŽ~aég âå—®÷ Ûý‚s4üˆÏ7;mÐ;Öªèsн¼>Þ>P ëÞ~ÙO Ò'×hºÙáO–ƒÞväõ@—8"Õ€<ÉVÝ‘wÅQñ_"·€ö‚?ZÓM/F‚(gLA?Ðqzykäã“N¼Ó2Iõ7Ì^ŒŽ8Úx?¿xÛTÐïï»gÁ} ?mÈ_ ¤Š§:ж$2éNDâ„E+¹$x;­% j§Ýt8þFîTÀc½¾HÛÿYеå= r Tݦ«Aµ©Ð­Óppó7^7q-HÐhæŸd˜­BëÀýܾ5r9- ?é,.«QþÊó ô›mÓî\ Œ—úê Ž¿")’"¼õyëóÖCfß̾™}!˜Ì æù–ù–ùÖ);€³xþÑ”ÿñpÂÖ’w;yNž“ÑEÑEÑEPx°ð`áApžwžwž‡Ês*Ï©<ŒF £ÆŸõØ5 fíkÇú-¼ïáöºÙ]xø5´ ôò-øÑ¡áu?¼£Ú•`Mi|×ÍCÁlX6 Ôò‚Þ.{vI¸ãŽ•Ùô)xCŒŸÓ¬#áÏvW£ƒ1IMÉd¿$R\³ÍΠ#l‘„wYÄü7âQB1HM™#+UP pmwaòŽø_ü¾ÀÛíÞªr¹Q-_vfeÔk^ÊÖœi­|­æ¤©%t„ëâG?­NÿÙ<ÄgmÕvŸ‚\©²F“H{Ñ §yOÚ/ xlÔ€¨nëòUFAÝà]ReüÅ[¼¬Ý`}—}Y»7€‡Õ«VÎÑg³³c19÷Š5Ñ7ê€l+¾p êîúât`š÷±ûx×ï½aÖù ²ç*ÀâYXr›$}Ü¿ôA}$ ¦© %µœª Ãz•›ÀŸ(•ÌG8óBå6ï C?UjN}ßoÓ¦ogiz…› zžÑ+Ø¢ƒ¢Çö@qãæìï¡ô÷ÿóäZ°6dÔ­òìÌ,ËËò²ààóŸ?ø<ø–ø–ø–@Úò´åiËÁ7Õ7Õ7Œ Æcp×ý›<“°FüÁ†É"YÆ4cš1 ,miKCpApApä'ÈN)ø©à§‚Ÿ TR5Ja°vft¯²B7ÖßvuÂ#6ØìÿýÁ×€ÿzsGAK°Þ7n÷…À}:úâáͯ¼î²×3ãîâøK éŒv¿sžn¯+Û¨ ]AuöGÊ´Ë@.â2-Z 0íiáÅ€ŠŽ±Ç›ub ­ÕŠBi z¿¼â´<ë>ÝÄð}ýh[#AÇ‚3üÞÓËÜ&ÀðÔ2Þ>vkEàZ_ßÐ ]Æ«¶@œ­‘W@,Ê¥ÍÑçZ -S¯ú' MÊ „4Ê ?§(\ =úN¡:Ìv=P´a HM|÷ÚâËsk€ÎŠÍ GÀ¿»fø’¡ÀÃÔJ$cÿoEJûu©O7‰Þ4¼C9£ë zØ–ß Ú̵c$è’ï« „ü3ҩɉªÄM»32E ¯c ¶ñÆu€Òw ¡s2¿Å>£Ž§h,e„/È0M9Ôôo®ð$0M?èVÝÑú!ý9OŒ–*¸ B+ê?{uÙäÄñìM,lRؤ° xý½þ^|ø,ð˜[Í­æVPkÕZµÄ ýû~þ× çqçꢺ¨.`Ì€_3_3_3î î î„ü¼ü¼üeù¦¤Þ²[½­ž>eªù¦¤ŽÏõ†ä}”ÓôDp‡y}hjpÅÏ;lµ'øqé¿æ ø"F‹r;ÏÉïÚ¬Ò;€^rüÛÕ£AZ»Ý‹Ú˜Ó27${ÃHöÆÙ¼éi€Ý>Ñgñ™ mй€ƒ‘̈¬0˜iœ¸ä&áÒå4 E”fÀ!½Íþ(­û;uA&G”yb%%×ç¥A4¨êg,€ŒÍ Ê_rT)kPÐw†¶½ÄK¼yÁ¼`^TÕFµÀŒÀŒÀ 0³Íl3ÔuD2ÿ}¿þ÷ @’bHT#ÕH0¦ÓéàÛáÛáÛ¡¡¡P4·hnÑ\(Î-Î-Î…TRϘé㯑9­ê…lSóÍnoBIøø»;ö‚ñvÉg¹À¸6¾§`  dŽlmsMI jø‚K%%·ÙmA;Lu’æ%Â8>ö‚Žš+TŸ™k^:jOp€¦îY€"*¦ñº‚Ž©õö€{J4.Ý@Ûz¯ó-}Zú4°:Y¬N`ü`ü`üÒZZKkÀÂú××SäïóþNf0ƒ`Œ2F£ÀúÙúÙú+++ÀßÓßÓßr'äNÈÎJg¥³òìêR3«ïð5¨6åÚ´ž %ë¯[x7XÿI}$Cž‘f€P”tÞ8™Å¨â£Vw€[âðfò¾Ä©„õVªžïCsˆ©6I‚dqGNÓÅ °į~µs—Áž™ÔW-yb!*%W‚¶½ª%€Xî…á„/  CM‡ A²Õ»¦ØéÖ '˜|ê9ƒ’újþáýj.Ù^> ä–x‚FÝä+àw2Q;y÷N~¥–‚\îû*ÅR†+øДPôûUÊp_\雞 Õ¼×}Ã3€*šSö¯R[ÿ‰§‡j}•\c-üúcÛ”cÔó“F:éµ?Ñ6•@üØÞ@ÀÀŽ_@Â72ñ4ûH\5šsÔ°øf“Ú^dÏV=E¯PL.H iÞåÎKöyP²/ÞBÅ@õ+ÿqëÏ Õ«º²Ý¢³¿—›éfº™p^:[îÆÞ cž?ö`¸Ï%QJؤÊ/* X2Š€Cz¡„2ôæ¯DS pHÓaÀãžøxÀ¤‚¶Yò•¡}߃T´ŠBw‘pF†“¿÷΢×Kþ©l•„ÞÒ_½ú-½Þû?³–ÿ^^öÒœ·Ao`¸þP”&½Á}ðœÓK½!¤00À­ : öñäpÊžmH²?tŒ«í÷@ütu `Ð ô6il6†Ø"Îî…È+ñ—1¨ææóúƒ±?øZÖ®³¿NÑÔ¢©ES¡¤]I»’v²€?Jò,r|PíSûÔ>ðµòµòµ÷+÷+÷+°÷Ûûíý[?·~n}ðçøsü9‚3À ûÓ3祥 ©Ï4xµÿ{PüÀº'?œ òÛc{À–«KúªÀ-±Ö€Gçd=·w’:ï/[~Œ<À•¦ò |Ì‘€]ÿÄ/8?‚ŽÈ7ñÅp“@šýÿ _4ûô‡€ç´+¼°Tóà ƒgüY@€^ XwÖÏÂê$–aÖiDg’„£§ÓÄìP•òþ‡@ùj¥H‰tS瀶Y›@,â¯3ÃfÈRµÇª­»Ò{t{|ɇÀLߌÿmµÖ¿ïõpÉá çyìJ€+If¢A;îG‘[@,§fÑý€c†3.Lüñá #hýRRYÓøÐ4À£”þÈ”WbóÀ;Ä‹) >Œ)·!œ-fÖZHYåŶÇÁWèêv•±1±1±1pl± Ç&@¨c¨c¨#R©Ôßöê3õ™úŒ“8ÿkùß-'¤ hêIõ¤zòw§…¿·¿·¿7¸¿º¿º¿‚s¯s¯s/xdà‘P9¯r^å<0~2~2~ú³Úоò?4Þ^÷øãý:BÉò½>9 ¼á ßþTã#ýHоH€S€wFý÷܄:fN3ßI³ú¹÷®wEt4àÉKIÚðXÒ§ðEç'w4ˆÏmZTè¤=ÿAÀÖÏë ­“ðåz›® À¶…塨:LÃX*¨FÖ´ýÀvs¹ÿS ‹*I((ï,  §Kœ8ä!¦É>PÕ½s¢.8¯M?4 R(ÿÍÿØfþ‰¼GUݼÇÃ뀱™ž:‘Òû³J»Fño™¸î½ÅWiÆy>t:¯.}URgðs¿¹ßÜA_ÐôuÜ:nã9ã9ã9crLŽYdýëįòzÿ6ð‹‹‹ d’I&888@üÁøƒñ! ‡Â!((_P¾ <Í 4¡B¨B¨BäCùP><ƒÞ×é¦WBÑâ¥>áâ5ö¤ášâoé|þeæFý:Èýœ·t!Ç9Fb!øko©"ûy $èÔ+¨:®žÖKG´JÀX°û_öE†œæ –{«œ£ŸÌU®Á…7*ðÒ¶LüÀ=%ÚÿxCÀb¨úGÚ²ˆ«Õ ú¤9-_–~°’@GÿÓTg@êK© öoö=ö¹{0u|RßoqßMÙ@ŽzÔ|éf-+^•â”}-!þõ²õc&Y&¾ãH- ’LVwrêò–AuÀÐu=$`?j?:ì3j:QÎLâÿH– ²È]^¦¨!ÖÚ­­€âBctÙ…ªÞ¼ÔWCZ³ñóÖ#X(gHU×wé»ô]p$ëHÖ‘,ˆ555…ŒÛ3nϸýw§¹¯Ÿ¯Ÿ¯¨¡j¨ e(Cÿßõëÿ~pBNÔ!oe+[ÁoŒ7ƃÕÇêcõÀÖÀÖÀVp¯r¯r¯‚Âù…ó çCÎÀœ9¡ÜrCÊ ¦2•©§è½…ÙÒÒVÕxæ¼Z ž,|Š>Ø2çÓo²ÒÒû | n *­ÞjÐÅa‰/æ™U¦SÑ >ï»hh×Ý]ôˆ):p/è˜qg¨! ‰œ<xüI¥"`r•þ´¶¯+>¤wzß.­¼R@eU@{CõçòÀŸøâO‡„¡€¹M~ô¤Å«oꔌ Ó™&>×s=×ñ Ç*«‘ББŠN:éü^Ôc]f]f]ÊR–²ø>ñOÈÿ»à„œˆô–ÞÒŒ²FY£,øžð=á{<¿ç÷üà•òJy¥ Kþ–ü-`.6›‹¡Ô²RËJ-ã$éáI™,÷«— ý¦ú9½»¹æµRP4mSïiAŠ¡tÀXk’ñ$(¿^ç>:Îv¾\Œ¤?HuÀä%o`8ÕóŽ>Ç9p–‘ ~ã2ßQÐQùÅL$˜à„Wül*AEU– gQ´èbo‹= ÈUÛòt°WTÈjxRO'hŸß’¡¡6é™ c·µp­ûƒCAçéÆÞ.ð ì·K²@ÅŒc¾: ïÉÐ.Å8ûp‰A6Í@oõ>p—õÂrüà_î\üVˆ¾·÷ÆŸžãp¹'›-3Ûw}ðþ÷²#ä|½àj ía³†ú^½+•@áÖ.)É„ŸJt èvNðœ"Õ‡¸×•jߘîõêMÀá Iùøˆ&E >2¼gä)#¢q§´…’¯½õ); tq‹w‡Cz£º…¥¥“*u†ö/cË /;/;/ Ë–),iii87pnà\°LË´LPãÕx5¨G½ä‚öÿ‹üï¢''Rˆgª™j&˜yfž™þOýŸú?…P~(?”)µRj¥Ô‚ÜN¹r;AþÕùWç_ çøÉŒ·SåMyQÍ‚ô9uÞïö¤nm6ü†K änodº‘Éñ . îFþ¿öÎ;<«*kû¿}ÊÓRH¡BUšCKEDDQ^Š£ðÚ+¨8£3RÞTAGEQäPF -´¡CBž”§œ¶¾?ˆeÆq|gF×ûŸsåºr}ž}ö^gíµîu¯¸žĸœW@ùÏRtS¹”rŠU 1÷בh¥¦ƒØrÐÍ<Ç‹.ïHe?w½ŠÑtÆøæ5,@“)îN˜“Í„òpZ¶º²Ñçë7ù><ÙÈ‹ßyßrNJMSàø…Š@,5R Ià<à|gQì Ï)Œ^FeSÓößyßÊ«OµW#@œØË%Ÿ±ËçÀ|­~Ëì:È«i7~*nÞ8éùS`O+Yš_)?þÏÁí2Ì] ñ’Ãç¯xœ+w5xi!õät¤;¨ŒTû©ró¾ò‹äÀqâÑ… –ìw+]]õ‰«R§;(M›äVËX4åÇ¢¨àjÞw›m̆è‹Ö<êBÅD¦¤n‚Ä#í»Ý‡ä¹-îîù>ð'ÕXûkGÊB )„ðýáûÃ÷Ãé÷N¿wú=Hè•Ð+¡kkkožožoè)zŠž*U¥ªTþ6Sî_„] àjÉáŽpG€½ÙÞlo†XA¬ VåÍÊ›•7ƒÈË‘—#/Cíaµ‡Õ)ÝSº§tç¬gñ-f ÚùÄÄ­«!üâoN#ðií8¶B⯧¿z;µß} Tïö[@™5ëD ÄöºÆï CUnô€¦F«º |æ¾äý 1ý„¯2¸vð,£®òË\Ùæ[ã(ÛA™ö®òŽ q§Qté´\ÖËpГÏkþ_×€·ïIJMÅ I…v ê€^)°¢}ƒÒºM–€ò›ÏVØŽÉ€ÇxU|ŠPDÙχ ¦k;Ak|¢æª¦ë·‚X㓪;žQØ2ÇýÒÚ^nñŸ÷µ Ö»\꺌ÄËW±û7oÌ«Kø¾Ã7C|Gò’ó>ß[Œëÿ4¤þñKîmÿÙË€6\Á­ß±n—qn8Ãcó_»<2¢è>`íÞñ¯ü7˜«¢ùû5P–ÖÄpAŠ)äXõsè ÊïÖ²ž±íf¥ O^ÊêÄéÙ Êǯµw$·UðNwY¯M÷SùPÿD\k˜\ñ+‚  Æ˜öÓFG!¸¸~“¬uÀ9œÿ5O´zÝæ0„W„W„W@Q“¢&EM ¡(¡(¡’’’ÀŸèOô'‚ÑÎhg´«–ô¢#ùºÿ[üxÀ©"ÚTQŠÝ‹Ý‹Ý‹ÁþÈþÈþ¢ë¢ë¢ë ¢ME›Š6Ñ#zD‡ôµékÓ×BêþÔý©û븎ëþö0Ö]%ûí…c˪¹ @Ë/Ù¼ý0$øü3´L0 ¼™§Úf_S|;H9Œ³t•û|* ]á›xþ‹“‡ƒX¬Ñþ€RÐ^ BÞ${ˆe ¿8r‡T–epí@³iC.ú—>w`xÛŽmÎ|ì÷U¶éNf'ìåÓ®Ñ.´`JÁ 1=l–ÈN>úÚóVrámN± ´1¾E‰ýAýÉ7:ù •!ÏÊ¡c|rGiÚQ x;qi£] ԟѱ1x w_õç™ ÷•8ÖTŠÚ¤û zS7 ~³ïã”àz¡/Ný•š¯¶Úú”û‚vÈ÷«„KAM M«s¸Oþéó·Àë[¸ns!|êíÍËÁ·1õ/Íã`¼[{í…ýA®;0g¾’§¦è• Ð *7vç‚òÑÙ»Ð⟕Ήy[pn•ì7UR\.Å iEgÖ²)ð'°ë8¬VÜ'xÍk³–@Šuqï­À÷§ÔüÌšß±Ž³˜ÅPÒ²¤eIK85çÔœSs ᙄgž„¬„¬„,ðgú3ý™`ô1ú}@SšÒ0ˆA ú·ï¾³ø×ÇþöÈ•‚Ug%½¶^[¯ œÃ9œ²WöÊ^`3˜ÁÙöå%%%àÍöf{³¡æÄškNä¬`É7á{)¥É¹Í æŒKî© á ;§.Z¥ >½t„î‘Ýçÿrý:#´Ã¤»GA5g‰„AÊq Pù•ì—"»5(Ÿ;<ÞÀø$XÙv<Žht“÷Çu#‡^'õ…:ÓH‡¥rð¾ö7^¬Ñ°õa– ¼‰f&àñªº»êþIæ¾ÀŸ@,}•YIð©}T뾋¨,Š9…Ùå´Ž$‚ºÙH ´µD?àË„æª#H'ëžÒ…I5ZꦌW$€×dOÛ7ꀌ¨ØvìrÀÔÞ×ÚƒD+Å?õsä¶€à]*#Ö¼¸=éàcà¶;zGþð:I%N¶}u±úªfnIµû¸¶²ÌK‹së>I¿Áªn _ì56ã©ìÅ %öm8 ˆUô˪±Æ„ÊW[iÀœÛâ@,Y`w˜VÓÜÞ…záŃR@ÈOù®ßžö´‡â!ÅCЇÀéN¿púH8˜p0á „ö†ö†ö‚¿µ¿µ¿5ÎFgЊµb­ø5¿þë=~þ½øñ<€o¢JH@\qů×ÎkÖ2k™µ âãã¡"©"©" Ê'”O(Ÿ)ñ”xJj?Tû¡Ú*U¥ªôo#ÞÇn]¨¸ ¿øãP~ëö‘/} ¾:ñÔ÷@hªï-õ Úp·)¨\™ã-¡²¨æ58Ų0T'£!(Íg2K½¥¿Êï¶Š ±¬e¿„=ÌÀøµ·D>wƒvq1o%•d®¯IÞþyuA¥ÉÁHÜ+3Ïeê3Œ‹@¼à5ž\õ¼^IL:Æö¿÷– rå5P~C®­8ðeê^ Ì{Î=‚~$©¨iu‡e·¯ÝÞoné_:4ÿr Qyz€Ê(ùWp˜/@µµz ¨ìQã E܈“Þìÿ÷ÉPo7êÚï(çÞòÈáK>QÕÎèrRºMAkVûWÙy Üšu³òÀ‹ï_òz_2ýj;P¦ qñâ³ÃÀ•ç8¨i*0iÁ­ -ÔmÚµà”{3õ=¹×ê+wUáOhpßjõÆ/@Âê̺$‚JÔþh<ôë'S2%Š¢EÑ¢(”&–&–&B†„  ¡kBׄ®àßãßã߯ c1´ºZ]­.0™ÉLæ'ƒÏø&ªøgˆZž–§å¯³¯³¯3g»óñ¨íj»Úááá`µÇÚc¡î亓ëNc‚1¡êKñ5¨­‹~÷4¦àÛ–Ö½Ùj(µ½áœã¾ÿ؇«€Ðï 3Þü´! á:÷bP5yó€rùg ;§# üÆe¡Î€8áÈL@˜#•UiuÕƒUƒÕÌš\ÌV—â]Úõ5—¶ûÔQí:=@*ìKA%ÈãuÀôE®\m§Q@V¹ü ¿×üi§uÝ!ñÏ@vÛ‹¢ÿ ê‹PqFPùé.ž Þ yXi_º8? $ªÕz¥Ð†w¶Þü›uç@¢^Ä] *hIô- ÐŸ*¯®³'\ RDcÊšïŸ Zÿôy—,¯Dݯמ¬\µM{$­Øûr6¨–u_ìø_ÀA«îË€Û\Ð0ÜhìKPºüÁÉ’ÈR-@þLoõð¦°\oñ¶¢";ûv‚þFFbç¦6­õç·å‚ѓ€âß5}ÎÇÎÇÎÇPо }A{ˆŽŠŽŠŽ‚¤QI£’FAp]p]pÝW\ýF£ÇWÒzOñOýÛvÓ÷ÆOÇø&"Dˆp–ûìÞåÞåÞö`{°=âvÜŽÛ]]]e×—]_v=èez™^õŽÖ;Zï(‡‡‡üýád¼{S|Tä,_s%”ÿyWÛ7çƒñëH‡C@p¯­Ú ¾Qzª< jº÷PýÕ›ª­¿à;2Ïy2V;ð8ã‰üµ4¡ÍL±@ ¬®µ´Â&o ÜޑݯϚ²Éi¹T óÍ@Tu ¼b3Z} @œ’hF+=Ór®WJ%jõ?­¼é¼þ-ÀK'Îâü&ÚÐcTLpjx•Á­¶ß“®ã⌓õ úùö%}š:粫qNþem1ÈÒòýšÁàÖ”Jf²ù{Ý¿šHUÙ“07ú2`8cJ¯e˜›Òo±xMOÈ3ª=áýY-%m]ˆ†Ûì›$ªÍÚi ÄJÙ,M>² ´ÍM:\ú ¨M)šN~$¡ð1°G[£¬ˆî³\7öƒúkiYà¸EÓNË!eCýªµ`,Ý›ö=úMH‰”H „§…§…§Á©ŒS§2ÀL3ÓÌ4Hžš<5y*òy<ðíõíõí½¿Þ_ïÚ~m¿¶ŸŸüÆ?ƒà‡âŒ!XËZÖ‚>QŸ¨Os­¹Ö\ þgüÏøŸPv(;” 5ž®ñt§!08080NÞ|òæ“7ñnǺëöóöóöóXcHèÖ´HµÚ|Ô?iñW+Šëu?¥ç¹M“ò¡|¿S7p)XªY` x Íþ‰Ÿƒ<Ì õ2¨D~ÅpPiø‰òáQhÔæ"=ÞÖ€,°:”^ ê©Àô€Æþø[µsÏð4;º*¨*-¡ à[ ÿjoN\>’Û@ej¿÷ù@[ß´Eß~åWï9ÞÚ£ã—5UC íÊEc*Yð•W¾óZżã¯0>wû–nZÙ…€F í@NxÃ,Áï­ j]rŸF;5rGÕ<ÅAÕdºêÒ >>ÜÜa±Ú% ¬PÂÖ¦£¡|»=ÝçBi·qÒ ¨~´{Ò*:twR·ùC¿Áèêö}6¾½ÁÞ`o€ã[Žo9¾ŠfÍ*šÁŠ`E°’#É‘ä„ú„ú„ú€ÿÿ#þGÀ8j5Ž‚¶EÛ¢mnåÖïL{þÄðÓ=ü=Teä^¹WîgŸ³ÏÙv©]j—B¼V¼V¼ÄÄÄ@ù3åÏ”?ê÷ê÷ê÷Þ!½CzH“<&y ¨ Õ…êÂï1îÙìAüùð“GCä¾£›F€­ž¿m+…öÿ;u>˜Ï;‹Ã`&j'½í ªõ—ëAP2T7ù\Î)‘7Úõ–u¸ èmÞjÞÕ‡·¿³ð«æj ³‰tPþبý;§2Ö´*÷u§ØÇe#h¯e^Õ; ÌL<$=¯÷+Q¯…s¨D}R’€Ä}³ÒÛ=ª<%‹ß9#ç0TÈ[ö HÜšY8 pX.Å üª•YÐ|o×Û R¡Þ4z‚ú$q}þ =^ÿž+ë‚ûòÞ´ùÍ@z3½Öà^*9*ì2o¸zì·S¬¶ãÁ¹¡Æµ­?óï‘Åšr΀ö—ƒÿó:0EeýUfÞ7§g‡ìPÖ­¬[Y7(º±èÆ¢QŒb$ÞxwâÝ ¾®¾®¾®`ö7û›ý¿¢É—¦ÒTÐŒf4û±7Å?ŽŸ¯8ƒ*mÂ3iCo¬7Ö vŽc瀷âVâ÷Åï‹ß‘‘‘ý]ôwÑßAÂÉ„“ '!ý®ô»Òï‚@@@ ô¿º±¾‰Ùô’ÏÀ®]QTôDï;qlë!ˆdý'õ@. Ÿ·çQðÍ$l½¾¦æSšÆ%zT5­%ÙÞ }šÔáÜi }–Ñõ’{Á;–·öh Htï! FK.ð6ÉÀ‹¬¿÷šÉdÕ°Š¥Ð2ñ¹KA»°ÎæKË@µÉèzQx§wͲÌúM¸ð©ûµJ%Aê:P>_NíwAbzZ»äóÛ3«¥êZ¹Zjr5(ÓÛáüЬy' Í»>þ*TÔ€WþXúoRꃼjέ• ÒJß T4þíM©`yù±€uuéÉãe`æÅÀÌmþüP!p;‹T£ïñžNp‚ooo……………… ÁµÁµÁµ²BVÈŠ?ÅŸæPs¨9Œ———A34C3€¬`gƒ×?Wüü ÀœÑ#ïBº€ô‚^œ—œ—œ—ÀŽØ;ÖXk¬5b›c›c›¡b@Å€Šà^ë^ë^ )-RZ¤´€šÙ5³kfƒQj”¥ÿÀsT‰LxØ÷FN@좢&{o‡(ÇÒ>; ö¹E}vlU/Þ¹ð÷`®Wûí•à›ìßë| šê;˜qxÃÛ‡@Å⯟Z j™!…À-ø¹ÔùV…½P±¿ØylÂÒÔ³7’G5\ÚîfçßÔ¼úûB¯2¨|ôƒ Bj³Þ 8“ÖS–i@P«8ˆ¯KÝ…€¨ƒzÀ ÂgT†kSÉw žscñ• ;ì]%7Ô¯´z ½ª+A^–™ª!¸$Y{OKHÿìw½õþ·Á_wa§wÀ{P)Ÿ Æ1õ”ׂfýuí/‚À—µö4´'ͧƒÿpÃ'ËÉr² xVñ¬âYÎ g†3Á¸Ç¸Ç¸BSCSCS!°3°3°|†Ïð`Ž5ÇšcAÏÓóôîü#C_©_Ø/ç­°Ã:h Žë‰@Mt9ø•ç;EŒ:ÀiÎQ€½Æi ÀBó‚”›@^æ$=@n”j+H©÷ëøëw‡÷±ÜN¦w?ÇÁm/Ž!àæèÓ“€ªta³D0¤û/jGêý&+üzZ&¥ _kŽ÷5“«&þãÓììwö;û!üÛðoÿ…’=%{Jö€Œ—ñ2BBB ð`àÁÀƒà¿Áƒÿ0]Ó5]Ð'é“ôI 5Òi¾Â+9ó8ïÇ^Üÿ|üç€oâG8ÂÙ>é^k¯µ×ܸwã`ϱçØsÀh´B¼k¼k¼+D»G»G»Cì‰Ø±'@{H{H{RÂ)á”0¤|šòiʧ`Ž6G›£ùáRM‡ÙÅzðpºGçƒó58V¬ŒpíƒCÁªU°âóóÀiS;´¤K´ àsव%ÜT«°¢ÔòøºØ60iôzÏ7@[ÉL»$çHxQOP>Uß{Ô«jŒºÔºP)wíá¼ÈjÖ‚Ü.ÏÊ&G 4¢ 4‹joïZú'w®”’ÒÃy­´dõå ¯cj]P«B-ê½Æ—5^È4Á÷ZÚìæ5Áw*e{“kÀ˜’”Vï Ð,c}p Ѐ–tþóv€{½Î^á}á}á}vÃnØïJïJïJ. . .…àôàôàtðÝá»Ãw˜Ùf¶™]-¶©?¯?¯?j¬«Æ˜À~°ÞþÏÿùà Δ¼Ã;¼rXËaðy‡¼Cà®w׻뫳ö8{œ=âÆ? ±ÜXn,b'b'b'@-UKÕRHj›Ô6©-¤lMÙš²333A]¦.S—ýž»‚1ÓÞg xóí;+v»/Ö­äRp&Gž;•îîXç²…à¥v×Ù n“_þE@ÚÅ®9>$É™»dšôwv¿ñ2J@PÀ8-ßÈu¯zÓh ªÌx#x9¨º ZÓÀÄôf 虼 ôîþ‰‰=À¸?ôDÍ@o–6´¾Pb¨dívã) À·ô~d£l”›››áÜpn8Ê—-.[ ìe/{!Ø.Ø.ØŒ@ø®ð]á»Ì&f³ A#hAߤoÒ7¶B[¡­6²‘@sšÿ ÙÿHüß1ßD)¥”™ÈD%²D–€»ÑÝènw“»ÉÝÎ{Î{Î{`²Ù‡ÀªgÕ³êA|^|^|ÄܘsÁàp@`n`n`.$·OnŸÜ‡'O¾_Ž/‡o œü«±‡l>`"«d„— |ʲºêp /«N@g5C;èÅãlZpþ÷ÖÎûg ªJÔi´FB¹”K¹@ÙȲ‘e#!.q‰ èIz’žZZZàïáïáï¾ù¾ù¾ù`î6w›»Á8iœ4N‚¶MÛ¦míˆvD;ÊQŽr€žô¤'ÿ1gúÿw À7qæ¨PE4’¥²T–‚›ïæ»ùàF܈·©ÛÔmZÍH´·ÛÛíí`í³öYû öNìØ;`¥X)V ¨ijššaaaÔ1©cRG  ÿ ÿ ÿ PëÔ:µîÇž„¤£t”Ž`m¶6[›¡âÁŠ+„ò¬ò¬ò,ˆµŒµŒµrÉ%|5}5}5!Ð/Ð/Ð|¦Ïô™`j¦fj`ÜnÜnÜÆcŠ1´eÚ2mh_j_j_‚RJ) e(CÀ?Ç3ù¹ãð·pÆ TÉËçò¹|^c¯±×ÜQî(w¸‹ÜEî"p‚NÐ ‚=ÞaÏ'ÓÉt2Áêdu²:A|Z|Z|ØžíÙg«Í^f/³Sƒ©ÁT­ ­ ­‚@n 7 æ5æ5æ5 /×—ëËùÉ“| ãÏxp¯q¯q¯©6±›c7Çn†è´è´è4ˆfG³£Ù`×±ëØu@-WËÕr0›™ÍÌfàëë æJs¥¹Ì5æs WWW‚±ÚXm¬=YOÖ“A Ð€š­f«Ù "*¢"À†0„jBÙ/ø~1ßUJ/La S@’$I’@“Çä1p ÝB·¼[½[½[ÁÝãîq÷€3Ôê ç\ç\ç\p;‡Ã`wµ»Ú]Á^m¯¶WƒagØànq·¸[€ãç8è=¢GÀìfv3»œœøfúfúf‚ÙÖlk¶óRóRóRÐÛëíõö 5ÖkAV£ÕhP…ªP‚zE½¢^zÑ‹^_ù}ò!‚ “a2 ¤–Ô’Z 3e¦ÌüJ¬$×ÍusÁγóì<°ÚGí£`M±¦XSª«7íö û¸½Ü^n/ }èF?£ŸÑ Ïð |=}=}=Á\f.3—‘j¤©Õgtcœ1κ£;ºSÝŠN;¨Ô‚º^]¯®çl×곿ˇïkÔë_ðWñ‹ø¡ˆ% ¬d%+9KõN{§½Ó “e²L¯–W˫ޫޫޫàöuûº}Á ¹!7nž›çæ»ÝÝîng±³ØY\­”ätp:8ÀéíôvzWÇ(¼åÞro9È&Ù$›¨”ó¶€rÈíííPmU[ÕT?ÕOõu\WÇ©®©ð)ŸòÌ—ù2¤…´ Ëe¹,)’")9)'å$È`,ƒ9›;“.ÕîÔîÔîýýý0ÖkŒ5`ì2v»À˜cÌ1æ€~£~£~#è­ôVz+ÐÓô4= ô½ú^}/è/è/è/€v™v™vh9ZŽ–êFu£ºT‘*REÀ£<Ê£œ•¡ÿ¿z†ÿßâðÏÆOa‹Xr§Ü)wA‚ÁËñr¼‡åay¼l/ÛËO÷tOo§·ÓÛ Þfo³·Ü5îwMõßÞ>oŸ·¼r¯Ü+OyÊSÕ¢ªgÒ_2A&ÈÕ²ZVƒ$J¢$‚ 2˜ÍlfSÍd{˜‡yÔ µB­¨6 j ¨‚6K›¥Í-WËÕr«÷›–¤%iI ehZh-µ–ZKÐ:h´ÕW½­ÞVo ZC­¡Ö´­@+õŽzG½SýeW-T ÕÔNµSíçq²É&›_Îîÿdübþ]8#jZõ…f:Ó™2PÊ@æÒ\šÃ™·q&M)ke­¬Y&Ëdx ¼ÞŲXƒ¬”•²d§ì” R! u¥®Ôé,¥3È8'ã€Wy•W£å(ÕÊLq£ÍhPsÕ\5Ô'êõ ¨¸Š«8¨t•®ÒAe©,•ª§ê©z‚ÖWë«õýÊ—újuµº´,-KËUKÕRµ¾r6ÿ„Oø¤:Hzö¬ÞšÖ´æ?>ÿþ“ü‚®¸âŠÈq9.ÇEäù@>‘á2\†‹ˆ%JÄ{Ò{Ò{RÄ-qKÜw°;Ø,â¬wÖ;ëE*)¯"öÛöÛöÛ"v–eg‰X[¬-Ö‘J ´ˆu‹u‹u‹ˆÕËêeõ±n°n°n±n³n³n±žµžµž±¢VÔŠŠØìö{¯½×Þ+âÜåÜåÜ%âXŽåX"îTwª;UÄkî5÷š‹xïyïyï‰HKi)-EäiyZž©<ªˆH©”Jé=é¿à ~ñ~.¡ºæ¡*HHyä;ÙÉN`;Ø|Îç|P@ÈVÙ*[©þòŸeUU‚g\ëª3µÊT™*hLcmiK[  mhCµ~}CÒ¨CêðK´ýg†ÿpú#_÷câ–%tEXtdate:create2014-12-31T13:30:38+02:00d·QÛ%tEXtdate:modify2014-10-17T01:10:21+03:00¢BÙaGtEXtsvg:base-urifile:///home/andrew/projects/aiohttp/docs/aiohttp-icon.svg!hËïIEND®B`‚aiohttp-0.20.2/docs/client.rst0000664000175000017500000004575612640011051016776 0ustar andrewandrew00000000000000.. _aiohttp-client: HTTP Client =========== .. module:: aiohttp .. currentmodule:: aiohttp Make a Request -------------- Begin by importing the aiohttp module:: import aiohttp Now, let's try to get a web-page. For example let's get GitHub's public time-line :: r = await aiohttp.get('https://api.github.com/events') Now, we have a :class:`ClientResponse` object called ``r``. We can get all the information we need from this object. The mandatory parameter of :func:`get` coroutine is an HTTP url. In order to make an HTTP POST request use :func:`post` coroutine:: r = await aiohttp.post('http://httpbin.org/post', data=b'data') Other HTTP methods are available as well:: r = await aiohttp.put('http://httpbin.org/put', data=b'data') r = await aiohttp.delete('http://httpbin.org/delete') r = await aiohttp.head('http://httpbin.org/get') r = await aiohttp.options('http://httpbin.org/get') r = await aiohttp.patch('http://httpbin.org/patch', data=b'data') Passing Parameters In URLs -------------------------- You often want to send some sort of data in the URL's query string. If you were constructing the URL by hand, this data would be given as key/value pairs in the URL after a question mark, e.g. ``httpbin.org/get?key=val``. Requests allows you to provide these arguments as a dictionary, using the ``params`` keyword argument. As an example, if you wanted to pass ``key1=value1`` and ``key2=value2`` to ``httpbin.org/get``, you would use the following code:: payload = {'key1': 'value1', 'key2': 'value2'} async with aiohttp.get('http://httpbin.org/get', params=payload) as r: assert r.url == 'http://httpbin.org/get?key2=value2&key1=value1' You can see that the URL has been correctly encoded by printing the URL. It is also possible to pass a list of 2 item tuples as parameters, in that case you can specify multiple values for each key:: payload = [('key', 'value1'), ('key', 'value2')] async with aiohttp.get('http://httpbin.org/get', params=payload) as r: assert r.url == 'http://httpbin.org/get?key=value2&key=value1' You can also pass ``str`` content as param, but beware - content is not encoded by library. Note that ``+`` is not encoded:: async with aiohttp.get('http://httpbin.org/get', params='key=value+1') as r: assert r.url = 'http://httpbin.org/get?key=value+1' Response Content ---------------- We can read the content of the server's response. Consider the GitHub time-line again:: r = await aiohttp.get('https://api.github.com/events') print(await r.text()) will printout something like:: '[{"created_at":"2015-06-12T14:06:22Z","public":true,"actor":{... ``aiohttp`` will automatically decode the content from the server. You can specify custom encoding for the :meth:`~ClientResponse.text` method:: await r.text(encoding='windows-1251') Binary Response Content ----------------------- You can also access the response body as bytes, for non-text requests:: print(await r.read()) :: b'[{"created_at":"2015-06-12T14:06:22Z","public":true,"actor":{... The ``gzip`` and ``deflate`` transfer-encodings are automatically decoded for you. JSON Response Content --------------------- There's also a built-in JSON decoder, in case you're dealing with JSON data:: async with aiohttp.get('https://api.github.com/events') as r: print(await r.json()) In case that JSON decoding fails, :meth:`~ClientResponse.json` will raise an exception. It is possible to specify custom encoding and decoder functions for the :meth:`~ClientResponse.json` call. Streaming Response Content -------------------------- While methods :meth:`~ClientResponse.read`, :meth:`~ClientResponse.json` and :meth:`~ClientResponse.text` are very convenient you should use them carefully. All these methods load the whole response in memory. For example if you want to download several gigabyte sized files, these methods will load all the data in memory. Instead you can use the :attr:`~ClientResponse.content` attribute. It is an instance of the ``aiohttp.StreamReader`` class. The ``gzip`` and ``deflate`` transfer-encodings are automatically decoded for you:: async with aiohttp.get('https://api.github.com/events') as r: await r.content.read(10) In general, however, you should use a pattern like this to save what is being streamed to a file:: with open(filename, 'wb') as fd: while True: chunk = await r.content.read(chunk_size) if not chunk: break fd.write(chunk) It is not possible to use :meth:`~ClientResponse.read`, :meth:`~ClientResponse.json` and :meth:`~ClientResponse.text` after explicit reading from :attr:`~ClientResponse.content`. Releasing Response -------------------------- Don't forget to release response after use. This will ensure explicit behavior and proper connection pooling. The easiest way to correctly response releasing is ``async with`` statement:: async with client.get(url) as resp: pass But explicit :meth:`~ClientResponse.release` call also may be used:: await r.release() But it's not necessary if you use :meth:`~ClientResponse.read`, :meth:`~ClientResponse.json` and :meth:`~ClientResponse.text` methods. They do release connection internally but better don't rely on that behavior. Custom Headers -------------- If you need to add HTTP headers to a request, pass them in a :class:`dict` to the *headers* parameter. For example, if you want to specify the content-type for the previous example:: import json url = 'https://api.github.com/some/endpoint' payload = {'some': 'data'} headers = {'content-type': 'application/json'} await aiohttp.post(url, data=json.dumps(payload), headers=headers) Custom Cookies -------------- To send your own cookies to the server, you can use the *cookies* parameter:: url = 'http://httpbin.org/cookies' cookies = dict(cookies_are='working') async with aiohttp.get(url, cookies=cookies) as r: assert await r.json() == {"cookies": {"cookies_are": "working"}} More complicated POST requests ------------------------------ Typically, you want to send some form-encoded data — much like an HTML form. To do this, simply pass a dictionary to the *data* argument. Your dictionary of data will automatically be form-encoded when the request is made:: payload = {'key1': 'value1', 'key2': 'value2'} async with aiohttp.post('http://httpbin.org/post', data=payload) as r: print(await r.text()) :: { ... "form": { "key2": "value2", "key1": "value1" }, ... } If you want to send data that is not form-encoded you can do it by passing a :class:`str` instead of a :class:`dict`. This data will be posted directly. For example, the GitHub API v3 accepts JSON-Encoded POST/PATCH data:: import json url = 'https://api.github.com/some/endpoint' payload = {'some': 'data'} r = await aiohttp.post(url, data=json.dumps(payload)) POST a Multipart-Encoded File ----------------------------- To upload Multipart-encoded files:: url = 'http://httpbin.org/post' files = {'file': open('report.xls', 'rb')} await aiohttp.post(url, data=files) You can set the filename, content_type explicitly:: url = 'http://httpbin.org/post' data = FormData() data.add_field('file', open('report.xls', 'rb'), filename='report.xls', content_type='application/vnd.ms-excel') await aiohttp.post(url, data=data) If you pass a file object as data parameter, aiohttp will stream it to the server automatically. Check :class:`~aiohttp.streams.StreamReader` for supported format information. .. seealso:: :ref:`aiohttp-multipart` Streaming uploads ----------------- :mod:`aiohttp` supports multiple types of streaming uploads, which allows you to send large files without reading them into memory. As a simple case, simply provide a file-like object for your body:: with open('massive-body', 'rb') as f: await aiohttp.post('http://some.url/streamed', data=f) Or you can provide an :ref:`coroutine` that yields bytes objects:: @asyncio.coroutine def my_coroutine(): chunk = yield from read_some_data_from_somewhere() if not chunk: return yield chunk .. warning:: ``yield`` expression is forbidden inside ``async def``. .. note:: It is not a standard :ref:`coroutine` as it yields values so it can not be used like ``yield from my_coroutine()``. :mod:`aiohttp` internally handles such coroutines. Also it is possible to use a :class:`~aiohttp.streams.StreamReader` object. Lets say we want to upload a file from another request and calculate the file SHA1 hash:: async def feed_stream(resp, stream): h = hashlib.sha256() while True: chunk = await resp.content.readany() if not chunk: break h.update(chunk) s.feed_data(chunk) return h.hexdigest() resp = aiohttp.get('http://httpbin.org/post') stream = StreamReader() loop.create_task(aiohttp.post('http://httpbin.org/post', data=stream)) file_hash = await feed_stream(resp, stream) Because the response content attribute is a :class:`~aiohttp.streams.StreamReader`, you can chain get and post requests together (aka HTTP pipelining):: r = await aiohttp.request('get', 'http://python.org') await aiohttp.post('http://httpbin.org/post', data=r.content) Uploading pre-compressed data ----------------------------- To upload data that is already compressed before passing it to aiohttp, call the request function with ``compress=False`` and set the used compression algorithm name (usually deflate or zlib) as the value of the ``Content-Encoding`` header:: @asyncio.coroutine def my_coroutine( my_data): data = zlib.compress(my_data) headers = {'Content-Encoding': 'deflate'} yield from aiohttp.post( 'http://httpbin.org/post', data=data, headers=headers, compress=False) .. _aiohttp-client-session: Keep-Alive, connection pooling and cookie sharing ------------------------------------------------- To share cookies between multiple requests you can create an :class:`~aiohttp.client.ClientSession` object:: session = aiohttp.ClientSession() await session.post( 'http://httpbin.org/cookies/set/my_cookie/my_value') async with session.get('http://httpbin.org/cookies') as r: json = await r.json() assert json['cookies']['my_cookie'] == 'my_value' You also can set default headers for all session requests:: session = aiohttp.ClientSession( headers={"Authorization": "Basic bG9naW46cGFzcw=="}) async with s.get("http://httpbin.org/headers") as r: json = yield from r.json() assert json['headers']['Authorization'] == 'Basic bG9naW46cGFzcw==' By default aiohttp does not use connection pooling. In other words multiple calls to :func:`~aiohttp.client.request` will start a new connection to host each. :class:`~aiohttp.client.ClientSession` object will do connection pooling for you. Connectors ---------- To tweak or change *transport* layer of requests you can pass a custom **Connector** to :func:`aiohttp.request` and family. For example:: conn = aiohttp.TCPConnector() r = await aiohttp.get('http://python.org', connector=conn) :class:`ClientSession` constructor also accepts *connector* instance:: session = aiohttp.ClientSession(connector=aiohttp.TCPConnector()) Limiting connection pool size ----------------------------- To limit amount of simultaneously opened connection to the same endpoint (``(host, port, is_ssl)`` triple) you can pass *limit* parameter to **connector**:: conn = aiohttp.TCPConnector(limit=30) The example limits amount of parallel connections to `30`. SSL control for TCP sockets --------------------------- :class:`aiohttp.connector.TCPConnector` constructor accepts mutually exclusive *verify_ssl* and *ssl_context* params. By default it uses strict checks for HTTPS protocol. Certification checks can be relaxed by passing ``verify_ssl=False``:: conn = aiohttp.TCPConnector(verify_ssl=False) session = aiohttp.ClientSession(connector=conn) r = await session.get('https://example.com') If you need to setup custom ssl parameters (use own certification files for example) you can create a :class:`ssl.SSLContext` instance and pass it into the connector:: sslcontext = ssl.create_default_context(cafile='/path/to/ca-bundle.crt') conn = aiohttp.TCPConnector(ssl_context=sslcontext) session = aiohttp.ClientSession(connector=conn) r = await session.get('https://example.com') You may also verify certificates via MD5, SHA1, or SHA256 fingerprint:: # Attempt to connect to https://www.python.org # with a pin to a bogus certificate: bad_md5 = b'\xa2\x06G\xad\xaa\xf5\xd8\\J\x99^by;\x06=' conn = aiohttp.TCPConnector(fingerprint=bad_md5) session = aiohttp.ClientSession(connector=conn) exc = None try: r = yield from session.get('https://www.python.org') except FingerprintMismatch as e: exc = e assert exc is not None assert exc.expected == bad_md5 # www.python.org cert's actual md5 assert exc.got == b'\xca;I\x9cuv\x8es\x138N$?\x15\xca\xcb' Note that this is the fingerprint of the DER-encoded certificate. If you have the certificate in PEM format, you can convert it to DER with e.g. ``openssl x509 -in crt.pem -inform PEM -outform DER > crt.der``. Tip: to convert from a hexadecimal digest to a binary byte-string, you can use :attr:`binascii.unhexlify`:: md5_hex = 'ca3b499c75768e7313384e243f15cacb' from binascii import unhexlify assert unhexlify(md5_hex) == b'\xca;I\x9cuv\x8es\x138N$?\x15\xca\xcb' Unix domain sockets ------------------- If your HTTP server uses UNIX domain sockets you can use :class:`aiohttp.connector.UnixConnector`:: conn = aiohttp.UnixConnector(path='/path/to/socket') r = await aiohttp.get('http://python.org', connector=conn) Proxy support ------------- aiohttp supports proxy. You have to use :class:`aiohttp.connector.ProxyConnector`:: conn = aiohttp.ProxyConnector(proxy="http://some.proxy.com") r = await aiohttp.get('http://python.org', connector=conn) :class:`~aiohttp.connector.ProxyConnector` also supports proxy authorization:: conn = aiohttp.ProxyConnector( proxy="http://some.proxy.com", proxy_auth=aiohttp.BasicAuth('user', 'pass')) session = aiohttp.ClientSession(connector=conn) async with session.get('http://python.org') as r: assert r.status == 200 Authentication credentials can be passed in proxy URL:: conn = aiohttp.ProxyConnector( proxy="http://user:pass@some.proxy.com") session = aiohttp.ClientSession(connector=conn) async with session.get('http://python.org') as r: assert r.status == 200 Response Status Codes --------------------- We can check the response status code:: async with aiohttp.get('http://httpbin.org/get') as r: assert r.status == 200 Response Headers ---------------- We can view the server's response headers using a multidict:: >>> r.headers {'ACCESS-CONTROL-ALLOW-ORIGIN': '*', 'CONTENT-TYPE': 'application/json', 'DATE': 'Tue, 15 Jul 2014 16:49:51 GMT', 'SERVER': 'gunicorn/18.0', 'CONTENT-LENGTH': '331', 'CONNECTION': 'keep-alive'} The dictionary is special, though: it's made just for HTTP headers. According to `RFC 7230 `_, HTTP Header names are case-insensitive. It also supports multiple values for the same key as HTTP protocol does. So, we can access the headers using any capitalization we want:: >>> r.headers['Content-Type'] 'application/json' >>> r.headers.get('content-type') 'application/json' Response Cookies ---------------- If a response contains some Cookies, you can quickly access them:: url = 'http://example.com/some/cookie/setting/url' async with aiohttp.get(url) as r: print(r.cookies['example_cookie_name']) .. note:: Response cookies contain only values, that were in ``Set-Cookie`` headers of the **last** request in redirection chain. To gather cookies between all redirection requests you can use :ref:`aiohttp.ClientSession ` object. Response History ---------------- If a request was redirected, it is possible to view previous responses using the :attr:`~ClientResponse.history` attribute:: >>> r = await aiohttp.get('http://example.com/some/redirect/') >>> r >>> r.history (,) If no redirects occurred or ``allow_redirects`` is set to ``False``, history will be an empty sequence. .. _aiohttp-client-websockets: WebSockets ---------- .. versionadded:: 0.15 :mod:`aiohttp` works with client websockets out-of-the-box. You have to use the :meth:`aiohttp.ClientSession.ws_connect` coroutine for client websocket connection. It accepts a *url* as a first parameter and returns :class:`ClientWebSocketResponse`, with that object you can communicate with websocket server using response's methods:: session = aiohttp.ClientSession() async with session.ws_connect('http://example.org/websocket') as ws: async for msg in ws: if msg.tp == aiohttp.MsgType.text: if msg.data == 'close cmd': await ws.close() break else: ws.send_str(msg.data + '/answer') elif msg.tp == aiohttp.MsgType.closed: break elif msg.tp == aiohttp.MsgType.error: break If you prefer to establish *websocket client connection* without explicit :class:`~aiohttp.ClientSession` instance please use :func:`ws_connect()`:: async with aiohttp.ws_connect('http://example.org/websocket') as ws: ... You **must** use the only websocket task for both reading (e.g ``await ws.receive()`` or ``async for msg in ws:``) and writing but may have multiple writer tasks which can only send data asynchronously (by ``ws.send_str('data')`` for example). Timeouts -------- You should use :func:`asyncio.wait_for()` coroutine if you want to limit time to wait for a response from a server:: >>> asyncio.wait_for(aiohttp.get('http://github.com'), ... 0.001) Traceback (most recent call last)\: File "", line 1, in asyncio.TimeoutError() Or wrap your client call in :class:`Timeout` context manager:: with aiohttp.Timeout(0.001): async with aiohttp.get('https://github.com') as r: await r.text() .. warning:: *timeout* is not a time limit on the entire response download; rather, an exception is raised if the server has not issued a response for *timeout* seconds (more precisely, if no bytes have been received on the underlying socket for *timeout* seconds). .. disqus:: aiohttp-0.20.2/docs/python33.rst0000664000175000017500000000114212621674010017175 0ustar andrewandrew00000000000000Python 3.3, ..., 3.4.1 support ============================== As of aiohttp **v0.18.0** we dropped support for Python 3.3 up to 3.4.1. The main reason for that is the :meth:`object.__del__` method, which is fully working since Python 3.4.1 and we need it for proper resource closing. The last Python 3.3, 3.4.0 compatible version of aiohttp is **v0.17.4**. This should not be an issue for most aiohttp users (for example Ubuntu 14.04.3 LTS provides python upgraded to 3.4.3), however libraries depending on aiohttp should consider this and either freeze aiohttp version or drop Python 3.3 support as well. aiohttp-0.20.2/docs/server.rst0000664000175000017500000000774512627010435017034 0ustar andrewandrew00000000000000.. _aiohttp-server: Low-level HTTP Server ===================== .. currentmodule:: aiohttp.server .. note:: This topic describes the low-level HTTP support. For high-level interface please take a look on :mod:`aiohttp.web`. Run a basic server ------------------ Start implementing the basic server by inheriting the :class:`ServerHttpProtocol` object. Your class should implement the only method :meth:`ServerHttpProtocol.handle_request` which must be a coroutine to handle requests asynchronously .. code-block:: python from urllib.parse import urlparse, parse_qsl import aiohttp import aiohttp.server from aiohttp import MultiDict import asyncio class HttpRequestHandler(aiohttp.server.ServerHttpProtocol): async def handle_request(self, message, payload): response = aiohttp.Response( self.writer, 200, http_version=message.version ) response.add_header('Content-Type', 'text/html') response.add_header('Content-Length', '18') response.send_headers() response.write(b'

It Works!

') await response.write_eof() The next step is to create a loop and register your handler within a server. :exc:`KeyboardInterrupt` exception handling is necessary so you can stop your server with Ctrl+C at any time. .. code-block:: python if __name__ == '__main__': loop = asyncio.get_event_loop() f = loop.create_server( lambda: HttpRequestHandler(debug=True, keep_alive=75), '0.0.0.0', '8080') srv = loop.run_until_complete(f) print('serving on', srv.sockets[0].getsockname()) try: loop.run_forever() except KeyboardInterrupt: pass Headers ------- Data is passed to the handler in the ``message``, while request body is passed in ``payload`` param. HTTP headers are accessed through ``headers`` member of the message. To check what the current method of the request is use the ``method`` member of the ``message``. It should be one of ``GET``, ``POST``, ``PUT`` or ``DELETE`` strings. Handling GET params ------------------- Currently aiohttp does not provide automatic parsing of incoming GET params. However aiohttp does provide a nice :class:`MulitiDict` wrapper for already parsed params. .. code-block:: python from urllib.parse import urlparse, parse_qsl from aiohttp import MultiDict class HttpRequestHandler(aiohttp.server.ServerHttpProtocol): async def handle_request(self, message, payload): response = aiohttp.Response( self.writer, 200, http_version=message.version ) get_params = MultiDict(parse_qsl(urlparse(message.path).query)) print("Passed in GET", get_params) Handling POST data ------------------ POST data is accessed through the ``payload.read()`` generator method. If you have form data in the request body, you can parse it in the same way as GET params. .. code-block:: python from urllib.parse import urlparse, parse_qsl from aiohttp import MultiDict class HttpRequestHandler(aiohttp.server.ServerHttpProtocol): async def handle_request(self, message, payload): response = aiohttp.Response( self.writer, 200, http_version=message.version ) data = await payload.read() post_params = MultiDict(parse_qsl(data)) print("Passed in POST", post_params) SSL --- To use asyncio's SSL support, just pass an SSLContext object to the :meth:`asyncio.BaseEventLoop.create_server` method of the loop. .. code-block:: python import ssl sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslcontext.load_cert_chain('sample.crt', 'sample.key') loop = asyncio.get_event_loop() loop.create_server(lambda: handler, "0.0.0.0", "8080", ssl=sslcontext) Reference --------- .. automodule:: aiohttp.server :members: :undoc-members: :show-inheritance: .. disqus:: aiohttp-0.20.2/docs/glossary.rst0000664000175000017500000000231112643552137017361 0ustar andrewandrew00000000000000.. _aiohttp-glossary: ========== Glossary ========== .. if you add new entries, keep the alphabetical sorting! .. glossary:: asyncio The library for writing single-threaded concurrent code using coroutines, multiplexing I/O access over sockets and other resources, running network clients and servers, and other related primitives. Reference implementation of :pep:`3156` https://pypi.python.org/pypi/asyncio/ callable Any object that can be called. Use :func:`callable` to check that. chardet The Universal Character Encoding Detector https://pypi.python.org/pypi/chardet/ cchardet cChardet is high speed universal character encoding detector - binding to charsetdetect. https://pypi.python.org/pypi/cchardet/ keep-alive A technique for communicating between HTTP client and server when connection is not closed after sending response but keeped open for sending next request through the same socket. It makes communication faster by getting rid of connection establishment for every request. web-handler An endpoint that returns HTTP response. .. disqus:: aiohttp-0.20.2/docs/web.rst0000664000175000017500000006262712643552137016313 0ustar andrewandrew00000000000000.. _aiohttp-web: HTTP Server Usage ================= .. currentmodule:: aiohttp.web .. versionchanged:: 0.12 :mod:`aiohttp.web` was deeply refactored making it backwards incompatible. Run a Simple Web Server ----------------------- In order to implement a web server, first create a :ref:`request handler `. A request handler is a :ref:`coroutine ` or regular function that accepts a :class:`Request` instance as its only parameter and returns a :class:`Response` instance:: import asyncio from aiohttp import web async def hello(request): return web.Response(body=b"Hello, world") Next, create an :class:`Application` instance and register the request handler with the application's :class:`router ` on a particular *HTTP method* and *path*:: app = web.Application() app.router.add_route('GET', '/', hello) After that, create a server and run the *asyncio loop* as usual:: loop = asyncio.get_event_loop() handler = app.make_handler() f = loop.create_server(handler, '0.0.0.0', 8080) srv = loop.run_until_complete(f) print('serving on', srv.sockets[0].getsockname()) try: loop.run_forever() except KeyboardInterrupt: pass finally: srv.close() loop.run_until_complete(srv.wait_closed()) loop.run_until_complete(handler.finish_connections(1.0)) loop.run_until_complete(app.finish()) loop.close() That's it. Now, head over to ``http://localhost:8080/`` to see the results. .. _aiohttp-web-handler: Handler ------- A request handler can be any :term:`callable` that accepts a :class:`Request` instance as its only argument and returns a :class:`StreamResponse` derived (e.g. :class:`Response`) instance:: def handler(request): return web.Response() A handler **may** also be a :ref:`coroutine`, in which case :mod:`aiohttp.web` will ``await`` the handler:: async def handler(request): return web.Response() Handlers are setup to handle requests by registering them with the :attr:`Application.router` on a particular route (*HTTP method* and *path* pair):: app.router.add_route('GET', '/', handler) app.router.add_route('POST', '/post', post_handler) app.router.add_route('PUT', '/put', put_handler) :meth:`~UrlDispatcher.add_route` also supports the wildcard *HTTP method*, allowing a handler to serve incoming requests on a *path* having **any** *HTTP method*:: app.router.add_route('*', '/path', all_handler) The *HTTP method* can be queried later in the request handler using the :attr:`Request.method` property. .. versionadded:: 0.15.2 Support for wildcard *HTTP method* routes. .. _aiohttp-web-variable-handler: Variable Routes ^^^^^^^^^^^^^^^ Handlers can also be attached to routes with *variable paths*. For instance, a route with the path ``'/a/{name}/c'`` would match all incoming requests with paths such as ``'/a/b/c'``, ``'/a/1/c'``, and ``'/a/etc/c'``. A variable *part* is specified in the form ``{identifier}``, where the ``identifier`` can be used later in a :ref:`request handler ` to access the matched value for that *part*. This is done by looking up the ``identifier`` in the :attr:`Request.match_info` mapping:: async def variable_handler(request): return web.Response( text="Hello, {}".format(request.match_info['name'])) app.router.add_route('GET', '/{name}', variable_handler) By default, each *part* matches the regular expression ``[^{}/]+``. You can also specify a custom regex in the form ``{identifier:regex}``:: app.router.add_route('GET', r'/{name:\d+}', variable_handler) .. versionadded:: 0.13 Support for custom regexs in variable routes. .. _aiohttp-web-named-routes: Reverse URL Constructing using Named Routes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Routes can also be given a *name*:: app.router.add_route('GET', '/root', handler, name='root') Which can then be used to access and build a *URL* for that route later (e.g. in a :ref:`request handler `):: >>> request.app.router['root'].url(query={"a": "b", "c": "d"}) '/root?a=b&c=d' A more interesting example is building *URLs* for :ref:`variable routes `:: app.router.add_route('GET', r'/{user}/info', variable_handler, name='user-info') In this case you can also pass in the *parts* of the route:: >>> request.app.router['user-info'].url( ... parts={'user': 'john_doe'}, ... query="?a=b") '/john_doe/info?a=b' Organizing Handlers in Classes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ As discussed above, :ref:`handlers ` can be first-class functions or coroutines:: async def hello(request): return web.Response(body=b"Hello, world") app.router.add_route('GET', '/', hello) But sometimes it's convenient to group logically similar handlers into a Python *class*. Since :mod:`aiohttp.web` does not dictate any implementation details, application developers can organize handlers in classes if they so wish:: class Handler: def __init__(self): pass def handle_intro(self, request): return web.Response(body=b"Hello, world") async def handle_greeting(self, request): name = request.match_info.get('name', "Anonymous") txt = "Hello, {}".format(name) return web.Response(text=txt) handler = Handler() app.router.add_route('GET', '/intro', handler.handle_intro) app.router.add_route('GET', '/greet/{name}', handler.handle_greeting) .. _aiohttp-web-class-based-views: Class Based Views ^^^^^^^^^^^^^^^^^ :mod:`aiohttp.web` has support for django-style class based views. You can derive from :class:`View` and define methods for handling http requests:: class MyView(web.View): async def get(self): return await get_resp(self.request) async def post(self): return await post_resp(self.request) Handlers should be coroutines accepting self only and returning response object as regular :term:`web-handler`. Request object can be retrieved by :attr:`View.request` property. After implementing the view (``MyView`` from example above) should be registered in application's router:: app.router.add_route('*', '/path/to', MyView) Example will process GET and POST requests for */path/to* but raise *405 Method not allowed* exception for unimplemented HTTP methods. Route Views ^^^^^^^^^^^ *All* registered routes in a router can be viewed using the :meth:`UrlDispatcher.routes` method:: for route in app.router.routes(): print(route) Similarly, a *subset* of the routes that were registered with a *name* can be viewed using the :meth:`UrlDispatcher.named_routes` method:: for name, route in app.router.named_routes().items(): print(name, route) .. versionadded:: 0.18 :meth:`UrlDispatcher.routes` .. versionadded:: 0.19 :meth:`UrlDispatcher.named_routes` Custom Routing Criteria ----------------------- Sometimes you need to register :ref:`handlers ` on more complex criteria than simply a *HTTP method* and *path* pair. Although :class:`UrlDispatcher` does not support any extra criteria, routing based on custom conditions can be accomplished by implementing a second layer of routing in your application. The following example shows custom routing based on the *HTTP Accept* header: .. code-block:: python class AcceptChooser: def __init__(self): self._accepts = {} async def do_route(self, request): for accept in request.headers.getall('ACCEPT', []): acceptor = self._accepts.get(accept) if acceptor is not None: return (await acceptor(request)) raise HTTPNotAcceptable() def reg_acceptor(self, accept, handler): self._accepts[accept] = handler async def handle_json(request): # do json handling async def handle_xml(request): # do xml handling chooser = AcceptChooser() app.router.add_route('GET', '/', chooser.do_route) chooser.reg_acceptor('application/json', handle_json) chooser.reg_acceptor('application/xml', handle_xml) Template Rendering ------------------ :mod:`aiohttp.web` does not support template rendering out-of-the-box. However, there is a third-party library, :mod:`aiohttp_jinja2`, which is supported by the *aiohttp* authors. Using it is rather simple. First, setup a *jinja2 environment* with a call to :func:`aiohttp_jinja2.setup`:: app = web.Application(loop=self.loop) aiohttp_jinja2.setup(app, loader=jinja2.FileSystemLoader('/path/to/templates/folder')) After that you may use the template engine in your :ref:`handlers `. The most convenient way is to simply wrap your handlers with the :func:`aiohttp_jinja2.template` decorator:: @aiohttp_jinja2.template('tmpl.jinja2') def handler(request): return {'name': 'Andrew', 'surname': 'Svetlov'} If you prefer the `Mako`_ template engine, please take a look at the `aiohttp_mako`_ library. .. _Mako: http://www.makotemplates.org/ .. _aiohttp_mako: https://github.com/aio-libs/aiohttp_mako User Sessions ------------- Often you need a container for storing user data across requests. The concept is usually called a *session*. :mod:`aiohttp.web` has no built-in concept of a *session*, however, there is a third-party library, :mod:`aiohttp_session`, that adds *session* support:: import asyncio import time from aiohttp import web from aiohttp_session import get_session, session_middleware from aiohttp_session.cookie_storage import EncryptedCookieStorage async def handler(request): session = await get_session(request) session['last_visit'] = time.time() return web.Response(body=b'OK') async def init(loop): app = web.Application(middlewares=[session_middleware( EncryptedCookieStorage(b'Sixteen byte key'))]) app.router.add_route('GET', '/', handler) srv = await loop.create_server( app.make_handler(), '0.0.0.0', 8080) return srv loop = asyncio.get_event_loop() loop.run_until_complete(init(loop)) try: loop.run_forever() except KeyboardInterrupt: pass .. _aiohttp-web-expect-header: *Expect* Header --------------- .. versionadded:: 0.15 By default, :mod:`aiohttp.web` simply responds with an ``HTTP/1.1 100 Continue`` status code whenever a requests contains an *Expect* header; however, it is possible to specify a custom *Expect* handler on a per route basis. This handler gets called **after** receiving the request headers, but **before** calling application :ref:`middlewares `, or route :ref:`handlers `. The *Expect* handler *may* return *None*, in which case the request processing continues as usual. If the handler returns an instance of class :class:`StreamResponse`, the *request handler* uses it as the response. If all checks pass, the custom handler *must* write a *HTTP/1.1 100 Continue* status code before returning. The following example shows how to setup a custom handler for the *Expect* header: .. code-block:: python async def check_auth(request): if request.version != aiohttp.HttpVersion11: return if request.headers.get('AUTHORIZATION') is None: return web.HTTPForbidden() request.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n") async def hello(request): return web.Response(body=b"Hello, world") app = web.Application() app.router.add_route('GET', '/', hello, expect_handler=check_auth) .. _aiohttp-web-file-upload: File Uploads ------------ :mod:`aiohttp.web` has built-in support for handling files uploaded from the browser. First, make sure that the HTML ``
`` element has its *enctype* attribute set to ``enctype="multipart/form-data"``. As an example, here is a form that accepts a MP3 file: .. code-block:: html
Then, in the :ref:`request handler ` you can access the file input field as a :class:`FileField` instance. :class:`FileField` is simply a container for the file as well as some of its metadata: .. code-block:: python async def store_mp3_handler(request): data = await request.post() mp3 = data['mp3'] # .filename contains the name of the file in string format. filename = mp3.filename # .file contains the actual file data that needs to be stored somewhere. mp3_file = data['mp3'].file content = mp3_file.read() return web.Response(body=content, headers=MultiDict( {'CONTENT-DISPOSITION': mp3_file}) .. _aiohttp-web-websockets: WebSockets ---------- .. versionadded:: 0.14 :mod:`aiohttp.web` supports *WebSockets* out-of-the-box. To setup a *WebSocket*, create a :class:`WebSocketResponse` in a :ref:`request handler ` and then use it to communicate with the peer: .. code-block:: python async def websocket_handler(request): ws = web.WebSocketResponse() await ws.prepare(request) async for msg in ws: if msg.tp == aiohttp.MsgType.text: if msg.data == 'close': await ws.close() else: ws.send_str(msg.data + '/answer') elif msg.tp == aiohttp.MsgType.error: print('ws connection closed with exception %s' % ws.exception()) print('websocket connection closed') return ws Reading from the *WebSocket* (``await ws.receive()``) **must only** be done inside the request handler coroutine; however, writing (``ws.send_str(...)``) to the *WebSocket* may be delegated to other coroutines. .. note:: While :mod:`aiohttp.web` itself only supports *WebSockets* without downgrading to *LONG-POLLING*, etc., our team supports SockJS_, an aiohttp-based library for implementing SockJS-compatible server code. .. _SockJS: https://github.com/aio-libs/sockjs .. _aiohttp-web-exceptions: Exceptions ---------- :mod:`aiohttp.web` defines a set of exceptions for every *HTTP status code*. Each exception is a subclass of :class:`~HTTPException` and relates to a single HTTP status code. The exceptions are also a subclass of :class:`Response`, allowing you to either ``raise`` or ``return`` them in a :ref:`request handler ` for the same effect. The following snippets are the same:: async def handler(request): return aiohttp.web.HTTPFound('/redirect') and:: async def handler(request): raise aiohttp.web.HTTPFound('/redirect') Each exception class has a status code according to :rfc:`2068`: codes with 100-300 are not really errors; 400s are client errors, and 500s are server errors. HTTP Exception hierarchy chart:: Exception HTTPException HTTPSuccessful * 200 - HTTPOk * 201 - HTTPCreated * 202 - HTTPAccepted * 203 - HTTPNonAuthoritativeInformation * 204 - HTTPNoContent * 205 - HTTPResetContent * 206 - HTTPPartialContent HTTPRedirection * 300 - HTTPMultipleChoices * 301 - HTTPMovedPermanently * 302 - HTTPFound * 303 - HTTPSeeOther * 304 - HTTPNotModified * 305 - HTTPUseProxy * 307 - HTTPTemporaryRedirect * 308 - HTTPPermanentRedirect HTTPError HTTPClientError * 400 - HTTPBadRequest * 401 - HTTPUnauthorized * 402 - HTTPPaymentRequired * 403 - HTTPForbidden * 404 - HTTPNotFound * 405 - HTTPMethodNotAllowed * 406 - HTTPNotAcceptable * 407 - HTTPProxyAuthenticationRequired * 408 - HTTPRequestTimeout * 409 - HTTPConflict * 410 - HTTPGone * 411 - HTTPLengthRequired * 412 - HTTPPreconditionFailed * 413 - HTTPRequestEntityTooLarge * 414 - HTTPRequestURITooLong * 415 - HTTPUnsupportedMediaType * 416 - HTTPRequestRangeNotSatisfiable * 417 - HTTPExpectationFailed * 421 - HTTPMisdirectedRequest * 426 - HTTPUpgradeRequired * 428 - HTTPPreconditionRequired * 429 - HTTPTooManyRequests * 431 - HTTPRequestHeaderFieldsTooLarge HTTPServerError * 500 - HTTPInternalServerError * 501 - HTTPNotImplemented * 502 - HTTPBadGateway * 503 - HTTPServiceUnavailable * 504 - HTTPGatewayTimeout * 505 - HTTPVersionNotSupported * 506 - HTTPVariantAlsoNegotiates * 510 - HTTPNotExtended * 511 - HTTPNetworkAuthenticationRequired All HTTP exceptions have the same constructor signature:: HTTPNotFound(*, headers=None, reason=None, body=None, text=None, content_type=None) If not directly specified, *headers* will be added to the *default response headers*. Classes :class:`HTTPMultipleChoices`, :class:`HTTPMovedPermanently`, :class:`HTTPFound`, :class:`HTTPSeeOther`, :class:`HTTPUseProxy`, :class:`HTTPTemporaryRedirect` have the following constructor signature:: HTTPFound(location, *, headers=None, reason=None, body=None, text=None, content_type=None) where *location* is value for *Location HTTP header*. :class:`HTTPMethodNotAllowed` is constructed by providing the incoming unsupported method and list of allowed methods:: HTTPMethodNotAllowed(method, allowed_methods, *, headers=None, reason=None, body=None, text=None, content_type=None) .. _aiohttp-web-data-sharing: Data Sharing ------------ :mod:`aiohttp.web` discourages the use of *global variables*, aka *singletons*. Every variable should have it's own context that is *not global*. So, :class:`aiohttp.web.Application` and :class:`aiohttp.web.Request` support a :class:`collections.abc.MutableMapping` interface (i.e. they are dict-like objects), allowing them to be used as data stores. For storing *global-like* variables, feel free to save them in an :class:`~.Application` instance:: app['my_private_key'] = data and get it back in the :term:`web-handler`:: async def handler(request): data = request.app['my_private_key'] Variables that are only needed for the lifetime of a :class:`~.Request`, can be stored in a :class:`~.Request`:: async def handler(request): request['my_private_key'] = "data" ... This is mostly useful for :ref:`aiohttp-web-middlewares` and :ref:`aiohttp-web-signals` handlers to store data for further processing by the next handlers in the chain. To avoid clashing with other *aiohttp* users and third-party libraries, please choose a unique key name for storing data. If your code is published on PyPI, then the project name is most likely unique 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-middlewares: Middlewares ----------- .. versionadded:: 0.13 :mod:`aiohttp.web` provides a powerful mechanism for customizing :ref:`request handlers` via *middlewares*. *Middlewares* are setup by providing a sequence of *middleware factories* to the keyword-only ``middlewares`` parameter when creating an :class:`Application`:: app = web.Application(middlewares=[middleware_factory_1, middleware_factory_2]) A *middleware factory* is simply a coroutine that implements the logic of a *middleware*. For example, here's a trivial *middleware factory*:: async def middleware_factory(app, handler): async def middleware_handler(request): return await handler(request) return middleware_handler Every *middleware factory* should accept two parameters, an :class:`app ` instance and a *handler*, and return a new handler. The *handler* passed in to a *middleware factory* is the handler returned by the **next** *middleware factory*. The last *middleware factory* always receives the :ref:`request handler ` selected by the router itself (by :meth:`UrlDispatcher.resolve`). *Middleware factories* should return a new handler that has the same signature as a :ref:`request handler `. That is, it should accept a single :class:`Response` instance and return a :class:`Response`, or raise an exception. Internally, a single :ref:`request handler ` is constructed by applying the middleware chain to the original handler in reverse order, and is called by the :class:`RequestHandler` as a regular *handler*. Since *middleware factories* are themselves coroutines, they may perform extra ``await`` calls when creating a new handler, e.g. call database etc. *Middlewares* usually call the inner handler, but they may choose to ignore it, e.g. displaying *403 Forbidden page* or raising :exc:`HTTPForbidden` exception if user has no permissions to access the underlying resource. They may also render errors raised by the handler, perform some pre- or post-processing like handling *CORS* and so on. .. versionchanged:: 0.14 Middlewares accept route exceptions (:exc:`HTTPNotFound` and :exc:`HTTPMethodNotAllowed`). .. _aiohttp-web-signals: Signals ------- .. versionadded:: 0.18 Although :ref:`middlewares ` can customize :ref:`request handlers` before or after a :class:`Response` has been prepared, they can't customize a :class:`Response` **while** it's being prepared. For this :mod:`aiohttp.web` provides *signals*. For example, a middleware can only change HTTP headers for *unprepared* responses (see :meth:`~aiohttp.web.StreamResponse.prepare`), but sometimes we need a hook for changing HTTP headers for streamed responses and WebSockets. This can be accomplished by subscribing to the :attr:`~aiohttp.web.Application.on_response_prepare` signal:: async def on_prepare(request, response): response.headers['My-Header'] = 'value' app.on_response_prepare.append(on_prepare) Signal handlers should not return a value but may modify incoming mutable parameters. .. warning:: Signals API has provisional status, meaning it may be changed in future releases. Signal subscription and sending will most likely be the same, but signal object creation is subject to change. As long as you are not creating new signals, but simply reusing existing ones, you will not be affected. Flow control ------------ :mod:`aiohttp.web` has sophisticated flow control for underlying TCP sockets write buffer. The problem is: by default TCP sockets use `Nagle's algorithm `_ for output buffer which is not optimal for streaming data protocols like HTTP. Web server response may have one of the following states: 1. **CORK** (:attr:`~StreamResponse.tcp_cork` is ``True``). Don't send out partial TCP/IP frames. All queued partial frames are sent when the option is cleared again. Optimal for sending big portion of data since data will be sent using minimum frames count. If OS doesn't support **CORK** mode (neither ``socket.TCP_CORK`` nor ``socket.TCP_NOPUSH`` exists) the mode is equal to *Nagle's enabled* one. The most widespread OS without **CORK** support is *Windows*. 2. **NODELAY** (:attr:`~StreamResponse.tcp_nodelay` is ``True``). Disable the Nagle algorithm. This means that small data pieces are always sent as soon as possible, even if there is only a small amount of data. Optimal for transmitting short messages. 3. Nagle's algorithm enabled (both :attr:`~StreamResponse.tcp_cork` and :attr:`~StreamResponse.tcp_nodelay` are ``False``). Data is buffered until there is a sufficient amount to send out. Avoid using this mode for sending HTTP data until you have no doubts. By default streaming data (:class:`StreamResponse`) and websockets (:class:`WebSocketResponse`) use **NODELAY** mode, regular responses (:class:`Response` and http exceptions derived from it) as well as static file handlers work in **CORK** mode. To manual mode switch :meth:`~StreamResponse.set_tcp_cork` and :meth:`~StreamResponse.set_tcp_nodelay` methods can be used. It may be helpful for better streaming control for example. CORS support ------------ :mod:`aiohttp.web` itself does not support `Cross-Origin Resource Sharing `_, but there is a aiohttp plugin for it: `aiohttp_cors `_. Debug Toolbar ------------- aiohttp_debugtoolbar_ is a very useful library that provides a debugging toolbar while you're developing an :mod:`aiohttp.web` application. Install it via ``pip``:: $ pip install aiohttp_debugtoolbar After that attach the :mod:`aiohttp_debugtoolbar` middleware to your :class:`aiohttp.web.Application` and call :func:`aiohttp_debugtoolbar.setup`:: import aiohttp_debugtoolbar from aiohttp_debugtoolbar import toolbar_middleware_factory app = web.Application(loop=loop, middlewares=[toolbar_middleware_factory]) aiohttp_debugtoolbar.setup(app) The toolbar is ready to use. Enjoy!!! .. _aiohttp_debugtoolbar: https://github.com/aio-libs/aiohttp_debugtoolbar .. disqus:: aiohttp-0.20.2/docs/aiohttp-icon.svg0000664000175000017500000014174612552474754020132 0ustar andrewandrew00000000000000 aiohttp-icon Created with Sketch. aiohttp-0.20.2/docs/index.rst0000664000175000017500000000763612641572352016643 0ustar andrewandrew00000000000000.. aiohttp documentation master file, created by sphinx-quickstart on Wed Mar 5 12:35:35 2014. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. aiohttp ======= HTTP client/server for :term:`asyncio` (:pep:`3156`). .. _GitHub: https://github.com/KeepSafe/aiohttp .. _Freenode: http://freenode.net Features -------- - Supports both :ref:`aiohttp-client` and :ref:`HTTP Server `. - Supports both :ref:`Server WebSockets ` and :ref:`Client WebSockets ` out-of-the-box. - Web-server has :ref:`aiohttp-web-middlewares`, :ref:`aiohttp-web-signals` and pluggable routing. Library Installation -------------------- :: $ pip install aiohttp You may want to install *optional* :term:`cchardet` library as faster replacement for :term:`chardet`:: $ pip install cchardet Getting Started --------------- Client example:: import asyncio import aiohttp async def fetch_page(client, url): async with client.get(url) as response: assert response.status == 200 return await response.read() loop = asyncio.get_event_loop() client = aiohttp.ClientSession(loop=loop) content = loop.run_until_complete( fetch_page(client, 'http://python.org')) print(content) client.close() Server example:: import asyncio from aiohttp import web async def handle(request): name = request.match_info.get('name', "Anonymous") text = "Hello, " + name return web.Response(body=text.encode('utf-8')) async def init(loop): app = web.Application(loop=loop) app.router.add_route('GET', '/{name}', handle) srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8080) print("Server started at http://127.0.0.1:8080") return srv loop = asyncio.get_event_loop() loop.run_until_complete(init(loop)) try: loop.run_forever() except KeyboardInterrupt: pass .. note:: Throughout this documentation, examples utilize the `async/await` syntax introduced by :pep:`492` that is only valid for Python 3.5+. If you are using Python 3.4, please replace ``await`` with ``yield from`` and ``async def`` with a ``@coroutine`` decorator. For example, this:: async def coro(...): ret = await f() should be replaced by:: @asyncio.coroutine def coro(...): ret = yield from f() Source code ----------- The project is hosted on GitHub_ Please feel free to file an issue on the `bug tracker `_ if you have found a bug or have some suggestion in order to improve the library. The library uses `Travis `_ for Continuous Integration. Dependencies ------------ - Python Python 3.4.1+ - *chardet* library - *Optional* :term:`cchardet` library as faster replacement for :term:`chardet`. Install it explicitly via:: $ pip install cchardet Discussion list --------------- *aio-libs* google group: https://groups.google.com/forum/#!forum/aio-libs Feel free to post your questions and ideas here. Contributing ------------ Please read the :ref:`instructions for contributors` before making a Pull Request. Authors and License ------------------- The ``aiohttp`` package is written mostly by Nikolay Kim and Andrew Svetlov. It's *Apache 2* licensed and freely available. Feel free to improve this package and send a pull request to GitHub_. Contents -------- .. toctree:: client client_reference web web_reference server multidict multipart api logging gunicorn contributing changes Python 3.3 support glossary Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` .. disqus:: aiohttp-0.20.2/docs/multipart.rst0000664000175000017500000002554312631071601017540 0ustar andrewandrew00000000000000.. module:: aiohttp.multipart .. _aiohttp-multipart: Working with Multipart ====================== `aiohttp` supports a full featured multipart reader and writer. Both are designed with steaming processing in mind to avoid unwanted footprint which may be significant if you're dealing with large payloads, but this also means that most I/O operation are only possible to be executed a single time. Reading Multipart Responses --------------------------- Assume you made a request, as usual, and want to process the response multipart data:: async with aiohttp.request(...) as resp: pass First, you need to wrap the response with a :meth:`MultipartReader.from_response`. This needs to keep the implementation of :class:`MultipartReader` separated from the response and the connection routines which makes it more portable:: reader = aiohttp.MultipartReader.from_response(resp) Let's assume with this response you'd received some JSON document and multiple files for it, but you don't need all of them, just a specific one. So first you need to enter into a loop where the multipart body will be processed:: metadata = None filedata = None while True: part = await reader.next() The returned type depends on what the next part is: if it's a simple body part then you'll get :class:`BodyPartReader` instance here, otherwise, it will be another :class:`MultipartReader` instance for the nested multipart. Remember, that multipart format is recursive and supports multiple levels of nested body parts. When there are no more parts left to fetch, ``None`` value will be returned - that's the signal to break the loop:: if part is None: break Both :class:`BodyPartReader` and :class:`MultipartReader` provides access to body part headers: this allows you to filter parts by their attributes:: if part.headers[aiohttp.hdrs.CONTENT-TYPE] == 'application/json': metadata = await part.json() continue Nor :class:`BodyPartReader` or :class:`MultipartReader` instances doesn't read the whole body part data without explicitly asking for. :class:`BodyPartReader` provides a set of helpers methods to fetch popular content types in friendly way: - :meth:`BodyPartReader.text` for plain text data; - :meth:`BodyPartReader.json` for JSON; - :meth:`BodyPartReader.form` for `application/www-urlform-encode` Each of these methods automatically recognizes if content is compressed by using `gzip` and `deflate` encoding (while it respects `identity` one), or if transfer encoding is base64 or `quoted-printable` - in each case the result will get automatically decoded. But in case you need to access to raw binary data as it is, there are :meth:`BodyPartReader.read` and :meth:`BodyPartReader.read_chunk` coroutine methods as well to read raw binary data as it is all-in-single-shot or by chunks respectively. When you have to deal with multipart files, the :attr:`BodyPartReader.filename` property comes to help. It's a very smart helper which handles `Content-Disposition` handler right and extracts the right filename attribute from it:: if part.filename != 'secret.txt': continue If current body part doesn't matches your expectation and you want to skip it - just continue a loop to start a next iteration of it. Here is where magic happens. Before fetching the next body part ``await reader.next()`` it ensures that the previous one was read completely. If it wasn't, all its content sends to the void in term to fetch the next part. So you don't have to care about cleanup routines while you're within a loop. Once you'd found a part for the file you'd searched for, just read it. Let's handle it as it is without applying any decoding magic:: filedata = await part.read(decode=False) Later you may decide to decode the data. It's still simple and possible to do:: filedata = part.decode(filedata) Once you are done with multipart processing, just break a loop:: break Sending Multipart Requests -------------------------- :class:`MultipartWriter` provides an interface to build multipart payload from the Python data and serialize it into chunked binary stream. Since multipart format is recursive and supports deeply nesting, you can use ``with`` statement to design your multipart data closer to how it will be:: with aiohttp.MultipartWriter('mixed') as mpwriter: ... with aiohttp.MultipartWriter('related') as subwriter: ... mpwriter.append(subwriter) with aiohttp.MultipartWriter('related') as subwriter: ... with aiohttp.MultipartWriter('related') as subsubwriter: ... subwriter.append(subsubwriter) mpwriter.append(subwriter) with aiohttp.MultipartWriter('related') as subwriter: ... mpwriter.append(subwriter) The :meth:`MultipartWriter.append` is used to join new body parts into a single stream. It accepts various inputs and determines what default headers should be used for. For text data default `Content-Type` is :mimetype:`text/plain; charset=utf-8`:: mpwriter.append('hello') For binary data :mimetype:`application/octet-stream` is used:: mpwriter.append(b'aiohttp') You can always override these default by passing your own headers with the second argument:: mpwriter.append(io.BytesIO(b'GIF89a...'), {'CONTENT-TYPE': 'image/gif'}) For file objects `Content-Type` will be determined by using Python's `mimetypes`_ module and additionally `Content-Disposition` header will include the file's basename:: part = root.append(open(__file__, 'rb')) If you want to send a file with a different name, just handle the :class:`BodyPartWriter` instance which :meth:`MultipartWriter.append` will always return and set `Content-Disposition` explicitly by using the :meth:`BodyPartWriter.set_content_disposition` helper:: part.set_content_disposition('attachment', filename='secret.txt') Additionally, you may want to set other headers here:: part.headers[aiohttp.hdrs.CONTENT_ID] = 'X-12345' If you'd set `Content-Encoding`, it will be automatically applied to the data on serialization (see below):: part.headers[aiohttp.hdrs.CONTENT_ENCODING] = 'gzip' There are also :meth:`MultipartWriter.append_json` and :meth:`MultipartWriter.append_form` helpers which are useful to work with JSON and form urlencoded data, so you don't have to encode it every time manually:: mpwriter.append_json({'test': 'passed'}) mpwriter.append_form([('key', 'value')]) When it's done, to make a request just pass a root :class:`MultipartWriter` instance as :func:`aiohttp.client.request` `data` argument:: await aiohttp.post('http://example.com', data=mpwriter) Behind the scenes :meth:`MultipartWriter.serialize` will yield chunks of every part and if body part has `Content-Encoding` or `Content-Transfer-Encoding` they will be applied on streaming content. Please note, that on :meth:`MultipartWriter.serialize` all the file objects will be read until the end and there is no way to repeat a request without rewinding their pointers to the start. Hacking Multipart ----------------- The Internet is full of terror and sometimes you may find a server which implements multipart support in strange ways when an oblivious solution doesn't work. For instance, is server used `cgi.FieldStorage`_ then you have to ensure that no body part contains a `Content-Length` header:: for part in mpwriter: part.headers.pop(aiohttp.hdrs.CONTENT_LENGTH, None) On the other hand, some server may require to specify `Content-Length` for the whole multipart request. `aiohttp` doesn't do that since it sends multipart using chunked transfer encoding by default. To overcome this issue, you have to serialize a :class:`MultipartWriter` by our own in the way to calculate its size:: body = b''.join(mpwriter.serialize()) await aiohttp.post('http://example.com', data=body, headers=mpwriter.headers) Sometimes the server response may not be well formed: it may or may not contains nested parts. For instance, we request a resource which returns JSON documents with the files attached to it. If the document has any attachments, they are returned as a nested multipart. If it has not it responds as plain body parts:: CONTENT-TYPE: multipart/mixed; boundary=--: --: CONTENT-TYPE: application/json {"_id": "foo"} --: CONTENT-TYPE: multipart/related; boundary=----: ----: CONTENT-TYPE: application/json {"_id": "bar"} ----: CONTENT-TYPE: text/plain CONTENT-DISPOSITION: attachment; filename=bar.txt bar! bar! bar! ----:-- --: CONTENT-TYPE: application/json {"_id": "boo"} --: CONTENT-TYPE: multipart/related; boundary=----: ----: CONTENT-TYPE: application/json {"_id": "baz"} ----: CONTENT-TYPE: text/plain CONTENT-DISPOSITION: attachment; filename=baz.txt baz! baz! baz! ----:-- --:-- Reading such kind of data in single stream is possible, but is not clean at all:: result = [] while True: part = await reader.next() if part is None: break if isinstance(part, aiohttp.MultipartReader): # Fetching files while True: filepart = await part.next() if filepart is None: break result[-1].append((await filepart.read())) else: # Fetching document result.append([(await part.json())]) Let's hack a reader in the way to return pairs of document and reader of the related files on each iteration:: class PairsMultipartReader(aiohttp.MultipartReader): # keep reference on the original reader multipart_reader_cls = aiohttp.MultipartReader async def next(self): """Emits a tuple of document object (:class:`dict`) and multipart reader of the followed attachments (if any). :rtype: tuple """ reader = await super().next() if self._at_eof: return None, None if isinstance(reader, self.multipart_reader_cls): part = await reader.next() doc = await part.json() else: doc = await reader.json() return doc, reader And this gives us a more cleaner solution:: reader = PairsMultipartReader.from_response(resp) result = [] while True: doc, files_reader = await reader.next() if doc is None: break files = [] while True: filepart = await files_reader.next() if file.part is None: break files.append((await filepart.read())) result.append((doc, files)) .. seealso:: Multipart API in :ref:`aiohttp-api` section. .. _cgi.FieldStorage: https://docs.python.org/3.4/library/cgi.html .. _mimetypes: https://docs.python.org/3.4/library/mimetypes.html .. disqus:: aiohttp-0.20.2/docs/aiohttp-icon.ico0000664000175000017500000000627612552474754020103 0ustar andrewandrew00000000000000 ¨ ( @ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýùùùôôôñññððððððñññõõõùùùýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúñññîííðïîóòñôôóôôôôôôôôóôòññðïïîîóòòúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûðððïîíõôôëóøÖìù®Ýø¡Õ÷‰Î÷‚Ë÷™Ó÷¦ÙøËçùîôùõôôðïïòòòûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþöööîííõõôàïùªÙ÷vÃösÅøIµùG°úX»ûG¶ûS¸úA³ù\¼ø†É÷µÝøáïùöõõðïï÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþóóóðïïîõùžÖ÷U¹÷G¶úE¶û^¿üJ´ûNµû_½ülÂüJ²ûG²û[½ûV¼û_¿ûU¹÷žÖ÷íõùòñðõõõþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþóóóòñðäñú†Éö>²ù:³ûE¸ûB¶ûT¸üD¯ûU¹ûgÁýoÃýf¼úšÒùÂåûš×úU¾û9³û8®ùyÁöáïúôóòõõõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöööññðãñúxÄöP·úI¶û@´ûAµûL¸ûX¹ûA¯ûU¸üoÄþlÂý®ÛúþþþÿÿÿûýþÓû>´û@°û@®úo¿öãñúôóò÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúðïïñöúŒË÷M¶úH¸ûC±û8®û4¯ûTºûaÀûH·ûV¹ûkÂþoÃýÑëüÿÿÿÿÿÿÿÿÿµáýB³ûN¸ûH¸ûN¶ú•Ï÷ñ÷úòòñûûûÿÿÿÿÿÿÿÿÿþþþñññôö÷¬Ø÷vÂùZ¸úH´ûA¬û>¬û?±û[ºûfÀüL¶ûS¶û]»ü\ºü²Ýûÿÿÿÿÿÿþÿÿ¡ÙüO¶ûR¶ûL·ûR¶ûpÁú©×÷õ÷øôôôÿÿÿÿÿÿÿÿÿùùùóòòÏéù‡ÊõÞðüÇæü[¸úN³ûS¶ûU¶üI®ûo¿úNµú7®ûC³ûV»üb¿û§ÚüÕíþ©ÚýuÄýf¼üS³ûJ²û;°ûY¼üQ¶÷ÈæùöôôúúúÿÿÿÿÿÿóóóóöøÈö­ÝúÿÿÿýþÿÆûK±ûa¼ýh¿þÆúãñüÊèü_¿û_¿üT»û5­ûH¯ûaºûX¸ükÀþ[¸ý]¸ümÁüS¹û^¿üB´ú{ÆöôöøõõõÿÿÿüüüóòòÙìùJ³÷kÃûÙïþËêþg¿ü_»ü~Èþ‚ÊþÇæüÿÿÿûýÿ€Êü=±û<±û<®ûC¯ûS¶ü]ºýoÂþg¾ýN´ûR¸ûfÀüoÅüV¼ü\º÷ÙìùöõôýýýøøøöõôºÝøD­ú0«ûV¸ûg¿ü2¬ûJ²ûf¼ýoÁþ‡ÊüØîýÅæýO±û2ªû9®ûK³û?±ûYºüY¶ülÀþaºýO´ûE´ûV¶ûG±û>±û^ºú¸Ý÷ø÷öúúúõõôõö÷ŽÈöY´û>¬ûN²ûh½üB¯ûL±ûQ³ûX·üN²ûV¶ûe¼üH¬û>«ûG°ûO²ûH±ûc¼üO²ûX·üQ³ûM²ûH±û_·üD¬ûA®ûK°ûŠÈö÷øø÷÷÷ôóóðõùt¿öj¾üd»ýH­ü^¶üI°û6¬û7­û>°û4¬û5ªûQ²ûi½üZ·üP±ü>§ûI®û\»ü7­û>°û6­û3ªûJ¯ûg¼üUµûY¶ý=§ûj¹öñöùöööôóóéòù`µöbºü€Èþ[¶ýd¹üR³û@®û<¯ûD³û7­û8§û>§ûg¼üvÃþcºþG¬ûO±ûc»ûH³úKµúC±ú8©ûW³üT²ûaºýk¾þL®üf¸öìôúööõôôóèòù_·÷\·ý‚ÈþsÁþe½üI²ûD¯û8«û6¬û?®ûC®ûA®ûU´üƒÈþsÁþS´üN³ún¿÷ƒÆô‚Æó}Äôp¾öh½úJ°ûf»ýl¿þ\·ýdº÷êóú÷ööõôôìôùk¼öU²ün¾þŒÊûuÂúD°û=¨û5¦û3ªûL°ûK²ûH²ûR±ûh¼ý}Åýa¸úl½ö¡ÐòËâóËàôÍâôÂßó‰Éõ[¶ù]¶üh¼þU²ük¼öíõú÷÷ööööó÷ùv¿öD¬ûO±û¼àûÇåüH®ûB©ûB©ûD¬ûI­ûI­ûF®ûF­ûK°üR³ûtÀø¦ÒòÏàô§ªó€òóËÒ÷¼Ýôv¿öM°ûN±üD¬ûv¿öô÷úøøøøøøùøø‡Éö.§ú>®ûvÅüzÆüH¬ûL®ûW´ü\µý>¥ûC¨ûD­û0¨û9¬û<­úcºõÃßó²µôbbò``ò_^ò‚ƒóÑá÷‰ÉôB¯ú=®û.§ú‡ÉöúùùúúúüüüùøöºÞø;ªøNµûR¶ü:¨ûZ²üI¬ûa¸ýj¼þP¯üJ­ûM°û;«û>®ûD°úp½õÇàô•˜ô__òbbòaaòlmòÍ×øÑôM³ù@¯û:ªø¸Ýøûùøýýýþþþ÷÷öçñúW²öO´üB­û9¨û=¬û]·üe¹ýj»þ[´üG¯ûE¯û=¨û2§û7ªûo¼ö¼Þô¯´öbbò``ò_^ò‚ôÖäø¢Òõ]¸úM´ür¾÷éóúùùøÿÿÿÿÿÿúúùùùù¦Ó÷H®úD¬ûI­û4§ûZ´ûr¾ýd¸ýS¯ûJ®û?«û9¢û2¤û=ªûd·øžÐóÕä÷§©öôŽõÊÒø¾ßõr»÷B¨û;©ú¥Ó÷ûúúûûûÿÿÿÿÿÿþþþø÷÷çñúg¶öB§ûC§ûA©û=¨ûQ²ü`¸ü@ªû=¨ûA§ûD¨ûF©ûE©ûQ­û„Äø¨ÔôÇâöÐâøÎã÷Áàõ‰ÅöT®úD¨ûg¶öåñúúùøþþþÿÿÿÿÿÿÿÿÿúúúúùùÇâùN©ø<¢ûI«û3¦û3§ûP´ûO³ü5¤ûG§úT¯ú_´ýd¶ý[°üY±û]µør¿öŒÉõÄögºøg¶ûO­û^²øÇâùûúúüûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøøùúú¨Ó÷JªøK­ûAªû9©û<«ûE®ûx¿ùËåûÆäü‹ÉýxÀþN­üJ¬ûI¬û?«ûG¯úB­ú:¥ûHªûbµù®Ö÷ùúûúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþùøøöùûžÐöH­ø;¦û0¢û,£û?¨ûª×ûÿÿÿþÿÿŸÒýbµþO®üB¬û?©û5¢û,£û8§ûD«ûF¬ø¥Ó÷øúûúùùþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýùùø÷ùû±Ù÷SªöA¥úM¯üe·ü‰Çûßðþ×ìþˆÇý_³üLªûEªû:£û7Ÿû1¢ûC¨ú`²ö²Ú÷÷úûúúùþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþùùùûúúÞíúŸÎöb²ø?¢ú>¢ûN®ûAªûC«ûY´üO°ü>¦ûA¤ûE¦úX­øŠÃöÛìúüûûúúúþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûûúùøúûØêú˜É÷p·öX®÷7¤ø=¨ø?¨øH«øjµ÷}½ö£Ð÷ÛëúùúûüûúüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþûûûûúúüûûôøûäðúÏçùÇãùÇãùÍæùâïúöùûüûûüûúûûûþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþüüüûûúûúúüûùýûúýûúýûúüûúûûûüüüþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿ€ÿþø?ðààÀ€€€€€ÀààðøþÿÿÿÀÿaiohttp-0.20.2/CONTRIBUTORS.txt0000664000175000017500000000277512635573675016563 0ustar andrewandrew00000000000000Contributors ------------ A. Jesse Jiryu Davis Alejandro Gómez Alex Khomchenko Alex Lisovoy Alexander Bayandin Alexander Karpinsky Alexander Malev Alexander Shorin Alexander Travov Alexey Popravka Andrei Ursulenko Andrej Antonov Andrew Svetlov Anton Kasyanov Arthur Darcet Ben Bader Benedikt Reinartz Brian C. Lane Boris Feld Carl George Chien-Wei Huang Chih-Yuan Chen Chris Laws Chris Moore Daniel Nelson David Michael Brown Dima Veselov Dimitar Dimitrov Dmytro Kuznetsov Elizabeth Leddy Erich Healy Eugene Chernyshov Frederik Gladhorn Gabriel Tremblay Gennady Andreyev Georges Dubus Greg Holt Hugo Herter Igor Pavlov Ingmar Steen Jaesung Lee Jashandeep Sohi Jeroen van der Heijden Jesus Cea Joel Watts Julien Duponchelle Junjie Tao Kay Zheng Kirill Klenov Kirill Malovitsa Kyrylo Perevozchikov Lars P. Søndergaard Ludovic Gasc Lukasz Marcin Dobrzanski Marco Paolini Martin Richard Mathias Fröjdman Matthieu Hauglustaine Michael Ihnatenko Mikhail Lukyanchenko Morgan Delahaye-Prat Moss Collum Nicolas Braem Nikolay Novik Olaf Conradi Pankaj Pandey Paul Colomiets Philipp A. Raúl Cumplido "Required Field" Robert Lu Sebastian Hanula Sebastian Hüther Sergey Ninua Sergey Skripnick Simon Kennedy Stanislas Plum Stanislav Prokop Stephen Granade Sviatoslav Bulbakha Taras Voinarovskyi Tolga Tezel Thomas Grainger Vaibhav Sagar Vasyl Baran Vitalik Verhovodov Vitaly Haritonsky Vitaly Magerya Vladimir Rutsky Vladimir Shulyak Vladimir Zakharov W. Trevor King Yannick Koechlin Коренберг Марк aiohttp-0.20.2/aiohttp.egg-info/0000775000175000017500000000000012643555674017212 5ustar andrewandrew00000000000000aiohttp-0.20.2/aiohttp.egg-info/requires.txt0000664000175000017500000000001012643555664021600 0ustar andrewandrew00000000000000chardet aiohttp-0.20.2/aiohttp.egg-info/dependency_links.txt0000664000175000017500000000000112643555664023257 0ustar andrewandrew00000000000000 aiohttp-0.20.2/aiohttp.egg-info/SOURCES.txt0000664000175000017500000000657412643555674021112 0ustar andrewandrew00000000000000CHANGES.txt CONTRIBUTORS.txt LICENSE.txt MANIFEST.in Makefile README.rst setup.cfg setup.py aiohttp/__init__.py aiohttp/_multidict.c aiohttp/_multidict.pyx aiohttp/_websocket.c aiohttp/_websocket.pyx aiohttp/abc.py aiohttp/client.py aiohttp/client_reqrep.py aiohttp/connector.py aiohttp/errors.py aiohttp/hdrs.py aiohttp/helpers.py aiohttp/log.py aiohttp/multidict.py aiohttp/multipart.py aiohttp/parsers.py aiohttp/protocol.py aiohttp/server.py aiohttp/signals.py aiohttp/streams.py aiohttp/test_utils.py aiohttp/web.py aiohttp/web_exceptions.py aiohttp/web_reqrep.py aiohttp/web_urldispatcher.py aiohttp/web_ws.py aiohttp/websocket.py aiohttp/websocket_client.py aiohttp/worker.py aiohttp/wsgi.py aiohttp.egg-info/PKG-INFO aiohttp.egg-info/SOURCES.txt aiohttp.egg-info/dependency_links.txt aiohttp.egg-info/pbr.json aiohttp.egg-info/requires.txt aiohttp.egg-info/top_level.txt docs/Makefile docs/aiohttp-icon.ico docs/aiohttp-icon.svg docs/aiohttp_doctools.py docs/api.rst docs/changes.rst docs/client.rst docs/client_reference.rst docs/conf.py docs/contributing.rst docs/glossary.rst docs/gunicorn.rst docs/index.rst docs/logging.rst docs/make.bat docs/multidict.rst docs/multipart.rst docs/python33.rst docs/server.rst docs/spelling_wordlist.txt docs/web.rst docs/web_reference.rst docs/_static/aiohttp-icon-128x128.png docs/_static/aiohttp-icon-32x32.png docs/_static/aiohttp-icon-64x64.png docs/_static/aiohttp-icon-96x96.png examples/basic_srv.py examples/client_auth.py examples/client_json.py examples/crawl.py examples/curl.py examples/mpsrv.py examples/srv.py examples/tcp_protocol_parser.py examples/web_classview1.py examples/web_cookies.py examples/web_rewrite_headers_middleware.py examples/web_srv.py examples/web_ws.py examples/websocket.html examples/wsclient.py examples/wssrv.py tests/conftest.py tests/data.unknown_mime_type tests/hello.txt.gz tests/sample.crt tests/sample.crt.der tests/sample.key tests/software_development_in_picture.jpg tests/test_classbasedview.py tests/test_client_connection.py tests/test_client_functional.py tests/test_client_functional_oldstyle.py tests/test_client_request.py tests/test_client_response.py tests/test_client_session.py tests/test_connector.py tests/test_errors.py tests/test_flowcontrol_streams.py tests/test_helpers.py tests/test_http_parser.py tests/test_multidict.py tests/test_multipart.py tests/test_parser_buffer.py tests/test_protocol.py tests/test_proxy_connector.py tests/test_server.py tests/test_signals.py tests/test_stream_parser.py tests/test_stream_protocol.py tests/test_stream_writer.py tests/test_streams.py tests/test_timeout.py tests/test_urldispatch.py tests/test_web_application.py tests/test_web_exceptions.py tests/test_web_functional.py tests/test_web_middleware.py tests/test_web_request.py tests/test_web_request_handler.py tests/test_web_response.py tests/test_web_websocket.py tests/test_web_websocket_functional.py tests/test_websocket_client.py tests/test_websocket_client_functional.py tests/test_websocket_handshake.py tests/test_websocket_parser.py tests/test_websocket_writer.py tests/test_worker.py tests/test_wsgi.py tests/autobahn/client.py tests/autobahn/fuzzingclient.json tests/autobahn/fuzzingserver.json tests/autobahn/server.py tests/test_py35/test_cbv35.py tests/test_py35/test_client_websocket_35.py tests/test_py35/test_multipart_35.py tests/test_py35/test_resp.py tests/test_py35/test_streams_35.py tests/test_py35/test_web_websocket_35.pyaiohttp-0.20.2/aiohttp.egg-info/top_level.txt0000664000175000017500000000001012643555664021732 0ustar andrewandrew00000000000000aiohttp aiohttp-0.20.2/aiohttp.egg-info/PKG-INFO0000664000175000017500000001344212643555664020312 0ustar andrewandrew00000000000000Metadata-Version: 1.1 Name: aiohttp Version: 0.20.2 Summary: http client/server for asyncio Home-page: https://github.com/KeepSafe/aiohttp/ Author: Andrew Svetlov Author-email: andrew.svetlov@gmail.com License: Apache 2 Description: http client/server for asyncio ============================== .. image:: https://raw.github.com/KeepSafe/aiohttp/master/docs/_static/aiohttp-icon-128x128.png :height: 64px :width: 64px :alt: aiohttp logo .. image:: https://travis-ci.org/KeepSafe/aiohttp.svg?branch=master :target: https://travis-ci.org/KeepSafe/aiohttp :align: right .. image:: https://coveralls.io/repos/KeepSafe/aiohttp/badge.svg?branch=master&service=github :target: https://coveralls.io/github/KeepSafe/aiohttp?branch=master :align: right .. image:: https://badge.fury.io/py/aiohttp.svg :target: https://badge.fury.io/py/aiohttp Features -------- - Supports both client and server side of HTTP protocol. - Supports both client and server Web-Sockets out-of-the-box. - Web-server has middlewares and pluggable routing. Getting started --------------- Client ^^^^^^ To retrieve something from the web: .. code-block:: python import aiohttp import asyncio async def get_body(client, url): async with client.get(url) as response: return await response.read() if __name__ == '__main__': loop = asyncio.get_event_loop() client = aiohttp.ClientSession(loop=loop) raw_html = loop.run_until_complete(get_body(client, 'http://python.org')) print(raw_html) client.close() If you want to use timeouts for aiohttp client please use standard asyncio approach: .. code-block:: python yield from asyncio.wait_for(client.get(url), 10) Server ^^^^^^ This is simple usage example: .. code-block:: python import asyncio from aiohttp import web async def handle(request): name = request.match_info.get('name', "Anonymous") text = "Hello, " + name return web.Response(body=text.encode('utf-8')) async def wshandler(request): ws = web.WebSocketResponse() await ws.prepare(request) async for msg in ws: if msg.tp == web.MsgType.text: ws.send_str("Hello, {}".format(msg.data)) elif msg.tp == web.MsgType.binary: ws.send_bytes(msg.data) elif msg.tp == web.MsgType.close: break return ws async def init(loop): app = web.Application(loop=loop) app.router.add_route('GET', '/echo', wshandler) app.router.add_route('GET', '/{name}', handle) srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8080) print("Server started at http://127.0.0.1:8080") return srv loop = asyncio.get_event_loop() loop.run_until_complete(init(loop)) loop.run_forever() Note: examples are written for Python 3.5+ and utilize PEP-492 aka async/await. If you are using Python 3.4 please replace ``await`` with ``yield from`` and ``async def`` with ``@coroutine`` e.g.:: async def coro(...): ret = await f() shoud be replaced by:: @asyncio.coroutine def coro(...): ret = yield from f() Documentation ------------- http://aiohttp.readthedocs.org/ Discussion list --------------- *aio-libs* google group: https://groups.google.com/forum/#!forum/aio-libs Requirements ------------ - Python >= 3.4.1 - chardet https://pypi.python.org/pypi/chardet Optionally you may install cChardet library: https://pypi.python.org/pypi/cchardet/1.0.0 License ------- ``aiohttp`` is offered under the Apache 2 license. Source code ------------ The latest developer version is available in a github repository: https://github.com/KeepSafe/aiohttp Benchmarks ---------- If you are interested in by efficiency, AsyncIO community maintains a list of benchmarks on the official wiki: https://github.com/python/asyncio/wiki/Benchmarks CHANGES ======= 0.20.2 (01-07-2015) -------------------- - Enable use of `await` for a class based view #717 - Check address family to fill wsgi env properly #718 - Fix memory leak in headers processing (thanks to Marco Paolini) #723 Platform: UNKNOWN Classifier: License :: OSI Approved :: Apache Software License Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Topic :: Internet :: WWW/HTTP aiohttp-0.20.2/aiohttp.egg-info/pbr.json0000664000175000017500000000005712611755232020655 0ustar andrewandrew00000000000000{"git_version": "bf5f5ca", "is_release": false}aiohttp-0.20.2/README.rst0000664000175000017500000000725412634502617015534 0ustar andrewandrew00000000000000http client/server for asyncio ============================== .. image:: https://raw.github.com/KeepSafe/aiohttp/master/docs/_static/aiohttp-icon-128x128.png :height: 64px :width: 64px :alt: aiohttp logo .. image:: https://travis-ci.org/KeepSafe/aiohttp.svg?branch=master :target: https://travis-ci.org/KeepSafe/aiohttp :align: right .. image:: https://coveralls.io/repos/KeepSafe/aiohttp/badge.svg?branch=master&service=github :target: https://coveralls.io/github/KeepSafe/aiohttp?branch=master :align: right .. image:: https://badge.fury.io/py/aiohttp.svg :target: https://badge.fury.io/py/aiohttp Features -------- - Supports both client and server side of HTTP protocol. - Supports both client and server Web-Sockets out-of-the-box. - Web-server has middlewares and pluggable routing. Getting started --------------- Client ^^^^^^ To retrieve something from the web: .. code-block:: python import aiohttp import asyncio async def get_body(client, url): async with client.get(url) as response: return await response.read() if __name__ == '__main__': loop = asyncio.get_event_loop() client = aiohttp.ClientSession(loop=loop) raw_html = loop.run_until_complete(get_body(client, 'http://python.org')) print(raw_html) client.close() If you want to use timeouts for aiohttp client please use standard asyncio approach: .. code-block:: python yield from asyncio.wait_for(client.get(url), 10) Server ^^^^^^ This is simple usage example: .. code-block:: python import asyncio from aiohttp import web async def handle(request): name = request.match_info.get('name', "Anonymous") text = "Hello, " + name return web.Response(body=text.encode('utf-8')) async def wshandler(request): ws = web.WebSocketResponse() await ws.prepare(request) async for msg in ws: if msg.tp == web.MsgType.text: ws.send_str("Hello, {}".format(msg.data)) elif msg.tp == web.MsgType.binary: ws.send_bytes(msg.data) elif msg.tp == web.MsgType.close: break return ws async def init(loop): app = web.Application(loop=loop) app.router.add_route('GET', '/echo', wshandler) app.router.add_route('GET', '/{name}', handle) srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8080) print("Server started at http://127.0.0.1:8080") return srv loop = asyncio.get_event_loop() loop.run_until_complete(init(loop)) loop.run_forever() Note: examples are written for Python 3.5+ and utilize PEP-492 aka async/await. If you are using Python 3.4 please replace ``await`` with ``yield from`` and ``async def`` with ``@coroutine`` e.g.:: async def coro(...): ret = await f() shoud be replaced by:: @asyncio.coroutine def coro(...): ret = yield from f() Documentation ------------- http://aiohttp.readthedocs.org/ Discussion list --------------- *aio-libs* google group: https://groups.google.com/forum/#!forum/aio-libs Requirements ------------ - Python >= 3.4.1 - chardet https://pypi.python.org/pypi/chardet Optionally you may install cChardet library: https://pypi.python.org/pypi/cchardet/1.0.0 License ------- ``aiohttp`` is offered under the Apache 2 license. Source code ------------ The latest developer version is available in a github repository: https://github.com/KeepSafe/aiohttp Benchmarks ---------- If you are interested in by efficiency, AsyncIO community maintains a list of benchmarks on the official wiki: https://github.com/python/asyncio/wiki/Benchmarks aiohttp-0.20.2/aiohttp/0000775000175000017500000000000012643555674015520 5ustar andrewandrew00000000000000aiohttp-0.20.2/aiohttp/server.py0000664000175000017500000003343512643555212017374 0ustar andrewandrew00000000000000"""simple http server.""" import asyncio import http.server import traceback import socket from html import escape as html_escape from math import ceil import aiohttp from aiohttp import errors, streams, hdrs, helpers from aiohttp.log import server_logger from aiohttp.helpers import ensure_future __all__ = ('ServerHttpProtocol',) RESPONSES = http.server.BaseHTTPRequestHandler.responses DEFAULT_ERROR_MESSAGE = """ {status} {reason}

{status} {reason}

{message} """ if hasattr(socket, 'SO_KEEPALIVE'): def tcp_keepalive(server, transport): sock = transport.get_extra_info('socket') sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) else: def tcp_keepalive(server, transport): # pragma: no cover pass EMPTY_PAYLOAD = streams.EmptyStreamReader() class ServerHttpProtocol(aiohttp.StreamProtocol): """Simple http protocol implementation. ServerHttpProtocol handles incoming http request. It reads request line, request headers and request payload and calls handle_request() method. By default it always returns with 404 response. ServerHttpProtocol handles errors in incoming request, like bad status line, bad headers or incomplete payload. If any error occurs, connection gets closed. :param keep_alive: number of seconds before closing keep-alive connection :type keep_alive: int or None :param bool keep_alive_on: keep-alive is o, default is on :param int timeout: slow request timeout :param allowed_methods: (optional) List of allowed request methods. Set to empty list to allow all methods. :type allowed_methods: tuple :param bool debug: enable debug mode :param logger: custom logger object :type logger: aiohttp.log.server_logger :param access_log: custom logging object :type access_log: aiohttp.log.server_logger :param str access_log_format: access log format string :param loop: Optional event loop """ _request_count = 0 _request_handler = None _reading_request = False _keep_alive = False # keep transport open _keep_alive_handle = None # keep alive timer handle _timeout_handle = None # slow request timer handle _request_prefix = aiohttp.HttpPrefixParser() # http method parser _request_parser = aiohttp.HttpRequestParser() # default request parser def __init__(self, *, loop=None, keep_alive=75, # NGINX default value is 75 secs keep_alive_on=True, timeout=0, logger=server_logger, access_log=None, access_log_format=helpers.AccessLogger.LOG_FORMAT, debug=False, log=None, **kwargs): super().__init__( loop=loop, disconnect_error=errors.ClientDisconnectedError, **kwargs) self._keep_alive_on = keep_alive_on self._keep_alive_period = keep_alive # number of seconds to keep alive self._timeout = timeout # slow request timeout self._loop = loop if loop is not None else asyncio.get_event_loop() self.logger = log or logger self.debug = debug self.access_log = access_log if access_log: self.access_logger = helpers.AccessLogger(access_log, access_log_format) else: self.access_logger = None @property def keep_alive_timeout(self): return self._keep_alive_period def closing(self, timeout=15.0): """Worker process is about to exit, we need cleanup everything and stop accepting requests. It is especially important for keep-alive connections.""" self._keep_alive = False self._keep_alive_on = False self._keep_alive_period = None if (not self._reading_request and self.transport is not None): if self._request_handler: self._request_handler.cancel() self._request_handler = None self.transport.close() self.transport = None elif self.transport is not None and timeout: if self._timeout_handle is not None: self._timeout_handle.cancel() # use slow request timeout for closing # connection_lost cleans timeout handler now = self._loop.time() self._timeout_handle = self._loop.call_at( ceil(now+timeout), self.cancel_slow_request) def connection_made(self, transport): super().connection_made(transport) self._request_handler = ensure_future(self.start(), loop=self._loop) # start slow request timer if self._timeout: now = self._loop.time() self._timeout_handle = self._loop.call_at( ceil(now+self._timeout), self.cancel_slow_request) if self._keep_alive_on: tcp_keepalive(self, transport) def connection_lost(self, exc): super().connection_lost(exc) if self._request_handler is not None: self._request_handler.cancel() self._request_handler = None if self._keep_alive_handle is not None: self._keep_alive_handle.cancel() self._keep_alive_handle = None if self._timeout_handle is not None: self._timeout_handle.cancel() self._timeout_handle = None def data_received(self, data): super().data_received(data) # reading request if not self._reading_request: self._reading_request = True # stop keep-alive timer if self._keep_alive_handle is not None: self._keep_alive_handle.cancel() self._keep_alive_handle = None def keep_alive(self, val): """Set keep-alive connection mode. :param bool val: new state. """ self._keep_alive = val def log_access(self, message, environ, response, time): if self.access_logger: self.access_logger.log(message, environ, response, self.transport, time) def log_debug(self, *args, **kw): if self.debug: self.logger.debug(*args, **kw) def log_exception(self, *args, **kw): self.logger.exception(*args, **kw) def cancel_slow_request(self): if self._request_handler is not None: self._request_handler.cancel() self._request_handler = None if self.transport is not None: self.transport.close() self.log_debug('Close slow request.') @asyncio.coroutine def start(self): """Start processing of incoming requests. It reads request line, request headers and request payload, then calls handle_request() method. Subclass has to override handle_request(). start() handles various exceptions in request or response handling. Connection is being closed always unless keep_alive(True) specified. """ reader = self.reader while True: message = None self._keep_alive = False self._request_count += 1 self._reading_request = False payload = None try: # read http request method prefix = reader.set_parser(self._request_prefix) yield from prefix.read() # start reading request self._reading_request = True # start slow request timer if self._timeout and self._timeout_handle is None: now = self._loop.time() self._timeout_handle = self._loop.call_at( ceil(now+self._timeout), self.cancel_slow_request) # read request headers httpstream = reader.set_parser(self._request_parser) message = yield from httpstream.read() # cancel slow request timer if self._timeout_handle is not None: self._timeout_handle.cancel() self._timeout_handle = None # request may not have payload if (message.headers.get(hdrs.CONTENT_LENGTH, 0) or hdrs.SEC_WEBSOCKET_KEY1 in message.headers or 'chunked' in message.headers.get( hdrs.TRANSFER_ENCODING, '')): payload = streams.FlowControlStreamReader( reader, loop=self._loop) reader.set_parser( aiohttp.HttpPayloadParser(message), payload) else: payload = EMPTY_PAYLOAD yield from self.handle_request(message, payload) except asyncio.CancelledError: return except errors.ClientDisconnectedError: self.log_debug( 'Ignored premature client disconnection #1.') return except errors.HttpProcessingError as exc: if self.transport is not None: yield from self.handle_error(exc.code, message, None, exc, exc.headers, exc.message) except errors.LineLimitExceededParserError as exc: yield from self.handle_error(400, message, None, exc) except Exception as exc: yield from self.handle_error(500, message, None, exc) finally: if self.transport is None: self.log_debug( 'Ignored premature client disconnection #2.') return if payload and not payload.is_eof(): self.log_debug('Uncompleted request.') self._request_handler = None self.transport.close() return else: reader.unset_parser() if self._request_handler: if self._keep_alive and self._keep_alive_period: self.log_debug( 'Start keep-alive timer for %s sec.', self._keep_alive_period) now = self._loop.time() self._keep_alive_handle = self._loop.call_at( ceil(now+self._keep_alive_period), self.transport.close) elif self._keep_alive and self._keep_alive_on: # do nothing, rely on kernel or upstream server pass else: self.log_debug('Close client connection.') self._request_handler = None self.transport.close() return else: # connection is closed return def handle_error(self, status=500, message=None, payload=None, exc=None, headers=None, reason=None): """Handle errors. Returns http response with specific status code. Logs additional information. It always closes current connection.""" now = self._loop.time() try: if self._request_handler is None: # client has been disconnected during writing. return () if status == 500: self.log_exception("Error handling request") try: if reason is None or reason == '': reason, msg = RESPONSES[status] else: msg = reason except KeyError: status = 500 reason, msg = '???', '' if self.debug and exc is not None: try: tb = traceback.format_exc() tb = html_escape(tb) msg += '

Traceback:

\n
{}
'.format(tb) except: pass html = DEFAULT_ERROR_MESSAGE.format( status=status, reason=reason, message=msg).encode('utf-8') response = aiohttp.Response(self.writer, status, close=True) response.add_header(hdrs.CONTENT_TYPE, 'text/html; charset=utf-8') response.add_header(hdrs.CONTENT_LENGTH, str(len(html))) if headers is not None: for name, value in headers: response.add_header(name, value) response.send_headers() response.write(html) # disable CORK, enable NODELAY if needed self.writer.set_tcp_nodelay(True) drain = response.write_eof() self.log_access(message, None, response, self._loop.time() - now) return drain finally: self.keep_alive(False) def handle_request(self, message, payload): """Handle a single http request. Subclass should override this method. By default it always returns 404 response. :param message: Request headers :type message: aiohttp.protocol.HttpRequestParser :param payload: Request payload :type payload: aiohttp.streams.FlowControlStreamReader """ now = self._loop.time() response = aiohttp.Response( self.writer, 404, http_version=message.version, close=True) body = b'Page Not Found!' response.add_header(hdrs.CONTENT_TYPE, 'text/plain') response.add_header(hdrs.CONTENT_LENGTH, str(len(body))) response.send_headers() response.write(body) drain = response.write_eof() self.keep_alive(False) self.log_access(message, None, response, self._loop.time() - now) return drain aiohttp-0.20.2/aiohttp/web_exceptions.py0000664000175000017500000001721112631631567021103 0ustar andrewandrew00000000000000from .web_reqrep import Response __all__ = ( 'HTTPException', 'HTTPError', 'HTTPRedirection', 'HTTPSuccessful', 'HTTPOk', 'HTTPCreated', 'HTTPAccepted', 'HTTPNonAuthoritativeInformation', 'HTTPNoContent', 'HTTPResetContent', 'HTTPPartialContent', 'HTTPMultipleChoices', 'HTTPMovedPermanently', 'HTTPFound', 'HTTPSeeOther', 'HTTPNotModified', 'HTTPUseProxy', 'HTTPTemporaryRedirect', 'HTTPPermanentRedirect', 'HTTPClientError', 'HTTPBadRequest', 'HTTPUnauthorized', 'HTTPPaymentRequired', 'HTTPForbidden', 'HTTPNotFound', 'HTTPMethodNotAllowed', 'HTTPNotAcceptable', 'HTTPProxyAuthenticationRequired', 'HTTPRequestTimeout', 'HTTPConflict', 'HTTPGone', 'HTTPLengthRequired', 'HTTPPreconditionFailed', 'HTTPRequestEntityTooLarge', 'HTTPRequestURITooLong', 'HTTPUnsupportedMediaType', 'HTTPRequestRangeNotSatisfiable', 'HTTPExpectationFailed', 'HTTPMisdirectedRequest', 'HTTPUpgradeRequired', 'HTTPPreconditionRequired', 'HTTPTooManyRequests', 'HTTPRequestHeaderFieldsTooLarge', 'HTTPServerError', 'HTTPInternalServerError', 'HTTPNotImplemented', 'HTTPBadGateway', 'HTTPServiceUnavailable', 'HTTPGatewayTimeout', 'HTTPVersionNotSupported', 'HTTPVariantAlsoNegotiates', 'HTTPNotExtended', 'HTTPNetworkAuthenticationRequired', ) ############################################################ # HTTP Exceptions ############################################################ class HTTPException(Response, Exception): # You should set in subclasses: # status = 200 status_code = None empty_body = False def __init__(self, *, headers=None, reason=None, body=None, text=None, content_type=None): Response.__init__(self, status=self.status_code, headers=headers, reason=reason, body=body, text=text, content_type=content_type) Exception.__init__(self, self.reason) if self.body is None and not self.empty_body: self.text = "{}: {}".format(self.status, self.reason) class HTTPError(HTTPException): """Base class for exceptions with status codes in the 400s and 500s.""" class HTTPRedirection(HTTPException): """Base class for exceptions with status codes in the 300s.""" class HTTPSuccessful(HTTPException): """Base class for exceptions with status codes in the 200s.""" class HTTPOk(HTTPSuccessful): status_code = 200 class HTTPCreated(HTTPSuccessful): status_code = 201 class HTTPAccepted(HTTPSuccessful): status_code = 202 class HTTPNonAuthoritativeInformation(HTTPSuccessful): status_code = 203 class HTTPNoContent(HTTPSuccessful): status_code = 204 empty_body = True class HTTPResetContent(HTTPSuccessful): status_code = 205 empty_body = True class HTTPPartialContent(HTTPSuccessful): status_code = 206 ############################################################ # 3xx redirection ############################################################ class _HTTPMove(HTTPRedirection): def __init__(self, location, *, headers=None, reason=None, body=None, text=None, content_type=None): if not location: raise ValueError("HTTP redirects need a location to redirect to.") super().__init__(headers=headers, reason=reason, body=body, text=text, content_type=content_type) self.headers['Location'] = location self.location = location class HTTPMultipleChoices(_HTTPMove): status_code = 300 class HTTPMovedPermanently(_HTTPMove): status_code = 301 class HTTPFound(_HTTPMove): status_code = 302 # This one is safe after a POST (the redirected location will be # retrieved with GET): class HTTPSeeOther(_HTTPMove): status_code = 303 class HTTPNotModified(HTTPRedirection): # FIXME: this should include a date or etag header status_code = 304 empty_body = True class HTTPUseProxy(_HTTPMove): # Not a move, but looks a little like one status_code = 305 class HTTPTemporaryRedirect(_HTTPMove): status_code = 307 class HTTPPermanentRedirect(_HTTPMove): status_code = 308 ############################################################ # 4xx client error ############################################################ class HTTPClientError(HTTPError): pass class HTTPBadRequest(HTTPClientError): status_code = 400 class HTTPUnauthorized(HTTPClientError): status_code = 401 class HTTPPaymentRequired(HTTPClientError): status_code = 402 class HTTPForbidden(HTTPClientError): status_code = 403 class HTTPNotFound(HTTPClientError): status_code = 404 class HTTPMethodNotAllowed(HTTPClientError): status_code = 405 def __init__(self, method, allowed_methods, *, headers=None, reason=None, body=None, text=None, content_type=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.method = method.upper() class HTTPNotAcceptable(HTTPClientError): status_code = 406 class HTTPProxyAuthenticationRequired(HTTPClientError): status_code = 407 class HTTPRequestTimeout(HTTPClientError): status_code = 408 class HTTPConflict(HTTPClientError): status_code = 409 class HTTPGone(HTTPClientError): status_code = 410 class HTTPLengthRequired(HTTPClientError): status_code = 411 class HTTPPreconditionFailed(HTTPClientError): status_code = 412 class HTTPRequestEntityTooLarge(HTTPClientError): status_code = 413 class HTTPRequestURITooLong(HTTPClientError): status_code = 414 class HTTPUnsupportedMediaType(HTTPClientError): status_code = 415 class HTTPRequestRangeNotSatisfiable(HTTPClientError): status_code = 416 class HTTPExpectationFailed(HTTPClientError): status_code = 417 class HTTPMisdirectedRequest(HTTPClientError): status_code = 421 class HTTPUpgradeRequired(HTTPClientError): status_code = 426 class HTTPPreconditionRequired(HTTPClientError): status_code = 428 class HTTPTooManyRequests(HTTPClientError): status_code = 429 class HTTPRequestHeaderFieldsTooLarge(HTTPClientError): status_code = 431 ############################################################ # 5xx Server Error ############################################################ # Response status codes beginning with the digit "5" indicate cases in # which the server is aware that it has erred or is incapable of # performing the request. Except when responding to a HEAD request, the # server SHOULD include an entity containing an explanation of the error # situation, and whether it is a temporary or permanent condition. User # agents SHOULD display any included entity to the user. These response # codes are applicable to any request method. class HTTPServerError(HTTPError): pass class HTTPInternalServerError(HTTPServerError): status_code = 500 class HTTPNotImplemented(HTTPServerError): status_code = 501 class HTTPBadGateway(HTTPServerError): status_code = 502 class HTTPServiceUnavailable(HTTPServerError): status_code = 503 class HTTPGatewayTimeout(HTTPServerError): status_code = 504 class HTTPVersionNotSupported(HTTPServerError): status_code = 505 class HTTPVariantAlsoNegotiates(HTTPServerError): status_code = 506 class HTTPNotExtended(HTTPServerError): status_code = 510 class HTTPNetworkAuthenticationRequired(HTTPServerError): status_code = 511 aiohttp-0.20.2/aiohttp/abc.py0000664000175000017500000000171612642312654016610 0ustar andrewandrew00000000000000import asyncio import sys from abc import ABCMeta, abstractmethod PY_35 = sys.version_info >= (3, 5) class AbstractRouter(metaclass=ABCMeta): @asyncio.coroutine # pragma: no branch @abstractmethod def resolve(self, request): """Return MATCH_INFO for given request""" class AbstractMatchInfo(metaclass=ABCMeta): @property # pragma: no branch @abstractmethod def handler(self): """Return handler for match info""" @property # pragma: no branch @abstractmethod def route(self): """Return route for match info""" class AbstractView(metaclass=ABCMeta): def __init__(self, request): self._request = request @property def request(self): return self._request @asyncio.coroutine @abstractmethod def __iter__(self): while False: # pragma: no cover yield None if PY_35: @abstractmethod def __await__(self): return aiohttp-0.20.2/aiohttp/errors.py0000664000175000017500000001065212637747134017407 0ustar andrewandrew00000000000000"""http related errors.""" from asyncio import TimeoutError __all__ = ( 'DisconnectedError', 'ClientDisconnectedError', 'ServerDisconnectedError', 'HttpProcessingError', 'BadHttpMessage', 'HttpMethodNotAllowed', 'HttpBadRequest', 'HttpProxyError', 'BadStatusLine', 'LineTooLong', 'InvalidHeader', 'ClientError', 'ClientHttpProcessingError', 'ClientConnectionError', 'ClientOSError', 'ClientTimeoutError', 'ProxyConnectionError', 'ClientRequestError', 'ClientResponseError', 'FingerprintMismatch', 'WSServerHandshakeError', 'WSClientDisconnectedError') class DisconnectedError(Exception): """Disconnected.""" class ClientDisconnectedError(DisconnectedError): """Client disconnected.""" class ServerDisconnectedError(DisconnectedError): """Server disconnected.""" class WSClientDisconnectedError(ClientDisconnectedError): """Deprecated.""" class ClientError(Exception): """Base class for client connection errors.""" class ClientHttpProcessingError(ClientError): """Base class for client http processing errors.""" class ClientRequestError(ClientHttpProcessingError): """Connection error during sending request.""" class ClientResponseError(ClientHttpProcessingError): """Connection error during reading response.""" class ClientConnectionError(ClientError): """Base class for client socket errors.""" class ClientOSError(ClientConnectionError, OSError): """OSError error.""" class ClientTimeoutError(ClientConnectionError, TimeoutError): """Client connection timeout error.""" class ProxyConnectionError(ClientConnectionError): """Proxy connection error. Raised in :class:`aiohttp.connector.ProxyConnector` if connection to proxy can not be established. """ class HttpProcessingError(Exception): """Http error. Shortcut for raising http errors with custom code, message and headers. :param int code: HTTP Error code. :param str message: (optional) Error message. :param list of [tuple] headers: (optional) Headers to be sent in response. """ code = 0 message = '' headers = None def __init__(self, *, code=None, message='', headers=None): if code is not None: self.code = code self.headers = headers self.message = message super().__init__("%s, message='%s'" % (self.code, message)) class WSServerHandshakeError(HttpProcessingError): """websocket server handshake error.""" class HttpProxyError(HttpProcessingError): """Http proxy error. Raised in :class:`aiohttp.connector.ProxyConnector` if proxy responds with status other than ``200 OK`` on ``CONNECT`` request. """ class BadHttpMessage(HttpProcessingError): code = 400 message = 'Bad Request' def __init__(self, message, *, headers=None): super().__init__(message=message, headers=headers) class HttpMethodNotAllowed(HttpProcessingError): code = 405 message = 'Method Not Allowed' class HttpBadRequest(BadHttpMessage): code = 400 message = 'Bad Request' class ContentEncodingError(BadHttpMessage): """Content encoding error.""" class TransferEncodingError(BadHttpMessage): """transfer encoding error.""" class LineTooLong(BadHttpMessage): def __init__(self, line, limit='Unknown'): super().__init__( "got more than %s bytes when reading %s" % (limit, line)) class InvalidHeader(BadHttpMessage): def __init__(self, hdr): super().__init__('Invalid HTTP Header: {}'.format(hdr)) self.hdr = hdr class BadStatusLine(BadHttpMessage): def __init__(self, line=''): if not line: line = repr(line) self.args = line, self.line = line class ParserError(Exception): """Base parser error.""" class LineLimitExceededParserError(ParserError): """Line is too long.""" def __init__(self, msg, limit): super().__init__(msg) self.limit = limit class FingerprintMismatch(ClientConnectionError): """SSL certificate does not match expected fingerprint.""" def __init__(self, expected, got, host, port): self.expected = expected self.got = got self.host = host self.port = port def __repr__(self): return '<{} expected={} got={} host={} port={}>'.format( self.__class__.__name__, self.expected, self.got, self.host, self.port) class InvalidURL(Exception): """Invalid URL.""" aiohttp-0.20.2/aiohttp/log.py0000664000175000017500000000050612624767531016650 0ustar andrewandrew00000000000000import logging access_logger = logging.getLogger('aiohttp.access') client_logger = logging.getLogger('aiohttp.client') internal_logger = logging.getLogger('aiohttp.internal') server_logger = logging.getLogger('aiohttp.server') web_logger = logging.getLogger('aiohttp.web') ws_logger = logging.getLogger('aiohttp.websocket') aiohttp-0.20.2/aiohttp/wsgi.py0000664000175000017500000001662612643555212017042 0ustar andrewandrew00000000000000"""wsgi server. TODO: * proxy protocol * x-forward security * wsgi file support (os.sendfile) """ import asyncio import inspect import io import os import socket import sys from urllib.parse import urlsplit import aiohttp from aiohttp import server, hdrs __all__ = ('WSGIServerHttpProtocol',) class WSGIServerHttpProtocol(server.ServerHttpProtocol): """HTTP Server that implements the Python WSGI protocol. It uses 'wsgi.async' of 'True'. 'wsgi.input' can behave differently depends on 'readpayload' constructor parameter. If readpayload is set to True, wsgi server reads all incoming data into BytesIO object and sends it as 'wsgi.input' environ var. If readpayload is set to false 'wsgi.input' is a StreamReader and application should read incoming data with "yield from environ['wsgi.input'].read()". It defaults to False. """ SCRIPT_NAME = os.environ.get('SCRIPT_NAME', '') def __init__(self, app, readpayload=False, is_ssl=False, *args, **kw): super().__init__(*args, **kw) self.wsgi = app self.is_ssl = is_ssl self.readpayload = readpayload def create_wsgi_response(self, message): return WsgiResponse(self.writer, message) def create_wsgi_environ(self, message, payload): uri_parts = urlsplit(message.path) environ = { 'wsgi.input': payload, 'wsgi.errors': sys.stderr, 'wsgi.version': (1, 0), 'wsgi.async': True, 'wsgi.multithread': False, 'wsgi.multiprocess': False, 'wsgi.run_once': False, 'wsgi.file_wrapper': FileWrapper, 'SERVER_SOFTWARE': aiohttp.HttpMessage.SERVER_SOFTWARE, 'REQUEST_METHOD': message.method, 'QUERY_STRING': uri_parts.query or '', 'RAW_URI': message.path, 'SERVER_PROTOCOL': 'HTTP/%s.%s' % message.version } script_name = self.SCRIPT_NAME for hdr_name, hdr_value in message.headers.items(): if hdr_name == 'SCRIPT_NAME': script_name = hdr_value elif hdr_name == 'CONTENT-TYPE': environ['CONTENT_TYPE'] = hdr_value continue elif hdr_name == 'CONTENT-LENGTH': environ['CONTENT_LENGTH'] = hdr_value continue key = 'HTTP_%s' % hdr_name.replace('-', '_') if key in environ: hdr_value = '%s,%s' % (environ[key], hdr_value) environ[key] = hdr_value url_scheme = environ.get('HTTP_X_FORWARDED_PROTO') if url_scheme is None: url_scheme = 'https' if self.is_ssl else 'http' environ['wsgi.url_scheme'] = url_scheme # authors should be aware that REMOTE_HOST and REMOTE_ADDR # may not qualify the remote addr # also SERVER_PORT variable MUST be set to the TCP/IP port number on # which this request is received from the client. # http://www.ietf.org/rfc/rfc3875 family = self.transport.get_extra_info('socket').family if family in (socket.AF_INET, socket.AF_INET6): peername = self.transport.get_extra_info('peername') environ['REMOTE_ADDR'] = peername[0] environ['REMOTE_PORT'] = str(peername[1]) http_host = message.headers.get("HOST", None) if http_host: hostport = http_host.split(":") environ['SERVER_NAME'] = hostport[0] if len(hostport) > 1: environ['SERVER_PORT'] = str(hostport[1]) else: environ['SERVER_PORT'] = '80' else: # SERVER_NAME should be set to value of Host header, but this # header is not required. In this case we shoud set it to local # address of socket sockname = self.transport.get_extra_info('sockname') environ['SERVER_NAME'] = sockname[0] environ['SERVER_PORT'] = str(sockname[1]) else: # We are behind reverse proxy, so get all vars from headers for header in ('REMOTE_ADDR', 'REMOTE_PORT', 'SERVER_NAME', 'SERVER_PORT'): environ[header] = message.headers.get(header, '') path_info = uri_parts.path if script_name: path_info = path_info.split(script_name, 1)[-1] environ['PATH_INFO'] = path_info environ['SCRIPT_NAME'] = script_name environ['async.reader'] = self.reader environ['async.writer'] = self.writer return environ @asyncio.coroutine def handle_request(self, message, payload): """Handle a single HTTP request""" now = self._loop.time() if self.readpayload: wsgiinput = io.BytesIO() wsgiinput.write((yield from payload.read())) wsgiinput.seek(0) payload = wsgiinput environ = self.create_wsgi_environ(message, payload) response = self.create_wsgi_response(message) riter = self.wsgi(environ, response.start_response) if isinstance(riter, asyncio.Future) or inspect.isgenerator(riter): riter = yield from riter resp = response.response try: for item in riter: if isinstance(item, asyncio.Future): item = yield from item yield from resp.write(item) yield from resp.write_eof() finally: if hasattr(riter, 'close'): riter.close() if resp.keep_alive(): self.keep_alive(True) self.log_access( message, environ, response.response, self._loop.time() - now) class FileWrapper: """Custom file wrapper.""" def __init__(self, fobj, chunk_size=8192): self.fobj = fobj self.chunk_size = chunk_size if hasattr(fobj, 'close'): self.close = fobj.close def __iter__(self): return self def __next__(self): data = self.fobj.read(self.chunk_size) if data: return data raise StopIteration class WsgiResponse: """Implementation of start_response() callable as specified by PEP 3333""" status = None HOP_HEADERS = { hdrs.CONNECTION, hdrs.KEEP_ALIVE, hdrs.PROXY_AUTHENTICATE, hdrs.PROXY_AUTHORIZATION, hdrs.TE, hdrs.TRAILER, hdrs.TRANSFER_ENCODING, hdrs.UPGRADE, } def __init__(self, writer, message): self.writer = writer self.message = message def start_response(self, status, headers, exc_info=None): if exc_info: try: if self.status: raise exc_info[1] finally: exc_info = None status_code = int(status.split(' ', 1)[0]) self.status = status resp = self.response = aiohttp.Response( self.writer, status_code, self.message.version, self.message.should_close) resp.HOP_HEADERS = self.HOP_HEADERS for name, value in headers: resp.add_header(name, value) if resp.has_chunked_hdr: resp.enable_chunked_encoding() # send headers immediately for websocket connection if status_code == 101 and resp.upgrade and resp.websocket: resp.send_headers() else: resp._send_headers = True return self.response.write aiohttp-0.20.2/aiohttp/_websocket.c0000664000175000017500000026650112635321272020005 0ustar andrewandrew00000000000000/* Generated by Cython 0.23.4 */ /* BEGIN: Cython Metadata { "distutils": { "depends": [] } } END: Cython Metadata */ #define PY_SSIZE_T_CLEAN #include "Python.h" #ifndef Py_PYTHON_H #error Python headers needed to compile C extensions, please install development version of Python. #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000) #error Cython requires Python 2.6+ or Python 3.2+. #else #define CYTHON_ABI "0_23_4" #include #ifndef offsetof #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) #endif #if !defined(WIN32) && !defined(MS_WINDOWS) #ifndef __stdcall #define __stdcall #endif #ifndef __cdecl #define __cdecl #endif #ifndef __fastcall #define __fastcall #endif #endif #ifndef DL_IMPORT #define DL_IMPORT(t) t #endif #ifndef DL_EXPORT #define DL_EXPORT(t) t #endif #ifndef PY_LONG_LONG #define PY_LONG_LONG LONG_LONG #endif #ifndef Py_HUGE_VAL #define Py_HUGE_VAL HUGE_VAL #endif #ifdef PYPY_VERSION #define CYTHON_COMPILING_IN_PYPY 1 #define CYTHON_COMPILING_IN_CPYTHON 0 #else #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_CPYTHON 1 #endif #if !defined(CYTHON_USE_PYLONG_INTERNALS) && CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000 #define CYTHON_USE_PYLONG_INTERNALS 1 #endif #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) #define Py_OptimizeFlag 0 #endif #define __PYX_BUILD_PY_SSIZE_T "n" #define CYTHON_FORMAT_SSIZE_T "z" #if PY_MAJOR_VERSION < 3 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #define __Pyx_DefaultClassType PyClass_Type #else #define __Pyx_BUILTIN_MODULE_NAME "builtins" #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #define __Pyx_DefaultClassType PyType_Type #endif #ifndef Py_TPFLAGS_CHECKTYPES #define Py_TPFLAGS_CHECKTYPES 0 #endif #ifndef Py_TPFLAGS_HAVE_INDEX #define Py_TPFLAGS_HAVE_INDEX 0 #endif #ifndef Py_TPFLAGS_HAVE_NEWBUFFER #define Py_TPFLAGS_HAVE_NEWBUFFER 0 #endif #ifndef Py_TPFLAGS_HAVE_FINALIZE #define Py_TPFLAGS_HAVE_FINALIZE 0 #endif #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) #define CYTHON_PEP393_ENABLED 1 #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ 0 : _PyUnicode_Ready((PyObject *)(op))) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) #else #define CYTHON_PEP393_ENABLED 0 #define __Pyx_PyUnicode_READY(op) (0) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) #endif #if CYTHON_COMPILING_IN_PYPY #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) #else #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) #endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) #endif #define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) #define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) #else #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) #endif #if PY_MAJOR_VERSION >= 3 #define PyBaseString_Type PyUnicode_Type #define PyStringObject PyUnicodeObject #define PyString_Type PyUnicode_Type #define PyString_Check PyUnicode_Check #define PyString_CheckExact PyUnicode_CheckExact #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) #else #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) #endif #ifndef PySet_CheckExact #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) #endif #define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) #if PY_MAJOR_VERSION >= 3 #define PyIntObject PyLongObject #define PyInt_Type PyLong_Type #define PyInt_Check(op) PyLong_Check(op) #define PyInt_CheckExact(op) PyLong_CheckExact(op) #define PyInt_FromString PyLong_FromString #define PyInt_FromUnicode PyLong_FromUnicode #define PyInt_FromLong PyLong_FromLong #define PyInt_FromSize_t PyLong_FromSize_t #define PyInt_FromSsize_t PyLong_FromSsize_t #define PyInt_AsLong PyLong_AsLong #define PyInt_AS_LONG PyLong_AS_LONG #define PyInt_AsSsize_t PyLong_AsSsize_t #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask #define PyNumber_Int PyNumber_Long #endif #if PY_MAJOR_VERSION >= 3 #define PyBoolObject PyLongObject #endif #if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY #ifndef PyUnicode_InternFromString #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) #endif #endif #if PY_VERSION_HEX < 0x030200A4 typedef long Py_hash_t; #define __Pyx_PyInt_FromHash_t PyInt_FromLong #define __Pyx_PyInt_AsHash_t PyInt_AsLong #else #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) #else #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) #endif #if PY_VERSION_HEX >= 0x030500B1 #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) #elif CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; } __Pyx_PyAsyncMethodsStruct; #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) #else #define __Pyx_PyType_AsAsync(obj) NULL #endif #ifndef CYTHON_RESTRICT #if defined(__GNUC__) #define CYTHON_RESTRICT __restrict__ #elif defined(_MSC_VER) && _MSC_VER >= 1400 #define CYTHON_RESTRICT __restrict #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define CYTHON_RESTRICT restrict #else #define CYTHON_RESTRICT #endif #endif #define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) #ifndef CYTHON_INLINE #if defined(__GNUC__) #define CYTHON_INLINE __inline__ #elif defined(_MSC_VER) #define CYTHON_INLINE __inline #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define CYTHON_INLINE inline #else #define CYTHON_INLINE #endif #endif #if defined(WIN32) || defined(MS_WINDOWS) #define _USE_MATH_DEFINES #endif #include #ifdef NAN #define __PYX_NAN() ((float) NAN) #else static CYTHON_INLINE float __PYX_NAN() { float value; memset(&value, 0xFF, sizeof(value)); return value; } #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) #else #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) #endif #ifndef __PYX_EXTERN_C #ifdef __cplusplus #define __PYX_EXTERN_C extern "C" #else #define __PYX_EXTERN_C extern #endif #endif #define __PYX_HAVE__aiohttp___websocket #define __PYX_HAVE_API__aiohttp___websocket #include "string.h" #include "stdio.h" #include "pythread.h" #include "stdint.h" #ifdef _OPENMP #include #endif /* _OPENMP */ #ifdef PYREX_WITHOUT_ASSERTIONS #define CYTHON_WITHOUT_ASSERTIONS #endif #ifndef CYTHON_UNUSED # if defined(__GNUC__) # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) # define CYTHON_UNUSED __attribute__ ((__unused__)) # else # define CYTHON_UNUSED # endif # elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) # define CYTHON_UNUSED __attribute__ ((__unused__)) # else # define CYTHON_UNUSED # endif #endif #ifndef CYTHON_NCP_UNUSED # if CYTHON_COMPILING_IN_CPYTHON # define CYTHON_NCP_UNUSED # else # define CYTHON_NCP_UNUSED CYTHON_UNUSED # endif #endif typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; #define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 #define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 #define __PYX_DEFAULT_STRING_ENCODING "" #define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString #define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize #define __Pyx_uchar_cast(c) ((unsigned char)c) #define __Pyx_long_cast(x) ((long)x) #define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ (sizeof(type) < sizeof(Py_ssize_t)) ||\ (sizeof(type) > sizeof(Py_ssize_t) &&\ likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX) &&\ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ v == (type)PY_SSIZE_T_MIN))) ||\ (sizeof(type) == sizeof(Py_ssize_t) &&\ (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX))) ) #if defined (__cplusplus) && __cplusplus >= 201103L #include #define __Pyx_sst_abs(value) std::abs(value) #elif SIZEOF_INT >= SIZEOF_SIZE_T #define __Pyx_sst_abs(value) abs(value) #elif SIZEOF_LONG >= SIZEOF_SIZE_T #define __Pyx_sst_abs(value) labs(value) #elif defined (_MSC_VER) && defined (_M_X64) #define __Pyx_sst_abs(value) _abs64(value) #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define __Pyx_sst_abs(value) llabs(value) #elif defined (__GNUC__) #define __Pyx_sst_abs(value) __builtin_llabs(value) #else #define __Pyx_sst_abs(value) ((value<0) ? -value : value) #endif static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*); static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); #define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) #define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) #define __Pyx_PyBytes_FromString PyBytes_FromString #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); #if PY_MAJOR_VERSION < 3 #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize #else #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize #endif #define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) #define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) #define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) #define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) #define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) #if PY_MAJOR_VERSION < 3 static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { const Py_UNICODE *u_end = u; while (*u_end++) ; return (size_t)(u_end - u - 1); } #else #define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen #endif #define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) #define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode #define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode #define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) #define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); #if CYTHON_COMPILING_IN_CPYTHON #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) #else #define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) #endif #define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII static int __Pyx_sys_getdefaultencoding_not_ascii; static int __Pyx_init_sys_getdefaultencoding_params(void) { PyObject* sys; PyObject* default_encoding = NULL; PyObject* ascii_chars_u = NULL; PyObject* ascii_chars_b = NULL; const char* default_encoding_c; sys = PyImport_ImportModule("sys"); if (!sys) goto bad; default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); Py_DECREF(sys); if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; if (strcmp(default_encoding_c, "ascii") == 0) { __Pyx_sys_getdefaultencoding_not_ascii = 0; } else { char ascii_chars[128]; int c; for (c = 0; c < 128; c++) { ascii_chars[c] = c; } __Pyx_sys_getdefaultencoding_not_ascii = 1; ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); if (!ascii_chars_u) goto bad; ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { PyErr_Format( PyExc_ValueError, "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", default_encoding_c); goto bad; } Py_DECREF(ascii_chars_u); Py_DECREF(ascii_chars_b); } Py_DECREF(default_encoding); return 0; bad: Py_XDECREF(default_encoding); Py_XDECREF(ascii_chars_u); Py_XDECREF(ascii_chars_b); return -1; } #endif #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) #else #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT static char* __PYX_DEFAULT_STRING_ENCODING; static int __Pyx_init_sys_getdefaultencoding_params(void) { PyObject* sys; PyObject* default_encoding = NULL; char* default_encoding_c; sys = PyImport_ImportModule("sys"); if (!sys) goto bad; default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); Py_DECREF(sys); 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)); if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); Py_DECREF(default_encoding); return 0; bad: Py_XDECREF(default_encoding); return -1; } #endif #endif /* Test for GCC > 2.95 */ #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else /* !__GNUC__ or GCC < 2.95 */ #define likely(x) (x) #define unlikely(x) (x) #endif /* __GNUC__ */ static PyObject *__pyx_m; static PyObject *__pyx_d; static PyObject *__pyx_b; static PyObject *__pyx_empty_tuple; static PyObject *__pyx_empty_bytes; static int __pyx_lineno; static int __pyx_clineno = 0; static const char * __pyx_cfilenm= __FILE__; static const char *__pyx_filename; static const char *__pyx_f[] = { "aiohttp/_websocket.pyx", "type.pxd", "bool.pxd", "complex.pxd", }; /*--- Type declarations ---*/ /* --- Runtime support code (head) --- */ #ifndef CYTHON_REFNANNY #define CYTHON_REFNANNY 0 #endif #if CYTHON_REFNANNY typedef struct { void (*INCREF)(void*, PyObject*, int); void (*DECREF)(void*, PyObject*, int); void (*GOTREF)(void*, PyObject*, int); void (*GIVEREF)(void*, PyObject*, int); void* (*SetupContext)(const char*, int, const char*); void (*FinishContext)(void**); } __Pyx_RefNannyAPIStruct; static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; #ifdef WITH_THREAD #define __Pyx_RefNannySetupContext(name, acquire_gil)\ if (acquire_gil) {\ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ PyGILState_Release(__pyx_gilstate_save);\ } else {\ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ } #else #define __Pyx_RefNannySetupContext(name, acquire_gil)\ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) #endif #define __Pyx_RefNannyFinishContext()\ __Pyx_RefNanny->FinishContext(&__pyx_refnanny) #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) #else #define __Pyx_RefNannyDeclarations #define __Pyx_RefNannySetupContext(name, acquire_gil) #define __Pyx_RefNannyFinishContext() #define __Pyx_INCREF(r) Py_INCREF(r) #define __Pyx_DECREF(r) Py_DECREF(r) #define __Pyx_GOTREF(r) #define __Pyx_GIVEREF(r) #define __Pyx_XINCREF(r) Py_XINCREF(r) #define __Pyx_XDECREF(r) Py_XDECREF(r) #define __Pyx_XGOTREF(r) #define __Pyx_XGIVEREF(r) #endif #define __Pyx_XDECREF_SET(r, v) do {\ PyObject *tmp = (PyObject *) r;\ r = v; __Pyx_XDECREF(tmp);\ } while (0) #define __Pyx_DECREF_SET(r, v) do {\ PyObject *tmp = (PyObject *) r;\ r = v; __Pyx_DECREF(tmp);\ } while (0) #define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) #define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { PyTypeObject* tp = Py_TYPE(obj); if (likely(tp->tp_getattro)) return tp->tp_getattro(obj, attr_name); #if PY_MAJOR_VERSION < 3 if (likely(tp->tp_getattr)) return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); #endif return PyObject_GetAttr(obj, attr_name); } #else #define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) #endif static PyObject *__Pyx_GetBuiltinName(PyObject *name); static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ const char* function_name); static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, const char *name, int exact); typedef struct { int code_line; PyCodeObject* code_object; } __Pyx_CodeObjectCacheEntry; struct __Pyx_CodeObjectCache { int count; int max_count; __Pyx_CodeObjectCacheEntry* entries; }; static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); static PyCodeObject *__pyx_find_code_object(int code_line); static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); static void __Pyx_AddTraceback(const char *funcname, int c_line, int py_line, const char *filename); static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); static int __Pyx_check_binary_version(void); #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 static PyObject *__Pyx_ImportModule(const char *name); static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /* Module declarations from 'cpython.version' */ /* Module declarations from '__builtin__' */ /* Module declarations from 'cpython.type' */ static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; /* Module declarations from 'libc.string' */ /* Module declarations from 'libc.stdio' */ /* Module declarations from 'cpython.object' */ /* Module declarations from 'cpython.ref' */ /* Module declarations from 'cpython.exc' */ /* Module declarations from 'cpython.module' */ /* Module declarations from 'cpython.mem' */ /* Module declarations from 'cpython.tuple' */ /* Module declarations from 'cpython.list' */ /* Module declarations from 'cpython.sequence' */ /* Module declarations from 'cpython.mapping' */ /* Module declarations from 'cpython.iterator' */ /* Module declarations from 'cpython.number' */ /* Module declarations from 'cpython.int' */ /* Module declarations from '__builtin__' */ /* Module declarations from 'cpython.bool' */ static PyTypeObject *__pyx_ptype_7cpython_4bool_bool = 0; /* Module declarations from 'cpython.long' */ /* Module declarations from 'cpython.float' */ /* Module declarations from '__builtin__' */ /* Module declarations from 'cpython.complex' */ static PyTypeObject *__pyx_ptype_7cpython_7complex_complex = 0; /* Module declarations from 'cpython.string' */ /* Module declarations from 'cpython.unicode' */ /* Module declarations from 'cpython.dict' */ /* Module declarations from 'cpython.instance' */ /* Module declarations from 'cpython.function' */ /* Module declarations from 'cpython.method' */ /* Module declarations from 'cpython.weakref' */ /* Module declarations from 'cpython.getargs' */ /* Module declarations from 'cpython.pythread' */ /* Module declarations from 'cpython.pystate' */ /* Module declarations from 'cpython.cobject' */ /* Module declarations from 'cpython.oldbuffer' */ /* Module declarations from 'cpython.set' */ /* Module declarations from 'cpython.buffer' */ /* Module declarations from 'cpython.bytes' */ /* Module declarations from 'cpython.pycapsule' */ /* Module declarations from 'cpython' */ /* Module declarations from 'libc.stdint' */ /* Module declarations from 'aiohttp._websocket' */ #define __Pyx_MODULE_NAME "aiohttp._websocket" int __pyx_module_is_main_aiohttp___websocket = 0; /* Implementation of 'aiohttp._websocket' */ static PyObject *__pyx_builtin_range; static char __pyx_k_i[] = "i"; static char __pyx_k_data[] = "data"; static char __pyx_k_main[] = "__main__"; static char __pyx_k_mask[] = "mask"; static char __pyx_k_test[] = "__test__"; static char __pyx_k_range[] = "range"; static char __pyx_k_in_buf[] = "in_buf"; static char __pyx_k_data_len[] = "data_len"; static char __pyx_k_mask_buf[] = "mask_buf"; static char __pyx_k_uint32_msk[] = "uint32_msk"; static char __pyx_k_uint64_msk[] = "uint64_msk"; static char __pyx_k_aiohttp__websocket[] = "aiohttp._websocket"; static char __pyx_k_websocket_mask_cython[] = "_websocket_mask_cython"; static char __pyx_k_home_andrew_projects_aiohttp_ai[] = "/home/andrew/projects/aiohttp/aiohttp/_websocket.pyx"; static PyObject *__pyx_n_s_aiohttp__websocket; static PyObject *__pyx_n_s_data; static PyObject *__pyx_n_s_data_len; static PyObject *__pyx_kp_s_home_andrew_projects_aiohttp_ai; static PyObject *__pyx_n_s_i; 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_range; static PyObject *__pyx_n_s_test; static PyObject *__pyx_n_s_uint32_msk; static PyObject *__pyx_n_s_uint64_msk; static PyObject *__pyx_n_s_websocket_mask_cython; static PyObject *__pyx_pf_7aiohttp_10_websocket__websocket_mask_cython(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_mask, PyObject *__pyx_v_data); /* proto */ static PyObject *__pyx_tuple_; static PyObject *__pyx_codeobj__2; /* "aiohttp/_websocket.pyx":9 * from libc.stdint cimport uint32_t, uint64_t, uintmax_t * * def _websocket_mask_cython(bytes mask, bytearray data): # <<<<<<<<<<<<<< * """Note, this function mutates it's `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 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; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("_websocket_mask_cython (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_mask,&__pyx_n_s_data,0}; PyObject* values[2] = {0,0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("_websocket_mask_cython", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_websocket_mask_cython") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); values[1] = PyTuple_GET_ITEM(__pyx_args, 1); } __pyx_v_mask = ((PyObject*)values[0]); __pyx_v_data = ((PyObject*)values[1]); } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("_websocket_mask_cython", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._websocket._websocket_mask_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mask), (&PyBytes_Type), 1, "mask", 1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_data), (&PyByteArray_Type), 1, "data", 1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = __pyx_pf_7aiohttp_10_websocket__websocket_mask_cython(__pyx_self, __pyx_v_mask, __pyx_v_data); /* function exit code */ goto __pyx_L0; __pyx_L1_error:; __pyx_r = NULL; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_websocket__websocket_mask_cython(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_mask, PyObject *__pyx_v_data) { Py_ssize_t __pyx_v_data_len; Py_ssize_t __pyx_v_i; unsigned char *__pyx_v_in_buf; unsigned char const *__pyx_v_mask_buf; uint32_t __pyx_v_uint32_msk; uint64_t __pyx_v_uint64_msk; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations Py_ssize_t __pyx_t_1; char *__pyx_t_2; int __pyx_t_3; uint64_t *__pyx_t_4; long __pyx_t_5; uint32_t *__pyx_t_6; Py_ssize_t __pyx_t_7; Py_ssize_t __pyx_t_8; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_websocket_mask_cython", 0); /* "aiohttp/_websocket.pyx":20 * uint64_t uint64_msk * * assert len(mask) == 4 # <<<<<<<<<<<<<< * * data_len = len(data) */ #ifndef CYTHON_WITHOUT_ASSERTIONS if (unlikely(!Py_OptimizeFlag)) { if (unlikely(__pyx_v_mask == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = PyBytes_GET_SIZE(__pyx_v_mask); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (unlikely(!((__pyx_t_1 == 4) != 0))) { PyErr_SetNone(PyExc_AssertionError); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } } #endif /* "aiohttp/_websocket.pyx":22 * assert len(mask) == 4 * * data_len = len(data) # <<<<<<<<<<<<<< * in_buf = PyByteArray_AsString(data) * mask_buf = PyBytes_AsString(mask) */ __pyx_t_1 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_v_data_len = __pyx_t_1; /* "aiohttp/_websocket.pyx":23 * * data_len = len(data) * in_buf = PyByteArray_AsString(data) # <<<<<<<<<<<<<< * mask_buf = PyBytes_AsString(mask) * uint32_msk = (mask_buf)[0] */ __pyx_t_2 = PyByteArray_AsString(__pyx_v_data); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_v_in_buf = ((unsigned char *)__pyx_t_2); /* "aiohttp/_websocket.pyx":24 * data_len = len(data) * in_buf = PyByteArray_AsString(data) * mask_buf = PyBytes_AsString(mask) # <<<<<<<<<<<<<< * uint32_msk = (mask_buf)[0] * */ __pyx_t_2 = PyBytes_AsString(__pyx_v_mask); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_v_mask_buf = ((unsigned char const *)__pyx_t_2); /* "aiohttp/_websocket.pyx":25 * in_buf = PyByteArray_AsString(data) * mask_buf = PyBytes_AsString(mask) * uint32_msk = (mask_buf)[0] # <<<<<<<<<<<<<< * * # TODO: align in_data ptr to achieve even faster speeds */ __pyx_v_uint32_msk = (((uint32_t *)__pyx_v_mask_buf)[0]); /* "aiohttp/_websocket.pyx":30 * # does it need in python ?! malloc() always aligns to sizeof(long) bytes * * if sizeof(size_t) >= 8: # <<<<<<<<<<<<<< * uint64_msk = uint32_msk * uint64_msk = (uint64_msk << 32) | uint32_msk */ __pyx_t_3 = (((sizeof(size_t)) >= 8) != 0); if (__pyx_t_3) { /* "aiohttp/_websocket.pyx":31 * * if sizeof(size_t) >= 8: * uint64_msk = uint32_msk # <<<<<<<<<<<<<< * uint64_msk = (uint64_msk << 32) | uint32_msk * */ __pyx_v_uint64_msk = __pyx_v_uint32_msk; /* "aiohttp/_websocket.pyx":32 * if sizeof(size_t) >= 8: * uint64_msk = uint32_msk * uint64_msk = (uint64_msk << 32) | uint32_msk # <<<<<<<<<<<<<< * * while data_len >= 8: */ __pyx_v_uint64_msk = ((__pyx_v_uint64_msk << 32) | __pyx_v_uint32_msk); /* "aiohttp/_websocket.pyx":34 * uint64_msk = (uint64_msk << 32) | uint32_msk * * while data_len >= 8: # <<<<<<<<<<<<<< * (in_buf)[0] ^= uint64_msk * in_buf += 8 */ while (1) { __pyx_t_3 = ((__pyx_v_data_len >= 8) != 0); if (!__pyx_t_3) break; /* "aiohttp/_websocket.pyx":35 * * while data_len >= 8: * (in_buf)[0] ^= uint64_msk # <<<<<<<<<<<<<< * in_buf += 8 * data_len -= 8 */ __pyx_t_4 = ((uint64_t *)__pyx_v_in_buf); __pyx_t_5 = 0; (__pyx_t_4[__pyx_t_5]) = ((__pyx_t_4[__pyx_t_5]) ^ __pyx_v_uint64_msk); /* "aiohttp/_websocket.pyx":36 * while data_len >= 8: * (in_buf)[0] ^= uint64_msk * in_buf += 8 # <<<<<<<<<<<<<< * data_len -= 8 * */ __pyx_v_in_buf = (__pyx_v_in_buf + 8); /* "aiohttp/_websocket.pyx":37 * (in_buf)[0] ^= uint64_msk * in_buf += 8 * data_len -= 8 # <<<<<<<<<<<<<< * * */ __pyx_v_data_len = (__pyx_v_data_len - 8); } /* "aiohttp/_websocket.pyx":30 * # does it need in python ?! malloc() always aligns to sizeof(long) bytes * * if sizeof(size_t) >= 8: # <<<<<<<<<<<<<< * uint64_msk = uint32_msk * uint64_msk = (uint64_msk << 32) | uint32_msk */ } /* "aiohttp/_websocket.pyx":40 * * * while data_len >= 4: # <<<<<<<<<<<<<< * (in_buf)[0] ^= uint32_msk * in_buf += 4 */ while (1) { __pyx_t_3 = ((__pyx_v_data_len >= 4) != 0); if (!__pyx_t_3) break; /* "aiohttp/_websocket.pyx":41 * * while data_len >= 4: * (in_buf)[0] ^= uint32_msk # <<<<<<<<<<<<<< * in_buf += 4 * data_len -= 4 */ __pyx_t_6 = ((uint32_t *)__pyx_v_in_buf); __pyx_t_5 = 0; (__pyx_t_6[__pyx_t_5]) = ((__pyx_t_6[__pyx_t_5]) ^ __pyx_v_uint32_msk); /* "aiohttp/_websocket.pyx":42 * while data_len >= 4: * (in_buf)[0] ^= uint32_msk * in_buf += 4 # <<<<<<<<<<<<<< * data_len -= 4 * */ __pyx_v_in_buf = (__pyx_v_in_buf + 4); /* "aiohttp/_websocket.pyx":43 * (in_buf)[0] ^= uint32_msk * in_buf += 4 * data_len -= 4 # <<<<<<<<<<<<<< * * for i in range(0, data_len): */ __pyx_v_data_len = (__pyx_v_data_len - 4); } /* "aiohttp/_websocket.pyx":45 * data_len -= 4 * * for i in range(0, data_len): # <<<<<<<<<<<<<< * in_buf[i] ^= mask_buf[i] * */ __pyx_t_1 = __pyx_v_data_len; for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_1; __pyx_t_7+=1) { __pyx_v_i = __pyx_t_7; /* "aiohttp/_websocket.pyx":46 * * for i in range(0, data_len): * in_buf[i] ^= mask_buf[i] # <<<<<<<<<<<<<< * * return data */ __pyx_t_8 = __pyx_v_i; (__pyx_v_in_buf[__pyx_t_8]) = ((__pyx_v_in_buf[__pyx_t_8]) ^ (__pyx_v_mask_buf[__pyx_v_i])); } /* "aiohttp/_websocket.pyx":48 * in_buf[i] ^= mask_buf[i] * * return data # <<<<<<<<<<<<<< */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_data); __pyx_r = __pyx_v_data; goto __pyx_L0; /* "aiohttp/_websocket.pyx":9 * from libc.stdint cimport uint32_t, uint64_t, uintmax_t * * def _websocket_mask_cython(bytes mask, bytearray data): # <<<<<<<<<<<<<< * """Note, this function mutates it's `data` argument * """ */ /* function exit code */ __pyx_L1_error:; __Pyx_AddTraceback("aiohttp._websocket._websocket_mask_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyMethodDef __pyx_methods[] = { {0, 0, 0, 0} }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef __pyx_moduledef = { #if PY_VERSION_HEX < 0x03020000 { PyObject_HEAD_INIT(NULL) NULL, 0, NULL }, #else PyModuleDef_HEAD_INIT, #endif "_websocket", 0, /* m_doc */ -1, /* m_size */ __pyx_methods /* m_methods */, NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL /* m_free */ }; #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}, {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1}, {&__pyx_n_s_data_len, __pyx_k_data_len, sizeof(__pyx_k_data_len), 0, 0, 1, 1}, {&__pyx_kp_s_home_andrew_projects_aiohttp_ai, __pyx_k_home_andrew_projects_aiohttp_ai, sizeof(__pyx_k_home_andrew_projects_aiohttp_ai), 0, 0, 1, 0}, {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, {&__pyx_n_s_in_buf, __pyx_k_in_buf, sizeof(__pyx_k_in_buf), 0, 0, 1, 1}, {&__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_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}, {&__pyx_n_s_uint64_msk, __pyx_k_uint64_msk, sizeof(__pyx_k_uint64_msk), 0, 0, 1, 1}, {&__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) { __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;} return 0; __pyx_L1_error:; return -1; } static int __Pyx_InitCachedConstants(void) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); /* "aiohttp/_websocket.pyx":9 * from libc.stdint cimport uint32_t, uint64_t, uintmax_t * * def _websocket_mask_cython(bytes mask, bytearray data): # <<<<<<<<<<<<<< * """Note, this function mutates it's `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_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple_); __Pyx_GIVEREF(__pyx_tuple_); __pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(2, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple_, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_andrew_projects_aiohttp_ai, __pyx_n_s_websocket_mask_cython, 9, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; __Pyx_RefNannyFinishContext(); return -1; } static int __Pyx_InitGlobals(void) { if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; return 0; __pyx_L1_error:; return -1; } #if PY_MAJOR_VERSION < 3 PyMODINIT_FUNC init_websocket(void); /*proto*/ PyMODINIT_FUNC init_websocket(void) #else PyMODINIT_FUNC PyInit__websocket(void); /*proto*/ PyMODINIT_FUNC PyInit__websocket(void) #endif { PyObject *__pyx_t_1 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannyDeclarations #if CYTHON_REFNANNY __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); if (!__Pyx_RefNanny) { PyErr_Clear(); __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); if (!__Pyx_RefNanny) Py_FatalError("failed to import 'refnanny' module"); } #endif __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__websocket(void)", 0); if (__Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #ifdef __Pyx_CyFunction_USED if (__pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif #ifdef __Pyx_FusedFunction_USED if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif #ifdef __Pyx_Coroutine_USED if (__pyx_Coroutine_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif #ifdef __Pyx_Generator_USED if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif #ifdef __Pyx_StopAsyncIteration_USED if (__pyx_StopAsyncIteration_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif /*--- Library function declarations ---*/ /*--- Threads initialization code ---*/ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS #ifdef WITH_THREAD /* Python build with threading support? */ PyEval_InitThreads(); #endif #endif /*--- Module creation code ---*/ #if PY_MAJOR_VERSION < 3 __pyx_m = Py_InitModule4("_websocket", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); #else __pyx_m = PyModule_Create(&__pyx_moduledef); #endif if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} Py_INCREF(__pyx_d); __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #if CYTHON_COMPILING_IN_PYPY Py_INCREF(__pyx_b); #endif if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; /*--- Initialize various global constants etc. ---*/ if (__Pyx_InitGlobals() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif if (__pyx_module_is_main_aiohttp___websocket) { if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } #if PY_MAJOR_VERSION >= 3 { PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (!PyDict_GetItemString(modules, "aiohttp._websocket")) { if (unlikely(PyDict_SetItemString(modules, "aiohttp._websocket", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } } #endif /*--- Builtin init code ---*/ if (__Pyx_InitCachedBuiltins() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /*--- Constants init code ---*/ if (__Pyx_InitCachedConstants() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /*--- Global init code ---*/ /*--- Variable export code ---*/ /*--- Function export code ---*/ /*--- Type init code ---*/ /*--- Type import code ---*/ __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", #if CYTHON_COMPILING_IN_PYPY sizeof(PyTypeObject), #else sizeof(PyHeapTypeObject), #endif 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[2]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[3]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /*--- Variable import code ---*/ /*--- Function import code ---*/ /*--- Execution code ---*/ #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) if (__Pyx_patch_abc() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif /* "aiohttp/_websocket.pyx":9 * from libc.stdint cimport uint32_t, uint64_t, uintmax_t * * def _websocket_mask_cython(bytes mask, bytearray data): # <<<<<<<<<<<<<< * """Note, this function mutates it's `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_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_websocket_mask_cython, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_websocket.pyx":1 * from cpython cimport PyBytes_AsString # <<<<<<<<<<<<<< * * #from cpython cimport PyByteArray_AsString # cython still not exports that */ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /*--- Wrapped vars code ---*/ goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); if (__pyx_m) { if (__pyx_d) { __Pyx_AddTraceback("init aiohttp._websocket", __pyx_clineno, __pyx_lineno, __pyx_filename); } Py_DECREF(__pyx_m); __pyx_m = 0; } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, "init aiohttp._websocket"); } __pyx_L0:; __Pyx_RefNannyFinishContext(); #if PY_MAJOR_VERSION < 3 return; #else return __pyx_m; #endif } /* --- Runtime support code --- */ #if CYTHON_REFNANNY static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { PyObject *m = NULL, *p = NULL; void *r = NULL; m = PyImport_ImportModule((char *)modname); if (!m) goto end; p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); if (!p) goto end; r = PyLong_AsVoidPtr(p); end: Py_XDECREF(p); Py_XDECREF(m); return (__Pyx_RefNannyAPIStruct *)r; } #endif static PyObject *__Pyx_GetBuiltinName(PyObject *name) { PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); if (unlikely(!result)) { PyErr_Format(PyExc_NameError, #if PY_MAJOR_VERSION >= 3 "name '%U' is not defined", name); #else "name '%.200s' is not defined", PyString_AS_STRING(name)); #endif } return result; } static void __Pyx_RaiseArgtupleInvalid( const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found) { Py_ssize_t num_expected; const char *more_or_less; if (num_found < num_min) { num_expected = num_min; more_or_less = "at least"; } else { num_expected = num_max; more_or_less = "at most"; } if (exact) { more_or_less = "exactly"; } PyErr_Format(PyExc_TypeError, "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", func_name, more_or_less, num_expected, (num_expected == 1) ? "" : "s", num_found); } static void __Pyx_RaiseDoubleKeywordsError( const char* func_name, PyObject* kw_name) { PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "%s() got multiple values for keyword argument '%U'", func_name, kw_name); #else "%s() got multiple values for keyword argument '%s'", func_name, PyString_AsString(kw_name)); #endif } static int __Pyx_ParseOptionalKeywords( PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name) { PyObject *key = 0, *value = 0; Py_ssize_t pos = 0; PyObject*** name; PyObject*** first_kw_arg = argnames + num_pos_args; while (PyDict_Next(kwds, &pos, &key, &value)) { name = first_kw_arg; while (*name && (**name != key)) name++; if (*name) { values[name-argnames] = value; continue; } name = first_kw_arg; #if PY_MAJOR_VERSION < 3 if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { while (*name) { if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) && _PyString_Eq(**name, key)) { values[name-argnames] = value; break; } name++; } if (*name) continue; else { PyObject*** argname = argnames; while (argname != first_kw_arg) { if ((**argname == key) || ( (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) && _PyString_Eq(**argname, key))) { goto arg_passed_twice; } argname++; } } } else #endif if (likely(PyUnicode_Check(key))) { while (*name) { int cmp = (**name == key) ? 0 : #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : #endif PyUnicode_Compare(**name, key); if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; if (cmp == 0) { values[name-argnames] = value; break; } name++; } if (*name) continue; else { PyObject*** argname = argnames; while (argname != first_kw_arg) { int cmp = (**argname == key) ? 0 : #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : #endif PyUnicode_Compare(**argname, key); if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; if (cmp == 0) goto arg_passed_twice; argname++; } } } else goto invalid_keyword_type; if (kwds2) { if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; } else { goto invalid_keyword; } } return 0; arg_passed_twice: __Pyx_RaiseDoubleKeywordsError(function_name, key); goto bad; invalid_keyword_type: PyErr_Format(PyExc_TypeError, "%.200s() keywords must be strings", function_name); goto bad; invalid_keyword: PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION < 3 "%.200s() got an unexpected keyword argument '%.200s'", function_name, PyString_AsString(key)); #else "%s() got an unexpected keyword argument '%U'", function_name, key); #endif bad: return -1; } static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) { PyErr_Format(PyExc_TypeError, "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", name, type->tp_name, Py_TYPE(obj)->tp_name); } static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, const char *name, int exact) { if (unlikely(!type)) { PyErr_SetString(PyExc_SystemError, "Missing type object"); return 0; } if (none_allowed && obj == Py_None) return 1; else if (exact) { if (likely(Py_TYPE(obj) == type)) return 1; #if PY_MAJOR_VERSION == 2 else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; #endif } else { if (likely(PyObject_TypeCheck(obj, type))) return 1; } __Pyx_RaiseArgumentTypeInvalid(name, obj, type); return 0; } 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; } while (start < end) { mid = start + (end - start) / 2; if (code_line < entries[mid].code_line) { end = mid; } else if (code_line > entries[mid].code_line) { start = mid + 1; } else { return mid; } } if (code_line <= entries[mid].code_line) { return mid; } else { return mid + 1; } } static PyCodeObject *__pyx_find_code_object(int code_line) { PyCodeObject* code_object; int pos; if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { return NULL; } pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { return NULL; } code_object = __pyx_code_cache.entries[pos].code_object; Py_INCREF(code_object); return code_object; } static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { int pos, i; __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; if (unlikely(!code_line)) { return; } if (unlikely(!entries)) { entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); if (likely(entries)) { __pyx_code_cache.entries = entries; __pyx_code_cache.max_count = 64; __pyx_code_cache.count = 1; entries[0].code_line = code_line; entries[0].code_object = code_object; Py_INCREF(code_object); } return; } pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { PyCodeObject* tmp = entries[pos].code_object; entries[pos].code_object = code_object; Py_DECREF(tmp); return; } if (__pyx_code_cache.count == __pyx_code_cache.max_count) { int new_max = __pyx_code_cache.max_count + 64; entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); if (unlikely(!entries)) { return; } __pyx_code_cache.entries = entries; __pyx_code_cache.max_count = new_max; } for (i=__pyx_code_cache.count; i>pos; i--) { entries[i] = entries[i-1]; } entries[pos].code_line = code_line; entries[pos].code_object = code_object; __pyx_code_cache.count++; Py_INCREF(code_object); } #include "compile.h" #include "frameobject.h" #include "traceback.h" static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( const char *funcname, int c_line, int py_line, const char *filename) { PyCodeObject *py_code = 0; PyObject *py_srcfile = 0; PyObject *py_funcname = 0; #if PY_MAJOR_VERSION < 3 py_srcfile = PyString_FromString(filename); #else py_srcfile = PyUnicode_FromString(filename); #endif if (!py_srcfile) goto bad; if (c_line) { #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); #else py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); #endif } else { #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromString(funcname); #else py_funcname = PyUnicode_FromString(funcname); #endif } if (!py_funcname) goto bad; py_code = __Pyx_PyCode_New( 0, 0, 0, 0, 0, __pyx_empty_bytes, /*PyObject *code,*/ __pyx_empty_tuple, /*PyObject *consts,*/ __pyx_empty_tuple, /*PyObject *names,*/ __pyx_empty_tuple, /*PyObject *varnames,*/ __pyx_empty_tuple, /*PyObject *freevars,*/ __pyx_empty_tuple, /*PyObject *cellvars,*/ py_srcfile, /*PyObject *filename,*/ py_funcname, /*PyObject *name,*/ py_line, __pyx_empty_bytes /*PyObject *lnotab*/ ); Py_DECREF(py_srcfile); Py_DECREF(py_funcname); return py_code; bad: Py_XDECREF(py_srcfile); Py_XDECREF(py_funcname); return NULL; } static void __Pyx_AddTraceback(const char *funcname, int c_line, int py_line, const char *filename) { PyCodeObject *py_code = 0; PyFrameObject *py_frame = 0; py_code = __pyx_find_code_object(c_line ? c_line : py_line); if (!py_code) { py_code = __Pyx_CreateCodeObjectForTraceback( funcname, c_line, py_line, filename); if (!py_code) goto bad; __pyx_insert_code_object(c_line ? c_line : py_line, py_code); } py_frame = PyFrame_New( PyThreadState_GET(), /*PyThreadState *tstate,*/ py_code, /*PyCodeObject *code,*/ __pyx_d, /*PyObject *globals,*/ 0 /*PyObject *locals*/ ); if (!py_frame) goto bad; py_frame->f_lineno = py_line; PyTraceBack_Here(py_frame); bad: Py_XDECREF(py_code); Py_XDECREF(py_frame); } static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { const long neg_one = (long) -1, const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(long) < sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(long) <= sizeof(unsigned long)) { return PyLong_FromUnsignedLong((unsigned long) value); } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); } } else { if (sizeof(long) <= sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { return PyLong_FromLongLong((PY_LONG_LONG) value); } } { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; return _PyLong_FromByteArray(bytes, sizeof(long), little, !is_unsigned); } } #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) #define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ {\ func_type value = func_value;\ if (sizeof(target_type) < sizeof(func_type)) {\ if (unlikely(value != (func_type) (target_type) value)) {\ func_type zero = 0;\ if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ return (target_type) -1;\ if (is_unsigned && unlikely(value < zero))\ goto raise_neg_overflow;\ else\ goto raise_overflow;\ }\ }\ return (target_type) value;\ } #if CYTHON_USE_PYLONG_INTERNALS #include "longintrepr.h" #endif static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { const long neg_one = (long) -1, const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { if (sizeof(long) < sizeof(long)) { __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { goto raise_neg_overflow; } return (long) val; } } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (long) 0; case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) case 2: if (8 * sizeof(long) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); } } break; case 3: if (8 * sizeof(long) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); } } break; case 4: if (8 * sizeof(long) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); } } break; } #endif #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } #else { int result = PyObject_RichCompareBool(x, Py_False, Py_LT); if (unlikely(result < 0)) return (long) -1; if (unlikely(result == 1)) goto raise_neg_overflow; } #endif if (sizeof(long) <= sizeof(unsigned long)) { __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) } } else { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (long) 0; case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) case -2: if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case 2: if (8 * sizeof(long) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case -3: if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case 3: if (8 * sizeof(long) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case -4: if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case 4: if (8 * sizeof(long) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; } #endif if (sizeof(long) <= sizeof(long)) { __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) } } { #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) PyErr_SetString(PyExc_RuntimeError, "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); #else long val; PyObject *v = __Pyx_PyNumber_Int(x); #if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } #endif if (likely(v)) { int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; int ret = _PyLong_AsByteArray((PyLongObject *)v, bytes, sizeof(val), is_little, !is_unsigned); Py_DECREF(v); if (likely(!ret)) return val; } #endif return (long) -1; } } else { long val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (long) -1; val = __Pyx_PyInt_As_long(tmp); Py_DECREF(tmp); return val; } raise_overflow: PyErr_SetString(PyExc_OverflowError, "value too large to convert to long"); return (long) -1; raise_neg_overflow: PyErr_SetString(PyExc_OverflowError, "can't convert negative value to long"); return (long) -1; } static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { const int neg_one = (int) -1, const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { if (sizeof(int) < sizeof(long)) { __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { goto raise_neg_overflow; } return (int) val; } } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (int) 0; case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) case 2: if (8 * sizeof(int) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); } } break; case 3: if (8 * sizeof(int) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); } } break; case 4: if (8 * sizeof(int) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); } } break; } #endif #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } #else { int result = PyObject_RichCompareBool(x, Py_False, Py_LT); if (unlikely(result < 0)) return (int) -1; if (unlikely(result == 1)) goto raise_neg_overflow; } #endif if (sizeof(int) <= sizeof(unsigned long)) { __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) } } else { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (int) 0; case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) case -2: if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case 2: if (8 * sizeof(int) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case -3: if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case 3: if (8 * sizeof(int) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case -4: if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case 4: if (8 * sizeof(int) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; } #endif if (sizeof(int) <= sizeof(long)) { __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) } } { #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) PyErr_SetString(PyExc_RuntimeError, "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); #else int val; PyObject *v = __Pyx_PyNumber_Int(x); #if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } #endif if (likely(v)) { int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; int ret = _PyLong_AsByteArray((PyLongObject *)v, bytes, sizeof(val), is_little, !is_unsigned); Py_DECREF(v); if (likely(!ret)) return val; } #endif return (int) -1; } } else { int val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (int) -1; val = __Pyx_PyInt_As_int(tmp); Py_DECREF(tmp); return val; } raise_overflow: PyErr_SetString(PyExc_OverflowError, "value too large to convert to int"); return (int) -1; raise_neg_overflow: PyErr_SetString(PyExc_OverflowError, "can't convert negative value to int"); return (int) -1; } 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()); if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { char message[200]; PyOS_snprintf(message, sizeof(message), "compiletime version %s of module '%.100s' " "does not match runtime version %s", ctversion, __Pyx_MODULE_NAME, rtversion); return PyErr_WarnEx(NULL, message, 1); } return 0; } #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 #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", module_name, class_name); 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", module_name, class_name); goto bad; } return (PyTypeObject *)result; bad: Py_XDECREF(py_module); Py_XDECREF(result); return NULL; } #endif static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { #if PY_MAJOR_VERSION < 3 if (t->is_unicode) { *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); } else if (t->intern) { *t->p = PyString_InternFromString(t->s); } else { *t->p = PyString_FromStringAndSize(t->s, t->n - 1); } #else if (t->is_unicode | t->is_str) { if (t->intern) { *t->p = PyUnicode_InternFromString(t->s); } else if (t->encoding) { *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); } else { *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); } } else { *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); } #endif if (!*t->p) return -1; ++t; } return 0; } static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); } static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) { Py_ssize_t ignore; return __Pyx_PyObject_AsStringAndSize(o, &ignore); } static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { #if CYTHON_COMPILING_IN_CPYTHON && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) if ( #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII __Pyx_sys_getdefaultencoding_not_ascii && #endif PyUnicode_Check(o)) { #if PY_VERSION_HEX < 0x03030000 char* defenc_c; PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); if (!defenc) return NULL; defenc_c = PyBytes_AS_STRING(defenc); #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII { char* end = defenc_c + PyBytes_GET_SIZE(defenc); char* c; for (c = defenc_c; c < end; c++) { if ((unsigned char) (*c) >= 128) { PyUnicode_AsASCIIString(o); return NULL; } } } #endif *length = PyBytes_GET_SIZE(defenc); return defenc_c; #else if (__Pyx_PyUnicode_READY(o) == -1) return NULL; #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII if (PyUnicode_IS_ASCII(o)) { *length = PyUnicode_GET_LENGTH(o); return PyUnicode_AsUTF8(o); } else { PyUnicode_AsASCIIString(o); return NULL; } #else return PyUnicode_AsUTF8AndSize(o, length); #endif #endif } else #endif #if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) if (PyByteArray_Check(o)) { *length = PyByteArray_GET_SIZE(o); return PyByteArray_AS_STRING(o); } else #endif { char* result; int r = PyBytes_AsStringAndSize(o, &result, length); if (unlikely(r < 0)) { return NULL; } else { return result; } } } static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { int is_true = x == Py_True; if (is_true | (x == Py_False) | (x == Py_None)) return is_true; else return PyObject_IsTrue(x); } static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) { PyNumberMethods *m; const char *name = NULL; PyObject *res = NULL; #if PY_MAJOR_VERSION < 3 if (PyInt_Check(x) || PyLong_Check(x)) #else if (PyLong_Check(x)) #endif return __Pyx_NewRef(x); m = Py_TYPE(x)->tp_as_number; #if PY_MAJOR_VERSION < 3 if (m && m->nb_int) { name = "int"; res = PyNumber_Int(x); } else if (m && m->nb_long) { name = "long"; res = PyNumber_Long(x); } #else if (m && m->nb_int) { name = "int"; res = PyNumber_Long(x); } #endif if (res) { #if PY_MAJOR_VERSION < 3 if (!PyInt_Check(res) && !PyLong_Check(res)) { #else if (!PyLong_Check(res)) { #endif PyErr_Format(PyExc_TypeError, "__%.4s__ returned non-%.4s (type %.200s)", name, name, Py_TYPE(res)->tp_name); Py_DECREF(res); return NULL; } } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "an integer is required"); } return res; } static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { Py_ssize_t ival; PyObject *x; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_CheckExact(b))) { if (sizeof(Py_ssize_t) >= sizeof(long)) return PyInt_AS_LONG(b); else return PyInt_AsSsize_t(x); } #endif if (likely(PyLong_CheckExact(b))) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)b)->ob_digit; const Py_ssize_t size = Py_SIZE(b); if (likely(__Pyx_sst_abs(size) <= 1)) { ival = likely(size) ? digits[0] : 0; if (size == -1) ival = -ival; return ival; } else { switch (size) { case 2: if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case -2: if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case 3: if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case -3: if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case 4: if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case -4: if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; } } #endif return PyLong_AsSsize_t(b); } x = PyNumber_Index(b); if (!x) return -1; ival = PyInt_AsSsize_t(x); Py_DECREF(x); return ival; } static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { return PyInt_FromSize_t(ival); } #endif /* Py_PYTHON_H */ aiohttp-0.20.2/aiohttp/streams.py0000664000175000017500000004142512640574137017546 0ustar andrewandrew00000000000000import sys import asyncio import collections import functools import traceback from .log import internal_logger __all__ = ( 'EofStream', 'StreamReader', 'DataQueue', 'ChunksQueue', 'FlowControlStreamReader', 'FlowControlDataQueue', 'FlowControlChunksQueue') PY_35 = sys.version_info >= (3, 5) EOF_MARKER = b'' DEFAULT_LIMIT = 2 ** 16 class EofStream(Exception): """eof stream indication.""" class AsyncStreamIterator: def __init__(self, read_func): self.read_func = read_func @asyncio.coroutine def __aiter__(self): return self @asyncio.coroutine def __anext__(self): try: rv = yield from self.read_func() except EofStream: raise StopAsyncIteration # NOQA if rv == EOF_MARKER: raise StopAsyncIteration # NOQA return rv class AsyncStreamReaderMixin: if PY_35: @asyncio.coroutine def __aiter__(self): return AsyncStreamIterator(self.readline) def iter_chunked(self, n): """Returns an asynchronous iterator that yields chunks of size n. .. versionadded:: Python-3.5 available for Python 3.5+ only """ return AsyncStreamIterator(lambda: self.read(n)) def iter_any(self): """Returns an asynchronous iterator that yields slices of data as they come. .. versionadded:: Python-3.5 available for Python 3.5+ only """ return AsyncStreamIterator(self.readany) class StreamReader(asyncio.StreamReader, AsyncStreamReaderMixin): """An enhancement of :class:`asyncio.StreamReader`. Supports asynchronous iteration by line, chunk or as available:: async for line in reader: ... async for chunk in reader.iter_chunked(1024): ... async for slice in reader.iter_any(): ... .. automethod:: AsyncStreamReaderMixin.iter_chunked .. automethod:: AsyncStreamReaderMixin.iter_any """ total_bytes = 0 def __init__(self, limit=DEFAULT_LIMIT, loop=None): self._limit = limit if loop is None: loop = asyncio.get_event_loop() self._loop = loop self._buffer = collections.deque() self._buffer_size = 0 self._buffer_offset = 0 self._eof = False self._waiter = None self._eof_waiter = None self._exception = None def __repr__(self): info = ['StreamReader'] if self._buffer_size: info.append('%d bytes' % self._buffer_size) if self._eof: info.append('eof') if self._limit != DEFAULT_LIMIT: info.append('l=%d' % self._limit) if self._waiter: info.append('w=%r' % self._waiter) if self._exception: info.append('e=%r' % self._exception) return '<%s>' % ' '.join(info) def exception(self): return self._exception def set_exception(self, exc): self._exception = exc waiter = self._waiter if waiter is not None: self._waiter = None if not waiter.cancelled(): waiter.set_exception(exc) def feed_eof(self): self._eof = True waiter = self._waiter if waiter is not None: self._waiter = None if not waiter.cancelled(): waiter.set_result(True) waiter = self._eof_waiter if waiter is not None: self._eof_waiter = None if not waiter.cancelled(): waiter.set_result(True) def is_eof(self): """Return True if 'feed_eof' was called.""" return self._eof def at_eof(self): """Return True if the buffer is empty and 'feed_eof' was called.""" return self._eof and not self._buffer @asyncio.coroutine def wait_eof(self): if self._eof: return assert self._eof_waiter is None self._eof_waiter = asyncio.Future(loop=self._loop) try: yield from self._eof_waiter finally: self._eof_waiter = None def feed_data(self, data): assert not self._eof, 'feed_data after feed_eof' if not data: return self._buffer.append(data) self._buffer_size += len(data) self.total_bytes += len(data) waiter = self._waiter if waiter is not None: self._waiter = None if not waiter.cancelled(): waiter.set_result(False) def _create_waiter(self, func_name): # 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 # which coroutine would get the next data. if self._waiter is not None: raise RuntimeError('%s() called while another coroutine is ' 'already waiting for incoming data' % func_name) return asyncio.Future(loop=self._loop) @asyncio.coroutine def readline(self): if self._exception is not None: raise self._exception line = [] line_size = 0 not_enough = True while not_enough: while self._buffer and not_enough: offset = self._buffer_offset ichar = self._buffer[0].find(b'\n', offset) + 1 # Read from current offset to found b'\n' or to the end. data = self._read_nowait(ichar - offset if ichar else 0) line.append(data) line_size += len(data) if ichar: not_enough = False if line_size > self._limit: raise ValueError('Line is too long') if self._eof: break if not_enough: self._waiter = self._create_waiter('readline') try: yield from self._waiter finally: self._waiter = None return b''.join(line) @asyncio.coroutine def read(self, n=-1): if self._exception is not None: raise self._exception # migration problem; with DataQueue you have to catch # EofStream exception, so common way is to run payload.read() inside # infinite loop. what can cause real infinite loop with StreamReader # lets keep this code one major release. if __debug__: if self._eof and not self._buffer: self._eof_counter = getattr(self, '_eof_counter', 0) + 1 if self._eof_counter > 5: stack = traceback.format_stack() internal_logger.warning( 'Multiple access to StreamReader in eof state, ' 'might be infinite loop: \n%s', stack) if not n: return EOF_MARKER if n < 0: # This used to just loop creating a new waiter hoping to # collect everything in self._buffer, but that would # deadlock if the subprocess sends more than self.limit # bytes. So just call self.readany() until EOF. blocks = [] while True: block = yield from self.readany() if not block: break blocks.append(block) return b''.join(blocks) if not self._buffer and not self._eof: self._waiter = self._create_waiter('read') try: yield from self._waiter finally: self._waiter = None return self._read_nowait(n) @asyncio.coroutine def readany(self): if self._exception is not None: raise self._exception if not self._buffer and not self._eof: self._waiter = self._create_waiter('readany') try: yield from self._waiter finally: self._waiter = None return self._read_nowait() @asyncio.coroutine def readexactly(self, n): if self._exception is not None: raise self._exception # There used to be "optimized" code here. It created its own # Future and waited until self._buffer had at least the n # bytes, then called read(n). Unfortunately, this could pause # the transport if the argument was larger than the pause # limit (which is twice self._limit). So now we just read() # into a local buffer. blocks = [] while n > 0: block = yield from self.read(n) if not block: partial = b''.join(blocks) raise asyncio.streams.IncompleteReadError( partial, len(partial) + n) blocks.append(block) n -= len(block) return b''.join(blocks) def read_nowait(self, n=None): if self._exception is not None: raise self._exception if self._waiter and not self._waiter.done(): raise RuntimeError( 'Called while some coroutine is waiting for incoming data.') return self._read_nowait(n) def _read_nowait(self, n=None): if not self._buffer: return EOF_MARKER first_buffer = self._buffer[0] offset = self._buffer_offset if n and len(first_buffer) - offset > n: data = first_buffer[offset:offset + n] self._buffer_offset += n elif offset: self._buffer.popleft() data = first_buffer[offset:] self._buffer_offset = 0 else: data = self._buffer.popleft() self._buffer_size -= len(data) return data class EmptyStreamReader(AsyncStreamReaderMixin): def exception(self): return None def set_exception(self, exc): pass def feed_eof(self): pass def is_eof(self): return True def at_eof(self): return True @asyncio.coroutine def wait_eof(self): return def feed_data(self, data): pass @asyncio.coroutine def readline(self): return EOF_MARKER @asyncio.coroutine def read(self, n=-1): return EOF_MARKER @asyncio.coroutine def readany(self): return EOF_MARKER @asyncio.coroutine def readexactly(self, n): raise asyncio.streams.IncompleteReadError(b'', n) def read_nowait(self): return EOF_MARKER class DataQueue: """DataQueue is a general-purpose blocking queue with one reader.""" def __init__(self, *, loop=None): self._loop = loop self._eof = False self._waiter = None self._exception = None self._size = 0 self._buffer = collections.deque() def is_eof(self): return self._eof def at_eof(self): return self._eof and not self._buffer def exception(self): return self._exception def set_exception(self, exc): self._exception = exc waiter = self._waiter if waiter is not None: self._waiter = None if not waiter.done(): waiter.set_exception(exc) def feed_data(self, data, size=0): self._size += size self._buffer.append((data, size)) waiter = self._waiter if waiter is not None: self._waiter = None if not waiter.cancelled(): waiter.set_result(True) def feed_eof(self): self._eof = True waiter = self._waiter if waiter is not None: self._waiter = None if not waiter.cancelled(): waiter.set_result(False) @asyncio.coroutine def read(self): if not self._buffer and not self._eof: if self._exception is not None: raise self._exception assert not self._waiter self._waiter = asyncio.Future(loop=self._loop) try: yield from self._waiter except (asyncio.CancelledError, asyncio.TimeoutError): self._waiter = None raise if self._buffer: data, size = self._buffer.popleft() self._size -= size return data else: if self._exception is not None: raise self._exception else: raise EofStream if PY_35: @asyncio.coroutine def __aiter__(self): return AsyncStreamIterator(self.read) class ChunksQueue(DataQueue): """Like a :class:`DataQueue`, but for binary chunked data transfer.""" @asyncio.coroutine def read(self): try: return (yield from super().read()) except EofStream: return EOF_MARKER readany = read def maybe_resume(func): @asyncio.coroutine @functools.wraps(func) def wrapper(self, *args, **kw): result = yield from func(self, *args, **kw) if self._stream.paused: if self._buffer_size < self._b_limit: try: self._stream.transport.resume_reading() except (AttributeError, NotImplementedError): pass else: self._stream.paused = False else: if self._buffer_size > self._b_limit: try: self._stream.transport.pause_reading() except (AttributeError, NotImplementedError): pass else: self._stream.paused = True return result return wrapper class FlowControlStreamReader(StreamReader): def __init__(self, stream, limit=DEFAULT_LIMIT, *args, **kwargs): super().__init__(*args, **kwargs) self._stream = stream self._b_limit = limit * 2 # resume transport reading if stream.paused: try: self._stream.transport.resume_reading() except (AttributeError, NotImplementedError): pass def feed_data(self, data, size=0): has_waiter = self._waiter is not None and not self._waiter.cancelled() super().feed_data(data) if (not self._stream.paused and not has_waiter and self._buffer_size > self._b_limit): try: self._stream.transport.pause_reading() except (AttributeError, NotImplementedError): pass else: self._stream.paused = True @maybe_resume def read(self, n=-1): return (yield from super().read(n)) @maybe_resume def readline(self): return (yield from super().readline()) @maybe_resume def readany(self): return (yield from super().readany()) @maybe_resume def readexactly(self, n): return (yield from super().readexactly(n)) class FlowControlDataQueue(DataQueue): """FlowControlDataQueue resumes and pauses an underlying stream. It is a destination for parsed data.""" def __init__(self, stream, *, limit=DEFAULT_LIMIT, loop=None): super().__init__(loop=loop) self._stream = stream self._limit = limit * 2 # resume transport reading if stream.paused: try: self._stream.transport.resume_reading() except (AttributeError, NotImplementedError): pass else: self._stream.paused = False def feed_data(self, data, size): has_waiter = self._waiter is not None and not self._waiter.cancelled() super().feed_data(data, size) if (not self._stream.paused and not has_waiter and self._size > self._limit): try: self._stream.transport.pause_reading() except (AttributeError, NotImplementedError): pass else: self._stream.paused = True @asyncio.coroutine def read(self): result = yield from super().read() if self._stream.paused: if self._size < self._limit: try: self._stream.transport.resume_reading() except (AttributeError, NotImplementedError): pass else: self._stream.paused = False else: if self._size > self._limit: try: self._stream.transport.pause_reading() except (AttributeError, NotImplementedError): pass else: self._stream.paused = True return result class FlowControlChunksQueue(FlowControlDataQueue): @asyncio.coroutine def read(self): try: return (yield from super().read()) except EofStream: return EOF_MARKER readany = read aiohttp-0.20.2/aiohttp/web_urldispatcher.py0000664000175000017500000004244512642547420021576 0ustar andrewandrew00000000000000import abc import asyncio import keyword import collections import mimetypes import re import os import sys import inspect from collections.abc import Sized, Iterable, Container from urllib.parse import urlencode, unquote from types import MappingProxyType from . import hdrs from .abc import AbstractRouter, AbstractMatchInfo, AbstractView from .protocol import HttpVersion11 from .web_exceptions import HTTPMethodNotAllowed, HTTPNotFound, HTTPNotModified from .web_reqrep import StreamResponse from .multidict import upstr __all__ = ('UrlDispatcher', 'UrlMappingMatchInfo', 'Route', 'PlainRoute', 'DynamicRoute', 'StaticRoute', 'View') PY_35 = sys.version_info >= (3, 5) class UrlMappingMatchInfo(dict, AbstractMatchInfo): def __init__(self, match_dict, route): super().__init__(match_dict) self._route = route @property def handler(self): return self._route.handler @property def route(self): return self._route def __repr__(self): return "".format(super().__repr__(), self._route) @asyncio.coroutine def _defaultExpectHandler(request): """Default handler for Except: 100-continue""" if request.version == HttpVersion11: request.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n") class Route(metaclass=abc.ABCMeta): def __init__(self, method, handler, name, *, expect_handler=None): if expect_handler is None: expect_handler = _defaultExpectHandler assert asyncio.iscoroutinefunction(expect_handler), \ 'Coroutine is expected, got {!r}'.format(expect_handler) self._method = method self._handler = handler self._name = name self._expect_handler = expect_handler @property def method(self): return self._method @property def handler(self): return self._handler @property def name(self): return self._name @abc.abstractmethod # pragma: no branch def match(self, path): """Return dict with info for given path or None if route cannot process path.""" @abc.abstractmethod # pragma: no branch def url(self, **kwargs): """Construct url for route with additional params.""" @asyncio.coroutine def handle_expect_header(self, request): return (yield from self._expect_handler(request)) @staticmethod def _append_query(url, query): if query is not None: return url + "?" + urlencode(query) else: return url class PlainRoute(Route): def __init__(self, method, handler, name, path, *, expect_handler=None): super().__init__(method, handler, name, expect_handler=expect_handler) self._path = path def match(self, path): # string comparison is about 10 times faster than regexp matching if self._path == path: return {} else: return None def url(self, *, query=None): return self._append_query(self._path, query) def __repr__(self): name = "'" + self.name + "' " if self.name is not None else "" return " {handler!r}".format( name=name, method=self.method, path=self._path, handler=self.handler) class DynamicRoute(Route): def __init__(self, method, handler, name, pattern, formatter, *, expect_handler=None): super().__init__(method, handler, name, expect_handler=expect_handler) self._pattern = pattern self._formatter = formatter def match(self, path): match = self._pattern.match(path) if match is None: return None else: return match.groupdict() def url(self, *, parts, query=None): url = self._formatter.format_map(parts) return self._append_query(url, query) def __repr__(self): name = "'" + self.name + "' " if self.name is not None else "" return (" {handler!r}" .format(name=name, method=self.method, formatter=self._formatter, handler=self.handler)) class StaticRoute(Route): def __init__(self, name, prefix, directory, *, expect_handler=None, chunk_size=256*1024, response_factory=StreamResponse): assert prefix.startswith('/'), prefix assert prefix.endswith('/'), prefix super().__init__( 'GET', self.handle, name, expect_handler=expect_handler) self._prefix = prefix self._prefix_len = len(self._prefix) self._directory = os.path.abspath(directory) + os.sep self._chunk_size = chunk_size self._response_factory = response_factory if not os.path.isdir(self._directory): raise ValueError( "No directory exists at '{}'".format(self._directory)) if bool(os.environ.get("AIOHTTP_NOSENDFILE")): self._sendfile = self._sendfile_fallback def match(self, path): if not path.startswith(self._prefix): return None return {'filename': path[self._prefix_len:]} def url(self, *, filename, query=None): while filename.startswith('/'): filename = filename[1:] url = self._prefix + filename return self._append_query(url, query) def _sendfile_cb(self, fut, out_fd, in_fd, offset, count, loop, registered): if registered: loop.remove_writer(out_fd) try: n = os.sendfile(out_fd, in_fd, offset, count) if n == 0: # EOF reached n = count except (BlockingIOError, InterruptedError): n = 0 except Exception as exc: fut.set_exception(exc) return if n < count: loop.add_writer(out_fd, self._sendfile_cb, fut, out_fd, in_fd, offset + n, count - n, loop, True) else: fut.set_result(None) @asyncio.coroutine def _sendfile_system(self, req, resp, fobj, count): """ Write `count` bytes of `fobj` to `resp` starting from `offset` using the ``sendfile`` system call. `req` should be a :obj:`aiohttp.web.Request` instance. `resp` should be a :obj:`aiohttp.web.StreamResponse` instance. `fobj` should be an open file object. `offset` should be an integer >= 0. `count` should be an integer > 0. """ transport = req.transport if transport.get_extra_info("sslcontext"): yield from self._sendfile_fallback(req, resp, fobj, count) return yield from resp.drain() loop = req.app.loop out_fd = transport.get_extra_info("socket").fileno() in_fd = fobj.fileno() fut = asyncio.Future(loop=loop) self._sendfile_cb(fut, out_fd, in_fd, 0, count, loop, False) yield from fut @asyncio.coroutine def _sendfile_fallback(self, req, resp, fobj, count): """ Mimic the :meth:`_sendfile_system` method, but without using the ``sendfile`` system call. This should be used on systems that don't support the ``sendfile`` system call. To avoid blocking the event loop & to keep memory usage low, `fobj` is transferred in chunks controlled by the `chunk_size` argument to :class:`StaticRoute`. """ chunk_size = self._chunk_size chunk = fobj.read(chunk_size) while chunk and count > chunk_size: resp.write(chunk) yield from resp.drain() count = count - chunk_size chunk = fobj.read(chunk_size) if chunk: resp.write(chunk[:count]) yield from resp.drain() if hasattr(os, "sendfile"): # pragma: no cover _sendfile = _sendfile_system else: # pragma: no cover _sendfile = _sendfile_fallback @asyncio.coroutine def handle(self, request): filename = request.match_info['filename'] filepath = os.path.abspath(os.path.join(self._directory, filename)) if not filepath.startswith(self._directory): raise HTTPNotFound() if not os.path.exists(filepath) or not os.path.isfile(filepath): raise HTTPNotFound() st = os.stat(filepath) modsince = request.if_modified_since if modsince is not None and st.st_mtime <= modsince.timestamp(): raise HTTPNotModified() ct, encoding = mimetypes.guess_type(filepath) if not ct: ct = 'application/octet-stream' resp = self._response_factory() resp.content_type = ct if encoding: resp.headers[hdrs.CONTENT_ENCODING] = encoding resp.last_modified = st.st_mtime file_size = st.st_size resp.content_length = file_size resp.set_tcp_cork(True) try: yield from resp.prepare(request) with open(filepath, 'rb') as f: yield from self._sendfile(request, resp, f, file_size) finally: resp.set_tcp_nodelay(True) return resp def __repr__(self): name = "'" + self.name + "' " if self.name is not None else "" return " {directory!r}".format( name=name, method=self.method, path=self._prefix, directory=self._directory) class SystemRoute(Route): def __init__(self, status, reason): super().__init__(hdrs.METH_ANY, None, None) self._status = status self._reason = reason def url(self, **kwargs): raise RuntimeError(".url() is not allowed for SystemRoute") def match(self, path): return None @property def status(self): return self._status @property def reason(self): return self._reason def __repr__(self): return "".format(status=self._status, reason=self._reason) class _NotFoundMatchInfo(UrlMappingMatchInfo): route = SystemRoute(404, 'Not Found') def __init__(self): super().__init__({}, None) @property def handler(self): return self._not_found @asyncio.coroutine def _not_found(self, request): raise HTTPNotFound() def __repr__(self): return "" class _MethodNotAllowedMatchInfo(UrlMappingMatchInfo): route = SystemRoute(405, 'Method Not Allowed') def __init__(self, method, allowed_methods): super().__init__({}, None) self._method = method self._allowed_methods = allowed_methods @property def handler(self): return self._not_allowed @asyncio.coroutine def _not_allowed(self, request): raise HTTPMethodNotAllowed(self._method, self._allowed_methods) def __repr__(self): return ("" .format(self._method, ', '.join(sorted(self._allowed_methods)))) class View(AbstractView): @asyncio.coroutine def __iter__(self): if self.request.method not in hdrs.METH_ALL: self._raise_allowed_methods() method = getattr(self, self.request.method.lower(), None) if method is None: self._raise_allowed_methods() resp = yield from method() return resp if PY_35: def __await__(self): return (yield from self.__iter__()) def _raise_allowed_methods(self): allowed_methods = {m for m in hdrs.METH_ALL if hasattr(self, m)} raise HTTPMethodNotAllowed(self.request.method, allowed_methods) class RoutesView(Sized, Iterable, Container): __slots__ = '_urls' def __init__(self, urls): self._urls = urls def __len__(self): return len(self._urls) def __iter__(self): yield from self._urls def __contains__(self, route): return route in self._urls class UrlDispatcher(AbstractRouter, collections.abc.Mapping): DYN = re.compile(r'^\{(?P[a-zA-Z][_a-zA-Z0-9]*)\}$') DYN_WITH_RE = re.compile( r'^\{(?P[a-zA-Z][_a-zA-Z0-9]*):(?P.+)\}$') GOOD = r'[^{}/]+' ROUTE_RE = re.compile(r'(\{[_a-zA-Z][^{}]*(?:\{[^{}]*\}[^{}]*)*\})') NAME_SPLIT_RE = re.compile('[.:-]') METHODS = {hdrs.METH_ANY, hdrs.METH_POST, hdrs.METH_GET, hdrs.METH_PUT, hdrs.METH_DELETE, hdrs.METH_PATCH, hdrs.METH_HEAD, hdrs.METH_OPTIONS} def __init__(self): super().__init__() self._urls = [] self._routes = {} @asyncio.coroutine def resolve(self, request): path = request.raw_path method = request.method allowed_methods = set() for route in self._urls: match_dict = route.match(path) if match_dict is None: continue route_method = route.method if route_method == method or route_method == hdrs.METH_ANY: # Unquote separate matching parts match_dict = {key: unquote(value) for key, value in match_dict.items()} return UrlMappingMatchInfo(match_dict, route) allowed_methods.add(route_method) else: if allowed_methods: return _MethodNotAllowedMatchInfo(method, allowed_methods) else: return _NotFoundMatchInfo() def __iter__(self): return iter(self._routes) def __len__(self): return len(self._routes) def __contains__(self, name): return name in self._routes def __getitem__(self, name): return self._routes[name] def routes(self): return RoutesView(self._urls) def named_routes(self): return MappingProxyType(self._routes) def register_route(self, route): assert isinstance(route, Route), 'Instance of Route class is required.' name = route.name if name is not None: parts = self.NAME_SPLIT_RE.split(name) for part in parts: if not part.isidentifier() or keyword.iskeyword(part): raise ValueError('Incorrect route name {!r}, ' 'the name should be a sequence of ' 'python identifiers separated ' 'by dash, dot or column'.format(name)) if name in self._routes: raise ValueError('Duplicate {!r}, ' 'already handled by {!r}' .format(name, self._routes[name])) self._routes[name] = route self._urls.append(route) def add_route(self, method, path, handler, *, name=None, expect_handler=None): if not path.startswith('/'): raise ValueError("path should be started with /") assert callable(handler), handler if asyncio.iscoroutinefunction(handler): pass elif inspect.isgeneratorfunction(handler): pass elif isinstance(handler, type) and issubclass(handler, AbstractView): pass else: handler = asyncio.coroutine(handler) method = upstr(method) if method not in self.METHODS: raise ValueError("{} is not allowed HTTP method".format(method)) if not ('{' in path or '}' in path or self.ROUTE_RE.search(path)): route = PlainRoute( method, handler, name, path, expect_handler=expect_handler) self.register_route(route) return route pattern = '' formatter = '' for part in self.ROUTE_RE.split(path): match = self.DYN.match(part) if match: pattern += '(?P<{}>{})'.format(match.group('var'), self.GOOD) formatter += '{' + match.group('var') + '}' continue match = self.DYN_WITH_RE.match(part) if match: pattern += '(?P<{var}>{re})'.format(**match.groupdict()) formatter += '{' + match.group('var') + '}' continue if '{' in part or '}' in part: raise ValueError("Invalid path '{}'['{}']".format(path, part)) formatter += part pattern += re.escape(part) try: compiled = re.compile('^' + pattern + '$') except re.error as exc: raise ValueError( "Bad pattern '{}': {}".format(pattern, exc)) from None route = DynamicRoute( method, handler, name, compiled, formatter, expect_handler=expect_handler) self.register_route(route) return route def add_static(self, prefix, path, *, name=None, expect_handler=None, chunk_size=256*1024, response_factory=StreamResponse): """ Adds static files view :param prefix - url prefix :param path - folder with files """ assert prefix.startswith('/') if not prefix.endswith('/'): prefix += '/' route = StaticRoute(name, prefix, path, expect_handler=expect_handler, chunk_size=chunk_size, response_factory=response_factory) self.register_route(route) return route aiohttp-0.20.2/aiohttp/_multidict.pyx0000664000175000017500000004351212607530676020417 0ustar andrewandrew00000000000000import sys from collections import abc from collections.abc import Iterable, Set from operator import itemgetter _marker = object() class upstr(str): """Case insensitive str.""" def __new__(cls, val='', encoding=sys.getdefaultencoding(), errors='strict'): if isinstance(val, (bytes, bytearray, memoryview)): val = str(val, encoding, errors) elif isinstance(val, str): pass else: val = str(val) val = val.upper() return str.__new__(cls, val) def upper(self): return self cdef _eq(self, other): cdef _Base typed_self cdef _Base typed_other cdef int is_left_base, is_right_base is_left_base = isinstance(self, _Base) is_right_base = isinstance(other, _Base) if is_left_base and is_right_base: return (<_Base>self)._items == (<_Base>other)._items elif is_left_base and isinstance(other, abc.Mapping): return (<_Base>self)._eq_to_mapping(other) elif is_right_base and isinstance(self, abc.Mapping): return (<_Base>other)._eq_to_mapping(self) else: return NotImplemented cdef class _Pair: cdef object _key cdef object _value def __cinit__(self, key, value): self._key = key self._value = value def __richcmp__(self, other, op): cdef _Pair left, right if not isinstance(self, _Pair) or not isinstance(other, _Pair): return NotImplemented left = <_Pair>self right = <_Pair>other if op == 2: # == return left._key == right._key and left._value == right._value elif op == 3: # != return left._key != right._key and left._value != right._value cdef class _Base: cdef list _items cdef object _upstr cdef object marker def __cinit__(self): self._upstr = upstr self.marker = _marker cdef str _upper(self, s): if type(s) is self._upstr: return s return s def getall(self, key, default=_marker): """Return a list of all values matching the key.""" return self._getall(self._upper(key), default) cdef _getall(self, str key, default): cdef list res cdef _Pair item key = self._upper(key) res = [] for i in self._items: item = <_Pair>i if item._key == key: res.append(item._value) if res: return res if not res and default is not self.marker: return default raise KeyError('Key not found: %r' % key) def getone(self, key, default=_marker): """Get first value matching the key.""" return self._getone(self._upper(key), default) cdef _getone(self, str key, default): cdef _Pair item key = self._upper(key) for i in self._items: item = <_Pair>i if item._key == key: return item._value if default is not self.marker: return default raise KeyError('Key not found: %r' % key) # Mapping interface # def __getitem__(self, key): return self._getone(self._upper(key), self.marker) def get(self, key, default=None): """Get first value matching the key. The method is alias for .getone(). """ return self._getone(self._upper(key), default) def __contains__(self, key): return self._contains(self._upper(key)) cdef _contains(self, str key): cdef _Pair item key = self._upper(key) for i in self._items: item = <_Pair>i if item._key == key: return True return False def __iter__(self): return iter(self.keys()) def __len__(self): return len(self._items) cpdef keys(self): """Return a new view of the dictionary's keys.""" return _KeysView.__new__(_KeysView, self._items) def items(self): """Return a new view of the dictionary's items *(key, value) pairs).""" return _ItemsView.__new__(_ItemsView, self._items) def values(self): """Return a new view of the dictionary's values.""" return _ValuesView.__new__(_ValuesView, self._items) def __repr__(self): cdef _Pair item lst = [] for i in self._items: item = <_Pair>i lst.append("'{}': {!r}".format(item._key, item._value)) body = ', '.join(lst) return '<{}({})>'.format(self.__class__.__name__, body) cdef _eq_to_mapping(self, other): cdef _Pair item left_keys = set(self.keys()) right_keys = set(other.keys()) if left_keys != right_keys: return False if len(self._items) != len(right_keys): return False for i in self._items: item = <_Pair>i nv = other.get(item._key, self.marker) if item._value != nv: return False return True def __richcmp__(self, other, op): if op == 2: # == return _eq(self, other) elif op == 3: # != ret = _eq(self, other) if ret is NotImplemented: return ret else: return not ret else: return NotImplemented cdef class MultiDictProxy(_Base): def __init__(self, arg): cdef MultiDict mdict if not isinstance(arg, MultiDict): raise TypeError( 'MultiDictProxy requires MultiDict instance, not {}'.format( type(arg))) mdict = arg self._items = mdict._items def copy(self): """Return a copy of itself.""" return MultiDict(self._items) abc.Mapping.register(MultiDictProxy) cdef class CIMultiDictProxy(MultiDictProxy): def __init__(self, arg): cdef CIMultiDict mdict if not isinstance(arg, CIMultiDict): raise TypeError( 'CIMultiDictProxy requires CIMultiDict instance, not {}'.format( type(arg))) mdict = arg self._items = mdict._items cdef str _upper(self, s): if type(s) is self._upstr: return s return s.upper() def copy(self): """Return a copy of itself.""" return CIMultiDict(self._items) abc.Mapping.register(CIMultiDictProxy) cdef class MultiDict(_Base): """An ordered dictionary that can have multiple values for each key.""" def __init__(self, *args, **kwargs): self._items = [] self._extend(args, kwargs, self.__class__.__name__, 1) cdef _extend(self, tuple args, dict kwargs, name, int do_add): cdef _Pair item cdef str key if len(args) > 1: raise TypeError("{} takes at most 1 positional argument" " ({} given)".format(name, len(args))) if args: arg = args[0] if isinstance(arg, _Base): for i in (<_Base>arg)._items: item = <_Pair>i key = self._upper(item._key) value = item._value if do_add: self._add(key, value) else: self._replace(key, value) elif hasattr(arg, 'items'): for i in arg.items(): if isinstance(i, _Pair): item = <_Pair>i key = item._key value = item._value else: key = self._upper(i[0]) value = i[1] if do_add: self._add(key, value) else: self._replace(key, value) else: for i in arg: if isinstance(i, _Pair): item = <_Pair>i key = item._key value = item._value else: if not len(i) == 2: raise TypeError( "{} takes either dict or list of (key, value) " "tuples".format(name)) key = self._upper(i[0]) value = i[1] if do_add: self._add(key, value) else: self._replace(key, value) for key, value in kwargs.items(): key = self._upper(key) if do_add: self._add(key, value) else: self._replace(key, value) cdef _add(self, str key, value): self._items.append(_Pair.__new__(_Pair, key, value)) cdef _replace(self, str key, value): self._remove(key, 0) self._items.append(_Pair.__new__(_Pair, key, value)) def add(self, key, value): """Add the key and value, not overwriting any previous value.""" self._add(self._upper(key), value) def copy(self): """Return a copy of itself.""" cls = self.__class__ return cls(self._items) def extend(self, *args, **kwargs): """Extend current MultiDict with more values. This method must be used instead of update. """ self._extend(args, kwargs, "extend", 1) def clear(self): """Remove all items from MultiDict""" self._items.clear() # MutableMapping interface # def __setitem__(self, key, value): self._replace(self._upper(key), value) def __delitem__(self, key): self._remove(self._upper(key), True) cdef _remove(self, str key, int raise_key_error): cdef _Pair item cdef int found found = False for i in range(len(self._items) - 1, -1, -1): item = <_Pair>self._items[i] if item._key == key: del self._items[i] found = True if not found and raise_key_error: raise KeyError(key) def setdefault(self, key, default=None): """Return value for key, set value to default if key is not present.""" cdef str skey cdef _Pair item skey = self._upper(key) for i in self._items: item = <_Pair>i if item._key == skey: return item._value self._add(skey, default) return default def pop(self, key, default=_marker): """Remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised. """ cdef int found cdef str skey cdef object value cdef _Pair item skey = self._upper(key) value = None found = False for i in range(len(self._items) - 1, -1, -1): item = <_Pair>self._items[i] if item._key == key: value = item._value del self._items[i] found = True if not found: if default is self.marker: raise KeyError(key) else: return default else: return value def popitem(self): """Remove and return an arbitrary (key, value) pair.""" cdef _Pair item if self._items: item = <_Pair>self._items.pop(0) return (item._key, item._value) else: raise KeyError("empty multidict") def update(self, *args, **kwargs): """Update the dictionary from *other*, overwriting existing keys.""" self._extend(args, kwargs, "update", 0) abc.MutableMapping.register(MultiDict) cdef class CIMultiDict(MultiDict): """An ordered dictionary that can have multiple values for each key.""" cdef str _upper(self, s): if type(s) is self._upstr: return s return s.upper() abc.MutableMapping.register(CIMultiDict) cdef class _ViewBase: cdef list _items def __cinit__(self, list items): self._items = items def __len__(self): return len(self._items) cdef class _ViewBaseSet(_ViewBase): def __richcmp__(self, other, op): if op == 0: # < if not isinstance(other, Set): return NotImplemented return len(self) < len(other) and self <= other elif op == 1: # <= if not isinstance(other, Set): return NotImplemented if len(self) > len(other): return False for elem in self: if elem not in other: return False return True elif op == 2: # == if not isinstance(other, Set): return NotImplemented return len(self) == len(other) and self <= other elif op == 3: # != return not self == other elif op == 4: # > if not isinstance(other, Set): return NotImplemented return len(self) > len(other) and self >= other elif op == 5: # >= if not isinstance(other, Set): return NotImplemented if len(self) < len(other): return False for elem in other: if elem not in self: return False return True def __and__(self, other): if not isinstance(other, Iterable): return NotImplemented if not isinstance(other, Set): other = set(other) return set(self) & other def __or__(self, other): if not isinstance(other, Iterable): return NotImplemented if not isinstance(other, Set): other = set(other) return set(self) | other def __sub__(self, other): if not isinstance(other, Iterable): return NotImplemented if not isinstance(other, Set): other = set(other) return set(self) - other def __xor__(self, other): if not isinstance(other, Set): if not isinstance(other, Iterable): return NotImplemented other = set(other) return set(self) ^ other cdef class _ItemsIter: cdef list _items cdef int _current cdef int _len def __cinit__(self, items): self._items = items self._current = 0 self._len = len(self._items) def __iter__(self): return self def __next__(self): if self._current == self._len: raise StopIteration item = <_Pair>self._items[self._current] self._current += 1 return (item._key, item._value) cdef class _ItemsView(_ViewBaseSet): def isdisjoint(self, other): 'Return True if two sets have a null intersection.' cdef _Pair item for i in self._items: item = <_Pair>i t = (item._key, item._value) if t in other: return False return True def __contains__(self, i): cdef _Pair item assert isinstance(i, tuple) or isinstance(i, list) assert len(i) == 2 item = _Pair.__new__(_Pair, i[0], i[1]) return item in self._items def __iter__(self): return _ItemsIter.__new__(_ItemsIter, self._items) def __repr__(self): cdef _Pair item lst = [] for i in self._items: item = <_Pair>i lst.append("{!r}: {!r}".format(item._key, item._value)) body = ', '.join(lst) return '{}({})'.format(self.__class__.__name__, body) abc.ItemsView.register(_ItemsView) cdef class _ValuesIter: cdef list _items cdef int _current cdef int _len def __cinit__(self, items): self._items = items self._current = 0 self._len = len(self._items) def __iter__(self): return self def __next__(self): if self._current == self._len: raise StopIteration item = <_Pair>self._items[self._current] self._current += 1 return item._value cdef class _ValuesView(_ViewBase): def __contains__(self, value): cdef _Pair item for i in self._items: item = <_Pair>i if item._value == value: return True return False def __iter__(self): return _ValuesIter.__new__(_ValuesIter, self._items) def __repr__(self): cdef _Pair item lst = [] for i in self._items: item = <_Pair>i lst.append("{!r}".format(item._value)) body = ', '.join(lst) return '{}({})'.format(self.__class__.__name__, body) abc.ValuesView.register(_ValuesView) cdef class _KeysIter: cdef list _items cdef int _current cdef int _len def __cinit__(self, items): self._items = items self._current = 0 self._len = len(self._items) def __iter__(self): return self def __next__(self): if self._current == self._len: raise StopIteration item = <_Pair>self._items[self._current] self._current += 1 return item._key cdef class _KeysView(_ViewBaseSet): def isdisjoint(self, other): 'Return True if two sets have a null intersection.' cdef _Pair item for i in self._items: item = <_Pair>i if item._key in other: return False return True def __contains__(self, value): cdef _Pair item for i in self._items: item = <_Pair>i if item._key == value: return True return False def __iter__(self): return _KeysIter.__new__(_KeysIter, self._items) def __repr__(self): cdef _Pair item lst = [] for i in self._items: item = <_Pair>i lst.append("{!r}".format(item._key)) body = ', '.join(lst) return '{}({})'.format(self.__class__.__name__, body) abc.KeysView.register(_KeysView) aiohttp-0.20.2/aiohttp/parsers.py0000664000175000017500000003666012634071642017550 0ustar andrewandrew00000000000000"""Parser is a generator function (NOT coroutine). Parser receives data with generator's send() method and sends data to destination DataQueue. Parser receives ParserBuffer and DataQueue objects as a parameters of the parser call, all subsequent send() calls should send bytes objects. Parser sends parsed `term` to destination buffer with DataQueue.feed_data() method. DataQueue object should implement two methods. feed_data() - parser uses this method to send parsed protocol data. feed_eof() - parser uses this method for indication of end of parsing stream. To indicate end of incoming data stream EofStream exception should be sent into parser. Parser could throw exceptions. There are three stages: * Data flow chain: 1. Application creates StreamParser object for storing incoming data. 2. StreamParser creates ParserBuffer as internal data buffer. 3. Application create parser and set it into stream buffer: parser = HttpRequestParser() data_queue = stream.set_parser(parser) 3. At this stage StreamParser creates DataQueue object and passes it and internal buffer into parser as an arguments. def set_parser(self, parser): output = DataQueue() self.p = parser(output, self._input) return output 4. Application waits data on output.read() while True: msg = yield from output.read() ... * Data flow: 1. asyncio's transport reads data from socket and sends data to protocol with data_received() call. 2. Protocol sends data to StreamParser with feed_data() call. 3. StreamParser sends data into parser with generator's send() method. 4. Parser processes incoming data and sends parsed data to DataQueue with feed_data() 5. Application received parsed data from DataQueue.read() * Eof: 1. StreamParser receives eof with feed_eof() call. 2. StreamParser throws EofStream exception into parser. 3. Then it unsets parser. _SocketSocketTransport -> -> "protocol" -> StreamParser -> "parser" -> DataQueue <- "application" """ import asyncio import asyncio.streams import inspect import socket from . import errors from .streams import FlowControlDataQueue, EofStream __all__ = ('EofStream', 'StreamParser', 'StreamProtocol', 'ParserBuffer', 'LinesParser', 'ChunksParser') DEFAULT_LIMIT = 2 ** 16 if hasattr(socket, 'TCP_CORK'): # pragma: no cover CORK = socket.TCP_CORK elif hasattr(socket, 'TCP_NOPUSH'): # pragma: no cover CORK = socket.TCP_NOPUSH else: # pragma: no cover CORK = None class StreamParser: """StreamParser manages incoming bytes stream and protocol parsers. StreamParser uses ParserBuffer as internal buffer. set_parser() sets current parser, it creates DataQueue object and sends ParserBuffer and DataQueue into parser generator. unset_parser() sends EofStream into parser and then removes it. """ def __init__(self, *, loop=None, buf=None, limit=DEFAULT_LIMIT, eof_exc_class=RuntimeError, **kwargs): self._loop = loop self._eof = False self._exception = None self._parser = None self._output = None self._limit = limit self._eof_exc_class = eof_exc_class self._buffer = buf if buf is not None else ParserBuffer() self.paused = False self.transport = None @property def output(self): return self._output def set_transport(self, transport): assert transport is None or self.transport is None, \ 'Transport already set' self.transport = transport def at_eof(self): return self._eof def exception(self): return self._exception def set_exception(self, exc): if isinstance(exc, ConnectionError): exc, old_exc = self._eof_exc_class(), exc exc.__cause__ = old_exc exc.__context__ = old_exc self._exception = exc if self._output is not None: self._output.set_exception(exc) self._output = None self._parser = None def feed_data(self, data): """send data to current parser or store in buffer.""" if data is None: return if self._parser: try: self._parser.send(data) except StopIteration: self._output.feed_eof() self._output = None self._parser = None except Exception as exc: self._output.set_exception(exc) self._output = None self._parser = None else: self._buffer.feed_data(data) def feed_eof(self): """send eof to all parsers, recursively.""" if self._parser: try: if self._buffer: self._parser.send(b'') self._parser.throw(EofStream()) except StopIteration: self._output.feed_eof() except EofStream: self._output.set_exception(self._eof_exc_class()) except Exception as exc: self._output.set_exception(exc) self._parser = None self._output = None self._eof = True def set_parser(self, parser, output=None): """set parser to stream. return parser's DataQueue.""" if self._parser: self.unset_parser() if output is None: output = FlowControlDataQueue( self, limit=self._limit, loop=self._loop) if self._exception: output.set_exception(self._exception) return output # init parser p = parser(output, self._buffer) assert inspect.isgenerator(p), 'Generator is required' try: # initialize parser with data and parser buffers next(p) except StopIteration: pass except Exception as exc: output.set_exception(exc) else: # parser still require more data self._parser = p self._output = output if self._eof: self.unset_parser() return output def unset_parser(self): """unset parser, send eof to the parser and then remove it.""" if self._parser is None: return # TODO: write test if hasattr(self._loop, 'is_closed'): if self._loop.is_closed(): # TODO: log something return try: self._parser.throw(EofStream()) except StopIteration: self._output.feed_eof() except EofStream: self._output.set_exception(self._eof_exc_class()) except Exception as exc: self._output.set_exception(exc) finally: self._output = None self._parser = None class StreamWriter(asyncio.streams.StreamWriter): def __init__(self, transport, protocol, reader, loop): self._transport = transport self._protocol = protocol self._reader = reader self._loop = loop self._tcp_nodelay = False self._tcp_cork = False self._socket = transport.get_extra_info('socket') @property def tcp_nodelay(self): return self._tcp_nodelay def set_tcp_nodelay(self, value): value = bool(value) if self._tcp_nodelay == value: return self._tcp_nodelay = value if self._socket is None: return if self._socket.family not in (socket.AF_INET, socket.AF_INET6): return if self._tcp_cork: self._tcp_cork = False if CORK is not None: # pragma: no branch self._socket.setsockopt(socket.IPPROTO_TCP, CORK, False) self._socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, value) @property def tcp_cork(self): return self._tcp_cork def set_tcp_cork(self, value): value = bool(value) if self._tcp_cork == value: return self._tcp_cork = value if self._socket is None: return if self._socket.family not in (socket.AF_INET, socket.AF_INET6): return if self._tcp_nodelay: self._socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, False) self._tcp_nodelay = False if CORK is not None: # pragma: no branch self._socket.setsockopt(socket.IPPROTO_TCP, CORK, value) class StreamProtocol(asyncio.streams.FlowControlMixin, asyncio.Protocol): """Helper class to adapt between Protocol and StreamReader.""" def __init__(self, *, loop=None, disconnect_error=RuntimeError, **kwargs): super().__init__(loop=loop) self.transport = None self.writer = None self.reader = StreamParser( loop=loop, eof_exc_class=disconnect_error, **kwargs) def is_connected(self): return self.transport is not None def connection_made(self, transport): self.transport = transport self.reader.set_transport(transport) self.writer = StreamWriter(transport, self, self.reader, self._loop) def connection_lost(self, exc): self.transport = self.writer = None self.reader.set_transport(None) if exc is None: self.reader.feed_eof() else: self.reader.set_exception(exc) super().connection_lost(exc) def data_received(self, data): self.reader.feed_data(data) def eof_received(self): self.reader.feed_eof() class _ParserBufferHelper: __slots__ = ('exception', 'data') def __init__(self, exception, data): self.exception = exception self.data = data class ParserBuffer: """ParserBuffer is NOT a bytearray extension anymore. ParserBuffer provides helper methods for parsers. """ __slots__ = ('_helper', '_writer', '_data') def __init__(self, *args): self._data = bytearray(*args) self._helper = _ParserBufferHelper(None, self._data) self._writer = self._feed_data(self._helper) next(self._writer) def exception(self): return self._helper.exception def set_exception(self, exc): self._helper.exception = exc @staticmethod def _feed_data(helper): while True: chunk = yield if chunk: helper.data.extend(chunk) if helper.exception: raise helper.exception def feed_data(self, data): if not self._helper.exception: self._writer.send(data) def read(self, size): """read() reads specified amount of bytes.""" while True: if self._helper.exception: raise self._helper.exception if len(self._data) >= size: data = self._data[:size] del self._data[:size] return data self._writer.send((yield)) def readsome(self, size=None): """reads size of less amount of bytes.""" while True: if self._helper.exception: raise self._helper.exception length = len(self._data) if length > 0: if size is None or length < size: size = length data = self._data[:size] del self._data[:size] return data self._writer.send((yield)) def readuntil(self, stop, limit=None): assert isinstance(stop, bytes) and stop, \ 'bytes is required: {!r}'.format(stop) stop_len = len(stop) while True: if self._helper.exception: raise self._helper.exception pos = self._data.find(stop) if pos >= 0: end = pos + stop_len size = end if limit is not None and size > limit: raise errors.LineLimitExceededParserError( 'Line is too long.', limit) data = self._data[:size] del self._data[:size] return data else: if limit is not None and len(self._data) > limit: raise errors.LineLimitExceededParserError( 'Line is too long.', limit) self._writer.send((yield)) def wait(self, size): """wait() waits for specified amount of bytes then returns data without changing internal buffer.""" while True: if self._helper.exception: raise self._helper.exception if len(self._data) >= size: return self._data[:size] self._writer.send((yield)) def waituntil(self, stop, limit=None): """waituntil() reads until `stop` bytes sequence.""" assert isinstance(stop, bytes) and stop, \ 'bytes is required: {!r}'.format(stop) stop_len = len(stop) while True: if self._helper.exception: raise self._helper.exception pos = self._data.find(stop) if pos >= 0: size = pos + stop_len if limit is not None and size > limit: raise errors.LineLimitExceededParserError( 'Line is too long. %s' % bytes(self._data), limit) return self._data[:size] else: if limit is not None and len(self._data) > limit: raise errors.LineLimitExceededParserError( 'Line is too long. %s' % bytes(self._data), limit) self._writer.send((yield)) def skip(self, size): """skip() skips specified amount of bytes.""" while len(self._data) < size: if self._helper.exception: raise self._helper.exception self._writer.send((yield)) del self._data[:size] def skipuntil(self, stop): """skipuntil() reads until `stop` bytes sequence.""" assert isinstance(stop, bytes) and stop, \ 'bytes is required: {!r}'.format(stop) stop_len = len(stop) while True: if self._helper.exception: raise self._helper.exception stop_line = self._data.find(stop) if stop_line >= 0: size = stop_line + stop_len del self._data[:size] return self._writer.send((yield)) def extend(self, data): self._data.extend(data) def __len__(self): return len(self._data) def __bytes__(self): return bytes(self._data) class LinesParser: """Lines parser. Lines parser splits a bytes stream into a chunks of data, each chunk ends with \\n symbol.""" def __init__(self, limit=DEFAULT_LIMIT): self._limit = limit def __call__(self, out, buf): try: while True: chunk = yield from buf.readuntil(b'\n', self._limit) out.feed_data(chunk, len(chunk)) except EofStream: pass class ChunksParser: """Chunks parser. Chunks parser splits a bytes stream into a specified size chunks of data.""" def __init__(self, size=8192): self._size = size def __call__(self, out, buf): try: while True: chunk = yield from buf.read(self._size) out.feed_data(chunk, len(chunk)) except EofStream: pass aiohttp-0.20.2/aiohttp/websocket.py0000664000175000017500000003425412637524575020067 0ustar andrewandrew00000000000000"""WebSocket protocol versions 13 and 8.""" import base64 import binascii import collections import hashlib import os import random import sys from struct import Struct from aiohttp import errors, hdrs from aiohttp.log import ws_logger __all__ = ('WebSocketParser', 'WebSocketWriter', 'do_handshake', 'Message', 'WebSocketError', 'MSG_TEXT', 'MSG_BINARY', 'MSG_CLOSE', 'MSG_PING', 'MSG_PONG') # Frame opcodes defined in the spec. OPCODE_CONTINUATION = 0x0 MSG_TEXT = OPCODE_TEXT = 0x1 MSG_BINARY = OPCODE_BINARY = 0x2 MSG_CLOSE = OPCODE_CLOSE = 0x8 MSG_PING = OPCODE_PING = 0x9 MSG_PONG = OPCODE_PONG = 0xa CLOSE_OK = 1000 CLOSE_GOING_AWAY = 1001 CLOSE_PROTOCOL_ERROR = 1002 CLOSE_UNSUPPORTED_DATA = 1003 CLOSE_INVALID_TEXT = 1007 CLOSE_POLICY_VIOLATION = 1008 CLOSE_MESSAGE_TOO_BIG = 1009 CLOSE_MANDATORY_EXTENSION = 1010 CLOSE_INTERNAL_ERROR = 1011 ALLOWED_CLOSE_CODES = ( CLOSE_OK, CLOSE_GOING_AWAY, CLOSE_PROTOCOL_ERROR, CLOSE_UNSUPPORTED_DATA, CLOSE_INVALID_TEXT, CLOSE_POLICY_VIOLATION, CLOSE_MESSAGE_TOO_BIG, CLOSE_MANDATORY_EXTENSION, CLOSE_INTERNAL_ERROR, ) WS_KEY = b'258EAFA5-E914-47DA-95CA-C5AB0DC85B11' WS_HDRS = (hdrs.UPGRADE, hdrs.CONNECTION, hdrs.SEC_WEBSOCKET_VERSION, hdrs.SEC_WEBSOCKET_KEY, hdrs.SEC_WEBSOCKET_PROTOCOL) Message = collections.namedtuple('Message', ['tp', 'data', 'extra']) UNPACK_LEN2 = Struct('!H').unpack_from UNPACK_LEN3 = Struct('!Q').unpack_from UNPACK_CLOSE_CODE = Struct('!H').unpack PACK_LEN1 = Struct('!BB').pack PACK_LEN2 = Struct('!BBH').pack PACK_LEN3 = Struct('!BBQ').pack PACK_CLOSE_CODE = Struct('!H').pack MSG_SIZE = 2 ** 14 class WebSocketError(Exception): """WebSocket protocol parser error.""" def __init__(self, code, message): self.code = code super().__init__(message) def WebSocketParser(out, buf): while True: fin, opcode, payload = yield from parse_frame(buf) if opcode == OPCODE_CLOSE: if len(payload) >= 2: close_code = UNPACK_CLOSE_CODE(payload[:2])[0] if close_code not in ALLOWED_CLOSE_CODES and close_code < 3000: raise WebSocketError( CLOSE_PROTOCOL_ERROR, 'Invalid close code: {}'.format(close_code)) try: close_message = payload[2:].decode('utf-8') except UnicodeDecodeError as exc: raise WebSocketError( CLOSE_INVALID_TEXT, 'Invalid UTF-8 text message') from exc msg = Message(OPCODE_CLOSE, close_code, close_message) elif payload: raise WebSocketError( CLOSE_PROTOCOL_ERROR, 'Invalid close frame: {} {} {!r}'.format( fin, opcode, payload)) else: msg = Message(OPCODE_CLOSE, 0, '') out.feed_data(msg, 0) elif opcode == OPCODE_PING: out.feed_data(Message(OPCODE_PING, payload, ''), len(payload)) elif opcode == OPCODE_PONG: out.feed_data(Message(OPCODE_PONG, payload, ''), len(payload)) elif opcode not in (OPCODE_TEXT, OPCODE_BINARY): raise WebSocketError( CLOSE_PROTOCOL_ERROR, "Unexpected opcode={!r}".format(opcode)) else: # load text/binary data = [payload] while not fin: fin, _opcode, payload = yield from parse_frame(buf, True) # We can receive ping/close in the middle of # text message, Case 5.* if _opcode == OPCODE_PING: out.feed_data( Message(OPCODE_PING, payload, ''), len(payload)) fin, _opcode, payload = yield from parse_frame(buf, True) elif _opcode == OPCODE_CLOSE: if len(payload) >= 2: close_code = UNPACK_CLOSE_CODE(payload[:2])[0] if (close_code not in ALLOWED_CLOSE_CODES and close_code < 3000): raise WebSocketError( CLOSE_PROTOCOL_ERROR, 'Invalid close code: {}'.format(close_code)) try: close_message = payload[2:].decode('utf-8') except UnicodeDecodeError as exc: raise WebSocketError( CLOSE_INVALID_TEXT, 'Invalid UTF-8 text message') from exc msg = Message(OPCODE_CLOSE, close_code, close_message) elif payload: raise WebSocketError( CLOSE_PROTOCOL_ERROR, 'Invalid close frame: {} {} {!r}'.format( fin, opcode, payload)) else: msg = Message(OPCODE_CLOSE, 0, '') out.feed_data(msg, 0) fin, _opcode, payload = yield from parse_frame(buf, True) if _opcode != OPCODE_CONTINUATION: raise WebSocketError( CLOSE_PROTOCOL_ERROR, 'The opcode in non-fin frame is expected ' 'to be zero, got {!r}'.format(_opcode)) else: data.append(payload) if opcode == OPCODE_TEXT: try: text = b''.join(data).decode('utf-8') out.feed_data( Message( OPCODE_TEXT, text, ''), len(text)) except UnicodeDecodeError as exc: raise WebSocketError( CLOSE_INVALID_TEXT, 'Invalid UTF-8 text message') from exc else: data = b''.join(data) out.feed_data( Message(OPCODE_BINARY, data, ''), len(data)) native_byteorder = sys.byteorder def _websocket_mask_python(mask, data): """Websocket masking function. `mask` is a `bytes` object of length 4; `data` is a `bytes` object of any length. Returns a `bytes` object of the same length as `data` with the mask applied as specified in section 5.3 of RFC 6455. This pure-python implementation may be replaced by an optimized version when available. """ assert isinstance(data, bytearray), data assert len(mask) == 4, mask datalen = len(data) if datalen == 0: # everything work without this, but may be changed later in Python. return bytearray() data = int.from_bytes(data, native_byteorder) mask = int.from_bytes(mask * (datalen // 4) + mask[: datalen % 4], native_byteorder) return (data ^ mask).to_bytes(datalen, native_byteorder) if bool(os.environ.get('AIOHTTP_NO_EXTENSIONS')): _websocket_mask = _websocket_mask_python else: try: from ._websocket import _websocket_mask_cython _websocket_mask = _websocket_mask_cython except ImportError: # pragma: no cover _websocket_mask = _websocket_mask_python def parse_frame(buf, continuation=False): """Return the next frame from the socket.""" # read header data = yield from buf.read(2) first_byte, second_byte = data fin = (first_byte >> 7) & 1 rsv1 = (first_byte >> 6) & 1 rsv2 = (first_byte >> 5) & 1 rsv3 = (first_byte >> 4) & 1 opcode = first_byte & 0xf # frame-fin = %x0 ; more frames of this message follow # / %x1 ; final frame of this message # frame-rsv1 = %x0 ; 1 bit, MUST be 0 unless negotiated otherwise # frame-rsv2 = %x0 ; 1 bit, MUST be 0 unless negotiated otherwise # frame-rsv3 = %x0 ; 1 bit, MUST be 0 unless negotiated otherwise if rsv1 or rsv2 or rsv3: raise WebSocketError( CLOSE_PROTOCOL_ERROR, 'Received frame with non-zero reserved bits') if opcode > 0x7 and fin == 0: raise WebSocketError( CLOSE_PROTOCOL_ERROR, 'Received fragmented control frame') if fin == 0 and opcode == OPCODE_CONTINUATION and not continuation: raise WebSocketError( CLOSE_PROTOCOL_ERROR, 'Received new fragment frame with non-zero ' 'opcode {!r}'.format(opcode)) has_mask = (second_byte >> 7) & 1 length = (second_byte) & 0x7f # Control frames MUST have a payload length of 125 bytes or less if opcode > 0x7 and length > 125: raise WebSocketError( CLOSE_PROTOCOL_ERROR, "Control frame payload cannot be larger than 125 bytes") # read payload if length == 126: data = yield from buf.read(2) length = UNPACK_LEN2(data)[0] elif length > 126: data = yield from buf.read(8) length = UNPACK_LEN3(data)[0] if has_mask: mask = yield from buf.read(4) if length: payload = yield from buf.read(length) else: payload = bytearray() if has_mask: payload = _websocket_mask(bytes(mask), payload) return fin, opcode, payload class WebSocketWriter: def __init__(self, writer, *, use_mask=False, random=random.Random()): self.writer = writer self.use_mask = use_mask self.randrange = random.randrange def _send_frame(self, message, opcode): """Send a frame over the websocket with message as its payload.""" msg_length = len(message) use_mask = self.use_mask if use_mask: mask_bit = 0x80 else: mask_bit = 0 if msg_length < 126: header = PACK_LEN1(0x80 | opcode, msg_length | mask_bit) elif msg_length < (1 << 16): header = PACK_LEN2(0x80 | opcode, 126 | mask_bit, msg_length) else: header = PACK_LEN3(0x80 | opcode, 127 | mask_bit, msg_length) if use_mask: mask = self.randrange(0, 0xffffffff) mask = mask.to_bytes(4, 'big') message = _websocket_mask(mask, bytearray(message)) self.writer.write(header + mask + message) else: if len(message) > MSG_SIZE: self.writer.write(header) self.writer.write(message) else: self.writer.write(header + message) def pong(self, message=b''): """Send pong message.""" if isinstance(message, str): message = message.encode('utf-8') self._send_frame(message, OPCODE_PONG) def ping(self, message=b''): """Send ping message.""" if isinstance(message, str): message = message.encode('utf-8') self._send_frame(message, OPCODE_PING) def send(self, message, binary=False): """Send a frame over the websocket with message as its payload.""" if isinstance(message, str): message = message.encode('utf-8') if binary: self._send_frame(message, OPCODE_BINARY) else: self._send_frame(message, OPCODE_TEXT) def close(self, code=1000, message=b''): """Close the websocket, sending the specified code and message.""" if isinstance(message, str): message = message.encode('utf-8') self._send_frame( PACK_CLOSE_CODE(code) + message, opcode=OPCODE_CLOSE) def do_handshake(method, headers, transport, protocols=()): """Prepare WebSocket handshake. It return http response code, response headers, websocket parser, websocket writer. It does not perform any IO. `protocols` is a sequence of known protocols. On successful handshake, the returned response headers contain the first protocol in this list which the server also knows. """ # WebSocket accepts only GET if method.upper() != hdrs.METH_GET: raise errors.HttpProcessingError( code=405, headers=((hdrs.ALLOW, hdrs.METH_GET),)) if 'websocket' != headers.get(hdrs.UPGRADE, '').lower().strip(): raise errors.HttpBadRequest( message='No WebSocket UPGRADE hdr: {}\n Can ' '"Upgrade" only to "WebSocket".'.format(headers.get(hdrs.UPGRADE))) if 'upgrade' not in headers.get(hdrs.CONNECTION, '').lower(): raise errors.HttpBadRequest( message='No CONNECTION upgrade hdr: {}'.format( headers.get(hdrs.CONNECTION))) # find common sub-protocol between client and server protocol = None if hdrs.SEC_WEBSOCKET_PROTOCOL in headers: req_protocols = [str(proto.strip()) for proto in headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(',')] for proto in req_protocols: if proto in protocols: protocol = proto break else: # No overlap found: Return no protocol as per spec ws_logger.warning( 'Client protocols %r don’t overlap server-known ones %r', protocols, req_protocols) # check supported version version = headers.get(hdrs.SEC_WEBSOCKET_VERSION, '') if version not in ('13', '8', '7'): raise errors.HttpBadRequest( message='Unsupported version: {}'.format(version), headers=((hdrs.SEC_WEBSOCKET_VERSION, '13'),)) # check client handshake for validity key = headers.get(hdrs.SEC_WEBSOCKET_KEY) try: if not key or len(base64.b64decode(key)) != 16: raise errors.HttpBadRequest( message='Handshake error: {!r}'.format(key)) except binascii.Error: raise errors.HttpBadRequest( message='Handshake error: {!r}'.format(key)) from None response_headers = [ (hdrs.UPGRADE, 'websocket'), (hdrs.CONNECTION, 'upgrade'), (hdrs.TRANSFER_ENCODING, 'chunked'), (hdrs.SEC_WEBSOCKET_ACCEPT, base64.b64encode( hashlib.sha1(key.encode() + WS_KEY).digest()).decode())] if protocol: response_headers.append((hdrs.SEC_WEBSOCKET_PROTOCOL, protocol)) # response code, headers, parser, writer, protocol return (101, response_headers, WebSocketParser, WebSocketWriter(transport), protocol) aiohttp-0.20.2/aiohttp/websocket_client.py0000664000175000017500000001272412637063114021406 0ustar andrewandrew00000000000000"""WebSocket client for asyncio.""" import asyncio import sys from enum import IntEnum from .websocket import Message from .websocket import WebSocketError from .websocket import MSG_BINARY, MSG_TEXT, MSG_CLOSE, MSG_PING, MSG_PONG __all__ = ('MsgType',) PY_35 = sys.version_info >= (3, 5) class MsgType(IntEnum): text = MSG_TEXT binary = MSG_BINARY ping = MSG_PING pong = MSG_PONG close = MSG_CLOSE closed = 20 error = 21 closedMessage = Message(MsgType.closed, None, None) class ClientWebSocketResponse: def __init__(self, reader, writer, protocol, response, timeout, autoclose, autoping, loop): self._response = response self._conn = response.connection self._writer = writer self._reader = reader self._protocol = protocol self._closed = False self._closing = False self._close_code = None self._timeout = timeout self._autoclose = autoclose self._autoping = autoping self._loop = loop self._waiting = False self._exception = None @property def closed(self): return self._closed @property def close_code(self): return self._close_code @property def protocol(self): return self._protocol def exception(self): return self._exception def ping(self, message='b'): if self._closed: raise RuntimeError('websocket connection is closed') self._writer.ping(message) def pong(self, message='b'): if self._closed: raise RuntimeError('websocket connection is closed') self._writer.pong(message) def send_str(self, data): if self._closed: raise RuntimeError('websocket connection is closed') if not isinstance(data, str): raise TypeError('data argument must be str (%r)' % type(data)) self._writer.send(data, binary=False) def send_bytes(self, data): if self._closed: raise RuntimeError('websocket connection is closed') if not isinstance(data, (bytes, bytearray, memoryview)): raise TypeError('data argument must be byte-ish (%r)' % type(data)) self._writer.send(data, binary=True) @asyncio.coroutine def close(self, *, code=1000, message=b''): if not self._closed: self._closed = True try: self._writer.close(code, message) except asyncio.CancelledError: self._close_code = 1006 self._response.close() raise except Exception as exc: self._close_code = 1006 self._exception = exc self._response.close() return True if self._closing: self._response.close() return True while True: try: msg = yield from asyncio.wait_for( self._reader.read(), self._timeout, loop=self._loop) except asyncio.CancelledError: self._close_code = 1006 self._response.close() raise except Exception as exc: self._close_code = 1006 self._exception = exc self._response.close() return True if msg.tp == MsgType.close: self._close_code = msg.data self._response.close() return True else: return False @asyncio.coroutine def receive(self): if self._waiting: raise RuntimeError('Concurrent call to receive() is not allowed') self._waiting = True try: while True: if self._closed: return closedMessage try: msg = yield from self._reader.read() except (asyncio.CancelledError, asyncio.TimeoutError): raise except WebSocketError as exc: self._close_code = exc.code yield from self.close(code=exc.code) return Message(MsgType.error, exc, None) except Exception as exc: self._exception = exc self._closing = True self._close_code = 1006 yield from self.close() return Message(MsgType.error, exc, None) if msg.tp == MsgType.close: self._closing = True self._close_code = msg.data if not self._closed and self._autoclose: yield from self.close() return msg elif not self._closed: if msg.tp == MsgType.ping and self._autoping: self._writer.pong(msg.data) elif msg.tp == MsgType.pong and self._autoping: continue else: return msg finally: self._waiting = False if PY_35: @asyncio.coroutine def __aiter__(self): return self @asyncio.coroutine def __anext__(self): msg = yield from self.receive() if msg.tp == MsgType.close: raise StopAsyncIteration # NOQA return msg aiohttp-0.20.2/aiohttp/web_ws.py0000664000175000017500000002401512613146237017346 0ustar andrewandrew00000000000000import sys import asyncio import warnings from . import hdrs from .errors import HttpProcessingError, ClientDisconnectedError from .websocket import do_handshake, Message, WebSocketError from .websocket_client import MsgType, closedMessage from .web_exceptions import ( HTTPBadRequest, HTTPMethodNotAllowed, HTTPInternalServerError) from .web_reqrep import StreamResponse __all__ = ('WebSocketResponse', 'MsgType') PY_35 = sys.version_info >= (3, 5) THRESHOLD_CONNLOST_ACCESS = 5 class WebSocketResponse(StreamResponse): def __init__(self, *, timeout=10.0, autoclose=True, autoping=True, protocols=()): super().__init__(status=101) self._protocols = protocols self._protocol = None self._writer = None self._reader = None self._closed = False self._closing = False self._conn_lost = 0 self._close_code = None self._loop = None self._waiting = False self._exception = None self._timeout = timeout self._autoclose = autoclose self._autoping = autoping @asyncio.coroutine def prepare(self, request): # make pre-check to don't hide it by do_handshake() exceptions resp_impl = self._start_pre_check(request) if resp_impl is not None: return resp_impl parser, protocol, writer = self._pre_start(request) resp_impl = yield from super().prepare(request) self._post_start(request, parser, protocol, writer) return resp_impl def _pre_start(self, request): try: status, headers, parser, writer, protocol = do_handshake( request.method, request.headers, request.transport, self._protocols) except HttpProcessingError as err: if err.code == 405: raise HTTPMethodNotAllowed( request.method, [hdrs.METH_GET], body=b'') elif err.code == 400: raise HTTPBadRequest(text=err.message, headers=err.headers) else: # pragma: no cover raise HTTPInternalServerError() from err if self.status != status: self.set_status(status) for k, v in headers: self.headers[k] = v self.force_close() return parser, protocol, writer def _post_start(self, request, parser, protocol, writer): self._reader = request._reader.set_parser(parser) self._writer = writer self._protocol = protocol self._loop = request.app.loop def start(self, request): warnings.warn('use .prepare(request) instead', DeprecationWarning) # make pre-check to don't hide it by do_handshake() exceptions resp_impl = self._start_pre_check(request) if resp_impl is not None: return resp_impl parser, protocol, writer = self._pre_start(request) resp_impl = super().start(request) self._post_start(request, parser, protocol, writer) return resp_impl def can_prepare(self, request): if self._writer is not None: raise RuntimeError('Already started') try: _, _, _, _, protocol = do_handshake( request.method, request.headers, request.transport, self._protocols) except HttpProcessingError: return False, None else: return True, protocol def can_start(self, request): warnings.warn('use .can_prepare(request) instead', DeprecationWarning) return self.can_prepare(request) @property def closed(self): return self._closed @property def close_code(self): return self._close_code @property def protocol(self): return self._protocol def exception(self): return self._exception def ping(self, message='b'): if self._writer is None: raise RuntimeError('Call .prepare() first') if self._closed: raise RuntimeError('websocket connection is closing') self._writer.ping(message) def pong(self, message='b'): # unsolicited pong if self._writer is None: raise RuntimeError('Call .prepare() first') if self._closed: raise RuntimeError('websocket connection is closing') self._writer.pong(message) def send_str(self, data): if self._writer is None: raise RuntimeError('Call .prepare() first') if self._closed: raise RuntimeError('websocket connection is closing') if not isinstance(data, str): raise TypeError('data argument must be str (%r)' % type(data)) self._writer.send(data, binary=False) def send_bytes(self, data): if self._writer is None: raise RuntimeError('Call .prepare() first') if self._closed: raise RuntimeError('websocket connection is closing') if not isinstance(data, (bytes, bytearray, memoryview)): raise TypeError('data argument must be byte-ish (%r)' % type(data)) self._writer.send(data, binary=True) @asyncio.coroutine def wait_closed(self): # pragma: no cover warnings.warn( 'wait_closed() coroutine is deprecated. use close() instead', DeprecationWarning) return (yield from self.close()) @asyncio.coroutine def write_eof(self): if self._eof_sent: return if self._resp_impl is None: raise RuntimeError("Response has not been started") yield from self.close() self._eof_sent = True @asyncio.coroutine def close(self, *, code=1000, message=b''): if self._writer is None: raise RuntimeError('Call .prepare() first') if not self._closed: self._closed = True try: self._writer.close(code, message) except (asyncio.CancelledError, asyncio.TimeoutError): self._close_code = 1006 raise except Exception as exc: self._close_code = 1006 self._exception = exc return True if self._closing: return True while True: try: msg = yield from asyncio.wait_for( self._reader.read(), timeout=self._timeout, loop=self._loop) except asyncio.CancelledError: self._close_code = 1006 raise except Exception as exc: self._close_code = 1006 self._exception = exc return True if msg.tp == MsgType.close: self._close_code = msg.data return True else: return False @asyncio.coroutine def receive(self): if self._reader is None: raise RuntimeError('Call .prepare() first') if self._waiting: raise RuntimeError('Concurrent call to receive() is not allowed') self._waiting = True try: while True: if self._closed: self._conn_lost += 1 if self._conn_lost >= THRESHOLD_CONNLOST_ACCESS: raise RuntimeError('WebSocket connection is closed.') return closedMessage try: msg = yield from self._reader.read() except (asyncio.CancelledError, asyncio.TimeoutError): raise except WebSocketError as exc: self._close_code = exc.code yield from self.close(code=exc.code) return Message(MsgType.error, exc, None) except ClientDisconnectedError: self._closed = True self._close_code = 1006 return Message(MsgType.close, None, None) except Exception as exc: self._exception = exc self._closing = True self._close_code = 1006 yield from self.close() return Message(MsgType.error, exc, None) if msg.tp == MsgType.close: self._closing = True self._close_code = msg.data if not self._closed and self._autoclose: yield from self.close() return msg elif not self._closed: if msg.tp == MsgType.ping and self._autoping: self._writer.pong(msg.data) elif msg.tp == MsgType.pong and self._autoping: continue else: return msg finally: self._waiting = False @asyncio.coroutine def receive_msg(self): warnings.warn( 'receive_msg() coroutine is deprecated. use receive() instead', DeprecationWarning) return (yield from self.receive()) @asyncio.coroutine def receive_str(self): msg = yield from self.receive() if msg.tp != MsgType.text: raise TypeError( "Received message {}:{!r} is not str".format(msg.tp, msg.data)) return msg.data @asyncio.coroutine def receive_bytes(self): msg = yield from self.receive() if msg.tp != MsgType.binary: raise TypeError( "Received message {}:{!r} is not bytes".format(msg.tp, msg.data)) return msg.data def write(self, data): raise RuntimeError("Cannot call .write() for websocket") if PY_35: @asyncio.coroutine def __aiter__(self): return self @asyncio.coroutine def __anext__(self): msg = yield from self.receive() if msg.tp == MsgType.close: raise StopAsyncIteration # NOQA return msg aiohttp-0.20.2/aiohttp/client.py0000664000175000017500000005570212640004716017340 0ustar andrewandrew00000000000000"""HTTP Client for asyncio.""" import asyncio import base64 import hashlib import os import sys import traceback import warnings import http.cookies import urllib.parse import aiohttp from .client_reqrep import ClientRequest, ClientResponse from .errors import WSServerHandshakeError from .multidict import MultiDictProxy, MultiDict, CIMultiDict, upstr from .websocket import WS_KEY, WebSocketParser, WebSocketWriter from .websocket_client import ClientWebSocketResponse from . import hdrs __all__ = ('ClientSession', 'request', 'get', 'options', 'head', 'delete', 'post', 'put', 'patch', 'ws_connect') PY_35 = sys.version_info >= (3, 5) class ClientSession: """First-class interface for making HTTP requests.""" _source_traceback = None _connector = None def __init__(self, *, connector=None, loop=None, cookies=None, headers=None, skip_auto_headers=None, auth=None, request_class=ClientRequest, response_class=ClientResponse, ws_response_class=ClientWebSocketResponse): if connector is None: connector = aiohttp.TCPConnector(loop=loop) loop = connector._loop # never None else: if loop is None: loop = connector._loop # never None elif connector._loop is not loop: raise ValueError("loop argument must agree with connector") self._loop = loop if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) self._cookies = http.cookies.SimpleCookie() # For Backward compatability with `share_cookies` connectors if connector._share_cookies: self._update_cookies(connector.cookies) if cookies is not None: self._update_cookies(cookies) self._connector = connector self._default_auth = auth # Convert to list of tuples if headers: headers = CIMultiDict(headers) else: headers = CIMultiDict() self._default_headers = headers if skip_auto_headers is not None: self._skip_auto_headers = frozenset([upstr(i) for i in skip_auto_headers]) else: self._skip_auto_headers = frozenset() self._request_class = request_class self._response_class = response_class self._ws_response_class = ws_response_class def __del__(self, _warnings=warnings): if not self.closed: self.close() _warnings.warn("Unclosed client session {!r}".format(self), ResourceWarning) context = {'client_session': self, 'message': 'Unclosed client session'} if self._source_traceback is not None: context['source_traceback'] = self._source_traceback self._loop.call_exception_handler(context) def request(self, method, url, *, params=None, data=None, headers=None, skip_auto_headers=None, auth=None, allow_redirects=True, max_redirects=10, encoding='utf-8', version=aiohttp.HttpVersion11, compress=None, chunked=None, expect100=False, read_until_eof=True): """Perform HTTP request.""" return _RequestContextManager( self._request( method, url, params=params, data=data, headers=headers, skip_auto_headers=skip_auto_headers, auth=auth, allow_redirects=allow_redirects, max_redirects=max_redirects, encoding=encoding, version=version, compress=compress, chunked=chunked, expect100=expect100, read_until_eof=read_until_eof)) @asyncio.coroutine def _request(self, method, url, *, params=None, data=None, headers=None, skip_auto_headers=None, auth=None, allow_redirects=True, max_redirects=10, encoding='utf-8', version=aiohttp.HttpVersion11, compress=None, chunked=None, expect100=False, read_until_eof=True): if self.closed: raise RuntimeError('Session is closed') redirects = 0 history = [] if not isinstance(method, upstr): method = upstr(method) # Merge with default headers and transform to CIMultiDict headers = self._prepare_headers(headers) if auth is None: auth = self._default_auth # It would be confusing if we support explicit Authorization header # with `auth` argument if (headers is not None and auth is not None and hdrs.AUTHORIZATION in headers): raise ValueError("Can't combine `Authorization` header with " "`auth` argument") skip_headers = set(self._skip_auto_headers) if skip_auto_headers is not None: for i in skip_auto_headers: skip_headers.add(upstr(i)) while True: req = self._request_class( method, url, params=params, headers=headers, skip_auto_headers=skip_headers, data=data, cookies=self.cookies, encoding=encoding, auth=auth, version=version, compress=compress, chunked=chunked, expect100=expect100, loop=self._loop, response_class=self._response_class) conn = yield from self._connector.connect(req) try: resp = req.send(conn.writer, conn.reader) try: yield from resp.start(conn, read_until_eof) except: resp.close() conn.close() raise except (aiohttp.HttpProcessingError, aiohttp.ServerDisconnectedError) as exc: raise aiohttp.ClientResponseError() from exc except OSError as exc: raise aiohttp.ClientOSError(*exc.args) from exc self._update_cookies(resp.cookies) # For Backward compatability with `share_cookie` connectors if self._connector._share_cookies: self._connector.update_cookies(resp.cookies) # redirects if resp.status in (301, 302, 303, 307) and allow_redirects: redirects += 1 history.append(resp) if max_redirects and redirects >= max_redirects: resp.close() break # For 301 and 302, mimic IE behaviour, now changed in RFC. # Details: https://github.com/kennethreitz/requests/pull/269 if resp.status != 307: method = hdrs.METH_GET data = None if headers.get(hdrs.CONTENT_LENGTH): headers.pop(hdrs.CONTENT_LENGTH) r_url = (resp.headers.get(hdrs.LOCATION) or resp.headers.get(hdrs.URI)) scheme = urllib.parse.urlsplit(r_url)[0] if scheme not in ('http', 'https', ''): resp.close() raise ValueError('Can redirect only to http or https') elif not scheme: r_url = urllib.parse.urljoin(url, r_url) url = r_url yield from resp.release() continue break resp._history = tuple(history) return resp def ws_connect(self, url, *, protocols=(), timeout=10.0, autoclose=True, autoping=True, auth=None, origin=None): """Initiate websocket connection.""" return _WSRequestContextManager( self._ws_connect(url, protocols=protocols, timeout=timeout, autoclose=autoclose, autoping=autoping, auth=auth, origin=origin)) @asyncio.coroutine def _ws_connect(self, url, *, protocols=(), timeout=10.0, autoclose=True, autoping=True, auth=None, origin=None): sec_key = base64.b64encode(os.urandom(16)) headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_VERSION: '13', hdrs.SEC_WEBSOCKET_KEY: sec_key.decode(), } if protocols: headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = ','.join(protocols) if origin is not None: headers[hdrs.ORIGIN] = origin # send request resp = yield from self.get(url, headers=headers, read_until_eof=False, auth=auth) try: # check handshake if resp.status != 101: raise WSServerHandshakeError( message='Invalid response status', code=resp.status, headers=resp.headers) if resp.headers.get(hdrs.UPGRADE, '').lower() != 'websocket': raise WSServerHandshakeError( message='Invalid upgrade header', code=resp.status, headers=resp.headers) if resp.headers.get(hdrs.CONNECTION, '').lower() != 'upgrade': raise WSServerHandshakeError( message='Invalid connection header', code=resp.status, headers=resp.headers) # key calculation key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, '') match = base64.b64encode( hashlib.sha1(sec_key + WS_KEY).digest()).decode() if key != match: raise WSServerHandshakeError( message='Invalid challenge response', code=resp.status, headers=resp.headers) # websocket protocol protocol = None if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers: resp_protocols = [ proto.strip() for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(',')] for proto in resp_protocols: if proto in protocols: protocol = proto break reader = resp.connection.reader.set_parser(WebSocketParser) writer = WebSocketWriter(resp.connection.writer, use_mask=True) except Exception: resp.close() raise else: return self._ws_response_class(reader, writer, protocol, resp, timeout, autoclose, autoping, self._loop) def _update_cookies(self, cookies): """Update shared cookies.""" if isinstance(cookies, dict): cookies = cookies.items() for name, value in cookies: if isinstance(value, http.cookies.Morsel): # use dict method because SimpleCookie class modifies value # before Python 3.4 dict.__setitem__(self.cookies, name, value) else: self.cookies[name] = value def _prepare_headers(self, headers): """ Add default headers and transform it to CIMultiDict """ # Convert headers to MultiDict result = CIMultiDict(self._default_headers) if headers: if not isinstance(headers, (MultiDictProxy, MultiDict)): headers = CIMultiDict(headers) added_names = set() for key, value in headers.items(): if key in added_names: result.add(key, value) else: result[key] = value added_names.add(key) return result def get(self, url, *, allow_redirects=True, **kwargs): """Perform HTTP GET request.""" return _RequestContextManager( self._request(hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs)) def options(self, url, *, allow_redirects=True, **kwargs): """Perform HTTP OPTIONS request.""" return _RequestContextManager( self._request(hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs)) def head(self, url, *, allow_redirects=False, **kwargs): """Perform HTTP HEAD request.""" return _RequestContextManager( self._request(hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs)) def post(self, url, *, data=None, **kwargs): """Perform HTTP POST request.""" return _RequestContextManager( self._request(hdrs.METH_POST, url, data=data, **kwargs)) def put(self, url, *, data=None, **kwargs): """Perform HTTP PUT request.""" return _RequestContextManager( self._request(hdrs.METH_PUT, url, data=data, **kwargs)) def patch(self, url, *, data=None, **kwargs): """Perform HTTP PATCH request.""" return _RequestContextManager( self._request(hdrs.METH_PATCH, url, data=data, **kwargs)) def delete(self, url, **kwargs): """Perform HTTP DELETE request.""" return _RequestContextManager( self._request(hdrs.METH_DELETE, url, **kwargs)) def close(self): """Close underlying connector. Release all acquired resources. """ if not self.closed: self._connector.close() self._connector = None @property def closed(self): """Is client session closed. A readonly property. """ return self._connector is None or self._connector.closed @property def connector(self): """Connector instance used for the session.""" return self._connector @property def cookies(self): """The session cookies.""" return self._cookies def detach(self): """Detach connector from session without closing the former. Session is switched to closed state anyway. """ self._connector = None def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self.close() if PY_35: from collections.abc import Coroutine base = Coroutine else: base = object class _BaseRequestContextManager(base): __slots__ = ('_coro', '_resp') def __init__(self, coro): self._coro = coro self._resp = None def send(self, value): return self._coro.send(value) def throw(self, typ, val=None, tb=None): if val is None: return self._coro.throw(typ) elif tb is None: return self._coro.throw(typ, val) else: return self._coro.throw(typ, val, tb) def close(self): return self._coro.close() @property def gi_frame(self): return self._coro.gi_frame @property def gi_running(self): return self._coro.gi_running @property def gi_code(self): return self._coro.gi_code def __next__(self): return self.send(None) @asyncio.coroutine def __iter__(self): resp = yield from self._coro return resp if PY_35: def __await__(self): resp = yield from self._coro return resp @asyncio.coroutine def __aenter__(self): self._resp = yield from self._coro return self._resp if not PY_35: try: from asyncio import coroutines coroutines._COROUTINE_TYPES += (_BaseRequestContextManager,) except: pass class _RequestContextManager(_BaseRequestContextManager): if PY_35: @asyncio.coroutine def __aexit__(self, exc_type, exc, tb): if exc_type is not None: self._resp.close() else: yield from self._resp.release() class _WSRequestContextManager(_BaseRequestContextManager): if PY_35: @asyncio.coroutine def __aexit__(self, exc_type, exc, tb): yield from self._resp.close() class _DetachedRequestContextManager(_RequestContextManager): __slots__ = _RequestContextManager.__slots__ + ('_session', ) def __init__(self, coro, session): super().__init__(coro) self._session = session @asyncio.coroutine def __iter__(self): try: return (yield from self._coro) except: self._session.close() raise if PY_35: def __await__(self): try: return (yield from self._coro) except: self._session.close() raise def __del__(self): self._session.detach() class _DetachedWSRequestContextManager(_WSRequestContextManager): __slots__ = _WSRequestContextManager.__slots__ + ('_session', ) def __init__(self, coro, session): super().__init__(coro) self._session = session def __del__(self): self._session.detach() def request(method, url, *, params=None, data=None, headers=None, skip_auto_headers=None, cookies=None, auth=None, allow_redirects=True, max_redirects=10, encoding='utf-8', version=aiohttp.HttpVersion11, compress=None, chunked=None, expect100=False, connector=None, loop=None, read_until_eof=True, request_class=None, response_class=None): """Constructs and sends a request. Returns response object. :param str method: http method :param str url: request url :param params: (optional) Dictionary or bytes to be sent in the query string of the new request :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the request :param dict headers: (optional) Dictionary of HTTP Headers to send with the request :param dict cookies: (optional) Dict object to send with the request :param auth: (optional) BasicAuth named tuple represent HTTP Basic Auth :type auth: aiohttp.helpers.BasicAuth :param bool allow_redirects: (optional) If set to False, do not follow redirects :param version: Request http version. :type version: aiohttp.protocol.HttpVersion :param bool compress: Set to True if request has to be compressed with deflate encoding. :param chunked: Set to chunk size for chunked transfer encoding. :type chunked: bool or int :param bool expect100: Expect 100-continue response from server. :param connector: BaseConnector sub-class instance to support connection pooling. :type connector: aiohttp.connector.BaseConnector :param bool read_until_eof: Read response until eof if response does not have Content-Length header. :param request_class: (optional) Custom Request class implementation. :param response_class: (optional) Custom Response class implementation. :param loop: Optional event loop. Usage:: >>> import aiohttp >>> resp = yield from aiohttp.request('GET', 'http://python.org/') >>> resp >>> data = yield from resp.read() """ if connector is None: connector = aiohttp.TCPConnector(loop=loop, force_close=True) kwargs = {} if request_class is not None: kwargs['request_class'] = request_class if response_class is not None: kwargs['response_class'] = response_class session = ClientSession(loop=loop, cookies=cookies, connector=connector, **kwargs) return _DetachedRequestContextManager( session._request(method, url, params=params, data=data, headers=headers, skip_auto_headers=skip_auto_headers, auth=auth, allow_redirects=allow_redirects, max_redirects=max_redirects, encoding=encoding, version=version, compress=compress, chunked=chunked, expect100=expect100, read_until_eof=read_until_eof), session=session) def get(url, **kwargs): return request(hdrs.METH_GET, url, **kwargs) def options(url, **kwargs): return request(hdrs.METH_OPTIONS, url, **kwargs) def head(url, **kwargs): return request(hdrs.METH_HEAD, url, **kwargs) def post(url, **kwargs): return request(hdrs.METH_POST, url, **kwargs) def put(url, **kwargs): return request(hdrs.METH_PUT, url, **kwargs) def patch(url, **kwargs): return request(hdrs.METH_PATCH, url, **kwargs) def delete(url, **kwargs): return request(hdrs.METH_DELETE, url, **kwargs) def ws_connect(url, *, protocols=(), timeout=10.0, connector=None, auth=None, ws_response_class=ClientWebSocketResponse, autoclose=True, autoping=True, loop=None, origin=None, headers=None): if loop is None: loop = asyncio.get_event_loop() if connector is None: connector = aiohttp.TCPConnector(loop=loop, force_close=True) session = aiohttp.ClientSession(loop=loop, connector=connector, auth=auth, ws_response_class=ws_response_class, headers=headers) return _DetachedWSRequestContextManager( session._ws_connect(url, protocols=protocols, timeout=timeout, autoclose=autoclose, autoping=autoping, origin=origin), session=session) aiohttp-0.20.2/aiohttp/_multidict.c0000664000175000017500000254154712607530701020023 0ustar andrewandrew00000000000000/* Generated by Cython 0.23.4 */ /* BEGIN: Cython Metadata { "distutils": {} } END: Cython Metadata */ #define PY_SSIZE_T_CLEAN #include "Python.h" #ifndef Py_PYTHON_H #error Python headers needed to compile C extensions, please install development version of Python. #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000) #error Cython requires Python 2.6+ or Python 3.2+. #else #define CYTHON_ABI "0_23_4" #include #ifndef offsetof #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) #endif #if !defined(WIN32) && !defined(MS_WINDOWS) #ifndef __stdcall #define __stdcall #endif #ifndef __cdecl #define __cdecl #endif #ifndef __fastcall #define __fastcall #endif #endif #ifndef DL_IMPORT #define DL_IMPORT(t) t #endif #ifndef DL_EXPORT #define DL_EXPORT(t) t #endif #ifndef PY_LONG_LONG #define PY_LONG_LONG LONG_LONG #endif #ifndef Py_HUGE_VAL #define Py_HUGE_VAL HUGE_VAL #endif #ifdef PYPY_VERSION #define CYTHON_COMPILING_IN_PYPY 1 #define CYTHON_COMPILING_IN_CPYTHON 0 #else #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_CPYTHON 1 #endif #if !defined(CYTHON_USE_PYLONG_INTERNALS) && CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000 #define CYTHON_USE_PYLONG_INTERNALS 1 #endif #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) #define Py_OptimizeFlag 0 #endif #define __PYX_BUILD_PY_SSIZE_T "n" #define CYTHON_FORMAT_SSIZE_T "z" #if PY_MAJOR_VERSION < 3 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #define __Pyx_DefaultClassType PyClass_Type #else #define __Pyx_BUILTIN_MODULE_NAME "builtins" #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #define __Pyx_DefaultClassType PyType_Type #endif #ifndef Py_TPFLAGS_CHECKTYPES #define Py_TPFLAGS_CHECKTYPES 0 #endif #ifndef Py_TPFLAGS_HAVE_INDEX #define Py_TPFLAGS_HAVE_INDEX 0 #endif #ifndef Py_TPFLAGS_HAVE_NEWBUFFER #define Py_TPFLAGS_HAVE_NEWBUFFER 0 #endif #ifndef Py_TPFLAGS_HAVE_FINALIZE #define Py_TPFLAGS_HAVE_FINALIZE 0 #endif #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) #define CYTHON_PEP393_ENABLED 1 #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ 0 : _PyUnicode_Ready((PyObject *)(op))) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) #else #define CYTHON_PEP393_ENABLED 0 #define __Pyx_PyUnicode_READY(op) (0) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) #endif #if CYTHON_COMPILING_IN_PYPY #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) #else #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) #endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) #endif #define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) #define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) #else #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) #endif #if PY_MAJOR_VERSION >= 3 #define PyBaseString_Type PyUnicode_Type #define PyStringObject PyUnicodeObject #define PyString_Type PyUnicode_Type #define PyString_Check PyUnicode_Check #define PyString_CheckExact PyUnicode_CheckExact #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) #else #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) #endif #ifndef PySet_CheckExact #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) #endif #define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) #if PY_MAJOR_VERSION >= 3 #define PyIntObject PyLongObject #define PyInt_Type PyLong_Type #define PyInt_Check(op) PyLong_Check(op) #define PyInt_CheckExact(op) PyLong_CheckExact(op) #define PyInt_FromString PyLong_FromString #define PyInt_FromUnicode PyLong_FromUnicode #define PyInt_FromLong PyLong_FromLong #define PyInt_FromSize_t PyLong_FromSize_t #define PyInt_FromSsize_t PyLong_FromSsize_t #define PyInt_AsLong PyLong_AsLong #define PyInt_AS_LONG PyLong_AS_LONG #define PyInt_AsSsize_t PyLong_AsSsize_t #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask #define PyNumber_Int PyNumber_Long #endif #if PY_MAJOR_VERSION >= 3 #define PyBoolObject PyLongObject #endif #if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY #ifndef PyUnicode_InternFromString #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) #endif #endif #if PY_VERSION_HEX < 0x030200A4 typedef long Py_hash_t; #define __Pyx_PyInt_FromHash_t PyInt_FromLong #define __Pyx_PyInt_AsHash_t PyInt_AsLong #else #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) #else #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) #endif #if PY_VERSION_HEX >= 0x030500B1 #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) #elif CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; } __Pyx_PyAsyncMethodsStruct; #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) #else #define __Pyx_PyType_AsAsync(obj) NULL #endif #ifndef CYTHON_RESTRICT #if defined(__GNUC__) #define CYTHON_RESTRICT __restrict__ #elif defined(_MSC_VER) && _MSC_VER >= 1400 #define CYTHON_RESTRICT __restrict #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define CYTHON_RESTRICT restrict #else #define CYTHON_RESTRICT #endif #endif #define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) #ifndef CYTHON_INLINE #if defined(__GNUC__) #define CYTHON_INLINE __inline__ #elif defined(_MSC_VER) #define CYTHON_INLINE __inline #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define CYTHON_INLINE inline #else #define CYTHON_INLINE #endif #endif #if defined(WIN32) || defined(MS_WINDOWS) #define _USE_MATH_DEFINES #endif #include #ifdef NAN #define __PYX_NAN() ((float) NAN) #else static CYTHON_INLINE float __PYX_NAN() { float value; memset(&value, 0xFF, sizeof(value)); return value; } #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) #else #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) #endif #ifndef __PYX_EXTERN_C #ifdef __cplusplus #define __PYX_EXTERN_C extern "C" #else #define __PYX_EXTERN_C extern #endif #endif #define __PYX_HAVE__aiohttp___multidict #define __PYX_HAVE_API__aiohttp___multidict #ifdef _OPENMP #include #endif /* _OPENMP */ #ifdef PYREX_WITHOUT_ASSERTIONS #define CYTHON_WITHOUT_ASSERTIONS #endif #ifndef CYTHON_UNUSED # if defined(__GNUC__) # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) # define CYTHON_UNUSED __attribute__ ((__unused__)) # else # define CYTHON_UNUSED # endif # elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) # define CYTHON_UNUSED __attribute__ ((__unused__)) # else # define CYTHON_UNUSED # endif #endif #ifndef CYTHON_NCP_UNUSED # if CYTHON_COMPILING_IN_CPYTHON # define CYTHON_NCP_UNUSED # else # define CYTHON_NCP_UNUSED CYTHON_UNUSED # endif #endif typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; #define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 #define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 #define __PYX_DEFAULT_STRING_ENCODING "" #define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString #define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize #define __Pyx_uchar_cast(c) ((unsigned char)c) #define __Pyx_long_cast(x) ((long)x) #define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ (sizeof(type) < sizeof(Py_ssize_t)) ||\ (sizeof(type) > sizeof(Py_ssize_t) &&\ likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX) &&\ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ v == (type)PY_SSIZE_T_MIN))) ||\ (sizeof(type) == sizeof(Py_ssize_t) &&\ (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX))) ) #if defined (__cplusplus) && __cplusplus >= 201103L #include #define __Pyx_sst_abs(value) std::abs(value) #elif SIZEOF_INT >= SIZEOF_SIZE_T #define __Pyx_sst_abs(value) abs(value) #elif SIZEOF_LONG >= SIZEOF_SIZE_T #define __Pyx_sst_abs(value) labs(value) #elif defined (_MSC_VER) && defined (_M_X64) #define __Pyx_sst_abs(value) _abs64(value) #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define __Pyx_sst_abs(value) llabs(value) #elif defined (__GNUC__) #define __Pyx_sst_abs(value) __builtin_llabs(value) #else #define __Pyx_sst_abs(value) ((value<0) ? -value : value) #endif static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*); static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); #define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) #define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) #define __Pyx_PyBytes_FromString PyBytes_FromString #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); #if PY_MAJOR_VERSION < 3 #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize #else #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize #endif #define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) #define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) #define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) #define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) #define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) #if PY_MAJOR_VERSION < 3 static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { const Py_UNICODE *u_end = u; while (*u_end++) ; return (size_t)(u_end - u - 1); } #else #define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen #endif #define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) #define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode #define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode #define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) #define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); #if CYTHON_COMPILING_IN_CPYTHON #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) #else #define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) #endif #define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII static int __Pyx_sys_getdefaultencoding_not_ascii; static int __Pyx_init_sys_getdefaultencoding_params(void) { PyObject* sys; PyObject* default_encoding = NULL; PyObject* ascii_chars_u = NULL; PyObject* ascii_chars_b = NULL; const char* default_encoding_c; sys = PyImport_ImportModule("sys"); if (!sys) goto bad; default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); Py_DECREF(sys); if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; if (strcmp(default_encoding_c, "ascii") == 0) { __Pyx_sys_getdefaultencoding_not_ascii = 0; } else { char ascii_chars[128]; int c; for (c = 0; c < 128; c++) { ascii_chars[c] = c; } __Pyx_sys_getdefaultencoding_not_ascii = 1; ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); if (!ascii_chars_u) goto bad; ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { PyErr_Format( PyExc_ValueError, "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", default_encoding_c); goto bad; } Py_DECREF(ascii_chars_u); Py_DECREF(ascii_chars_b); } Py_DECREF(default_encoding); return 0; bad: Py_XDECREF(default_encoding); Py_XDECREF(ascii_chars_u); Py_XDECREF(ascii_chars_b); return -1; } #endif #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) #else #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT static char* __PYX_DEFAULT_STRING_ENCODING; static int __Pyx_init_sys_getdefaultencoding_params(void) { PyObject* sys; PyObject* default_encoding = NULL; char* default_encoding_c; sys = PyImport_ImportModule("sys"); if (!sys) goto bad; default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); Py_DECREF(sys); 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)); if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); Py_DECREF(default_encoding); return 0; bad: Py_XDECREF(default_encoding); return -1; } #endif #endif /* Test for GCC > 2.95 */ #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else /* !__GNUC__ or GCC < 2.95 */ #define likely(x) (x) #define unlikely(x) (x) #endif /* __GNUC__ */ static PyObject *__pyx_m; static PyObject *__pyx_d; static PyObject *__pyx_b; static PyObject *__pyx_empty_tuple; static PyObject *__pyx_empty_bytes; static int __pyx_lineno; static int __pyx_clineno = 0; static const char * __pyx_cfilenm= __FILE__; static const char *__pyx_filename; static const char *__pyx_f[] = { "aiohttp/_multidict.pyx", }; /*--- Type declarations ---*/ struct __pyx_obj_7aiohttp_10_multidict__Pair; struct __pyx_obj_7aiohttp_10_multidict__Base; struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy; struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy; struct __pyx_obj_7aiohttp_10_multidict_MultiDict; struct __pyx_obj_7aiohttp_10_multidict_CIMultiDict; struct __pyx_obj_7aiohttp_10_multidict__ViewBase; struct __pyx_obj_7aiohttp_10_multidict__ViewBaseSet; struct __pyx_obj_7aiohttp_10_multidict__ItemsIter; struct __pyx_obj_7aiohttp_10_multidict__ItemsView; struct __pyx_obj_7aiohttp_10_multidict__ValuesIter; struct __pyx_obj_7aiohttp_10_multidict__ValuesView; struct __pyx_obj_7aiohttp_10_multidict__KeysIter; struct __pyx_obj_7aiohttp_10_multidict__KeysView; struct __pyx_defaults; typedef struct __pyx_defaults __pyx_defaults; struct __pyx_defaults { PyObject *__pyx_arg_encoding; }; /* "aiohttp/_multidict.pyx":47 * * * cdef class _Pair: # <<<<<<<<<<<<<< * cdef object _key * cdef object _value */ struct __pyx_obj_7aiohttp_10_multidict__Pair { PyObject_HEAD PyObject *_key; PyObject *_value; }; /* "aiohttp/_multidict.pyx":66 * return left._key != right._key and left._value != right._value * * cdef class _Base: # <<<<<<<<<<<<<< * * cdef list _items */ struct __pyx_obj_7aiohttp_10_multidict__Base { PyObject_HEAD struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *__pyx_vtab; PyObject *_items; PyObject *_upstr; PyObject *marker; }; /* "aiohttp/_multidict.pyx":194 * * * cdef class MultiDictProxy(_Base): # <<<<<<<<<<<<<< * * def __init__(self, arg): */ struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy { struct __pyx_obj_7aiohttp_10_multidict__Base __pyx_base; }; /* "aiohttp/_multidict.pyx":213 * * * cdef class CIMultiDictProxy(MultiDictProxy): # <<<<<<<<<<<<<< * * def __init__(self, arg): */ struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy { struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy __pyx_base; }; /* "aiohttp/_multidict.pyx":238 * * * cdef class MultiDict(_Base): # <<<<<<<<<<<<<< * """An ordered dictionary that can have multiple values for each key.""" * */ struct __pyx_obj_7aiohttp_10_multidict_MultiDict { struct __pyx_obj_7aiohttp_10_multidict__Base __pyx_base; }; /* "aiohttp/_multidict.pyx":408 * * * cdef class CIMultiDict(MultiDict): # <<<<<<<<<<<<<< * """An ordered dictionary that can have multiple values for each key.""" * */ struct __pyx_obj_7aiohttp_10_multidict_CIMultiDict { struct __pyx_obj_7aiohttp_10_multidict_MultiDict __pyx_base; }; /* "aiohttp/_multidict.pyx":421 * * * cdef class _ViewBase: # <<<<<<<<<<<<<< * * cdef list _items */ struct __pyx_obj_7aiohttp_10_multidict__ViewBase { PyObject_HEAD PyObject *_items; }; /* "aiohttp/_multidict.pyx":432 * * * cdef class _ViewBaseSet(_ViewBase): # <<<<<<<<<<<<<< * * def __richcmp__(self, other, op): */ struct __pyx_obj_7aiohttp_10_multidict__ViewBaseSet { struct __pyx_obj_7aiohttp_10_multidict__ViewBase __pyx_base; }; /* "aiohttp/_multidict.pyx":497 * * * cdef class _ItemsIter: # <<<<<<<<<<<<<< * cdef list _items * cdef int _current */ struct __pyx_obj_7aiohttp_10_multidict__ItemsIter { PyObject_HEAD PyObject *_items; int _current; int _len; }; /* "aiohttp/_multidict.pyx":518 * * * cdef class _ItemsView(_ViewBaseSet): # <<<<<<<<<<<<<< * * def isdisjoint(self, other): */ struct __pyx_obj_7aiohttp_10_multidict__ItemsView { struct __pyx_obj_7aiohttp_10_multidict__ViewBaseSet __pyx_base; }; /* "aiohttp/_multidict.pyx":553 * * * cdef class _ValuesIter: # <<<<<<<<<<<<<< * cdef list _items * cdef int _current */ struct __pyx_obj_7aiohttp_10_multidict__ValuesIter { PyObject_HEAD PyObject *_items; int _current; int _len; }; /* "aiohttp/_multidict.pyx":574 * * * cdef class _ValuesView(_ViewBase): # <<<<<<<<<<<<<< * * def __contains__(self, value): */ struct __pyx_obj_7aiohttp_10_multidict__ValuesView { struct __pyx_obj_7aiohttp_10_multidict__ViewBase __pyx_base; }; /* "aiohttp/_multidict.pyx":600 * * * cdef class _KeysIter: # <<<<<<<<<<<<<< * cdef list _items * cdef int _current */ struct __pyx_obj_7aiohttp_10_multidict__KeysIter { PyObject_HEAD PyObject *_items; int _current; int _len; }; /* "aiohttp/_multidict.pyx":621 * * * cdef class _KeysView(_ViewBaseSet): # <<<<<<<<<<<<<< * * def isdisjoint(self, other): */ struct __pyx_obj_7aiohttp_10_multidict__KeysView { struct __pyx_obj_7aiohttp_10_multidict__ViewBaseSet __pyx_base; }; /* "aiohttp/_multidict.pyx":66 * return left._key != right._key and left._value != right._value * * cdef class _Base: # <<<<<<<<<<<<<< * * cdef list _items */ struct __pyx_vtabstruct_7aiohttp_10_multidict__Base { PyObject *(*_upper)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *); PyObject *(*_getall)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *, PyObject *); PyObject *(*_getone)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *, PyObject *); PyObject *(*_contains)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *); PyObject *(*keys)(struct __pyx_obj_7aiohttp_10_multidict__Base *, int __pyx_skip_dispatch); PyObject *(*_eq_to_mapping)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *); }; static struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *__pyx_vtabptr_7aiohttp_10_multidict__Base; /* "aiohttp/_multidict.pyx":194 * * * cdef class MultiDictProxy(_Base): # <<<<<<<<<<<<<< * * def __init__(self, arg): */ struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDictProxy { struct __pyx_vtabstruct_7aiohttp_10_multidict__Base __pyx_base; }; static struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDictProxy *__pyx_vtabptr_7aiohttp_10_multidict_MultiDictProxy; /* "aiohttp/_multidict.pyx":213 * * * cdef class CIMultiDictProxy(MultiDictProxy): # <<<<<<<<<<<<<< * * def __init__(self, arg): */ struct __pyx_vtabstruct_7aiohttp_10_multidict_CIMultiDictProxy { struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDictProxy __pyx_base; }; static struct __pyx_vtabstruct_7aiohttp_10_multidict_CIMultiDictProxy *__pyx_vtabptr_7aiohttp_10_multidict_CIMultiDictProxy; /* "aiohttp/_multidict.pyx":238 * * * cdef class MultiDict(_Base): # <<<<<<<<<<<<<< * """An ordered dictionary that can have multiple values for each key.""" * */ struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict { struct __pyx_vtabstruct_7aiohttp_10_multidict__Base __pyx_base; PyObject *(*_extend)(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *, PyObject *, PyObject *, PyObject *, int); PyObject *(*_add)(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *, PyObject *, PyObject *); PyObject *(*_replace)(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *, PyObject *, PyObject *); PyObject *(*_remove)(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *, PyObject *, int); }; static struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *__pyx_vtabptr_7aiohttp_10_multidict_MultiDict; /* "aiohttp/_multidict.pyx":408 * * * cdef class CIMultiDict(MultiDict): # <<<<<<<<<<<<<< * """An ordered dictionary that can have multiple values for each key.""" * */ struct __pyx_vtabstruct_7aiohttp_10_multidict_CIMultiDict { struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict __pyx_base; }; static struct __pyx_vtabstruct_7aiohttp_10_multidict_CIMultiDict *__pyx_vtabptr_7aiohttp_10_multidict_CIMultiDict; /* --- Runtime support code (head) --- */ #ifndef CYTHON_REFNANNY #define CYTHON_REFNANNY 0 #endif #if CYTHON_REFNANNY typedef struct { void (*INCREF)(void*, PyObject*, int); void (*DECREF)(void*, PyObject*, int); void (*GOTREF)(void*, PyObject*, int); void (*GIVEREF)(void*, PyObject*, int); void* (*SetupContext)(const char*, int, const char*); void (*FinishContext)(void**); } __Pyx_RefNannyAPIStruct; static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; #ifdef WITH_THREAD #define __Pyx_RefNannySetupContext(name, acquire_gil)\ if (acquire_gil) {\ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ PyGILState_Release(__pyx_gilstate_save);\ } else {\ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ } #else #define __Pyx_RefNannySetupContext(name, acquire_gil)\ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) #endif #define __Pyx_RefNannyFinishContext()\ __Pyx_RefNanny->FinishContext(&__pyx_refnanny) #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) #else #define __Pyx_RefNannyDeclarations #define __Pyx_RefNannySetupContext(name, acquire_gil) #define __Pyx_RefNannyFinishContext() #define __Pyx_INCREF(r) Py_INCREF(r) #define __Pyx_DECREF(r) Py_DECREF(r) #define __Pyx_GOTREF(r) #define __Pyx_GIVEREF(r) #define __Pyx_XINCREF(r) Py_XINCREF(r) #define __Pyx_XDECREF(r) Py_XDECREF(r) #define __Pyx_XGOTREF(r) #define __Pyx_XGIVEREF(r) #endif #define __Pyx_XDECREF_SET(r, v) do {\ PyObject *tmp = (PyObject *) r;\ r = v; __Pyx_XDECREF(tmp);\ } while (0) #define __Pyx_DECREF_SET(r, v) do {\ PyObject *tmp = (PyObject *) r;\ r = v; __Pyx_DECREF(tmp);\ } while (0) #define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) #define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { PyTypeObject* tp = Py_TYPE(obj); if (likely(tp->tp_getattro)) return tp->tp_getattro(obj, attr_name); #if PY_MAJOR_VERSION < 3 if (likely(tp->tp_getattr)) return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); #endif return PyObject_GetAttr(obj, attr_name); } #else #define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) #endif static PyObject *__Pyx_GetBuiltinName(PyObject *name); static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ const char* function_name); static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); #else #define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) #endif #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); #endif static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); #else #define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) #endif static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, long intval, int inplace); #else #define __Pyx_PyInt_EqObjC(op1, op2, intval, inplace)\ PyObject_RichCompare(op1, op2, Py_EQ) #endif static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict, const char* function_name, int kw_allowed); #include static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals #else #define __Pyx_PyString_Equals __Pyx_PyBytes_Equals #endif #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { PyListObject* L = (PyListObject*) list; Py_ssize_t len = Py_SIZE(list); if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { Py_INCREF(x); PyList_SET_ITEM(list, len, x); Py_SIZE(list) = len+1; return 0; } return PyList_Append(list, x); } #else #define __Pyx_PyList_Append(L,x) PyList_Append(L,x) #endif static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); #if PY_MAJOR_VERSION < 3 #define __Pyx_PyString_Join __Pyx_PyBytes_Join #define __Pyx_PyBaseString_Join(s, v) (PyUnicode_CheckExact(s) ? PyUnicode_Join(s, v) : __Pyx_PyBytes_Join(s, v)) #else #define __Pyx_PyString_Join PyUnicode_Join #define __Pyx_PyBaseString_Join PyUnicode_Join #endif #if CYTHON_COMPILING_IN_CPYTHON #if PY_MAJOR_VERSION < 3 #define __Pyx_PyBytes_Join _PyString_Join #else #define __Pyx_PyBytes_Join _PyBytes_Join #endif #else static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values); #endif static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); #define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ __Pyx_GetItemInt_Generic(o, to_py_func(i)))) #define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, int wraparound, int boundscheck); #define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, int wraparound, int boundscheck); static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, int wraparound, int boundscheck); static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d); typedef struct { PyObject *type; PyObject **method_name; PyCFunction func; PyObject *method; int flag; } __Pyx_CachedCFunction; static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_CallUnboundCMethod0(cfunc, self)\ ((likely((cfunc)->func)) ?\ (likely((cfunc)->flag == METH_NOARGS) ? (*((cfunc)->func))(self, NULL) :\ (likely((cfunc)->flag == (METH_VARARGS | METH_KEYWORDS)) ? ((*(PyCFunctionWithKeywords)(cfunc)->func)(self, __pyx_empty_tuple, NULL)) :\ ((cfunc)->flag == METH_VARARGS ? (*((cfunc)->func))(self, __pyx_empty_tuple) : __Pyx__CallUnboundCMethod0(cfunc, self)))) :\ __Pyx__CallUnboundCMethod0(cfunc, self)) #else #define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self) #endif static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); static CYTHON_INLINE int __Pyx_IterFinish(void); static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); #define __Pyx_DelItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ __Pyx_DelItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound) :\ (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) :\ __Pyx_DelItem_Generic(o, to_py_func(i)))) static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j); static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, int wraparound); static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix); static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix); #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix); #define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) (\ (likely(PyList_CheckExact(L) && __Pyx_fits_Py_ssize_t(ix, type, is_signed))) ?\ __Pyx__PyList_PopIndex(L, py_ix, ix) : (\ (unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) :\ __Pyx__PyObject_PopIndex(L, py_ix))) #define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) (\ __Pyx_fits_Py_ssize_t(ix, type, is_signed) ?\ __Pyx__PyList_PopIndex(L, py_ix, ix) : (\ (unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) :\ __Pyx__PyObject_PopIndex(L, py_ix))) #else #define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func)\ __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) #define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) (\ (unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) :\ __Pyx__PyObject_PopIndex(L, py_ix)) #endif static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, const char *name, int exact); static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { int result = PySequence_Contains(seq, item); return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); } static int __Pyx_SetVtable(PyObject *dict, void *vtable); static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases); static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); #define __Pyx_CyFunction_USED 1 #include #define __Pyx_CYFUNCTION_STATICMETHOD 0x01 #define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 #define __Pyx_CYFUNCTION_CCLASS 0x04 #define __Pyx_CyFunction_GetClosure(f)\ (((__pyx_CyFunctionObject *) (f))->func_closure) #define __Pyx_CyFunction_GetClassObj(f)\ (((__pyx_CyFunctionObject *) (f))->func_classobj) #define __Pyx_CyFunction_Defaults(type, f)\ ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) #define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) typedef struct { PyCFunctionObject func; #if PY_VERSION_HEX < 0x030500A0 PyObject *func_weakreflist; #endif PyObject *func_dict; PyObject *func_name; PyObject *func_qualname; PyObject *func_doc; PyObject *func_globals; PyObject *func_code; PyObject *func_closure; PyObject *func_classobj; void *defaults; int defaults_pyobjects; int flags; PyObject *defaults_tuple; PyObject *defaults_kwdict; PyObject *(*defaults_getter)(PyObject *); PyObject *func_annotations; } __pyx_CyFunctionObject; static PyTypeObject *__pyx_CyFunctionType = 0; #define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code)\ __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code) static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml, int flags, PyObject* qualname, PyObject *self, PyObject *module, PyObject *globals, PyObject* code); static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, size_t size, int pyobjects); static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, PyObject *tuple); static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, PyObject *dict); static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, PyObject *dict); static int __pyx_CyFunction_init(void); static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc); static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass); typedef struct { int code_line; PyCodeObject* code_object; } __Pyx_CodeObjectCacheEntry; struct __Pyx_CodeObjectCache { int count; int max_count; __Pyx_CodeObjectCacheEntry* entries; }; static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); static PyCodeObject *__pyx_find_code_object(int code_line); static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); static void __Pyx_AddTraceback(const char *funcname, int c_line, int py_line, const char *filename); static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); static int __Pyx_check_binary_version(void); static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base__upper(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_s); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base__getall(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base__getone(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base__contains(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base_keys(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base__eq_to_mapping(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_other); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_16CIMultiDictProxy__upper(struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy *__pyx_v_self, PyObject *__pyx_v_s); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_9MultiDict__extend(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs, PyObject *__pyx_v_name, int __pyx_v_do_add); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_9MultiDict__add(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_9MultiDict__replace(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_9MultiDict__remove(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_v_raise_key_error); /* proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_11CIMultiDict__upper(struct __pyx_obj_7aiohttp_10_multidict_CIMultiDict *__pyx_v_self, PyObject *__pyx_v_s); /* proto*/ /* Module declarations from 'aiohttp._multidict' */ static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict__Pair = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict__Base = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict_MultiDictProxy = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict_CIMultiDictProxy = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict_MultiDict = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict_CIMultiDict = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict__ViewBase = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict__ViewBaseSet = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict__ItemsIter = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict__ItemsView = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict__ValuesIter = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict__ValuesView = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict__KeysIter = 0; static PyTypeObject *__pyx_ptype_7aiohttp_10_multidict__KeysView = 0; static PyObject *__pyx_f_7aiohttp_10_multidict__eq(PyObject *, PyObject *); /*proto*/ #define __Pyx_MODULE_NAME "aiohttp._multidict" int __pyx_module_is_main_aiohttp___multidict = 0; /* Implementation of 'aiohttp._multidict' */ static PyObject *__pyx_builtin_object; static PyObject *__pyx_builtin_memoryview; static PyObject *__pyx_builtin_NotImplemented; static PyObject *__pyx_builtin_KeyError; static PyObject *__pyx_builtin_TypeError; static PyObject *__pyx_builtin_range; static PyObject *__pyx_builtin_StopIteration; static char __pyx_k_[] = ""; static char __pyx_k_r[] = "'{}': {!r}"; static char __pyx_k__4[] = ", "; static char __pyx_k__5[] = "<{}({})>"; static char __pyx_k__8[] = "{}({})"; static char __pyx_k_Set[] = "Set"; static char __pyx_k_abc[] = "abc"; static char __pyx_k_arg[] = "arg"; static char __pyx_k_cls[] = "cls"; static char __pyx_k_doc[] = "__doc__"; static char __pyx_k_get[] = "get"; static char __pyx_k_key[] = "key"; static char __pyx_k_new[] = "__new__"; static char __pyx_k_pop[] = "pop"; static char __pyx_k_r_2[] = "{!r}"; static char __pyx_k_r_r[] = "{!r}: {!r}"; static char __pyx_k_sys[] = "sys"; static char __pyx_k_val[] = "val"; static char __pyx_k_join[] = "join"; static char __pyx_k_keys[] = "keys"; static char __pyx_k_main[] = "__main__"; static char __pyx_k_name[] = "__name__"; static char __pyx_k_self[] = "self"; static char __pyx_k_test[] = "__test__"; static char __pyx_k_class[] = "__class__"; static char __pyx_k_clear[] = "clear"; static char __pyx_k_items[] = "items"; static char __pyx_k_range[] = "range"; static char __pyx_k_upper[] = "upper"; static char __pyx_k_upstr[] = "upstr"; static char __pyx_k_value[] = "value"; static char __pyx_k_errors[] = "errors"; static char __pyx_k_extend[] = "extend"; static char __pyx_k_format[] = "format"; static char __pyx_k_import[] = "__import__"; static char __pyx_k_marker[] = "_marker"; static char __pyx_k_module[] = "__module__"; static char __pyx_k_object[] = "object"; static char __pyx_k_strict[] = "strict"; static char __pyx_k_update[] = "update"; static char __pyx_k_Mapping[] = "Mapping"; static char __pyx_k_default[] = "default"; static char __pyx_k_prepare[] = "__prepare__"; static char __pyx_k_Iterable[] = "Iterable"; static char __pyx_k_KeyError[] = "KeyError"; static char __pyx_k_KeysView[] = "KeysView"; static char __pyx_k_encoding[] = "encoding"; static char __pyx_k_operator[] = "operator"; static char __pyx_k_qualname[] = "__qualname__"; static char __pyx_k_register[] = "register"; static char __pyx_k_ItemsView[] = "ItemsView"; static char __pyx_k_TypeError[] = "TypeError"; static char __pyx_k_metaclass[] = "__metaclass__"; static char __pyx_k_ValuesView[] = "ValuesView"; static char __pyx_k_itemgetter[] = "itemgetter"; static char __pyx_k_memoryview[] = "memoryview"; static char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; static char __pyx_k_collections[] = "collections"; static char __pyx_k_upstr___new[] = "upstr.__new__"; static char __pyx_k_upstr_upper[] = "upstr.upper"; static char __pyx_k_StopIteration[] = "StopIteration"; static char __pyx_k_MutableMapping[] = "MutableMapping"; static char __pyx_k_NotImplemented[] = "NotImplemented"; static char __pyx_k_Key_not_found_r[] = "Key not found: %r"; static char __pyx_k_collections_abc[] = "collections.abc"; static char __pyx_k_empty_multidict[] = "empty multidict"; static char __pyx_k_aiohttp__multidict[] = "aiohttp._multidict"; static char __pyx_k_getdefaultencoding[] = "getdefaultencoding"; static char __pyx_k_Case_insensitive_str[] = "Case insensitive str."; static char __pyx_k_home_andrew_projects_aiohttp_ai[] = "/home/andrew/projects/aiohttp/aiohttp/_multidict.pyx"; static char __pyx_k_takes_at_most_1_positional_argu[] = "{} takes at most 1 positional argument ({} given)"; static char __pyx_k_takes_either_dict_or_list_of_ke[] = "{} takes either dict or list of (key, value) tuples"; static char __pyx_k_CIMultiDictProxy_requires_CIMult[] = "CIMultiDictProxy requires CIMultiDict instance, not {}"; static char __pyx_k_MultiDictProxy_requires_MultiDic[] = "MultiDictProxy requires MultiDict instance, not {}"; static PyObject *__pyx_kp_s_; static PyObject *__pyx_kp_s_CIMultiDictProxy_requires_CIMult; static PyObject *__pyx_kp_s_Case_insensitive_str; static PyObject *__pyx_n_s_ItemsView; static PyObject *__pyx_n_s_Iterable; static PyObject *__pyx_n_s_KeyError; static PyObject *__pyx_kp_s_Key_not_found_r; static PyObject *__pyx_n_s_KeysView; static PyObject *__pyx_n_s_Mapping; static PyObject *__pyx_kp_s_MultiDictProxy_requires_MultiDic; static PyObject *__pyx_n_s_MutableMapping; static PyObject *__pyx_n_s_NotImplemented; static PyObject *__pyx_n_s_Set; static PyObject *__pyx_n_s_StopIteration; static PyObject *__pyx_n_s_TypeError; static PyObject *__pyx_n_s_ValuesView; static PyObject *__pyx_kp_s__4; static PyObject *__pyx_kp_s__5; static PyObject *__pyx_kp_s__8; static PyObject *__pyx_n_s_abc; static PyObject *__pyx_n_s_aiohttp__multidict; static PyObject *__pyx_n_s_arg; static PyObject *__pyx_n_s_class; static PyObject *__pyx_n_s_clear; static PyObject *__pyx_n_s_cls; static PyObject *__pyx_n_s_collections; static PyObject *__pyx_n_s_collections_abc; static PyObject *__pyx_n_s_default; static PyObject *__pyx_n_s_doc; static PyObject *__pyx_kp_s_empty_multidict; static PyObject *__pyx_n_s_encoding; static PyObject *__pyx_n_s_errors; static PyObject *__pyx_n_s_extend; static PyObject *__pyx_n_s_format; static PyObject *__pyx_n_s_get; static PyObject *__pyx_n_s_getdefaultencoding; static PyObject *__pyx_kp_s_home_andrew_projects_aiohttp_ai; static PyObject *__pyx_n_s_import; static PyObject *__pyx_n_s_itemgetter; static PyObject *__pyx_n_s_items; static PyObject *__pyx_n_s_join; static PyObject *__pyx_n_s_key; static PyObject *__pyx_n_s_keys; static PyObject *__pyx_n_s_main; static PyObject *__pyx_n_s_marker; static PyObject *__pyx_n_s_memoryview; static PyObject *__pyx_n_s_metaclass; static PyObject *__pyx_n_s_module; static PyObject *__pyx_n_s_name; static PyObject *__pyx_n_s_new; static PyObject *__pyx_n_s_object; static PyObject *__pyx_n_s_operator; static PyObject *__pyx_n_s_pop; static PyObject *__pyx_n_s_prepare; static PyObject *__pyx_n_s_pyx_vtable; static PyObject *__pyx_n_s_qualname; static PyObject *__pyx_kp_s_r; static PyObject *__pyx_kp_s_r_2; static PyObject *__pyx_kp_s_r_r; static PyObject *__pyx_n_s_range; static PyObject *__pyx_n_s_register; static PyObject *__pyx_n_s_self; static PyObject *__pyx_n_s_strict; static PyObject *__pyx_n_s_sys; static PyObject *__pyx_kp_s_takes_at_most_1_positional_argu; static PyObject *__pyx_kp_s_takes_either_dict_or_list_of_ke; static PyObject *__pyx_n_s_test; static PyObject *__pyx_n_s_update; static PyObject *__pyx_n_s_upper; static PyObject *__pyx_n_s_upstr; static PyObject *__pyx_n_s_upstr___new; static PyObject *__pyx_n_s_upstr_upper; static PyObject *__pyx_n_s_val; static PyObject *__pyx_n_s_value; static PyObject *__pyx_pf_7aiohttp_10_multidict_5upstr_4__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5upstr___new__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_cls, PyObject *__pyx_v_val, PyObject *__pyx_v_encoding, PyObject *__pyx_v_errors); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5upstr_2upper(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_5_Pair___cinit__(struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Pair_2__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_5_Base___cinit__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_2getall(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_4getone(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_6__getitem__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_8get(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_5_Base_10__contains__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_12__iter__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self); /* proto */ static Py_ssize_t __pyx_pf_7aiohttp_10_multidict_5_Base_14__len__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_16keys(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_18items(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_20values(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_22__repr__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_24__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_14MultiDictProxy___init__(struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy *__pyx_v_self, PyObject *__pyx_v_arg); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_14MultiDictProxy_2copy(struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy *__pyx_v_self); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_16CIMultiDictProxy___init__(struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy *__pyx_v_self, PyObject *__pyx_v_arg); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_16CIMultiDictProxy_2copy(struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy *__pyx_v_self); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_9MultiDict___init__(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_2add(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_4copy(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_6extend(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_8clear(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_9MultiDict_10__setitem__(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_9MultiDict_12__delitem__(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_14setdefault(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_16pop(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_18popitem(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_20update(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_9_ViewBase___cinit__(struct __pyx_obj_7aiohttp_10_multidict__ViewBase *__pyx_v_self, PyObject *__pyx_v_items); /* proto */ static Py_ssize_t __pyx_pf_7aiohttp_10_multidict_9_ViewBase_2__len__(struct __pyx_obj_7aiohttp_10_multidict__ViewBase *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet___richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_2__and__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_4__or__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_6__sub__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_8__xor__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_10_ItemsIter___cinit__(struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *__pyx_v_self, PyObject *__pyx_v_items); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_10_ItemsIter_2__iter__(struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_10_ItemsIter_4__next__(struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_10_ItemsView_isdisjoint(struct __pyx_obj_7aiohttp_10_multidict__ItemsView *__pyx_v_self, PyObject *__pyx_v_other); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_10_ItemsView_2__contains__(struct __pyx_obj_7aiohttp_10_multidict__ItemsView *__pyx_v_self, PyObject *__pyx_v_i); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_10_ItemsView_4__iter__(struct __pyx_obj_7aiohttp_10_multidict__ItemsView *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_10_ItemsView_6__repr__(struct __pyx_obj_7aiohttp_10_multidict__ItemsView *__pyx_v_self); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_11_ValuesIter___cinit__(struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *__pyx_v_self, PyObject *__pyx_v_items); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_11_ValuesIter_2__iter__(struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_11_ValuesIter_4__next__(struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *__pyx_v_self); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_11_ValuesView___contains__(struct __pyx_obj_7aiohttp_10_multidict__ValuesView *__pyx_v_self, PyObject *__pyx_v_value); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_11_ValuesView_2__iter__(struct __pyx_obj_7aiohttp_10_multidict__ValuesView *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_11_ValuesView_4__repr__(struct __pyx_obj_7aiohttp_10_multidict__ValuesView *__pyx_v_self); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_9_KeysIter___cinit__(struct __pyx_obj_7aiohttp_10_multidict__KeysIter *__pyx_v_self, PyObject *__pyx_v_items); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9_KeysIter_2__iter__(struct __pyx_obj_7aiohttp_10_multidict__KeysIter *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9_KeysIter_4__next__(struct __pyx_obj_7aiohttp_10_multidict__KeysIter *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9_KeysView_isdisjoint(struct __pyx_obj_7aiohttp_10_multidict__KeysView *__pyx_v_self, PyObject *__pyx_v_other); /* proto */ static int __pyx_pf_7aiohttp_10_multidict_9_KeysView_2__contains__(struct __pyx_obj_7aiohttp_10_multidict__KeysView *__pyx_v_self, PyObject *__pyx_v_value); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9_KeysView_4__iter__(struct __pyx_obj_7aiohttp_10_multidict__KeysView *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_7aiohttp_10_multidict_9_KeysView_6__repr__(struct __pyx_obj_7aiohttp_10_multidict__KeysView *__pyx_v_self); /* proto */ static PyObject *__pyx_tp_new_7aiohttp_10_multidict__Pair(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict__Base(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict_MultiDictProxy(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict_CIMultiDictProxy(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict_MultiDict(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict_CIMultiDict(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ViewBase(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ViewBaseSet(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ItemsIter(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ItemsView(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ValuesIter(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ValuesView(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict__KeysIter(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_7aiohttp_10_multidict__KeysView(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_items = {0, &__pyx_n_s_items, 0, 0, 0}; static PyObject *__pyx_int_0; static PyObject *__pyx_int_1; static PyObject *__pyx_int_2; static PyObject *__pyx_int_3; static PyObject *__pyx_int_4; static PyObject *__pyx_int_5; static PyObject *__pyx_k__2; static PyObject *__pyx_k__3; static PyObject *__pyx_k__6; static PyObject *__pyx_tuple__7; static PyObject *__pyx_tuple__9; static PyObject *__pyx_tuple__11; static PyObject *__pyx_codeobj__10; static PyObject *__pyx_codeobj__12; /* "aiohttp/_multidict.pyx":14 * """Case insensitive str.""" * * def __new__(cls, val='', # <<<<<<<<<<<<<< * encoding=sys.getdefaultencoding(), errors='strict'): * if isinstance(val, (bytes, bytearray, memoryview)): */ static PyObject *__pyx_pf_7aiohttp_10_multidict_5upstr_4__defaults__(CYTHON_UNUSED PyObject *__pyx_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__defaults__", 0); __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(((PyObject*)__pyx_kp_s_)); __Pyx_GIVEREF(((PyObject*)__pyx_kp_s_)); PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject*)__pyx_kp_s_)); __Pyx_INCREF(__Pyx_CyFunction_Defaults(__pyx_defaults, __pyx_self)->__pyx_arg_encoding); __Pyx_GIVEREF(__Pyx_CyFunction_Defaults(__pyx_defaults, __pyx_self)->__pyx_arg_encoding); PyTuple_SET_ITEM(__pyx_t_1, 1, __Pyx_CyFunction_Defaults(__pyx_defaults, __pyx_self)->__pyx_arg_encoding); __Pyx_INCREF(((PyObject*)__pyx_n_s_strict)); __Pyx_GIVEREF(((PyObject*)__pyx_n_s_strict)); PyTuple_SET_ITEM(__pyx_t_1, 2, ((PyObject*)__pyx_n_s_strict)); __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __Pyx_INCREF(Py_None); __Pyx_GIVEREF(Py_None); PyTuple_SET_ITEM(__pyx_t_2, 1, Py_None); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict.upstr.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5upstr_1__new__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static PyMethodDef __pyx_mdef_7aiohttp_10_multidict_5upstr_1__new__ = {"__new__", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_5upstr_1__new__, METH_VARARGS|METH_KEYWORDS, 0}; static PyObject *__pyx_pw_7aiohttp_10_multidict_5upstr_1__new__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_cls = 0; PyObject *__pyx_v_val = 0; PyObject *__pyx_v_encoding = 0; PyObject *__pyx_v_errors = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__new__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_cls,&__pyx_n_s_val,&__pyx_n_s_encoding,&__pyx_n_s_errors,0}; PyObject* values[4] = {0,0,0,0}; __pyx_defaults *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults, __pyx_self); values[1] = ((PyObject *)((PyObject*)__pyx_kp_s_)); values[2] = __pyx_dynamic_args->__pyx_arg_encoding; values[3] = ((PyObject *)((PyObject*)__pyx_n_s_strict)); if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_cls)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_val); if (value) { values[1] = value; kw_args--; } } case 2: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_encoding); if (value) { values[2] = value; kw_args--; } } case 3: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_errors); if (value) { values[3] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__new__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } __pyx_v_cls = values[0]; __pyx_v_val = values[1]; __pyx_v_encoding = values[2]; __pyx_v_errors = values[3]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__new__", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict.upstr.__new__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_5upstr___new__(__pyx_self, __pyx_v_cls, __pyx_v_val, __pyx_v_encoding, __pyx_v_errors); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5upstr___new__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_cls, PyObject *__pyx_v_val, PyObject *__pyx_v_encoding, PyObject *__pyx_v_errors) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_t_2; int __pyx_t_3; int __pyx_t_4; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; Py_ssize_t __pyx_t_7; PyObject *__pyx_t_8 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__new__", 0); __Pyx_INCREF(__pyx_v_val); /* "aiohttp/_multidict.pyx":16 * def __new__(cls, val='', * encoding=sys.getdefaultencoding(), errors='strict'): * if isinstance(val, (bytes, bytearray, memoryview)): # <<<<<<<<<<<<<< * val = str(val, encoding, errors) * elif isinstance(val, str): */ __Pyx_INCREF(__pyx_builtin_memoryview); __pyx_t_1 = __pyx_builtin_memoryview; __pyx_t_3 = PyBytes_Check(__pyx_v_val); __pyx_t_4 = (__pyx_t_3 != 0); if (!__pyx_t_4) { } else { __pyx_t_2 = __pyx_t_4; goto __pyx_L4_bool_binop_done; } __pyx_t_4 = PyByteArray_Check(__pyx_v_val); __pyx_t_3 = (__pyx_t_4 != 0); if (!__pyx_t_3) { } else { __pyx_t_2 = __pyx_t_3; goto __pyx_L4_bool_binop_done; } __pyx_t_3 = PyObject_IsInstance(__pyx_v_val, __pyx_t_1); __pyx_t_4 = (__pyx_t_3 != 0); __pyx_t_2 = __pyx_t_4; __pyx_L4_bool_binop_done:; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_4 = (__pyx_t_2 != 0); if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":17 * encoding=sys.getdefaultencoding(), errors='strict'): * if isinstance(val, (bytes, bytearray, memoryview)): * val = str(val, encoding, errors) # <<<<<<<<<<<<<< * elif isinstance(val, str): * pass */ __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_val); __Pyx_GIVEREF(__pyx_v_val); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_val); __Pyx_INCREF(__pyx_v_encoding); __Pyx_GIVEREF(__pyx_v_encoding); PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_encoding); __Pyx_INCREF(__pyx_v_errors); __Pyx_GIVEREF(__pyx_v_errors); PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_errors); __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)(&PyString_Type)), __pyx_t_1, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF_SET(__pyx_v_val, __pyx_t_5); __pyx_t_5 = 0; /* "aiohttp/_multidict.pyx":16 * def __new__(cls, val='', * encoding=sys.getdefaultencoding(), errors='strict'): * if isinstance(val, (bytes, bytearray, memoryview)): # <<<<<<<<<<<<<< * val = str(val, encoding, errors) * elif isinstance(val, str): */ goto __pyx_L3; } /* "aiohttp/_multidict.pyx":18 * if isinstance(val, (bytes, bytearray, memoryview)): * val = str(val, encoding, errors) * elif isinstance(val, str): # <<<<<<<<<<<<<< * pass * else: */ __pyx_t_4 = PyString_Check(__pyx_v_val); __pyx_t_2 = (__pyx_t_4 != 0); if (__pyx_t_2) { goto __pyx_L3; } /* "aiohttp/_multidict.pyx":21 * pass * else: * val = str(val) # <<<<<<<<<<<<<< * val = val.upper() * return str.__new__(cls, val) */ /*else*/ { __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); __Pyx_INCREF(__pyx_v_val); __Pyx_GIVEREF(__pyx_v_val); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_val); __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)(&PyString_Type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF_SET(__pyx_v_val, __pyx_t_1); __pyx_t_1 = 0; } __pyx_L3:; /* "aiohttp/_multidict.pyx":22 * else: * val = str(val) * val = val.upper() # <<<<<<<<<<<<<< * return str.__new__(cls, val) * */ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_val, __pyx_n_s_upper); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); __pyx_t_6 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) { __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); if (likely(__pyx_t_6)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); __Pyx_INCREF(__pyx_t_6); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_5, function); } } if (__pyx_t_6) { __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } else { __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF_SET(__pyx_v_val, __pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":23 * val = str(val) * val = val.upper() * return str.__new__(cls, val) # <<<<<<<<<<<<<< * * def upper(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)(&PyString_Type)), __pyx_n_s_new); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); __pyx_t_6 = NULL; __pyx_t_7 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) { __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); if (likely(__pyx_t_6)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); __Pyx_INCREF(__pyx_t_6); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_5, function); __pyx_t_7 = 1; } } __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_8); if (__pyx_t_6) { __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL; } __Pyx_INCREF(__pyx_v_cls); __Pyx_GIVEREF(__pyx_v_cls); PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_v_cls); __Pyx_INCREF(__pyx_v_val); __Pyx_GIVEREF(__pyx_v_val); PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_val); __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":14 * """Case insensitive str.""" * * def __new__(cls, val='', # <<<<<<<<<<<<<< * encoding=sys.getdefaultencoding(), errors='strict'): * if isinstance(val, (bytes, bytearray, memoryview)): */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_8); __Pyx_AddTraceback("aiohttp._multidict.upstr.__new__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_val); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":25 * return str.__new__(cls, val) * * def upper(self): # <<<<<<<<<<<<<< * return self * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5upstr_3upper(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ static PyMethodDef __pyx_mdef_7aiohttp_10_multidict_5upstr_3upper = {"upper", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_5upstr_3upper, METH_O, 0}; static PyObject *__pyx_pw_7aiohttp_10_multidict_5upstr_3upper(PyObject *__pyx_self, PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("upper (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_5upstr_2upper(__pyx_self, ((PyObject *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5upstr_2upper(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("upper", 0); /* "aiohttp/_multidict.pyx":26 * * def upper(self): * return self # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_self); __pyx_r = __pyx_v_self; goto __pyx_L0; /* "aiohttp/_multidict.pyx":25 * return str.__new__(cls, val) * * def upper(self): # <<<<<<<<<<<<<< * return self * */ /* function exit code */ __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":29 * * * cdef _eq(self, other): # <<<<<<<<<<<<<< * cdef _Base typed_self * cdef _Base typed_other */ static PyObject *__pyx_f_7aiohttp_10_multidict__eq(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { int __pyx_v_is_left_base; int __pyx_v_is_right_base; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; int __pyx_t_5; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_eq", 0); /* "aiohttp/_multidict.pyx":34 * cdef int is_left_base, is_right_base * * is_left_base = isinstance(self, _Base) # <<<<<<<<<<<<<< * is_right_base = isinstance(other, _Base) * */ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_self, __pyx_ptype_7aiohttp_10_multidict__Base); __pyx_v_is_left_base = __pyx_t_1; /* "aiohttp/_multidict.pyx":35 * * is_left_base = isinstance(self, _Base) * is_right_base = isinstance(other, _Base) # <<<<<<<<<<<<<< * * if is_left_base and is_right_base: */ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_other, __pyx_ptype_7aiohttp_10_multidict__Base); __pyx_v_is_right_base = __pyx_t_1; /* "aiohttp/_multidict.pyx":37 * is_right_base = isinstance(other, _Base) * * if is_left_base and is_right_base: # <<<<<<<<<<<<<< * return (<_Base>self)._items == (<_Base>other)._items * elif is_left_base and isinstance(other, abc.Mapping): */ __pyx_t_2 = (__pyx_v_is_left_base != 0); if (__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L4_bool_binop_done; } __pyx_t_2 = (__pyx_v_is_right_base != 0); __pyx_t_1 = __pyx_t_2; __pyx_L4_bool_binop_done:; if (__pyx_t_1) { /* "aiohttp/_multidict.pyx":38 * * if is_left_base and is_right_base: * return (<_Base>self)._items == (<_Base>other)._items # <<<<<<<<<<<<<< * elif is_left_base and isinstance(other, abc.Mapping): * return (<_Base>self)._eq_to_mapping(other) */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = PyObject_RichCompare(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self)->_items, ((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_other)->_items, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":37 * is_right_base = isinstance(other, _Base) * * if is_left_base and is_right_base: # <<<<<<<<<<<<<< * return (<_Base>self)._items == (<_Base>other)._items * elif is_left_base and isinstance(other, abc.Mapping): */ } /* "aiohttp/_multidict.pyx":39 * if is_left_base and is_right_base: * return (<_Base>self)._items == (<_Base>other)._items * elif is_left_base and isinstance(other, abc.Mapping): # <<<<<<<<<<<<<< * return (<_Base>self)._eq_to_mapping(other) * elif is_right_base and isinstance(self, abc.Mapping): */ __pyx_t_2 = (__pyx_v_is_left_base != 0); if (__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L6_bool_binop_done; } __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_abc); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_Mapping); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_2 = PyObject_IsInstance(__pyx_v_other, __pyx_t_4); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_5 = (__pyx_t_2 != 0); __pyx_t_1 = __pyx_t_5; __pyx_L6_bool_binop_done:; if (__pyx_t_1) { /* "aiohttp/_multidict.pyx":40 * return (<_Base>self)._items == (<_Base>other)._items * elif is_left_base and isinstance(other, abc.Mapping): * return (<_Base>self)._eq_to_mapping(other) # <<<<<<<<<<<<<< * elif is_right_base and isinstance(self, abc.Mapping): * return (<_Base>other)._eq_to_mapping(self) */ __Pyx_XDECREF(__pyx_r); __pyx_t_4 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self)->__pyx_vtab)->_eq_to_mapping(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_v_other); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":39 * if is_left_base and is_right_base: * return (<_Base>self)._items == (<_Base>other)._items * elif is_left_base and isinstance(other, abc.Mapping): # <<<<<<<<<<<<<< * return (<_Base>self)._eq_to_mapping(other) * elif is_right_base and isinstance(self, abc.Mapping): */ } /* "aiohttp/_multidict.pyx":41 * elif is_left_base and isinstance(other, abc.Mapping): * return (<_Base>self)._eq_to_mapping(other) * elif is_right_base and isinstance(self, abc.Mapping): # <<<<<<<<<<<<<< * return (<_Base>other)._eq_to_mapping(self) * else: */ __pyx_t_5 = (__pyx_v_is_right_base != 0); if (__pyx_t_5) { } else { __pyx_t_1 = __pyx_t_5; goto __pyx_L8_bool_binop_done; } __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_abc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Mapping); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_5 = PyObject_IsInstance(__pyx_v_self, __pyx_t_3); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_2 = (__pyx_t_5 != 0); __pyx_t_1 = __pyx_t_2; __pyx_L8_bool_binop_done:; if (__pyx_t_1) { /* "aiohttp/_multidict.pyx":42 * return (<_Base>self)._eq_to_mapping(other) * elif is_right_base and isinstance(self, abc.Mapping): * return (<_Base>other)._eq_to_mapping(self) # <<<<<<<<<<<<<< * else: * return NotImplemented */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_other)->__pyx_vtab)->_eq_to_mapping(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_other), __pyx_v_self); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":41 * elif is_left_base and isinstance(other, abc.Mapping): * return (<_Base>self)._eq_to_mapping(other) * elif is_right_base and isinstance(self, abc.Mapping): # <<<<<<<<<<<<<< * return (<_Base>other)._eq_to_mapping(self) * else: */ } /* "aiohttp/_multidict.pyx":44 * return (<_Base>other)._eq_to_mapping(self) * else: * return NotImplemented # <<<<<<<<<<<<<< * * */ /*else*/ { __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; } /* "aiohttp/_multidict.pyx":29 * * * cdef _eq(self, other): # <<<<<<<<<<<<<< * cdef _Base typed_self * cdef _Base typed_other */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._multidict._eq", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":51 * cdef object _value * * def __cinit__(self, key, value): # <<<<<<<<<<<<<< * self._key = key * self._value = value */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_5_Pair_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_5_Pair_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_key = 0; PyObject *__pyx_v_value = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_key,&__pyx_n_s_value,0}; PyObject* values[2] = {0,0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_value)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); values[1] = PyTuple_GET_ITEM(__pyx_args, 1); } __pyx_v_key = values[0]; __pyx_v_value = values[1]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._Pair.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Pair___cinit__(((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_v_self), __pyx_v_key, __pyx_v_value); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_5_Pair___cinit__(struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__cinit__", 0); /* "aiohttp/_multidict.pyx":52 * * def __cinit__(self, key, value): * self._key = key # <<<<<<<<<<<<<< * self._value = value * */ __Pyx_INCREF(__pyx_v_key); __Pyx_GIVEREF(__pyx_v_key); __Pyx_GOTREF(__pyx_v_self->_key); __Pyx_DECREF(__pyx_v_self->_key); __pyx_v_self->_key = __pyx_v_key; /* "aiohttp/_multidict.pyx":53 * def __cinit__(self, key, value): * self._key = key * self._value = value # <<<<<<<<<<<<<< * * def __richcmp__(self, other, op): */ __Pyx_INCREF(__pyx_v_value); __Pyx_GIVEREF(__pyx_v_value); __Pyx_GOTREF(__pyx_v_self->_value); __Pyx_DECREF(__pyx_v_self->_value); __pyx_v_self->_value = __pyx_v_value; /* "aiohttp/_multidict.pyx":51 * cdef object _value * * def __cinit__(self, key, value): # <<<<<<<<<<<<<< * self._key = key * self._value = value */ /* function exit code */ __pyx_r = 0; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":55 * self._value = value * * def __richcmp__(self, other, op): # <<<<<<<<<<<<<< * cdef _Pair left, right * if not isinstance(self, _Pair) or not isinstance(other, _Pair): */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Pair_3__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Pair_3__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op) { PyObject *__pyx_v_op = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__richcmp__ (wrapper)", 0); __pyx_v_op = __Pyx_PyInt_From_int(__pyx_arg_op); if (unlikely(!__pyx_v_op)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __Pyx_GOTREF(__pyx_v_op); goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._Pair.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Pair_2__richcmp__(((PyObject *)__pyx_v_self), ((PyObject *)__pyx_v_other), ((PyObject *)__pyx_v_op)); /* function exit code */ __Pyx_XDECREF(__pyx_v_op); __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Pair_2__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_left = 0; struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_right = 0; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; int __pyx_t_3; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__richcmp__", 0); /* "aiohttp/_multidict.pyx":57 * def __richcmp__(self, other, op): * cdef _Pair left, right * if not isinstance(self, _Pair) or not isinstance(other, _Pair): # <<<<<<<<<<<<<< * return NotImplemented * left = <_Pair>self */ __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_self, __pyx_ptype_7aiohttp_10_multidict__Pair); __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); if (!__pyx_t_3) { } else { __pyx_t_1 = __pyx_t_3; goto __pyx_L4_bool_binop_done; } __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_other, __pyx_ptype_7aiohttp_10_multidict__Pair); __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); __pyx_t_1 = __pyx_t_2; __pyx_L4_bool_binop_done:; if (__pyx_t_1) { /* "aiohttp/_multidict.pyx":58 * cdef _Pair left, right * if not isinstance(self, _Pair) or not isinstance(other, _Pair): * return NotImplemented # <<<<<<<<<<<<<< * left = <_Pair>self * right = <_Pair>other */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; /* "aiohttp/_multidict.pyx":57 * def __richcmp__(self, other, op): * cdef _Pair left, right * if not isinstance(self, _Pair) or not isinstance(other, _Pair): # <<<<<<<<<<<<<< * return NotImplemented * left = <_Pair>self */ } /* "aiohttp/_multidict.pyx":59 * if not isinstance(self, _Pair) or not isinstance(other, _Pair): * return NotImplemented * left = <_Pair>self # <<<<<<<<<<<<<< * right = <_Pair>other * if op == 2: # == */ __pyx_t_4 = __pyx_v_self; __Pyx_INCREF(__pyx_t_4); __pyx_v_left = ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":60 * return NotImplemented * left = <_Pair>self * right = <_Pair>other # <<<<<<<<<<<<<< * if op == 2: # == * return left._key == right._key and left._value == right._value */ __pyx_t_4 = __pyx_v_other; __Pyx_INCREF(__pyx_t_4); __pyx_v_right = ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":61 * left = <_Pair>self * right = <_Pair>other * if op == 2: # == # <<<<<<<<<<<<<< * return left._key == right._key and left._value == right._value * elif op == 3: # != */ __pyx_t_4 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_2, 2, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_1) { /* "aiohttp/_multidict.pyx":62 * right = <_Pair>other * if op == 2: # == * return left._key == right._key and left._value == right._value # <<<<<<<<<<<<<< * elif op == 3: # != * return left._key != right._key and left._value != right._value */ __Pyx_XDECREF(__pyx_r); __pyx_t_5 = PyObject_RichCompare(__pyx_v_left->_key, __pyx_v_right->_key, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__pyx_t_1) { __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } else { __Pyx_INCREF(__pyx_t_5); __pyx_t_4 = __pyx_t_5; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; goto __pyx_L7_bool_binop_done; } __pyx_t_5 = PyObject_RichCompare(__pyx_v_left->_value, __pyx_v_right->_value, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_INCREF(__pyx_t_5); __pyx_t_4 = __pyx_t_5; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_L7_bool_binop_done:; __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":61 * left = <_Pair>self * right = <_Pair>other * if op == 2: # == # <<<<<<<<<<<<<< * return left._key == right._key and left._value == right._value * elif op == 3: # != */ } /* "aiohttp/_multidict.pyx":63 * if op == 2: # == * return left._key == right._key and left._value == right._value * elif op == 3: # != # <<<<<<<<<<<<<< * return left._key != right._key and left._value != right._value * */ __pyx_t_4 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_3, 3, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_1) { /* "aiohttp/_multidict.pyx":64 * return left._key == right._key and left._value == right._value * elif op == 3: # != * return left._key != right._key and left._value != right._value # <<<<<<<<<<<<<< * * cdef class _Base: */ __Pyx_XDECREF(__pyx_r); __pyx_t_5 = PyObject_RichCompare(__pyx_v_left->_key, __pyx_v_right->_key, Py_NE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__pyx_t_1) { __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } else { __Pyx_INCREF(__pyx_t_5); __pyx_t_4 = __pyx_t_5; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; goto __pyx_L9_bool_binop_done; } __pyx_t_5 = PyObject_RichCompare(__pyx_v_left->_value, __pyx_v_right->_value, Py_NE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_INCREF(__pyx_t_5); __pyx_t_4 = __pyx_t_5; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_L9_bool_binop_done:; __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":63 * if op == 2: # == * return left._key == right._key and left._value == right._value * elif op == 3: # != # <<<<<<<<<<<<<< * return left._key != right._key and left._value != right._value * */ } /* "aiohttp/_multidict.pyx":55 * self._value = value * * def __richcmp__(self, other, op): # <<<<<<<<<<<<<< * cdef _Pair left, right * if not isinstance(self, _Pair) or not isinstance(other, _Pair): */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("aiohttp._multidict._Pair.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_left); __Pyx_XDECREF((PyObject *)__pyx_v_right); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":72 * cdef object marker * * def __cinit__(self): # <<<<<<<<<<<<<< * self._upstr = upstr * self.marker = _marker */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_5_Base_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_5_Base_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) { __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return -1;} if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__cinit__", 0))) return -1; __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base___cinit__(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_5_Base___cinit__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__cinit__", 0); /* "aiohttp/_multidict.pyx":73 * * def __cinit__(self): * self._upstr = upstr # <<<<<<<<<<<<<< * self.marker = _marker * */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_upstr); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v_self->_upstr); __Pyx_DECREF(__pyx_v_self->_upstr); __pyx_v_self->_upstr = __pyx_t_1; __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":74 * def __cinit__(self): * self._upstr = upstr * self.marker = _marker # <<<<<<<<<<<<<< * * cdef str _upper(self, s): */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_marker); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v_self->marker); __Pyx_DECREF(__pyx_v_self->marker); __pyx_v_self->marker = __pyx_t_1; __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":72 * cdef object marker * * def __cinit__(self): # <<<<<<<<<<<<<< * self._upstr = upstr * self.marker = _marker */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("aiohttp._multidict._Base.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":76 * self.marker = _marker * * cdef str _upper(self, s): # <<<<<<<<<<<<<< * if type(s) is self._upstr: * return s */ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base__upper(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_s) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_upper", 0); /* "aiohttp/_multidict.pyx":77 * * cdef str _upper(self, s): * if type(s) is self._upstr: # <<<<<<<<<<<<<< * return s * return s */ __pyx_t_1 = (((PyObject *)Py_TYPE(__pyx_v_s)) == __pyx_v_self->_upstr); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":78 * cdef str _upper(self, s): * if type(s) is self._upstr: * return s # <<<<<<<<<<<<<< * return s * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject*)__pyx_v_s)); __pyx_r = ((PyObject*)__pyx_v_s); goto __pyx_L0; /* "aiohttp/_multidict.pyx":77 * * cdef str _upper(self, s): * if type(s) is self._upstr: # <<<<<<<<<<<<<< * return s * return s */ } /* "aiohttp/_multidict.pyx":79 * if type(s) is self._upstr: * return s * return s # <<<<<<<<<<<<<< * * def getall(self, key, default=_marker): */ __Pyx_XDECREF(__pyx_r); if (!(likely(PyString_CheckExact(__pyx_v_s))||((__pyx_v_s) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_v_s)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_INCREF(__pyx_v_s); __pyx_r = ((PyObject*)__pyx_v_s); goto __pyx_L0; /* "aiohttp/_multidict.pyx":76 * self.marker = _marker * * cdef str _upper(self, s): # <<<<<<<<<<<<<< * if type(s) is self._upstr: * return s */ /* function exit code */ __pyx_L1_error:; __Pyx_AddTraceback("aiohttp._multidict._Base._upper", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":81 * return s * * def getall(self, key, default=_marker): # <<<<<<<<<<<<<< * """Return a list of all values matching the key.""" * return self._getall(self._upper(key), default) */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_3getall(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_5_Base_2getall[] = "Return a list of all values matching the key."; static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_3getall(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_key = 0; PyObject *__pyx_v_default = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("getall (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_key,&__pyx_n_s_default,0}; PyObject* values[2] = {0,0}; values[1] = __pyx_k__2; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_default); if (value) { values[1] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "getall") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } __pyx_v_key = values[0]; __pyx_v_default = values[1]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("getall", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._Base.getall", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_2getall(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_v_key, __pyx_v_default); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_2getall(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("getall", 0); /* "aiohttp/_multidict.pyx":83 * def getall(self, key, default=_marker): * """Return a list of all values matching the key.""" * return self._getall(self._upper(key), default) # <<<<<<<<<<<<<< * * cdef _getall(self, str key, default): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_upper(__pyx_v_self, __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_getall(__pyx_v_self, ((PyObject*)__pyx_t_1), __pyx_v_default); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":81 * return s * * def getall(self, key, default=_marker): # <<<<<<<<<<<<<< * """Return a list of all values matching the key.""" * return self._getall(self._upper(key), default) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict._Base.getall", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":85 * return self._getall(self._upper(key), default) * * cdef _getall(self, str key, default): # <<<<<<<<<<<<<< * cdef list res * cdef _Pair item */ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base__getall(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default) { PyObject *__pyx_v_res = 0; struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_i = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; int __pyx_t_5; int __pyx_t_6; int __pyx_t_7; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_getall", 0); __Pyx_INCREF(__pyx_v_key); /* "aiohttp/_multidict.pyx":88 * cdef list res * cdef _Pair item * key = self._upper(key) # <<<<<<<<<<<<<< * res = [] * for i in self._items: */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_upper(__pyx_v_self, __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF_SET(__pyx_v_key, ((PyObject*)__pyx_t_1)); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":89 * cdef _Pair item * key = self._upper(key) * res = [] # <<<<<<<<<<<<<< * for i in self._items: * item = <_Pair>i */ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_res = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":90 * key = self._upper(key) * res = [] * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key == key: */ if (unlikely(__pyx_v_self->_items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":91 * res = [] * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * if item._key == key: * res.append(item._value) */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":92 * for i in self._items: * item = <_Pair>i * if item._key == key: # <<<<<<<<<<<<<< * res.append(item._value) * if res: */ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_item->_key, __pyx_v_key, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":93 * item = <_Pair>i * if item._key == key: * res.append(item._value) # <<<<<<<<<<<<<< * if res: * return res */ __pyx_t_3 = __pyx_v_item->_value; __Pyx_INCREF(__pyx_t_3); __pyx_t_5 = __Pyx_PyList_Append(__pyx_v_res, __pyx_t_3); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":92 * for i in self._items: * item = <_Pair>i * if item._key == key: # <<<<<<<<<<<<<< * res.append(item._value) * if res: */ } /* "aiohttp/_multidict.pyx":90 * key = self._upper(key) * res = [] * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key == key: */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":94 * if item._key == key: * res.append(item._value) * if res: # <<<<<<<<<<<<<< * return res * if not res and default is not self.marker: */ __pyx_t_4 = (__pyx_v_res != Py_None) && (PyList_GET_SIZE(__pyx_v_res) != 0); if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":95 * res.append(item._value) * if res: * return res # <<<<<<<<<<<<<< * if not res and default is not self.marker: * return default */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_res); __pyx_r = __pyx_v_res; goto __pyx_L0; /* "aiohttp/_multidict.pyx":94 * if item._key == key: * res.append(item._value) * if res: # <<<<<<<<<<<<<< * return res * if not res and default is not self.marker: */ } /* "aiohttp/_multidict.pyx":96 * if res: * return res * if not res and default is not self.marker: # <<<<<<<<<<<<<< * return default * raise KeyError('Key not found: %r' % key) */ __pyx_t_6 = (__pyx_v_res != Py_None) && (PyList_GET_SIZE(__pyx_v_res) != 0); __pyx_t_7 = ((!__pyx_t_6) != 0); if (__pyx_t_7) { } else { __pyx_t_4 = __pyx_t_7; goto __pyx_L8_bool_binop_done; } __pyx_t_7 = (__pyx_v_default != __pyx_v_self->marker); __pyx_t_6 = (__pyx_t_7 != 0); __pyx_t_4 = __pyx_t_6; __pyx_L8_bool_binop_done:; if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":97 * return res * if not res and default is not self.marker: * return default # <<<<<<<<<<<<<< * raise KeyError('Key not found: %r' % key) * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_default); __pyx_r = __pyx_v_default; goto __pyx_L0; /* "aiohttp/_multidict.pyx":96 * if res: * return res * if not res and default is not self.marker: # <<<<<<<<<<<<<< * return default * raise KeyError('Key not found: %r' % key) */ } /* "aiohttp/_multidict.pyx":98 * if not res and default is not self.marker: * return default * raise KeyError('Key not found: %r' % key) # <<<<<<<<<<<<<< * * def getone(self, key, default=_marker): */ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_Key_not_found_r, __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __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; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":85 * return self._getall(self._upper(key), default) * * cdef _getall(self, str key, default): # <<<<<<<<<<<<<< * cdef list res * cdef _Pair item */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._Base._getall", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF(__pyx_v_res); __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_i); __Pyx_XDECREF(__pyx_v_key); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":100 * raise KeyError('Key not found: %r' % key) * * def getone(self, key, default=_marker): # <<<<<<<<<<<<<< * """Get first value matching the key.""" * return self._getone(self._upper(key), default) */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_5getone(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_5_Base_4getone[] = "Get first value matching the key."; static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_5getone(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_key = 0; PyObject *__pyx_v_default = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("getone (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_key,&__pyx_n_s_default,0}; PyObject* values[2] = {0,0}; values[1] = __pyx_k__3; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_default); if (value) { values[1] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "getone") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } __pyx_v_key = values[0]; __pyx_v_default = values[1]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("getone", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._Base.getone", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_4getone(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_v_key, __pyx_v_default); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_4getone(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("getone", 0); /* "aiohttp/_multidict.pyx":102 * def getone(self, key, default=_marker): * """Get first value matching the key.""" * return self._getone(self._upper(key), default) # <<<<<<<<<<<<<< * * cdef _getone(self, str key, default): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_upper(__pyx_v_self, __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_getone(__pyx_v_self, ((PyObject*)__pyx_t_1), __pyx_v_default); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":100 * raise KeyError('Key not found: %r' % key) * * def getone(self, key, default=_marker): # <<<<<<<<<<<<<< * """Get first value matching the key.""" * return self._getone(self._upper(key), default) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict._Base.getone", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":104 * return self._getone(self._upper(key), default) * * cdef _getone(self, str key, default): # <<<<<<<<<<<<<< * cdef _Pair item * key = self._upper(key) */ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base__getone(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_i = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; int __pyx_t_5; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_getone", 0); __Pyx_INCREF(__pyx_v_key); /* "aiohttp/_multidict.pyx":106 * cdef _getone(self, str key, default): * cdef _Pair item * key = self._upper(key) # <<<<<<<<<<<<<< * for i in self._items: * item = <_Pair>i */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_upper(__pyx_v_self, __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF_SET(__pyx_v_key, ((PyObject*)__pyx_t_1)); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":107 * cdef _Pair item * key = self._upper(key) * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key == key: */ if (unlikely(__pyx_v_self->_items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":108 * key = self._upper(key) * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * if item._key == key: * return item._value */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":109 * for i in self._items: * item = <_Pair>i * if item._key == key: # <<<<<<<<<<<<<< * return item._value * if default is not self.marker: */ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_item->_key, __pyx_v_key, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":110 * item = <_Pair>i * if item._key == key: * return item._value # <<<<<<<<<<<<<< * if default is not self.marker: * return default */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_item->_value); __pyx_r = __pyx_v_item->_value; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":109 * for i in self._items: * item = <_Pair>i * if item._key == key: # <<<<<<<<<<<<<< * return item._value * if default is not self.marker: */ } /* "aiohttp/_multidict.pyx":107 * cdef _Pair item * key = self._upper(key) * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key == key: */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":111 * if item._key == key: * return item._value * if default is not self.marker: # <<<<<<<<<<<<<< * return default * raise KeyError('Key not found: %r' % key) */ __pyx_t_4 = (__pyx_v_default != __pyx_v_self->marker); __pyx_t_5 = (__pyx_t_4 != 0); if (__pyx_t_5) { /* "aiohttp/_multidict.pyx":112 * return item._value * if default is not self.marker: * return default # <<<<<<<<<<<<<< * raise KeyError('Key not found: %r' % key) * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_default); __pyx_r = __pyx_v_default; goto __pyx_L0; /* "aiohttp/_multidict.pyx":111 * if item._key == key: * return item._value * if default is not self.marker: # <<<<<<<<<<<<<< * return default * raise KeyError('Key not found: %r' % key) */ } /* "aiohttp/_multidict.pyx":113 * if default is not self.marker: * return default * raise KeyError('Key not found: %r' % key) # <<<<<<<<<<<<<< * * # Mapping interface # */ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_Key_not_found_r, __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __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; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":104 * return self._getone(self._upper(key), default) * * cdef _getone(self, str key, default): # <<<<<<<<<<<<<< * cdef _Pair item * key = self._upper(key) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._Base._getone", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_i); __Pyx_XDECREF(__pyx_v_key); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":117 * # Mapping interface # * * def __getitem__(self, key): # <<<<<<<<<<<<<< * return self._getone(self._upper(key), self.marker) * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_7__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_7__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_6__getitem__(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), ((PyObject *)__pyx_v_key)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_6__getitem__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__getitem__", 0); /* "aiohttp/_multidict.pyx":118 * * def __getitem__(self, key): * return self._getone(self._upper(key), self.marker) # <<<<<<<<<<<<<< * * def get(self, key, default=None): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_upper(__pyx_v_self, __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __pyx_v_self->marker; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_getone(__pyx_v_self, ((PyObject*)__pyx_t_1), __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":117 * # Mapping interface # * * def __getitem__(self, key): # <<<<<<<<<<<<<< * return self._getone(self._upper(key), self.marker) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._Base.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":120 * return self._getone(self._upper(key), self.marker) * * def get(self, key, default=None): # <<<<<<<<<<<<<< * """Get first value matching the key. * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_9get(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_5_Base_8get[] = "Get first value matching the key.\n\n The method is alias for .getone().\n "; static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_9get(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_key = 0; PyObject *__pyx_v_default = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("get (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_key,&__pyx_n_s_default,0}; PyObject* values[2] = {0,0}; values[1] = ((PyObject *)Py_None); if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_default); if (value) { values[1] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } __pyx_v_key = values[0]; __pyx_v_default = values[1]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("get", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._Base.get", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_8get(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_v_key, __pyx_v_default); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_8get(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("get", 0); /* "aiohttp/_multidict.pyx":125 * The method is alias for .getone(). * """ * return self._getone(self._upper(key), default) # <<<<<<<<<<<<<< * * def __contains__(self, key): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_upper(__pyx_v_self, __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_getone(__pyx_v_self, ((PyObject*)__pyx_t_1), __pyx_v_default); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":120 * return self._getone(self._upper(key), self.marker) * * def get(self, key, default=None): # <<<<<<<<<<<<<< * """Get first value matching the key. * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict._Base.get", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":127 * return self._getone(self._upper(key), default) * * def __contains__(self, key): # <<<<<<<<<<<<<< * return self._contains(self._upper(key)) * */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_5_Base_11__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_5_Base_11__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_10__contains__(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), ((PyObject *)__pyx_v_key)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_5_Base_10__contains__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_t_3; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__contains__", 0); /* "aiohttp/_multidict.pyx":128 * * def __contains__(self, key): * return self._contains(self._upper(key)) # <<<<<<<<<<<<<< * * cdef _contains(self, str key): */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_upper(__pyx_v_self, __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_contains(__pyx_v_self, ((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_3; goto __pyx_L0; /* "aiohttp/_multidict.pyx":127 * return self._getone(self._upper(key), default) * * def __contains__(self, key): # <<<<<<<<<<<<<< * return self._contains(self._upper(key)) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict._Base.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":130 * return self._contains(self._upper(key)) * * cdef _contains(self, str key): # <<<<<<<<<<<<<< * cdef _Pair item * key = self._upper(key) */ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base__contains(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_key) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_i = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_contains", 0); __Pyx_INCREF(__pyx_v_key); /* "aiohttp/_multidict.pyx":132 * cdef _contains(self, str key): * cdef _Pair item * key = self._upper(key) # <<<<<<<<<<<<<< * for i in self._items: * item = <_Pair>i */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->_upper(__pyx_v_self, __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF_SET(__pyx_v_key, ((PyObject*)__pyx_t_1)); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":133 * cdef _Pair item * key = self._upper(key) * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key == key: */ if (unlikely(__pyx_v_self->_items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":134 * key = self._upper(key) * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * if item._key == key: * return True */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":135 * for i in self._items: * item = <_Pair>i * if item._key == key: # <<<<<<<<<<<<<< * return True * return False */ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_item->_key, __pyx_v_key, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":136 * item = <_Pair>i * if item._key == key: * return True # <<<<<<<<<<<<<< * return False * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_True); __pyx_r = Py_True; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":135 * for i in self._items: * item = <_Pair>i * if item._key == key: # <<<<<<<<<<<<<< * return True * return False */ } /* "aiohttp/_multidict.pyx":133 * cdef _Pair item * key = self._upper(key) * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key == key: */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":137 * if item._key == key: * return True * return False # <<<<<<<<<<<<<< * * def __iter__(self): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; goto __pyx_L0; /* "aiohttp/_multidict.pyx":130 * return self._contains(self._upper(key)) * * cdef _contains(self, str key): # <<<<<<<<<<<<<< * cdef _Pair item * key = self._upper(key) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._Base._contains", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_i); __Pyx_XDECREF(__pyx_v_key); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":139 * return False * * def __iter__(self): # <<<<<<<<<<<<<< * return iter(self.keys()) * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_13__iter__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_13__iter__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_12__iter__(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_12__iter__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__iter__", 0); /* "aiohttp/_multidict.pyx":140 * * def __iter__(self): * return iter(self.keys()) # <<<<<<<<<<<<<< * * def __len__(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->keys(__pyx_v_self, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":139 * return False * * def __iter__(self): # <<<<<<<<<<<<<< * return iter(self.keys()) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict._Base.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":142 * return iter(self.keys()) * * def __len__(self): # <<<<<<<<<<<<<< * return len(self._items) * */ /* Python wrapper */ static Py_ssize_t __pyx_pw_7aiohttp_10_multidict_5_Base_15__len__(PyObject *__pyx_v_self); /*proto*/ static Py_ssize_t __pyx_pw_7aiohttp_10_multidict_5_Base_15__len__(PyObject *__pyx_v_self) { Py_ssize_t __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_14__len__(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static Py_ssize_t __pyx_pf_7aiohttp_10_multidict_5_Base_14__len__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self) { Py_ssize_t __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__len__", 0); /* "aiohttp/_multidict.pyx":143 * * def __len__(self): * return len(self._items) # <<<<<<<<<<<<<< * * cpdef keys(self): */ __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); if (unlikely(__pyx_t_1 == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = PyList_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; goto __pyx_L0; /* "aiohttp/_multidict.pyx":142 * return iter(self.keys()) * * def __len__(self): # <<<<<<<<<<<<<< * return len(self._items) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("aiohttp._multidict._Base.__len__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":145 * return len(self._items) * * cpdef keys(self): # <<<<<<<<<<<<<< * """Return a new view of the dictionary's keys.""" * return _KeysView.__new__(_KeysView, self._items) */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_17keys(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base_keys(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, int __pyx_skip_dispatch) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("keys", 0); /* Check if called by wrapper */ if (unlikely(__pyx_skip_dispatch)) ; /* Check if overridden in Python */ else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) { __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_keys); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_7aiohttp_10_multidict_5_Base_17keys)) { __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) { __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_4); __Pyx_INCREF(function); __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_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_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_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } /* "aiohttp/_multidict.pyx":147 * cpdef keys(self): * """Return a new view of the dictionary's keys.""" * return _KeysView.__new__(_KeysView, self._items) # <<<<<<<<<<<<<< * * def items(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_self->_items); __Pyx_GIVEREF(__pyx_v_self->_items); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->_items); __pyx_t_2 = __pyx_tp_new_7aiohttp_10_multidict__KeysView(((PyTypeObject *)__pyx_ptype_7aiohttp_10_multidict__KeysView), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":145 * return len(self._items) * * cpdef keys(self): # <<<<<<<<<<<<<< * """Return a new view of the dictionary's keys.""" * return _KeysView.__new__(_KeysView, self._items) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._multidict._Base.keys", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_17keys(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_5_Base_16keys[] = "Return a new view of the dictionary's keys."; static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_17keys(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("keys (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_16keys(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_16keys(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("keys", 0); __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __pyx_f_7aiohttp_10_multidict_5_Base_keys(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("aiohttp._multidict._Base.keys", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":149 * return _KeysView.__new__(_KeysView, self._items) * * def items(self): # <<<<<<<<<<<<<< * """Return a new view of the dictionary's items *(key, value) pairs).""" * return _ItemsView.__new__(_ItemsView, self._items) */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_19items(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_5_Base_18items[] = "Return a new view of the dictionary's items *(key, value) pairs)."; static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_19items(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("items (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_18items(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_18items(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("items", 0); /* "aiohttp/_multidict.pyx":151 * def items(self): * """Return a new view of the dictionary's items *(key, value) pairs).""" * return _ItemsView.__new__(_ItemsView, self._items) # <<<<<<<<<<<<<< * * def values(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_self->_items); __Pyx_GIVEREF(__pyx_v_self->_items); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->_items); __pyx_t_2 = __pyx_tp_new_7aiohttp_10_multidict__ItemsView(((PyTypeObject *)__pyx_ptype_7aiohttp_10_multidict__ItemsView), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":149 * return _KeysView.__new__(_KeysView, self._items) * * def items(self): # <<<<<<<<<<<<<< * """Return a new view of the dictionary's items *(key, value) pairs).""" * return _ItemsView.__new__(_ItemsView, self._items) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict._Base.items", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":153 * return _ItemsView.__new__(_ItemsView, self._items) * * def values(self): # <<<<<<<<<<<<<< * """Return a new view of the dictionary's values.""" * return _ValuesView.__new__(_ValuesView, self._items) */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_21values(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_5_Base_20values[] = "Return a new view of the dictionary's values."; static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_21values(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("values (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_20values(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_20values(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("values", 0); /* "aiohttp/_multidict.pyx":155 * def values(self): * """Return a new view of the dictionary's values.""" * return _ValuesView.__new__(_ValuesView, self._items) # <<<<<<<<<<<<<< * * def __repr__(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_self->_items); __Pyx_GIVEREF(__pyx_v_self->_items); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->_items); __pyx_t_2 = __pyx_tp_new_7aiohttp_10_multidict__ValuesView(((PyTypeObject *)__pyx_ptype_7aiohttp_10_multidict__ValuesView), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":153 * return _ItemsView.__new__(_ItemsView, self._items) * * def values(self): # <<<<<<<<<<<<<< * """Return a new view of the dictionary's values.""" * return _ValuesView.__new__(_ValuesView, self._items) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict._Base.values", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":157 * return _ValuesView.__new__(_ValuesView, self._items) * * def __repr__(self): # <<<<<<<<<<<<<< * cdef _Pair item * lst = [] */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_23__repr__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_23__repr__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_22__repr__(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_22__repr__(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_lst = NULL; PyObject *__pyx_v_i = NULL; PyObject *__pyx_v_body = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; Py_ssize_t __pyx_t_6; PyObject *__pyx_t_7 = NULL; int __pyx_t_8; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__repr__", 0); /* "aiohttp/_multidict.pyx":159 * def __repr__(self): * cdef _Pair item * lst = [] # <<<<<<<<<<<<<< * for i in self._items: * item = <_Pair>i */ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_lst = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":160 * cdef _Pair item * lst = [] * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * lst.append("'{}': {!r}".format(item._key, item._value)) */ if (unlikely(__pyx_v_self->_items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":161 * lst = [] * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * lst.append("'{}': {!r}".format(item._key, item._value)) * body = ', '.join(lst) */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":162 * for i in self._items: * item = <_Pair>i * lst.append("'{}': {!r}".format(item._key, item._value)) # <<<<<<<<<<<<<< * body = ', '.join(lst) * return '<{}({})>'.format(self.__class__.__name__, body) */ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; __pyx_t_6 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(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_6 = 1; } } __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); if (__pyx_t_5) { __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL; } __Pyx_INCREF(__pyx_v_item->_key); __Pyx_GIVEREF(__pyx_v_item->_key); PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_v_item->_key); __Pyx_INCREF(__pyx_v_item->_value); __Pyx_GIVEREF(__pyx_v_item->_value); PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_v_item->_value); __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_8 = __Pyx_PyList_Append(__pyx_v_lst, __pyx_t_3); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":160 * cdef _Pair item * lst = [] * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * lst.append("'{}': {!r}".format(item._key, item._value)) */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":163 * item = <_Pair>i * lst.append("'{}': {!r}".format(item._key, item._value)) * body = ', '.join(lst) # <<<<<<<<<<<<<< * return '<{}({})>'.format(self.__class__.__name__, body) * */ __pyx_t_1 = __Pyx_PyString_Join(__pyx_kp_s__4, __pyx_v_lst); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_body = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":164 * lst.append("'{}': {!r}".format(item._key, item._value)) * body = ', '.join(lst) * return '<{}({})>'.format(self.__class__.__name__, body) # <<<<<<<<<<<<<< * * cdef _eq_to_mapping(self, other): */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s__5, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = NULL; __pyx_t_2 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) { __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_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); __pyx_t_2 = 1; } } __pyx_t_5 = PyTuple_New(2+__pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); if (__pyx_t_4) { __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL; } __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_v_body); __Pyx_GIVEREF(__pyx_v_body); PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_2, __pyx_v_body); __pyx_t_7 = 0; __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":157 * return _ValuesView.__new__(_ValuesView, self._items) * * def __repr__(self): # <<<<<<<<<<<<<< * cdef _Pair item * lst = [] */ /* function exit code */ __pyx_L1_error:; __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._multidict._Base.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_lst); __Pyx_XDECREF(__pyx_v_i); __Pyx_XDECREF(__pyx_v_body); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":166 * return '<{}({})>'.format(self.__class__.__name__, body) * * cdef _eq_to_mapping(self, other): # <<<<<<<<<<<<<< * cdef _Pair item * left_keys = set(self.keys()) */ static PyObject *__pyx_f_7aiohttp_10_multidict_5_Base__eq_to_mapping(struct __pyx_obj_7aiohttp_10_multidict__Base *__pyx_v_self, PyObject *__pyx_v_other) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_left_keys = NULL; PyObject *__pyx_v_right_keys = NULL; PyObject *__pyx_v_i = NULL; PyObject *__pyx_v_nv = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; Py_ssize_t __pyx_t_5; Py_ssize_t __pyx_t_6; PyObject *__pyx_t_7 = NULL; PyObject *__pyx_t_8 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_eq_to_mapping", 0); /* "aiohttp/_multidict.pyx":168 * cdef _eq_to_mapping(self, other): * cdef _Pair item * left_keys = set(self.keys()) # <<<<<<<<<<<<<< * right_keys = set(other.keys()) * if left_keys != right_keys: */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict__Base *)__pyx_v_self->__pyx_vtab)->keys(__pyx_v_self, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PySet_New(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_left_keys = ((PyObject*)__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":169 * cdef _Pair item * left_keys = set(self.keys()) * right_keys = set(other.keys()) # <<<<<<<<<<<<<< * if left_keys != right_keys: * return False */ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_other, __pyx_n_s_keys); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) { __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); if (likely(__pyx_t_3)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_1, function); } } if (__pyx_t_3) { __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } else { __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = PySet_New(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_right_keys = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":170 * left_keys = set(self.keys()) * right_keys = set(other.keys()) * if left_keys != right_keys: # <<<<<<<<<<<<<< * return False * if len(self._items) != len(right_keys): */ __pyx_t_1 = PyObject_RichCompare(__pyx_v_left_keys, __pyx_v_right_keys, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":171 * right_keys = set(other.keys()) * if left_keys != right_keys: * return False # <<<<<<<<<<<<<< * if len(self._items) != len(right_keys): * return False */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; goto __pyx_L0; /* "aiohttp/_multidict.pyx":170 * left_keys = set(self.keys()) * right_keys = set(other.keys()) * if left_keys != right_keys: # <<<<<<<<<<<<<< * return False * if len(self._items) != len(right_keys): */ } /* "aiohttp/_multidict.pyx":172 * if left_keys != right_keys: * return False * if len(self._items) != len(right_keys): # <<<<<<<<<<<<<< * return False * for i in self._items: */ __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); if (unlikely(__pyx_t_1 == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_5 = PyList_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_6 = PySet_GET_SIZE(__pyx_v_right_keys); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_4 = ((__pyx_t_5 != __pyx_t_6) != 0); if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":173 * return False * if len(self._items) != len(right_keys): * return False # <<<<<<<<<<<<<< * for i in self._items: * item = <_Pair>i */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; goto __pyx_L0; /* "aiohttp/_multidict.pyx":172 * if left_keys != right_keys: * return False * if len(self._items) != len(right_keys): # <<<<<<<<<<<<<< * return False * for i in self._items: */ } /* "aiohttp/_multidict.pyx":174 * if len(self._items) != len(right_keys): * return False * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * nv = other.get(item._key, self.marker) */ if (unlikely(__pyx_v_self->_items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); __pyx_t_6 = 0; for (;;) { if (__pyx_t_6 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":175 * return False * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * nv = other.get(item._key, self.marker) * if item._value != nv: */ __pyx_t_2 = __pyx_v_i; __Pyx_INCREF(__pyx_t_2); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_2)); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":176 * for i in self._items: * item = <_Pair>i * nv = other.get(item._key, self.marker) # <<<<<<<<<<<<<< * if item._value != nv: * return False */ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_other, __pyx_n_s_get); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_t_7 = NULL; __pyx_t_5 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) { __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_3); if (likely(__pyx_t_7)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); __Pyx_INCREF(__pyx_t_7); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); __pyx_t_5 = 1; } } __pyx_t_8 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_8); if (__pyx_t_7) { __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL; } __Pyx_INCREF(__pyx_v_item->_key); __Pyx_GIVEREF(__pyx_v_item->_key); PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_5, __pyx_v_item->_key); __Pyx_INCREF(__pyx_v_self->marker); __Pyx_GIVEREF(__pyx_v_self->marker); PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_5, __pyx_v_self->marker); __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_XDECREF_SET(__pyx_v_nv, __pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":177 * item = <_Pair>i * nv = other.get(item._key, self.marker) * if item._value != nv: # <<<<<<<<<<<<<< * return False * return True */ __pyx_t_2 = PyObject_RichCompare(__pyx_v_item->_value, __pyx_v_nv, Py_NE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":178 * nv = other.get(item._key, self.marker) * if item._value != nv: * return False # <<<<<<<<<<<<<< * return True * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":177 * item = <_Pair>i * nv = other.get(item._key, self.marker) * if item._value != nv: # <<<<<<<<<<<<<< * return False * return True */ } /* "aiohttp/_multidict.pyx":174 * if len(self._items) != len(right_keys): * return False * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * nv = other.get(item._key, self.marker) */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":179 * if item._value != nv: * return False * return True # <<<<<<<<<<<<<< * * def __richcmp__(self, other, op): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_True); __pyx_r = Py_True; goto __pyx_L0; /* "aiohttp/_multidict.pyx":166 * return '<{}({})>'.format(self.__class__.__name__, body) * * cdef _eq_to_mapping(self, other): # <<<<<<<<<<<<<< * cdef _Pair item * left_keys = set(self.keys()) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_8); __Pyx_AddTraceback("aiohttp._multidict._Base._eq_to_mapping", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_left_keys); __Pyx_XDECREF(__pyx_v_right_keys); __Pyx_XDECREF(__pyx_v_i); __Pyx_XDECREF(__pyx_v_nv); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":181 * return True * * def __richcmp__(self, other, op): # <<<<<<<<<<<<<< * if op == 2: # == * return _eq(self, other) */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_25__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_5_Base_25__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op) { PyObject *__pyx_v_op = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__richcmp__ (wrapper)", 0); __pyx_v_op = __Pyx_PyInt_From_int(__pyx_arg_op); if (unlikely(!__pyx_v_op)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __Pyx_GOTREF(__pyx_v_op); goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._Base.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_5_Base_24__richcmp__(((PyObject *)__pyx_v_self), ((PyObject *)__pyx_v_other), ((PyObject *)__pyx_v_op)); /* function exit code */ __Pyx_XDECREF(__pyx_v_op); __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_5_Base_24__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op) { PyObject *__pyx_v_ret = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_t_2; int __pyx_t_3; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__richcmp__", 0); /* "aiohttp/_multidict.pyx":182 * * def __richcmp__(self, other, op): * if op == 2: # == # <<<<<<<<<<<<<< * return _eq(self, other) * elif op == 3: # != */ __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_2, 2, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":183 * def __richcmp__(self, other, op): * if op == 2: # == * return _eq(self, other) # <<<<<<<<<<<<<< * elif op == 3: # != * ret = _eq(self, other) */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __pyx_f_7aiohttp_10_multidict__eq(__pyx_v_self, __pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":182 * * def __richcmp__(self, other, op): * if op == 2: # == # <<<<<<<<<<<<<< * return _eq(self, other) * elif op == 3: # != */ } /* "aiohttp/_multidict.pyx":184 * if op == 2: # == * return _eq(self, other) * elif op == 3: # != # <<<<<<<<<<<<<< * ret = _eq(self, other) * if ret is NotImplemented: */ __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_3, 3, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":185 * return _eq(self, other) * elif op == 3: # != * ret = _eq(self, other) # <<<<<<<<<<<<<< * if ret is NotImplemented: * return ret */ __pyx_t_1 = __pyx_f_7aiohttp_10_multidict__eq(__pyx_v_self, __pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_ret = __pyx_t_1; __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":186 * elif op == 3: # != * ret = _eq(self, other) * if ret is NotImplemented: # <<<<<<<<<<<<<< * return ret * else: */ __pyx_t_2 = (__pyx_v_ret == __pyx_builtin_NotImplemented); __pyx_t_3 = (__pyx_t_2 != 0); if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":187 * ret = _eq(self, other) * if ret is NotImplemented: * return ret # <<<<<<<<<<<<<< * else: * return not ret */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_ret); __pyx_r = __pyx_v_ret; goto __pyx_L0; /* "aiohttp/_multidict.pyx":186 * elif op == 3: # != * ret = _eq(self, other) * if ret is NotImplemented: # <<<<<<<<<<<<<< * return ret * else: */ } /* "aiohttp/_multidict.pyx":189 * return ret * else: * return not ret # <<<<<<<<<<<<<< * else: * return NotImplemented */ /*else*/ { __Pyx_XDECREF(__pyx_r); __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_ret); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; } /* "aiohttp/_multidict.pyx":184 * if op == 2: # == * return _eq(self, other) * elif op == 3: # != # <<<<<<<<<<<<<< * ret = _eq(self, other) * if ret is NotImplemented: */ } /* "aiohttp/_multidict.pyx":191 * return not ret * else: * return NotImplemented # <<<<<<<<<<<<<< * * */ /*else*/ { __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; } /* "aiohttp/_multidict.pyx":181 * return True * * def __richcmp__(self, other, op): # <<<<<<<<<<<<<< * if op == 2: # == * return _eq(self, other) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("aiohttp._multidict._Base.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_ret); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":196 * cdef class MultiDictProxy(_Base): * * def __init__(self, arg): # <<<<<<<<<<<<<< * cdef MultiDict mdict * if not isinstance(arg, MultiDict): */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_14MultiDictProxy_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_14MultiDictProxy_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_arg = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arg,0}; PyObject* values[1] = {0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_arg)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); } __pyx_v_arg = values[0]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict.MultiDictProxy.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_14MultiDictProxy___init__(((struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy *)__pyx_v_self), __pyx_v_arg); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_14MultiDictProxy___init__(struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy *__pyx_v_self, PyObject *__pyx_v_arg) { struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_mdict = 0; int __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__init__", 0); /* "aiohttp/_multidict.pyx":198 * def __init__(self, arg): * cdef MultiDict mdict * if not isinstance(arg, MultiDict): # <<<<<<<<<<<<<< * raise TypeError( * 'MultiDictProxy requires MultiDict instance, not {}'.format( */ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_arg, __pyx_ptype_7aiohttp_10_multidict_MultiDict); __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":200 * if not isinstance(arg, MultiDict): * raise TypeError( * 'MultiDictProxy requires MultiDict instance, not {}'.format( # <<<<<<<<<<<<<< * type(arg))) * */ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_MultiDictProxy_requires_MultiDic, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); /* "aiohttp/_multidict.pyx":201 * raise TypeError( * 'MultiDictProxy requires MultiDict instance, not {}'.format( * type(arg))) # <<<<<<<<<<<<<< * * mdict = arg */ __pyx_t_5 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(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); } } if (!__pyx_t_5) { __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, ((PyObject *)Py_TYPE(__pyx_v_arg))); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); } else { __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __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(((PyObject *)Py_TYPE(__pyx_v_arg))); __Pyx_GIVEREF(((PyObject *)Py_TYPE(__pyx_v_arg))); PyTuple_SET_ITEM(__pyx_t_6, 0+1, ((PyObject *)Py_TYPE(__pyx_v_arg))); __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":199 * cdef MultiDict mdict * if not isinstance(arg, MultiDict): * raise TypeError( # <<<<<<<<<<<<<< * 'MultiDictProxy requires MultiDict instance, not {}'.format( * type(arg))) */ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __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 = 0; __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":198 * def __init__(self, arg): * cdef MultiDict mdict * if not isinstance(arg, MultiDict): # <<<<<<<<<<<<<< * raise TypeError( * 'MultiDictProxy requires MultiDict instance, not {}'.format( */ } /* "aiohttp/_multidict.pyx":203 * type(arg))) * * mdict = arg # <<<<<<<<<<<<<< * self._items = mdict._items * */ if (!(likely(((__pyx_v_arg) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_arg, __pyx_ptype_7aiohttp_10_multidict_MultiDict))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_3 = __pyx_v_arg; __Pyx_INCREF(__pyx_t_3); __pyx_v_mdict = ((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":204 * * mdict = arg * self._items = mdict._items # <<<<<<<<<<<<<< * * def copy(self): */ __pyx_t_3 = __pyx_v_mdict->__pyx_base._items; __Pyx_INCREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __Pyx_GOTREF(__pyx_v_self->__pyx_base._items); __Pyx_DECREF(__pyx_v_self->__pyx_base._items); __pyx_v_self->__pyx_base._items = ((PyObject*)__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":196 * cdef class MultiDictProxy(_Base): * * def __init__(self, arg): # <<<<<<<<<<<<<< * cdef MultiDict mdict * if not isinstance(arg, MultiDict): */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._multidict.MultiDictProxy.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_mdict); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":206 * self._items = mdict._items * * def copy(self): # <<<<<<<<<<<<<< * """Return a copy of itself.""" * return MultiDict(self._items) */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_14MultiDictProxy_3copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_14MultiDictProxy_2copy[] = "Return a copy of itself."; static PyObject *__pyx_pw_7aiohttp_10_multidict_14MultiDictProxy_3copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("copy (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_14MultiDictProxy_2copy(((struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_14MultiDictProxy_2copy(struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("copy", 0); /* "aiohttp/_multidict.pyx":208 * def copy(self): * """Return a copy of itself.""" * return MultiDict(self._items) # <<<<<<<<<<<<<< * * abc.Mapping.register(MultiDictProxy) */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_self->__pyx_base._items); __Pyx_GIVEREF(__pyx_v_self->__pyx_base._items); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->__pyx_base._items); __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_7aiohttp_10_multidict_MultiDict), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":206 * self._items = mdict._items * * def copy(self): # <<<<<<<<<<<<<< * """Return a copy of itself.""" * return MultiDict(self._items) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict.MultiDictProxy.copy", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":215 * cdef class CIMultiDictProxy(MultiDictProxy): * * def __init__(self, arg): # <<<<<<<<<<<<<< * cdef CIMultiDict mdict * if not isinstance(arg, CIMultiDict): */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_16CIMultiDictProxy_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_16CIMultiDictProxy_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_arg = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arg,0}; PyObject* values[1] = {0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_arg)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); } __pyx_v_arg = values[0]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict.CIMultiDictProxy.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_16CIMultiDictProxy___init__(((struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy *)__pyx_v_self), __pyx_v_arg); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_16CIMultiDictProxy___init__(struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy *__pyx_v_self, PyObject *__pyx_v_arg) { struct __pyx_obj_7aiohttp_10_multidict_CIMultiDict *__pyx_v_mdict = 0; int __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__init__", 0); /* "aiohttp/_multidict.pyx":217 * def __init__(self, arg): * cdef CIMultiDict mdict * if not isinstance(arg, CIMultiDict): # <<<<<<<<<<<<<< * raise TypeError( * 'CIMultiDictProxy requires CIMultiDict instance, not {}'.format( */ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_arg, __pyx_ptype_7aiohttp_10_multidict_CIMultiDict); __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":219 * if not isinstance(arg, CIMultiDict): * raise TypeError( * 'CIMultiDictProxy requires CIMultiDict instance, not {}'.format( # <<<<<<<<<<<<<< * type(arg))) * */ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_CIMultiDictProxy_requires_CIMult, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); /* "aiohttp/_multidict.pyx":220 * raise TypeError( * 'CIMultiDictProxy requires CIMultiDict instance, not {}'.format( * type(arg))) # <<<<<<<<<<<<<< * * mdict = arg */ __pyx_t_5 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(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); } } if (!__pyx_t_5) { __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, ((PyObject *)Py_TYPE(__pyx_v_arg))); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); } else { __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __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(((PyObject *)Py_TYPE(__pyx_v_arg))); __Pyx_GIVEREF(((PyObject *)Py_TYPE(__pyx_v_arg))); PyTuple_SET_ITEM(__pyx_t_6, 0+1, ((PyObject *)Py_TYPE(__pyx_v_arg))); __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":218 * cdef CIMultiDict mdict * if not isinstance(arg, CIMultiDict): * raise TypeError( # <<<<<<<<<<<<<< * 'CIMultiDictProxy requires CIMultiDict instance, not {}'.format( * type(arg))) */ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __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 = 0; __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":217 * def __init__(self, arg): * cdef CIMultiDict mdict * if not isinstance(arg, CIMultiDict): # <<<<<<<<<<<<<< * raise TypeError( * 'CIMultiDictProxy requires CIMultiDict instance, not {}'.format( */ } /* "aiohttp/_multidict.pyx":222 * type(arg))) * * mdict = arg # <<<<<<<<<<<<<< * self._items = mdict._items * */ if (!(likely(((__pyx_v_arg) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_arg, __pyx_ptype_7aiohttp_10_multidict_CIMultiDict))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_3 = __pyx_v_arg; __Pyx_INCREF(__pyx_t_3); __pyx_v_mdict = ((struct __pyx_obj_7aiohttp_10_multidict_CIMultiDict *)__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":223 * * mdict = arg * self._items = mdict._items # <<<<<<<<<<<<<< * * cdef str _upper(self, s): */ __pyx_t_3 = __pyx_v_mdict->__pyx_base.__pyx_base._items; __Pyx_INCREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __Pyx_GOTREF(__pyx_v_self->__pyx_base.__pyx_base._items); __Pyx_DECREF(__pyx_v_self->__pyx_base.__pyx_base._items); __pyx_v_self->__pyx_base.__pyx_base._items = ((PyObject*)__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":215 * cdef class CIMultiDictProxy(MultiDictProxy): * * def __init__(self, arg): # <<<<<<<<<<<<<< * cdef CIMultiDict mdict * if not isinstance(arg, CIMultiDict): */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._multidict.CIMultiDictProxy.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_mdict); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":225 * self._items = mdict._items * * cdef str _upper(self, s): # <<<<<<<<<<<<<< * if type(s) is self._upstr: * return s */ static PyObject *__pyx_f_7aiohttp_10_multidict_16CIMultiDictProxy__upper(struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy *__pyx_v_self, PyObject *__pyx_v_s) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_upper", 0); /* "aiohttp/_multidict.pyx":226 * * cdef str _upper(self, s): * if type(s) is self._upstr: # <<<<<<<<<<<<<< * return s * return s.upper() */ __pyx_t_1 = (((PyObject *)Py_TYPE(__pyx_v_s)) == __pyx_v_self->__pyx_base.__pyx_base._upstr); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":227 * cdef str _upper(self, s): * if type(s) is self._upstr: * return s # <<<<<<<<<<<<<< * return s.upper() * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject*)__pyx_v_s)); __pyx_r = ((PyObject*)__pyx_v_s); goto __pyx_L0; /* "aiohttp/_multidict.pyx":226 * * cdef str _upper(self, s): * if type(s) is self._upstr: # <<<<<<<<<<<<<< * return s * return s.upper() */ } /* "aiohttp/_multidict.pyx":228 * if type(s) is self._upstr: * return s * return s.upper() # <<<<<<<<<<<<<< * * def copy(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_s, __pyx_n_s_upper); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(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); } } if (__pyx_t_5) { __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } else { __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (!(likely(PyString_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = ((PyObject*)__pyx_t_3); __pyx_t_3 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":225 * self._items = mdict._items * * cdef str _upper(self, s): # <<<<<<<<<<<<<< * if type(s) is self._upstr: * return s */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("aiohttp._multidict.CIMultiDictProxy._upper", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":230 * return s.upper() * * def copy(self): # <<<<<<<<<<<<<< * """Return a copy of itself.""" * return CIMultiDict(self._items) */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_16CIMultiDictProxy_3copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_16CIMultiDictProxy_2copy[] = "Return a copy of itself."; static PyObject *__pyx_pw_7aiohttp_10_multidict_16CIMultiDictProxy_3copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("copy (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_16CIMultiDictProxy_2copy(((struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_16CIMultiDictProxy_2copy(struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("copy", 0); /* "aiohttp/_multidict.pyx":232 * def copy(self): * """Return a copy of itself.""" * return CIMultiDict(self._items) # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_self->__pyx_base.__pyx_base._items); __Pyx_GIVEREF(__pyx_v_self->__pyx_base.__pyx_base._items); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->__pyx_base.__pyx_base._items); __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_7aiohttp_10_multidict_CIMultiDict), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":230 * return s.upper() * * def copy(self): # <<<<<<<<<<<<<< * """Return a copy of itself.""" * return CIMultiDict(self._items) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict.CIMultiDictProxy.copy", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":241 * """An ordered dictionary that can have multiple values for each key.""" * * def __init__(self, *args, **kwargs): # <<<<<<<<<<<<<< * self._items = [] * */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_9MultiDict_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_9MultiDict_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_args = 0; PyObject *__pyx_v_kwargs = 0; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); if (unlikely(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__init__", 1))) return -1; __pyx_v_kwargs = (__pyx_kwds) ? PyDict_Copy(__pyx_kwds) : PyDict_New(); if (unlikely(!__pyx_v_kwargs)) return -1; __Pyx_GOTREF(__pyx_v_kwargs); __Pyx_INCREF(__pyx_args); __pyx_v_args = __pyx_args; __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict___init__(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self), __pyx_v_args, __pyx_v_kwargs); /* function exit code */ __Pyx_XDECREF(__pyx_v_args); __Pyx_XDECREF(__pyx_v_kwargs); __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_9MultiDict___init__(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__init__", 0); /* "aiohttp/_multidict.pyx":242 * * def __init__(self, *args, **kwargs): * self._items = [] # <<<<<<<<<<<<<< * * self._extend(args, kwargs, self.__class__.__name__, 1) */ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v_self->__pyx_base._items); __Pyx_DECREF(__pyx_v_self->__pyx_base._items); __pyx_v_self->__pyx_base._items = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":244 * self._items = [] * * self._extend(args, kwargs, self.__class__.__name__, 1) # <<<<<<<<<<<<<< * * cdef _extend(self, tuple args, dict kwargs, name, int do_add): */ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_extend(__pyx_v_self, __pyx_v_args, __pyx_v_kwargs, __pyx_t_2, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __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; /* "aiohttp/_multidict.pyx":241 * """An ordered dictionary that can have multiple values for each key.""" * * def __init__(self, *args, **kwargs): # <<<<<<<<<<<<<< * self._items = [] * */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":246 * self._extend(args, kwargs, self.__class__.__name__, 1) * * cdef _extend(self, tuple args, dict kwargs, name, int do_add): # <<<<<<<<<<<<<< * cdef _Pair item * cdef str key */ static PyObject *__pyx_f_7aiohttp_10_multidict_9MultiDict__extend(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs, PyObject *__pyx_v_name, int __pyx_v_do_add) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_key = 0; PyObject *__pyx_v_arg = NULL; PyObject *__pyx_v_i = NULL; PyObject *__pyx_v_value = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations Py_ssize_t __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; int __pyx_t_8; PyObject *(*__pyx_t_9)(PyObject *); Py_ssize_t __pyx_t_10; PyObject *(*__pyx_t_11)(PyObject *); int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_extend", 0); /* "aiohttp/_multidict.pyx":250 * cdef str key * * if len(args) > 1: # <<<<<<<<<<<<<< * raise TypeError("{} takes at most 1 positional argument" * " ({} given)".format(name, len(args))) */ if (unlikely(__pyx_v_args == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_args); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_2 = ((__pyx_t_1 > 1) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":252 * if len(args) > 1: * raise TypeError("{} takes at most 1 positional argument" * " ({} given)".format(name, len(args))) # <<<<<<<<<<<<<< * * if args: */ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_takes_at_most_1_positional_argu, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); if (unlikely(__pyx_v_args == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_args); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); __pyx_t_6 = NULL; __pyx_t_1 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) { __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4); if (likely(__pyx_t_6)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); __Pyx_INCREF(__pyx_t_6); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_4, function); __pyx_t_1 = 1; } } __pyx_t_7 = PyTuple_New(2+__pyx_t_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); if (__pyx_t_6) { __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL; } __Pyx_INCREF(__pyx_v_name); __Pyx_GIVEREF(__pyx_v_name); PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_1, __pyx_v_name); __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_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_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":251 * * if len(args) > 1: * raise TypeError("{} takes at most 1 positional argument" # <<<<<<<<<<<<<< * " ({} given)".format(name, len(args))) * */ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __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 = 0; __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":250 * cdef str key * * if len(args) > 1: # <<<<<<<<<<<<<< * raise TypeError("{} takes at most 1 positional argument" * " ({} given)".format(name, len(args))) */ } /* "aiohttp/_multidict.pyx":254 * " ({} given)".format(name, len(args))) * * if args: # <<<<<<<<<<<<<< * arg = args[0] * if isinstance(arg, _Base): */ __pyx_t_2 = (__pyx_v_args != Py_None) && (PyTuple_GET_SIZE(__pyx_v_args) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":255 * * if args: * arg = args[0] # <<<<<<<<<<<<<< * if isinstance(arg, _Base): * for i in (<_Base>arg)._items: */ if (unlikely(__pyx_v_args == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_3 = __Pyx_GetItemInt_Tuple(__pyx_v_args, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_3); __pyx_v_arg = __pyx_t_3; __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":256 * if args: * arg = args[0] * if isinstance(arg, _Base): # <<<<<<<<<<<<<< * for i in (<_Base>arg)._items: * item = <_Pair>i */ __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_arg, __pyx_ptype_7aiohttp_10_multidict__Base); __pyx_t_8 = (__pyx_t_2 != 0); if (__pyx_t_8) { /* "aiohttp/_multidict.pyx":257 * arg = args[0] * if isinstance(arg, _Base): * for i in (<_Base>arg)._items: # <<<<<<<<<<<<<< * item = <_Pair>i * key = self._upper(item._key) */ if (unlikely(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_arg)->_items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_3 = ((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_arg)->_items; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0; for (;;) { if (__pyx_t_1 >= PyList_GET_SIZE(__pyx_t_3)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_4); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":258 * if isinstance(arg, _Base): * for i in (<_Base>arg)._items: * item = <_Pair>i # <<<<<<<<<<<<<< * key = self._upper(item._key) * value = item._value */ __pyx_t_4 = __pyx_v_i; __Pyx_INCREF(__pyx_t_4); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_4)); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":259 * for i in (<_Base>arg)._items: * item = <_Pair>i * key = self._upper(item._key) # <<<<<<<<<<<<<< * value = item._value * if do_add: */ __pyx_t_4 = __pyx_v_item->_key; __Pyx_INCREF(__pyx_t_4); __pyx_t_7 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._upper(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF_SET(__pyx_v_key, ((PyObject*)__pyx_t_7)); __pyx_t_7 = 0; /* "aiohttp/_multidict.pyx":260 * item = <_Pair>i * key = self._upper(item._key) * value = item._value # <<<<<<<<<<<<<< * if do_add: * self._add(key, value) */ __pyx_t_7 = __pyx_v_item->_value; __Pyx_INCREF(__pyx_t_7); __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_7); __pyx_t_7 = 0; /* "aiohttp/_multidict.pyx":261 * key = self._upper(item._key) * value = item._value * if do_add: # <<<<<<<<<<<<<< * self._add(key, value) * else: */ __pyx_t_8 = (__pyx_v_do_add != 0); if (__pyx_t_8) { /* "aiohttp/_multidict.pyx":262 * value = item._value * if do_add: * self._add(key, value) # <<<<<<<<<<<<<< * else: * self._replace(key, value) */ __pyx_t_7 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add(__pyx_v_self, __pyx_v_key, __pyx_v_value); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; /* "aiohttp/_multidict.pyx":261 * key = self._upper(item._key) * value = item._value * if do_add: # <<<<<<<<<<<<<< * self._add(key, value) * else: */ goto __pyx_L8; } /* "aiohttp/_multidict.pyx":264 * self._add(key, value) * else: * self._replace(key, value) # <<<<<<<<<<<<<< * elif hasattr(arg, 'items'): * for i in arg.items(): */ /*else*/ { __pyx_t_7 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_replace(__pyx_v_self, __pyx_v_key, __pyx_v_value); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; } __pyx_L8:; /* "aiohttp/_multidict.pyx":257 * arg = args[0] * if isinstance(arg, _Base): * for i in (<_Base>arg)._items: # <<<<<<<<<<<<<< * item = <_Pair>i * key = self._upper(item._key) */ } __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":256 * if args: * arg = args[0] * if isinstance(arg, _Base): # <<<<<<<<<<<<<< * for i in (<_Base>arg)._items: * item = <_Pair>i */ goto __pyx_L5; } /* "aiohttp/_multidict.pyx":265 * else: * self._replace(key, value) * elif hasattr(arg, 'items'): # <<<<<<<<<<<<<< * for i in arg.items(): * if isinstance(i, _Pair): */ __pyx_t_8 = PyObject_HasAttr(__pyx_v_arg, __pyx_n_s_items); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_2 = (__pyx_t_8 != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":266 * self._replace(key, value) * elif hasattr(arg, 'items'): * for i in arg.items(): # <<<<<<<<<<<<<< * if isinstance(i, _Pair): * item = <_Pair>i */ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_items); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __pyx_t_4 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) { __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_7); if (likely(__pyx_t_4)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_7, function); } } if (__pyx_t_4) { __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; } else { __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_7); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) { __pyx_t_7 = __pyx_t_3; __Pyx_INCREF(__pyx_t_7); __pyx_t_1 = 0; __pyx_t_9 = NULL; } else { __pyx_t_1 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __pyx_t_9 = Py_TYPE(__pyx_t_7)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; for (;;) { if (likely(!__pyx_t_9)) { if (likely(PyList_CheckExact(__pyx_t_7))) { if (__pyx_t_1 >= PyList_GET_SIZE(__pyx_t_7)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_1); __Pyx_INCREF(__pyx_t_3); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_7, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif } else { if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_7)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_1); __Pyx_INCREF(__pyx_t_3); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_7, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif } } else { __pyx_t_3 = __pyx_t_9(__pyx_t_7); if (unlikely(!__pyx_t_3)) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } break; } __Pyx_GOTREF(__pyx_t_3); } __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":267 * elif hasattr(arg, 'items'): * for i in arg.items(): * if isinstance(i, _Pair): # <<<<<<<<<<<<<< * item = <_Pair>i * key = item._key */ __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_i, __pyx_ptype_7aiohttp_10_multidict__Pair); __pyx_t_8 = (__pyx_t_2 != 0); if (__pyx_t_8) { /* "aiohttp/_multidict.pyx":268 * for i in arg.items(): * if isinstance(i, _Pair): * item = <_Pair>i # <<<<<<<<<<<<<< * key = item._key * value = item._value */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":269 * if isinstance(i, _Pair): * item = <_Pair>i * key = item._key # <<<<<<<<<<<<<< * value = item._value * else: */ if (!(likely(PyString_CheckExact(__pyx_v_item->_key))||((__pyx_v_item->_key) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_v_item->_key)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_3 = __pyx_v_item->_key; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_key, ((PyObject*)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":270 * item = <_Pair>i * key = item._key * value = item._value # <<<<<<<<<<<<<< * else: * key = self._upper(i[0]) */ __pyx_t_3 = __pyx_v_item->_value; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":267 * elif hasattr(arg, 'items'): * for i in arg.items(): * if isinstance(i, _Pair): # <<<<<<<<<<<<<< * item = <_Pair>i * key = item._key */ goto __pyx_L11; } /* "aiohttp/_multidict.pyx":272 * value = item._value * else: * key = self._upper(i[0]) # <<<<<<<<<<<<<< * value = i[1] * if do_add: */ /*else*/ { __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_i, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._upper(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_XDECREF_SET(__pyx_v_key, ((PyObject*)__pyx_t_4)); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":273 * else: * key = self._upper(i[0]) * value = i[1] # <<<<<<<<<<<<<< * if do_add: * self._add(key, value) */ __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_i, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_4); __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_4); __pyx_t_4 = 0; } __pyx_L11:; /* "aiohttp/_multidict.pyx":274 * key = self._upper(i[0]) * value = i[1] * if do_add: # <<<<<<<<<<<<<< * self._add(key, value) * else: */ __pyx_t_8 = (__pyx_v_do_add != 0); if (__pyx_t_8) { /* "aiohttp/_multidict.pyx":275 * value = i[1] * if do_add: * self._add(key, value) # <<<<<<<<<<<<<< * else: * self._replace(key, value) */ __pyx_t_4 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add(__pyx_v_self, __pyx_v_key, __pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":274 * key = self._upper(i[0]) * value = i[1] * if do_add: # <<<<<<<<<<<<<< * self._add(key, value) * else: */ goto __pyx_L12; } /* "aiohttp/_multidict.pyx":277 * self._add(key, value) * else: * self._replace(key, value) # <<<<<<<<<<<<<< * else: * for i in arg: */ /*else*/ { __pyx_t_4 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_replace(__pyx_v_self, __pyx_v_key, __pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; } __pyx_L12:; /* "aiohttp/_multidict.pyx":266 * self._replace(key, value) * elif hasattr(arg, 'items'): * for i in arg.items(): # <<<<<<<<<<<<<< * if isinstance(i, _Pair): * item = <_Pair>i */ } __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; /* "aiohttp/_multidict.pyx":265 * else: * self._replace(key, value) * elif hasattr(arg, 'items'): # <<<<<<<<<<<<<< * for i in arg.items(): * if isinstance(i, _Pair): */ goto __pyx_L5; } /* "aiohttp/_multidict.pyx":279 * self._replace(key, value) * else: * for i in arg: # <<<<<<<<<<<<<< * if isinstance(i, _Pair): * item = <_Pair>i */ /*else*/ { if (likely(PyList_CheckExact(__pyx_v_arg)) || PyTuple_CheckExact(__pyx_v_arg)) { __pyx_t_7 = __pyx_v_arg; __Pyx_INCREF(__pyx_t_7); __pyx_t_1 = 0; __pyx_t_9 = NULL; } else { __pyx_t_1 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_v_arg); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __pyx_t_9 = Py_TYPE(__pyx_t_7)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } for (;;) { if (likely(!__pyx_t_9)) { if (likely(PyList_CheckExact(__pyx_t_7))) { if (__pyx_t_1 >= PyList_GET_SIZE(__pyx_t_7)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_4 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_1); __Pyx_INCREF(__pyx_t_4); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_4 = PySequence_ITEM(__pyx_t_7, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); #endif } else { if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_7)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_1); __Pyx_INCREF(__pyx_t_4); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_4 = PySequence_ITEM(__pyx_t_7, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); #endif } } else { __pyx_t_4 = __pyx_t_9(__pyx_t_7); if (unlikely(!__pyx_t_4)) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } break; } __Pyx_GOTREF(__pyx_t_4); } __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":280 * else: * for i in arg: * if isinstance(i, _Pair): # <<<<<<<<<<<<<< * item = <_Pair>i * key = item._key */ __pyx_t_8 = __Pyx_TypeCheck(__pyx_v_i, __pyx_ptype_7aiohttp_10_multidict__Pair); __pyx_t_2 = (__pyx_t_8 != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":281 * for i in arg: * if isinstance(i, _Pair): * item = <_Pair>i # <<<<<<<<<<<<<< * key = item._key * value = item._value */ __pyx_t_4 = __pyx_v_i; __Pyx_INCREF(__pyx_t_4); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_4)); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":282 * if isinstance(i, _Pair): * item = <_Pair>i * key = item._key # <<<<<<<<<<<<<< * value = item._value * else: */ if (!(likely(PyString_CheckExact(__pyx_v_item->_key))||((__pyx_v_item->_key) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_v_item->_key)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_4 = __pyx_v_item->_key; __Pyx_INCREF(__pyx_t_4); __Pyx_XDECREF_SET(__pyx_v_key, ((PyObject*)__pyx_t_4)); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":283 * item = <_Pair>i * key = item._key * value = item._value # <<<<<<<<<<<<<< * else: * if not len(i) == 2: */ __pyx_t_4 = __pyx_v_item->_value; __Pyx_INCREF(__pyx_t_4); __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":280 * else: * for i in arg: * if isinstance(i, _Pair): # <<<<<<<<<<<<<< * item = <_Pair>i * key = item._key */ goto __pyx_L15; } /* "aiohttp/_multidict.pyx":285 * value = item._value * else: * if not len(i) == 2: # <<<<<<<<<<<<<< * raise TypeError( * "{} takes either dict or list of (key, value) " */ /*else*/ { __pyx_t_10 = PyObject_Length(__pyx_v_i); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_2 = ((!((__pyx_t_10 == 2) != 0)) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":288 * raise TypeError( * "{} takes either dict or list of (key, value) " * "tuples".format(name)) # <<<<<<<<<<<<<< * key = self._upper(i[0]) * value = i[1] */ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_takes_either_dict_or_list_of_ke, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_t_5 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) { __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); if (likely(__pyx_t_5)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); __Pyx_INCREF(__pyx_t_5); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); } } if (!__pyx_t_5) { __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_name); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); } else { __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __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_name); __Pyx_GIVEREF(__pyx_v_name); PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_name); __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":286 * else: * if not len(i) == 2: * raise TypeError( # <<<<<<<<<<<<<< * "{} takes either dict or list of (key, value) " * "tuples".format(name)) */ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __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_DECREF(__pyx_t_4); __pyx_t_4 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":285 * value = item._value * else: * if not len(i) == 2: # <<<<<<<<<<<<<< * raise TypeError( * "{} takes either dict or list of (key, value) " */ } /* "aiohttp/_multidict.pyx":289 * "{} takes either dict or list of (key, value) " * "tuples".format(name)) * key = self._upper(i[0]) # <<<<<<<<<<<<<< * value = i[1] * if do_add: */ __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_i, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._upper(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF_SET(__pyx_v_key, ((PyObject*)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":290 * "tuples".format(name)) * key = self._upper(i[0]) * value = i[1] # <<<<<<<<<<<<<< * if do_add: * self._add(key, value) */ __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_i, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_3); __pyx_t_3 = 0; } __pyx_L15:; /* "aiohttp/_multidict.pyx":291 * key = self._upper(i[0]) * value = i[1] * if do_add: # <<<<<<<<<<<<<< * self._add(key, value) * else: */ __pyx_t_2 = (__pyx_v_do_add != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":292 * value = i[1] * if do_add: * self._add(key, value) # <<<<<<<<<<<<<< * else: * self._replace(key, value) */ __pyx_t_3 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add(__pyx_v_self, __pyx_v_key, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":291 * key = self._upper(i[0]) * value = i[1] * if do_add: # <<<<<<<<<<<<<< * self._add(key, value) * else: */ goto __pyx_L17; } /* "aiohttp/_multidict.pyx":294 * self._add(key, value) * else: * self._replace(key, value) # <<<<<<<<<<<<<< * * */ /*else*/ { __pyx_t_3 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_replace(__pyx_v_self, __pyx_v_key, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } __pyx_L17:; /* "aiohttp/_multidict.pyx":279 * self._replace(key, value) * else: * for i in arg: # <<<<<<<<<<<<<< * if isinstance(i, _Pair): * item = <_Pair>i */ } __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; } __pyx_L5:; /* "aiohttp/_multidict.pyx":254 * " ({} given)".format(name, len(args))) * * if args: # <<<<<<<<<<<<<< * arg = args[0] * if isinstance(arg, _Base): */ } /* "aiohttp/_multidict.pyx":297 * * * for key, value in kwargs.items(): # <<<<<<<<<<<<<< * key = self._upper(key) * if do_add: */ if (unlikely(__pyx_v_kwargs == Py_None)) { PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "items"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_7 = __Pyx_PyDict_Items(__pyx_v_kwargs); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); if (likely(PyList_CheckExact(__pyx_t_7)) || PyTuple_CheckExact(__pyx_t_7)) { __pyx_t_3 = __pyx_t_7; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0; __pyx_t_9 = NULL; } else { __pyx_t_1 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_t_9 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; for (;;) { if (likely(!__pyx_t_9)) { if (likely(PyList_CheckExact(__pyx_t_3))) { if (__pyx_t_1 >= PyList_GET_SIZE(__pyx_t_3)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_7 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); #endif } else { if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); #endif } } else { __pyx_t_7 = __pyx_t_9(__pyx_t_3); if (unlikely(!__pyx_t_7)) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } break; } __Pyx_GOTREF(__pyx_t_7); } if ((likely(PyTuple_CheckExact(__pyx_t_7))) || (PyList_CheckExact(__pyx_t_7))) { PyObject* sequence = __pyx_t_7; #if CYTHON_COMPILING_IN_CPYTHON Py_ssize_t size = Py_SIZE(sequence); #else Py_ssize_t size = PySequence_Size(sequence); #endif if (unlikely(size != 2)) { if (size > 2) __Pyx_RaiseTooManyValuesError(2); else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } #if CYTHON_COMPILING_IN_CPYTHON if (likely(PyTuple_CheckExact(sequence))) { __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); } else { __pyx_t_4 = PyList_GET_ITEM(sequence, 0); __pyx_t_6 = PyList_GET_ITEM(sequence, 1); } __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(__pyx_t_6); #else __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); #endif __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; } else { Py_ssize_t index = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __pyx_t_11 = Py_TYPE(__pyx_t_5)->tp_iternext; index = 0; __pyx_t_4 = __pyx_t_11(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L20_unpacking_failed; __Pyx_GOTREF(__pyx_t_4); index = 1; __pyx_t_6 = __pyx_t_11(__pyx_t_5); if (unlikely(!__pyx_t_6)) goto __pyx_L20_unpacking_failed; __Pyx_GOTREF(__pyx_t_6); if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_5), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_11 = NULL; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; goto __pyx_L21_unpacking_done; __pyx_L20_unpacking_failed:; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_t_11 = NULL; if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_L21_unpacking_done:; } if (!(likely(PyString_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_XDECREF_SET(__pyx_v_key, ((PyObject*)__pyx_t_4)); __pyx_t_4 = 0; __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_6); __pyx_t_6 = 0; /* "aiohttp/_multidict.pyx":298 * * for key, value in kwargs.items(): * key = self._upper(key) # <<<<<<<<<<<<<< * if do_add: * self._add(key, value) */ __pyx_t_7 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._upper(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_v_key); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF_SET(__pyx_v_key, ((PyObject*)__pyx_t_7)); __pyx_t_7 = 0; /* "aiohttp/_multidict.pyx":299 * for key, value in kwargs.items(): * key = self._upper(key) * if do_add: # <<<<<<<<<<<<<< * self._add(key, value) * else: */ __pyx_t_2 = (__pyx_v_do_add != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":300 * key = self._upper(key) * if do_add: * self._add(key, value) # <<<<<<<<<<<<<< * else: * self._replace(key, value) */ __pyx_t_7 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add(__pyx_v_self, __pyx_v_key, __pyx_v_value); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 300; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; /* "aiohttp/_multidict.pyx":299 * for key, value in kwargs.items(): * key = self._upper(key) * if do_add: # <<<<<<<<<<<<<< * self._add(key, value) * else: */ goto __pyx_L22; } /* "aiohttp/_multidict.pyx":302 * self._add(key, value) * else: * self._replace(key, value) # <<<<<<<<<<<<<< * * cdef _add(self, str key, value): */ /*else*/ { __pyx_t_7 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_replace(__pyx_v_self, __pyx_v_key, __pyx_v_value); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; } __pyx_L22:; /* "aiohttp/_multidict.pyx":297 * * * for key, value in kwargs.items(): # <<<<<<<<<<<<<< * key = self._upper(key) * if do_add: */ } __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":246 * self._extend(args, kwargs, self.__class__.__name__, 1) * * cdef _extend(self, tuple args, dict kwargs, name, int do_add): # <<<<<<<<<<<<<< * cdef _Pair item * cdef str key */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); __Pyx_AddTraceback("aiohttp._multidict.MultiDict._extend", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_key); __Pyx_XDECREF(__pyx_v_arg); __Pyx_XDECREF(__pyx_v_i); __Pyx_XDECREF(__pyx_v_value); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":304 * self._replace(key, value) * * cdef _add(self, str key, value): # <<<<<<<<<<<<<< * self._items.append(_Pair.__new__(_Pair, key, value)) * */ static PyObject *__pyx_f_7aiohttp_10_multidict_9MultiDict__add(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_t_3; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_add", 0); /* "aiohttp/_multidict.pyx":305 * * cdef _add(self, str key, value): * self._items.append(_Pair.__new__(_Pair, key, value)) # <<<<<<<<<<<<<< * * cdef _replace(self, str key, value): */ if (unlikely(__pyx_v_self->__pyx_base._items == Py_None)) { PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_key); __Pyx_GIVEREF(__pyx_v_key); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_key); __Pyx_INCREF(__pyx_v_value); __Pyx_GIVEREF(__pyx_v_value); PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_value); __pyx_t_2 = __pyx_tp_new_7aiohttp_10_multidict__Pair(((PyTypeObject *)__pyx_ptype_7aiohttp_10_multidict__Pair), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = __Pyx_PyList_Append(__pyx_v_self->__pyx_base._items, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":304 * self._replace(key, value) * * cdef _add(self, str key, value): # <<<<<<<<<<<<<< * self._items.append(_Pair.__new__(_Pair, key, value)) * */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict.MultiDict._add", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":307 * self._items.append(_Pair.__new__(_Pair, key, value)) * * cdef _replace(self, str key, value): # <<<<<<<<<<<<<< * self._remove(key, 0) * self._items.append(_Pair.__new__(_Pair, key, value)) */ static PyObject *__pyx_f_7aiohttp_10_multidict_9MultiDict__replace(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_t_3; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_replace", 0); /* "aiohttp/_multidict.pyx":308 * * cdef _replace(self, str key, value): * self._remove(key, 0) # <<<<<<<<<<<<<< * self._items.append(_Pair.__new__(_Pair, key, value)) * */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_remove(__pyx_v_self, __pyx_v_key, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":309 * cdef _replace(self, str key, value): * self._remove(key, 0) * self._items.append(_Pair.__new__(_Pair, key, value)) # <<<<<<<<<<<<<< * * def add(self, key, value): */ if (unlikely(__pyx_v_self->__pyx_base._items == Py_None)) { PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_key); __Pyx_GIVEREF(__pyx_v_key); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_key); __Pyx_INCREF(__pyx_v_value); __Pyx_GIVEREF(__pyx_v_value); PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_value); __pyx_t_2 = __pyx_tp_new_7aiohttp_10_multidict__Pair(((PyTypeObject *)__pyx_ptype_7aiohttp_10_multidict__Pair), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = __Pyx_PyList_Append(__pyx_v_self->__pyx_base._items, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":307 * self._items.append(_Pair.__new__(_Pair, key, value)) * * cdef _replace(self, str key, value): # <<<<<<<<<<<<<< * self._remove(key, 0) * self._items.append(_Pair.__new__(_Pair, key, value)) */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict.MultiDict._replace", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":311 * self._items.append(_Pair.__new__(_Pair, key, value)) * * def add(self, key, value): # <<<<<<<<<<<<<< * """Add the key and value, not overwriting any previous value.""" * self._add(self._upper(key), value) */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_3add(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_9MultiDict_2add[] = "Add the key and value, not overwriting any previous value."; static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_3add(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_key = 0; PyObject *__pyx_v_value = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("add (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_key,&__pyx_n_s_value,0}; PyObject* values[2] = {0,0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_value)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); values[1] = PyTuple_GET_ITEM(__pyx_args, 1); } __pyx_v_key = values[0]; __pyx_v_value = values[1]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict.MultiDict.add", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict_2add(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self), __pyx_v_key, __pyx_v_value); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_2add(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("add", 0); /* "aiohttp/_multidict.pyx":313 * def add(self, key, value): * """Add the key and value, not overwriting any previous value.""" * self._add(self._upper(key), value) # <<<<<<<<<<<<<< * * def copy(self): */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._upper(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add(__pyx_v_self, ((PyObject*)__pyx_t_1), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":311 * self._items.append(_Pair.__new__(_Pair, key, value)) * * def add(self, key, value): # <<<<<<<<<<<<<< * """Add the key and value, not overwriting any previous value.""" * self._add(self._upper(key), value) */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.add", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":315 * self._add(self._upper(key), value) * * def copy(self): # <<<<<<<<<<<<<< * """Return a copy of itself.""" * cls = self.__class__ */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_5copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_9MultiDict_4copy[] = "Return a copy of itself."; static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_5copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("copy (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict_4copy(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_4copy(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self) { PyObject *__pyx_v_cls = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("copy", 0); /* "aiohttp/_multidict.pyx":317 * def copy(self): * """Return a copy of itself.""" * cls = self.__class__ # <<<<<<<<<<<<<< * return cls(self._items) * */ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_cls = __pyx_t_1; __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":318 * """Return a copy of itself.""" * cls = self.__class__ * return cls(self._items) # <<<<<<<<<<<<<< * * def extend(self, *args, **kwargs): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_cls); __pyx_t_2 = __pyx_v_cls; __pyx_t_3 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) { __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); if (likely(__pyx_t_3)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_2, function); } } if (!__pyx_t_3) { __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_self->__pyx_base._items); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); } else { __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __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_self->__pyx_base._items); __Pyx_GIVEREF(__pyx_v_self->__pyx_base._items); PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_self->__pyx_base._items); __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; } __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":315 * self._add(self._upper(key), value) * * def copy(self): # <<<<<<<<<<<<<< * """Return a copy of itself.""" * cls = self.__class__ */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.copy", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_cls); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":320 * return cls(self._items) * * def extend(self, *args, **kwargs): # <<<<<<<<<<<<<< * """Extend current MultiDict with more values. * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_7extend(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_9MultiDict_6extend[] = "Extend current MultiDict with more values.\n\n This method must be used instead of update.\n "; static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_7extend(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_args = 0; PyObject *__pyx_v_kwargs = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("extend (wrapper)", 0); if (unlikely(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "extend", 1))) return NULL; __pyx_v_kwargs = (__pyx_kwds) ? PyDict_Copy(__pyx_kwds) : PyDict_New(); if (unlikely(!__pyx_v_kwargs)) return NULL; __Pyx_GOTREF(__pyx_v_kwargs); __Pyx_INCREF(__pyx_args); __pyx_v_args = __pyx_args; __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict_6extend(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self), __pyx_v_args, __pyx_v_kwargs); /* function exit code */ __Pyx_XDECREF(__pyx_v_args); __Pyx_XDECREF(__pyx_v_kwargs); __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_6extend(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("extend", 0); /* "aiohttp/_multidict.pyx":325 * This method must be used instead of update. * """ * self._extend(args, kwargs, "extend", 1) # <<<<<<<<<<<<<< * * def clear(self): */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_extend(__pyx_v_self, __pyx_v_args, __pyx_v_kwargs, __pyx_n_s_extend, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":320 * return cls(self._items) * * def extend(self, *args, **kwargs): # <<<<<<<<<<<<<< * """Extend current MultiDict with more values. * */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.extend", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":327 * self._extend(args, kwargs, "extend", 1) * * def clear(self): # <<<<<<<<<<<<<< * """Remove all items from MultiDict""" * self._items.clear() */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_9clear(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_9MultiDict_8clear[] = "Remove all items from MultiDict"; static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_9clear(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("clear (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict_8clear(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_8clear(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("clear", 0); /* "aiohttp/_multidict.pyx":329 * def clear(self): * """Remove all items from MultiDict""" * self._items.clear() # <<<<<<<<<<<<<< * * # MutableMapping interface # */ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->__pyx_base._items, __pyx_n_s_clear); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) { __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); if (likely(__pyx_t_3)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(function); __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_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __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; /* "aiohttp/_multidict.pyx":327 * self._extend(args, kwargs, "extend", 1) * * def clear(self): # <<<<<<<<<<<<<< * """Remove all items from MultiDict""" * self._items.clear() */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.clear", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":333 * # MutableMapping interface # * * def __setitem__(self, key, value): # <<<<<<<<<<<<<< * self._replace(self._upper(key), value) * */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_9MultiDict_11__setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_9MultiDict_11__setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict_10__setitem__(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self), ((PyObject *)__pyx_v_key), ((PyObject *)__pyx_v_value)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_9MultiDict_10__setitem__(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__setitem__", 0); /* "aiohttp/_multidict.pyx":334 * * def __setitem__(self, key, value): * self._replace(self._upper(key), value) # <<<<<<<<<<<<<< * * def __delitem__(self, key): */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._upper(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_replace(__pyx_v_self, ((PyObject*)__pyx_t_1), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":333 * # MutableMapping interface # * * def __setitem__(self, key, value): # <<<<<<<<<<<<<< * self._replace(self._upper(key), value) * */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":336 * self._replace(self._upper(key), value) * * def __delitem__(self, key): # <<<<<<<<<<<<<< * self._remove(self._upper(key), True) * */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_9MultiDict_13__delitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_9MultiDict_13__delitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__delitem__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict_12__delitem__(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self), ((PyObject *)__pyx_v_key)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_9MultiDict_12__delitem__(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__delitem__", 0); /* "aiohttp/_multidict.pyx":337 * * def __delitem__(self, key): * self._remove(self._upper(key), True) # <<<<<<<<<<<<<< * * cdef _remove(self, str key, int raise_key_error): */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._upper(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 337; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_remove(__pyx_v_self, ((PyObject*)__pyx_t_1), 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 337; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":336 * self._replace(self._upper(key), value) * * def __delitem__(self, key): # <<<<<<<<<<<<<< * self._remove(self._upper(key), True) * */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.__delitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":339 * self._remove(self._upper(key), True) * * cdef _remove(self, str key, int raise_key_error): # <<<<<<<<<<<<<< * cdef _Pair item * cdef int found */ static PyObject *__pyx_f_7aiohttp_10_multidict_9MultiDict__remove(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_v_raise_key_error) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; int __pyx_v_found; Py_ssize_t __pyx_v_i; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; Py_ssize_t __pyx_t_3; PyObject *__pyx_t_4 = NULL; int __pyx_t_5; int __pyx_t_6; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_remove", 0); /* "aiohttp/_multidict.pyx":342 * cdef _Pair item * cdef int found * found = False # <<<<<<<<<<<<<< * for i in range(len(self._items) - 1, -1, -1): * item = <_Pair>self._items[i] */ __pyx_v_found = 0; /* "aiohttp/_multidict.pyx":343 * cdef int found * found = False * for i in range(len(self._items) - 1, -1, -1): # <<<<<<<<<<<<<< * item = <_Pair>self._items[i] * if item._key == key: */ __pyx_t_1 = __pyx_v_self->__pyx_base._items; __Pyx_INCREF(__pyx_t_1); if (unlikely(__pyx_t_1 == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = PyList_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; for (__pyx_t_3 = (__pyx_t_2 - 1); __pyx_t_3 > -1L; __pyx_t_3-=1) { __pyx_v_i = __pyx_t_3; /* "aiohttp/_multidict.pyx":344 * found = False * for i in range(len(self._items) - 1, -1, -1): * item = <_Pair>self._items[i] # <<<<<<<<<<<<<< * if item._key == key: * del self._items[i] */ if (unlikely(__pyx_v_self->__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 344; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __Pyx_GetItemInt_List(__pyx_v_self->__pyx_base._items, __pyx_v_i, Py_ssize_t, 1, PyInt_FromSsize_t, 1, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 344; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = __pyx_t_1; __Pyx_INCREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_4)); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":345 * for i in range(len(self._items) - 1, -1, -1): * item = <_Pair>self._items[i] * if item._key == key: # <<<<<<<<<<<<<< * del self._items[i] * found = True */ __pyx_t_5 = (__Pyx_PyString_Equals(__pyx_v_item->_key, __pyx_v_key, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 345; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__pyx_t_5) { /* "aiohttp/_multidict.pyx":346 * item = <_Pair>self._items[i] * if item._key == key: * del self._items[i] # <<<<<<<<<<<<<< * found = True * if not found and raise_key_error: */ if (unlikely(__pyx_v_self->__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } if (__Pyx_DelItemInt(__pyx_v_self->__pyx_base._items, __pyx_v_i, Py_ssize_t, 1, PyInt_FromSsize_t, 1, 1, 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":347 * if item._key == key: * del self._items[i] * found = True # <<<<<<<<<<<<<< * if not found and raise_key_error: * raise KeyError(key) */ __pyx_v_found = 1; /* "aiohttp/_multidict.pyx":345 * for i in range(len(self._items) - 1, -1, -1): * item = <_Pair>self._items[i] * if item._key == key: # <<<<<<<<<<<<<< * del self._items[i] * found = True */ } } /* "aiohttp/_multidict.pyx":348 * del self._items[i] * found = True * if not found and raise_key_error: # <<<<<<<<<<<<<< * raise KeyError(key) * */ __pyx_t_6 = ((!(__pyx_v_found != 0)) != 0); if (__pyx_t_6) { } else { __pyx_t_5 = __pyx_t_6; goto __pyx_L7_bool_binop_done; } __pyx_t_6 = (__pyx_v_raise_key_error != 0); __pyx_t_5 = __pyx_t_6; __pyx_L7_bool_binop_done:; if (__pyx_t_5) { /* "aiohttp/_multidict.pyx":349 * found = True * if not found and raise_key_error: * raise KeyError(key) # <<<<<<<<<<<<<< * * def setdefault(self, key, default=None): */ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_INCREF(__pyx_v_key); __Pyx_GIVEREF(__pyx_v_key); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_key); __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_Raise(__pyx_t_1, 0, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":348 * del self._items[i] * found = True * if not found and raise_key_error: # <<<<<<<<<<<<<< * raise KeyError(key) * */ } /* "aiohttp/_multidict.pyx":339 * self._remove(self._upper(key), True) * * cdef _remove(self, str key, int raise_key_error): # <<<<<<<<<<<<<< * cdef _Pair item * cdef int found */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._multidict.MultiDict._remove", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":351 * raise KeyError(key) * * def setdefault(self, key, default=None): # <<<<<<<<<<<<<< * """Return value for key, set value to default if key is not present.""" * cdef str skey */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_15setdefault(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_9MultiDict_14setdefault[] = "Return value for key, set value to default if key is not present."; static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_15setdefault(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_key = 0; PyObject *__pyx_v_default = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("setdefault (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_key,&__pyx_n_s_default,0}; PyObject* values[2] = {0,0}; values[1] = ((PyObject *)Py_None); if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_default); if (value) { values[1] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "setdefault") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } __pyx_v_key = values[0]; __pyx_v_default = values[1]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("setdefault", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict.MultiDict.setdefault", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict_14setdefault(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self), __pyx_v_key, __pyx_v_default); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_14setdefault(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default) { PyObject *__pyx_v_skey = 0; struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_i = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("setdefault", 0); /* "aiohttp/_multidict.pyx":355 * cdef str skey * cdef _Pair item * skey = self._upper(key) # <<<<<<<<<<<<<< * for i in self._items: * item = <_Pair>i */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._upper(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_skey = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":356 * cdef _Pair item * skey = self._upper(key) * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key == skey: */ if (unlikely(__pyx_v_self->__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->__pyx_base._items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":357 * skey = self._upper(key) * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * if item._key == skey: * return item._value */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":358 * for i in self._items: * item = <_Pair>i * if item._key == skey: # <<<<<<<<<<<<<< * return item._value * self._add(skey, default) */ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_item->_key, __pyx_v_skey, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":359 * item = <_Pair>i * if item._key == skey: * return item._value # <<<<<<<<<<<<<< * self._add(skey, default) * return default */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_item->_value); __pyx_r = __pyx_v_item->_value; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":358 * for i in self._items: * item = <_Pair>i * if item._key == skey: # <<<<<<<<<<<<<< * return item._value * self._add(skey, default) */ } /* "aiohttp/_multidict.pyx":356 * cdef _Pair item * skey = self._upper(key) * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key == skey: */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":360 * if item._key == skey: * return item._value * self._add(skey, default) # <<<<<<<<<<<<<< * return default * */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add(__pyx_v_self, __pyx_v_skey, __pyx_v_default); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":361 * return item._value * self._add(skey, default) * return default # <<<<<<<<<<<<<< * * def pop(self, key, default=_marker): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_default); __pyx_r = __pyx_v_default; goto __pyx_L0; /* "aiohttp/_multidict.pyx":351 * raise KeyError(key) * * def setdefault(self, key, default=None): # <<<<<<<<<<<<<< * """Return value for key, set value to default if key is not present.""" * cdef str skey */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.setdefault", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_skey); __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_i); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":363 * return default * * def pop(self, key, default=_marker): # <<<<<<<<<<<<<< * """Remove specified key and return the corresponding value. * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_17pop(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_9MultiDict_16pop[] = "Remove specified key and return the corresponding value.\n\n If key is not found, d is returned if given, otherwise\n KeyError is raised.\n\n "; static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_17pop(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_key = 0; PyObject *__pyx_v_default = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("pop (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_key,&__pyx_n_s_default,0}; PyObject* values[2] = {0,0}; values[1] = __pyx_k__6; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_default); if (value) { values[1] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "pop") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } __pyx_v_key = values[0]; __pyx_v_default = values[1]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("pop", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict.MultiDict.pop", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict_16pop(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self), __pyx_v_key, __pyx_v_default); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_16pop(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_default) { int __pyx_v_found; CYTHON_UNUSED PyObject *__pyx_v_skey = 0; PyObject *__pyx_v_value = 0; struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; Py_ssize_t __pyx_v_i; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; Py_ssize_t __pyx_t_3; PyObject *__pyx_t_4 = NULL; int __pyx_t_5; int __pyx_t_6; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("pop", 0); /* "aiohttp/_multidict.pyx":374 * cdef object value * cdef _Pair item * skey = self._upper(key) # <<<<<<<<<<<<<< * value = None * found = False */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._upper(((struct __pyx_obj_7aiohttp_10_multidict__Base *)__pyx_v_self), __pyx_v_key); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_skey = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":375 * cdef _Pair item * skey = self._upper(key) * value = None # <<<<<<<<<<<<<< * found = False * for i in range(len(self._items) - 1, -1, -1): */ __Pyx_INCREF(Py_None); __pyx_v_value = Py_None; /* "aiohttp/_multidict.pyx":376 * skey = self._upper(key) * value = None * found = False # <<<<<<<<<<<<<< * for i in range(len(self._items) - 1, -1, -1): * item = <_Pair>self._items[i] */ __pyx_v_found = 0; /* "aiohttp/_multidict.pyx":377 * value = None * found = False * for i in range(len(self._items) - 1, -1, -1): # <<<<<<<<<<<<<< * item = <_Pair>self._items[i] * if item._key == key: */ __pyx_t_1 = __pyx_v_self->__pyx_base._items; __Pyx_INCREF(__pyx_t_1); if (unlikely(__pyx_t_1 == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = PyList_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; for (__pyx_t_3 = (__pyx_t_2 - 1); __pyx_t_3 > -1L; __pyx_t_3-=1) { __pyx_v_i = __pyx_t_3; /* "aiohttp/_multidict.pyx":378 * found = False * for i in range(len(self._items) - 1, -1, -1): * item = <_Pair>self._items[i] # <<<<<<<<<<<<<< * if item._key == key: * value = item._value */ if (unlikely(__pyx_v_self->__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __Pyx_GetItemInt_List(__pyx_v_self->__pyx_base._items, __pyx_v_i, Py_ssize_t, 1, PyInt_FromSsize_t, 1, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = __pyx_t_1; __Pyx_INCREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_4)); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":379 * for i in range(len(self._items) - 1, -1, -1): * item = <_Pair>self._items[i] * if item._key == key: # <<<<<<<<<<<<<< * value = item._value * del self._items[i] */ __pyx_t_4 = PyObject_RichCompare(__pyx_v_item->_key, __pyx_v_key, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_5) { /* "aiohttp/_multidict.pyx":380 * item = <_Pair>self._items[i] * if item._key == key: * value = item._value # <<<<<<<<<<<<<< * del self._items[i] * found = True */ __pyx_t_4 = __pyx_v_item->_value; __Pyx_INCREF(__pyx_t_4); __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":381 * if item._key == key: * value = item._value * del self._items[i] # <<<<<<<<<<<<<< * found = True * if not found: */ if (unlikely(__pyx_v_self->__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } if (__Pyx_DelItemInt(__pyx_v_self->__pyx_base._items, __pyx_v_i, Py_ssize_t, 1, PyInt_FromSsize_t, 1, 1, 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":382 * value = item._value * del self._items[i] * found = True # <<<<<<<<<<<<<< * if not found: * if default is self.marker: */ __pyx_v_found = 1; /* "aiohttp/_multidict.pyx":379 * for i in range(len(self._items) - 1, -1, -1): * item = <_Pair>self._items[i] * if item._key == key: # <<<<<<<<<<<<<< * value = item._value * del self._items[i] */ } } /* "aiohttp/_multidict.pyx":383 * del self._items[i] * found = True * if not found: # <<<<<<<<<<<<<< * if default is self.marker: * raise KeyError(key) */ __pyx_t_5 = ((!(__pyx_v_found != 0)) != 0); if (__pyx_t_5) { /* "aiohttp/_multidict.pyx":384 * found = True * if not found: * if default is self.marker: # <<<<<<<<<<<<<< * raise KeyError(key) * else: */ __pyx_t_5 = (__pyx_v_default == __pyx_v_self->__pyx_base.marker); __pyx_t_6 = (__pyx_t_5 != 0); if (__pyx_t_6) { /* "aiohttp/_multidict.pyx":385 * if not found: * if default is self.marker: * raise KeyError(key) # <<<<<<<<<<<<<< * else: * return default */ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_INCREF(__pyx_v_key); __Pyx_GIVEREF(__pyx_v_key); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_key); __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_Raise(__pyx_t_1, 0, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":384 * found = True * if not found: * if default is self.marker: # <<<<<<<<<<<<<< * raise KeyError(key) * else: */ } /* "aiohttp/_multidict.pyx":387 * raise KeyError(key) * else: * return default # <<<<<<<<<<<<<< * else: * return value */ /*else*/ { __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_default); __pyx_r = __pyx_v_default; goto __pyx_L0; } /* "aiohttp/_multidict.pyx":383 * del self._items[i] * found = True * if not found: # <<<<<<<<<<<<<< * if default is self.marker: * raise KeyError(key) */ } /* "aiohttp/_multidict.pyx":389 * return default * else: * return value # <<<<<<<<<<<<<< * * def popitem(self): */ /*else*/ { __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_value); __pyx_r = __pyx_v_value; goto __pyx_L0; } /* "aiohttp/_multidict.pyx":363 * return default * * def pop(self, key, default=_marker): # <<<<<<<<<<<<<< * """Remove specified key and return the corresponding value. * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.pop", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_skey); __Pyx_XDECREF(__pyx_v_value); __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":391 * return value * * def popitem(self): # <<<<<<<<<<<<<< * """Remove and return an arbitrary (key, value) pair.""" * cdef _Pair item */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_19popitem(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_9MultiDict_18popitem[] = "Remove and return an arbitrary (key, value) pair."; static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_19popitem(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("popitem (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict_18popitem(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_18popitem(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("popitem", 0); /* "aiohttp/_multidict.pyx":394 * """Remove and return an arbitrary (key, value) pair.""" * cdef _Pair item * if self._items: # <<<<<<<<<<<<<< * item = <_Pair>self._items.pop(0) * return (item._key, item._value) */ __pyx_t_1 = (__pyx_v_self->__pyx_base._items != Py_None) && (PyList_GET_SIZE(__pyx_v_self->__pyx_base._items) != 0); if (__pyx_t_1) { /* "aiohttp/_multidict.pyx":395 * cdef _Pair item * if self._items: * item = <_Pair>self._items.pop(0) # <<<<<<<<<<<<<< * return (item._key, item._value) * else: */ if (unlikely(__pyx_v_self->__pyx_base._items == Py_None)) { PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "pop"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = __Pyx_PyList_PopIndex(__pyx_v_self->__pyx_base._items, __pyx_int_0, 0, 1, Py_ssize_t, PyInt_FromSsize_t); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __pyx_t_2; __Pyx_INCREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_item = ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":396 * if self._items: * item = <_Pair>self._items.pop(0) * return (item._key, item._value) # <<<<<<<<<<<<<< * else: * raise KeyError("empty multidict") */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_INCREF(__pyx_v_item->_key); __Pyx_GIVEREF(__pyx_v_item->_key); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_item->_key); __Pyx_INCREF(__pyx_v_item->_value); __Pyx_GIVEREF(__pyx_v_item->_value); PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_item->_value); __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":394 * """Remove and return an arbitrary (key, value) pair.""" * cdef _Pair item * if self._items: # <<<<<<<<<<<<<< * item = <_Pair>self._items.pop(0) * return (item._key, item._value) */ } /* "aiohttp/_multidict.pyx":398 * return (item._key, item._value) * else: * raise KeyError("empty multidict") # <<<<<<<<<<<<<< * * def update(self, *args, **kwargs): */ /*else*/ { __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } /* "aiohttp/_multidict.pyx":391 * return value * * def popitem(self): # <<<<<<<<<<<<<< * """Remove and return an arbitrary (key, value) pair.""" * cdef _Pair item */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.popitem", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":400 * raise KeyError("empty multidict") * * def update(self, *args, **kwargs): # <<<<<<<<<<<<<< * """Update the dictionary from *other*, overwriting existing keys.""" * self._extend(args, kwargs, "update", 0) */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_21update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_9MultiDict_20update[] = "Update the dictionary from *other*, overwriting existing keys."; static PyObject *__pyx_pw_7aiohttp_10_multidict_9MultiDict_21update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_args = 0; PyObject *__pyx_v_kwargs = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("update (wrapper)", 0); if (unlikely(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "update", 1))) return NULL; __pyx_v_kwargs = (__pyx_kwds) ? PyDict_Copy(__pyx_kwds) : PyDict_New(); if (unlikely(!__pyx_v_kwargs)) return NULL; __Pyx_GOTREF(__pyx_v_kwargs); __Pyx_INCREF(__pyx_args); __pyx_v_args = __pyx_args; __pyx_r = __pyx_pf_7aiohttp_10_multidict_9MultiDict_20update(((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)__pyx_v_self), __pyx_v_args, __pyx_v_kwargs); /* function exit code */ __Pyx_XDECREF(__pyx_v_args); __Pyx_XDECREF(__pyx_v_kwargs); __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9MultiDict_20update(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *__pyx_v_self, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("update", 0); /* "aiohttp/_multidict.pyx":402 * def update(self, *args, **kwargs): * """Update the dictionary from *other*, overwriting existing keys.""" * self._extend(args, kwargs, "update", 0) # <<<<<<<<<<<<<< * * */ __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict *)__pyx_v_self->__pyx_base.__pyx_vtab)->_extend(__pyx_v_self, __pyx_v_args, __pyx_v_kwargs, __pyx_n_s_update, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":400 * raise KeyError("empty multidict") * * def update(self, *args, **kwargs): # <<<<<<<<<<<<<< * """Update the dictionary from *other*, overwriting existing keys.""" * self._extend(args, kwargs, "update", 0) */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("aiohttp._multidict.MultiDict.update", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":411 * """An ordered dictionary that can have multiple values for each key.""" * * cdef str _upper(self, s): # <<<<<<<<<<<<<< * if type(s) is self._upstr: * return s */ static PyObject *__pyx_f_7aiohttp_10_multidict_11CIMultiDict__upper(struct __pyx_obj_7aiohttp_10_multidict_CIMultiDict *__pyx_v_self, PyObject *__pyx_v_s) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_upper", 0); /* "aiohttp/_multidict.pyx":412 * * cdef str _upper(self, s): * if type(s) is self._upstr: # <<<<<<<<<<<<<< * return s * return s.upper() */ __pyx_t_1 = (((PyObject *)Py_TYPE(__pyx_v_s)) == __pyx_v_self->__pyx_base.__pyx_base._upstr); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":413 * cdef str _upper(self, s): * if type(s) is self._upstr: * return s # <<<<<<<<<<<<<< * return s.upper() * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject*)__pyx_v_s)); __pyx_r = ((PyObject*)__pyx_v_s); goto __pyx_L0; /* "aiohttp/_multidict.pyx":412 * * cdef str _upper(self, s): * if type(s) is self._upstr: # <<<<<<<<<<<<<< * return s * return s.upper() */ } /* "aiohttp/_multidict.pyx":414 * if type(s) is self._upstr: * return s * return s.upper() # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_s, __pyx_n_s_upper); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(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); } } if (__pyx_t_5) { __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } else { __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (!(likely(PyString_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = ((PyObject*)__pyx_t_3); __pyx_t_3 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":411 * """An ordered dictionary that can have multiple values for each key.""" * * cdef str _upper(self, s): # <<<<<<<<<<<<<< * if type(s) is self._upstr: * return s */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("aiohttp._multidict.CIMultiDict._upper", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":425 * cdef list _items * * def __cinit__(self, list items): # <<<<<<<<<<<<<< * self._items = items * */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_9_ViewBase_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_9_ViewBase_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_items = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_items,0}; PyObject* values[1] = {0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_items)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); } __pyx_v_items = ((PyObject*)values[0]); } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._ViewBase.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_items), (&PyList_Type), 1, "items", 1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = __pyx_pf_7aiohttp_10_multidict_9_ViewBase___cinit__(((struct __pyx_obj_7aiohttp_10_multidict__ViewBase *)__pyx_v_self), __pyx_v_items); /* function exit code */ goto __pyx_L0; __pyx_L1_error:; __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_9_ViewBase___cinit__(struct __pyx_obj_7aiohttp_10_multidict__ViewBase *__pyx_v_self, PyObject *__pyx_v_items) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__cinit__", 0); /* "aiohttp/_multidict.pyx":426 * * def __cinit__(self, list items): * self._items = items # <<<<<<<<<<<<<< * * def __len__(self): */ __Pyx_INCREF(__pyx_v_items); __Pyx_GIVEREF(__pyx_v_items); __Pyx_GOTREF(__pyx_v_self->_items); __Pyx_DECREF(__pyx_v_self->_items); __pyx_v_self->_items = __pyx_v_items; /* "aiohttp/_multidict.pyx":425 * cdef list _items * * def __cinit__(self, list items): # <<<<<<<<<<<<<< * self._items = items * */ /* function exit code */ __pyx_r = 0; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":428 * self._items = items * * def __len__(self): # <<<<<<<<<<<<<< * return len(self._items) * */ /* Python wrapper */ static Py_ssize_t __pyx_pw_7aiohttp_10_multidict_9_ViewBase_3__len__(PyObject *__pyx_v_self); /*proto*/ static Py_ssize_t __pyx_pw_7aiohttp_10_multidict_9_ViewBase_3__len__(PyObject *__pyx_v_self) { Py_ssize_t __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9_ViewBase_2__len__(((struct __pyx_obj_7aiohttp_10_multidict__ViewBase *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static Py_ssize_t __pyx_pf_7aiohttp_10_multidict_9_ViewBase_2__len__(struct __pyx_obj_7aiohttp_10_multidict__ViewBase *__pyx_v_self) { Py_ssize_t __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__len__", 0); /* "aiohttp/_multidict.pyx":429 * * def __len__(self): * return len(self._items) # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); if (unlikely(__pyx_t_1 == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = PyList_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; goto __pyx_L0; /* "aiohttp/_multidict.pyx":428 * self._items = items * * def __len__(self): # <<<<<<<<<<<<<< * return len(self._items) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("aiohttp._multidict._ViewBase.__len__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":434 * cdef class _ViewBaseSet(_ViewBase): * * def __richcmp__(self, other, op): # <<<<<<<<<<<<<< * if op == 0: # < * if not isinstance(other, Set): */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_1__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_1__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op) { PyObject *__pyx_v_op = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__richcmp__ (wrapper)", 0); __pyx_v_op = __Pyx_PyInt_From_int(__pyx_arg_op); if (unlikely(!__pyx_v_op)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __Pyx_GOTREF(__pyx_v_op); goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._ViewBaseSet.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet___richcmp__(((PyObject *)__pyx_v_self), ((PyObject *)__pyx_v_other), ((PyObject *)__pyx_v_op)); /* function exit code */ __Pyx_XDECREF(__pyx_v_op); __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet___richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op) { PyObject *__pyx_v_elem = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_t_2; int __pyx_t_3; Py_ssize_t __pyx_t_4; Py_ssize_t __pyx_t_5; PyObject *__pyx_t_6 = NULL; PyObject *(*__pyx_t_7)(PyObject *); int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__richcmp__", 0); /* "aiohttp/_multidict.pyx":435 * * def __richcmp__(self, other, op): * if op == 0: # < # <<<<<<<<<<<<<< * if not isinstance(other, Set): * return NotImplemented */ __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_0, 0, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":436 * def __richcmp__(self, other, op): * if op == 0: # < * if not isinstance(other, Set): # <<<<<<<<<<<<<< * return NotImplemented * return len(self) < len(other) and self <= other */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Set); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":437 * if op == 0: # < * if not isinstance(other, Set): * return NotImplemented # <<<<<<<<<<<<<< * return len(self) < len(other) and self <= other * elif op == 1: # <= */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; /* "aiohttp/_multidict.pyx":436 * def __richcmp__(self, other, op): * if op == 0: # < * if not isinstance(other, Set): # <<<<<<<<<<<<<< * return NotImplemented * return len(self) < len(other) and self <= other */ } /* "aiohttp/_multidict.pyx":438 * if not isinstance(other, Set): * return NotImplemented * return len(self) < len(other) and self <= other # <<<<<<<<<<<<<< * elif op == 1: # <= * if not isinstance(other, Set): */ __Pyx_XDECREF(__pyx_r); __pyx_t_4 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_5 = PyObject_Length(__pyx_v_other); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_3 = (__pyx_t_4 < __pyx_t_5); if (__pyx_t_3) { } else { __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); __pyx_t_1 = __pyx_t_6; __pyx_t_6 = 0; goto __pyx_L5_bool_binop_done; } __pyx_t_6 = PyObject_RichCompare(__pyx_v_self, __pyx_v_other, Py_LE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_INCREF(__pyx_t_6); __pyx_t_1 = __pyx_t_6; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_L5_bool_binop_done:; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":435 * * def __richcmp__(self, other, op): * if op == 0: # < # <<<<<<<<<<<<<< * if not isinstance(other, Set): * return NotImplemented */ } /* "aiohttp/_multidict.pyx":439 * return NotImplemented * return len(self) < len(other) and self <= other * elif op == 1: # <= # <<<<<<<<<<<<<< * if not isinstance(other, Set): * return NotImplemented */ __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_1, 1, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":440 * return len(self) < len(other) and self <= other * elif op == 1: # <= * if not isinstance(other, Set): # <<<<<<<<<<<<<< * return NotImplemented * if len(self) > len(other): */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Set); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":441 * elif op == 1: # <= * if not isinstance(other, Set): * return NotImplemented # <<<<<<<<<<<<<< * if len(self) > len(other): * return False */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; /* "aiohttp/_multidict.pyx":440 * return len(self) < len(other) and self <= other * elif op == 1: # <= * if not isinstance(other, Set): # <<<<<<<<<<<<<< * return NotImplemented * if len(self) > len(other): */ } /* "aiohttp/_multidict.pyx":442 * if not isinstance(other, Set): * return NotImplemented * if len(self) > len(other): # <<<<<<<<<<<<<< * return False * for elem in self: */ __pyx_t_5 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_4 = PyObject_Length(__pyx_v_other); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_2 = ((__pyx_t_5 > __pyx_t_4) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":443 * return NotImplemented * if len(self) > len(other): * return False # <<<<<<<<<<<<<< * for elem in self: * if elem not in other: */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; goto __pyx_L0; /* "aiohttp/_multidict.pyx":442 * if not isinstance(other, Set): * return NotImplemented * if len(self) > len(other): # <<<<<<<<<<<<<< * return False * for elem in self: */ } /* "aiohttp/_multidict.pyx":444 * if len(self) > len(other): * return False * for elem in self: # <<<<<<<<<<<<<< * if elem not in other: * return False */ if (likely(PyList_CheckExact(__pyx_v_self)) || PyTuple_CheckExact(__pyx_v_self)) { __pyx_t_1 = __pyx_v_self; __Pyx_INCREF(__pyx_t_1); __pyx_t_4 = 0; __pyx_t_7 = NULL; } else { __pyx_t_4 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_7 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } for (;;) { if (likely(!__pyx_t_7)) { if (likely(PyList_CheckExact(__pyx_t_1))) { if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_6 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); #endif } else { if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); #endif } } else { __pyx_t_6 = __pyx_t_7(__pyx_t_1); if (unlikely(!__pyx_t_6)) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } break; } __Pyx_GOTREF(__pyx_t_6); } __Pyx_XDECREF_SET(__pyx_v_elem, __pyx_t_6); __pyx_t_6 = 0; /* "aiohttp/_multidict.pyx":445 * return False * for elem in self: * if elem not in other: # <<<<<<<<<<<<<< * return False * return True */ __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_v_elem, __pyx_v_other, Py_NE)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_3 = (__pyx_t_2 != 0); if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":446 * for elem in self: * if elem not in other: * return False # <<<<<<<<<<<<<< * return True * elif op == 2: # == */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":445 * return False * for elem in self: * if elem not in other: # <<<<<<<<<<<<<< * return False * return True */ } /* "aiohttp/_multidict.pyx":444 * if len(self) > len(other): * return False * for elem in self: # <<<<<<<<<<<<<< * if elem not in other: * return False */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":447 * if elem not in other: * return False * return True # <<<<<<<<<<<<<< * elif op == 2: # == * if not isinstance(other, Set): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_True); __pyx_r = Py_True; goto __pyx_L0; /* "aiohttp/_multidict.pyx":439 * return NotImplemented * return len(self) < len(other) and self <= other * elif op == 1: # <= # <<<<<<<<<<<<<< * if not isinstance(other, Set): * return NotImplemented */ } /* "aiohttp/_multidict.pyx":448 * return False * return True * elif op == 2: # == # <<<<<<<<<<<<<< * if not isinstance(other, Set): * return NotImplemented */ __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_2, 2, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":449 * return True * elif op == 2: # == * if not isinstance(other, Set): # <<<<<<<<<<<<<< * return NotImplemented * return len(self) == len(other) and self <= other */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Set); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":450 * elif op == 2: # == * if not isinstance(other, Set): * return NotImplemented # <<<<<<<<<<<<<< * return len(self) == len(other) and self <= other * elif op == 3: # != */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; /* "aiohttp/_multidict.pyx":449 * return True * elif op == 2: # == * if not isinstance(other, Set): # <<<<<<<<<<<<<< * return NotImplemented * return len(self) == len(other) and self <= other */ } /* "aiohttp/_multidict.pyx":451 * if not isinstance(other, Set): * return NotImplemented * return len(self) == len(other) and self <= other # <<<<<<<<<<<<<< * elif op == 3: # != * return not self == other */ __Pyx_XDECREF(__pyx_r); __pyx_t_4 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_5 = PyObject_Length(__pyx_v_other); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_2 = (__pyx_t_4 == __pyx_t_5); if (__pyx_t_2) { } else { __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); __pyx_t_1 = __pyx_t_6; __pyx_t_6 = 0; goto __pyx_L13_bool_binop_done; } __pyx_t_6 = PyObject_RichCompare(__pyx_v_self, __pyx_v_other, Py_LE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_INCREF(__pyx_t_6); __pyx_t_1 = __pyx_t_6; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_L13_bool_binop_done:; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":448 * return False * return True * elif op == 2: # == # <<<<<<<<<<<<<< * if not isinstance(other, Set): * return NotImplemented */ } /* "aiohttp/_multidict.pyx":452 * return NotImplemented * return len(self) == len(other) and self <= other * elif op == 3: # != # <<<<<<<<<<<<<< * return not self == other * elif op == 4: # > */ __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_3, 3, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":453 * return len(self) == len(other) and self <= other * elif op == 3: # != * return not self == other # <<<<<<<<<<<<<< * elif op == 4: # > * if not isinstance(other, Set): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyObject_RichCompare(__pyx_v_self, __pyx_v_other, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":452 * return NotImplemented * return len(self) == len(other) and self <= other * elif op == 3: # != # <<<<<<<<<<<<<< * return not self == other * elif op == 4: # > */ } /* "aiohttp/_multidict.pyx":454 * elif op == 3: # != * return not self == other * elif op == 4: # > # <<<<<<<<<<<<<< * if not isinstance(other, Set): * return NotImplemented */ __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_4, 4, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":455 * return not self == other * elif op == 4: # > * if not isinstance(other, Set): # <<<<<<<<<<<<<< * return NotImplemented * return len(self) > len(other) and self >= other */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Set); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":456 * elif op == 4: # > * if not isinstance(other, Set): * return NotImplemented # <<<<<<<<<<<<<< * return len(self) > len(other) and self >= other * elif op == 5: # >= */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; /* "aiohttp/_multidict.pyx":455 * return not self == other * elif op == 4: # > * if not isinstance(other, Set): # <<<<<<<<<<<<<< * return NotImplemented * return len(self) > len(other) and self >= other */ } /* "aiohttp/_multidict.pyx":457 * if not isinstance(other, Set): * return NotImplemented * return len(self) > len(other) and self >= other # <<<<<<<<<<<<<< * elif op == 5: # >= * if not isinstance(other, Set): */ __Pyx_XDECREF(__pyx_r); __pyx_t_5 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_4 = PyObject_Length(__pyx_v_other); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_3 = (__pyx_t_5 > __pyx_t_4); if (__pyx_t_3) { } else { __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); __pyx_t_1 = __pyx_t_6; __pyx_t_6 = 0; goto __pyx_L16_bool_binop_done; } __pyx_t_6 = PyObject_RichCompare(__pyx_v_self, __pyx_v_other, Py_GE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_INCREF(__pyx_t_6); __pyx_t_1 = __pyx_t_6; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_L16_bool_binop_done:; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":454 * elif op == 3: # != * return not self == other * elif op == 4: # > # <<<<<<<<<<<<<< * if not isinstance(other, Set): * return NotImplemented */ } /* "aiohttp/_multidict.pyx":458 * return NotImplemented * return len(self) > len(other) and self >= other * elif op == 5: # >= # <<<<<<<<<<<<<< * if not isinstance(other, Set): * return NotImplemented */ __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_5, 5, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":459 * return len(self) > len(other) and self >= other * elif op == 5: # >= * if not isinstance(other, Set): # <<<<<<<<<<<<<< * return NotImplemented * if len(self) < len(other): */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Set); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":460 * elif op == 5: # >= * if not isinstance(other, Set): * return NotImplemented # <<<<<<<<<<<<<< * if len(self) < len(other): * return False */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; /* "aiohttp/_multidict.pyx":459 * return len(self) > len(other) and self >= other * elif op == 5: # >= * if not isinstance(other, Set): # <<<<<<<<<<<<<< * return NotImplemented * if len(self) < len(other): */ } /* "aiohttp/_multidict.pyx":461 * if not isinstance(other, Set): * return NotImplemented * if len(self) < len(other): # <<<<<<<<<<<<<< * return False * for elem in other: */ __pyx_t_4 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_5 = PyObject_Length(__pyx_v_other); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_2 = ((__pyx_t_4 < __pyx_t_5) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":462 * return NotImplemented * if len(self) < len(other): * return False # <<<<<<<<<<<<<< * for elem in other: * if elem not in self: */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; goto __pyx_L0; /* "aiohttp/_multidict.pyx":461 * if not isinstance(other, Set): * return NotImplemented * if len(self) < len(other): # <<<<<<<<<<<<<< * return False * for elem in other: */ } /* "aiohttp/_multidict.pyx":463 * if len(self) < len(other): * return False * for elem in other: # <<<<<<<<<<<<<< * if elem not in self: * return False */ if (likely(PyList_CheckExact(__pyx_v_other)) || PyTuple_CheckExact(__pyx_v_other)) { __pyx_t_1 = __pyx_v_other; __Pyx_INCREF(__pyx_t_1); __pyx_t_5 = 0; __pyx_t_7 = NULL; } else { __pyx_t_5 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_7 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } for (;;) { if (likely(!__pyx_t_7)) { if (likely(PyList_CheckExact(__pyx_t_1))) { if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_6 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_6); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); #endif } else { if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_6); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); #endif } } else { __pyx_t_6 = __pyx_t_7(__pyx_t_1); if (unlikely(!__pyx_t_6)) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } break; } __Pyx_GOTREF(__pyx_t_6); } __Pyx_XDECREF_SET(__pyx_v_elem, __pyx_t_6); __pyx_t_6 = 0; /* "aiohttp/_multidict.pyx":464 * return False * for elem in other: * if elem not in self: # <<<<<<<<<<<<<< * return False * return True */ __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_v_elem, __pyx_v_self, Py_NE)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_3 = (__pyx_t_2 != 0); if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":465 * for elem in other: * if elem not in self: * return False # <<<<<<<<<<<<<< * return True * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":464 * return False * for elem in other: * if elem not in self: # <<<<<<<<<<<<<< * return False * return True */ } /* "aiohttp/_multidict.pyx":463 * if len(self) < len(other): * return False * for elem in other: # <<<<<<<<<<<<<< * if elem not in self: * return False */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":466 * if elem not in self: * return False * return True # <<<<<<<<<<<<<< * * def __and__(self, other): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_True); __pyx_r = Py_True; goto __pyx_L0; /* "aiohttp/_multidict.pyx":458 * return NotImplemented * return len(self) > len(other) and self >= other * elif op == 5: # >= # <<<<<<<<<<<<<< * if not isinstance(other, Set): * return NotImplemented */ } /* "aiohttp/_multidict.pyx":434 * cdef class _ViewBaseSet(_ViewBase): * * def __richcmp__(self, other, op): # <<<<<<<<<<<<<< * if op == 0: # < * if not isinstance(other, Set): */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._multidict._ViewBaseSet.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_elem); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":468 * return True * * def __and__(self, other): # <<<<<<<<<<<<<< * if not isinstance(other, Iterable): * return NotImplemented */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_3__and__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_3__and__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__and__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_2__and__(((PyObject *)__pyx_v_self), ((PyObject *)__pyx_v_other)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_2__and__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_t_2; int __pyx_t_3; PyObject *__pyx_t_4 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__and__", 0); __Pyx_INCREF(__pyx_v_other); /* "aiohttp/_multidict.pyx":469 * * def __and__(self, other): * if not isinstance(other, Iterable): # <<<<<<<<<<<<<< * return NotImplemented * if not isinstance(other, Set): */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Iterable); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":470 * def __and__(self, other): * if not isinstance(other, Iterable): * return NotImplemented # <<<<<<<<<<<<<< * if not isinstance(other, Set): * other = set(other) */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; /* "aiohttp/_multidict.pyx":469 * * def __and__(self, other): * if not isinstance(other, Iterable): # <<<<<<<<<<<<<< * return NotImplemented * if not isinstance(other, Set): */ } /* "aiohttp/_multidict.pyx":471 * if not isinstance(other, Iterable): * return NotImplemented * if not isinstance(other, Set): # <<<<<<<<<<<<<< * other = set(other) * return set(self) & other */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Set); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":472 * return NotImplemented * if not isinstance(other, Set): * other = set(other) # <<<<<<<<<<<<<< * return set(self) & other * */ __pyx_t_1 = PySet_New(__pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF_SET(__pyx_v_other, __pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":471 * if not isinstance(other, Iterable): * return NotImplemented * if not isinstance(other, Set): # <<<<<<<<<<<<<< * other = set(other) * return set(self) & other */ } /* "aiohttp/_multidict.pyx":473 * if not isinstance(other, Set): * other = set(other) * return set(self) & other # <<<<<<<<<<<<<< * * def __or__(self, other): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PySet_New(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = PyNumber_And(__pyx_t_1, __pyx_v_other); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":468 * return True * * def __and__(self, other): # <<<<<<<<<<<<<< * if not isinstance(other, Iterable): * return NotImplemented */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._multidict._ViewBaseSet.__and__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_other); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":475 * return set(self) & other * * def __or__(self, other): # <<<<<<<<<<<<<< * if not isinstance(other, Iterable): * return NotImplemented */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_5__or__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_5__or__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__or__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_4__or__(((PyObject *)__pyx_v_self), ((PyObject *)__pyx_v_other)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_4__or__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_t_2; int __pyx_t_3; PyObject *__pyx_t_4 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__or__", 0); __Pyx_INCREF(__pyx_v_other); /* "aiohttp/_multidict.pyx":476 * * def __or__(self, other): * if not isinstance(other, Iterable): # <<<<<<<<<<<<<< * return NotImplemented * if not isinstance(other, Set): */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Iterable); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":477 * def __or__(self, other): * if not isinstance(other, Iterable): * return NotImplemented # <<<<<<<<<<<<<< * if not isinstance(other, Set): * other = set(other) */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; /* "aiohttp/_multidict.pyx":476 * * def __or__(self, other): * if not isinstance(other, Iterable): # <<<<<<<<<<<<<< * return NotImplemented * if not isinstance(other, Set): */ } /* "aiohttp/_multidict.pyx":478 * if not isinstance(other, Iterable): * return NotImplemented * if not isinstance(other, Set): # <<<<<<<<<<<<<< * other = set(other) * return set(self) | other */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Set); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":479 * return NotImplemented * if not isinstance(other, Set): * other = set(other) # <<<<<<<<<<<<<< * return set(self) | other * */ __pyx_t_1 = PySet_New(__pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF_SET(__pyx_v_other, __pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":478 * if not isinstance(other, Iterable): * return NotImplemented * if not isinstance(other, Set): # <<<<<<<<<<<<<< * other = set(other) * return set(self) | other */ } /* "aiohttp/_multidict.pyx":480 * if not isinstance(other, Set): * other = set(other) * return set(self) | other # <<<<<<<<<<<<<< * * def __sub__(self, other): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PySet_New(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = PyNumber_Or(__pyx_t_1, __pyx_v_other); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":475 * return set(self) & other * * def __or__(self, other): # <<<<<<<<<<<<<< * if not isinstance(other, Iterable): * return NotImplemented */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._multidict._ViewBaseSet.__or__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_other); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":482 * return set(self) | other * * def __sub__(self, other): # <<<<<<<<<<<<<< * if not isinstance(other, Iterable): * return NotImplemented */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_7__sub__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_7__sub__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__sub__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_6__sub__(((PyObject *)__pyx_v_self), ((PyObject *)__pyx_v_other)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_6__sub__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_t_2; int __pyx_t_3; PyObject *__pyx_t_4 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__sub__", 0); __Pyx_INCREF(__pyx_v_other); /* "aiohttp/_multidict.pyx":483 * * def __sub__(self, other): * if not isinstance(other, Iterable): # <<<<<<<<<<<<<< * return NotImplemented * if not isinstance(other, Set): */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Iterable); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":484 * def __sub__(self, other): * if not isinstance(other, Iterable): * return NotImplemented # <<<<<<<<<<<<<< * if not isinstance(other, Set): * other = set(other) */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; /* "aiohttp/_multidict.pyx":483 * * def __sub__(self, other): * if not isinstance(other, Iterable): # <<<<<<<<<<<<<< * return NotImplemented * if not isinstance(other, Set): */ } /* "aiohttp/_multidict.pyx":485 * if not isinstance(other, Iterable): * return NotImplemented * if not isinstance(other, Set): # <<<<<<<<<<<<<< * other = set(other) * return set(self) - other */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Set); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":486 * return NotImplemented * if not isinstance(other, Set): * other = set(other) # <<<<<<<<<<<<<< * return set(self) - other * */ __pyx_t_1 = PySet_New(__pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF_SET(__pyx_v_other, __pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":485 * if not isinstance(other, Iterable): * return NotImplemented * if not isinstance(other, Set): # <<<<<<<<<<<<<< * other = set(other) * return set(self) - other */ } /* "aiohttp/_multidict.pyx":487 * if not isinstance(other, Set): * other = set(other) * return set(self) - other # <<<<<<<<<<<<<< * * def __xor__(self, other): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PySet_New(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = PyNumber_Subtract(__pyx_t_1, __pyx_v_other); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":482 * return set(self) | other * * def __sub__(self, other): # <<<<<<<<<<<<<< * if not isinstance(other, Iterable): * return NotImplemented */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._multidict._ViewBaseSet.__sub__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_other); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":489 * return set(self) - other * * def __xor__(self, other): # <<<<<<<<<<<<<< * if not isinstance(other, Set): * if not isinstance(other, Iterable): */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_9__xor__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_9__xor__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__xor__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_8__xor__(((PyObject *)__pyx_v_self), ((PyObject *)__pyx_v_other)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_12_ViewBaseSet_8__xor__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_t_2; int __pyx_t_3; PyObject *__pyx_t_4 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__xor__", 0); __Pyx_INCREF(__pyx_v_other); /* "aiohttp/_multidict.pyx":490 * * def __xor__(self, other): * if not isinstance(other, Set): # <<<<<<<<<<<<<< * if not isinstance(other, Iterable): * return NotImplemented */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Set); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_3) { /* "aiohttp/_multidict.pyx":491 * def __xor__(self, other): * if not isinstance(other, Set): * if not isinstance(other, Iterable): # <<<<<<<<<<<<<< * return NotImplemented * other = set(other) */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Iterable); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyObject_IsInstance(__pyx_v_other, __pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); if (__pyx_t_2) { /* "aiohttp/_multidict.pyx":492 * if not isinstance(other, Set): * if not isinstance(other, Iterable): * return NotImplemented # <<<<<<<<<<<<<< * other = set(other) * return set(self) ^ other */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_builtin_NotImplemented); __pyx_r = __pyx_builtin_NotImplemented; goto __pyx_L0; /* "aiohttp/_multidict.pyx":491 * def __xor__(self, other): * if not isinstance(other, Set): * if not isinstance(other, Iterable): # <<<<<<<<<<<<<< * return NotImplemented * other = set(other) */ } /* "aiohttp/_multidict.pyx":493 * if not isinstance(other, Iterable): * return NotImplemented * other = set(other) # <<<<<<<<<<<<<< * return set(self) ^ other * */ __pyx_t_1 = PySet_New(__pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF_SET(__pyx_v_other, __pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":490 * * def __xor__(self, other): * if not isinstance(other, Set): # <<<<<<<<<<<<<< * if not isinstance(other, Iterable): * return NotImplemented */ } /* "aiohttp/_multidict.pyx":494 * return NotImplemented * other = set(other) * return set(self) ^ other # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PySet_New(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = PyNumber_Xor(__pyx_t_1, __pyx_v_other); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":489 * return set(self) - other * * def __xor__(self, other): # <<<<<<<<<<<<<< * if not isinstance(other, Set): * if not isinstance(other, Iterable): */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("aiohttp._multidict._ViewBaseSet.__xor__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_other); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":502 * cdef int _len * * def __cinit__(self, items): # <<<<<<<<<<<<<< * self._items = items * self._current = 0 */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_10_ItemsIter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_10_ItemsIter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_items = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_items,0}; PyObject* values[1] = {0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_items)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); } __pyx_v_items = values[0]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._ItemsIter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_10_ItemsIter___cinit__(((struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *)__pyx_v_self), __pyx_v_items); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_10_ItemsIter___cinit__(struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *__pyx_v_self, PyObject *__pyx_v_items) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__cinit__", 0); /* "aiohttp/_multidict.pyx":503 * * def __cinit__(self, items): * self._items = items # <<<<<<<<<<<<<< * self._current = 0 * self._len = len(self._items) */ if (!(likely(PyList_CheckExact(__pyx_v_items))||((__pyx_v_items) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_v_items)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_1 = __pyx_v_items; __Pyx_INCREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v_self->_items); __Pyx_DECREF(__pyx_v_self->_items); __pyx_v_self->_items = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":504 * def __cinit__(self, items): * self._items = items * self._current = 0 # <<<<<<<<<<<<<< * self._len = len(self._items) * */ __pyx_v_self->_current = 0; /* "aiohttp/_multidict.pyx":505 * self._items = items * self._current = 0 * self._len = len(self._items) # <<<<<<<<<<<<<< * * def __iter__(self): */ __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); if (unlikely(__pyx_t_1 == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = PyList_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_self->_len = __pyx_t_2; /* "aiohttp/_multidict.pyx":502 * cdef int _len * * def __cinit__(self, items): # <<<<<<<<<<<<<< * self._items = items * self._current = 0 */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("aiohttp._multidict._ItemsIter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":507 * self._len = len(self._items) * * def __iter__(self): # <<<<<<<<<<<<<< * return self * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_10_ItemsIter_3__iter__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_10_ItemsIter_3__iter__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_10_ItemsIter_2__iter__(((struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_10_ItemsIter_2__iter__(struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__iter__", 0); /* "aiohttp/_multidict.pyx":508 * * def __iter__(self): * return self # <<<<<<<<<<<<<< * * def __next__(self): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_self)); __pyx_r = ((PyObject *)__pyx_v_self); goto __pyx_L0; /* "aiohttp/_multidict.pyx":507 * self._len = len(self._items) * * def __iter__(self): # <<<<<<<<<<<<<< * return self * */ /* function exit code */ __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":510 * return self * * def __next__(self): # <<<<<<<<<<<<<< * if self._current == self._len: * raise StopIteration */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_10_ItemsIter_5__next__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_10_ItemsIter_5__next__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__next__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_10_ItemsIter_4__next__(((struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_10_ItemsIter_4__next__(struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *__pyx_v_self) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__next__", 0); /* "aiohttp/_multidict.pyx":511 * * def __next__(self): * if self._current == self._len: # <<<<<<<<<<<<<< * raise StopIteration * item = <_Pair>self._items[self._current] */ __pyx_t_1 = ((__pyx_v_self->_current == __pyx_v_self->_len) != 0); if (__pyx_t_1) { /* "aiohttp/_multidict.pyx":512 * def __next__(self): * if self._current == self._len: * raise StopIteration # <<<<<<<<<<<<<< * item = <_Pair>self._items[self._current] * self._current += 1 */ __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":511 * * def __next__(self): * if self._current == self._len: # <<<<<<<<<<<<<< * raise StopIteration * item = <_Pair>self._items[self._current] */ } /* "aiohttp/_multidict.pyx":513 * if self._current == self._len: * raise StopIteration * item = <_Pair>self._items[self._current] # <<<<<<<<<<<<<< * self._current += 1 * return (item._key, item._value) */ if (unlikely(__pyx_v_self->_items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 513; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = __Pyx_GetItemInt_List(__pyx_v_self->_items, __pyx_v_self->_current, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 513; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __pyx_t_2; __Pyx_INCREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_item = ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":514 * raise StopIteration * item = <_Pair>self._items[self._current] * self._current += 1 # <<<<<<<<<<<<<< * return (item._key, item._value) * */ __pyx_v_self->_current = (__pyx_v_self->_current + 1); /* "aiohttp/_multidict.pyx":515 * item = <_Pair>self._items[self._current] * self._current += 1 * return (item._key, item._value) # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_INCREF(__pyx_v_item->_key); __Pyx_GIVEREF(__pyx_v_item->_key); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_item->_key); __Pyx_INCREF(__pyx_v_item->_value); __Pyx_GIVEREF(__pyx_v_item->_value); PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_item->_value); __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":510 * return self * * def __next__(self): # <<<<<<<<<<<<<< * if self._current == self._len: * raise StopIteration */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._ItemsIter.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":520 * cdef class _ItemsView(_ViewBaseSet): * * def isdisjoint(self, other): # <<<<<<<<<<<<<< * 'Return True if two sets have a null intersection.' * cdef _Pair item */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_10_ItemsView_1isdisjoint(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_10_ItemsView_isdisjoint[] = "Return True if two sets have a null intersection."; static PyObject *__pyx_pw_7aiohttp_10_multidict_10_ItemsView_1isdisjoint(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("isdisjoint (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_10_ItemsView_isdisjoint(((struct __pyx_obj_7aiohttp_10_multidict__ItemsView *)__pyx_v_self), ((PyObject *)__pyx_v_other)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_10_ItemsView_isdisjoint(struct __pyx_obj_7aiohttp_10_multidict__ItemsView *__pyx_v_self, PyObject *__pyx_v_other) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_i = NULL; PyObject *__pyx_v_t = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; int __pyx_t_5; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("isdisjoint", 0); /* "aiohttp/_multidict.pyx":523 * 'Return True if two sets have a null intersection.' * cdef _Pair item * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * t = (item._key, item._value) */ if (unlikely(__pyx_v_self->__pyx_base.__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base._items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":524 * cdef _Pair item * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * t = (item._key, item._value) * if t in other: */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":525 * for i in self._items: * item = <_Pair>i * t = (item._key, item._value) # <<<<<<<<<<<<<< * if t in other: * return False */ __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_INCREF(__pyx_v_item->_key); __Pyx_GIVEREF(__pyx_v_item->_key); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_item->_key); __Pyx_INCREF(__pyx_v_item->_value); __Pyx_GIVEREF(__pyx_v_item->_value); PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_item->_value); __Pyx_XDECREF_SET(__pyx_v_t, ((PyObject*)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":526 * item = <_Pair>i * t = (item._key, item._value) * if t in other: # <<<<<<<<<<<<<< * return False * return True */ __pyx_t_4 = (__Pyx_PySequence_ContainsTF(__pyx_v_t, __pyx_v_other, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_5 = (__pyx_t_4 != 0); if (__pyx_t_5) { /* "aiohttp/_multidict.pyx":527 * t = (item._key, item._value) * if t in other: * return False # <<<<<<<<<<<<<< * return True * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":526 * item = <_Pair>i * t = (item._key, item._value) * if t in other: # <<<<<<<<<<<<<< * return False * return True */ } /* "aiohttp/_multidict.pyx":523 * 'Return True if two sets have a null intersection.' * cdef _Pair item * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * t = (item._key, item._value) */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":528 * if t in other: * return False * return True # <<<<<<<<<<<<<< * * def __contains__(self, i): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_True); __pyx_r = Py_True; goto __pyx_L0; /* "aiohttp/_multidict.pyx":520 * cdef class _ItemsView(_ViewBaseSet): * * def isdisjoint(self, other): # <<<<<<<<<<<<<< * 'Return True if two sets have a null intersection.' * cdef _Pair item */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._ItemsView.isdisjoint", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_i); __Pyx_XDECREF(__pyx_v_t); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":530 * return True * * def __contains__(self, i): # <<<<<<<<<<<<<< * cdef _Pair item * assert isinstance(i, tuple) or isinstance(i, list) */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_10_ItemsView_3__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_i); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_10_ItemsView_3__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_i) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_10_ItemsView_2__contains__(((struct __pyx_obj_7aiohttp_10_multidict__ItemsView *)__pyx_v_self), ((PyObject *)__pyx_v_i)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_10_ItemsView_2__contains__(struct __pyx_obj_7aiohttp_10_multidict__ItemsView *__pyx_v_self, PyObject *__pyx_v_i) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; int __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; int __pyx_t_3; Py_ssize_t __pyx_t_4; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__contains__", 0); /* "aiohttp/_multidict.pyx":532 * def __contains__(self, i): * cdef _Pair item * assert isinstance(i, tuple) or isinstance(i, list) # <<<<<<<<<<<<<< * assert len(i) == 2 * item = _Pair.__new__(_Pair, i[0], i[1]) */ #ifndef CYTHON_WITHOUT_ASSERTIONS if (unlikely(!Py_OptimizeFlag)) { __pyx_t_2 = PyTuple_Check(__pyx_v_i); __pyx_t_3 = (__pyx_t_2 != 0); if (!__pyx_t_3) { } else { __pyx_t_1 = __pyx_t_3; goto __pyx_L3_bool_binop_done; } __pyx_t_3 = PyList_Check(__pyx_v_i); __pyx_t_2 = (__pyx_t_3 != 0); __pyx_t_1 = __pyx_t_2; __pyx_L3_bool_binop_done:; if (unlikely(!__pyx_t_1)) { PyErr_SetNone(PyExc_AssertionError); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 532; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } } #endif /* "aiohttp/_multidict.pyx":533 * cdef _Pair item * assert isinstance(i, tuple) or isinstance(i, list) * assert len(i) == 2 # <<<<<<<<<<<<<< * item = _Pair.__new__(_Pair, i[0], i[1]) * return item in self._items */ #ifndef CYTHON_WITHOUT_ASSERTIONS if (unlikely(!Py_OptimizeFlag)) { __pyx_t_4 = PyObject_Length(__pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (unlikely(!((__pyx_t_4 == 2) != 0))) { PyErr_SetNone(PyExc_AssertionError); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } } #endif /* "aiohttp/_multidict.pyx":534 * assert isinstance(i, tuple) or isinstance(i, list) * assert len(i) == 2 * item = _Pair.__new__(_Pair, i[0], i[1]) # <<<<<<<<<<<<<< * return item in self._items * */ __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_i, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_5); __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_i, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_6); __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_6); __pyx_t_5 = 0; __pyx_t_6 = 0; __pyx_t_6 = __pyx_tp_new_7aiohttp_10_multidict__Pair(((PyTypeObject *)__pyx_ptype_7aiohttp_10_multidict__Pair), __pyx_t_7, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; if (!(likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_7aiohttp_10_multidict__Pair)))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_v_item = ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_6); __pyx_t_6 = 0; /* "aiohttp/_multidict.pyx":535 * assert len(i) == 2 * item = _Pair.__new__(_Pair, i[0], i[1]) * return item in self._items # <<<<<<<<<<<<<< * * def __iter__(self): */ __pyx_t_1 = (__Pyx_PySequence_ContainsTF(((PyObject *)__pyx_v_item), __pyx_v_self->__pyx_base.__pyx_base._items, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 535; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = __pyx_t_1; goto __pyx_L0; /* "aiohttp/_multidict.pyx":530 * return True * * def __contains__(self, i): # <<<<<<<<<<<<<< * cdef _Pair item * assert isinstance(i, tuple) or isinstance(i, list) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); __Pyx_AddTraceback("aiohttp._multidict._ItemsView.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":537 * return item in self._items * * def __iter__(self): # <<<<<<<<<<<<<< * return _ItemsIter.__new__(_ItemsIter, self._items) * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_10_ItemsView_5__iter__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_10_ItemsView_5__iter__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_10_ItemsView_4__iter__(((struct __pyx_obj_7aiohttp_10_multidict__ItemsView *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_10_ItemsView_4__iter__(struct __pyx_obj_7aiohttp_10_multidict__ItemsView *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__iter__", 0); /* "aiohttp/_multidict.pyx":538 * * def __iter__(self): * return _ItemsIter.__new__(_ItemsIter, self._items) # <<<<<<<<<<<<<< * * def __repr__(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_self->__pyx_base.__pyx_base._items); __Pyx_GIVEREF(__pyx_v_self->__pyx_base.__pyx_base._items); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->__pyx_base.__pyx_base._items); __pyx_t_2 = __pyx_tp_new_7aiohttp_10_multidict__ItemsIter(((PyTypeObject *)__pyx_ptype_7aiohttp_10_multidict__ItemsIter), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":537 * return item in self._items * * def __iter__(self): # <<<<<<<<<<<<<< * return _ItemsIter.__new__(_ItemsIter, self._items) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict._ItemsView.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":540 * return _ItemsIter.__new__(_ItemsIter, self._items) * * def __repr__(self): # <<<<<<<<<<<<<< * cdef _Pair item * lst = [] */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_10_ItemsView_7__repr__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_10_ItemsView_7__repr__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_10_ItemsView_6__repr__(((struct __pyx_obj_7aiohttp_10_multidict__ItemsView *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_10_ItemsView_6__repr__(struct __pyx_obj_7aiohttp_10_multidict__ItemsView *__pyx_v_self) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_lst = NULL; PyObject *__pyx_v_i = NULL; PyObject *__pyx_v_body = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; Py_ssize_t __pyx_t_6; PyObject *__pyx_t_7 = NULL; int __pyx_t_8; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__repr__", 0); /* "aiohttp/_multidict.pyx":542 * def __repr__(self): * cdef _Pair item * lst = [] # <<<<<<<<<<<<<< * for i in self._items: * item = <_Pair>i */ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_lst = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":543 * cdef _Pair item * lst = [] * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * lst.append("{!r}: {!r}".format(item._key, item._value)) */ if (unlikely(__pyx_v_self->__pyx_base.__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 543; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base._items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 543; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 543; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":544 * lst = [] * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * lst.append("{!r}: {!r}".format(item._key, item._value)) * body = ', '.join(lst) */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":545 * for i in self._items: * item = <_Pair>i * lst.append("{!r}: {!r}".format(item._key, item._value)) # <<<<<<<<<<<<<< * body = ', '.join(lst) * return '{}({})'.format(self.__class__.__name__, body) */ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_r_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 545; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; __pyx_t_6 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(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_6 = 1; } } __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 545; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); if (__pyx_t_5) { __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL; } __Pyx_INCREF(__pyx_v_item->_key); __Pyx_GIVEREF(__pyx_v_item->_key); PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_v_item->_key); __Pyx_INCREF(__pyx_v_item->_value); __Pyx_GIVEREF(__pyx_v_item->_value); PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_v_item->_value); __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 545; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_8 = __Pyx_PyList_Append(__pyx_v_lst, __pyx_t_3); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 545; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":543 * cdef _Pair item * lst = [] * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * lst.append("{!r}: {!r}".format(item._key, item._value)) */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":546 * item = <_Pair>i * lst.append("{!r}: {!r}".format(item._key, item._value)) * body = ', '.join(lst) # <<<<<<<<<<<<<< * return '{}({})'.format(self.__class__.__name__, body) * */ __pyx_t_1 = __Pyx_PyString_Join(__pyx_kp_s__4, __pyx_v_lst); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_body = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":547 * lst.append("{!r}: {!r}".format(item._key, item._value)) * body = ', '.join(lst) * return '{}({})'.format(self.__class__.__name__, body) # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s__8, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = NULL; __pyx_t_2 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) { __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_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); __pyx_t_2 = 1; } } __pyx_t_5 = PyTuple_New(2+__pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); if (__pyx_t_4) { __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL; } __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_v_body); __Pyx_GIVEREF(__pyx_v_body); PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_2, __pyx_v_body); __pyx_t_7 = 0; __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":540 * return _ItemsIter.__new__(_ItemsIter, self._items) * * def __repr__(self): # <<<<<<<<<<<<<< * cdef _Pair item * lst = [] */ /* function exit code */ __pyx_L1_error:; __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._multidict._ItemsView.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_lst); __Pyx_XDECREF(__pyx_v_i); __Pyx_XDECREF(__pyx_v_body); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":558 * cdef int _len * * def __cinit__(self, items): # <<<<<<<<<<<<<< * self._items = items * self._current = 0 */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_11_ValuesIter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_11_ValuesIter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_items = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_items,0}; PyObject* values[1] = {0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_items)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 558; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); } __pyx_v_items = values[0]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 558; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._ValuesIter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_11_ValuesIter___cinit__(((struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *)__pyx_v_self), __pyx_v_items); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_11_ValuesIter___cinit__(struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *__pyx_v_self, PyObject *__pyx_v_items) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__cinit__", 0); /* "aiohttp/_multidict.pyx":559 * * def __cinit__(self, items): * self._items = items # <<<<<<<<<<<<<< * self._current = 0 * self._len = len(self._items) */ if (!(likely(PyList_CheckExact(__pyx_v_items))||((__pyx_v_items) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_v_items)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 559; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_1 = __pyx_v_items; __Pyx_INCREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v_self->_items); __Pyx_DECREF(__pyx_v_self->_items); __pyx_v_self->_items = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":560 * def __cinit__(self, items): * self._items = items * self._current = 0 # <<<<<<<<<<<<<< * self._len = len(self._items) * */ __pyx_v_self->_current = 0; /* "aiohttp/_multidict.pyx":561 * self._items = items * self._current = 0 * self._len = len(self._items) # <<<<<<<<<<<<<< * * def __iter__(self): */ __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); if (unlikely(__pyx_t_1 == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = PyList_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_self->_len = __pyx_t_2; /* "aiohttp/_multidict.pyx":558 * cdef int _len * * def __cinit__(self, items): # <<<<<<<<<<<<<< * self._items = items * self._current = 0 */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("aiohttp._multidict._ValuesIter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":563 * self._len = len(self._items) * * def __iter__(self): # <<<<<<<<<<<<<< * return self * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_11_ValuesIter_3__iter__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_11_ValuesIter_3__iter__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_11_ValuesIter_2__iter__(((struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_11_ValuesIter_2__iter__(struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__iter__", 0); /* "aiohttp/_multidict.pyx":564 * * def __iter__(self): * return self # <<<<<<<<<<<<<< * * def __next__(self): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_self)); __pyx_r = ((PyObject *)__pyx_v_self); goto __pyx_L0; /* "aiohttp/_multidict.pyx":563 * self._len = len(self._items) * * def __iter__(self): # <<<<<<<<<<<<<< * return self * */ /* function exit code */ __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":566 * return self * * def __next__(self): # <<<<<<<<<<<<<< * if self._current == self._len: * raise StopIteration */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_11_ValuesIter_5__next__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_11_ValuesIter_5__next__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__next__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_11_ValuesIter_4__next__(((struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_11_ValuesIter_4__next__(struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *__pyx_v_self) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__next__", 0); /* "aiohttp/_multidict.pyx":567 * * def __next__(self): * if self._current == self._len: # <<<<<<<<<<<<<< * raise StopIteration * item = <_Pair>self._items[self._current] */ __pyx_t_1 = ((__pyx_v_self->_current == __pyx_v_self->_len) != 0); if (__pyx_t_1) { /* "aiohttp/_multidict.pyx":568 * def __next__(self): * if self._current == self._len: * raise StopIteration # <<<<<<<<<<<<<< * item = <_Pair>self._items[self._current] * self._current += 1 */ __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":567 * * def __next__(self): * if self._current == self._len: # <<<<<<<<<<<<<< * raise StopIteration * item = <_Pair>self._items[self._current] */ } /* "aiohttp/_multidict.pyx":569 * if self._current == self._len: * raise StopIteration * item = <_Pair>self._items[self._current] # <<<<<<<<<<<<<< * self._current += 1 * return item._value */ if (unlikely(__pyx_v_self->_items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = __Pyx_GetItemInt_List(__pyx_v_self->_items, __pyx_v_self->_current, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __pyx_t_2; __Pyx_INCREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_item = ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":570 * raise StopIteration * item = <_Pair>self._items[self._current] * self._current += 1 # <<<<<<<<<<<<<< * return item._value * */ __pyx_v_self->_current = (__pyx_v_self->_current + 1); /* "aiohttp/_multidict.pyx":571 * item = <_Pair>self._items[self._current] * self._current += 1 * return item._value # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_item->_value); __pyx_r = __pyx_v_item->_value; goto __pyx_L0; /* "aiohttp/_multidict.pyx":566 * return self * * def __next__(self): # <<<<<<<<<<<<<< * if self._current == self._len: * raise StopIteration */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._ValuesIter.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":576 * cdef class _ValuesView(_ViewBase): * * def __contains__(self, value): # <<<<<<<<<<<<<< * cdef _Pair item * for i in self._items: */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_11_ValuesView_1__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_11_ValuesView_1__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_11_ValuesView___contains__(((struct __pyx_obj_7aiohttp_10_multidict__ValuesView *)__pyx_v_self), ((PyObject *)__pyx_v_value)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_11_ValuesView___contains__(struct __pyx_obj_7aiohttp_10_multidict__ValuesView *__pyx_v_self, PyObject *__pyx_v_value) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_i = NULL; int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__contains__", 0); /* "aiohttp/_multidict.pyx":578 * def __contains__(self, value): * cdef _Pair item * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._value == value: */ if (unlikely(__pyx_v_self->__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 578; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->__pyx_base._items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 578; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 578; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":579 * cdef _Pair item * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * if item._value == value: * return True */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":580 * for i in self._items: * item = <_Pair>i * if item._value == value: # <<<<<<<<<<<<<< * return True * return False */ __pyx_t_3 = PyObject_RichCompare(__pyx_v_item->_value, __pyx_v_value, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 580; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 580; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":581 * item = <_Pair>i * if item._value == value: * return True # <<<<<<<<<<<<<< * return False * */ __pyx_r = 1; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":580 * for i in self._items: * item = <_Pair>i * if item._value == value: # <<<<<<<<<<<<<< * return True * return False */ } /* "aiohttp/_multidict.pyx":578 * def __contains__(self, value): * cdef _Pair item * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._value == value: */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":582 * if item._value == value: * return True * return False # <<<<<<<<<<<<<< * * def __iter__(self): */ __pyx_r = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":576 * cdef class _ValuesView(_ViewBase): * * def __contains__(self, value): # <<<<<<<<<<<<<< * cdef _Pair item * for i in self._items: */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._ValuesView.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_i); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":584 * return False * * def __iter__(self): # <<<<<<<<<<<<<< * return _ValuesIter.__new__(_ValuesIter, self._items) * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_11_ValuesView_3__iter__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_11_ValuesView_3__iter__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_11_ValuesView_2__iter__(((struct __pyx_obj_7aiohttp_10_multidict__ValuesView *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_11_ValuesView_2__iter__(struct __pyx_obj_7aiohttp_10_multidict__ValuesView *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__iter__", 0); /* "aiohttp/_multidict.pyx":585 * * def __iter__(self): * return _ValuesIter.__new__(_ValuesIter, self._items) # <<<<<<<<<<<<<< * * def __repr__(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_self->__pyx_base._items); __Pyx_GIVEREF(__pyx_v_self->__pyx_base._items); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->__pyx_base._items); __pyx_t_2 = __pyx_tp_new_7aiohttp_10_multidict__ValuesIter(((PyTypeObject *)__pyx_ptype_7aiohttp_10_multidict__ValuesIter), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":584 * return False * * def __iter__(self): # <<<<<<<<<<<<<< * return _ValuesIter.__new__(_ValuesIter, self._items) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict._ValuesView.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":587 * return _ValuesIter.__new__(_ValuesIter, self._items) * * def __repr__(self): # <<<<<<<<<<<<<< * cdef _Pair item * lst = [] */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_11_ValuesView_5__repr__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_11_ValuesView_5__repr__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_11_ValuesView_4__repr__(((struct __pyx_obj_7aiohttp_10_multidict__ValuesView *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_11_ValuesView_4__repr__(struct __pyx_obj_7aiohttp_10_multidict__ValuesView *__pyx_v_self) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_lst = NULL; PyObject *__pyx_v_i = NULL; PyObject *__pyx_v_body = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; 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_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__repr__", 0); /* "aiohttp/_multidict.pyx":589 * def __repr__(self): * cdef _Pair item * lst = [] # <<<<<<<<<<<<<< * for i in self._items: * item = <_Pair>i */ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 589; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_lst = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":590 * cdef _Pair item * lst = [] * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * lst.append("{!r}".format(item._value)) */ if (unlikely(__pyx_v_self->__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 590; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->__pyx_base._items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 590; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 590; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":591 * lst = [] * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * lst.append("{!r}".format(item._value)) * body = ', '.join(lst) */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":592 * for i in self._items: * item = <_Pair>i * lst.append("{!r}".format(item._value)) # <<<<<<<<<<<<<< * body = ', '.join(lst) * return '{}({})'.format(self.__class__.__name__, body) */ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_r_2, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(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); } } if (!__pyx_t_5) { __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_item->_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); } else { __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __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_item->_value); __Pyx_GIVEREF(__pyx_v_item->_value); PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_item->_value); __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_7 = __Pyx_PyList_Append(__pyx_v_lst, __pyx_t_3); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":590 * cdef _Pair item * lst = [] * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * lst.append("{!r}".format(item._value)) */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":593 * item = <_Pair>i * lst.append("{!r}".format(item._value)) * body = ', '.join(lst) # <<<<<<<<<<<<<< * return '{}({})'.format(self.__class__.__name__, body) * */ __pyx_t_1 = __Pyx_PyString_Join(__pyx_kp_s__4, __pyx_v_lst); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 593; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_body = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":594 * lst.append("{!r}".format(item._value)) * body = ', '.join(lst) * return '{}({})'.format(self.__class__.__name__, body) # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s__8, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = NULL; __pyx_t_2 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) { __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_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); __pyx_t_2 = 1; } } __pyx_t_5 = PyTuple_New(2+__pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); if (__pyx_t_4) { __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL; } __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_v_body); __Pyx_GIVEREF(__pyx_v_body); PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_2, __pyx_v_body); __pyx_t_6 = 0; __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":587 * return _ValuesIter.__new__(_ValuesIter, self._items) * * def __repr__(self): # <<<<<<<<<<<<<< * cdef _Pair item * lst = [] */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._multidict._ValuesView.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_lst); __Pyx_XDECREF(__pyx_v_i); __Pyx_XDECREF(__pyx_v_body); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":605 * cdef int _len * * def __cinit__(self, items): # <<<<<<<<<<<<<< * self._items = items * self._current = 0 */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_9_KeysIter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_9_KeysIter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_items = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_items,0}; PyObject* values[1] = {0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_items)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); } __pyx_v_items = values[0]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("aiohttp._multidict._KeysIter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_7aiohttp_10_multidict_9_KeysIter___cinit__(((struct __pyx_obj_7aiohttp_10_multidict__KeysIter *)__pyx_v_self), __pyx_v_items); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_9_KeysIter___cinit__(struct __pyx_obj_7aiohttp_10_multidict__KeysIter *__pyx_v_self, PyObject *__pyx_v_items) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__cinit__", 0); /* "aiohttp/_multidict.pyx":606 * * def __cinit__(self, items): * self._items = items # <<<<<<<<<<<<<< * self._current = 0 * self._len = len(self._items) */ if (!(likely(PyList_CheckExact(__pyx_v_items))||((__pyx_v_items) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_v_items)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 606; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_1 = __pyx_v_items; __Pyx_INCREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v_self->_items); __Pyx_DECREF(__pyx_v_self->_items); __pyx_v_self->_items = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":607 * def __cinit__(self, items): * self._items = items * self._current = 0 # <<<<<<<<<<<<<< * self._len = len(self._items) * */ __pyx_v_self->_current = 0; /* "aiohttp/_multidict.pyx":608 * self._items = items * self._current = 0 * self._len = len(self._items) # <<<<<<<<<<<<<< * * def __iter__(self): */ __pyx_t_1 = __pyx_v_self->_items; __Pyx_INCREF(__pyx_t_1); if (unlikely(__pyx_t_1 == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 608; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = PyList_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 608; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_self->_len = __pyx_t_2; /* "aiohttp/_multidict.pyx":605 * cdef int _len * * def __cinit__(self, items): # <<<<<<<<<<<<<< * self._items = items * self._current = 0 */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("aiohttp._multidict._KeysIter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":610 * self._len = len(self._items) * * def __iter__(self): # <<<<<<<<<<<<<< * return self * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9_KeysIter_3__iter__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_9_KeysIter_3__iter__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9_KeysIter_2__iter__(((struct __pyx_obj_7aiohttp_10_multidict__KeysIter *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9_KeysIter_2__iter__(struct __pyx_obj_7aiohttp_10_multidict__KeysIter *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__iter__", 0); /* "aiohttp/_multidict.pyx":611 * * def __iter__(self): * return self # <<<<<<<<<<<<<< * * def __next__(self): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_self)); __pyx_r = ((PyObject *)__pyx_v_self); goto __pyx_L0; /* "aiohttp/_multidict.pyx":610 * self._len = len(self._items) * * def __iter__(self): # <<<<<<<<<<<<<< * return self * */ /* function exit code */ __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":613 * return self * * def __next__(self): # <<<<<<<<<<<<<< * if self._current == self._len: * raise StopIteration */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9_KeysIter_5__next__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_9_KeysIter_5__next__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__next__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9_KeysIter_4__next__(((struct __pyx_obj_7aiohttp_10_multidict__KeysIter *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9_KeysIter_4__next__(struct __pyx_obj_7aiohttp_10_multidict__KeysIter *__pyx_v_self) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__next__", 0); /* "aiohttp/_multidict.pyx":614 * * def __next__(self): * if self._current == self._len: # <<<<<<<<<<<<<< * raise StopIteration * item = <_Pair>self._items[self._current] */ __pyx_t_1 = ((__pyx_v_self->_current == __pyx_v_self->_len) != 0); if (__pyx_t_1) { /* "aiohttp/_multidict.pyx":615 * def __next__(self): * if self._current == self._len: * raise StopIteration # <<<<<<<<<<<<<< * item = <_Pair>self._items[self._current] * self._current += 1 */ __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":614 * * def __next__(self): * if self._current == self._len: # <<<<<<<<<<<<<< * raise StopIteration * item = <_Pair>self._items[self._current] */ } /* "aiohttp/_multidict.pyx":616 * if self._current == self._len: * raise StopIteration * item = <_Pair>self._items[self._current] # <<<<<<<<<<<<<< * self._current += 1 * return item._key */ if (unlikely(__pyx_v_self->_items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_2 = __Pyx_GetItemInt_List(__pyx_v_self->_items, __pyx_v_self->_current, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __pyx_t_2; __Pyx_INCREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_item = ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":617 * raise StopIteration * item = <_Pair>self._items[self._current] * self._current += 1 # <<<<<<<<<<<<<< * return item._key * */ __pyx_v_self->_current = (__pyx_v_self->_current + 1); /* "aiohttp/_multidict.pyx":618 * item = <_Pair>self._items[self._current] * self._current += 1 * return item._key # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_item->_key); __pyx_r = __pyx_v_item->_key; goto __pyx_L0; /* "aiohttp/_multidict.pyx":613 * return self * * def __next__(self): # <<<<<<<<<<<<<< * if self._current == self._len: * raise StopIteration */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._KeysIter.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":623 * cdef class _KeysView(_ViewBaseSet): * * def isdisjoint(self, other): # <<<<<<<<<<<<<< * 'Return True if two sets have a null intersection.' * cdef _Pair item */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9_KeysView_1isdisjoint(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/ static char __pyx_doc_7aiohttp_10_multidict_9_KeysView_isdisjoint[] = "Return True if two sets have a null intersection."; static PyObject *__pyx_pw_7aiohttp_10_multidict_9_KeysView_1isdisjoint(PyObject *__pyx_v_self, PyObject *__pyx_v_other) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("isdisjoint (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9_KeysView_isdisjoint(((struct __pyx_obj_7aiohttp_10_multidict__KeysView *)__pyx_v_self), ((PyObject *)__pyx_v_other)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9_KeysView_isdisjoint(struct __pyx_obj_7aiohttp_10_multidict__KeysView *__pyx_v_self, PyObject *__pyx_v_other) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_i = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; int __pyx_t_5; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("isdisjoint", 0); /* "aiohttp/_multidict.pyx":626 * 'Return True if two sets have a null intersection.' * cdef _Pair item * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key in other: */ if (unlikely(__pyx_v_self->__pyx_base.__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 626; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base._items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 626; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 626; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":627 * cdef _Pair item * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * if item._key in other: * return False */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":628 * for i in self._items: * item = <_Pair>i * if item._key in other: # <<<<<<<<<<<<<< * return False * return True */ __pyx_t_4 = (__Pyx_PySequence_ContainsTF(__pyx_v_item->_key, __pyx_v_other, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_5 = (__pyx_t_4 != 0); if (__pyx_t_5) { /* "aiohttp/_multidict.pyx":629 * item = <_Pair>i * if item._key in other: * return False # <<<<<<<<<<<<<< * return True * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":628 * for i in self._items: * item = <_Pair>i * if item._key in other: # <<<<<<<<<<<<<< * return False * return True */ } /* "aiohttp/_multidict.pyx":626 * 'Return True if two sets have a null intersection.' * cdef _Pair item * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key in other: */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":630 * if item._key in other: * return False * return True # <<<<<<<<<<<<<< * * def __contains__(self, value): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_True); __pyx_r = Py_True; goto __pyx_L0; /* "aiohttp/_multidict.pyx":623 * cdef class _KeysView(_ViewBaseSet): * * def isdisjoint(self, other): # <<<<<<<<<<<<<< * 'Return True if two sets have a null intersection.' * cdef _Pair item */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._KeysView.isdisjoint", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_i); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":632 * return True * * def __contains__(self, value): # <<<<<<<<<<<<<< * cdef _Pair item * for i in self._items: */ /* Python wrapper */ static int __pyx_pw_7aiohttp_10_multidict_9_KeysView_3__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/ static int __pyx_pw_7aiohttp_10_multidict_9_KeysView_3__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9_KeysView_2__contains__(((struct __pyx_obj_7aiohttp_10_multidict__KeysView *)__pyx_v_self), ((PyObject *)__pyx_v_value)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_7aiohttp_10_multidict_9_KeysView_2__contains__(struct __pyx_obj_7aiohttp_10_multidict__KeysView *__pyx_v_self, PyObject *__pyx_v_value) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_i = NULL; int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__contains__", 0); /* "aiohttp/_multidict.pyx":634 * def __contains__(self, value): * cdef _Pair item * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key == value: */ if (unlikely(__pyx_v_self->__pyx_base.__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 634; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base._items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 634; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 634; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":635 * cdef _Pair item * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * if item._key == value: * return True */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":636 * for i in self._items: * item = <_Pair>i * if item._key == value: # <<<<<<<<<<<<<< * return True * return False */ __pyx_t_3 = PyObject_RichCompare(__pyx_v_item->_key, __pyx_v_value, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_4) { /* "aiohttp/_multidict.pyx":637 * item = <_Pair>i * if item._key == value: * return True # <<<<<<<<<<<<<< * return False * */ __pyx_r = 1; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":636 * for i in self._items: * item = <_Pair>i * if item._key == value: # <<<<<<<<<<<<<< * return True * return False */ } /* "aiohttp/_multidict.pyx":634 * def __contains__(self, value): * cdef _Pair item * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * if item._key == value: */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":638 * if item._key == value: * return True * return False # <<<<<<<<<<<<<< * * def __iter__(self): */ __pyx_r = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":632 * return True * * def __contains__(self, value): # <<<<<<<<<<<<<< * cdef _Pair item * for i in self._items: */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("aiohttp._multidict._KeysView.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_i); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":640 * return False * * def __iter__(self): # <<<<<<<<<<<<<< * return _KeysIter.__new__(_KeysIter, self._items) * */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9_KeysView_5__iter__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_9_KeysView_5__iter__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9_KeysView_4__iter__(((struct __pyx_obj_7aiohttp_10_multidict__KeysView *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9_KeysView_4__iter__(struct __pyx_obj_7aiohttp_10_multidict__KeysView *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__iter__", 0); /* "aiohttp/_multidict.pyx":641 * * def __iter__(self): * return _KeysIter.__new__(_KeysIter, self._items) # <<<<<<<<<<<<<< * * def __repr__(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_self->__pyx_base.__pyx_base._items); __Pyx_GIVEREF(__pyx_v_self->__pyx_base.__pyx_base._items); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->__pyx_base.__pyx_base._items); __pyx_t_2 = __pyx_tp_new_7aiohttp_10_multidict__KeysIter(((PyTypeObject *)__pyx_ptype_7aiohttp_10_multidict__KeysIter), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":640 * return False * * def __iter__(self): # <<<<<<<<<<<<<< * return _KeysIter.__new__(_KeysIter, self._items) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("aiohttp._multidict._KeysView.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "aiohttp/_multidict.pyx":643 * return _KeysIter.__new__(_KeysIter, self._items) * * def __repr__(self): # <<<<<<<<<<<<<< * cdef _Pair item * lst = [] */ /* Python wrapper */ static PyObject *__pyx_pw_7aiohttp_10_multidict_9_KeysView_7__repr__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_7aiohttp_10_multidict_9_KeysView_7__repr__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); __pyx_r = __pyx_pf_7aiohttp_10_multidict_9_KeysView_6__repr__(((struct __pyx_obj_7aiohttp_10_multidict__KeysView *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_7aiohttp_10_multidict_9_KeysView_6__repr__(struct __pyx_obj_7aiohttp_10_multidict__KeysView *__pyx_v_self) { struct __pyx_obj_7aiohttp_10_multidict__Pair *__pyx_v_item = 0; PyObject *__pyx_v_lst = NULL; PyObject *__pyx_v_i = NULL; PyObject *__pyx_v_body = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; 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_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("__repr__", 0); /* "aiohttp/_multidict.pyx":645 * def __repr__(self): * cdef _Pair item * lst = [] # <<<<<<<<<<<<<< * for i in self._items: * item = <_Pair>i */ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_lst = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":646 * cdef _Pair item * lst = [] * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * lst.append("{!r}".format(item._key)) */ if (unlikely(__pyx_v_self->__pyx_base.__pyx_base._items == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base._items; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":647 * lst = [] * for i in self._items: * item = <_Pair>i # <<<<<<<<<<<<<< * lst.append("{!r}".format(item._key)) * body = ', '.join(lst) */ __pyx_t_3 = __pyx_v_i; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_item, ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)__pyx_t_3)); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":648 * for i in self._items: * item = <_Pair>i * lst.append("{!r}".format(item._key)) # <<<<<<<<<<<<<< * body = ', '.join(lst) * return '{}({})'.format(self.__class__.__name__, body) */ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_r_2, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(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); } } if (!__pyx_t_5) { __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_item->_key); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); } else { __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __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_item->_key); __Pyx_GIVEREF(__pyx_v_item->_key); PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_item->_key); __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_7 = __Pyx_PyList_Append(__pyx_v_lst, __pyx_t_3); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "aiohttp/_multidict.pyx":646 * cdef _Pair item * lst = [] * for i in self._items: # <<<<<<<<<<<<<< * item = <_Pair>i * lst.append("{!r}".format(item._key)) */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":649 * item = <_Pair>i * lst.append("{!r}".format(item._key)) * body = ', '.join(lst) # <<<<<<<<<<<<<< * return '{}({})'.format(self.__class__.__name__, body) * */ __pyx_t_1 = __Pyx_PyString_Join(__pyx_kp_s__4, __pyx_v_lst); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 649; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_v_body = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":650 * lst.append("{!r}".format(item._key)) * body = ', '.join(lst) * return '{}({})'.format(self.__class__.__name__, body) # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s__8, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = NULL; __pyx_t_2 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) { __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_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); __pyx_t_2 = 1; } } __pyx_t_5 = PyTuple_New(2+__pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); if (__pyx_t_4) { __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL; } __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_v_body); __Pyx_GIVEREF(__pyx_v_body); PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_2, __pyx_v_body); __pyx_t_6 = 0; __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "aiohttp/_multidict.pyx":643 * return _KeysIter.__new__(_KeysIter, self._items) * * def __repr__(self): # <<<<<<<<<<<<<< * cdef _Pair item * lst = [] */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("aiohttp._multidict._KeysView.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_item); __Pyx_XDECREF(__pyx_v_lst); __Pyx_XDECREF(__pyx_v_i); __Pyx_XDECREF(__pyx_v_body); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_tp_new_7aiohttp_10_multidict__Pair(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_obj_7aiohttp_10_multidict__Pair *p; PyObject *o; if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { o = (*t->tp_alloc)(t, 0); } else { o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); } if (unlikely(!o)) return 0; p = ((struct __pyx_obj_7aiohttp_10_multidict__Pair *)o); p->_key = Py_None; Py_INCREF(Py_None); p->_value = Py_None; Py_INCREF(Py_None); if (unlikely(__pyx_pw_7aiohttp_10_multidict_5_Pair_1__cinit__(o, a, k) < 0)) { Py_DECREF(o); o = 0; } return o; } static void __pyx_tp_dealloc_7aiohttp_10_multidict__Pair(PyObject *o) { struct __pyx_obj_7aiohttp_10_multidict__Pair *p = (struct __pyx_obj_7aiohttp_10_multidict__Pair *)o; #if PY_VERSION_HEX >= 0x030400a1 if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { if (PyObject_CallFinalizerFromDealloc(o)) return; } #endif PyObject_GC_UnTrack(o); Py_CLEAR(p->_key); Py_CLEAR(p->_value); (*Py_TYPE(o)->tp_free)(o); } static int __pyx_tp_traverse_7aiohttp_10_multidict__Pair(PyObject *o, visitproc v, void *a) { int e; struct __pyx_obj_7aiohttp_10_multidict__Pair *p = (struct __pyx_obj_7aiohttp_10_multidict__Pair *)o; if (p->_key) { e = (*v)(p->_key, a); if (e) return e; } if (p->_value) { e = (*v)(p->_value, a); if (e) return e; } return 0; } static int __pyx_tp_clear_7aiohttp_10_multidict__Pair(PyObject *o) { PyObject* tmp; struct __pyx_obj_7aiohttp_10_multidict__Pair *p = (struct __pyx_obj_7aiohttp_10_multidict__Pair *)o; tmp = ((PyObject*)p->_key); p->_key = Py_None; Py_INCREF(Py_None); Py_XDECREF(tmp); tmp = ((PyObject*)p->_value); p->_value = Py_None; Py_INCREF(Py_None); Py_XDECREF(tmp); return 0; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict__Pair[] = { {0, 0, 0, 0} }; static PyTypeObject __pyx_type_7aiohttp_10_multidict__Pair = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict._Pair", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict__Pair), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__Pair, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__Pair, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__Pair, /*tp_clear*/ __pyx_pw_7aiohttp_10_multidict_5_Pair_3__richcmp__, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict__Pair, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict__Pair, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static struct __pyx_vtabstruct_7aiohttp_10_multidict__Base __pyx_vtable_7aiohttp_10_multidict__Base; static PyObject *__pyx_tp_new_7aiohttp_10_multidict__Base(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { struct __pyx_obj_7aiohttp_10_multidict__Base *p; PyObject *o; if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { o = (*t->tp_alloc)(t, 0); } else { o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); } if (unlikely(!o)) return 0; p = ((struct __pyx_obj_7aiohttp_10_multidict__Base *)o); p->__pyx_vtab = __pyx_vtabptr_7aiohttp_10_multidict__Base; p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); p->_upstr = Py_None; Py_INCREF(Py_None); p->marker = Py_None; Py_INCREF(Py_None); if (unlikely(__pyx_pw_7aiohttp_10_multidict_5_Base_1__cinit__(o, __pyx_empty_tuple, NULL) < 0)) { Py_DECREF(o); o = 0; } return o; } static void __pyx_tp_dealloc_7aiohttp_10_multidict__Base(PyObject *o) { struct __pyx_obj_7aiohttp_10_multidict__Base *p = (struct __pyx_obj_7aiohttp_10_multidict__Base *)o; #if PY_VERSION_HEX >= 0x030400a1 if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { if (PyObject_CallFinalizerFromDealloc(o)) return; } #endif PyObject_GC_UnTrack(o); Py_CLEAR(p->_items); Py_CLEAR(p->_upstr); Py_CLEAR(p->marker); (*Py_TYPE(o)->tp_free)(o); } static int __pyx_tp_traverse_7aiohttp_10_multidict__Base(PyObject *o, visitproc v, void *a) { int e; struct __pyx_obj_7aiohttp_10_multidict__Base *p = (struct __pyx_obj_7aiohttp_10_multidict__Base *)o; if (p->_items) { e = (*v)(p->_items, a); if (e) return e; } if (p->_upstr) { e = (*v)(p->_upstr, a); if (e) return e; } if (p->marker) { e = (*v)(p->marker, a); if (e) return e; } return 0; } static int __pyx_tp_clear_7aiohttp_10_multidict__Base(PyObject *o) { PyObject* tmp; struct __pyx_obj_7aiohttp_10_multidict__Base *p = (struct __pyx_obj_7aiohttp_10_multidict__Base *)o; tmp = ((PyObject*)p->_items); p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); Py_XDECREF(tmp); tmp = ((PyObject*)p->_upstr); p->_upstr = Py_None; Py_INCREF(Py_None); Py_XDECREF(tmp); tmp = ((PyObject*)p->marker); p->marker = Py_None; Py_INCREF(Py_None); Py_XDECREF(tmp); return 0; } static PyObject *__pyx_sq_item_7aiohttp_10_multidict__Base(PyObject *o, Py_ssize_t i) { PyObject *r; PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); Py_DECREF(x); return r; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict__Base[] = { {"getall", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_5_Base_3getall, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_multidict_5_Base_2getall}, {"getone", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_5_Base_5getone, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_multidict_5_Base_4getone}, {"get", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_5_Base_9get, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_multidict_5_Base_8get}, {"keys", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_5_Base_17keys, METH_NOARGS, __pyx_doc_7aiohttp_10_multidict_5_Base_16keys}, {"items", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_5_Base_19items, METH_NOARGS, __pyx_doc_7aiohttp_10_multidict_5_Base_18items}, {"values", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_5_Base_21values, METH_NOARGS, __pyx_doc_7aiohttp_10_multidict_5_Base_20values}, {0, 0, 0, 0} }; static PySequenceMethods __pyx_tp_as_sequence__Base = { __pyx_pw_7aiohttp_10_multidict_5_Base_15__len__, /*sq_length*/ 0, /*sq_concat*/ 0, /*sq_repeat*/ __pyx_sq_item_7aiohttp_10_multidict__Base, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ __pyx_pw_7aiohttp_10_multidict_5_Base_11__contains__, /*sq_contains*/ 0, /*sq_inplace_concat*/ 0, /*sq_inplace_repeat*/ }; static PyMappingMethods __pyx_tp_as_mapping__Base = { __pyx_pw_7aiohttp_10_multidict_5_Base_15__len__, /*mp_length*/ __pyx_pw_7aiohttp_10_multidict_5_Base_7__getitem__, /*mp_subscript*/ 0, /*mp_ass_subscript*/ }; static PyTypeObject __pyx_type_7aiohttp_10_multidict__Base = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict._Base", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict__Base), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__Base, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif __pyx_pw_7aiohttp_10_multidict_5_Base_23__repr__, /*tp_repr*/ 0, /*tp_as_number*/ &__pyx_tp_as_sequence__Base, /*tp_as_sequence*/ &__pyx_tp_as_mapping__Base, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__Base, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__Base, /*tp_clear*/ __pyx_pw_7aiohttp_10_multidict_5_Base_25__richcmp__, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ __pyx_pw_7aiohttp_10_multidict_5_Base_13__iter__, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict__Base, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict__Base, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDictProxy __pyx_vtable_7aiohttp_10_multidict_MultiDictProxy; static PyObject *__pyx_tp_new_7aiohttp_10_multidict_MultiDictProxy(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy *p; PyObject *o = __pyx_tp_new_7aiohttp_10_multidict__Base(t, a, k); if (unlikely(!o)) return 0; p = ((struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy *)o); p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_7aiohttp_10_multidict__Base*)__pyx_vtabptr_7aiohttp_10_multidict_MultiDictProxy; return o; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict_MultiDictProxy[] = { {"copy", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_14MultiDictProxy_3copy, METH_NOARGS, __pyx_doc_7aiohttp_10_multidict_14MultiDictProxy_2copy}, {0, 0, 0, 0} }; static PyTypeObject __pyx_type_7aiohttp_10_multidict_MultiDictProxy = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict.MultiDictProxy", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict_MultiDictProxy), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__Base, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_5_Base_23__repr__, /*tp_repr*/ #else 0, /*tp_repr*/ #endif 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__Base, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__Base, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_5_Base_13__iter__, /*tp_iter*/ #else 0, /*tp_iter*/ #endif 0, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict_MultiDictProxy, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ __pyx_pw_7aiohttp_10_multidict_14MultiDictProxy_1__init__, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict_MultiDictProxy, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static struct __pyx_vtabstruct_7aiohttp_10_multidict_CIMultiDictProxy __pyx_vtable_7aiohttp_10_multidict_CIMultiDictProxy; static PyObject *__pyx_tp_new_7aiohttp_10_multidict_CIMultiDictProxy(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy *p; PyObject *o = __pyx_tp_new_7aiohttp_10_multidict_MultiDictProxy(t, a, k); if (unlikely(!o)) return 0; p = ((struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy *)o); p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_7aiohttp_10_multidict__Base*)__pyx_vtabptr_7aiohttp_10_multidict_CIMultiDictProxy; return o; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict_CIMultiDictProxy[] = { {"copy", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_16CIMultiDictProxy_3copy, METH_NOARGS, __pyx_doc_7aiohttp_10_multidict_16CIMultiDictProxy_2copy}, {0, 0, 0, 0} }; static PyTypeObject __pyx_type_7aiohttp_10_multidict_CIMultiDictProxy = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict.CIMultiDictProxy", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict_CIMultiDictProxy), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__Base, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_5_Base_23__repr__, /*tp_repr*/ #else 0, /*tp_repr*/ #endif 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__Base, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__Base, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_5_Base_13__iter__, /*tp_iter*/ #else 0, /*tp_iter*/ #endif 0, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict_CIMultiDictProxy, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ __pyx_pw_7aiohttp_10_multidict_16CIMultiDictProxy_1__init__, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict_CIMultiDictProxy, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static struct __pyx_vtabstruct_7aiohttp_10_multidict_MultiDict __pyx_vtable_7aiohttp_10_multidict_MultiDict; static PyObject *__pyx_tp_new_7aiohttp_10_multidict_MultiDict(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_obj_7aiohttp_10_multidict_MultiDict *p; PyObject *o = __pyx_tp_new_7aiohttp_10_multidict__Base(t, a, k); if (unlikely(!o)) return 0; p = ((struct __pyx_obj_7aiohttp_10_multidict_MultiDict *)o); p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_7aiohttp_10_multidict__Base*)__pyx_vtabptr_7aiohttp_10_multidict_MultiDict; return o; } static int __pyx_mp_ass_subscript_7aiohttp_10_multidict_MultiDict(PyObject *o, PyObject *i, PyObject *v) { if (v) { return __pyx_pw_7aiohttp_10_multidict_9MultiDict_11__setitem__(o, i, v); } else { return __pyx_pw_7aiohttp_10_multidict_9MultiDict_13__delitem__(o, i); } } static PyMethodDef __pyx_methods_7aiohttp_10_multidict_MultiDict[] = { {"add", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_9MultiDict_3add, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_multidict_9MultiDict_2add}, {"copy", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_9MultiDict_5copy, METH_NOARGS, __pyx_doc_7aiohttp_10_multidict_9MultiDict_4copy}, {"extend", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_9MultiDict_7extend, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_multidict_9MultiDict_6extend}, {"clear", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_9MultiDict_9clear, METH_NOARGS, __pyx_doc_7aiohttp_10_multidict_9MultiDict_8clear}, {"setdefault", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_9MultiDict_15setdefault, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_multidict_9MultiDict_14setdefault}, {"pop", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_9MultiDict_17pop, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_multidict_9MultiDict_16pop}, {"popitem", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_9MultiDict_19popitem, METH_NOARGS, __pyx_doc_7aiohttp_10_multidict_9MultiDict_18popitem}, {"update", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_9MultiDict_21update, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_multidict_9MultiDict_20update}, {0, 0, 0, 0} }; static PyMappingMethods __pyx_tp_as_mapping_MultiDict = { #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_5_Base_15__len__, /*mp_length*/ #else 0, /*mp_length*/ #endif #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_5_Base_7__getitem__, /*mp_subscript*/ #else 0, /*mp_subscript*/ #endif __pyx_mp_ass_subscript_7aiohttp_10_multidict_MultiDict, /*mp_ass_subscript*/ }; static PyTypeObject __pyx_type_7aiohttp_10_multidict_MultiDict = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict.MultiDict", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict_MultiDict), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__Base, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_5_Base_23__repr__, /*tp_repr*/ #else 0, /*tp_repr*/ #endif 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ &__pyx_tp_as_mapping_MultiDict, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ "An ordered dictionary that can have multiple values for each key.", /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__Base, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__Base, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_5_Base_13__iter__, /*tp_iter*/ #else 0, /*tp_iter*/ #endif 0, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict_MultiDict, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ __pyx_pw_7aiohttp_10_multidict_9MultiDict_1__init__, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict_MultiDict, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static struct __pyx_vtabstruct_7aiohttp_10_multidict_CIMultiDict __pyx_vtable_7aiohttp_10_multidict_CIMultiDict; static PyObject *__pyx_tp_new_7aiohttp_10_multidict_CIMultiDict(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_obj_7aiohttp_10_multidict_CIMultiDict *p; PyObject *o = __pyx_tp_new_7aiohttp_10_multidict_MultiDict(t, a, k); if (unlikely(!o)) return 0; p = ((struct __pyx_obj_7aiohttp_10_multidict_CIMultiDict *)o); p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_7aiohttp_10_multidict__Base*)__pyx_vtabptr_7aiohttp_10_multidict_CIMultiDict; return o; } static PyTypeObject __pyx_type_7aiohttp_10_multidict_CIMultiDict = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict.CIMultiDict", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict_CIMultiDict), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__Base, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_5_Base_23__repr__, /*tp_repr*/ #else 0, /*tp_repr*/ #endif 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ "An ordered dictionary that can have multiple values for each key.", /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__Base, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__Base, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_5_Base_13__iter__, /*tp_iter*/ #else 0, /*tp_iter*/ #endif 0, /*tp_iternext*/ 0, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_9MultiDict_1__init__, /*tp_init*/ #else 0, /*tp_init*/ #endif 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict_CIMultiDict, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ViewBase(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_obj_7aiohttp_10_multidict__ViewBase *p; PyObject *o; if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { o = (*t->tp_alloc)(t, 0); } else { o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); } if (unlikely(!o)) return 0; p = ((struct __pyx_obj_7aiohttp_10_multidict__ViewBase *)o); p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); if (unlikely(__pyx_pw_7aiohttp_10_multidict_9_ViewBase_1__cinit__(o, a, k) < 0)) { Py_DECREF(o); o = 0; } return o; } static void __pyx_tp_dealloc_7aiohttp_10_multidict__ViewBase(PyObject *o) { struct __pyx_obj_7aiohttp_10_multidict__ViewBase *p = (struct __pyx_obj_7aiohttp_10_multidict__ViewBase *)o; #if PY_VERSION_HEX >= 0x030400a1 if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { if (PyObject_CallFinalizerFromDealloc(o)) return; } #endif PyObject_GC_UnTrack(o); Py_CLEAR(p->_items); (*Py_TYPE(o)->tp_free)(o); } static int __pyx_tp_traverse_7aiohttp_10_multidict__ViewBase(PyObject *o, visitproc v, void *a) { int e; struct __pyx_obj_7aiohttp_10_multidict__ViewBase *p = (struct __pyx_obj_7aiohttp_10_multidict__ViewBase *)o; if (p->_items) { e = (*v)(p->_items, a); if (e) return e; } return 0; } static int __pyx_tp_clear_7aiohttp_10_multidict__ViewBase(PyObject *o) { PyObject* tmp; struct __pyx_obj_7aiohttp_10_multidict__ViewBase *p = (struct __pyx_obj_7aiohttp_10_multidict__ViewBase *)o; tmp = ((PyObject*)p->_items); p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); Py_XDECREF(tmp); return 0; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict__ViewBase[] = { {0, 0, 0, 0} }; static PySequenceMethods __pyx_tp_as_sequence__ViewBase = { __pyx_pw_7aiohttp_10_multidict_9_ViewBase_3__len__, /*sq_length*/ 0, /*sq_concat*/ 0, /*sq_repeat*/ 0, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ 0, /*sq_contains*/ 0, /*sq_inplace_concat*/ 0, /*sq_inplace_repeat*/ }; static PyMappingMethods __pyx_tp_as_mapping__ViewBase = { __pyx_pw_7aiohttp_10_multidict_9_ViewBase_3__len__, /*mp_length*/ 0, /*mp_subscript*/ 0, /*mp_ass_subscript*/ }; static PyTypeObject __pyx_type_7aiohttp_10_multidict__ViewBase = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict._ViewBase", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict__ViewBase), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__ViewBase, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif 0, /*tp_repr*/ 0, /*tp_as_number*/ &__pyx_tp_as_sequence__ViewBase, /*tp_as_sequence*/ &__pyx_tp_as_mapping__ViewBase, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__ViewBase, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__ViewBase, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict__ViewBase, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict__ViewBase, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ViewBaseSet(PyTypeObject *t, PyObject *a, PyObject *k) { PyObject *o = __pyx_tp_new_7aiohttp_10_multidict__ViewBase(t, a, k); if (unlikely(!o)) return 0; return o; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict__ViewBaseSet[] = { {0, 0, 0, 0} }; static PyNumberMethods __pyx_tp_as_number__ViewBaseSet = { 0, /*nb_add*/ __pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_7__sub__, /*nb_subtract*/ 0, /*nb_multiply*/ #if PY_MAJOR_VERSION < 3 || CYTHON_COMPILING_IN_PYPY 0, /*nb_divide*/ #endif 0, /*nb_remainder*/ 0, /*nb_divmod*/ 0, /*nb_power*/ 0, /*nb_negative*/ 0, /*nb_positive*/ 0, /*nb_absolute*/ 0, /*nb_nonzero*/ 0, /*nb_invert*/ 0, /*nb_lshift*/ 0, /*nb_rshift*/ __pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_3__and__, /*nb_and*/ __pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_9__xor__, /*nb_xor*/ __pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_5__or__, /*nb_or*/ #if PY_MAJOR_VERSION < 3 || CYTHON_COMPILING_IN_PYPY 0, /*nb_coerce*/ #endif 0, /*nb_int*/ #if PY_MAJOR_VERSION < 3 0, /*nb_long*/ #else 0, /*reserved*/ #endif 0, /*nb_float*/ #if PY_MAJOR_VERSION < 3 || CYTHON_COMPILING_IN_PYPY 0, /*nb_oct*/ #endif #if PY_MAJOR_VERSION < 3 || CYTHON_COMPILING_IN_PYPY 0, /*nb_hex*/ #endif 0, /*nb_inplace_add*/ 0, /*nb_inplace_subtract*/ 0, /*nb_inplace_multiply*/ #if PY_MAJOR_VERSION < 3 || CYTHON_COMPILING_IN_PYPY 0, /*nb_inplace_divide*/ #endif 0, /*nb_inplace_remainder*/ 0, /*nb_inplace_power*/ 0, /*nb_inplace_lshift*/ 0, /*nb_inplace_rshift*/ 0, /*nb_inplace_and*/ 0, /*nb_inplace_xor*/ 0, /*nb_inplace_or*/ 0, /*nb_floor_divide*/ 0, /*nb_true_divide*/ 0, /*nb_inplace_floor_divide*/ 0, /*nb_inplace_true_divide*/ 0, /*nb_index*/ #if PY_VERSION_HEX >= 0x03050000 0, /*nb_matrix_multiply*/ #endif #if PY_VERSION_HEX >= 0x03050000 0, /*nb_inplace_matrix_multiply*/ #endif }; static PyTypeObject __pyx_type_7aiohttp_10_multidict__ViewBaseSet = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict._ViewBaseSet", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict__ViewBaseSet), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__ViewBase, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif 0, /*tp_repr*/ &__pyx_tp_as_number__ViewBaseSet, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__ViewBase, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__ViewBase, /*tp_clear*/ __pyx_pw_7aiohttp_10_multidict_12_ViewBaseSet_1__richcmp__, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict__ViewBaseSet, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict__ViewBaseSet, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ItemsIter(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *p; PyObject *o; if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { o = (*t->tp_alloc)(t, 0); } else { o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); } if (unlikely(!o)) return 0; p = ((struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *)o); p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); if (unlikely(__pyx_pw_7aiohttp_10_multidict_10_ItemsIter_1__cinit__(o, a, k) < 0)) { Py_DECREF(o); o = 0; } return o; } static void __pyx_tp_dealloc_7aiohttp_10_multidict__ItemsIter(PyObject *o) { struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *p = (struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *)o; #if PY_VERSION_HEX >= 0x030400a1 if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { if (PyObject_CallFinalizerFromDealloc(o)) return; } #endif PyObject_GC_UnTrack(o); Py_CLEAR(p->_items); (*Py_TYPE(o)->tp_free)(o); } static int __pyx_tp_traverse_7aiohttp_10_multidict__ItemsIter(PyObject *o, visitproc v, void *a) { int e; struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *p = (struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *)o; if (p->_items) { e = (*v)(p->_items, a); if (e) return e; } return 0; } static int __pyx_tp_clear_7aiohttp_10_multidict__ItemsIter(PyObject *o) { PyObject* tmp; struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *p = (struct __pyx_obj_7aiohttp_10_multidict__ItemsIter *)o; tmp = ((PyObject*)p->_items); p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); Py_XDECREF(tmp); return 0; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict__ItemsIter[] = { {"__next__", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_10_ItemsIter_5__next__, METH_NOARGS|METH_COEXIST, 0}, {0, 0, 0, 0} }; static PyTypeObject __pyx_type_7aiohttp_10_multidict__ItemsIter = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict._ItemsIter", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict__ItemsIter), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__ItemsIter, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__ItemsIter, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__ItemsIter, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ __pyx_pw_7aiohttp_10_multidict_10_ItemsIter_3__iter__, /*tp_iter*/ __pyx_pw_7aiohttp_10_multidict_10_ItemsIter_5__next__, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict__ItemsIter, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict__ItemsIter, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ItemsView(PyTypeObject *t, PyObject *a, PyObject *k) { PyObject *o = __pyx_tp_new_7aiohttp_10_multidict__ViewBaseSet(t, a, k); if (unlikely(!o)) return 0; return o; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict__ItemsView[] = { {"isdisjoint", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_10_ItemsView_1isdisjoint, METH_O, __pyx_doc_7aiohttp_10_multidict_10_ItemsView_isdisjoint}, {0, 0, 0, 0} }; static PySequenceMethods __pyx_tp_as_sequence__ItemsView = { #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_9_ViewBase_3__len__, /*sq_length*/ #else 0, /*sq_length*/ #endif 0, /*sq_concat*/ 0, /*sq_repeat*/ 0, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ __pyx_pw_7aiohttp_10_multidict_10_ItemsView_3__contains__, /*sq_contains*/ 0, /*sq_inplace_concat*/ 0, /*sq_inplace_repeat*/ }; static PyTypeObject __pyx_type_7aiohttp_10_multidict__ItemsView = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict._ItemsView", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict__ItemsView), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__ViewBase, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif __pyx_pw_7aiohttp_10_multidict_10_ItemsView_7__repr__, /*tp_repr*/ 0, /*tp_as_number*/ &__pyx_tp_as_sequence__ItemsView, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__ViewBase, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__ViewBase, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ __pyx_pw_7aiohttp_10_multidict_10_ItemsView_5__iter__, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict__ItemsView, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict__ItemsView, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ValuesIter(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *p; PyObject *o; if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { o = (*t->tp_alloc)(t, 0); } else { o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); } if (unlikely(!o)) return 0; p = ((struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *)o); p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); if (unlikely(__pyx_pw_7aiohttp_10_multidict_11_ValuesIter_1__cinit__(o, a, k) < 0)) { Py_DECREF(o); o = 0; } return o; } static void __pyx_tp_dealloc_7aiohttp_10_multidict__ValuesIter(PyObject *o) { struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *p = (struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *)o; #if PY_VERSION_HEX >= 0x030400a1 if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { if (PyObject_CallFinalizerFromDealloc(o)) return; } #endif PyObject_GC_UnTrack(o); Py_CLEAR(p->_items); (*Py_TYPE(o)->tp_free)(o); } static int __pyx_tp_traverse_7aiohttp_10_multidict__ValuesIter(PyObject *o, visitproc v, void *a) { int e; struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *p = (struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *)o; if (p->_items) { e = (*v)(p->_items, a); if (e) return e; } return 0; } static int __pyx_tp_clear_7aiohttp_10_multidict__ValuesIter(PyObject *o) { PyObject* tmp; struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *p = (struct __pyx_obj_7aiohttp_10_multidict__ValuesIter *)o; tmp = ((PyObject*)p->_items); p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); Py_XDECREF(tmp); return 0; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict__ValuesIter[] = { {"__next__", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_11_ValuesIter_5__next__, METH_NOARGS|METH_COEXIST, 0}, {0, 0, 0, 0} }; static PyTypeObject __pyx_type_7aiohttp_10_multidict__ValuesIter = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict._ValuesIter", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict__ValuesIter), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__ValuesIter, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__ValuesIter, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__ValuesIter, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ __pyx_pw_7aiohttp_10_multidict_11_ValuesIter_3__iter__, /*tp_iter*/ __pyx_pw_7aiohttp_10_multidict_11_ValuesIter_5__next__, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict__ValuesIter, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict__ValuesIter, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyObject *__pyx_tp_new_7aiohttp_10_multidict__ValuesView(PyTypeObject *t, PyObject *a, PyObject *k) { PyObject *o = __pyx_tp_new_7aiohttp_10_multidict__ViewBase(t, a, k); if (unlikely(!o)) return 0; return o; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict__ValuesView[] = { {0, 0, 0, 0} }; static PySequenceMethods __pyx_tp_as_sequence__ValuesView = { #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_9_ViewBase_3__len__, /*sq_length*/ #else 0, /*sq_length*/ #endif 0, /*sq_concat*/ 0, /*sq_repeat*/ 0, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ __pyx_pw_7aiohttp_10_multidict_11_ValuesView_1__contains__, /*sq_contains*/ 0, /*sq_inplace_concat*/ 0, /*sq_inplace_repeat*/ }; static PyTypeObject __pyx_type_7aiohttp_10_multidict__ValuesView = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict._ValuesView", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict__ValuesView), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__ViewBase, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif __pyx_pw_7aiohttp_10_multidict_11_ValuesView_5__repr__, /*tp_repr*/ 0, /*tp_as_number*/ &__pyx_tp_as_sequence__ValuesView, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__ViewBase, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__ViewBase, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ __pyx_pw_7aiohttp_10_multidict_11_ValuesView_3__iter__, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict__ValuesView, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict__ValuesView, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyObject *__pyx_tp_new_7aiohttp_10_multidict__KeysIter(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_obj_7aiohttp_10_multidict__KeysIter *p; PyObject *o; if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { o = (*t->tp_alloc)(t, 0); } else { o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); } if (unlikely(!o)) return 0; p = ((struct __pyx_obj_7aiohttp_10_multidict__KeysIter *)o); p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); if (unlikely(__pyx_pw_7aiohttp_10_multidict_9_KeysIter_1__cinit__(o, a, k) < 0)) { Py_DECREF(o); o = 0; } return o; } static void __pyx_tp_dealloc_7aiohttp_10_multidict__KeysIter(PyObject *o) { struct __pyx_obj_7aiohttp_10_multidict__KeysIter *p = (struct __pyx_obj_7aiohttp_10_multidict__KeysIter *)o; #if PY_VERSION_HEX >= 0x030400a1 if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { if (PyObject_CallFinalizerFromDealloc(o)) return; } #endif PyObject_GC_UnTrack(o); Py_CLEAR(p->_items); (*Py_TYPE(o)->tp_free)(o); } static int __pyx_tp_traverse_7aiohttp_10_multidict__KeysIter(PyObject *o, visitproc v, void *a) { int e; struct __pyx_obj_7aiohttp_10_multidict__KeysIter *p = (struct __pyx_obj_7aiohttp_10_multidict__KeysIter *)o; if (p->_items) { e = (*v)(p->_items, a); if (e) return e; } return 0; } static int __pyx_tp_clear_7aiohttp_10_multidict__KeysIter(PyObject *o) { PyObject* tmp; struct __pyx_obj_7aiohttp_10_multidict__KeysIter *p = (struct __pyx_obj_7aiohttp_10_multidict__KeysIter *)o; tmp = ((PyObject*)p->_items); p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); Py_XDECREF(tmp); return 0; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict__KeysIter[] = { {"__next__", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_9_KeysIter_5__next__, METH_NOARGS|METH_COEXIST, 0}, {0, 0, 0, 0} }; static PyTypeObject __pyx_type_7aiohttp_10_multidict__KeysIter = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict._KeysIter", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict__KeysIter), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__KeysIter, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__KeysIter, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__KeysIter, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ __pyx_pw_7aiohttp_10_multidict_9_KeysIter_3__iter__, /*tp_iter*/ __pyx_pw_7aiohttp_10_multidict_9_KeysIter_5__next__, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict__KeysIter, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict__KeysIter, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyObject *__pyx_tp_new_7aiohttp_10_multidict__KeysView(PyTypeObject *t, PyObject *a, PyObject *k) { PyObject *o = __pyx_tp_new_7aiohttp_10_multidict__ViewBaseSet(t, a, k); if (unlikely(!o)) return 0; return o; } static PyMethodDef __pyx_methods_7aiohttp_10_multidict__KeysView[] = { {"isdisjoint", (PyCFunction)__pyx_pw_7aiohttp_10_multidict_9_KeysView_1isdisjoint, METH_O, __pyx_doc_7aiohttp_10_multidict_9_KeysView_isdisjoint}, {0, 0, 0, 0} }; static PySequenceMethods __pyx_tp_as_sequence__KeysView = { #if CYTHON_COMPILING_IN_PYPY __pyx_pw_7aiohttp_10_multidict_9_ViewBase_3__len__, /*sq_length*/ #else 0, /*sq_length*/ #endif 0, /*sq_concat*/ 0, /*sq_repeat*/ 0, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ __pyx_pw_7aiohttp_10_multidict_9_KeysView_3__contains__, /*sq_contains*/ 0, /*sq_inplace_concat*/ 0, /*sq_inplace_repeat*/ }; static PyTypeObject __pyx_type_7aiohttp_10_multidict__KeysView = { PyVarObject_HEAD_INIT(0, 0) "aiohttp._multidict._KeysView", /*tp_name*/ sizeof(struct __pyx_obj_7aiohttp_10_multidict__KeysView), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_7aiohttp_10_multidict__ViewBase, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif __pyx_pw_7aiohttp_10_multidict_9_KeysView_7__repr__, /*tp_repr*/ 0, /*tp_as_number*/ &__pyx_tp_as_sequence__KeysView, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_7aiohttp_10_multidict__ViewBase, /*tp_traverse*/ __pyx_tp_clear_7aiohttp_10_multidict__ViewBase, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ __pyx_pw_7aiohttp_10_multidict_9_KeysView_5__iter__, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_7aiohttp_10_multidict__KeysView, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_7aiohttp_10_multidict__KeysView, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyMethodDef __pyx_methods[] = { {0, 0, 0, 0} }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef __pyx_moduledef = { #if PY_VERSION_HEX < 0x03020000 { PyObject_HEAD_INIT(NULL) NULL, 0, NULL }, #else PyModuleDef_HEAD_INIT, #endif "_multidict", 0, /* m_doc */ -1, /* m_size */ __pyx_methods /* m_methods */, NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL /* m_free */ }; #endif static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_kp_s_, __pyx_k_, sizeof(__pyx_k_), 0, 0, 1, 0}, {&__pyx_kp_s_CIMultiDictProxy_requires_CIMult, __pyx_k_CIMultiDictProxy_requires_CIMult, sizeof(__pyx_k_CIMultiDictProxy_requires_CIMult), 0, 0, 1, 0}, {&__pyx_kp_s_Case_insensitive_str, __pyx_k_Case_insensitive_str, sizeof(__pyx_k_Case_insensitive_str), 0, 0, 1, 0}, {&__pyx_n_s_ItemsView, __pyx_k_ItemsView, sizeof(__pyx_k_ItemsView), 0, 0, 1, 1}, {&__pyx_n_s_Iterable, __pyx_k_Iterable, sizeof(__pyx_k_Iterable), 0, 0, 1, 1}, {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1}, {&__pyx_kp_s_Key_not_found_r, __pyx_k_Key_not_found_r, sizeof(__pyx_k_Key_not_found_r), 0, 0, 1, 0}, {&__pyx_n_s_KeysView, __pyx_k_KeysView, sizeof(__pyx_k_KeysView), 0, 0, 1, 1}, {&__pyx_n_s_Mapping, __pyx_k_Mapping, sizeof(__pyx_k_Mapping), 0, 0, 1, 1}, {&__pyx_kp_s_MultiDictProxy_requires_MultiDic, __pyx_k_MultiDictProxy_requires_MultiDic, sizeof(__pyx_k_MultiDictProxy_requires_MultiDic), 0, 0, 1, 0}, {&__pyx_n_s_MutableMapping, __pyx_k_MutableMapping, sizeof(__pyx_k_MutableMapping), 0, 0, 1, 1}, {&__pyx_n_s_NotImplemented, __pyx_k_NotImplemented, sizeof(__pyx_k_NotImplemented), 0, 0, 1, 1}, {&__pyx_n_s_Set, __pyx_k_Set, sizeof(__pyx_k_Set), 0, 0, 1, 1}, {&__pyx_n_s_StopIteration, __pyx_k_StopIteration, sizeof(__pyx_k_StopIteration), 0, 0, 1, 1}, {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, {&__pyx_n_s_ValuesView, __pyx_k_ValuesView, sizeof(__pyx_k_ValuesView), 0, 0, 1, 1}, {&__pyx_kp_s__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 0, 1, 0}, {&__pyx_kp_s__5, __pyx_k__5, sizeof(__pyx_k__5), 0, 0, 1, 0}, {&__pyx_kp_s__8, __pyx_k__8, sizeof(__pyx_k__8), 0, 0, 1, 0}, {&__pyx_n_s_abc, __pyx_k_abc, sizeof(__pyx_k_abc), 0, 0, 1, 1}, {&__pyx_n_s_aiohttp__multidict, __pyx_k_aiohttp__multidict, sizeof(__pyx_k_aiohttp__multidict), 0, 0, 1, 1}, {&__pyx_n_s_arg, __pyx_k_arg, sizeof(__pyx_k_arg), 0, 0, 1, 1}, {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1}, {&__pyx_n_s_clear, __pyx_k_clear, sizeof(__pyx_k_clear), 0, 0, 1, 1}, {&__pyx_n_s_cls, __pyx_k_cls, sizeof(__pyx_k_cls), 0, 0, 1, 1}, {&__pyx_n_s_collections, __pyx_k_collections, sizeof(__pyx_k_collections), 0, 0, 1, 1}, {&__pyx_n_s_collections_abc, __pyx_k_collections_abc, sizeof(__pyx_k_collections_abc), 0, 0, 1, 1}, {&__pyx_n_s_default, __pyx_k_default, sizeof(__pyx_k_default), 0, 0, 1, 1}, {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1}, {&__pyx_kp_s_empty_multidict, __pyx_k_empty_multidict, sizeof(__pyx_k_empty_multidict), 0, 0, 1, 0}, {&__pyx_n_s_encoding, __pyx_k_encoding, sizeof(__pyx_k_encoding), 0, 0, 1, 1}, {&__pyx_n_s_errors, __pyx_k_errors, sizeof(__pyx_k_errors), 0, 0, 1, 1}, {&__pyx_n_s_extend, __pyx_k_extend, sizeof(__pyx_k_extend), 0, 0, 1, 1}, {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, {&__pyx_n_s_get, __pyx_k_get, sizeof(__pyx_k_get), 0, 0, 1, 1}, {&__pyx_n_s_getdefaultencoding, __pyx_k_getdefaultencoding, sizeof(__pyx_k_getdefaultencoding), 0, 0, 1, 1}, {&__pyx_kp_s_home_andrew_projects_aiohttp_ai, __pyx_k_home_andrew_projects_aiohttp_ai, sizeof(__pyx_k_home_andrew_projects_aiohttp_ai), 0, 0, 1, 0}, {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, {&__pyx_n_s_itemgetter, __pyx_k_itemgetter, sizeof(__pyx_k_itemgetter), 0, 0, 1, 1}, {&__pyx_n_s_items, __pyx_k_items, sizeof(__pyx_k_items), 0, 0, 1, 1}, {&__pyx_n_s_join, __pyx_k_join, sizeof(__pyx_k_join), 0, 0, 1, 1}, {&__pyx_n_s_key, __pyx_k_key, sizeof(__pyx_k_key), 0, 0, 1, 1}, {&__pyx_n_s_keys, __pyx_k_keys, sizeof(__pyx_k_keys), 0, 0, 1, 1}, {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, {&__pyx_n_s_marker, __pyx_k_marker, sizeof(__pyx_k_marker), 0, 0, 1, 1}, {&__pyx_n_s_memoryview, __pyx_k_memoryview, sizeof(__pyx_k_memoryview), 0, 0, 1, 1}, {&__pyx_n_s_metaclass, __pyx_k_metaclass, sizeof(__pyx_k_metaclass), 0, 0, 1, 1}, {&__pyx_n_s_module, __pyx_k_module, sizeof(__pyx_k_module), 0, 0, 1, 1}, {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, {&__pyx_n_s_object, __pyx_k_object, sizeof(__pyx_k_object), 0, 0, 1, 1}, {&__pyx_n_s_operator, __pyx_k_operator, sizeof(__pyx_k_operator), 0, 0, 1, 1}, {&__pyx_n_s_pop, __pyx_k_pop, sizeof(__pyx_k_pop), 0, 0, 1, 1}, {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1}, {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, {&__pyx_n_s_qualname, __pyx_k_qualname, sizeof(__pyx_k_qualname), 0, 0, 1, 1}, {&__pyx_kp_s_r, __pyx_k_r, sizeof(__pyx_k_r), 0, 0, 1, 0}, {&__pyx_kp_s_r_2, __pyx_k_r_2, sizeof(__pyx_k_r_2), 0, 0, 1, 0}, {&__pyx_kp_s_r_r, __pyx_k_r_r, sizeof(__pyx_k_r_r), 0, 0, 1, 0}, {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, {&__pyx_n_s_register, __pyx_k_register, sizeof(__pyx_k_register), 0, 0, 1, 1}, {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1}, {&__pyx_n_s_strict, __pyx_k_strict, sizeof(__pyx_k_strict), 0, 0, 1, 1}, {&__pyx_n_s_sys, __pyx_k_sys, sizeof(__pyx_k_sys), 0, 0, 1, 1}, {&__pyx_kp_s_takes_at_most_1_positional_argu, __pyx_k_takes_at_most_1_positional_argu, sizeof(__pyx_k_takes_at_most_1_positional_argu), 0, 0, 1, 0}, {&__pyx_kp_s_takes_either_dict_or_list_of_ke, __pyx_k_takes_either_dict_or_list_of_ke, sizeof(__pyx_k_takes_either_dict_or_list_of_ke), 0, 0, 1, 0}, {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, {&__pyx_n_s_upper, __pyx_k_upper, sizeof(__pyx_k_upper), 0, 0, 1, 1}, {&__pyx_n_s_upstr, __pyx_k_upstr, sizeof(__pyx_k_upstr), 0, 0, 1, 1}, {&__pyx_n_s_upstr___new, __pyx_k_upstr___new, sizeof(__pyx_k_upstr___new), 0, 0, 1, 1}, {&__pyx_n_s_upstr_upper, __pyx_k_upstr_upper, sizeof(__pyx_k_upstr_upper), 0, 0, 1, 1}, {&__pyx_n_s_val, __pyx_k_val, sizeof(__pyx_k_val), 0, 0, 1, 1}, {&__pyx_n_s_value, __pyx_k_value, sizeof(__pyx_k_value), 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0} }; static int __Pyx_InitCachedBuiltins(void) { __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_memoryview = __Pyx_GetBuiltinName(__pyx_n_s_memoryview); if (!__pyx_builtin_memoryview) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_NotImplemented = __Pyx_GetBuiltinName(__pyx_n_s_NotImplemented); if (!__pyx_builtin_NotImplemented) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;} return 0; __pyx_L1_error:; return -1; } static int __Pyx_InitCachedConstants(void) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); /* "aiohttp/_multidict.pyx":398 * return (item._key, item._value) * else: * raise KeyError("empty multidict") # <<<<<<<<<<<<<< * * def update(self, *args, **kwargs): */ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_empty_multidict); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__7); __Pyx_GIVEREF(__pyx_tuple__7); /* "aiohttp/_multidict.pyx":14 * """Case insensitive str.""" * * def __new__(cls, val='', # <<<<<<<<<<<<<< * encoding=sys.getdefaultencoding(), errors='strict'): * if isinstance(val, (bytes, bytearray, memoryview)): */ __pyx_tuple__9 = PyTuple_Pack(4, __pyx_n_s_cls, __pyx_n_s_val, __pyx_n_s_encoding, __pyx_n_s_errors); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__9); __Pyx_GIVEREF(__pyx_tuple__9); __pyx_codeobj__10 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__9, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_andrew_projects_aiohttp_ai, __pyx_n_s_new, 14, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":25 * return str.__new__(cls, val) * * def upper(self): # <<<<<<<<<<<<<< * return self * */ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__11); __Pyx_GIVEREF(__pyx_tuple__11); __pyx_codeobj__12 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_andrew_projects_aiohttp_ai, __pyx_n_s_upper, 25, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; __Pyx_RefNannyFinishContext(); return -1; } static int __Pyx_InitGlobals(void) { __pyx_umethod_PyDict_Type_items.type = (PyObject*)&PyDict_Type; if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} return 0; __pyx_L1_error:; return -1; } #if PY_MAJOR_VERSION < 3 PyMODINIT_FUNC init_multidict(void); /*proto*/ PyMODINIT_FUNC init_multidict(void) #else PyMODINIT_FUNC PyInit__multidict(void); /*proto*/ PyMODINIT_FUNC PyInit__multidict(void) #endif { PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannyDeclarations #if CYTHON_REFNANNY __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); if (!__Pyx_RefNanny) { PyErr_Clear(); __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); if (!__Pyx_RefNanny) Py_FatalError("failed to import 'refnanny' module"); } #endif __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__multidict(void)", 0); if (__Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #ifdef __Pyx_CyFunction_USED if (__pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif #ifdef __Pyx_FusedFunction_USED if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif #ifdef __Pyx_Coroutine_USED if (__pyx_Coroutine_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif #ifdef __Pyx_Generator_USED if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif #ifdef __Pyx_StopAsyncIteration_USED if (__pyx_StopAsyncIteration_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif /*--- Library function declarations ---*/ /*--- Threads initialization code ---*/ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS #ifdef WITH_THREAD /* Python build with threading support? */ PyEval_InitThreads(); #endif #endif /*--- Module creation code ---*/ #if PY_MAJOR_VERSION < 3 __pyx_m = Py_InitModule4("_multidict", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); #else __pyx_m = PyModule_Create(&__pyx_moduledef); #endif if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} Py_INCREF(__pyx_d); __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #if CYTHON_COMPILING_IN_PYPY Py_INCREF(__pyx_b); #endif if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; /*--- Initialize various global constants etc. ---*/ if (__Pyx_InitGlobals() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif if (__pyx_module_is_main_aiohttp___multidict) { if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } #if PY_MAJOR_VERSION >= 3 { PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (!PyDict_GetItemString(modules, "aiohttp._multidict")) { if (unlikely(PyDict_SetItemString(modules, "aiohttp._multidict", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } } #endif /*--- Builtin init code ---*/ if (__Pyx_InitCachedBuiltins() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /*--- Constants init code ---*/ if (__Pyx_InitCachedConstants() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /*--- Global init code ---*/ /*--- Variable export code ---*/ /*--- Function export code ---*/ /*--- Type init code ---*/ if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict__Pair) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict__Pair.tp_print = 0; if (PyObject_SetAttrString(__pyx_m, "_Pair", (PyObject *)&__pyx_type_7aiohttp_10_multidict__Pair) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict__Pair = &__pyx_type_7aiohttp_10_multidict__Pair; __pyx_vtabptr_7aiohttp_10_multidict__Base = &__pyx_vtable_7aiohttp_10_multidict__Base; __pyx_vtable_7aiohttp_10_multidict__Base._upper = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *))__pyx_f_7aiohttp_10_multidict_5_Base__upper; __pyx_vtable_7aiohttp_10_multidict__Base._getall = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *, PyObject *))__pyx_f_7aiohttp_10_multidict_5_Base__getall; __pyx_vtable_7aiohttp_10_multidict__Base._getone = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *, PyObject *))__pyx_f_7aiohttp_10_multidict_5_Base__getone; __pyx_vtable_7aiohttp_10_multidict__Base._contains = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *))__pyx_f_7aiohttp_10_multidict_5_Base__contains; __pyx_vtable_7aiohttp_10_multidict__Base.keys = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict__Base *, int __pyx_skip_dispatch))__pyx_f_7aiohttp_10_multidict_5_Base_keys; __pyx_vtable_7aiohttp_10_multidict__Base._eq_to_mapping = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *))__pyx_f_7aiohttp_10_multidict_5_Base__eq_to_mapping; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict__Base) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict__Base.tp_print = 0; if (__Pyx_SetVtable(__pyx_type_7aiohttp_10_multidict__Base.tp_dict, __pyx_vtabptr_7aiohttp_10_multidict__Base) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (PyObject_SetAttrString(__pyx_m, "_Base", (PyObject *)&__pyx_type_7aiohttp_10_multidict__Base) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict__Base = &__pyx_type_7aiohttp_10_multidict__Base; __pyx_vtabptr_7aiohttp_10_multidict_MultiDictProxy = &__pyx_vtable_7aiohttp_10_multidict_MultiDictProxy; __pyx_vtable_7aiohttp_10_multidict_MultiDictProxy.__pyx_base = *__pyx_vtabptr_7aiohttp_10_multidict__Base; __pyx_type_7aiohttp_10_multidict_MultiDictProxy.tp_base = __pyx_ptype_7aiohttp_10_multidict__Base; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict_MultiDictProxy) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict_MultiDictProxy.tp_print = 0; if (__Pyx_SetVtable(__pyx_type_7aiohttp_10_multidict_MultiDictProxy.tp_dict, __pyx_vtabptr_7aiohttp_10_multidict_MultiDictProxy) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (PyObject_SetAttrString(__pyx_m, "MultiDictProxy", (PyObject *)&__pyx_type_7aiohttp_10_multidict_MultiDictProxy) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict_MultiDictProxy = &__pyx_type_7aiohttp_10_multidict_MultiDictProxy; __pyx_vtabptr_7aiohttp_10_multidict_CIMultiDictProxy = &__pyx_vtable_7aiohttp_10_multidict_CIMultiDictProxy; __pyx_vtable_7aiohttp_10_multidict_CIMultiDictProxy.__pyx_base = *__pyx_vtabptr_7aiohttp_10_multidict_MultiDictProxy; __pyx_vtable_7aiohttp_10_multidict_CIMultiDictProxy.__pyx_base.__pyx_base._upper = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *))__pyx_f_7aiohttp_10_multidict_16CIMultiDictProxy__upper; __pyx_type_7aiohttp_10_multidict_CIMultiDictProxy.tp_base = __pyx_ptype_7aiohttp_10_multidict_MultiDictProxy; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict_CIMultiDictProxy) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict_CIMultiDictProxy.tp_print = 0; if (__Pyx_SetVtable(__pyx_type_7aiohttp_10_multidict_CIMultiDictProxy.tp_dict, __pyx_vtabptr_7aiohttp_10_multidict_CIMultiDictProxy) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (PyObject_SetAttrString(__pyx_m, "CIMultiDictProxy", (PyObject *)&__pyx_type_7aiohttp_10_multidict_CIMultiDictProxy) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict_CIMultiDictProxy = &__pyx_type_7aiohttp_10_multidict_CIMultiDictProxy; __pyx_vtabptr_7aiohttp_10_multidict_MultiDict = &__pyx_vtable_7aiohttp_10_multidict_MultiDict; __pyx_vtable_7aiohttp_10_multidict_MultiDict.__pyx_base = *__pyx_vtabptr_7aiohttp_10_multidict__Base; __pyx_vtable_7aiohttp_10_multidict_MultiDict._extend = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *, PyObject *, PyObject *, PyObject *, int))__pyx_f_7aiohttp_10_multidict_9MultiDict__extend; __pyx_vtable_7aiohttp_10_multidict_MultiDict._add = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *, PyObject *, PyObject *))__pyx_f_7aiohttp_10_multidict_9MultiDict__add; __pyx_vtable_7aiohttp_10_multidict_MultiDict._replace = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *, PyObject *, PyObject *))__pyx_f_7aiohttp_10_multidict_9MultiDict__replace; __pyx_vtable_7aiohttp_10_multidict_MultiDict._remove = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict_MultiDict *, PyObject *, int))__pyx_f_7aiohttp_10_multidict_9MultiDict__remove; __pyx_type_7aiohttp_10_multidict_MultiDict.tp_base = __pyx_ptype_7aiohttp_10_multidict__Base; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict_MultiDict) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict_MultiDict.tp_print = 0; if (__Pyx_SetVtable(__pyx_type_7aiohttp_10_multidict_MultiDict.tp_dict, __pyx_vtabptr_7aiohttp_10_multidict_MultiDict) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (PyObject_SetAttrString(__pyx_m, "MultiDict", (PyObject *)&__pyx_type_7aiohttp_10_multidict_MultiDict) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict_MultiDict = &__pyx_type_7aiohttp_10_multidict_MultiDict; __pyx_vtabptr_7aiohttp_10_multidict_CIMultiDict = &__pyx_vtable_7aiohttp_10_multidict_CIMultiDict; __pyx_vtable_7aiohttp_10_multidict_CIMultiDict.__pyx_base = *__pyx_vtabptr_7aiohttp_10_multidict_MultiDict; __pyx_vtable_7aiohttp_10_multidict_CIMultiDict.__pyx_base.__pyx_base._upper = (PyObject *(*)(struct __pyx_obj_7aiohttp_10_multidict__Base *, PyObject *))__pyx_f_7aiohttp_10_multidict_11CIMultiDict__upper; __pyx_type_7aiohttp_10_multidict_CIMultiDict.tp_base = __pyx_ptype_7aiohttp_10_multidict_MultiDict; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict_CIMultiDict) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict_CIMultiDict.tp_print = 0; if (__Pyx_SetVtable(__pyx_type_7aiohttp_10_multidict_CIMultiDict.tp_dict, __pyx_vtabptr_7aiohttp_10_multidict_CIMultiDict) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (PyObject_SetAttrString(__pyx_m, "CIMultiDict", (PyObject *)&__pyx_type_7aiohttp_10_multidict_CIMultiDict) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict_CIMultiDict = &__pyx_type_7aiohttp_10_multidict_CIMultiDict; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict__ViewBase) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict__ViewBase.tp_print = 0; if (PyObject_SetAttrString(__pyx_m, "_ViewBase", (PyObject *)&__pyx_type_7aiohttp_10_multidict__ViewBase) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict__ViewBase = &__pyx_type_7aiohttp_10_multidict__ViewBase; __pyx_type_7aiohttp_10_multidict__ViewBaseSet.tp_base = __pyx_ptype_7aiohttp_10_multidict__ViewBase; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict__ViewBaseSet) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict__ViewBaseSet.tp_print = 0; if (PyObject_SetAttrString(__pyx_m, "_ViewBaseSet", (PyObject *)&__pyx_type_7aiohttp_10_multidict__ViewBaseSet) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict__ViewBaseSet = &__pyx_type_7aiohttp_10_multidict__ViewBaseSet; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict__ItemsIter) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict__ItemsIter.tp_print = 0; if (PyObject_SetAttrString(__pyx_m, "_ItemsIter", (PyObject *)&__pyx_type_7aiohttp_10_multidict__ItemsIter) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict__ItemsIter = &__pyx_type_7aiohttp_10_multidict__ItemsIter; __pyx_type_7aiohttp_10_multidict__ItemsView.tp_base = __pyx_ptype_7aiohttp_10_multidict__ViewBaseSet; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict__ItemsView) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 518; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict__ItemsView.tp_print = 0; if (PyObject_SetAttrString(__pyx_m, "_ItemsView", (PyObject *)&__pyx_type_7aiohttp_10_multidict__ItemsView) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 518; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict__ItemsView = &__pyx_type_7aiohttp_10_multidict__ItemsView; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict__ValuesIter) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict__ValuesIter.tp_print = 0; if (PyObject_SetAttrString(__pyx_m, "_ValuesIter", (PyObject *)&__pyx_type_7aiohttp_10_multidict__ValuesIter) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict__ValuesIter = &__pyx_type_7aiohttp_10_multidict__ValuesIter; __pyx_type_7aiohttp_10_multidict__ValuesView.tp_base = __pyx_ptype_7aiohttp_10_multidict__ViewBase; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict__ValuesView) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 574; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict__ValuesView.tp_print = 0; if (PyObject_SetAttrString(__pyx_m, "_ValuesView", (PyObject *)&__pyx_type_7aiohttp_10_multidict__ValuesView) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 574; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict__ValuesView = &__pyx_type_7aiohttp_10_multidict__ValuesView; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict__KeysIter) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict__KeysIter.tp_print = 0; if (PyObject_SetAttrString(__pyx_m, "_KeysIter", (PyObject *)&__pyx_type_7aiohttp_10_multidict__KeysIter) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict__KeysIter = &__pyx_type_7aiohttp_10_multidict__KeysIter; __pyx_type_7aiohttp_10_multidict__KeysView.tp_base = __pyx_ptype_7aiohttp_10_multidict__ViewBaseSet; if (PyType_Ready(&__pyx_type_7aiohttp_10_multidict__KeysView) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 621; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_type_7aiohttp_10_multidict__KeysView.tp_print = 0; if (PyObject_SetAttrString(__pyx_m, "_KeysView", (PyObject *)&__pyx_type_7aiohttp_10_multidict__KeysView) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 621; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_7aiohttp_10_multidict__KeysView = &__pyx_type_7aiohttp_10_multidict__KeysView; /*--- Type import code ---*/ /*--- Variable import code ---*/ /*--- Function import code ---*/ /*--- Execution code ---*/ #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) if (__Pyx_patch_abc() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif /* "aiohttp/_multidict.pyx":1 * import sys # <<<<<<<<<<<<<< * from collections import abc * from collections.abc import Iterable, Set */ __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_sys, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":2 * import sys * from collections import abc # <<<<<<<<<<<<<< * from collections.abc import Iterable, Set * from operator import itemgetter */ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_n_s_abc); __Pyx_GIVEREF(__pyx_n_s_abc); PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_abc); __pyx_t_2 = __Pyx_Import(__pyx_n_s_collections, __pyx_t_1, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_abc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_abc, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":3 * import sys * from collections import abc * from collections.abc import Iterable, Set # <<<<<<<<<<<<<< * from operator import itemgetter * */ __pyx_t_2 = PyList_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_n_s_Iterable); __Pyx_GIVEREF(__pyx_n_s_Iterable); PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_Iterable); __Pyx_INCREF(__pyx_n_s_Set); __Pyx_GIVEREF(__pyx_n_s_Set); PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_Set); __pyx_t_1 = __Pyx_Import(__pyx_n_s_collections_abc, __pyx_t_2, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __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_Iterable); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); if (PyDict_SetItem(__pyx_d, __pyx_n_s_Iterable, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Set); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); if (PyDict_SetItem(__pyx_d, __pyx_n_s_Set, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "aiohttp/_multidict.pyx":4 * from collections import abc * from collections.abc import Iterable, Set * from operator import itemgetter # <<<<<<<<<<<<<< * * */ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_n_s_itemgetter); __Pyx_GIVEREF(__pyx_n_s_itemgetter); PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_itemgetter); __pyx_t_2 = __Pyx_Import(__pyx_n_s_operator, __pyx_t_1, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_itemgetter); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_itemgetter, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":7 * * * _marker = object() # <<<<<<<<<<<<<< * * */ __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_builtin_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); if (PyDict_SetItem(__pyx_d, __pyx_n_s_marker, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":10 * * * class upstr(str): # <<<<<<<<<<<<<< * * """Case insensitive str.""" */ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(((PyObject *)(&PyString_Type))); __Pyx_GIVEREF(((PyObject *)(&PyString_Type))); PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)(&PyString_Type))); __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_upstr, __pyx_n_s_upstr, (PyObject *) NULL, __pyx_n_s_aiohttp__multidict, __pyx_kp_s_Case_insensitive_str); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); /* "aiohttp/_multidict.pyx":14 * """Case insensitive str.""" * * def __new__(cls, val='', # <<<<<<<<<<<<<< * encoding=sys.getdefaultencoding(), errors='strict'): * if isinstance(val, (bytes, bytearray, memoryview)): */ __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_7aiohttp_10_multidict_5upstr_1__new__, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_upstr___new, NULL, __pyx_n_s_aiohttp__multidict, __pyx_d, ((PyObject *)__pyx_codeobj__10)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); if (!__Pyx_CyFunction_InitDefaults(__pyx_t_4, sizeof(__pyx_defaults), 1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "aiohttp/_multidict.pyx":15 * * def __new__(cls, val='', * encoding=sys.getdefaultencoding(), errors='strict'): # <<<<<<<<<<<<<< * if isinstance(val, (bytes, bytearray, memoryview)): * val = str(val, encoding, errors) */ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_sys); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_6); __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_getdefaultencoding); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_t_6 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_7))) { __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_7); if (likely(__pyx_t_6)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); __Pyx_INCREF(__pyx_t_6); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_7, function); } } if (__pyx_t_6) { __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } else { __pyx_t_5 = __Pyx_PyObject_CallNoArg(__pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;} } __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_CyFunction_Defaults(__pyx_defaults, __pyx_t_4)->__pyx_arg_encoding = __pyx_t_5; __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_4, __pyx_pf_7aiohttp_10_multidict_5upstr_4__defaults__); if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_new, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":25 * return str.__new__(cls, val) * * def upper(self): # <<<<<<<<<<<<<< * return self * */ __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_7aiohttp_10_multidict_5upstr_3upper, 0, __pyx_n_s_upstr_upper, NULL, __pyx_n_s_aiohttp__multidict, __pyx_d, ((PyObject *)__pyx_codeobj__12)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_upper, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; /* "aiohttp/_multidict.pyx":10 * * * class upstr(str): # <<<<<<<<<<<<<< * * """Case insensitive str.""" */ __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_upstr, __pyx_t_2, __pyx_t_3, NULL, 0, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); if (PyDict_SetItem(__pyx_d, __pyx_n_s_upstr, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":81 * return s * * def getall(self, key, default=_marker): # <<<<<<<<<<<<<< * """Return a list of all values matching the key.""" * return self._getall(self._upper(key), default) */ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_marker); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __pyx_k__2 = __pyx_t_2; __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":100 * raise KeyError('Key not found: %r' % key) * * def getone(self, key, default=_marker): # <<<<<<<<<<<<<< * """Get first value matching the key.""" * return self._getone(self._upper(key), default) */ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_marker); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __pyx_k__3 = __pyx_t_2; __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":210 * return MultiDict(self._items) * * abc.Mapping.register(MultiDictProxy) # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_abc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Mapping); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_register); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) { __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); if (likely(__pyx_t_3)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_1, function); } } if (!__pyx_t_3) { __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict_MultiDictProxy)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); } else { __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __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(((PyObject *)__pyx_ptype_7aiohttp_10_multidict_MultiDictProxy)); __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7aiohttp_10_multidict_MultiDictProxy)); PyTuple_SET_ITEM(__pyx_t_4, 0+1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict_MultiDictProxy)); __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":235 * * * abc.Mapping.register(CIMultiDictProxy) # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_abc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Mapping); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_register); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) { __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1); if (likely(__pyx_t_4)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_1, function); } } if (!__pyx_t_4) { __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict_CIMultiDictProxy)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); } else { __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __pyx_t_4 = NULL; __Pyx_INCREF(((PyObject *)__pyx_ptype_7aiohttp_10_multidict_CIMultiDictProxy)); __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7aiohttp_10_multidict_CIMultiDictProxy)); PyTuple_SET_ITEM(__pyx_t_3, 0+1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict_CIMultiDictProxy)); __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":363 * return default * * def pop(self, key, default=_marker): # <<<<<<<<<<<<<< * """Remove specified key and return the corresponding value. * */ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_marker); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __pyx_k__6 = __pyx_t_2; __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":405 * * * abc.MutableMapping.register(MultiDict) # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_abc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_MutableMapping); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_register); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) { __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); if (likely(__pyx_t_3)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_1, function); } } if (!__pyx_t_3) { __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict_MultiDict)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); } else { __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __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(((PyObject *)__pyx_ptype_7aiohttp_10_multidict_MultiDict)); __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7aiohttp_10_multidict_MultiDict)); PyTuple_SET_ITEM(__pyx_t_4, 0+1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict_MultiDict)); __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":418 * * * abc.MutableMapping.register(CIMultiDict) # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_abc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_MutableMapping); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_register); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) { __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1); if (likely(__pyx_t_4)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_1, function); } } if (!__pyx_t_4) { __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict_CIMultiDict)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); } else { __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __pyx_t_4 = NULL; __Pyx_INCREF(((PyObject *)__pyx_ptype_7aiohttp_10_multidict_CIMultiDict)); __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7aiohttp_10_multidict_CIMultiDict)); PyTuple_SET_ITEM(__pyx_t_3, 0+1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict_CIMultiDict)); __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":550 * * * abc.ItemsView.register(_ItemsView) # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_abc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 550; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ItemsView); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 550; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_register); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 550; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) { __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); if (likely(__pyx_t_3)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_1, function); } } if (!__pyx_t_3) { __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict__ItemsView)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 550; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); } else { __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 550; __pyx_clineno = __LINE__; goto __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(((PyObject *)__pyx_ptype_7aiohttp_10_multidict__ItemsView)); __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7aiohttp_10_multidict__ItemsView)); PyTuple_SET_ITEM(__pyx_t_4, 0+1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict__ItemsView)); __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 550; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":597 * * * abc.ValuesView.register(_ValuesView) # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_abc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ValuesView); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_register); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) { __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1); if (likely(__pyx_t_4)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_1, function); } } if (!__pyx_t_4) { __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict__ValuesView)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); } else { __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __pyx_t_4 = NULL; __Pyx_INCREF(((PyObject *)__pyx_ptype_7aiohttp_10_multidict__ValuesView)); __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7aiohttp_10_multidict__ValuesView)); PyTuple_SET_ITEM(__pyx_t_3, 0+1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict__ValuesView)); __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":653 * * * abc.KeysView.register(_KeysView) # <<<<<<<<<<<<<< */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_abc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 653; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_KeysView); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 653; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_register); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 653; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) { __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); if (likely(__pyx_t_3)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_1, function); } } if (!__pyx_t_3) { __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict__KeysView)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 653; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); } else { __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 653; __pyx_clineno = __LINE__; goto __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(((PyObject *)__pyx_ptype_7aiohttp_10_multidict__KeysView)); __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7aiohttp_10_multidict__KeysView)); PyTuple_SET_ITEM(__pyx_t_4, 0+1, ((PyObject *)__pyx_ptype_7aiohttp_10_multidict__KeysView)); __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 653; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "aiohttp/_multidict.pyx":1 * import sys # <<<<<<<<<<<<<< * from collections import abc * from collections.abc import Iterable, Set */ __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /*--- Wrapped vars code ---*/ goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); if (__pyx_m) { if (__pyx_d) { __Pyx_AddTraceback("init aiohttp._multidict", __pyx_clineno, __pyx_lineno, __pyx_filename); } Py_DECREF(__pyx_m); __pyx_m = 0; } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, "init aiohttp._multidict"); } __pyx_L0:; __Pyx_RefNannyFinishContext(); #if PY_MAJOR_VERSION < 3 return; #else return __pyx_m; #endif } /* --- Runtime support code --- */ #if CYTHON_REFNANNY static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { PyObject *m = NULL, *p = NULL; void *r = NULL; m = PyImport_ImportModule((char *)modname); if (!m) goto end; p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); if (!p) goto end; r = PyLong_AsVoidPtr(p); end: Py_XDECREF(p); Py_XDECREF(m); return (__Pyx_RefNannyAPIStruct *)r; } #endif static PyObject *__Pyx_GetBuiltinName(PyObject *name) { PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); if (unlikely(!result)) { PyErr_Format(PyExc_NameError, #if PY_MAJOR_VERSION >= 3 "name '%U' is not defined", name); #else "name '%.200s' is not defined", PyString_AS_STRING(name)); #endif } return result; } static void __Pyx_RaiseDoubleKeywordsError( const char* func_name, PyObject* kw_name) { PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "%s() got multiple values for keyword argument '%U'", func_name, kw_name); #else "%s() got multiple values for keyword argument '%s'", func_name, PyString_AsString(kw_name)); #endif } static int __Pyx_ParseOptionalKeywords( PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name) { PyObject *key = 0, *value = 0; Py_ssize_t pos = 0; PyObject*** name; PyObject*** first_kw_arg = argnames + num_pos_args; while (PyDict_Next(kwds, &pos, &key, &value)) { name = first_kw_arg; while (*name && (**name != key)) name++; if (*name) { values[name-argnames] = value; continue; } name = first_kw_arg; #if PY_MAJOR_VERSION < 3 if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { while (*name) { if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) && _PyString_Eq(**name, key)) { values[name-argnames] = value; break; } name++; } if (*name) continue; else { PyObject*** argname = argnames; while (argname != first_kw_arg) { if ((**argname == key) || ( (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) && _PyString_Eq(**argname, key))) { goto arg_passed_twice; } argname++; } } } else #endif if (likely(PyUnicode_Check(key))) { while (*name) { int cmp = (**name == key) ? 0 : #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : #endif PyUnicode_Compare(**name, key); if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; if (cmp == 0) { values[name-argnames] = value; break; } name++; } if (*name) continue; else { PyObject*** argname = argnames; while (argname != first_kw_arg) { int cmp = (**argname == key) ? 0 : #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : #endif PyUnicode_Compare(**argname, key); if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; if (cmp == 0) goto arg_passed_twice; argname++; } } } else goto invalid_keyword_type; if (kwds2) { if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; } else { goto invalid_keyword; } } return 0; arg_passed_twice: __Pyx_RaiseDoubleKeywordsError(function_name, key); goto bad; invalid_keyword_type: PyErr_Format(PyExc_TypeError, "%.200s() keywords must be strings", function_name); goto bad; invalid_keyword: PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION < 3 "%.200s() got an unexpected keyword argument '%.200s'", function_name, PyString_AsString(key)); #else "%s() got an unexpected keyword argument '%U'", function_name, key); #endif bad: return -1; } static void __Pyx_RaiseArgtupleInvalid( const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found) { Py_ssize_t num_expected; const char *more_or_less; if (num_found < num_min) { num_expected = num_min; more_or_less = "at least"; } else { num_expected = num_max; more_or_less = "at most"; } if (exact) { more_or_less = "exactly"; } PyErr_Format(PyExc_TypeError, "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", func_name, more_or_less, num_expected, (num_expected == 1) ? "" : "s", num_found); } #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; if (unlikely(!call)) return PyObject_Call(func, arg, kw); if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) return NULL; result = (*call)(func, arg, kw); Py_LeaveRecursiveCall(); if (unlikely(!result) && unlikely(!PyErr_Occurred())) { PyErr_SetString( PyExc_SystemError, "NULL result without error in PyObject_Call"); } return result; } #endif #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { PyObject *self, *result; PyCFunction cfunc; cfunc = PyCFunction_GET_FUNCTION(func); self = PyCFunction_GET_SELF(func); if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) return NULL; result = cfunc(self, arg); Py_LeaveRecursiveCall(); if (unlikely(!result) && unlikely(!PyErr_Occurred())) { PyErr_SetString( PyExc_SystemError, "NULL result without error in PyObject_Call"); } return result; } #endif #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { PyObject *result; PyObject *args = PyTuple_New(1); if (unlikely(!args)) return NULL; Py_INCREF(arg); PyTuple_SET_ITEM(args, 0, arg); result = __Pyx_PyObject_Call(func, args, NULL); Py_DECREF(args); return result; } static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { #ifdef __Pyx_CyFunction_USED if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) { #else if (likely(PyCFunction_Check(func))) { #endif if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { return __Pyx_PyObject_CallMethO(func, arg); } } return __Pyx__PyObject_CallOneArg(func, arg); } #else static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { PyObject *result; PyObject *args = PyTuple_Pack(1, arg); if (unlikely(!args)) return NULL; result = __Pyx_PyObject_Call(func, args, NULL); Py_DECREF(args); return result; } #endif #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { #ifdef __Pyx_CyFunction_USED if (likely(PyCFunction_Check(func) || PyObject_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 static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { PyObject *result; #if CYTHON_COMPILING_IN_CPYTHON result = PyDict_GetItem(__pyx_d, name); if (likely(result)) { Py_INCREF(result); } else { #else result = PyObject_GetItem(__pyx_d, name); if (!result) { PyErr_Clear(); #endif result = __Pyx_GetBuiltinName(name); } return result; } #if CYTHON_USE_PYLONG_INTERNALS #include "longintrepr.h" #endif #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, CYTHON_UNUSED int inplace) { if (op1 == op2) { Py_RETURN_TRUE; } #if PY_MAJOR_VERSION < 3 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; } } #endif #if CYTHON_USE_PYLONG_INTERNALS && PY_MAJOR_VERSION >= 3 if (likely(PyLong_CheckExact(op1))) { const long b = intval; long a; 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; } 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; } case 2: if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); break; } 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; } 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; } 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; } 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; } #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 { 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; } } return PyObject_RichCompare(op1, op2, Py_EQ); } #endif static CYTHON_INLINE int __Pyx_CheckKeywordStrings( PyObject *kwdict, const char* function_name, int kw_allowed) { PyObject* key = 0; Py_ssize_t pos = 0; #if CYTHON_COMPILING_IN_PYPY if (!kw_allowed && PyDict_Next(kwdict, &pos, &key, 0)) goto invalid_keyword; return 1; #else while (PyDict_Next(kwdict, &pos, &key, 0)) { #if PY_MAJOR_VERSION < 3 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) #endif if (unlikely(!PyUnicode_Check(key))) goto invalid_keyword_type; } if ((!kw_allowed) && unlikely(key)) goto invalid_keyword; return 1; invalid_keyword_type: PyErr_Format(PyExc_TypeError, "%.200s() keywords must be strings", function_name); return 0; #endif invalid_keyword: PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION < 3 "%.200s() got an unexpected keyword argument '%.200s'", function_name, PyString_AsString(key)); #else "%s() got an unexpected keyword argument '%U'", function_name, key); #endif return 0; } 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 if (s1 == s2) { return (equals == Py_EQ); } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { const char *ps1, *ps2; Py_ssize_t length = PyBytes_GET_SIZE(s1); if (length != PyBytes_GET_SIZE(s2)) return (equals == Py_NE); ps1 = PyBytes_AS_STRING(s1); ps2 = PyBytes_AS_STRING(s2); if (ps1[0] != ps2[0]) { return (equals == Py_NE); } else if (length == 1) { return (equals == Py_EQ); } else { int result = memcmp(ps1, ps2, (size_t)length); return (equals == Py_EQ) ? (result == 0) : (result != 0); } } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { return (equals == Py_NE); } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { return (equals == Py_NE); } else { int result; PyObject* py_result = PyObject_RichCompare(s1, s2, equals); if (!py_result) return -1; result = __Pyx_PyObject_IsTrue(py_result); Py_DECREF(py_result); return result; } #endif } 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 #if PY_MAJOR_VERSION < 3 PyObject* owned_ref = NULL; #endif int s1_is_unicode, s2_is_unicode; if (s1 == s2) { goto return_eq; } s1_is_unicode = PyUnicode_CheckExact(s1); s2_is_unicode = PyUnicode_CheckExact(s2); #if PY_MAJOR_VERSION < 3 if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { owned_ref = PyUnicode_FromObject(s2); if (unlikely(!owned_ref)) return -1; s2 = owned_ref; s2_is_unicode = 1; } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { owned_ref = PyUnicode_FromObject(s1); if (unlikely(!owned_ref)) return -1; s1 = owned_ref; s1_is_unicode = 1; } else if (((!s2_is_unicode) & (!s1_is_unicode))) { return __Pyx_PyBytes_Equals(s1, s2, equals); } #endif if (s1_is_unicode & s2_is_unicode) { Py_ssize_t length; int kind; void *data1, *data2; if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) return -1; length = __Pyx_PyUnicode_GET_LENGTH(s1); if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { goto return_ne; } kind = __Pyx_PyUnicode_KIND(s1); if (kind != __Pyx_PyUnicode_KIND(s2)) { goto return_ne; } data1 = __Pyx_PyUnicode_DATA(s1); data2 = __Pyx_PyUnicode_DATA(s2); if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { goto return_ne; } else if (length == 1) { goto return_eq; } else { int result = memcmp(data1, data2, (size_t)(length * kind)); #if PY_MAJOR_VERSION < 3 Py_XDECREF(owned_ref); #endif return (equals == Py_EQ) ? (result == 0) : (result != 0); } } else if ((s1 == Py_None) & s2_is_unicode) { goto return_ne; } else if ((s2 == Py_None) & s1_is_unicode) { goto return_ne; } else { int result; PyObject* py_result = PyObject_RichCompare(s1, s2, equals); if (!py_result) return -1; result = __Pyx_PyObject_IsTrue(py_result); Py_DECREF(py_result); return result; } return_eq: #if PY_MAJOR_VERSION < 3 Py_XDECREF(owned_ref); #endif return (equals == Py_EQ); return_ne: #if PY_MAJOR_VERSION < 3 Py_XDECREF(owned_ref); #endif return (equals == Py_NE); #endif } static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) { #if CYTHON_COMPILING_IN_CPYTHON PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); tmp_type = tstate->curexc_type; tmp_value = tstate->curexc_value; tmp_tb = tstate->curexc_traceback; tstate->curexc_type = type; tstate->curexc_value = value; tstate->curexc_traceback = tb; Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); #else PyErr_Restore(type, value, tb); #endif } static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) { #if CYTHON_COMPILING_IN_CPYTHON PyThreadState *tstate = PyThreadState_GET(); *type = tstate->curexc_type; *value = tstate->curexc_value; *tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; #else PyErr_Fetch(type, value, tb); #endif } #if PY_MAJOR_VERSION < 3 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, CYTHON_UNUSED PyObject *cause) { Py_XINCREF(type); if (!value || value == Py_None) value = NULL; else Py_INCREF(value); if (!tb || tb == Py_None) tb = NULL; else { Py_INCREF(tb); if (!PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "raise: arg 3 must be a traceback or None"); goto raise_error; } } if (PyType_Check(type)) { #if CYTHON_COMPILING_IN_PYPY if (!value) { Py_INCREF(Py_None); value = Py_None; } #endif PyErr_NormalizeException(&type, &value, &tb); } else { if (value) { PyErr_SetString(PyExc_TypeError, "instance exception may not have a separate value"); goto raise_error; } value = type; type = (PyObject*) Py_TYPE(type); Py_INCREF(type); if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { PyErr_SetString(PyExc_TypeError, "raise: exception class must be a subclass of BaseException"); goto raise_error; } } __Pyx_ErrRestore(type, value, tb); return; raise_error: Py_XDECREF(value); Py_XDECREF(type); Py_XDECREF(tb); return; } #else static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { PyObject* owned_instance = NULL; if (tb == Py_None) { tb = 0; } else if (tb && !PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "raise: arg 3 must be a traceback or None"); goto bad; } if (value == Py_None) value = 0; if (PyExceptionInstance_Check(type)) { if (value) { PyErr_SetString(PyExc_TypeError, "instance exception may not have a separate value"); goto bad; } value = type; type = (PyObject*) Py_TYPE(value); } else if (PyExceptionClass_Check(type)) { PyObject *instance_class = NULL; if (value && PyExceptionInstance_Check(value)) { instance_class = (PyObject*) Py_TYPE(value); if (instance_class != type) { int is_subclass = PyObject_IsSubclass(instance_class, type); if (!is_subclass) { instance_class = NULL; } else if (unlikely(is_subclass == -1)) { goto bad; } else { type = instance_class; } } } if (!instance_class) { PyObject *args; if (!value) args = PyTuple_New(0); else if (PyTuple_Check(value)) { Py_INCREF(value); args = value; } else args = PyTuple_Pack(1, value); if (!args) goto bad; owned_instance = PyObject_Call(type, args, NULL); Py_DECREF(args); if (!owned_instance) goto bad; value = owned_instance; if (!PyExceptionInstance_Check(value)) { PyErr_Format(PyExc_TypeError, "calling %R should have returned an instance of " "BaseException, not %R", type, Py_TYPE(value)); goto bad; } } } else { PyErr_SetString(PyExc_TypeError, "raise: exception class must be a subclass of BaseException"); goto bad; } #if PY_VERSION_HEX >= 0x03030000 if (cause) { #else if (cause && cause != Py_None) { #endif PyObject *fixed_cause; if (cause == Py_None) { fixed_cause = NULL; } else if (PyExceptionClass_Check(cause)) { fixed_cause = PyObject_CallObject(cause, NULL); if (fixed_cause == NULL) goto bad; } else if (PyExceptionInstance_Check(cause)) { fixed_cause = cause; Py_INCREF(fixed_cause); } else { PyErr_SetString(PyExc_TypeError, "exception causes must derive from " "BaseException"); goto bad; } PyException_SetCause(value, fixed_cause); } PyErr_SetObject(type, value); if (tb) { #if CYTHON_COMPILING_IN_PYPY PyObject *tmp_type, *tmp_value, *tmp_tb; PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); Py_INCREF(tb); PyErr_Restore(tmp_type, tmp_value, tb); Py_XDECREF(tmp_tb); #else PyThreadState *tstate = PyThreadState_GET(); PyObject* tmp_tb = tstate->curexc_traceback; if (tb != tmp_tb) { Py_INCREF(tb); tstate->curexc_traceback = tb; Py_XDECREF(tmp_tb); } #endif } bad: Py_XDECREF(owned_instance); return; } #endif #if !CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values) { return PyObject_CallMethodObjArgs(sep, __pyx_n_s_join, values, NULL); } #endif static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { if (unlikely(!type)) { PyErr_SetString(PyExc_SystemError, "Missing type object"); return 0; } if (likely(PyObject_TypeCheck(obj, type))) return 1; PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", Py_TYPE(obj)->tp_name, type->tp_name); return 0; } static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { PyObject *r; if (!j) return NULL; r = PyObject_GetItem(o, j); Py_DECREF(j); return r; } static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { #if CYTHON_COMPILING_IN_CPYTHON if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o); if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) { PyObject *r = PyList_GET_ITEM(o, i); Py_INCREF(r); return r; } return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); #else return PySequence_GetItem(o, i); #endif } static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { #if CYTHON_COMPILING_IN_CPYTHON if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o); if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, i); Py_INCREF(r); return r; } return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); #else return PySequence_GetItem(o, i); #endif } static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { #if CYTHON_COMPILING_IN_CPYTHON 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))))) { PyObject *r = PyList_GET_ITEM(o, n); Py_INCREF(r); return r; } } 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)))) { PyObject *r = PyTuple_GET_ITEM(o, n); Py_INCREF(r); return r; } } else { PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; if (likely(m && m->sq_item)) { if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { Py_ssize_t l = m->sq_length(o); if (likely(l >= 0)) { i += l; } else { if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_Clear(); else return NULL; } } return m->sq_item(o, i); } } #else if (is_list || PySequence_Check(o)) { return PySequence_GetItem(o, i); } #endif return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); } static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { PyObject *method; method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); if (unlikely(!method)) return -1; target->method = method; #if CYTHON_COMPILING_IN_CPYTHON #if PY_MAJOR_VERSION >= 3 if (likely(PyObject_TypeCheck(method, &PyMethodDescr_Type))) #endif { PyMethodDescrObject *descr = (PyMethodDescrObject*) method; target->func = descr->d_method->ml_meth; target->flag = descr->d_method->ml_flags & (METH_VARARGS | METH_KEYWORDS | METH_O | METH_NOARGS); } #endif return 0; } static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { PyObject *args, *result = NULL; if (unlikely(!cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; #if CYTHON_COMPILING_IN_CPYTHON args = PyTuple_New(1); if (unlikely(!args)) goto bad; Py_INCREF(self); PyTuple_SET_ITEM(args, 0, self); #else args = PyTuple_Pack(1, self); if (unlikely(!args)) goto bad; #endif result = __Pyx_PyObject_Call(cfunc->method, args, NULL); Py_DECREF(args); bad: return result; } static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d) { if (PY_MAJOR_VERSION >= 3) return __Pyx_CallUnboundCMethod0(&__pyx_umethod_PyDict_Type_items, d); else return PyDict_Items(d); } 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); } 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"); } static CYTHON_INLINE int __Pyx_IterFinish(void) { #if CYTHON_COMPILING_IN_CPYTHON PyThreadState *tstate = PyThreadState_GET(); PyObject* exc_type = tstate->curexc_type; if (unlikely(exc_type)) { if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) { PyObject *exc_value, *exc_tb; exc_value = tstate->curexc_value; exc_tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; Py_DECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_tb); return 0; } else { return -1; } } return 0; #else if (unlikely(PyErr_Occurred())) { if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { PyErr_Clear(); return 0; } else { return -1; } } return 0; #endif } static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { if (unlikely(retval)) { Py_DECREF(retval); __Pyx_RaiseTooManyValuesError(expected); return -1; } else { return __Pyx_IterFinish(); } return 0; } static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) { int r; if (!j) return -1; r = PyObject_DelItem(o, j); Py_DECREF(j); return r; } static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, CYTHON_UNUSED int is_list, CYTHON_NCP_UNUSED int wraparound) { #if CYTHON_COMPILING_IN_PYPY if (is_list || PySequence_Check(o)) { return PySequence_DelItem(o, i); } #else PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; if (likely(m && m->sq_ass_item)) { if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { Py_ssize_t l = m->sq_length(o); if (likely(l >= 0)) { i += l; } else { if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_Clear(); else return -1; } } return m->sq_ass_item(o, i, (PyObject *)NULL); } #endif return __Pyx_DelItem_Generic(o, PyInt_FromSsize_t(i)); } static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { PyObject *method, *result = NULL; method = __Pyx_PyObject_GetAttrStr(obj, method_name); if (unlikely(!method)) goto bad; #if CYTHON_COMPILING_IN_CPYTHON if (likely(PyMethod_Check(method))) { PyObject *self = PyMethod_GET_SELF(method); if (likely(self)) { PyObject *args; PyObject *function = PyMethod_GET_FUNCTION(method); args = PyTuple_New(2); if (unlikely(!args)) goto bad; Py_INCREF(self); PyTuple_SET_ITEM(args, 0, self); Py_INCREF(arg); PyTuple_SET_ITEM(args, 1, arg); Py_INCREF(function); Py_DECREF(method); method = NULL; result = __Pyx_PyObject_Call(function, args, NULL); Py_DECREF(args); Py_DECREF(function); return result; } } #endif result = __Pyx_PyObject_CallOneArg(method, arg); bad: Py_XDECREF(method); return result; } 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); Py_DECREF(py_ix); return r; } static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix) { return __Pyx_PyObject_CallMethod1(L, __pyx_n_s_pop, py_ix); } #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix) { Py_ssize_t size = PyList_GET_SIZE(L); if (likely(size > (((PyListObject*)L)->allocated >> 1))) { Py_ssize_t cix = ix; if (cix < 0) { cix += size; } if (likely(0 <= cix && cix < size)) { PyObject* v = PyList_GET_ITEM(L, cix); Py_SIZE(L) -= 1; size -= 1; memmove(&PyList_GET_ITEM(L, cix), &PyList_GET_ITEM(L, cix+1), (size_t)(size-cix)*sizeof(PyObject*)); return v; } } if (py_ix == Py_None) { return __Pyx__PyObject_PopNewIndex(L, PyInt_FromSsize_t(ix)); } else { return __Pyx__PyObject_PopIndex(L, py_ix); } } #endif static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) { PyErr_Format(PyExc_TypeError, "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", name, type->tp_name, Py_TYPE(obj)->tp_name); } static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, const char *name, int exact) { if (unlikely(!type)) { PyErr_SetString(PyExc_SystemError, "Missing type object"); return 0; } if (none_allowed && obj == Py_None) return 1; else if (exact) { if (likely(Py_TYPE(obj) == type)) return 1; #if PY_MAJOR_VERSION == 2 else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; #endif } else { if (likely(PyObject_TypeCheck(obj, type))) return 1; } __Pyx_RaiseArgumentTypeInvalid(name, obj, type); return 0; } static int __Pyx_SetVtable(PyObject *dict, void *vtable) { #if PY_VERSION_HEX >= 0x02070000 PyObject *ob = PyCapsule_New(vtable, 0, 0); #else PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); #endif if (!ob) goto bad; if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0) goto bad; Py_DECREF(ob); return 0; bad: Py_XDECREF(ob); return -1; } static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { PyObject *empty_list = 0; PyObject *module = 0; PyObject *global_dict = 0; PyObject *empty_dict = 0; PyObject *list; #if PY_VERSION_HEX < 0x03030000 PyObject *py_import; py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); if (!py_import) goto bad; #endif if (from_list) list = from_list; else { empty_list = PyList_New(0); if (!empty_list) goto bad; list = empty_list; } global_dict = PyModule_GetDict(__pyx_m); if (!global_dict) goto bad; empty_dict = PyDict_New(); if (!empty_dict) goto bad; { #if PY_MAJOR_VERSION >= 3 if (level == -1) { if (strchr(__Pyx_MODULE_NAME, '.')) { #if PY_VERSION_HEX < 0x03030000 PyObject *py_level = PyInt_FromLong(1); if (!py_level) goto bad; module = PyObject_CallFunctionObjArgs(py_import, name, global_dict, empty_dict, list, py_level, NULL); Py_DECREF(py_level); #else module = PyImport_ImportModuleLevelObject( name, global_dict, empty_dict, list, 1); #endif if (!module) { if (!PyErr_ExceptionMatches(PyExc_ImportError)) goto bad; PyErr_Clear(); } } level = 0; } #endif if (!module) { #if PY_VERSION_HEX < 0x03030000 PyObject *py_level = PyInt_FromLong(level); if (!py_level) goto bad; module = PyObject_CallFunctionObjArgs(py_import, name, global_dict, empty_dict, list, py_level, NULL); Py_DECREF(py_level); #else module = PyImport_ImportModuleLevelObject( name, global_dict, empty_dict, list, level); #endif } } bad: #if PY_VERSION_HEX < 0x03030000 Py_XDECREF(py_import); #endif Py_XDECREF(empty_list); Py_XDECREF(empty_dict); return module; } 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, #if PY_MAJOR_VERSION < 3 "cannot import name %.230s", PyString_AS_STRING(name)); #else "cannot import name %S", name); #endif } return value; } static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) { Py_ssize_t i, nbases = PyTuple_GET_SIZE(bases); for (i=0; i < nbases; i++) { PyTypeObject *tmptype; PyObject *tmp = PyTuple_GET_ITEM(bases, i); tmptype = Py_TYPE(tmp); #if PY_MAJOR_VERSION < 3 if (tmptype == &PyClass_Type) continue; #endif if (!metaclass) { metaclass = tmptype; continue; } if (PyType_IsSubtype(metaclass, tmptype)) continue; if (PyType_IsSubtype(tmptype, metaclass)) { metaclass = tmptype; continue; } PyErr_SetString(PyExc_TypeError, "metaclass conflict: " "the metaclass of a derived class " "must be a (non-strict) subclass " "of the metaclasses of all its bases"); return NULL; } if (!metaclass) { #if PY_MAJOR_VERSION < 3 metaclass = &PyClass_Type; #else metaclass = &PyType_Type; #endif } Py_INCREF((PyObject*) metaclass); return (PyObject*) metaclass; } static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { PyObject* fake_module; PyTypeObject* cached_type = NULL; fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI); if (!fake_module) return NULL; Py_INCREF(fake_module); cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name); if (cached_type) { if (!PyType_Check((PyObject*)cached_type)) { PyErr_Format(PyExc_TypeError, "Shared Cython type %.200s is not a type object", type->tp_name); goto bad; } if (cached_type->tp_basicsize != type->tp_basicsize) { PyErr_Format(PyExc_TypeError, "Shared Cython type %.200s has the wrong size, try recompiling", type->tp_name); goto bad; } } else { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; PyErr_Clear(); if (PyType_Ready(type) < 0) goto bad; if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0) goto bad; Py_INCREF(type); cached_type = type; } done: Py_DECREF(fake_module); return cached_type; bad: Py_XDECREF(cached_type); cached_type = NULL; goto done; } static PyObject * __Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure) { if (unlikely(op->func_doc == NULL)) { if (op->func.m_ml->ml_doc) { #if PY_MAJOR_VERSION >= 3 op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc); #else op->func_doc = PyString_FromString(op->func.m_ml->ml_doc); #endif if (unlikely(op->func_doc == NULL)) return NULL; } else { Py_INCREF(Py_None); return Py_None; } } Py_INCREF(op->func_doc); return op->func_doc; } static int __Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value) { PyObject *tmp = op->func_doc; if (value == NULL) { value = Py_None; } Py_INCREF(value); op->func_doc = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op) { if (unlikely(op->func_name == NULL)) { #if PY_MAJOR_VERSION >= 3 op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name); #else op->func_name = PyString_InternFromString(op->func.m_ml->ml_name); #endif if (unlikely(op->func_name == NULL)) return NULL; } Py_INCREF(op->func_name); return op->func_name; } static int __Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value) { PyObject *tmp; #if PY_MAJOR_VERSION >= 3 if (unlikely(value == NULL || !PyUnicode_Check(value))) { #else if (unlikely(value == NULL || !PyString_Check(value))) { #endif PyErr_SetString(PyExc_TypeError, "__name__ must be set to a string object"); return -1; } tmp = op->func_name; Py_INCREF(value); op->func_name = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op) { Py_INCREF(op->func_qualname); return op->func_qualname; } static int __Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value) { PyObject *tmp; #if PY_MAJOR_VERSION >= 3 if (unlikely(value == NULL || !PyUnicode_Check(value))) { #else if (unlikely(value == NULL || !PyString_Check(value))) { #endif PyErr_SetString(PyExc_TypeError, "__qualname__ must be set to a string object"); return -1; } tmp = op->func_qualname; Py_INCREF(value); op->func_qualname = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure) { PyObject *self; self = m->func_closure; if (self == NULL) self = Py_None; Py_INCREF(self); return self; } static PyObject * __Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op) { if (unlikely(op->func_dict == NULL)) { op->func_dict = PyDict_New(); if (unlikely(op->func_dict == NULL)) return NULL; } Py_INCREF(op->func_dict); return op->func_dict; } static int __Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value) { PyObject *tmp; if (unlikely(value == NULL)) { PyErr_SetString(PyExc_TypeError, "function's dictionary may not be deleted"); return -1; } if (unlikely(!PyDict_Check(value))) { PyErr_SetString(PyExc_TypeError, "setting function's dictionary to a non-dict"); return -1; } tmp = op->func_dict; Py_INCREF(value); op->func_dict = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op) { Py_INCREF(op->func_globals); return op->func_globals; } static PyObject * __Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op) { Py_INCREF(Py_None); return Py_None; } static PyObject * __Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op) { PyObject* result = (op->func_code) ? op->func_code : Py_None; Py_INCREF(result); return result; } static int __Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { int result = 0; PyObject *res = op->defaults_getter((PyObject *) op); if (unlikely(!res)) return -1; #if CYTHON_COMPILING_IN_CPYTHON op->defaults_tuple = PyTuple_GET_ITEM(res, 0); Py_INCREF(op->defaults_tuple); op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); Py_INCREF(op->defaults_kwdict); #else op->defaults_tuple = PySequence_ITEM(res, 0); if (unlikely(!op->defaults_tuple)) result = -1; else { op->defaults_kwdict = PySequence_ITEM(res, 1); if (unlikely(!op->defaults_kwdict)) result = -1; } #endif Py_DECREF(res); return result; } static int __Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value) { PyObject* tmp; if (!value) { value = Py_None; } else if (value != Py_None && !PyTuple_Check(value)) { PyErr_SetString(PyExc_TypeError, "__defaults__ must be set to a tuple object"); return -1; } Py_INCREF(value); tmp = op->defaults_tuple; op->defaults_tuple = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op) { PyObject* result = op->defaults_tuple; if (unlikely(!result)) { if (op->defaults_getter) { if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL; result = op->defaults_tuple; } else { result = Py_None; } } Py_INCREF(result); return result; } static int __Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value) { PyObject* tmp; if (!value) { value = Py_None; } else if (value != Py_None && !PyDict_Check(value)) { PyErr_SetString(PyExc_TypeError, "__kwdefaults__ must be set to a dict object"); return -1; } Py_INCREF(value); tmp = op->defaults_kwdict; op->defaults_kwdict = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op) { PyObject* result = op->defaults_kwdict; if (unlikely(!result)) { if (op->defaults_getter) { if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL; result = op->defaults_kwdict; } else { result = Py_None; } } Py_INCREF(result); return result; } static int __Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value) { PyObject* tmp; if (!value || value == Py_None) { value = NULL; } else if (!PyDict_Check(value)) { PyErr_SetString(PyExc_TypeError, "__annotations__ must be set to a dict object"); return -1; } Py_XINCREF(value); tmp = op->func_annotations; op->func_annotations = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op) { PyObject* result = op->func_annotations; if (unlikely(!result)) { result = PyDict_New(); if (unlikely(!result)) return NULL; op->func_annotations = result; } Py_INCREF(result); return result; } static PyGetSetDef __pyx_CyFunction_getsets[] = { {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0}, {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, {0, 0, 0, 0, 0} }; static PyMemberDef __pyx_CyFunction_members[] = { {(char *) "__module__", T_OBJECT, offsetof(__pyx_CyFunctionObject, func.m_module), PY_WRITE_RESTRICTED, 0}, {0, 0, 0, 0, 0} }; static PyObject * __Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args) { #if PY_MAJOR_VERSION >= 3 return PyUnicode_FromString(m->func.m_ml->ml_name); #else return PyString_FromString(m->func.m_ml->ml_name); #endif } static PyMethodDef __pyx_CyFunction_methods[] = { {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, {0, 0, 0, 0} }; #if PY_VERSION_HEX < 0x030500A0 #define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) #else #define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist) #endif static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname, PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type); if (op == NULL) return NULL; op->flags = flags; __Pyx_CyFunction_weakreflist(op) = NULL; op->func.m_ml = ml; op->func.m_self = (PyObject *) op; Py_XINCREF(closure); op->func_closure = closure; Py_XINCREF(module); op->func.m_module = module; op->func_dict = NULL; op->func_name = NULL; Py_INCREF(qualname); op->func_qualname = qualname; op->func_doc = NULL; op->func_classobj = NULL; op->func_globals = globals; Py_INCREF(op->func_globals); Py_XINCREF(code); op->func_code = code; op->defaults_pyobjects = 0; op->defaults = NULL; op->defaults_tuple = NULL; op->defaults_kwdict = NULL; op->defaults_getter = NULL; op->func_annotations = NULL; PyObject_GC_Track(op); return (PyObject *) op; } static int __Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) { Py_CLEAR(m->func_closure); Py_CLEAR(m->func.m_module); Py_CLEAR(m->func_dict); Py_CLEAR(m->func_name); Py_CLEAR(m->func_qualname); Py_CLEAR(m->func_doc); Py_CLEAR(m->func_globals); Py_CLEAR(m->func_code); Py_CLEAR(m->func_classobj); Py_CLEAR(m->defaults_tuple); Py_CLEAR(m->defaults_kwdict); Py_CLEAR(m->func_annotations); if (m->defaults) { PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); int i; for (i = 0; i < m->defaults_pyobjects; i++) Py_XDECREF(pydefaults[i]); PyMem_Free(m->defaults); m->defaults = NULL; } return 0; } static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) { PyObject_GC_UnTrack(m); if (__Pyx_CyFunction_weakreflist(m) != NULL) PyObject_ClearWeakRefs((PyObject *) m); __Pyx_CyFunction_clear(m); PyObject_GC_Del(m); } static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) { Py_VISIT(m->func_closure); Py_VISIT(m->func.m_module); Py_VISIT(m->func_dict); Py_VISIT(m->func_name); Py_VISIT(m->func_qualname); Py_VISIT(m->func_doc); Py_VISIT(m->func_globals); Py_VISIT(m->func_code); Py_VISIT(m->func_classobj); Py_VISIT(m->defaults_tuple); Py_VISIT(m->defaults_kwdict); if (m->defaults) { PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); int i; for (i = 0; i < m->defaults_pyobjects; i++) Py_VISIT(pydefaults[i]); } return 0; } static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) { Py_INCREF(func); return func; } if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) { if (type == NULL) type = (PyObject *)(Py_TYPE(obj)); return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type))); } if (obj == Py_None) obj = NULL; return __Pyx_PyMethod_New(func, obj, type); } static PyObject* __Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) { #if PY_MAJOR_VERSION >= 3 return PyUnicode_FromFormat("", op->func_qualname, (void *)op); #else return PyString_FromFormat("", PyString_AsString(op->func_qualname), (void *)op); #endif } #if CYTHON_COMPILING_IN_PYPY static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { PyCFunctionObject* f = (PyCFunctionObject*)func; PyCFunction meth = f->m_ml->ml_meth; PyObject *self = f->m_self; Py_ssize_t size; switch (f->m_ml->ml_flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { case METH_VARARGS: if (likely(kw == NULL || PyDict_Size(kw) == 0)) return (*meth)(self, arg); break; case METH_VARARGS | METH_KEYWORDS: return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); case METH_NOARGS: if (likely(kw == NULL || PyDict_Size(kw) == 0)) { size = PyTuple_GET_SIZE(arg); if (likely(size == 0)) return (*meth)(self, NULL); PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", f->m_ml->ml_name, size); return NULL; } break; case METH_O: if (likely(kw == NULL || PyDict_Size(kw) == 0)) { size = PyTuple_GET_SIZE(arg); if (likely(size == 1)) { PyObject *result, *arg0 = PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; result = (*meth)(self, arg0); Py_DECREF(arg0); return result; } PyErr_Format(PyExc_TypeError, "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", f->m_ml->ml_name, size); return NULL; } break; default: PyErr_SetString(PyExc_SystemError, "Bad call flags in " "__Pyx_CyFunction_Call. METH_OLDARGS is no " "longer supported!"); return NULL; } PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", f->m_ml->ml_name); return NULL; } #else static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { return PyCFunction_Call(func, arg, kw); } #endif static PyTypeObject __pyx_CyFunctionType_type = { PyVarObject_HEAD_INIT(0, 0) "cython_function_or_method", sizeof(__pyx_CyFunctionObject), 0, (destructor) __Pyx_CyFunction_dealloc, 0, 0, 0, #if PY_MAJOR_VERSION < 3 0, #else 0, #endif (reprfunc) __Pyx_CyFunction_repr, 0, 0, 0, 0, __Pyx_CyFunction_Call, 0, 0, 0, 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, 0, (traverseproc) __Pyx_CyFunction_traverse, (inquiry) __Pyx_CyFunction_clear, 0, #if PY_VERSION_HEX < 0x030500A0 offsetof(__pyx_CyFunctionObject, func_weakreflist), #else offsetof(PyCFunctionObject, m_weakreflist), #endif 0, 0, __pyx_CyFunction_methods, __pyx_CyFunction_members, __pyx_CyFunction_getsets, 0, 0, __Pyx_CyFunction_descr_get, 0, offsetof(__pyx_CyFunctionObject, func_dict), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, #if PY_VERSION_HEX >= 0x030400a1 0, #endif }; static int __pyx_CyFunction_init(void) { #if !CYTHON_COMPILING_IN_PYPY __pyx_CyFunctionType_type.tp_call = PyCFunction_Call; #endif __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); if (__pyx_CyFunctionType == NULL) { return -1; } return 0; } static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; m->defaults = PyMem_Malloc(size); if (!m->defaults) return PyErr_NoMemory(); memset(m->defaults, 0, size); m->defaults_pyobjects = pyobjects; return m->defaults; } static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; m->defaults_tuple = tuple; Py_INCREF(tuple); } static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; m->defaults_kwdict = dict; Py_INCREF(dict); } static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; m->func_annotations = dict; Py_INCREF(dict); } static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) { PyObject *ns; if (metaclass) { PyObject *prep = __Pyx_PyObject_GetAttrStr(metaclass, __pyx_n_s_prepare); if (prep) { PyObject *pargs = PyTuple_Pack(2, name, bases); if (unlikely(!pargs)) { Py_DECREF(prep); return NULL; } ns = PyObject_Call(prep, pargs, mkw); Py_DECREF(prep); Py_DECREF(pargs); } else { if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError))) return NULL; PyErr_Clear(); ns = PyDict_New(); } } else { ns = PyDict_New(); } if (unlikely(!ns)) return NULL; if (unlikely(PyObject_SetItem(ns, __pyx_n_s_module, modname) < 0)) goto bad; if (unlikely(PyObject_SetItem(ns, __pyx_n_s_qualname, qualname) < 0)) goto bad; if (unlikely(doc && PyObject_SetItem(ns, __pyx_n_s_doc, doc) < 0)) goto bad; return ns; bad: Py_DECREF(ns); return NULL; } static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass) { PyObject *result, *margs; PyObject *owned_metaclass = NULL; if (allow_py2_metaclass) { owned_metaclass = PyObject_GetItem(dict, __pyx_n_s_metaclass); if (owned_metaclass) { metaclass = owned_metaclass; } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) { PyErr_Clear(); } else { return NULL; } } if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) { metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases); Py_XDECREF(owned_metaclass); if (unlikely(!metaclass)) return NULL; owned_metaclass = metaclass; } margs = PyTuple_Pack(3, name, bases, dict); if (unlikely(!margs)) { result = NULL; } else { result = PyObject_Call(metaclass, margs, mkw); Py_DECREF(margs); } Py_XDECREF(owned_metaclass); return result; } 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; } while (start < end) { mid = start + (end - start) / 2; if (code_line < entries[mid].code_line) { end = mid; } else if (code_line > entries[mid].code_line) { start = mid + 1; } else { return mid; } } if (code_line <= entries[mid].code_line) { return mid; } else { return mid + 1; } } static PyCodeObject *__pyx_find_code_object(int code_line) { PyCodeObject* code_object; int pos; if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { return NULL; } pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { return NULL; } code_object = __pyx_code_cache.entries[pos].code_object; Py_INCREF(code_object); return code_object; } static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { int pos, i; __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; if (unlikely(!code_line)) { return; } if (unlikely(!entries)) { entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); if (likely(entries)) { __pyx_code_cache.entries = entries; __pyx_code_cache.max_count = 64; __pyx_code_cache.count = 1; entries[0].code_line = code_line; entries[0].code_object = code_object; Py_INCREF(code_object); } return; } pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { PyCodeObject* tmp = entries[pos].code_object; entries[pos].code_object = code_object; Py_DECREF(tmp); return; } if (__pyx_code_cache.count == __pyx_code_cache.max_count) { int new_max = __pyx_code_cache.max_count + 64; entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); if (unlikely(!entries)) { return; } __pyx_code_cache.entries = entries; __pyx_code_cache.max_count = new_max; } for (i=__pyx_code_cache.count; i>pos; i--) { entries[i] = entries[i-1]; } entries[pos].code_line = code_line; entries[pos].code_object = code_object; __pyx_code_cache.count++; Py_INCREF(code_object); } #include "compile.h" #include "frameobject.h" #include "traceback.h" static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( const char *funcname, int c_line, int py_line, const char *filename) { PyCodeObject *py_code = 0; PyObject *py_srcfile = 0; PyObject *py_funcname = 0; #if PY_MAJOR_VERSION < 3 py_srcfile = PyString_FromString(filename); #else py_srcfile = PyUnicode_FromString(filename); #endif if (!py_srcfile) goto bad; if (c_line) { #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); #else py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); #endif } else { #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromString(funcname); #else py_funcname = PyUnicode_FromString(funcname); #endif } if (!py_funcname) goto bad; py_code = __Pyx_PyCode_New( 0, 0, 0, 0, 0, __pyx_empty_bytes, /*PyObject *code,*/ __pyx_empty_tuple, /*PyObject *consts,*/ __pyx_empty_tuple, /*PyObject *names,*/ __pyx_empty_tuple, /*PyObject *varnames,*/ __pyx_empty_tuple, /*PyObject *freevars,*/ __pyx_empty_tuple, /*PyObject *cellvars,*/ py_srcfile, /*PyObject *filename,*/ py_funcname, /*PyObject *name,*/ py_line, __pyx_empty_bytes /*PyObject *lnotab*/ ); Py_DECREF(py_srcfile); Py_DECREF(py_funcname); return py_code; bad: Py_XDECREF(py_srcfile); Py_XDECREF(py_funcname); return NULL; } static void __Pyx_AddTraceback(const char *funcname, int c_line, int py_line, const char *filename) { PyCodeObject *py_code = 0; PyFrameObject *py_frame = 0; py_code = __pyx_find_code_object(c_line ? c_line : py_line); if (!py_code) { py_code = __Pyx_CreateCodeObjectForTraceback( funcname, c_line, py_line, filename); if (!py_code) goto bad; __pyx_insert_code_object(c_line ? c_line : py_line, py_code); } py_frame = PyFrame_New( PyThreadState_GET(), /*PyThreadState *tstate,*/ py_code, /*PyCodeObject *code,*/ __pyx_d, /*PyObject *globals,*/ 0 /*PyObject *locals*/ ); if (!py_frame) goto bad; py_frame->f_lineno = py_line; PyTraceBack_Here(py_frame); bad: Py_XDECREF(py_code); Py_XDECREF(py_frame); } static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { const int neg_one = (int) -1, const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(int) < sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(int) <= sizeof(unsigned long)) { return PyLong_FromUnsignedLong((unsigned long) value); } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); } } else { if (sizeof(int) <= sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { return PyLong_FromLongLong((PY_LONG_LONG) value); } } { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; return _PyLong_FromByteArray(bytes, sizeof(int), little, !is_unsigned); } } #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) #define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ {\ func_type value = func_value;\ if (sizeof(target_type) < sizeof(func_type)) {\ if (unlikely(value != (func_type) (target_type) value)) {\ func_type zero = 0;\ if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ return (target_type) -1;\ if (is_unsigned && unlikely(value < zero))\ goto raise_neg_overflow;\ else\ goto raise_overflow;\ }\ }\ return (target_type) value;\ } static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { const int neg_one = (int) -1, const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { if (sizeof(int) < sizeof(long)) { __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { goto raise_neg_overflow; } return (int) val; } } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (int) 0; case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) case 2: if (8 * sizeof(int) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); } } break; case 3: if (8 * sizeof(int) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); } } break; case 4: if (8 * sizeof(int) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); } } break; } #endif #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } #else { int result = PyObject_RichCompareBool(x, Py_False, Py_LT); if (unlikely(result < 0)) return (int) -1; if (unlikely(result == 1)) goto raise_neg_overflow; } #endif if (sizeof(int) <= sizeof(unsigned long)) { __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) } } else { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (int) 0; case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) case -2: if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case 2: if (8 * sizeof(int) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case -3: if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case 3: if (8 * sizeof(int) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case -4: if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case 4: if (8 * sizeof(int) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; } #endif if (sizeof(int) <= sizeof(long)) { __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) } } { #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) PyErr_SetString(PyExc_RuntimeError, "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); #else int val; PyObject *v = __Pyx_PyNumber_Int(x); #if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } #endif if (likely(v)) { int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; int ret = _PyLong_AsByteArray((PyLongObject *)v, bytes, sizeof(val), is_little, !is_unsigned); Py_DECREF(v); if (likely(!ret)) return val; } #endif return (int) -1; } } else { int val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (int) -1; val = __Pyx_PyInt_As_int(tmp); Py_DECREF(tmp); return val; } raise_overflow: PyErr_SetString(PyExc_OverflowError, "value too large to convert to int"); return (int) -1; raise_neg_overflow: PyErr_SetString(PyExc_OverflowError, "can't convert negative value to int"); return (int) -1; } static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { const long neg_one = (long) -1, const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(long) < sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(long) <= sizeof(unsigned long)) { return PyLong_FromUnsignedLong((unsigned long) value); } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); } } else { if (sizeof(long) <= sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { return PyLong_FromLongLong((PY_LONG_LONG) value); } } { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; return _PyLong_FromByteArray(bytes, sizeof(long), little, !is_unsigned); } } static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { const long neg_one = (long) -1, const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { if (sizeof(long) < sizeof(long)) { __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { goto raise_neg_overflow; } return (long) val; } } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (long) 0; case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) case 2: if (8 * sizeof(long) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); } } break; case 3: if (8 * sizeof(long) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); } } break; case 4: if (8 * sizeof(long) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); } } break; } #endif #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } #else { int result = PyObject_RichCompareBool(x, Py_False, Py_LT); if (unlikely(result < 0)) return (long) -1; if (unlikely(result == 1)) goto raise_neg_overflow; } #endif if (sizeof(long) <= sizeof(unsigned long)) { __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) } } else { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (long) 0; case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) case -2: if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case 2: if (8 * sizeof(long) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case -3: if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case 3: if (8 * sizeof(long) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case -4: if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case 4: if (8 * sizeof(long) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; } #endif if (sizeof(long) <= sizeof(long)) { __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) } } { #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) PyErr_SetString(PyExc_RuntimeError, "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); #else long val; PyObject *v = __Pyx_PyNumber_Int(x); #if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } #endif if (likely(v)) { int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; int ret = _PyLong_AsByteArray((PyLongObject *)v, bytes, sizeof(val), is_little, !is_unsigned); Py_DECREF(v); if (likely(!ret)) return val; } #endif return (long) -1; } } else { long val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (long) -1; val = __Pyx_PyInt_As_long(tmp); Py_DECREF(tmp); return val; } raise_overflow: PyErr_SetString(PyExc_OverflowError, "value too large to convert to long"); return (long) -1; raise_neg_overflow: PyErr_SetString(PyExc_OverflowError, "can't convert negative value to long"); return (long) -1; } 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()); if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { char message[200]; PyOS_snprintf(message, sizeof(message), "compiletime version %s of module '%.100s' " "does not match runtime version %s", ctversion, __Pyx_MODULE_NAME, rtversion); return PyErr_WarnEx(NULL, message, 1); } return 0; } static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { #if PY_MAJOR_VERSION < 3 if (t->is_unicode) { *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); } else if (t->intern) { *t->p = PyString_InternFromString(t->s); } else { *t->p = PyString_FromStringAndSize(t->s, t->n - 1); } #else if (t->is_unicode | t->is_str) { if (t->intern) { *t->p = PyUnicode_InternFromString(t->s); } else if (t->encoding) { *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); } else { *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); } } else { *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); } #endif if (!*t->p) return -1; ++t; } return 0; } static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); } static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) { Py_ssize_t ignore; return __Pyx_PyObject_AsStringAndSize(o, &ignore); } static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { #if CYTHON_COMPILING_IN_CPYTHON && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) if ( #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII __Pyx_sys_getdefaultencoding_not_ascii && #endif PyUnicode_Check(o)) { #if PY_VERSION_HEX < 0x03030000 char* defenc_c; PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); if (!defenc) return NULL; defenc_c = PyBytes_AS_STRING(defenc); #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII { char* end = defenc_c + PyBytes_GET_SIZE(defenc); char* c; for (c = defenc_c; c < end; c++) { if ((unsigned char) (*c) >= 128) { PyUnicode_AsASCIIString(o); return NULL; } } } #endif *length = PyBytes_GET_SIZE(defenc); return defenc_c; #else if (__Pyx_PyUnicode_READY(o) == -1) return NULL; #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII if (PyUnicode_IS_ASCII(o)) { *length = PyUnicode_GET_LENGTH(o); return PyUnicode_AsUTF8(o); } else { PyUnicode_AsASCIIString(o); return NULL; } #else return PyUnicode_AsUTF8AndSize(o, length); #endif #endif } else #endif #if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) if (PyByteArray_Check(o)) { *length = PyByteArray_GET_SIZE(o); return PyByteArray_AS_STRING(o); } else #endif { char* result; int r = PyBytes_AsStringAndSize(o, &result, length); if (unlikely(r < 0)) { return NULL; } else { return result; } } } static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { int is_true = x == Py_True; if (is_true | (x == Py_False) | (x == Py_None)) return is_true; else return PyObject_IsTrue(x); } static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) { PyNumberMethods *m; const char *name = NULL; PyObject *res = NULL; #if PY_MAJOR_VERSION < 3 if (PyInt_Check(x) || PyLong_Check(x)) #else if (PyLong_Check(x)) #endif return __Pyx_NewRef(x); m = Py_TYPE(x)->tp_as_number; #if PY_MAJOR_VERSION < 3 if (m && m->nb_int) { name = "int"; res = PyNumber_Int(x); } else if (m && m->nb_long) { name = "long"; res = PyNumber_Long(x); } #else if (m && m->nb_int) { name = "int"; res = PyNumber_Long(x); } #endif if (res) { #if PY_MAJOR_VERSION < 3 if (!PyInt_Check(res) && !PyLong_Check(res)) { #else if (!PyLong_Check(res)) { #endif PyErr_Format(PyExc_TypeError, "__%.4s__ returned non-%.4s (type %.200s)", name, name, Py_TYPE(res)->tp_name); Py_DECREF(res); return NULL; } } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "an integer is required"); } return res; } static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { Py_ssize_t ival; PyObject *x; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_CheckExact(b))) { if (sizeof(Py_ssize_t) >= sizeof(long)) return PyInt_AS_LONG(b); else return PyInt_AsSsize_t(x); } #endif if (likely(PyLong_CheckExact(b))) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)b)->ob_digit; const Py_ssize_t size = Py_SIZE(b); if (likely(__Pyx_sst_abs(size) <= 1)) { ival = likely(size) ? digits[0] : 0; if (size == -1) ival = -ival; return ival; } else { switch (size) { case 2: if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case -2: if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case 3: if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case -3: if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case 4: if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case -4: if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; } } #endif return PyLong_AsSsize_t(b); } x = PyNumber_Index(b); if (!x) return -1; ival = PyInt_AsSsize_t(x); Py_DECREF(x); return ival; } static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { return PyInt_FromSize_t(ival); } #endif /* Py_PYTHON_H */ aiohttp-0.20.2/aiohttp/protocol.py0000664000175000017500000006735312643555212017735 0ustar andrewandrew00000000000000"""Http related parsers and protocol.""" import collections import functools import http.server import re import string import sys import zlib from abc import abstractmethod, ABCMeta from wsgiref.handlers import format_date_time import aiohttp from . import errors, hdrs from .multidict import CIMultiDict, upstr from .log import internal_logger from .helpers import reify __all__ = ('HttpMessage', 'Request', 'Response', 'HttpVersion', 'HttpVersion10', 'HttpVersion11', 'RawRequestMessage', 'RawResponseMessage', 'HttpPrefixParser', 'HttpRequestParser', 'HttpResponseParser', 'HttpPayloadParser') ASCIISET = set(string.printable) METHRE = re.compile('[A-Z0-9$-_.]+') VERSRE = re.compile('HTTP/(\d+).(\d+)') HDRRE = re.compile('[\x00-\x1F\x7F()<>@,;:\[\]={} \t\\\\\"]') CONTINUATION = (' ', '\t') EOF_MARKER = object() EOL_MARKER = object() STATUS_LINE_READY = object() RESPONSES = http.server.BaseHTTPRequestHandler.responses HttpVersion = collections.namedtuple( 'HttpVersion', ['major', 'minor']) HttpVersion10 = HttpVersion(1, 0) HttpVersion11 = HttpVersion(1, 1) RawStatusLineMessage = collections.namedtuple( 'RawStatusLineMessage', ['method', 'path', 'version']) RawRequestMessage = collections.namedtuple( 'RawRequestMessage', ['method', 'path', 'version', 'headers', 'should_close', 'compression']) RawResponseMessage = collections.namedtuple( 'RawResponseMessage', ['version', 'code', 'reason', 'headers', 'should_close', 'compression']) class HttpParser: def __init__(self, max_line_size=8190, max_headers=32768, max_field_size=8190): self.max_line_size = max_line_size self.max_headers = max_headers self.max_field_size = max_field_size def parse_headers(self, lines): """Parses RFC2822 headers from a stream. Line continuations are supported. Returns list of header name and value pairs. Header name is in upper case. """ close_conn = None encoding = None headers = CIMultiDict() lines_idx = 1 line = lines[1] while line: header_length = len(line) # Parse initial header name : value pair. try: name, value = line.split(':', 1) except ValueError: raise errors.InvalidHeader(line) from None name = name.strip(' \t').upper() if HDRRE.search(name): raise errors.InvalidHeader(name) # next line lines_idx += 1 line = lines[lines_idx] # consume continuation lines continuation = line and line[0] in CONTINUATION if continuation: value = [value] while continuation: header_length += len(line) if header_length > self.max_field_size: raise errors.LineTooLong( 'limit request headers fields size') value.append(line) # next line lines_idx += 1 line = lines[lines_idx] continuation = line[0] in CONTINUATION value = '\r\n'.join(value) else: if header_length > self.max_field_size: raise errors.LineTooLong( 'limit request headers fields size') value = value.strip() # keep-alive and encoding if name == hdrs.CONNECTION: v = value.lower() if v == 'close': close_conn = True elif v == 'keep-alive': close_conn = False elif name == hdrs.CONTENT_ENCODING: enc = value.lower() if enc in ('gzip', 'deflate'): encoding = enc headers.add(name, value) return headers, close_conn, encoding class HttpPrefixParser: """Waits for 'HTTP' prefix (non destructive)""" def __init__(self, allowed_methods=()): self.allowed_methods = [m.upper() for m in allowed_methods] def __call__(self, out, buf): raw_data = yield from buf.waituntil(b' ', 12) method = raw_data.decode('ascii', 'surrogateescape').strip() # method method = method.upper() if not METHRE.match(method): raise errors.BadStatusLine(method) # allowed method if self.allowed_methods and method not in self.allowed_methods: raise errors.HttpMethodNotAllowed(message=method) out.feed_data(method, len(method)) out.feed_eof() class HttpRequestParser(HttpParser): """Read request status line. Exception errors.BadStatusLine could be raised in case of any errors in status line. Returns RawRequestMessage. """ def __call__(self, out, buf): # read http message (request line + headers) try: raw_data = yield from buf.readuntil( b'\r\n\r\n', self.max_headers) except errors.LineLimitExceededParserError as exc: raise errors.LineTooLong(exc.limit) from None lines = raw_data.decode( 'utf-8', 'surrogateescape').split('\r\n') # request line line = lines[0] try: method, path, version = line.split(None, 2) except ValueError: raise errors.BadStatusLine(line) from None # method method = method.upper() if not METHRE.match(method): raise errors.BadStatusLine(method) # version try: if version.startswith('HTTP/'): n1, n2 = version[5:].split('.', 1) version = HttpVersion(int(n1), int(n2)) else: raise errors.BadStatusLine(version) except: raise errors.BadStatusLine(version) # read headers headers, close, compression = 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 close = True else: # HTTP 1.1 must ask to close. close = False out.feed_data( RawRequestMessage( method, path, version, headers, close, compression), len(raw_data)) out.feed_eof() class HttpResponseParser(HttpParser): """Read response status line and headers. BadStatusLine could be raised in case of any errors in status line. Returns RawResponseMessage""" def __call__(self, out, buf): # read http message (response line + headers) try: raw_data = yield from buf.readuntil( b'\r\n\r\n', self.max_line_size + self.max_headers) except errors.LineLimitExceededParserError as exc: raise errors.LineTooLong(exc.limit) from None lines = raw_data.decode( 'utf-8', 'surrogateescape').split('\r\n') line = lines[0] try: version, status = line.split(None, 1) except ValueError: raise errors.BadStatusLine(line) from None else: try: status, reason = status.split(None, 1) except ValueError: reason = '' # version match = VERSRE.match(version) if match is None: raise errors.BadStatusLine(line) version = HttpVersion(int(match.group(1)), int(match.group(2))) # The status code is a three-digit number try: status = int(status) except ValueError: raise errors.BadStatusLine(line) from None if status < 100 or status > 999: raise errors.BadStatusLine(line) # read headers headers, close, compression = self.parse_headers(lines) if close is None: close = version <= HttpVersion10 out.feed_data( RawResponseMessage( version, status, reason.strip(), headers, close, compression), len(raw_data)) out.feed_eof() class HttpPayloadParser: def __init__(self, message, length=None, compression=True, readall=False, response_with_body=True): self.message = message self.length = length self.compression = compression self.readall = readall self.response_with_body = response_with_body def __call__(self, out, buf): # payload params length = self.message.headers.get(hdrs.CONTENT_LENGTH, self.length) if hdrs.SEC_WEBSOCKET_KEY1 in self.message.headers: length = 8 # payload decompression wrapper if self.compression and self.message.compression: out = DeflateBuffer(out, self.message.compression) # payload parser if not self.response_with_body: # don't parse payload if it's not expected to be received pass elif 'chunked' in self.message.headers.get( hdrs.TRANSFER_ENCODING, ''): yield from self.parse_chunked_payload(out, buf) elif length is not None: try: length = int(length) except ValueError: raise errors.InvalidHeader(hdrs.CONTENT_LENGTH) from None if length < 0: raise errors.InvalidHeader(hdrs.CONTENT_LENGTH) elif length > 0: yield from self.parse_length_payload(out, buf, length) else: if self.readall and getattr(self.message, 'code', 0) != 204: yield from self.parse_eof_payload(out, buf) elif getattr(self.message, 'method', None) in ('PUT', 'POST'): internal_logger.warning( # pragma: no cover 'Content-Length or Transfer-Encoding header is required') out.feed_eof() def parse_chunked_payload(self, out, buf): """Chunked transfer encoding parser.""" while True: # read next chunk size line = yield from buf.readuntil(b'\r\n', 8192) i = line.find(b';') if i >= 0: line = line[:i] # strip chunk-extensions else: line = line.strip() try: size = int(line, 16) except ValueError: raise errors.TransferEncodingError(line) from None if size == 0: # eof marker break # read chunk and feed buffer while size: chunk = yield from buf.readsome(size) out.feed_data(chunk, len(chunk)) size = size - len(chunk) # toss the CRLF at the end of the chunk yield from buf.skip(2) # read and discard trailer up to the CRLF terminator yield from buf.skipuntil(b'\r\n') def parse_length_payload(self, out, buf, length=0): """Read specified amount of bytes.""" required = length while required: chunk = yield from buf.readsome(required) out.feed_data(chunk, len(chunk)) required -= len(chunk) def parse_eof_payload(self, out, buf): """Read all bytes until eof.""" try: while True: chunk = yield from buf.readsome() out.feed_data(chunk, len(chunk)) except aiohttp.EofStream: pass class DeflateBuffer: """DeflateStream decompress stream and feed data into specified stream.""" def __init__(self, out, encoding): self.out = out zlib_mode = (16 + zlib.MAX_WBITS if encoding == 'gzip' else -zlib.MAX_WBITS) self.zlib = zlib.decompressobj(wbits=zlib_mode) def feed_data(self, chunk, size): try: chunk = self.zlib.decompress(chunk) except Exception: raise errors.ContentEncodingError('deflate') if chunk: self.out.feed_data(chunk, len(chunk)) def feed_eof(self): chunk = self.zlib.flush() self.out.feed_data(chunk, len(chunk)) if not self.zlib.eof: raise errors.ContentEncodingError('deflate') self.out.feed_eof() def wrap_payload_filter(func): """Wraps payload filter and piped filters. Filter is a generator that accepts arbitrary chunks of data, modify data and emit new stream of data. For example we have stream of chunks: ['1', '2', '3', '4', '5'], we can apply chunking filter to this stream: ['1', '2', '3', '4', '5'] | response.add_chunking_filter(2) | ['12', '34', '5'] It is possible to use different filters at the same time. For a example to compress incoming stream with 'deflate' encoding and then split data and emit chunks of 8192 bytes size chunks: >>> response.add_compression_filter('deflate') >>> response.add_chunking_filter(8192) Filters do not alter transfer encoding. Filter can receive types types of data, bytes object or EOF_MARKER. 1. If filter receives bytes object, it should process data and yield processed data then yield EOL_MARKER object. 2. If Filter received EOF_MARKER, it should yield remaining data (buffered) and then yield EOF_MARKER. """ @functools.wraps(func) def wrapper(self, *args, **kw): new_filter = func(self, *args, **kw) filter = self.filter if filter is not None: next(new_filter) self.filter = filter_pipe(filter, new_filter) else: self.filter = new_filter next(self.filter) return wrapper def filter_pipe(filter, filter2, *, EOF_MARKER=EOF_MARKER, EOL_MARKER=EOL_MARKER): """Creates pipe between two filters. filter_pipe() feeds first filter with incoming data and then send yielded from first filter data into filter2, results of filter2 are being emitted. 1. If filter_pipe receives bytes object, it sends it to the first filter. 2. Reads yielded values from the first filter until it receives EOF_MARKER or EOL_MARKER. 3. Each of this values is being send to second filter. 4. Reads yielded values from second filter until it receives EOF_MARKER or EOL_MARKER. Each of this values yields to writer. """ chunk = yield while True: eof = chunk is EOF_MARKER chunk = filter.send(chunk) while chunk is not EOL_MARKER: chunk = filter2.send(chunk) while chunk not in (EOF_MARKER, EOL_MARKER): yield chunk chunk = next(filter2) if chunk is not EOF_MARKER: if eof: chunk = EOF_MARKER else: chunk = next(filter) else: break chunk = yield EOL_MARKER class HttpMessage(metaclass=ABCMeta): """HttpMessage allows to write headers and payload to a stream. For example, lets say we want to read file then compress it with deflate compression and then send it with chunked transfer encoding, code may look like this: >>> response = aiohttp.Response(transport, 200) We have to use deflate compression first: >>> response.add_compression_filter('deflate') Then we want to split output stream into chunks of 1024 bytes size: >>> response.add_chunking_filter(1024) We can add headers to response with add_headers() method. add_headers() does not send data to transport, send_headers() sends request/response line and then sends headers: >>> response.add_headers( ... ('Content-Disposition', 'attachment; filename="..."')) >>> response.send_headers() Now we can use chunked writer to write stream to a network stream. First call to write() method sends response status line and headers, add_header() and add_headers() method unavailable at this stage: >>> with open('...', 'rb') as f: ... chunk = fp.read(8192) ... while chunk: ... response.write(chunk) ... chunk = fp.read(8192) >>> response.write_eof() """ writer = None # 'filter' is being used for altering write() behaviour, # add_chunking_filter adds deflate/gzip compression and # add_compression_filter splits incoming data into a chunks. filter = None HOP_HEADERS = None # Must be set by subclass. SERVER_SOFTWARE = 'Python/{0[0]}.{0[1]} aiohttp/{1}'.format( sys.version_info, aiohttp.__version__) upgrade = False # Connection: UPGRADE websocket = False # Upgrade: WEBSOCKET has_chunked_hdr = False # Transfer-encoding: chunked # subclass can enable auto sending headers with write() call, # this is useful for wsgi's start_response implementation. _send_headers = False def __init__(self, transport, version, close): self.transport = transport self._version = version self.closing = close self.keepalive = None self.chunked = False self.length = None self.headers = CIMultiDict() self.headers_sent = False self.output_length = 0 self.headers_length = 0 self._output_size = 0 @property @abstractmethod def status_line(self): return b'' @abstractmethod def autochunked(self): return False @property def version(self): return self._version @property def body_length(self): return self.output_length - self.headers_length def force_close(self): self.closing = True self.keepalive = False def enable_chunked_encoding(self): self.chunked = True def keep_alive(self): if self.keepalive is None: if self.version < HttpVersion10: # keep alive not supported at all return False if self.version == HttpVersion10: if self.headers.get(hdrs.CONNECTION) == 'keep-alive': return True else: # no headers means we close for Http 1.0 return False else: return not self.closing else: return self.keepalive def is_headers_sent(self): return self.headers_sent def add_header(self, name, value): """Analyze headers. Calculate content length, removes hop headers, etc.""" assert not self.headers_sent, 'headers have been sent already' assert isinstance(name, str), \ 'Header name should be a string, got {!r}'.format(name) assert set(name).issubset(ASCIISET), \ 'Header name should contain ASCII chars, got {!r}'.format(name) assert isinstance(value, str), \ 'Header {!r} should have string value, got {!r}'.format( name, value) name = upstr(name) value = value.strip() if name == hdrs.CONTENT_LENGTH: self.length = int(value) if name == hdrs.TRANSFER_ENCODING: self.has_chunked_hdr = value.lower().strip() == 'chunked' if name == hdrs.CONNECTION: val = value.lower() # handle websocket if 'upgrade' in val: self.upgrade = True # connection keep-alive elif 'close' in val: self.keepalive = False elif 'keep-alive' in val: self.keepalive = True elif name == hdrs.UPGRADE: if 'websocket' in value.lower(): self.websocket = True self.headers[name] = value elif name not in self.HOP_HEADERS: # ignore hop-by-hop headers self.headers.add(name, value) def add_headers(self, *headers): """Adds headers to a http message.""" for name, value in headers: self.add_header(name, value) def send_headers(self, _sep=': ', _end='\r\n'): """Writes headers to a stream. Constructs payload writer.""" # Chunked response is only for HTTP/1.1 clients or newer # and there is no Content-Length header is set. # Do not use chunked responses when the response is guaranteed to # not have a response body (304, 204). assert not self.headers_sent, 'headers have been sent already' self.headers_sent = True if self.chunked or self.autochunked(): self.writer = self._write_chunked_payload() self.headers[hdrs.TRANSFER_ENCODING] = 'chunked' elif self.length is not None: self.writer = self._write_length_payload(self.length) else: self.writer = self._write_eof_payload() next(self.writer) self._add_default_headers() # status + headers headers = self.status_line + ''.join( [k + _sep + v + _end for k, v in self.headers.items()]) headers = headers.encode('utf-8') + b'\r\n' self.output_length += len(headers) self.headers_length = len(headers) self.transport.write(headers) def _add_default_headers(self): # set the connection header if self.upgrade: connection = 'upgrade' elif not self.closing if self.keepalive is None else self.keepalive: connection = 'keep-alive' else: connection = 'close' self.headers[hdrs.CONNECTION] = connection def write(self, chunk, *, drain=False, EOF_MARKER=EOF_MARKER, EOL_MARKER=EOL_MARKER): """Writes chunk of data to a stream by using different writers. writer uses filter to modify chunk of data. write_eof() indicates end of stream. writer can't be used after write_eof() method being called. write() return drain future. """ assert (isinstance(chunk, (bytes, bytearray)) or chunk is EOF_MARKER), chunk size = self.output_length if self._send_headers and not self.headers_sent: self.send_headers() assert self.writer is not None, 'send_headers() is not called.' if self.filter: chunk = self.filter.send(chunk) while chunk not in (EOF_MARKER, EOL_MARKER): if chunk: self.writer.send(chunk) chunk = next(self.filter) else: if chunk is not EOF_MARKER: self.writer.send(chunk) self._output_size += self.output_length - size if self._output_size > 64 * 1024: if drain: self._output_size = 0 return self.transport.drain() return () def write_eof(self): self.write(EOF_MARKER) try: self.writer.throw(aiohttp.EofStream()) except StopIteration: pass return self.transport.drain() def _write_chunked_payload(self): """Write data in chunked transfer encoding.""" while True: try: chunk = yield except aiohttp.EofStream: self.transport.write(b'0\r\n\r\n') self.output_length += 5 break chunk = bytes(chunk) chunk_len = '{:x}\r\n'.format(len(chunk)).encode('ascii') self.transport.write(chunk_len + chunk + b'\r\n') self.output_length += len(chunk_len) + len(chunk) + 2 def _write_length_payload(self, length): """Write specified number of bytes to a stream.""" while True: try: chunk = yield except aiohttp.EofStream: break if length: l = len(chunk) if length >= l: self.transport.write(chunk) self.output_length += l length = length-l else: self.transport.write(chunk[:length]) self.output_length += length length = 0 def _write_eof_payload(self): while True: try: chunk = yield except aiohttp.EofStream: break self.transport.write(chunk) self.output_length += len(chunk) @wrap_payload_filter def add_chunking_filter(self, chunk_size=16*1024, *, EOF_MARKER=EOF_MARKER, EOL_MARKER=EOL_MARKER): """Split incoming stream into chunks.""" buf = bytearray() chunk = yield while True: if chunk is EOF_MARKER: if buf: yield buf yield EOF_MARKER else: buf.extend(chunk) while len(buf) >= chunk_size: chunk = bytes(buf[:chunk_size]) del buf[:chunk_size] yield chunk chunk = yield EOL_MARKER @wrap_payload_filter def add_compression_filter(self, encoding='deflate', *, EOF_MARKER=EOF_MARKER, EOL_MARKER=EOL_MARKER): """Compress incoming stream with deflate or gzip encoding.""" zlib_mode = (16 + zlib.MAX_WBITS if encoding == 'gzip' else -zlib.MAX_WBITS) zcomp = zlib.compressobj(wbits=zlib_mode) chunk = yield while True: if chunk is EOF_MARKER: yield zcomp.flush() chunk = yield EOF_MARKER else: yield zcomp.compress(chunk) chunk = yield EOL_MARKER class Response(HttpMessage): """Create http response message. Transport is a socket stream transport. status is a response status code, status has to be integer value. http_version is a tuple that represents http version, (1, 0) stands for HTTP/1.0 and (1, 1) is for HTTP/1.1 """ HOP_HEADERS = () @staticmethod def calc_reason(status, *, _RESPONSES=RESPONSES): record = _RESPONSES.get(status) if record is not None: reason = record[0] else: reason = str(status) return reason def __init__(self, transport, status, http_version=HttpVersion11, close=False, reason=None): super().__init__(transport, http_version, close) self._status = status if reason is None: reason = self.calc_reason(status) self._reason = reason @property def status(self): return self._status @property def reason(self): return self._reason @reify def status_line(self): version = self.version return 'HTTP/{}.{} {} {}\r\n'.format( version[0], version[1], self.status, self.reason) def autochunked(self): return (self.length is None and self.version >= HttpVersion11) def _add_default_headers(self): super()._add_default_headers() if hdrs.DATE not in self.headers: # format_date_time(None) is quite expensive self.headers.setdefault(hdrs.DATE, format_date_time(None)) self.headers.setdefault(hdrs.SERVER, self.SERVER_SOFTWARE) class Request(HttpMessage): HOP_HEADERS = () def __init__(self, transport, method, path, http_version=HttpVersion11, close=False): # set the default for HTTP 1.0 to be different # will only be overwritten with keep-alive header if http_version < HttpVersion11: close = True super().__init__(transport, http_version, close) self._method = method self._path = path @property def method(self): return self._method @property def path(self): return self._path @reify def status_line(self): return '{0} {1} HTTP/{2[0]}.{2[1]}\r\n'.format( self.method, self.path, self.version) def autochunked(self): return (self.length is None and self.version >= HttpVersion11 and self.status not in (304, 204)) aiohttp-0.20.2/aiohttp/signals.py0000664000175000017500000000342412610121516017507 0ustar andrewandrew00000000000000import asyncio from itertools import count class BaseSignal(list): @asyncio.coroutine def _send(self, *args, **kwargs): for receiver in self: res = receiver(*args, **kwargs) if asyncio.iscoroutine(res) or isinstance(res, asyncio.Future): yield from res def copy(self): raise NotImplementedError("copy() is forbidden") def sort(self): raise NotImplementedError("sort() is forbidden") class Signal(BaseSignal): """Coroutine-based signal implementation. To connect a callback to a signal, use any list method. Signals are fired using the :meth:`send` coroutine, which takes named arguments. """ def __init__(self, app): super().__init__() self._app = app klass = self.__class__ self._name = klass.__module__ + ':' + klass.__qualname__ self._pre = app.on_pre_signal self._post = app.on_post_signal @asyncio.coroutine def send(self, *args, **kwargs): """ Sends data to all registered receivers. """ ordinal = None debug = self._app._debug if debug: ordinal = self._pre.ordinal() yield from self._pre.send(ordinal, self._name, *args, **kwargs) yield from self._send(*args, **kwargs) if debug: yield from self._post.send(ordinal, self._name, *args, **kwargs) class DebugSignal(BaseSignal): @asyncio.coroutine def send(self, ordinal, name, *args, **kwargs): yield from self._send(ordinal, name, *args, **kwargs) class PreSignal(DebugSignal): def __init__(self): super().__init__() self._counter = count(1) def ordinal(self): return next(self._counter) class PostSignal(DebugSignal): pass aiohttp-0.20.2/aiohttp/multipart.py0000664000175000017500000007127612624767365020131 0ustar andrewandrew00000000000000import asyncio import binascii import base64 import json import io import mimetypes import os import re import uuid import warnings import zlib from urllib.parse import quote, unquote, urlencode, parse_qsl from collections import deque, Mapping, Sequence from .helpers import parse_mimetype from .multidict import CIMultiDict from .protocol import HttpParser from .hdrs import ( CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_TRANSFER_ENCODING, CONTENT_TYPE ) __all__ = ('MultipartReader', 'MultipartWriter', 'BodyPartReader', 'BodyPartWriter', 'BadContentDispositionHeader', 'BadContentDispositionParam', 'parse_content_disposition', 'content_disposition_filename') CHAR = set(chr(i) for i in range(0, 128)) CTL = set(chr(i) for i in range(0, 32)) | {chr(127), } SEPARATORS = {'(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', chr(9)} TOKEN = CHAR ^ CTL ^ SEPARATORS class BadContentDispositionHeader(RuntimeWarning): pass class BadContentDispositionParam(RuntimeWarning): pass def parse_content_disposition(header): def is_token(string): return string and TOKEN >= set(string) def is_quoted(string): return string[0] == string[-1] == '"' def is_rfc5987(string): return is_token(string) and string.count("'") == 2 def is_extended_param(string): return string.endswith('*') def is_continuous_param(string): 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))): return re.sub('\\\\([{}])'.format(chars), '\\1', text) if not header: return None, {} disptype, *parts = header.split(';') if not is_token(disptype): warnings.warn(BadContentDispositionHeader(header)) return None, {} params = {} for item in parts: if '=' not in item: warnings.warn(BadContentDispositionHeader(header)) return None, {} key, value = item.split('=', 1) key = key.lower().strip() value = value.lstrip() if key in params: warnings.warn(BadContentDispositionHeader(header)) return None, {} if not is_token(key): warnings.warn(BadContentDispositionParam(item)) continue elif is_continuous_param(key): if is_quoted(value): value = unescape(value[1:-1]) elif not is_token(value): warnings.warn(BadContentDispositionParam(item)) continue elif is_extended_param(key): if is_rfc5987(value): encoding, _, value = value.split("'", 2) encoding = encoding or 'utf-8' else: warnings.warn(BadContentDispositionParam(item)) continue try: value = unquote(value, encoding, 'strict') except UnicodeDecodeError: # pragma: nocover warnings.warn(BadContentDispositionParam(item)) continue else: if is_quoted(value): value = unescape(value[1:-1].lstrip('\\/')) elif not is_token(value): warnings.warn(BadContentDispositionHeader(header)) return None, {} params[key] = value return disptype.lower(), params def content_disposition_filename(params): if not params: return None elif 'filename*' in params: return params['filename*'] elif 'filename' in params: return params['filename'] else: parts = [] fnparams = sorted((key, value) for key, value in params.items() if key.startswith('filename*')) for num, (key, value) in enumerate(fnparams): _, tail = key.split('*', 1) if tail.endswith('*'): tail = tail[:-1] if tail == str(num): parts.append(value) else: break if not parts: return None value = ''.join(parts) if "'" in value: encoding, _, value = value.split("'", 2) encoding = encoding or 'utf-8' return unquote(value, encoding, 'strict') return value class MultipartResponseWrapper(object): """Wrapper around the :class:`MultipartBodyReader` to take care about underlying connection and close it when it needs in.""" def __init__(self, resp, stream): self.resp = resp self.stream = stream @asyncio.coroutine def __aiter__(self): return self @asyncio.coroutine def __anext__(self): part = yield from self.next() if part is None: raise StopAsyncIteration # NOQA return part def at_eof(self): """Returns ``True`` when all response data had been read. :rtype: bool """ return self.resp.content.at_eof() @asyncio.coroutine def next(self): """Emits next multipart reader object.""" item = yield from self.stream.next() if self.stream.at_eof(): yield from self.release() return item @asyncio.coroutine def release(self): """Releases the connection gracefully, reading all the content to the void.""" yield from self.resp.release() class BodyPartReader(object): """Multipart reader for single body part.""" chunk_size = 8192 def __init__(self, boundary, headers, content): self.headers = headers self._boundary = boundary self._content = content self._at_eof = False 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() @asyncio.coroutine def __aiter__(self): return self @asyncio.coroutine def __anext__(self): part = yield from self.next() if part is None: raise StopAsyncIteration # NOQA return part @asyncio.coroutine def next(self): item = yield from self.read() if not item: return None return item @asyncio.coroutine def read(self, *, decode=False): """Reads body part data. :param bool decode: Decodes data following by encoding method from `Content-Encoding` header. If it missed data remains untouched :rtype: bytearray """ if self._at_eof: return b'' data = bytearray() if self._length is None: while not self._at_eof: data.extend((yield from self.readline())) else: while not self._at_eof: data.extend((yield from self.read_chunk(self.chunk_size))) if decode: return self.decode(data) return data @asyncio.coroutine def read_chunk(self, size=chunk_size): """Reads body part content chunk of the specified size. The body part must has `Content-Length` header with proper value. :param int size: chunk size :rtype: bytearray """ if self._at_eof: return b'' assert self._length is not None, \ 'Content-Length required for chunked read' chunk_size = min(size, self._length - self._read_bytes) chunk = yield from self._content.read(chunk_size) self._read_bytes += len(chunk) if self._read_bytes == self._length: self._at_eof = True assert b'\r\n' == (yield from self._content.readline()), \ 'reader did not read all the data or it is malformed' return chunk @asyncio.coroutine def readline(self): """Reads body part by line by line. :rtype: bytearray """ if self._at_eof: return b'' if self._unread: line = self._unread.popleft() else: line = yield from self._content.readline() if line.startswith(self._boundary): # the very last boundary may not come with \r\n, # so set single rules for everyone sline = line.rstrip(b'\r\n') boundary = self._boundary last_boundary = self._boundary + b'--' # ensure that we read exactly the boundary, not something alike if sline == boundary or sline == last_boundary: self._at_eof = True self._unread.append(line) return b'' else: next_line = yield from self._content.readline() if next_line.startswith(self._boundary): line = line[:-2] # strip CRLF but only once self._unread.append(next_line) return line @asyncio.coroutine def release(self): """Lke :meth:`read`, but reads all the data to the void. :rtype: None """ if self._at_eof: return if self._length is None: while not self._at_eof: yield from self.readline() else: while not self._at_eof: yield from self.read_chunk(self.chunk_size) @asyncio.coroutine def text(self, *, encoding=None): """Lke :meth:`read`, but assumes that body part contains text data. :param str encoding: Custom text encoding. Overrides specified in charset param of `Content-Type` header :rtype: str """ data = yield from self.read(decode=True) encoding = encoding or self.get_charset(default='latin1') return data.decode(encoding) @asyncio.coroutine def json(self, *, encoding=None): """Lke :meth:`read`, but assumes that body parts contains JSON data. :param str encoding: Custom JSON encoding. Overrides specified in charset param of `Content-Type` header """ data = yield from self.read(decode=True) if not data: return None encoding = encoding or self.get_charset(default='utf-8') return json.loads(data.decode(encoding)) @asyncio.coroutine def form(self, *, encoding=None): """Lke :meth:`read`, but assumes that body parts contains form urlencoded data. :param str encoding: Custom form encoding. Overrides specified in charset param of `Content-Type` header """ data = yield from 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), encoding=encoding) def at_eof(self): """Returns ``True`` if the boundary was reached or ``False`` otherwise. :rtype: bool """ return self._at_eof def decode(self, data): """Decodes data according the specified `Content-Encoding` or `Content-Transfer-Encoding` headers value. Supports ``gzip``, ``deflate`` and ``identity`` encodings for `Content-Encoding` header. Supports ``base64``, ``quoted-printable`` encodings for `Content-Transfer-Encoding` header. :param bytearray data: Data to decode. :raises: :exc:`RuntimeError` - if encoding is unknown. :rtype: bytes """ if CONTENT_TRANSFER_ENCODING in self.headers: data = self._decode_content_transfer(data) if CONTENT_ENCODING in self.headers: return self._decode_content(data) return data def _decode_content(self, data): encoding = self.headers[CONTENT_ENCODING].lower() if encoding == 'deflate': return zlib.decompress(data, -zlib.MAX_WBITS) elif encoding == 'gzip': return zlib.decompress(data, 16 + zlib.MAX_WBITS) elif encoding == 'identity': return data else: raise RuntimeError('unknown content encoding: {}'.format(encoding)) def _decode_content_transfer(self, data): encoding = self.headers[CONTENT_TRANSFER_ENCODING].lower() if encoding == 'base64': return base64.b64decode(data) elif encoding == 'quoted-printable': return binascii.a2b_qp(data) else: raise RuntimeError('unknown content transfer encoding: {}' ''.format(encoding)) def get_charset(self, default=None): """Returns charset parameter from ``Content-Type`` header or default. """ ctype = self.headers.get(CONTENT_TYPE, '') *_, params = parse_mimetype(ctype) return params.get('charset', default) @property def filename(self): """Returns filename 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) class MultipartReader(object): """Multipart body reader.""" #: Response wrapper, used when multipart readers constructs from response. response_wrapper_cls = MultipartResponseWrapper #: Multipart reader class, used to handle multipart/* body parts. #: None points to type(self) multipart_reader_cls = None #: Body part reader class for non multipart/* content types. part_reader_cls = BodyPartReader def __init__(self, headers, content): self.headers = headers self._boundary = ('--' + self._get_boundary()).encode() self._content = content self._last_part = None self._at_eof = False self._unread = [] @asyncio.coroutine def __aiter__(self): return self @asyncio.coroutine def __anext__(self): part = yield from self.next() if part is None: raise StopAsyncIteration # NOQA return part @classmethod def from_response(cls, response): """Constructs reader instance from HTTP response. :param response: :class:`~aiohttp.client.ClientResponse` instance """ obj = cls.response_wrapper_cls(response, cls(response.headers, response.content)) return obj def at_eof(self): """Returns ``True`` if the final boundary was reached or ``False`` otherwise. :rtype: bool """ return self._at_eof @asyncio.coroutine def next(self): """Emits the next multipart body part.""" if self._at_eof: return yield from self._maybe_release_last_part() yield from self._read_boundary() if self._at_eof: # we just read the last boundary, nothing to do there return self._last_part = yield from self.fetch_next_part() return self._last_part @asyncio.coroutine def release(self): """Reads all the body parts to the void till the final boundary.""" while not self._at_eof: item = yield from self.next() if item is None: break yield from item.release() @asyncio.coroutine def fetch_next_part(self): """Returns the next body part reader.""" headers = yield from self._read_headers() return self._get_part_reader(headers) def _get_part_reader(self, headers): """Dispatches the response by the `Content-Type` header, returning suitable reader instance. :param dict headers: Response headers """ ctype = headers.get(CONTENT_TYPE, '') mtype, *_ = parse_mimetype(ctype) if mtype == 'multipart': if self.multipart_reader_cls is None: return type(self)(headers, self._content) return self.multipart_reader_cls(headers, self._content) else: return self.part_reader_cls(self._boundary, headers, self._content) def _get_boundary(self): mtype, *_, params = parse_mimetype(self.headers[CONTENT_TYPE]) assert mtype == 'multipart', 'multipart/* content type expected' if 'boundary' not in params: raise ValueError('boundary missed for Content-Type: %s' % self.headers[CONTENT_TYPE]) boundary = params['boundary'] if len(boundary) > 70: raise ValueError('boundary %r is too long (70 chars max)' % boundary) return boundary @asyncio.coroutine def _readline(self): if self._unread: return self._unread.pop() return (yield from self._content.readline()) @asyncio.coroutine def _read_boundary(self): chunk = (yield from self._readline()).rstrip() if chunk == self._boundary: pass elif chunk == self._boundary + b'--': self._at_eof = True else: raise ValueError('Invalid boundary %r, expected %r' % (chunk, self._boundary)) @asyncio.coroutine def _read_headers(self): lines = [''] while True: chunk = yield from self._content.readline() chunk = chunk.decode().strip() lines.append(chunk) if not chunk: break parser = HttpParser() headers, *_ = parser.parse_headers(lines) return headers @asyncio.coroutine def _maybe_release_last_part(self): """Ensures that the last read body part is read completely.""" if self._last_part is not None: if not self._last_part.at_eof(): yield from self._last_part.release() self._unread.extend(self._last_part._unread) self._last_part = None class BodyPartWriter(object): """Multipart writer for single body part.""" def __init__(self, obj, headers=None, *, chunk_size=8192): if headers is None: headers = CIMultiDict() elif not isinstance(headers, CIMultiDict): headers = CIMultiDict(headers) self.obj = obj self.headers = headers self._chunk_size = chunk_size self._fill_headers_with_defaults() self._serialize_map = { bytes: self._serialize_bytes, str: self._serialize_str, io.IOBase: self._serialize_io, MultipartWriter: self._serialize_multipart, ('application', 'json'): self._serialize_json, ('application', 'x-www-form-urlencoded'): self._serialize_form } def _fill_headers_with_defaults(self): if CONTENT_TYPE not in self.headers: content_type = self._guess_content_type(self.obj) if content_type is not None: self.headers[CONTENT_TYPE] = content_type if CONTENT_LENGTH not in self.headers: content_length = self._guess_content_length(self.obj) if content_length is not None: self.headers[CONTENT_LENGTH] = str(content_length) if CONTENT_DISPOSITION not in self.headers: filename = self._guess_filename(self.obj) if filename is not None: self.set_content_disposition('attachment', filename=filename) def _guess_content_length(self, obj): if isinstance(obj, bytes): return len(obj) elif isinstance(obj, str): *_, params = parse_mimetype(self.headers.get(CONTENT_TYPE)) charset = params.get('charset', 'us-ascii') return len(obj.encode(charset)) elif isinstance(obj, io.StringIO): *_, params = parse_mimetype(self.headers.get(CONTENT_TYPE)) charset = params.get('charset', 'us-ascii') return len(obj.getvalue().encode(charset)) - obj.tell() elif isinstance(obj, io.BytesIO): return len(obj.getvalue()) - obj.tell() elif isinstance(obj, io.IOBase): try: return os.fstat(obj.fileno()).st_size - obj.tell() except (AttributeError, OSError): return None else: return None def _guess_content_type(self, obj, default='application/octet-stream'): if hasattr(obj, 'name'): name = getattr(obj, 'name') return mimetypes.guess_type(name)[0] elif isinstance(obj, (str, io.StringIO)): return 'text/plain; charset=utf-8' else: return default def _guess_filename(self, obj): if isinstance(obj, io.IOBase): name = getattr(obj, 'name', None) if name is not None: return os.path.basename(name) def serialize(self): """Yields byte chunks for body part.""" has_encoding = ( CONTENT_ENCODING in self.headers and self.headers[CONTENT_ENCODING] != 'identity' or CONTENT_TRANSFER_ENCODING in self.headers ) if has_encoding: # since we're following streaming approach which doesn't assumes # any intermediate buffers, we cannot calculate real content length # with the specified content encoding scheme. So, instead of lying # about content length and cause reading issues, we have to strip # this information. self.headers.pop(CONTENT_LENGTH, None) if self.headers: yield b'\r\n'.join( b': '.join(map(lambda i: i.encode('latin1'), item)) for item in self.headers.items() ) yield b'\r\n\r\n' yield from self._maybe_encode_stream(self._serialize_obj()) yield b'\r\n' def _serialize_obj(self): obj = self.obj mtype, stype, *_ = parse_mimetype(self.headers.get(CONTENT_TYPE)) serializer = self._serialize_map.get((mtype, stype)) if serializer is not None: return serializer(obj) for key in self._serialize_map: if not isinstance(key, tuple) and isinstance(obj, key): return self._serialize_map[key](obj) return self._serialize_default(obj) def _serialize_bytes(self, obj): yield obj def _serialize_str(self, obj): *_, params = parse_mimetype(self.headers.get(CONTENT_TYPE)) yield obj.encode(params.get('charset', 'us-ascii')) def _serialize_io(self, obj): while True: chunk = obj.read(self._chunk_size) if not chunk: break if isinstance(chunk, str): yield from self._serialize_str(chunk) else: yield from self._serialize_bytes(chunk) def _serialize_multipart(self, obj): yield from obj.serialize() def _serialize_json(self, obj): *_, params = parse_mimetype(self.headers.get(CONTENT_TYPE)) yield json.dumps(obj).encode(params.get('charset', 'utf-8')) def _serialize_form(self, obj): if isinstance(obj, Mapping): obj = list(obj.items()) return self._serialize_str(urlencode(obj, doseq=True)) def _serialize_default(self, obj): raise TypeError('unknown body part type %r' % type(obj)) def _maybe_encode_stream(self, stream): if CONTENT_ENCODING in self.headers: stream = self._apply_content_encoding(stream) if CONTENT_TRANSFER_ENCODING in self.headers: stream = self._apply_content_transfer_encoding(stream) yield from stream def _apply_content_encoding(self, stream): encoding = self.headers[CONTENT_ENCODING].lower() if encoding == 'identity': yield from stream elif encoding in ('deflate', 'gzip'): if encoding == 'gzip': zlib_mode = 16 + zlib.MAX_WBITS else: zlib_mode = -zlib.MAX_WBITS zcomp = zlib.compressobj(wbits=zlib_mode) for chunk in stream: yield zcomp.compress(chunk) else: yield zcomp.flush() else: raise RuntimeError('unknown content encoding: {}' ''.format(encoding)) def _apply_content_transfer_encoding(self, stream): encoding = self.headers[CONTENT_TRANSFER_ENCODING].lower() if encoding == 'base64': buffer = bytearray() while True: if buffer: div, mod = divmod(len(buffer), 3) chunk, buffer = buffer[:div * 3], buffer[div * 3:] if chunk: yield base64.b64encode(chunk) chunk = next(stream, None) if not chunk: if buffer: yield base64.b64encode(buffer[:]) return buffer.extend(chunk) elif encoding == 'quoted-printable': for chunk in stream: yield binascii.b2a_qp(chunk) else: raise RuntimeError('unknown content transfer encoding: {}' ''.format(encoding)) def set_content_disposition(self, disptype, **params): """Sets ``Content-Disposition`` header. :param str disptype: Disposition type: inline, attachment, form-data. Should be valid extension token (see RFC 2183) :param dict params: Disposition params """ if not disptype or not (TOKEN > set(disptype)): raise ValueError('bad content disposition type {!r}' ''.format(disptype)) value = disptype if params: lparams = [] for key, val in params.items(): if not key or not (TOKEN > set(key)): raise ValueError('bad content disposition parameter' ' {!r}={!r}'.format(key, val)) qval = quote(val, '') lparams.append((key, '"%s"' % qval)) if key == 'filename': lparams.append(('filename*', "utf-8''" + qval)) sparams = '; '.join('='.join(pair) for pair in lparams) value = '; '.join((value, sparams)) self.headers[CONTENT_DISPOSITION] = value @property def filename(self): """Returns filename specified in Content-Disposition header or ``None`` if missed.""" _, params = parse_content_disposition( self.headers.get(CONTENT_DISPOSITION)) return content_disposition_filename(params) class MultipartWriter(object): """Multipart body writer.""" #: Body part reader class for non multipart/* content types. part_writer_cls = BodyPartWriter def __init__(self, subtype='mixed', boundary=None): boundary = boundary if boundary is not None else uuid.uuid4().hex try: boundary.encode('us-ascii') except UnicodeEncodeError: raise ValueError('boundary should contains ASCII only chars') self.headers = CIMultiDict() self.headers[CONTENT_TYPE] = 'multipart/{}; boundary="{}"'.format( subtype, boundary ) self.parts = [] def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): pass def __iter__(self): return iter(self.parts) def __len__(self): return len(self.parts) @property def boundary(self): *_, params = parse_mimetype(self.headers.get(CONTENT_TYPE)) return params['boundary'].encode('us-ascii') def append(self, obj, headers=None): """Adds a new body part to multipart writer.""" if isinstance(obj, self.part_writer_cls): if headers: obj.headers.update(headers) self.parts.append(obj) else: if not headers: headers = CIMultiDict() self.parts.append(self.part_writer_cls(obj, headers)) return self.parts[-1] def append_json(self, obj, headers=None): """Helper to append JSON part.""" if not headers: headers = CIMultiDict() headers[CONTENT_TYPE] = 'application/json' return self.append(obj, headers) def append_form(self, obj, headers=None): """Helper to append form urlencoded part.""" if not headers: headers = CIMultiDict() headers[CONTENT_TYPE] = 'application/x-www-form-urlencoded' assert isinstance(obj, (Sequence, Mapping)) return self.append(obj, headers) def serialize(self): """Yields multipart byte chunks.""" if not self.parts: yield b'' return for part in self.parts: yield b'--' + self.boundary + b'\r\n' yield from part.serialize() else: yield b'--' + self.boundary + b'--\r\n' yield b'' aiohttp-0.20.2/aiohttp/__init__.py0000664000175000017500000000153312643555212017617 0ustar andrewandrew00000000000000# This relies on each of the submodules having an __all__ variable. __version__ = '0.20.2' from . import hdrs # noqa from .protocol import * # noqa from .connector import * # noqa from .client import * # noqa from .client_reqrep import * # noqa from .errors import * # noqa from .helpers import * # noqa from .parsers import * # noqa from .streams import * # noqa from .multidict import * # noqa from .multipart import * # noqa from .websocket_client import * # noqa __all__ = (client.__all__ + client_reqrep.__all__ + errors.__all__ + helpers.__all__ + parsers.__all__ + protocol.__all__ + connector.__all__ + streams.__all__ + multidict.__all__ + multipart.__all__ + websocket_client.__all__ + ('hdrs', '__version__')) aiohttp-0.20.2/aiohttp/test_utils.py0000664000175000017500000002251512620113026020246 0ustar andrewandrew00000000000000"""Utilities shared by tests.""" import cgi import contextlib import gc import email.parser import http.server import json import logging import io import os import re import ssl import sys import threading import traceback import urllib.parse import asyncio import aiohttp from aiohttp import server from aiohttp import helpers def run_briefly(loop): @asyncio.coroutine def once(): pass t = asyncio.Task(once(), loop=loop) loop.run_until_complete(t) @contextlib.contextmanager def run_server(loop, *, listen_addr=('127.0.0.1', 0), use_ssl=False, router=None): properties = {} transports = [] class HttpRequestHandler: def __init__(self, addr): if isinstance(addr, tuple): host, port = addr self.host = host self.port = port else: self.host = host = 'localhost' self.port = port = 0 self.address = addr self._url = '{}://{}:{}'.format( 'https' if use_ssl else 'http', host, port) def __getitem__(self, key): return properties[key] def __setitem__(self, key, value): properties[key] = value def url(self, *suffix): return urllib.parse.urljoin( self._url, '/'.join(str(s) for s in suffix)) class TestHttpServer(server.ServerHttpProtocol): def connection_made(self, transport): transports.append(transport) super().connection_made(transport) def handle_request(self, message, payload): if properties.get('close', False): return for hdr, val in message.headers.items(): if (hdr == 'EXPECT') and (val == '100-continue'): self.transport.write(b'HTTP/1.0 100 Continue\r\n\r\n') break if router is not None: body = yield from payload.read() rob = router( self, properties, self.transport, message, body) rob.dispatch() else: response = aiohttp.Response(self.writer, 200, message.version) text = b'Test message' response.add_header('Content-type', 'text/plain') response.add_header('Content-length', str(len(text))) response.send_headers() response.write(text) response.write_eof() if use_ssl: here = os.path.join(os.path.dirname(__file__), '..', 'tests') keyfile = os.path.join(here, 'sample.key') certfile = os.path.join(here, 'sample.crt') sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslcontext.load_cert_chain(certfile, keyfile) else: sslcontext = None def run(loop, fut): thread_loop = asyncio.new_event_loop() asyncio.set_event_loop(thread_loop) if isinstance(listen_addr, tuple): host, port = listen_addr server_coroutine = thread_loop.create_server( lambda: TestHttpServer(keep_alive=0.5), host, port, ssl=sslcontext) else: try: os.unlink(listen_addr) except FileNotFoundError: pass server_coroutine = thread_loop.create_unix_server( lambda: TestHttpServer(keep_alive=0.5, timeout=15), listen_addr, ssl=sslcontext) server = thread_loop.run_until_complete(server_coroutine) waiter = asyncio.Future(loop=thread_loop) loop.call_soon_threadsafe( fut.set_result, (thread_loop, waiter, server.sockets[0].getsockname())) try: thread_loop.run_until_complete(waiter) finally: # call pending connection_made if present run_briefly(thread_loop) # close opened transports for tr in transports: tr.close() run_briefly(thread_loop) # call close callbacks server.close() thread_loop.stop() thread_loop.close() gc.collect() fut = asyncio.Future(loop=loop) server_thread = threading.Thread(target=run, args=(loop, fut)) server_thread.start() thread_loop, waiter, addr = loop.run_until_complete(fut) try: yield HttpRequestHandler(addr) finally: thread_loop.call_soon_threadsafe(waiter.set_result, None) server_thread.join() class Router: _response_version = "1.1" _responses = http.server.BaseHTTPRequestHandler.responses def __init__(self, srv, props, transport, message, payload): # headers self._headers = http.client.HTTPMessage() for hdr, val in message.headers.items(): self._headers.add_header(hdr, val) self._srv = srv self._props = props self._transport = transport self._method = message.method self._uri = message.path self._version = message.version self._compression = message.compression self._body = payload url = urllib.parse.urlsplit(self._uri) self._path = url.path self._query = url.query @staticmethod def define(rmatch): def wrapper(fn): f_locals = sys._getframe(1).f_locals mapping = f_locals.setdefault('_mapping', []) mapping.append((re.compile(rmatch), fn.__name__)) return fn return wrapper def dispatch(self): # pragma: no cover for route, fn in self._mapping: match = route.match(self._path) if match is not None: try: return getattr(self, fn)(match) except Exception: out = io.StringIO() traceback.print_exc(file=out) self._response(500, out.getvalue()) return return self._response(self._start_response(404)) def _start_response(self, code): return aiohttp.Response(self._srv.writer, code) def _response(self, response, body=None, headers=None, chunked=False, write_body=None): r_headers = {} for key, val in self._headers.items(): key = '-'.join(p.capitalize() for p in key.split('-')) r_headers[key] = val encoding = self._headers.get('content-encoding', '').lower() if 'gzip' in encoding: # pragma: no cover cmod = 'gzip' elif 'deflate' in encoding: cmod = 'deflate' else: cmod = '' resp = { 'method': self._method, 'version': '%s.%s' % self._version, 'path': self._uri, 'headers': r_headers, 'origin': self._transport.get_extra_info('addr', ' ')[0], 'query': self._query, 'form': {}, 'compression': cmod, 'multipart-data': [] } if body: # pragma: no cover resp['content'] = body else: resp['content'] = self._body.decode('utf-8', 'ignore') ct = self._headers.get('content-type', '').lower() # application/x-www-form-urlencoded if ct == 'application/x-www-form-urlencoded': resp['form'] = urllib.parse.parse_qs(self._body.decode('latin1')) # multipart/form-data elif ct.startswith('multipart/form-data'): # pragma: no cover out = io.BytesIO() for key, val in self._headers.items(): out.write(bytes('{}: {}\r\n'.format(key, val), 'latin1')) out.write(b'\r\n') out.write(self._body) out.write(b'\r\n') out.seek(0) message = email.parser.BytesParser().parse(out) if message.is_multipart(): for msg in message.get_payload(): if msg.is_multipart(): logging.warning('multipart msg is not expected') else: key, params = cgi.parse_header( msg.get('content-disposition', '')) params['data'] = msg.get_payload() params['content-type'] = msg.get_content_type() cte = msg.get('content-transfer-encoding') if cte is not None: resp['content-transfer-encoding'] = cte resp['multipart-data'].append(params) body = json.dumps(resp, indent=4, sort_keys=True) # default headers hdrs = [('Connection', 'close'), ('Content-Type', 'application/json')] if chunked: hdrs.append(('Transfer-Encoding', 'chunked')) else: hdrs.append(('Content-Length', str(len(body)))) # extra headers if headers: hdrs.extend(headers.items()) if chunked: response.enable_chunked_encoding() # headers response.add_headers(*hdrs) response.send_headers() # write payload if write_body: try: write_body(response, body) except: return else: response.write(helpers.str_to_bytes(body)) response.write_eof() # keep-alive if response.keep_alive(): self._srv.keep_alive(True) aiohttp-0.20.2/aiohttp/connector.py0000664000175000017500000006104512631071601020046 0ustar andrewandrew00000000000000import asyncio import aiohttp import functools import http.cookies import ssl import socket import sys import traceback import warnings from collections import defaultdict from hashlib import md5, sha1, sha256 from itertools import chain from math import ceil from types import MappingProxyType from . import hdrs from .client import ClientRequest from .errors import ServerDisconnectedError from .errors import HttpProxyError, ProxyConnectionError from .errors import ClientOSError, ClientTimeoutError from .errors import FingerprintMismatch from .helpers import BasicAuth __all__ = ('BaseConnector', 'TCPConnector', 'ProxyConnector', 'UnixConnector') PY_343 = sys.version_info >= (3, 4, 3) HASHFUNC_BY_DIGESTLEN = { 16: md5, 20: sha1, 32: sha256, } class Connection(object): _source_traceback = None _transport = None def __init__(self, connector, key, request, transport, protocol, loop): self._key = key self._connector = connector self._request = request self._transport = transport self._protocol = protocol self._loop = loop self.reader = protocol.reader self.writer = protocol.writer if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) def __repr__(self): return 'Connection<{}>'.format(self._key) def __del__(self, _warnings=warnings): if self._transport is not None: _warnings.warn('Unclosed connection {!r}'.format(self), ResourceWarning) if hasattr(self._loop, 'is_closed'): if self._loop.is_closed(): return self._connector._release( self._key, self._request, self._transport, self._protocol, should_close=True) context = {'client_connection': self, 'message': 'Unclosed connection'} if self._source_traceback is not None: context['source_traceback'] = self._source_traceback self._loop.call_exception_handler(context) @property def loop(self): return self._loop def close(self): if self._transport is not None: self._connector._release( self._key, self._request, self._transport, self._protocol, should_close=True) self._transport = None def release(self): if self._transport is not None: self._connector._release( self._key, self._request, self._transport, self._protocol, should_close=False) self._transport = None def detach(self): self._transport = None @property def closed(self): return self._transport is None class BaseConnector(object): """Base connector class. :param conn_timeout: (optional) Connect timeout. :param keepalive_timeout: (optional) Keep-alive timeout. :param bool force_close: Set to True to force close and do reconnect after each request (and between redirects). :param loop: Optional event loop. """ _closed = True # prevent AttributeError in __del__ if ctor was failed _source_traceback = None def __init__(self, *, conn_timeout=None, keepalive_timeout=30, share_cookies=False, force_close=False, limit=None, loop=None): if loop is None: loop = asyncio.get_event_loop() self._closed = False if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) self._conns = {} self._acquired = defaultdict(set) self._conn_timeout = conn_timeout self._keepalive_timeout = keepalive_timeout if share_cookies: warnings.warn( 'Using `share_cookies` is deprecated. ' 'Use Session object instead', DeprecationWarning) self._share_cookies = share_cookies self._cleanup_handle = None self._force_close = force_close self._limit = limit self._waiters = defaultdict(list) self._loop = loop self._factory = functools.partial( aiohttp.StreamProtocol, loop=loop, disconnect_error=ServerDisconnectedError) self.cookies = http.cookies.SimpleCookie() def __del__(self, _warnings=warnings): if self._closed: return if not self._conns: return conns = [repr(c) for c in self._conns.values()] self.close() _warnings.warn("Unclosed connector {!r}".format(self), ResourceWarning) context = {'connector': self, 'connections': conns, 'message': 'Unclosed connector'} if self._source_traceback is not None: context['source_traceback'] = self._source_traceback self._loop.call_exception_handler(context) @property def force_close(self): """Ultimately close connection on releasing if True.""" return self._force_close @property def limit(self): """The limit for simultaneous connections to the same endpoint. Endpoints are the same if they are have equal (host, port, is_ssl) triple. If limit is None the connector has no limit (default). """ return self._limit def _cleanup(self): """Cleanup unused transports.""" if self._cleanup_handle: self._cleanup_handle.cancel() self._cleanup_handle = None now = self._loop.time() connections = {} timeout = self._keepalive_timeout for key, conns in self._conns.items(): alive = [] for transport, proto, t0 in conns: if transport is not None: if proto and not proto.is_connected(): transport = None else: delta = t0 + self._keepalive_timeout - now if delta < 0: transport.close() transport = None elif delta < timeout: timeout = delta if transport is not None: alive.append((transport, proto, t0)) if alive: connections[key] = alive if connections: self._cleanup_handle = self._loop.call_at( ceil(now + timeout), self._cleanup) self._conns = connections def _start_cleanup_task(self): if self._cleanup_handle is None: now = self._loop.time() self._cleanup_handle = self._loop.call_at( ceil(now + self._keepalive_timeout), self._cleanup) def close(self): """Close all opened transports.""" if self._closed: return self._closed = True try: if hasattr(self._loop, 'is_closed'): if self._loop.is_closed(): return for key, data in self._conns.items(): for transport, proto, t0 in data: transport.close() for transport in chain(*self._acquired.values()): transport.close() if self._cleanup_handle: self._cleanup_handle.cancel() finally: self._conns.clear() self._acquired.clear() self._cleanup_handle = None @property def closed(self): """Is connector closed. A readonly property. """ return self._closed def update_cookies(self, cookies): """Update shared cookies. Deprecated, use ClientSession instead. """ if isinstance(cookies, dict): cookies = cookies.items() for name, value in cookies: if PY_343: self.cookies[name] = value else: if isinstance(value, http.cookies.Morsel): # use dict method because SimpleCookie class modifies value dict.__setitem__(self.cookies, name, value) else: self.cookies[name] = value @asyncio.coroutine def connect(self, req): """Get from pool or create new connection.""" key = (req.host, req.port, req.ssl) limit = self._limit if limit is not None: fut = asyncio.Future(loop=self._loop) waiters = self._waiters[key] # The limit defines the maximum number of concurrent connections # for a key. Waiters must be counted against the limit, even before # the underlying connection is created. available = limit - len(waiters) - len(self._acquired[key]) # Don't wait if there are connections available. if available > 0: fut.set_result(None) # This connection will now count towards the limit. waiters.append(fut) yield from fut transport, proto = self._get(key) if transport is None: try: if self._conn_timeout: transport, proto = yield from asyncio.wait_for( self._create_connection(req), self._conn_timeout, loop=self._loop) else: transport, proto = yield from self._create_connection(req) except asyncio.TimeoutError as exc: raise ClientTimeoutError( 'Connection timeout to host {0[0]}:{0[1]} ssl:{0[2]}' .format(key)) from exc except OSError as exc: raise ClientOSError( exc.errno, 'Cannot connect to host {0[0]}:{0[1]} ssl:{0[2]} [{1}]' .format(key, exc.strerror)) from exc self._acquired[key].add(transport) conn = Connection(self, key, req, transport, proto, self._loop) return conn def _get(self, key): try: conns = self._conns[key] except KeyError: return None, None t1 = self._loop.time() while conns: transport, proto, t0 = conns.pop() if transport is not None and proto.is_connected(): if t1 - t0 > self._keepalive_timeout: transport.close() transport = None else: if not conns: # The very last connection was reclaimed: drop the key del self._conns[key] return transport, proto # No more connections: drop the key del self._conns[key] return None, None def _release(self, key, req, transport, protocol, *, should_close=False): if self._closed: # acquired connection is already released on connector closing return acquired = self._acquired[key] try: acquired.remove(transport) except KeyError: # pragma: no cover # this may be result of undetermenistic order of objects # finalization due garbage collection. pass else: if self._limit is not None and len(acquired) < self._limit: waiters = self._waiters[key] while waiters: waiter = waiters.pop(0) if not waiter.done(): waiter.set_result(None) break resp = req.response if not should_close: if self._force_close: should_close = True elif resp is not None: should_close = resp._should_close reader = protocol.reader if should_close or (reader.output and not reader.output.at_eof()): transport.close() else: conns = self._conns.get(key) if conns is None: conns = self._conns[key] = [] conns.append((transport, protocol, self._loop.time())) reader.unset_parser() self._start_cleanup_task() @asyncio.coroutine def _create_connection(self, req): raise NotImplementedError() _SSL_OP_NO_COMPRESSION = getattr(ssl, "OP_NO_COMPRESSION", 0) _marker = object() class TCPConnector(BaseConnector): """TCP connector. :param bool verify_ssl: Set to True to check ssl certifications. :param bytes fingerprint: Pass the binary md5, sha1, or sha256 digest of the expected certificate in DER format to verify that the certificate the server presents matches. See also https://en.wikipedia.org/wiki/Transport_Layer_Security#Certificate_pinning :param bool resolve: Set to True to do DNS lookup for host name. :param family: socket address family :param args: see :class:`BaseConnector` :param kwargs: see :class:`BaseConnector` """ def __init__(self, *, verify_ssl=True, fingerprint=None, resolve=_marker, use_dns_cache=_marker, family=0, ssl_context=None, **kwargs): super().__init__(**kwargs) if not verify_ssl and ssl_context is not None: raise ValueError( "Either disable ssl certificate validation by " "verify_ssl=False or specify ssl_context, not both.") self._verify_ssl = verify_ssl if fingerprint: digestlen = len(fingerprint) hashfunc = HASHFUNC_BY_DIGESTLEN.get(digestlen) if not hashfunc: raise ValueError('fingerprint has invalid length') self._hashfunc = hashfunc self._fingerprint = fingerprint if resolve is not _marker: warnings.warn(("resolve parameter is deprecated, " "use use_dns_cache instead"), DeprecationWarning, stacklevel=2) if use_dns_cache is not _marker and resolve is not _marker: if use_dns_cache != resolve: raise ValueError("use_dns_cache must agree with resolve") _use_dns_cache = use_dns_cache elif use_dns_cache is not _marker: _use_dns_cache = use_dns_cache elif resolve is not _marker: _use_dns_cache = resolve else: _use_dns_cache = False self._use_dns_cache = _use_dns_cache self._cached_hosts = {} self._ssl_context = ssl_context self._family = family @property def verify_ssl(self): """Do check for ssl certifications?""" return self._verify_ssl @property def fingerprint(self): """Expected ssl certificate fingerprint.""" return self._fingerprint @property def ssl_context(self): """SSLContext instance for https requests. Lazy property, creates context on demand. """ if self._ssl_context is None: if not self._verify_ssl: sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslcontext.options |= ssl.OP_NO_SSLv2 sslcontext.options |= ssl.OP_NO_SSLv3 sslcontext.options |= _SSL_OP_NO_COMPRESSION sslcontext.set_default_verify_paths() else: sslcontext = ssl.create_default_context() self._ssl_context = sslcontext return self._ssl_context @property def family(self): """Socket family like AF_INET.""" return self._family @property def use_dns_cache(self): """True if local DNS caching is enabled.""" return self._use_dns_cache @property def cached_hosts(self): """Read-only dict of cached DNS record.""" return MappingProxyType(self._cached_hosts) def clear_dns_cache(self, host=None, port=None): """Remove specified host/port or clear all dns local cache.""" if host is not None and port is not None: self._cached_hosts.pop((host, port), None) elif host is not None or port is not None: raise ValueError("either both host and port " "or none of them are allowed") else: self._cached_hosts.clear() @property def resolve(self): """Do DNS lookup for host name?""" warnings.warn((".resolve property is deprecated, " "use .dns_cache instead"), DeprecationWarning, stacklevel=2) return self.use_dns_cache @property def resolved_hosts(self): """The dict of (host, port) -> (ipaddr, port) pairs.""" warnings.warn((".resolved_hosts property is deprecated, " "use .cached_hosts instead"), DeprecationWarning, stacklevel=2) return self.cached_hosts def clear_resolved_hosts(self, host=None, port=None): """Remove specified host/port or clear all resolve cache.""" warnings.warn((".clear_resolved_hosts() is deprecated, " "use .clear_dns_cache() instead"), DeprecationWarning, stacklevel=2) if host is not None and port is not None: self.clear_dns_cache(host, port) else: self.clear_dns_cache() @asyncio.coroutine def _resolve_host(self, host, port): if self._use_dns_cache: key = (host, port) if key not in self._cached_hosts: infos = yield from self._loop.getaddrinfo( host, port, type=socket.SOCK_STREAM, family=self._family) hosts = [] for family, _, proto, _, address in infos: hosts.append( {'hostname': host, 'host': address[0], 'port': address[1], 'family': family, 'proto': proto, 'flags': socket.AI_NUMERICHOST}) self._cached_hosts[key] = hosts return list(self._cached_hosts[key]) else: return [{'hostname': host, 'host': host, 'port': port, 'family': self._family, 'proto': 0, 'flags': 0}] @asyncio.coroutine def _create_connection(self, req): """Create connection. Has same keyword arguments as BaseEventLoop.create_connection. """ if req.ssl: sslcontext = self.ssl_context else: sslcontext = None hosts = yield from self._resolve_host(req.host, req.port) exc = None for hinfo in hosts: try: host = hinfo['host'] port = hinfo['port'] transp, proto = yield from self._loop.create_connection( self._factory, host, port, ssl=sslcontext, family=hinfo['family'], proto=hinfo['proto'], flags=hinfo['flags'], server_hostname=hinfo['hostname'] if sslcontext else None) has_cert = transp.get_extra_info('sslcontext') if has_cert and self._fingerprint: sock = transp.get_extra_info('socket') if not hasattr(sock, 'getpeercert'): # Workaround for asyncio 3.5.0 # Starting from 3.5.1 version # there is 'ssl_object' extra info in transport sock = transp._ssl_protocol._sslpipe.ssl_object # gives DER-encoded cert as a sequence of bytes (or None) cert = sock.getpeercert(binary_form=True) assert cert got = self._hashfunc(cert).digest() expected = self._fingerprint if got != expected: transp.close() raise FingerprintMismatch(expected, got, host, port) return transp, proto except OSError as e: exc = e else: raise ClientOSError(exc.errno, 'Can not connect to %s:%s [%s]' % (req.host, req.port, exc.strerror)) from exc class ProxyConnector(TCPConnector): """Http Proxy connector. :param str proxy: Proxy URL address. Only http proxy supported. :param proxy_auth: (optional) Proxy HTTP Basic Auth :type proxy_auth: aiohttp.helpers.BasicAuth :param args: see :class:`TCPConnector` :param kwargs: see :class:`TCPConnector` Usage: >>> conn = ProxyConnector(proxy="http://some.proxy.com") >>> session = ClientSession(connector=conn) >>> resp = yield from session.get('http://python.org') """ def __init__(self, proxy, *, proxy_auth=None, force_close=True, **kwargs): super().__init__(force_close=force_close, **kwargs) self._proxy = proxy self._proxy_auth = proxy_auth assert proxy.startswith('http://'), ( "Only http proxy supported", proxy) assert proxy_auth is None or isinstance(proxy_auth, BasicAuth), ( "proxy_auth must be None or BasicAuth() tuple", proxy_auth) @property def proxy(self): """Proxy URL.""" return self._proxy @property def proxy_auth(self): """Proxy auth info. Should be BasicAuth instance. """ return self._proxy_auth @asyncio.coroutine def _create_connection(self, req): proxy_req = ClientRequest( hdrs.METH_GET, self._proxy, headers={hdrs.HOST: req.host}, auth=self._proxy_auth, loop=self._loop) try: transport, proto = yield from super()._create_connection(proxy_req) except OSError as exc: raise ProxyConnectionError(*exc.args) from exc if not req.ssl: req.path = '{scheme}://{host}{path}'.format(scheme=req.scheme, host=req.netloc, path=req.path) if hdrs.AUTHORIZATION in proxy_req.headers: auth = proxy_req.headers[hdrs.AUTHORIZATION] del proxy_req.headers[hdrs.AUTHORIZATION] if not req.ssl: req.headers[hdrs.PROXY_AUTHORIZATION] = auth else: proxy_req.headers[hdrs.PROXY_AUTHORIZATION] = auth if req.ssl: # For HTTPS requests over HTTP proxy # we must notify proxy to tunnel connection # so we send CONNECT command: # CONNECT www.python.org:443 HTTP/1.1 # Host: www.python.org # # next we must do TLS handshake and so on # to do this we must wrap raw socket into secure one # asyncio handles this perfectly proxy_req.method = hdrs.METH_CONNECT proxy_req.path = '{}:{}'.format(req.host, req.port) key = (req.host, req.port, req.ssl) conn = Connection(self, key, proxy_req, transport, proto, self._loop) self._acquired[key].add(conn._transport) proxy_resp = proxy_req.send(conn.writer, conn.reader) try: resp = yield from proxy_resp.start(conn, True) except: proxy_resp.close() conn.close() raise else: conn.detach() if resp.status != 200: raise HttpProxyError(code=resp.status, message=resp.reason) rawsock = transport.get_extra_info('socket', default=None) if rawsock is None: raise RuntimeError( "Transport does not expose socket instance") transport.pause_reading() transport, proto = yield from self._loop.create_connection( self._factory, ssl=self.ssl_context, sock=rawsock, server_hostname=req.host) finally: proxy_resp.close() return transport, proto class UnixConnector(BaseConnector): """Unix socket connector. :param str path: Unix socket path. :param args: see :class:`BaseConnector` :param kwargs: see :class:`BaseConnector` Usage: >>> conn = UnixConnector(path='/path/to/socket') >>> session = ClientSession(connector=conn) >>> resp = yield from session.get('http://python.org') """ def __init__(self, path, **kwargs): super().__init__(**kwargs) self._path = path @property def path(self): """Path to unix socket.""" return self._path @asyncio.coroutine def _create_connection(self, req): return (yield from self._loop.create_unix_connection( self._factory, self._path)) aiohttp-0.20.2/aiohttp/client_reqrep.py0000664000175000017500000006224412643555212020722 0ustar andrewandrew00000000000000import asyncio import collections import http.cookies import io import json import mimetypes import os import sys import traceback import urllib.parse import warnings try: import cchardet as chardet except ImportError: import chardet import aiohttp from . import hdrs, helpers, streams from .log import client_logger from .streams import EOF_MARKER, FlowControlStreamReader from .multidict import (CIMultiDictProxy, MultiDictProxy, MultiDict, CIMultiDict) from .multipart import MultipartWriter from .protocol import HttpMessage __all__ = ('ClientRequest', 'ClientResponse') PY_35 = sys.version_info >= (3, 5) HTTP_PORT = 80 HTTPS_PORT = 443 class ClientRequest: GET_METHODS = {hdrs.METH_GET, hdrs.METH_HEAD, hdrs.METH_OPTIONS} POST_METHODS = {hdrs.METH_PATCH, hdrs.METH_POST, hdrs.METH_PUT} ALL_METHODS = GET_METHODS.union(POST_METHODS).union( {hdrs.METH_DELETE, hdrs.METH_TRACE}) DEFAULT_HEADERS = { hdrs.ACCEPT: '*/*', hdrs.ACCEPT_ENCODING: 'gzip, deflate', } SERVER_SOFTWARE = HttpMessage.SERVER_SOFTWARE body = b'' auth = None response = None response_class = None _writer = None # async task for streaming data _continue = None # waiter future for '100 Continue' response # N.B. # Adding __del__ method with self._writer closing doesn't make sense # 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, encoding='utf-8', version=aiohttp.HttpVersion11, compress=None, chunked=None, expect100=False, loop=None, response_class=None): if loop is None: loop = asyncio.get_event_loop() self.url = url self.method = method.upper() self.encoding = encoding self.chunked = chunked self.compress = compress self.loop = loop self.response_class = response_class or ClientResponse if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) self.update_version(version) self.update_host(url) self.update_path(params) self.update_headers(headers) self.update_auto_headers(skip_auto_headers) self.update_cookies(cookies) self.update_content_encoding() self.update_auth(auth) self.update_body_from_data(data, skip_auto_headers) self.update_transfer_encoding() self.update_expect_continue(expect100) def update_host(self, url): """Update destination host, port and connection type (ssl).""" url_parsed = urllib.parse.urlsplit(url) # check for network location part netloc = url_parsed.netloc if not netloc: raise ValueError('Host could not be detected.') # get host/port host = url_parsed.hostname if not host: raise ValueError('Host could not be detected.') try: port = url_parsed.port except ValueError: raise ValueError( 'Port number could not be converted.') from None # check domain idna encoding try: netloc = netloc.encode('idna').decode('utf-8') host = host.encode('idna').decode('utf-8') except UnicodeError: raise ValueError('URL has an invalid label.') # basic auth info username, password = url_parsed.username, url_parsed.password if username: self.auth = helpers.BasicAuth(username, password or '') netloc = netloc.split('@', 1)[1] # Record entire netloc for usage in host header self.netloc = netloc scheme = url_parsed.scheme self.ssl = scheme in ('https', 'wss') # set port number if it isn't already set if not port: if self.ssl: port = HTTPS_PORT else: port = HTTP_PORT self.host, self.port, self.scheme = host, port, scheme def update_version(self, version): """Convert request version to two elements tuple. parser http version '1.1' => (1, 1) """ if isinstance(version, str): v = [l.strip() for l in version.split('.', 1)] try: version = 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_path(self, params): """Build path.""" # extract path scheme, netloc, path, query, fragment = urllib.parse.urlsplit(self.url) if not path: path = '/' if isinstance(params, collections.Mapping): params = list(params.items()) if params: if not isinstance(params, str): params = urllib.parse.urlencode(params) if query: query = '%s&%s' % (query, params) else: query = params self.path = urllib.parse.urlunsplit(('', '', helpers.requote_uri(path), query, fragment)) self.url = urllib.parse.urlunsplit( (scheme, netloc, self.path, '', '')) def update_headers(self, headers): """Update request headers.""" self.headers = CIMultiDict() if headers: if isinstance(headers, dict): headers = headers.items() elif isinstance(headers, (MultiDictProxy, MultiDict)): headers = headers.items() for key, value in headers: self.headers.add(key, value) def update_auto_headers(self, skip_auto_headers): self.skip_auto_headers = skip_auto_headers used_headers = set(self.headers) | skip_auto_headers 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: self.headers[hdrs.HOST] = self.netloc if hdrs.USER_AGENT not in used_headers: self.headers[hdrs.USER_AGENT] = self.SERVER_SOFTWARE def update_cookies(self, cookies): """Update request cookies header.""" if not cookies: return c = http.cookies.SimpleCookie() if hdrs.COOKIE in self.headers: c.load(self.headers.get(hdrs.COOKIE, '')) del self.headers[hdrs.COOKIE] if isinstance(cookies, dict): cookies = cookies.items() for name, value in cookies: if isinstance(value, http.cookies.Morsel): c[value.key] = value.value else: c[name] = value self.headers[hdrs.COOKIE] = c.output(header='', sep=';').strip() def update_content_encoding(self): """Set request content encoding.""" enc = self.headers.get(hdrs.CONTENT_ENCODING, '').lower() if enc: if self.compress is not False: self.compress = enc # enable chunked, no need to deal with length self.chunked = True elif self.compress: if not isinstance(self.compress, str): self.compress = 'deflate' self.headers[hdrs.CONTENT_ENCODING] = self.compress self.chunked = True # enable chunked, no need to deal with length def update_auth(self, auth): """Set basic auth.""" if auth is None: auth = self.auth if auth is None: return if not isinstance(auth, helpers.BasicAuth): warnings.warn( 'BasicAuth() tuple is required instead ', DeprecationWarning) auth = helpers.BasicAuth(*auth) self.headers[hdrs.AUTHORIZATION] = auth.encode() def update_body_from_data(self, data, skip_auto_headers): if not data: return if isinstance(data, str): data = data.encode(self.encoding) if isinstance(data, (bytes, bytearray)): self.body = data if (hdrs.CONTENT_TYPE not in self.headers and hdrs.CONTENT_TYPE not in skip_auto_headers): self.headers[hdrs.CONTENT_TYPE] = 'application/octet-stream' if hdrs.CONTENT_LENGTH not in self.headers and not self.chunked: self.headers[hdrs.CONTENT_LENGTH] = str(len(self.body)) elif isinstance(data, (asyncio.StreamReader, streams.DataQueue)): self.body = data elif asyncio.iscoroutine(data): self.body = data if (hdrs.CONTENT_LENGTH not in self.headers and self.chunked is None): self.chunked = True elif isinstance(data, io.IOBase): assert not isinstance(data, io.StringIO), \ 'attempt to send text data instead of binary' self.body = data if not self.chunked and isinstance(data, io.BytesIO): # Not chunking if content-length can be determined size = len(data.getbuffer()) self.headers[hdrs.CONTENT_LENGTH] = str(size) self.chunked = False elif not self.chunked and isinstance(data, io.BufferedReader): # Not chunking if content-length can be determined try: size = os.fstat(data.fileno()).st_size - data.tell() self.headers[hdrs.CONTENT_LENGTH] = str(size) self.chunked = False except OSError: # data.fileno() is not supported, e.g. # io.BufferedReader(io.BytesIO(b'data')) self.chunked = True else: self.chunked = True if hasattr(data, 'mode'): if data.mode == 'r': raise ValueError('file {!r} should be open in binary mode' ''.format(data)) if (hdrs.CONTENT_TYPE not in self.headers and hdrs.CONTENT_TYPE not in skip_auto_headers and hasattr(data, 'name')): mime = mimetypes.guess_type(data.name)[0] mime = 'application/octet-stream' if mime is None else mime self.headers[hdrs.CONTENT_TYPE] = mime elif isinstance(data, MultipartWriter): self.body = data.serialize() self.headers.update(data.headers) self.chunked = self.chunked or 8192 else: if not isinstance(data, helpers.FormData): data = helpers.FormData(data) self.body = data(self.encoding) if (hdrs.CONTENT_TYPE not in self.headers and hdrs.CONTENT_TYPE not in skip_auto_headers): self.headers[hdrs.CONTENT_TYPE] = data.content_type if data.is_multipart: self.chunked = self.chunked or 8192 else: if (hdrs.CONTENT_LENGTH not in self.headers and not self.chunked): self.headers[hdrs.CONTENT_LENGTH] = str(len(self.body)) def update_transfer_encoding(self): """Analyze transfer-encoding header.""" te = self.headers.get(hdrs.TRANSFER_ENCODING, '').lower() if self.chunked: if hdrs.CONTENT_LENGTH in self.headers: del self.headers[hdrs.CONTENT_LENGTH] if 'chunked' not in te: self.headers[hdrs.TRANSFER_ENCODING] = 'chunked' self.chunked = self.chunked if type(self.chunked) is int else 8192 else: if 'chunked' in te: self.chunked = 8192 else: self.chunked = None if hdrs.CONTENT_LENGTH not in self.headers: self.headers[hdrs.CONTENT_LENGTH] = str(len(self.body)) def update_expect_continue(self, expect=False): if expect: self.headers[hdrs.EXPECT] = '100-continue' elif self.headers.get(hdrs.EXPECT, '').lower() == '100-continue': expect = True if expect: self._continue = asyncio.Future(loop=self.loop) @asyncio.coroutine def write_bytes(self, request, reader): """Support coroutines that yields bytes objects.""" # 100 response if self._continue is not None: yield from self._continue try: if asyncio.iscoroutine(self.body): exc = None value = None stream = self.body while True: try: if exc is not None: result = stream.throw(exc) else: result = stream.send(value) except StopIteration as exc: if isinstance(exc.value, bytes): yield from request.write(exc.value, drain=True) break except: self.response.close(True) raise if isinstance(result, asyncio.Future): exc = None value = None try: value = yield result except Exception as err: exc = err elif isinstance(result, (bytes, bytearray)): yield from request.write(result, drain=True) value = None else: raise ValueError( 'Bytes object is expected, got: %s.' % type(result)) elif isinstance(self.body, asyncio.StreamReader): chunk = yield from self.body.read(streams.DEFAULT_LIMIT) while chunk: yield from request.write(chunk, drain=True) chunk = yield from self.body.read(streams.DEFAULT_LIMIT) elif isinstance(self.body, streams.DataQueue): while True: try: chunk = yield from self.body.read() if chunk is EOF_MARKER: break yield from request.write(chunk, drain=True) except streams.EofStream: break elif isinstance(self.body, io.IOBase): chunk = self.body.read(self.chunked) while chunk: request.write(chunk) chunk = self.body.read(self.chunked) else: if isinstance(self.body, (bytes, bytearray)): self.body = (self.body,) for chunk in self.body: request.write(chunk) except Exception as exc: new_exc = aiohttp.ClientRequestError( 'Can not write request body for %s' % self.url) new_exc.__context__ = exc new_exc.__cause__ = exc reader.set_exception(new_exc) else: try: ret = request.write_eof() # NB: in asyncio 3.4.1+ StreamWriter.drain() is coroutine # see bug #170 if (asyncio.iscoroutine(ret) or isinstance(ret, asyncio.Future)): yield from ret except Exception as exc: new_exc = aiohttp.ClientRequestError( 'Can not write request body for %s' % self.url) new_exc.__context__ = exc new_exc.__cause__ = exc reader.set_exception(new_exc) self._writer = None def send(self, writer, reader): request = aiohttp.Request(writer, self.method, self.path, self.version) if self.compress: request.add_compression_filter(self.compress) if self.chunked is not None: request.enable_chunked_encoding() request.add_chunking_filter(self.chunked) # set default content-type if (self.method in self.POST_METHODS and hdrs.CONTENT_TYPE not in self.skip_auto_headers and hdrs.CONTENT_TYPE not in self.headers): self.headers[hdrs.CONTENT_TYPE] = 'application/octet-stream' for k, value in self.headers.items(): request.add_header(k, value) request.send_headers() self._writer = helpers.ensure_future( self.write_bytes(request, reader), loop=self.loop) self.response = self.response_class( self.method, self.url, self.host, writer=self._writer, continue100=self._continue) self.response._post_init(self.loop) return self.response @asyncio.coroutine def close(self): if self._writer is not None: try: yield from self._writer finally: self._writer = None def terminate(self): if self._writer is not None: if hasattr(self.loop, 'is_closed'): if not self.loop.is_closed(): self._writer.cancel() else: self._writer.cancel() self._writer = None class ClientResponse: # from the Status-Line of the response version = None # HTTP-Version status = None # Status-Code reason = None # Reason-Phrase cookies = None # Response cookies (Set-Cookie) content = None # Payload stream headers = None # Response headers, CIMultiDictProxy _connection = None # current connection flow_control_class = FlowControlStreamReader # reader flow control _reader = None # input stream _response_parser = aiohttp.HttpResponseParser() _source_traceback = None # setted up by ClientRequest after ClientResponse object creation # post-init stage allows to not change ctor signature _loop = None _closed = True # to allow __del__ for non-initialized properly response def __init__(self, method, url, host='', *, writer=None, continue100=None): super().__init__() self.method = method self.url = url self.host = host self._content = None self._writer = writer self._continue = continue100 self._closed = False self._should_close = True # override by message.should_close later self._history = () def _post_init(self, loop): self._loop = loop if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) def __del__(self, _warnings=warnings): if self._closed: return self.close() _warnings.warn("Unclosed response {!r}".format(self), ResourceWarning) context = {'client_response': self, 'message': 'Unclosed response'} if self._source_traceback: context['source_traceback'] = self._source_traceback self._loop.call_exception_handler(context) def __repr__(self): out = io.StringIO() print(''.format( self.url, self.status, self.reason), file=out) print(self.headers, file=out) return out.getvalue() @property def connection(self): return self._connection @property def history(self): """A sequence of of responses, if redirects occured.""" return self._history def waiting_for_continue(self): return self._continue is not None def _setup_connection(self, connection): self._reader = connection.reader self._connection = connection self.content = self.flow_control_class( connection.reader, loop=connection.loop) def _need_parse_response_body(self): return (self.method.lower() != 'head' and self.status not in [204, 304]) @asyncio.coroutine def start(self, connection, read_until_eof=False): """Start response processing.""" self._setup_connection(connection) while True: httpstream = self._reader.set_parser(self._response_parser) # read response message = yield from httpstream.read() if message.code != 100: break if self._continue is not None and not self._continue.done(): self._continue.set_result(True) self._continue = None # response status self.version = message.version self.status = message.code self.reason = message.reason self._should_close = message.should_close # headers self.headers = CIMultiDictProxy(message.headers) # payload response_with_body = self._need_parse_response_body() self._reader.set_parser( aiohttp.HttpPayloadParser(message, readall=read_until_eof, response_with_body=response_with_body), self.content) # cookies self.cookies = http.cookies.SimpleCookie() if hdrs.SET_COOKIE in self.headers: for hdr in self.headers.getall(hdrs.SET_COOKIE): try: self.cookies.load(hdr) except http.cookies.CookieError as exc: client_logger.warning( 'Can not load response cookies: %s', exc) return self def close(self, force=True): if not force: warnings.warn("force parameter should be True", DeprecationWarning, stacklevel=2) if self._closed: return self._closed = True if hasattr(self._loop, 'is_closed'): if self._loop.is_closed(): return if self._connection is not None: self._connection.close() self._connection = None self._cleanup_writer() @asyncio.coroutine def release(self): try: content = self.content if content is not None and not content.at_eof(): chunk = yield from content.readany() while chunk is not EOF_MARKER or chunk: chunk = yield from content.readany() finally: self._closed = True if self._connection is not None: self._connection.release() if self._reader is not None: self._reader.unset_parser() self._connection = None self._cleanup_writer() def _cleanup_writer(self): if self._writer is not None and not self._writer.done(): self._writer.cancel() self._writer = None @asyncio.coroutine def wait_for_close(self): if self._writer is not None: try: yield from self._writer finally: self._writer = None yield from self.release() @asyncio.coroutine def read(self, decode=False): """Read response payload.""" if self._content is None: try: self._content = yield from self.content.read() except: self.close() raise else: yield from self.release() data = self._content if decode: warnings.warn( '.read(True) is deprecated. use .json() instead', DeprecationWarning) return (yield from self.json()) return data def _get_encoding(self): ctype = self.headers.get(hdrs.CONTENT_TYPE, '').lower() mtype, stype, _, params = helpers.parse_mimetype(ctype) encoding = params.get('charset') if not encoding: encoding = chardet.detect(self._content)['encoding'] if not encoding: encoding = 'utf-8' return encoding @asyncio.coroutine def text(self, encoding=None): """Read response payload and decode.""" if self._content is None: yield from self.read() if encoding is None: encoding = self._get_encoding() return self._content.decode(encoding) @asyncio.coroutine def json(self, *, encoding=None, loads=json.loads): """Read and decodes JSON response.""" if self._content is None: yield from self.read() ctype = self.headers.get(hdrs.CONTENT_TYPE, '').lower() if 'json' not in ctype: client_logger.warning( 'Attempt to decode JSON with unexpected mimetype: %s', ctype) stripped = self._content.strip() if not stripped: return None if encoding is None: encoding = self._get_encoding() return loads(stripped.decode(encoding)) if PY_35: @asyncio.coroutine def __aenter__(self): return self @asyncio.coroutine def __aexit__(self, exc_type, exc_val, exc_tb): if exc_type is None: yield from self.release() else: self.close() aiohttp-0.20.2/aiohttp/helpers.py0000664000175000017500000003720712640154230017521 0ustar andrewandrew00000000000000"""Various helper functions""" import asyncio import base64 import datetime import functools import io import os import re from urllib.parse import quote, urlencode from collections import namedtuple from . import hdrs, multidict from .errors import InvalidURL try: from asyncio import ensure_future except ImportError: ensure_future = asyncio.async __all__ = ('BasicAuth', 'FormData', 'parse_mimetype', 'Timeout') class BasicAuth(namedtuple('BasicAuth', ['login', 'password', 'encoding'])): """Http basic authentication helper. :param str login: Login :param str password: Password :param str encoding: (optional) encoding ('latin1' by default) """ def __new__(cls, login, password='', encoding='latin1'): if login is None: raise ValueError('None is not allowed as login value') if password is None: raise ValueError('None is not allowed as password value') return super().__new__(cls, login, password, encoding) def encode(self): """Encode credentials.""" creds = ('%s:%s' % (self.login, self.password)).encode(self.encoding) return 'Basic %s' % base64.b64encode(creds).decode(self.encoding) class FormData: """Helper class for multipart/form-data and application/x-www-form-urlencoded body generation.""" def __init__(self, fields=()): from . import multipart self._writer = multipart.MultipartWriter('form-data') self._fields = [] self._is_multipart = False if isinstance(fields, dict): fields = list(fields.items()) elif not isinstance(fields, (list, tuple)): fields = (fields,) self.add_fields(*fields) @property def is_multipart(self): return self._is_multipart @property def content_type(self): if self._is_multipart: return self._writer.headers[hdrs.CONTENT_TYPE] else: return 'application/x-www-form-urlencoded' def add_field(self, name, value, *, content_type=None, filename=None, content_transfer_encoding=None): if isinstance(value, io.IOBase): self._is_multipart = True elif isinstance(value, (bytes, bytearray, memoryview)): if filename is None and content_transfer_encoding is None: filename = name type_options = multidict.MultiDict({'name': name}) if filename is not None and not isinstance(filename, str): raise TypeError('filename must be an instance of str. ' 'Got: %s' % filename) if filename is None and isinstance(value, io.IOBase): filename = guess_filename(value, name) if filename is not None: type_options['filename'] = filename self._is_multipart = True headers = {} if content_type is not None: if not isinstance(content_type, str): raise TypeError('content_type must be an instance of str. ' 'Got: %s' % content_type) headers[hdrs.CONTENT_TYPE] = content_type self._is_multipart = True if content_transfer_encoding is not None: if not isinstance(content_transfer_encoding, str): raise TypeError('content_transfer_encoding must be an instance' ' of str. Got: %s' % content_transfer_encoding) headers[hdrs.CONTENT_TRANSFER_ENCODING] = content_transfer_encoding self._is_multipart = True self._fields.append((type_options, headers, value)) def add_fields(self, *fields): to_add = list(fields) while to_add: rec = to_add.pop(0) if isinstance(rec, io.IOBase): k = guess_filename(rec, 'unknown') self.add_field(k, rec) elif isinstance(rec, (multidict.MultiDictProxy, multidict.MultiDict)): to_add.extend(rec.items()) elif isinstance(rec, (list, tuple)) and len(rec) == 2: k, fp = rec self.add_field(k, fp) else: raise TypeError('Only io.IOBase, multidict and (name, file) ' 'pairs allowed, use .add_field() for passing ' 'more complex parameters') def _gen_form_urlencoded(self, encoding): # form data (x-www-form-urlencoded) data = [] for type_options, _, value in self._fields: data.append((type_options['name'], value)) data = urlencode(data, doseq=True) return data.encode(encoding) def _gen_form_data(self, *args, **kwargs): """Encode a list of fields using the multipart/form-data MIME format""" for dispparams, headers, value in self._fields: part = self._writer.append(value, headers) if dispparams: part.set_content_disposition('form-data', **dispparams) # FIXME cgi.FieldStorage doesn't likes body parts with # Content-Length which were sent via chunked transfer encoding part.headers.pop(hdrs.CONTENT_LENGTH, None) yield from self._writer.serialize() def __call__(self, encoding): if self._is_multipart: return self._gen_form_data(encoding) else: return self._gen_form_urlencoded(encoding) def parse_mimetype(mimetype): """Parses a MIME type into its components. :param str mimetype: MIME type :returns: 4 element tuple for MIME type, subtype, suffix and parameters :rtype: tuple Example: >>> parse_mimetype('text/html; charset=utf-8') ('text', 'html', '', {'charset': 'utf-8'}) """ if not mimetype: return '', '', '', {} parts = mimetype.split(';') params = [] 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 = dict(params) 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, '') return mtype, stype, suffix, params def str_to_bytes(s, encoding='utf-8'): if isinstance(s, str): return s.encode(encoding) return s def guess_filename(obj, default=None): name = getattr(obj, 'name', None) if name and name[0] != '<' and name[-1] != '>': return os.path.split(name)[-1] return default class AccessLogger: """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(message, environ, response, transport, 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, excluding HTTP headers %O Bytes sent, including 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 = '%a %l %u %t "%r" %s %b "%{Referrer}i" "%{User-Agent}i"' FORMAT_RE = re.compile(r'%(\{([A-Za-z\-]+)\}([ioe])|[atPrsbOD]|Tf?)') CLEANUP_RE = re.compile(r'(%[^s])') _FORMAT_CACHE = {} def __init__(self, logger, log_format=LOG_FORMAT): """Initialise the logger. :param logger: logger object to be used for logging :param log_format: apache compatible log format """ self.logger = logger _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 apropriate 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) """ log_format = log_format.replace("%l", "-") log_format = log_format.replace("%u", "-") methods = [] for atom in self.FORMAT_RE.findall(log_format): if atom[1] == '': methods.append(getattr(AccessLogger, '_format_%s' % atom[0])) else: m = getattr(AccessLogger, '_format_%s' % atom[2]) methods.append(functools.partial(m, atom[1])) 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_e(key, args): return (args[1] or {}).get(multidict.upstr(key), '-') @staticmethod def _format_i(key, args): return args[0].headers.get(multidict.upstr(key), '-') @staticmethod def _format_o(key, args): return args[2].headers.get(multidict.upstr(key), '-') @staticmethod def _format_a(args): return args[3].get_extra_info('peername')[0] @staticmethod def _format_t(args): return datetime.datetime.utcnow().strftime('[%d/%b/%Y:%H:%M:%S +0000]') @staticmethod def _format_P(args): return "<%s>" % os.getpid() @staticmethod def _format_r(args): msg = args[0] if not msg: return '-' return '%s %s HTTP/%s.%s' % tuple((msg.method, msg.path) + msg.version) @staticmethod def _format_s(args): return args[2].status @staticmethod def _format_b(args): return args[2].body_length @staticmethod def _format_O(args): return args[2].output_length @staticmethod def _format_T(args): return round(args[4]) @staticmethod def _format_Tf(args): return '%06f' % args[4] @staticmethod def _format_D(args): return round(args[4] * 1000000) def _format_line(self, args): return tuple(m(args) for m in self._methods) def log(self, message, environ, response, transport, time): """Log access. :param message: Request object. May be None. :param environ: Environment dict. May be None. :param response: Response object. :param transport: Tansport object. :param float time: Time taken to serve the request. """ try: self.logger.info(self._log_format % self._format_line( [message, environ, response, transport, time])) except Exception: self.logger.exception("Error in logging") _marker = object() class reify: """Use as a class method decorator. It operates almost exactly like the Python ``@property`` decorator, but it puts the result of the method it decorates into the instance dict after the first call, effectively replacing the function it decorates with an instance variable. It is, in Python parlance, a non-data descriptor. """ def __init__(self, wrapped): self.wrapped = wrapped try: self.__doc__ = wrapped.__doc__ except: # pragma: no cover pass self.name = wrapped.__name__ def __get__(self, inst, owner, _marker=_marker): if inst is None: return self val = inst.__dict__.get(self.name, _marker) if val is not _marker: return val val = self.wrapped(inst) inst.__dict__[self.name] = val return val def __set__(self, inst, value): raise AttributeError("reified property is read-only") # The unreserved URI characters (RFC 3986) UNRESERVED_SET = frozenset( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~") def unquote_unreserved(uri): """Un-escape any percent-escape sequences in a URI that are unreserved characters. This leaves all reserved, illegal and non-ASCII bytes encoded. """ parts = uri.split('%') for i in range(1, len(parts)): h = parts[i][0:2] if len(h) == 2 and h.isalnum(): try: c = chr(int(h, 16)) except ValueError: raise InvalidURL("Invalid percent-escape sequence: '%s'" % h) if c in UNRESERVED_SET: parts[i] = c + parts[i][2:] else: parts[i] = '%' + parts[i] else: parts[i] = '%' + parts[i] return ''.join(parts) def requote_uri(uri): """Re-quote the given URI. This function passes the given URI through an unquote/quote cycle to ensure that it is fully and consistently quoted. """ safe_with_percent = "!#$%&'()*+,/:;=?@[]~" safe_without_percent = "!#$&'()*+,/:;=?@[]~" try: # Unquote only the unreserved characters # Then quote only illegal characters (do not quote reserved, # unreserved, or '%') return quote(unquote_unreserved(uri), safe=safe_with_percent) except InvalidURL: # We couldn't unquote the given URI, so let's try quoting it, but # there may be unquoted '%'s in the URI. We need to make sure they're # properly quoted so they do not cause issues elsewhere. return quote(uri, safe=safe_without_percent) class Timeout: """Timeout context manager. Useful in cases when you want to apply timeout logic around block of code or in cases when asyncio.wait_for is not suitable. For example: >>> with aiohttp.Timeout(0.001): >>> async with aiohttp.get('https://github.com') as r: >>> await r.text() :param timeout: timeout value in seconds :param loop: asyncio compatible event loop """ def __init__(self, timeout, *, loop=None): self._timeout = timeout if loop is None: loop = asyncio.get_event_loop() self._loop = loop self._task = None self._cancelled = False self._cancel_handler = None def __enter__(self): self._task = asyncio.Task.current_task(loop=self._loop) if self._task is None: raise RuntimeError('Timeout context manager should be used ' 'inside a task') self._cancel_handler = self._loop.call_later( self._timeout, self._cancel_task) return self def __exit__(self, exc_type, exc_val, exc_tb): if exc_type is asyncio.CancelledError and self._cancelled: self._task = None raise asyncio.TimeoutError self._cancel_handler.cancel() self._task = None def _cancel_task(self): self._cancelled = self._task.cancel() aiohttp-0.20.2/aiohttp/web_reqrep.py0000664000175000017500000006560612637747134020237 0ustar andrewandrew00000000000000import asyncio import binascii import cgi import collections import datetime import http.cookies import io import json import math import time import warnings import enum from email.utils import parsedate from types import MappingProxyType from urllib.parse import urlsplit, parse_qsl, unquote from . import hdrs from .helpers import reify from .multidict import (CIMultiDictProxy, CIMultiDict, MultiDictProxy, MultiDict) from .protocol import Response as ResponseImpl, HttpVersion10, HttpVersion11 from .streams import EOF_MARKER __all__ = ( 'ContentCoding', 'Request', 'StreamResponse', 'Response', 'json_response' ) sentinel = object() class HeadersMixin: _content_type = None _content_dict = None _stored_content_type = sentinel def _parse_content_type(self, raw): self._stored_content_type = raw if raw is None: # default value according to RFC 2616 self._content_type = 'application/octet-stream' self._content_dict = {} else: self._content_type, self._content_dict = cgi.parse_header(raw) @property def content_type(self, _CONTENT_TYPE=hdrs.CONTENT_TYPE): """The value of content part for Content-Type HTTP header.""" raw = self.headers.get(_CONTENT_TYPE) if self._stored_content_type != raw: self._parse_content_type(raw) return self._content_type @property def charset(self, _CONTENT_TYPE=hdrs.CONTENT_TYPE): """The value of charset part for Content-Type HTTP header.""" raw = self.headers.get(_CONTENT_TYPE) if self._stored_content_type != raw: self._parse_content_type(raw) return self._content_dict.get('charset') @property def content_length(self, _CONTENT_LENGTH=hdrs.CONTENT_LENGTH): """The value of Content-Length HTTP header.""" l = self.headers.get(_CONTENT_LENGTH) if l is None: return None else: return int(l) FileField = collections.namedtuple('Field', 'name filename file content_type') class ContentCoding(enum.Enum): # The content codings that we have support for. # # Additional registered codings are listed at: # https://www.iana.org/assignments/http-parameters/http-parameters.xhtml#content-coding deflate = 'deflate' gzip = 'gzip' identity = 'identity' ############################################################ # HTTP Request ############################################################ class Request(dict, HeadersMixin): POST_METHODS = {hdrs.METH_PATCH, hdrs.METH_POST, hdrs.METH_PUT, hdrs.METH_TRACE, hdrs.METH_DELETE} def __init__(self, app, message, payload, transport, reader, writer, *, _HOST=hdrs.HOST, secure_proxy_ssl_header=None): self._app = app self._version = message.version self._transport = transport self._reader = reader self._writer = writer self._method = message.method self._host = message.headers.get(_HOST) self._path_qs = message.path self._post = None self._post_files_cache = None self._headers = CIMultiDictProxy(message.headers) if self._version < HttpVersion10: self._keep_alive = False else: self._keep_alive = not message.should_close # matchdict, route_name, handler # or information about traversal lookup self._match_info = None # initialized after route resolving self._payload = payload self._cookies = None self._read_bytes = None self._has_body = not payload.at_eof() self._secure_proxy_ssl_header = secure_proxy_ssl_header @reify def scheme(self): """A string representing the scheme of the request. 'http' or 'https'. """ if self._transport.get_extra_info('sslcontext'): return 'https' secure_proxy_ssl_header = self._secure_proxy_ssl_header if secure_proxy_ssl_header is not None: header, value = secure_proxy_ssl_header if self._headers.get(header) == value: return 'https' return 'http' @property def method(self): """Read only property for getting HTTP method. The value is upper-cased str like 'GET', 'POST', 'PUT' etc. """ return self._method @property def version(self): """Read only property for getting HTTP version of request. Returns aiohttp.protocol.HttpVersion instance. """ return self._version @property def host(self): """Read only property for getting *HOST* header of request. Returns str or None if HTTP request has no HOST header. """ return self._host @property def path_qs(self): """The URL including PATH_INFO and the query string. E.g, /app/blog?id=10 """ return self._path_qs @reify def _splitted_path(self): url = '{}://{}{}'.format(self.scheme, self.host, self._path_qs) return urlsplit(url) @property def raw_path(self): """ The URL including raw *PATH INFO* without the host or scheme. Warning, the path is unquoted and may contains non valid URL characters E.g., ``/my%2Fpath%7Cwith%21some%25strange%24characters`` """ return self._splitted_path.path @reify def path(self): """The URL including *PATH INFO* without the host or scheme. E.g., ``/app/blog`` """ return unquote(self.raw_path) @reify def query_string(self): """The query string in the URL. E.g., id=10 """ return self._splitted_path.query @reify def GET(self): """A multidict with all the variables in the query string. Lazy property. """ return MultiDictProxy(MultiDict(parse_qsl(self.query_string, keep_blank_values=True))) @reify def POST(self): """A multidict with all the variables in the POST parameters. post() methods has to be called before using this attribute. """ if self._post is None: raise RuntimeError("POST is not available before post()") return self._post @property def headers(self): """A case-insensitive multidict proxy with all headers.""" return self._headers @property def if_modified_since(self, _IF_MODIFIED_SINCE=hdrs.IF_MODIFIED_SINCE): """The value of If-Modified-Since HTTP header, or None. This header is represented as a `datetime` object. """ httpdate = self.headers.get(_IF_MODIFIED_SINCE) if httpdate is not None: timetuple = parsedate(httpdate) if timetuple is not None: return datetime.datetime(*timetuple[:6], tzinfo=datetime.timezone.utc) return None @property def keep_alive(self): """Is keepalive enabled by client?""" return self._keep_alive @property def match_info(self): """Result of route resolving.""" return self._match_info @property def app(self): """Application instance.""" return self._app @property def transport(self): """Transport used for request processing.""" return self._transport @property def cookies(self): """Return request cookies. A read-only dictionary-like object. """ if self._cookies is None: raw = self.headers.get(hdrs.COOKIE, '') parsed = http.cookies.SimpleCookie(raw) self._cookies = MappingProxyType( {key: val.value for key, val in parsed.items()}) return self._cookies @property def payload(self): """Return raw payload stream.""" warnings.warn('use Request.content instead', DeprecationWarning) return self._payload @property def content(self): """Return raw payload stream.""" return self._payload @property def has_body(self): """Return True if request has HTTP BODY, False otherwise.""" return self._has_body @asyncio.coroutine def release(self): """Release request. Eat unread part of HTTP BODY if present. """ chunk = yield from self._payload.readany() while chunk is not EOF_MARKER or chunk: chunk = yield from self._payload.readany() @asyncio.coroutine def read(self): """Read request body if present. Returns bytes object with full request content. """ if self._read_bytes is None: body = bytearray() while True: chunk = yield from self._payload.readany() body.extend(chunk) if chunk is EOF_MARKER: break self._read_bytes = bytes(body) return self._read_bytes @asyncio.coroutine def text(self): """Return BODY as text using encoding from .charset.""" bytes_body = yield from self.read() encoding = self.charset or 'utf-8' return bytes_body.decode(encoding) @asyncio.coroutine def json(self, *, loader=json.loads): """Return BODY as JSON.""" body = yield from self.text() return loader(body) @asyncio.coroutine def post(self): """Return POST parameters.""" if self._post is not None: return self._post if self.method not in self.POST_METHODS: self._post = MultiDictProxy(MultiDict()) return self._post content_type = self.content_type if (content_type not in ('', 'application/x-www-form-urlencoded', 'multipart/form-data')): self._post = MultiDictProxy(MultiDict()) return self._post body = yield from self.read() content_charset = self.charset or 'utf-8' environ = {'REQUEST_METHOD': self.method, 'CONTENT_LENGTH': str(len(body)), 'QUERY_STRING': '', 'CONTENT_TYPE': self.headers.get(hdrs.CONTENT_TYPE)} fs = cgi.FieldStorage(fp=io.BytesIO(body), environ=environ, keep_blank_values=True, encoding=content_charset) supported_transfer_encoding = { 'base64': binascii.a2b_base64, 'quoted-printable': binascii.a2b_qp } out = MultiDict() _count = 1 for field in fs.list or (): transfer_encoding = field.headers.get( hdrs.CONTENT_TRANSFER_ENCODING, None) if field.filename: ff = FileField(field.name, field.filename, field.file, # N.B. file closed error field.type) if self._post_files_cache is None: self._post_files_cache = {} self._post_files_cache[field.name+str(_count)] = field _count += 1 out.add(field.name, ff) else: value = field.value if transfer_encoding in supported_transfer_encoding: # binascii accepts bytes value = value.encode('utf-8') value = supported_transfer_encoding[ transfer_encoding](value) out.add(field.name, value) self._post = MultiDictProxy(out) return self._post def copy(self): raise NotImplementedError def __repr__(self): return "<{} {} {} >".format(self.__class__.__name__, self.method, self.path) ############################################################ # HTTP Response classes ############################################################ class StreamResponse(HeadersMixin): def __init__(self, *, status=200, reason=None, headers=None): self._body = None self._keep_alive = None self._chunked = False self._chunk_size = None self._compression = False self._compression_force = False self._headers = CIMultiDict() self._cookies = http.cookies.SimpleCookie() self.set_status(status, reason) self._req = None self._resp_impl = None self._eof_sent = False self._tcp_nodelay = True self._tcp_cork = False if headers is not None: self._headers.extend(headers) def _copy_cookies(self): for cookie in self._cookies.values(): value = cookie.output(header='')[1:] self.headers.add(hdrs.SET_COOKIE, value) @property def prepared(self): return self._resp_impl is not None @property def started(self): warnings.warn('use Response.prepared instead', DeprecationWarning) return self.prepared @property def status(self): return self._status @property def chunked(self): return self._chunked @property def compression(self): return self._compression @property def reason(self): return self._reason def set_status(self, status, reason=None): self._status = int(status) if reason is None: reason = ResponseImpl.calc_reason(status) self._reason = reason @property def keep_alive(self): return self._keep_alive def force_close(self): self._keep_alive = False def enable_chunked_encoding(self, chunk_size=None): """Enables automatic chunked transfer encoding.""" self._chunked = True self._chunk_size = chunk_size def enable_compression(self, force=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 self._compression = True self._compression_force = force @property def headers(self): return self._headers @property def cookies(self): return self._cookies def set_cookie(self, name, value, *, expires=None, domain=None, max_age=None, path='/', secure=None, httponly=None, version=None): """Set or update response cookie. Sets new cookie or updates existent with new value. Also updates only those params which are not None. """ old = self._cookies.get(name) if old is not None and old.coded_value == '': # deleted cookie self._cookies.pop(name, None) self._cookies[name] = value c = self._cookies[name] if expires is not None: c['expires'] = expires if domain is not None: c['domain'] = domain if max_age is not None: c['max-age'] = max_age elif 'max-age' in c: del c['max-age'] c['path'] = path if secure is not None: c['secure'] = secure if httponly is not None: c['httponly'] = httponly if version is not None: c['version'] = version def del_cookie(self, name, *, domain=None, path='/'): """Delete cookie. Creates new empty expired cookie. """ # TODO: do we need domain/path here? self._cookies.pop(name, None) self.set_cookie(name, '', max_age=0, domain=domain, path=path) @property def content_length(self): # Just a placeholder for adding setter return super().content_length @content_length.setter def content_length(self, value): if value is not None: value = int(value) # TODO: raise error if chunked enabled self.headers[hdrs.CONTENT_LENGTH] = str(value) else: self.headers.pop(hdrs.CONTENT_LENGTH, None) @property def content_type(self): # Just a placeholder for adding setter return super().content_type @content_type.setter def content_type(self, value): self.content_type # read header values if needed self._content_type = str(value) self._generate_content_type_header() @property def charset(self): # Just a placeholder for adding setter return super().charset @charset.setter def charset(self, value): 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") if value is None: self._content_dict.pop('charset', None) else: self._content_dict['charset'] = str(value).lower() self._generate_content_type_header() @property def last_modified(self, _LAST_MODIFIED=hdrs.LAST_MODIFIED): """The value of Last-Modified HTTP header, or None. This header is represented as a `datetime` object. """ httpdate = self.headers.get(_LAST_MODIFIED) if httpdate is not None: timetuple = parsedate(httpdate) if timetuple is not None: return datetime.datetime(*timetuple[:6], tzinfo=datetime.timezone.utc) return None @last_modified.setter def last_modified(self, value): if value is None: if hdrs.LAST_MODIFIED in self.headers: del self.headers[hdrs.LAST_MODIFIED] elif isinstance(value, (int, float)): 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( "%a, %d %b %Y %H:%M:%S GMT", value.utctimetuple()) elif isinstance(value, str): self.headers[hdrs.LAST_MODIFIED] = value @property def tcp_nodelay(self): return self._tcp_nodelay def set_tcp_nodelay(self, value): value = bool(value) self._tcp_nodelay = value if value: self._tcp_cork = False if self._resp_impl is None: return if value: self._resp_impl.transport.set_tcp_cork(False) self._resp_impl.transport.set_tcp_nodelay(value) @property def tcp_cork(self): return self._tcp_cork def set_tcp_cork(self, value): value = bool(value) self._tcp_cork = value if value: self._tcp_nodelay = False if self._resp_impl is None: return if value: self._resp_impl.transport.set_tcp_nodelay(False) self._resp_impl.transport.set_tcp_cork(value) def _generate_content_type_header(self, CONTENT_TYPE=hdrs.CONTENT_TYPE): params = '; '.join("%s=%s" % i for i in self._content_dict.items()) if params: ctype = self._content_type + '; ' + params else: ctype = self._content_type self.headers[CONTENT_TYPE] = ctype def _start_pre_check(self, request): if self._resp_impl is not None: if self._req is not request: raise RuntimeError( 'Response has been started with different request.') else: return self._resp_impl else: return None def _start_compression(self, request): def _start(coding): if coding != ContentCoding.identity: self.headers[hdrs.CONTENT_ENCODING] = coding.value self._resp_impl.add_compression_filter(coding.value) self.content_length = None if self._compression_force: _start(self._compression_force) else: accept_encoding = request.headers.get( hdrs.ACCEPT_ENCODING, '').lower() for coding in ContentCoding: if coding.value in accept_encoding: _start(coding) return def start(self, request): warnings.warn('use .prepare(request) instead', DeprecationWarning) resp_impl = self._start_pre_check(request) if resp_impl is not None: return resp_impl return self._start(request) @asyncio.coroutine def prepare(self, request): resp_impl = self._start_pre_check(request) if resp_impl is not None: return resp_impl yield from request.app.on_response_prepare.send(request, self) return self._start(request) def _start(self, request): self._req = request keep_alive = self._keep_alive if keep_alive is None: keep_alive = request.keep_alive self._keep_alive = keep_alive resp_impl = self._resp_impl = ResponseImpl( request._writer, self._status, request.version, not keep_alive, self._reason) self._copy_cookies() if self._compression: self._start_compression(request) if self._chunked: if request.version != HttpVersion11: raise RuntimeError("Using chunked encoding is forbidden " "for HTTP/{0.major}.{0.minor}".format( request.version)) resp_impl.enable_chunked_encoding() if self._chunk_size: resp_impl.add_chunking_filter(self._chunk_size) headers = self.headers.items() for key, val in headers: resp_impl.add_header(key, val) resp_impl.transport.set_tcp_nodelay(self._tcp_nodelay) resp_impl.transport.set_tcp_cork(self._tcp_cork) resp_impl.send_headers() return resp_impl def write(self, data): assert isinstance(data, (bytes, bytearray, memoryview)), \ 'data argument must be byte-ish (%r)' % type(data) if self._eof_sent: raise RuntimeError("Cannot call write() after write_eof()") if self._resp_impl is None: raise RuntimeError("Cannot call write() before start()") if data: return self._resp_impl.write(data) else: return () @asyncio.coroutine def drain(self): if self._resp_impl is None: raise RuntimeError("Response has not been started") yield from self._resp_impl.transport.drain() @asyncio.coroutine def write_eof(self): if self._eof_sent: return if self._resp_impl is None: raise RuntimeError("Response has not been started") yield from self._resp_impl.write_eof() self._eof_sent = True def __repr__(self): if self.started: info = "{} {} ".format(self._req.method, self._req.path) else: info = "not started" return "<{} {} {}>".format(self.__class__.__name__, self.reason, info) class Response(StreamResponse): def __init__(self, *, body=None, status=200, reason=None, text=None, headers=None, content_type=None, charset=None): super().__init__(status=status, reason=reason, headers=headers) self.set_tcp_cork(True) if body is not None and text is not None: raise ValueError("body and text are not allowed together.") if text is not None: if hdrs.CONTENT_TYPE not in self.headers: # fast path for filling headers if not isinstance(text, str): raise TypeError('text argument must be str (%r)' % type(text)) if content_type is None: content_type = 'text/plain' elif ";" in content_type: raise ValueError('charset must not be in content_type ' 'argument') charset = charset or 'utf-8' self.headers[hdrs.CONTENT_TYPE] = ( content_type + '; charset=%s' % charset) self._content_type = content_type self._content_dict = {'charset': charset} self.body = text.encode(charset) else: self.text = text if content_type or charset: raise ValueError("Passing both Content-Type header and " "content_type or charset params " "is forbidden") else: if hdrs.CONTENT_TYPE in self.headers: if content_type or charset: raise ValueError("Passing both Content-Type header and " "content_type or charset params " "is forbidden") if content_type: self.content_type = content_type if charset: self.charset = charset if body is not None: self.body = body else: self.body = None @property def body(self): return self._body @body.setter def body(self, body): if body is not None and not isinstance(body, bytes): raise TypeError('body argument must be bytes (%r)' % type(body)) self._body = body if body is not None: self.content_length = len(body) else: self.content_length = 0 @property def text(self): if self._body is None: return None return self._body.decode(self.charset or 'utf-8') @text.setter def text(self, text): if text is not None and not isinstance(text, str): raise TypeError('text argument must be str (%r)' % type(text)) if self.content_type == 'application/octet-stream': self.content_type = 'text/plain' if self.charset is None: self.charset = 'utf-8' self.body = text.encode(self.charset) @asyncio.coroutine def write_eof(self): try: body = self._body if body is not None: self.write(body) finally: self.set_tcp_nodelay(True) yield from super().write_eof() def json_response(data=sentinel, *, text=None, body=None, status=200, reason=None, headers=None, content_type='application/json', dumps=json.dumps): if data is not sentinel: if text or body: raise ValueError( 'only one of data, text, or body should be specified' ) else: text = dumps(data) return Response(text=text, body=body, status=status, reason=reason, headers=headers, content_type=content_type) aiohttp-0.20.2/aiohttp/multidict.py0000664000175000017500000002501312621672701020054 0ustar andrewandrew00000000000000"""Multidict implementation. HTTP Headers and URL query string require specific data structure: multidict. It behaves mostly like a dict but it can have several values for the same key. """ from collections import abc import os import sys __all__ = ('MultiDictProxy', 'CIMultiDictProxy', 'MultiDict', 'CIMultiDict', 'upstr') _marker = object() class _upstr(str): """Case insensitive str.""" def __new__(cls, val='', encoding=sys.getdefaultencoding(), errors='strict'): if isinstance(val, (bytes, bytearray, memoryview)): val = str(val, encoding, errors) elif isinstance(val, str): pass else: val = str(val) val = val.upper() return str.__new__(cls, val) def upper(self): return self class _Base: def getall(self, key, default=_marker): """Return a list of all values matching the key.""" res = [v for k, v in self._items if k == key] if res: return res if not res and default is not _marker: return default raise KeyError('Key not found: %r' % key) def getone(self, key, default=_marker): """Get first value matching the key.""" for k, v in self._items: if k == key: return v if default is not _marker: return default raise KeyError('Key not found: %r' % key) # Mapping interface # def __getitem__(self, key): return self.getone(key, _marker) def get(self, key, default=None): """Get first value matching the key. The method is alias for .getone(). """ return self.getone(key, default) def __iter__(self): return iter(self.keys()) def __len__(self): return len(self._items) def keys(self): """Return a new view of the dictionary's keys.""" return _KeysView(self._items) def items(self): """Return a new view of the dictionary's items *(key, value) pairs).""" return _ItemsView(self._items) def values(self): """Return a new view of the dictionary's values.""" return _ValuesView(self._items) def __eq__(self, other): if not isinstance(other, abc.Mapping): return NotImplemented if isinstance(other, _Base): return self._items == other._items for k, v in self.items(): nv = other.get(k, _marker) if v != nv: return False return True def __contains__(self, key): for k, v in self._items: if k == key: return True return False def __repr__(self): body = ', '.join("'{}': {!r}".format(k, v) for k, v in self.items()) return '<{}({})>'.format(self.__class__.__name__, body) class _CIBase(_Base): def getall(self, key, default=_marker): """Return a list of all values matching the key.""" return super().getall(key.upper(), default) def getone(self, key, default=_marker): """Get first value matching the key.""" return super().getone(key.upper(), default) def get(self, key, default=None): """Get first value matching the key. The method is alias for .getone(). """ return super().get(key.upper(), default) def __getitem__(self, key): return super().__getitem__(key.upper()) def __contains__(self, key): return super().__contains__(key.upper()) class _MultiDictProxy(_Base, abc.Mapping): def __init__(self, arg): if not isinstance(arg, _MultiDict): raise TypeError( 'MultiDictProxy requires MultiDict instance, not {}'.format( type(arg))) self._items = arg._items def copy(self): """Return a copy of itself.""" return _MultiDict(self.items()) class _CIMultiDictProxy(_CIBase, _MultiDictProxy): def __init__(self, arg): if not isinstance(arg, _CIMultiDict): raise TypeError( 'CIMultiDictProxy requires CIMultiDict instance, not {}' .format(type(arg))) self._items = arg._items def copy(self): """Return a copy of itself.""" return _CIMultiDict(self.items()) class _MultiDict(_Base, abc.MutableMapping): def __init__(self, *args, **kwargs): self._items = [] self._extend(args, kwargs, self.__class__.__name__, self.add) def add(self, key, value): """Add the key and value, not overwriting any previous value.""" self._items.append((key, value)) def copy(self): """Return a copy of itself.""" cls = self.__class__ return cls(self.items()) def extend(self, *args, **kwargs): """Extend current MultiDict with more values. This method must be used instead of update. """ self._extend(args, kwargs, 'extend', self.add) def _extend(self, args, kwargs, name, method): if len(args) > 1: raise TypeError("{} takes at most 1 positional argument" " ({} given)".format(name, len(args))) if args: arg = args[0] if isinstance(args[0], _MultiDictProxy): items = arg._items elif isinstance(args[0], _MultiDict): items = arg._items elif hasattr(arg, 'items'): items = arg.items() else: for item in arg: if not len(item) == 2: raise TypeError( "{} takes either dict or list of (key, value) " "tuples".format(name)) items = arg for key, value in items: method(key, value) for key, value in kwargs.items(): method(key, value) def clear(self): """Remove all items from MultiDict.""" self._items.clear() # Mapping interface # def __setitem__(self, key, value): self._replace(key, value) def __delitem__(self, key): items = self._items found = False for i in range(len(items) - 1, -1, -1): if items[i][0] == key: del items[i] found = True if not found: raise KeyError(key) def setdefault(self, key, default=None): """Return value for key, set value to default if key is not present.""" for k, v in self._items: if k == key: return v self._items.append((key, default)) return default def pop(self, key, default=_marker): """Remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised. """ value = None found = False for i in range(len(self._items) - 1, -1, -1): if self._items[i][0] == key: value = self._items[i][1] del self._items[i] found = True if not found: if default is _marker: raise KeyError(key) else: return default else: return value def popitem(self): """Remove and return an arbitrary (key, value) pair.""" if self._items: return self._items.pop(0) else: raise KeyError("empty multidict") def update(self, *args, **kwargs): """Update the dictionary from *other*, overwriting existing keys.""" self._extend(args, kwargs, 'update', self._replace) def _replace(self, key, value): if key in self: del self[key] self.add(key, value) class _CIMultiDict(_CIBase, _MultiDict): def add(self, key, value): """Add the key and value, not overwriting any previous value.""" super().add(key.upper(), value) def __setitem__(self, key, value): super().__setitem__(key.upper(), value) def __delitem__(self, key): super().__delitem__(key.upper()) def _replace(self, key, value): super()._replace(key.upper(), value) def setdefault(self, key, default=None): """Return value for key, set value to default if key is not present.""" key = key.upper() return super().setdefault(key, default) class _ViewBase: def __init__(self, items): self._items = items def __len__(self): return len(self._items) class _ItemsView(_ViewBase, abc.ItemsView): def __contains__(self, item): assert isinstance(item, tuple) or isinstance(item, list) assert len(item) == 2 return item in self._items def __iter__(self): yield from self._items def __repr__(self): lst = [] for item in self._items: lst.append("{!r}: {!r}".format(item[0], item[1])) body = ', '.join(lst) return '{}({})'.format(self.__class__.__name__, body) class _ValuesView(_ViewBase, abc.ValuesView): def __contains__(self, value): for item in self._items: if item[1] == value: return True return False def __iter__(self): for item in self._items: yield item[1] def __repr__(self): lst = [] for item in self._items: lst.append("{!r}".format(item[1])) body = ', '.join(lst) return '{}({})'.format(self.__class__.__name__, body) class _KeysView(_ViewBase, abc.KeysView): def __contains__(self, key): for item in self._items: if item[0] == key: return True return False def __iter__(self): for item in self._items: yield item[0] def __repr__(self): lst = [] for item in self._items: lst.append("{!r}".format(item[0])) body = ', '.join(lst) return '{}({})'.format(self.__class__.__name__, body) if bool(os.environ.get('AIOHTTP_NO_EXTENSIONS')): MultiDictProxy = _MultiDictProxy CIMultiDictProxy = _CIMultiDictProxy MultiDict = _MultiDict CIMultiDict = _CIMultiDict upstr = _upstr else: try: from ._multidict import (MultiDictProxy, CIMultiDictProxy, MultiDict, CIMultiDict, upstr) except ImportError: # pragma: no cover MultiDictProxy = _MultiDictProxy CIMultiDictProxy = _CIMultiDictProxy MultiDict = _MultiDict CIMultiDict = _CIMultiDict upstr = _upstr aiohttp-0.20.2/aiohttp/web.py0000664000175000017500000002003412643552137016635 0ustar andrewandrew00000000000000from . import web_reqrep from . import web_exceptions from . import web_urldispatcher from . import web_ws from .web_reqrep import * # noqa from .web_exceptions import * # noqa from .web_urldispatcher import * # noqa from .web_ws import * # noqa from .protocol import HttpVersion # noqa from .signals import Signal, PreSignal, PostSignal import asyncio from . import hdrs from .abc import AbstractRouter, AbstractMatchInfo from .log import web_logger from .server import ServerHttpProtocol __all__ = (web_reqrep.__all__ + web_exceptions.__all__ + web_urldispatcher.__all__ + web_ws.__all__ + ('Application', 'RequestHandler', 'RequestHandlerFactory', 'HttpVersion')) class RequestHandler(ServerHttpProtocol): _meth = 'none' _path = 'none' def __init__(self, manager, app, router, *, secure_proxy_ssl_header=None, **kwargs): super().__init__(**kwargs) self._manager = manager self._app = app self._router = router self._middlewares = app.middlewares self._secure_proxy_ssl_header = secure_proxy_ssl_header def __repr__(self): return "<{} {}:{} {}>".format( self.__class__.__name__, self._meth, self._path, 'connected' if self.transport is not None else 'disconnected') def connection_made(self, transport): super().connection_made(transport) self._manager.connection_made(self, transport) def connection_lost(self, exc): self._manager.connection_lost(self, exc) super().connection_lost(exc) @asyncio.coroutine def handle_request(self, message, payload): if self.access_log: now = self._loop.time() app = self._app request = Request( app, message, payload, self.transport, self.reader, self.writer, secure_proxy_ssl_header=self._secure_proxy_ssl_header) self._meth = request.method self._path = request.path try: match_info = yield from self._router.resolve(request) assert isinstance(match_info, AbstractMatchInfo), match_info resp = None request._match_info = match_info expect = request.headers.get(hdrs.EXPECT) if expect and expect.lower() == "100-continue": resp = ( yield from match_info.route.handle_expect_header(request)) if resp is None: handler = match_info.handler for factory in reversed(self._middlewares): handler = yield from factory(app, handler) resp = yield from handler(request) assert isinstance(resp, StreamResponse), \ ("Handler {!r} should return response instance, " "got {!r} [middlewares {!r}]").format( match_info.handler, type(resp), self._middlewares) except HTTPException as exc: resp = exc resp_msg = yield from resp.prepare(request) yield from resp.write_eof() # notify server about keep-alive self.keep_alive(resp_msg.keep_alive()) # log access if self.access_log: self.log_access(message, None, resp_msg, self._loop.time() - now) # for repr self._meth = 'none' self._path = 'none' class RequestHandlerFactory: def __init__(self, app, router, *, handler=RequestHandler, loop=None, secure_proxy_ssl_header=None, **kwargs): self._app = app self._router = router self._handler = handler self._loop = loop self._connections = {} self._secure_proxy_ssl_header = secure_proxy_ssl_header self._kwargs = kwargs self._kwargs.setdefault('logger', app.logger) self.num_connections = 0 @property def secure_proxy_ssl_header(self): return self._secure_proxy_ssl_header @property def connections(self): return list(self._connections.keys()) def connection_made(self, handler, transport): self._connections[handler] = transport def connection_lost(self, handler, exc=None): if handler in self._connections: del self._connections[handler] @asyncio.coroutine def finish_connections(self, timeout=None): # try to close connections in 90% of graceful timeout timeout90 = None if timeout: timeout90 = timeout / 100 * 90 for handler in self._connections.keys(): handler.closing(timeout=timeout90) @asyncio.coroutine def cleanup(): sleep = 0.05 while self._connections: yield from asyncio.sleep(sleep, loop=self._loop) if sleep < 5: sleep = sleep * 2 if timeout: try: yield from asyncio.wait_for( cleanup(), timeout, loop=self._loop) except asyncio.TimeoutError: self._app.logger.warning( "Not all connections are closed (pending: %d)", len(self._connections)) for transport in self._connections.values(): transport.close() self._connections.clear() def __call__(self): self.num_connections += 1 try: return self._handler( self, self._app, self._router, loop=self._loop, secure_proxy_ssl_header=self._secure_proxy_ssl_header, **self._kwargs) except: web_logger.exception( 'Can not create request handler: {!r}'.format(self._handler)) class Application(dict): def __init__(self, *, logger=web_logger, loop=None, router=None, handler_factory=RequestHandlerFactory, middlewares=(), debug=False): if loop is None: loop = asyncio.get_event_loop() if router is None: router = UrlDispatcher() assert isinstance(router, AbstractRouter), router self._debug = debug self._router = router self._handler_factory = handler_factory self._finish_callbacks = [] self._loop = loop self.logger = logger for factory in middlewares: assert asyncio.iscoroutinefunction(factory), factory self._middlewares = list(middlewares) self._on_pre_signal = PreSignal() self._on_post_signal = PostSignal() self._on_response_prepare = Signal(self) @property def debug(self): return self._debug @property def on_response_prepare(self): return self._on_response_prepare @property def on_pre_signal(self): return self._on_pre_signal @property def on_post_signal(self): return self._on_post_signal @property def router(self): return self._router @property def loop(self): return self._loop @property def middlewares(self): return self._middlewares def make_handler(self, **kwargs): return self._handler_factory( self, self.router, loop=self.loop, **kwargs) @asyncio.coroutine def finish(self): callbacks = self._finish_callbacks self._finish_callbacks = [] for (cb, args, kwargs) in callbacks: try: res = cb(self, *args, **kwargs) if (asyncio.iscoroutine(res) or isinstance(res, asyncio.Future)): yield from res except Exception as exc: self._loop.call_exception_handler({ 'message': "Error in finish callback", 'exception': exc, 'application': self, }) def register_on_finish(self, func, *args, **kwargs): self._finish_callbacks.insert(0, (func, args, kwargs)) def copy(self): raise NotImplementedError def __call__(self): """gunicorn compatibility""" return self def __repr__(self): return "" aiohttp-0.20.2/aiohttp/hdrs.py0000664000175000017500000000632112637063114017016 0ustar andrewandrew00000000000000"""HTTP Headers constants.""" from .multidict import upstr METH_ANY = upstr('*') METH_CONNECT = upstr('CONNECT') METH_HEAD = upstr('HEAD') METH_GET = upstr('GET') METH_DELETE = upstr('DELETE') METH_OPTIONS = upstr('OPTIONS') METH_PATCH = upstr('PATCH') METH_POST = upstr('POST') METH_PUT = upstr('PUT') METH_TRACE = upstr('TRACE') METH_ALL = {METH_CONNECT, METH_HEAD, METH_GET, METH_DELETE, METH_OPTIONS, METH_PATCH, METH_POST, METH_PUT, METH_TRACE} ACCEPT = upstr('ACCEPT') ACCEPT_CHARSET = upstr('ACCEPT-CHARSET') ACCEPT_ENCODING = upstr('ACCEPT-ENCODING') ACCEPT_LANGUAGE = upstr('ACCEPT-LANGUAGE') ACCEPT_RANGES = upstr('ACCEPT-RANGES') ACCESS_CONTROL_MAX_AGE = upstr('ACCESS-CONTROL-MAX-AGE') ACCESS_CONTROL_ALLOW_CREDENTIALS = upstr('ACCESS-CONTROL-ALLOW-CREDENTIALS') ACCESS_CONTROL_ALLOW_HEADERS = upstr('ACCESS-CONTROL-ALLOW-HEADERS') ACCESS_CONTROL_ALLOW_METHODS = upstr('ACCESS-CONTROL-ALLOW-METHODS') ACCESS_CONTROL_ALLOW_ORIGIN = upstr('ACCESS-CONTROL-ALLOW-ORIGIN') ACCESS_CONTROL_EXPOSE_HEADERS = upstr('ACCESS-CONTROL-EXPOSE-HEADERS') ACCESS_CONTROL_REQUEST_HEADERS = upstr('ACCESS-CONTROL-REQUEST-HEADERS') ACCESS_CONTROL_REQUEST_METHOD = upstr('ACCESS-CONTROL-REQUEST-METHOD') AGE = upstr('AGE') ALLOW = upstr('ALLOW') AUTHORIZATION = upstr('AUTHORIZATION') CACHE_CONTROL = upstr('CACHE-CONTROL') CONNECTION = upstr('CONNECTION') CONTENT_DISPOSITION = upstr('CONTENT-DISPOSITION') CONTENT_ENCODING = upstr('CONTENT-ENCODING') CONTENT_LANGUAGE = upstr('CONTENT-LANGUAGE') CONTENT_LENGTH = upstr('CONTENT-LENGTH') CONTENT_LOCATION = upstr('CONTENT-LOCATION') CONTENT_MD5 = upstr('CONTENT-MD5') CONTENT_RANGE = upstr('CONTENT-RANGE') CONTENT_TRANSFER_ENCODING = upstr('CONTENT-TRANSFER-ENCODING') CONTENT_TYPE = upstr('CONTENT-TYPE') COOKIE = upstr('COOKIE') DATE = upstr('DATE') DESTINATION = upstr('DESTINATION') DIGEST = upstr('DIGEST') ETAG = upstr('ETAG') EXPECT = upstr('EXPECT') EXPIRES = upstr('EXPIRES') FROM = upstr('FROM') HOST = upstr('HOST') IF_MATCH = upstr('IF-MATCH') IF_MODIFIED_SINCE = upstr('IF-MODIFIED-SINCE') IF_NONE_MATCH = upstr('IF-NONE-MATCH') IF_RANGE = upstr('IF-RANGE') IF_UNMODIFIED_SINCE = upstr('IF-UNMODIFIED-SINCE') KEEP_ALIVE = upstr('KEEP-ALIVE') LAST_EVENT_ID = upstr('LAST-EVENT-ID') LAST_MODIFIED = upstr('LAST-MODIFIED') LINK = upstr('LINK') LOCATION = upstr('LOCATION') MAX_FORWARDS = upstr('MAX-FORWARDS') ORIGIN = upstr('ORIGIN') PRAGMA = upstr('PRAGMA') PROXY_AUTHENTICATE = upstr('PROXY_AUTHENTICATE') PROXY_AUTHORIZATION = upstr('PROXY-AUTHORIZATION') RANGE = upstr('RANGE') REFERER = upstr('REFERER') RETRY_AFTER = upstr('RETRY-AFTER') SEC_WEBSOCKET_ACCEPT = upstr('SEC-WEBSOCKET-ACCEPT') SEC_WEBSOCKET_VERSION = upstr('SEC-WEBSOCKET-VERSION') SEC_WEBSOCKET_PROTOCOL = upstr('SEC-WEBSOCKET-PROTOCOL') SEC_WEBSOCKET_KEY = upstr('SEC-WEBSOCKET-KEY') SEC_WEBSOCKET_KEY1 = upstr('SEC-WEBSOCKET-KEY1') SERVER = upstr('SERVER') SET_COOKIE = upstr('SET-COOKIE') TE = upstr('TE') TRAILER = upstr('TRAILER') TRANSFER_ENCODING = upstr('TRANSFER-ENCODING') UPGRADE = upstr('UPGRADE') WEBSOCKET = upstr('WEBSOCKET') URI = upstr('URI') USER_AGENT = upstr('USER-AGENT') VARY = upstr('VARY') VIA = upstr('VIA') WANT_DIGEST = upstr('WANT-DIGEST') WARNING = upstr('WARNING') WWW_AUTHENTICATE = upstr('WWW-AUTHENTICATE') aiohttp-0.20.2/aiohttp/worker.py0000664000175000017500000001017112643552137017372 0ustar andrewandrew00000000000000"""Async gunicorn worker for aiohttp.web""" import asyncio import logging import os import signal import sys import gunicorn.workers.base as base from aiohttp.helpers import ensure_future __all__ = ('GunicornWebWorker',) class GunicornWebWorker(base.Worker): def __init__(self, *args, **kw): # pragma: no cover super().__init__(*args, **kw) self.servers = {} self.exit_code = 0 def init_process(self): # create new event_loop after fork asyncio.get_event_loop().close() self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) super().init_process() def run(self): self._runner = ensure_future(self._run(), loop=self.loop) try: self.loop.run_until_complete(self._runner) finally: self.loop.close() sys.exit(self.exit_code) def make_handler(self, app, host, port): if hasattr(self.cfg, 'debug'): is_debug = self.cfg.debug else: is_debug = self.log.loglevel == logging.DEBUG return app.make_handler( host=host, port=port, logger=self.log, debug=is_debug, timeout=self.cfg.timeout, keep_alive=self.cfg.keepalive, access_log=self.log.access_log, access_log_format=self.cfg.access_log_format) @asyncio.coroutine def close(self): if self.servers: servers = self.servers self.servers = None # stop accepting connections for server, handler in servers.items(): self.log.info("Stopping server: %s, connections: %s", self.pid, len(handler.connections)) server.close() # stop alive connections tasks = [ handler.finish_connections( timeout=self.cfg.graceful_timeout / 100 * 95) for handler in servers.values()] yield from asyncio.wait(tasks, loop=self.loop) # stop application yield from self.wsgi.finish() @asyncio.coroutine def _run(self): for sock in self.sockets: handler = self.make_handler(self.wsgi, *sock.cfg_addr) srv = yield from self.loop.create_server(handler, sock=sock.sock) self.servers[srv] = handler # If our parent changed then we shut down. pid = os.getpid() try: while self.alive: self.notify() if pid == os.getpid() and self.ppid != os.getppid(): self.alive = False self.log.info("Parent changed, shutting down: %s", self) else: yield from asyncio.sleep(1.0, loop=self.loop) if self.cfg.max_requests and self.servers: connections = 0 for _, handler in self.servers.items(): connections += handler.num_connections if connections > self.cfg.max_requests: self.alive = False self.log.info("Max requests, shutting down: %s", self) except (Exception, BaseException, GeneratorExit, KeyboardInterrupt): pass yield from self.close() def init_signal(self): # init new signaling self.loop.add_signal_handler(signal.SIGQUIT, self.handle_quit) self.loop.add_signal_handler(signal.SIGTERM, self.handle_exit) self.loop.add_signal_handler(signal.SIGINT, self.handle_quit) self.loop.add_signal_handler(signal.SIGWINCH, self.handle_winch) self.loop.add_signal_handler(signal.SIGUSR1, self.handle_usr1) self.loop.add_signal_handler(signal.SIGABRT, self.handle_abort) # Don't let SIGTERM and SIGUSR1 disturb active requests # by interrupting system calls signal.siginterrupt(signal.SIGTERM, False) signal.siginterrupt(signal.SIGUSR1, False) def handle_quit(self, sig, frame): self.alive = False def handle_abort(self, sig, frame): self.alive = False self.exit_code = 1 aiohttp-0.20.2/aiohttp/_websocket.pyx0000664000175000017500000000257612635103355020403 0ustar andrewandrew00000000000000from cpython cimport PyBytes_AsString #from cpython cimport PyByteArray_AsString # cython still not exports that cdef extern from "Python.h": char* PyByteArray_AsString(bytearray ba) except NULL from libc.stdint cimport uint32_t, uint64_t, uintmax_t def _websocket_mask_cython(bytes mask, bytearray data): """Note, this function mutates it's `data` argument """ cdef: Py_ssize_t data_len, i # bit operations on signed integers are implementation-specific unsigned char * in_buf const unsigned char * mask_buf uint32_t uint32_msk uint64_t uint64_msk assert len(mask) == 4 data_len = len(data) in_buf = PyByteArray_AsString(data) mask_buf = PyBytes_AsString(mask) uint32_msk = (mask_buf)[0] # TODO: align in_data ptr to achieve even faster speeds # does it need in python ?! malloc() always aligns to sizeof(long) bytes if sizeof(size_t) >= 8: uint64_msk = uint32_msk uint64_msk = (uint64_msk << 32) | uint32_msk while data_len >= 8: (in_buf)[0] ^= uint64_msk in_buf += 8 data_len -= 8 while data_len >= 4: (in_buf)[0] ^= uint32_msk in_buf += 4 data_len -= 4 for i in range(0, data_len): in_buf[i] ^= mask_buf[i] return data aiohttp-0.20.2/setup.cfg0000664000175000017500000000020112643555674015662 0ustar andrewandrew00000000000000[easy_install] zip_ok = false [flake8] ignore = N801,N802,N803,E226 [egg_info] tag_date = 0 tag_svn_revision = 0 tag_build = aiohttp-0.20.2/tests/0000775000175000017500000000000012643555674015212 5ustar andrewandrew00000000000000aiohttp-0.20.2/tests/test_client_response.py0000664000175000017500000002367312633254767022030 0ustar andrewandrew00000000000000# -*- coding: utf-8 -*- """Tests for aiohttp/client.py""" import asyncio import gc import unittest import unittest.mock import aiohttp from aiohttp.client_reqrep import ClientResponse class TestClientResponse(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) self.connection = unittest.mock.Mock() self.stream = aiohttp.StreamParser(loop=self.loop) self.response = ClientResponse('get', 'http://def-cl-resp.org') self.response._post_init(self.loop) self.response._setup_connection(self.connection) def tearDown(self): self.response.close() self.loop.close() gc.collect() def test_del(self): response = ClientResponse('get', 'http://del-cl-resp.org') response._post_init(self.loop) connection = unittest.mock.Mock() response._setup_connection(connection) self.loop.set_exception_handler(lambda loop, ctx: None) with self.assertWarns(ResourceWarning): del response gc.collect() connection.close.assert_called_with() def test_close(self): self.response._connection = self.connection self.response.close() self.assertIsNone(self.response.connection) self.response.close() self.response.close() def test_wait_for_100_1(self): response = ClientResponse( 'get', 'http://python.org', continue100=object()) response._post_init(self.loop) self.assertTrue(response.waiting_for_continue()) response.close() def test_wait_for_100_2(self): response = ClientResponse( 'get', 'http://python.org') response._post_init(self.loop) self.assertFalse(response.waiting_for_continue()) response.close() def test_repr(self): self.response.status = 200 self.response.reason = 'Ok' self.assertIn( '', repr(self.response)) def test_read_and_release_connection(self): def side_effect(*args, **kwargs): fut = asyncio.Future(loop=self.loop) fut.set_result(b'payload') return fut content = self.response.content = unittest.mock.Mock() content.read.side_effect = side_effect res = self.loop.run_until_complete(self.response.read()) self.assertEqual(res, b'payload') self.assertIsNone(self.response._connection) def test_read_and_release_connection_with_error(self): content = self.response.content = unittest.mock.Mock() content.read.return_value = asyncio.Future(loop=self.loop) content.read.return_value.set_exception(ValueError) self.assertRaises( ValueError, self.loop.run_until_complete, self.response.read()) self.assertTrue(self.response._closed) def test_release(self): fut = asyncio.Future(loop=self.loop) fut.set_result(b'') content = self.response.content = unittest.mock.Mock() content.readany.return_value = fut self.loop.run_until_complete(self.response.release()) self.assertIsNone(self.response._connection) def test_read_decode_deprecated(self): self.response._content = b'data' self.response.json = unittest.mock.Mock() self.response.json.return_value = asyncio.Future(loop=self.loop) self.response.json.return_value.set_result('json') with self.assertWarns(DeprecationWarning): res = self.loop.run_until_complete(self.response.read(decode=True)) self.assertEqual(res, 'json') self.assertTrue(self.response.json.called) def test_text(self): def side_effect(*args, **kwargs): fut = asyncio.Future(loop=self.loop) fut.set_result('{"теÑÑ‚": "пройден"}'.encode('cp1251')) return fut self.response.headers = { 'CONTENT-TYPE': 'application/json;charset=cp1251'} content = self.response.content = unittest.mock.Mock() content.read.side_effect = side_effect res = self.loop.run_until_complete(self.response.text()) self.assertEqual(res, '{"теÑÑ‚": "пройден"}') self.assertIsNone(self.response._connection) def test_text_custom_encoding(self): def side_effect(*args, **kwargs): fut = asyncio.Future(loop=self.loop) fut.set_result('{"теÑÑ‚": "пройден"}'.encode('cp1251')) return fut self.response.headers = { 'CONTENT-TYPE': 'application/json'} content = self.response.content = unittest.mock.Mock() content.read.side_effect = side_effect self.response._get_encoding = unittest.mock.Mock() res = self.loop.run_until_complete( self.response.text(encoding='cp1251')) self.assertEqual(res, '{"теÑÑ‚": "пройден"}') self.assertIsNone(self.response._connection) self.assertFalse(self.response._get_encoding.called) def test_text_detect_encoding(self): def side_effect(*args, **kwargs): fut = asyncio.Future(loop=self.loop) fut.set_result('{"теÑÑ‚": "пройден"}'.encode('cp1251')) return fut self.response.headers = {'CONTENT-TYPE': 'application/json'} content = self.response.content = unittest.mock.Mock() content.read.side_effect = side_effect self.loop.run_until_complete(self.response.read()) res = self.loop.run_until_complete(self.response.text()) self.assertEqual(res, '{"теÑÑ‚": "пройден"}') self.assertIsNone(self.response._connection) def test_text_after_read(self): def side_effect(*args, **kwargs): fut = asyncio.Future(loop=self.loop) fut.set_result('{"теÑÑ‚": "пройден"}'.encode('cp1251')) return fut self.response.headers = { 'CONTENT-TYPE': 'application/json;charset=cp1251'} content = self.response.content = unittest.mock.Mock() content.read.side_effect = side_effect res = self.loop.run_until_complete(self.response.text()) self.assertEqual(res, '{"теÑÑ‚": "пройден"}') self.assertIsNone(self.response._connection) def test_json(self): def side_effect(*args, **kwargs): fut = asyncio.Future(loop=self.loop) fut.set_result('{"теÑÑ‚": "пройден"}'.encode('cp1251')) return fut self.response.headers = { 'CONTENT-TYPE': 'application/json;charset=cp1251'} content = self.response.content = unittest.mock.Mock() content.read.side_effect = side_effect res = self.loop.run_until_complete(self.response.json()) self.assertEqual(res, {'теÑÑ‚': 'пройден'}) self.assertIsNone(self.response._connection) def test_json_custom_loader(self): self.response.headers = { 'CONTENT-TYPE': 'application/json;charset=cp1251'} self.response._content = b'data' def custom(content): return content + '-custom' res = self.loop.run_until_complete(self.response.json(loads=custom)) self.assertEqual(res, 'data-custom') @unittest.mock.patch('aiohttp.client_reqrep.client_logger') def test_json_no_content(self, m_log): self.response.headers = { 'CONTENT-TYPE': 'data/octet-stream'} self.response._content = b'' res = self.loop.run_until_complete(self.response.json()) self.assertIsNone(res) m_log.warning.assert_called_with( 'Attempt to decode JSON with unexpected mimetype: %s', 'data/octet-stream') def test_json_override_encoding(self): def side_effect(*args, **kwargs): fut = asyncio.Future(loop=self.loop) fut.set_result('{"теÑÑ‚": "пройден"}'.encode('cp1251')) return fut self.response.headers = { 'CONTENT-TYPE': 'application/json;charset=utf8'} content = self.response.content = unittest.mock.Mock() content.read.side_effect = side_effect self.response._get_encoding = unittest.mock.Mock() res = self.loop.run_until_complete( self.response.json(encoding='cp1251')) self.assertEqual(res, {'теÑÑ‚': 'пройден'}) self.assertIsNone(self.response._connection) self.assertFalse(self.response._get_encoding.called) def test_json_detect_encoding(self): def side_effect(*args, **kwargs): fut = asyncio.Future(loop=self.loop) fut.set_result('{"теÑÑ‚": "пройден"}'.encode('cp1251')) return fut self.response.headers = {'CONTENT-TYPE': 'application/json'} content = self.response.content = unittest.mock.Mock() content.read.side_effect = side_effect res = self.loop.run_until_complete(self.response.json()) self.assertEqual(res, {'теÑÑ‚': 'пройден'}) self.assertIsNone(self.response._connection) def test_override_flow_control(self): class MyResponse(ClientResponse): flow_control_class = aiohttp.FlowControlDataQueue response = MyResponse('get', 'http://my-cl-resp.org') response._post_init(self.loop) response._setup_connection(self.connection) self.assertIsInstance(response.content, aiohttp.FlowControlDataQueue) response.close() @unittest.mock.patch('aiohttp.client_reqrep.chardet') def test_get_encoding_unknown(self, m_chardet): m_chardet.detect.return_value = {'encoding': None} self.response.headers = {'CONTENT-TYPE': 'application/json'} self.assertEqual(self.response._get_encoding(), 'utf-8') def test_close_deprecated(self): self.response._connection = self.connection with self.assertWarns(DeprecationWarning): self.response.close(force=False) self.assertIsNone(self.response._connection) aiohttp-0.20.2/tests/test_client_session.py0000664000175000017500000003073112634604626021640 0ustar andrewandrew00000000000000import asyncio import contextlib import gc import re import types from unittest import mock import aiohttp import pytest from aiohttp.client import ClientSession from aiohttp.connector import BaseConnector, TCPConnector from aiohttp.multidict import CIMultiDict, MultiDict @pytest.fixture def connector(loop): conn = BaseConnector(loop=loop) transp = mock.Mock() conn._conns['a'] = [(transp, 'proto', 123)] return conn @pytest.yield_fixture def create_session(loop): session = None def maker(*args, **kwargs): nonlocal session session = ClientSession(*args, loop=loop, **kwargs) return session yield maker if session is not None: session.close() @pytest.fixture def session(create_session): return create_session() @pytest.fixture def params(): return dict( headers={"Authorization": "Basic ..."}, max_redirects=2, encoding="latin1", version=aiohttp.HttpVersion10, compress="deflate", chunked=True, expect100=True, read_until_eof=False) def test_init_headers_simple_dict(create_session): session = 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")]) 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")])) 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")]) 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"}) assert set(session.cookies) == {'c1', 'c2'} assert session.cookies['c1'].value == 'cookie1' assert session.cookies['c2'].value == 'cookie2' def test_init_cookies_with_list_of_tuples(create_session): session = create_session(cookies=[("c1", "cookie1"), ("c2", "cookie2")]) assert set(session.cookies) == {'c1', 'c2'} assert session.cookies['c1'].value == 'cookie1' assert session.cookies['c2'].value == 'cookie2' def test_merge_headers(create_session): # Check incoming simple dict session = create_session(headers={"h1": "header1", "h2": "header2"}) headers = session._prepare_headers({"h1": "h1"}) assert isinstance(headers, CIMultiDict) assert headers == CIMultiDict([("h2", "header2"), ("h1", "h1")]) def test_merge_headers_with_multi_dict(create_session): session = create_session(headers={"h1": "header1", "h2": "header2"}) headers = session._prepare_headers(MultiDict([("h1", "h1")])) assert isinstance(headers, CIMultiDict) assert headers == CIMultiDict([("h2", "header2"), ("h1", "h1")]) def test_merge_headers_with_list_of_tuples(create_session): session = create_session(headers={"h1": "header1", "h2": "header2"}) headers = session._prepare_headers([("h1", "h1")]) assert isinstance(headers, CIMultiDict) assert headers == CIMultiDict([("h2", "header2"), ("h1", "h1")]) def test_merge_headers_with_list_of_tuples_duplicated_names(create_session): session = create_session(headers={"h1": "header1", "h2": "header2"}) headers = session._prepare_headers([("h1", "v1"), ("h1", "v2")]) assert isinstance(headers, CIMultiDict) assert headers == CIMultiDict([("H2", "header2"), ("H1", "v1"), ("H1", "v2")]) def test_http_GET(session, params): with mock.patch("aiohttp.client.ClientSession._request") as patched: session.get("http://test.example.com", params={"x": 1}, **params) assert patched.called, "`ClientSession._request` not called" assert list(patched.call_args) == [("GET", "http://test.example.com",), dict( params={"x": 1}, allow_redirects=True, **params)] def test_http_OPTIONS(session, params): with mock.patch("aiohttp.client.ClientSession._request") as patched: session.options("http://opt.example.com", params={"x": 2}, **params) assert patched.called, "`ClientSession._request` not called" assert list(patched.call_args) == [("OPTIONS", "http://opt.example.com",), dict( params={"x": 2}, allow_redirects=True, **params)] def test_http_HEAD(session, params): with mock.patch("aiohttp.client.ClientSession._request") as patched: session.head("http://head.example.com", params={"x": 2}, **params) assert patched.called, "`ClientSession._request` not called" assert list(patched.call_args) == [("HEAD", "http://head.example.com",), dict( params={"x": 2}, allow_redirects=False, **params)] def test_http_POST(session, params): with mock.patch("aiohttp.client.ClientSession._request") as patched: session.post("http://post.example.com", params={"x": 2}, data="Some_data", **params) assert patched.called, "`ClientSession._request` not called" assert list(patched.call_args) == [("POST", "http://post.example.com",), dict( params={"x": 2}, data="Some_data", **params)] def test_http_PUT(session, params): with mock.patch("aiohttp.client.ClientSession._request") as patched: session.put("http://put.example.com", params={"x": 2}, data="Some_data", **params) assert patched.called, "`ClientSession._request` not called" assert list(patched.call_args) == [("PUT", "http://put.example.com",), dict( params={"x": 2}, data="Some_data", **params)] def test_http_PATCH(session, params): with mock.patch("aiohttp.client.ClientSession._request") as patched: session.patch("http://patch.example.com", params={"x": 2}, data="Some_data", **params) assert patched.called, "`ClientSession._request` not called" assert list(patched.call_args) == [("PATCH", "http://patch.example.com",), dict( params={"x": 2}, data="Some_data", **params)] def test_http_DELETE(session, params): with mock.patch("aiohttp.client.ClientSession._request") as patched: session.delete("http://delete.example.com", params={"x": 2}, **params) assert patched.called, "`ClientSession._request` not called" assert list(patched.call_args) == [("DELETE", "http://delete.example.com",), dict( params={"x": 2}, **params)] def test_close(create_session, connector): session = create_session(connector=connector) session.close() assert session.connector is None assert connector.closed def test_closed(session): assert not session.closed session.close() assert session.closed def test_connector(create_session, loop): connector = TCPConnector(loop=loop) session = create_session(connector=connector) assert session.connector is connector def test_connector_loop(loop): with contextlib.ExitStack() as stack: another_loop = asyncio.new_event_loop() stack.enter_context(contextlib.closing(another_loop)) connector = TCPConnector(loop=another_loop) stack.enter_context(contextlib.closing(connector)) with pytest.raises(ValueError) as ctx: ClientSession(connector=connector, loop=loop) assert re.match("loop argument must agree with connector", str(ctx.value)) def test_cookies_are_readonly(session): with pytest.raises(AttributeError): session.cookies = 123 def test_detach(session): conn = session.connector try: assert not conn.closed session.detach() assert session.connector is None assert session.closed assert not conn.closed finally: conn.close() @pytest.mark.run_loop def test_request_closed_session(session): session.close() with pytest.raises(RuntimeError): yield from session.request('get', '/') def test_close_flag_for_closed_connector(session): conn = session.connector assert not session.closed conn.close() assert session.closed def test_double_close(connector, create_session): session = create_session(connector=connector) session.close() assert session.connector is None session.close() assert session.closed assert connector.closed def test_del(connector, loop, warning): # 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) with warning(ResourceWarning): del session gc.collect() def test_context_manager(connector, loop): with ClientSession(loop=loop, connector=connector) as session: pass assert session.closed def test_borrow_connector_loop(connector, create_session, loop): session = ClientSession(connector=connector, loop=None) try: assert session._loop, loop finally: session.close() @pytest.mark.run_loop def test_reraise_os_error(create_session): 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) @asyncio.coroutine def create_connection(req): # return self.transport, self.protocol return mock.Mock(), mock.Mock() session._connector._create_connection = create_connection with pytest.raises(aiohttp.ClientOSError) as ctx: yield from session.request('get', 'http://example.com') e = ctx.value assert e.errno == err.errno assert e.strerror == err.strerror def test_request_ctx_manager_props(loop): with aiohttp.ClientSession(loop=loop) as client: ctx_mgr = client.get('http://example.com') next(ctx_mgr) assert isinstance(ctx_mgr.gi_frame, types.FrameType) assert not ctx_mgr.gi_running assert isinstance(ctx_mgr.gi_code, types.CodeType) aiohttp-0.20.2/tests/test_client_functional_oldstyle.py0000664000175000017500000015420712635103355024235 0ustar andrewandrew00000000000000"""Http client functional tests.""" import binascii import gc import io import os.path import json import http.cookies import asyncio import unittest from unittest import mock import aiohttp from aiohttp import client, helpers from aiohttp import test_utils from aiohttp.multidict import MultiDict from aiohttp.multipart import MultipartWriter class TestHttpClientFunctional(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): # just in case if we have transport close callbacks test_utils.run_briefly(self.loop) self.loop.close() gc.collect() def test_HTTP_200_OK_METHOD(self): with test_utils.run_server(self.loop, router=Functional) as httpd: for meth in ('get', 'post', 'put', 'delete', 'head'): r = self.loop.run_until_complete( client.request(meth, httpd.url('method', meth), loop=self.loop)) content1 = self.loop.run_until_complete(r.read()) content2 = self.loop.run_until_complete(r.read()) content = content1.decode() self.assertEqual(r.status, 200) if meth == 'head': self.assertEqual(b'', content1) else: self.assertIn('"method": "%s"' % meth.upper(), content) self.assertEqual(content1, content2) r.close() def test_HTTP_200_OK_METHOD_connector(self): with test_utils.run_server(self.loop, router=Functional) as httpd: conn = aiohttp.TCPConnector( conn_timeout=0.2, resolve=True, loop=self.loop) conn.clear_resolved_hosts() for meth in ('get', 'post', 'put', 'delete', 'head'): r = self.loop.run_until_complete( client.request( meth, httpd.url('method', meth), connector=conn, loop=self.loop)) content1 = self.loop.run_until_complete(r.read()) content2 = self.loop.run_until_complete(r.read()) content = content1.decode() self.assertEqual(r.status, 200) if meth == 'head': self.assertEqual(b'', content1) else: self.assertIn('"method": "%s"' % meth.upper(), content) self.assertEqual(content1, content2) r.close() def test_use_global_loop(self): with test_utils.run_server(self.loop, router=Functional) as httpd: try: asyncio.set_event_loop(self.loop) r = self.loop.run_until_complete( client.request('get', httpd.url('method', 'get'))) finally: asyncio.set_event_loop(None) content1 = self.loop.run_until_complete(r.read()) content2 = self.loop.run_until_complete(r.read()) content = content1.decode() self.assertEqual(r.status, 200) self.assertIn('"method": "GET"', content) self.assertEqual(content1, content2) r.close() def test_HTTP_302_REDIRECT_GET(self): with test_utils.run_server(self.loop, router=Functional) as httpd: @asyncio.coroutine def go(): r = yield from client.request('get', httpd.url('redirect', 2), loop=self.loop) self.assertEqual(r.status, 200) self.assertEqual(2, httpd['redirects']) r.close() self.loop.run_until_complete(go()) def test_HTTP_302_REDIRECT_NON_HTTP(self): with test_utils.run_server(self.loop, router=Functional) as httpd: @asyncio.coroutine def go(): with self.assertRaises(ValueError): yield from client.request('get', httpd.url('redirect_err'), loop=self.loop) self.loop.run_until_complete(go()) def test_HTTP_302_REDIRECT_POST(self): with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('post', httpd.url('redirect', 2), data={'some': 'data'}, loop=self.loop)) content = self.loop.run_until_complete(r.content.read()) content = content.decode() self.assertEqual(r.status, 200) self.assertIn('"method": "GET"', content) self.assertEqual(2, httpd['redirects']) r.close() def test_HTTP_302_REDIRECT_POST_with_content_length_header(self): data = json.dumps({'some': 'data'}) with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('post', httpd.url('redirect', 2), data=data, headers={'Content-Length': str(len(data))}, loop=self.loop)) content = self.loop.run_until_complete(r.content.read()) content = content.decode() self.assertEqual(r.status, 200) self.assertIn('"method": "GET"', content) self.assertEqual(2, httpd['redirects']) r.close() def test_HTTP_307_REDIRECT_POST(self): with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('post', httpd.url('redirect_307', 2), data={'some': 'data'}, loop=self.loop)) content = self.loop.run_until_complete(r.content.read()) content = content.decode() self.assertEqual(r.status, 200) self.assertIn('"method": "POST"', content) self.assertEqual(2, httpd['redirects']) r.close() def test_HTTP_302_max_redirects(self): with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('get', httpd.url('redirect', 5), max_redirects=2, loop=self.loop)) self.assertEqual(r.status, 302) self.assertEqual(2, httpd['redirects']) r.close() def test_HTTP_200_GET_WITH_PARAMS(self): with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('get', httpd.url('method', 'get'), params={'q': 'test'}, loop=self.loop)) content = self.loop.run_until_complete(r.content.read()) content = content.decode() self.assertIn('"query": "q=test"', content) self.assertEqual(r.status, 200) r.close() def test_HTTP_200_GET_MultiDict_PARAMS(self): with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('get', httpd.url('method', 'get'), params=MultiDict( [('q', 'test1'), ('q', 'test2')]), loop=self.loop)) content = self.loop.run_until_complete(r.content.read()) content = content.decode() self.assertIn('"query": "q=test1&q=test2"', content) self.assertEqual(r.status, 200) r.close() def test_HTTP_200_GET_WITH_MIXED_PARAMS(self): with test_utils.run_server(self.loop, router=Functional) as httpd: @asyncio.coroutine def go(): r = yield from client.request( 'get', httpd.url('method', 'get') + '?test=true', params={'q': 'test'}, loop=self.loop) content = yield from r.content.read() content = content.decode() self.assertIn('"query": "test=true&q=test"', content) self.assertEqual(r.status, 200) r.close() # let loop to make one iteration to call connection_lost # and close socket yield from asyncio.sleep(0, loop=self.loop) self.loop.run_until_complete(go()) def test_POST_DATA(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') r = self.loop.run_until_complete( client.request('post', url, data={'some': 'data'}, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual({'some': ['data']}, content['form']) self.assertEqual(r.status, 200) r.close() def test_POST_DATA_with_explicit_formdata(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') form = aiohttp.FormData() form.add_field('name', 'text') r = self.loop.run_until_complete( client.request('post', url, data=form, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual({'name': ['text']}, content['form']) self.assertEqual(r.status, 200) r.close() def test_POST_DATA_with_charset(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') form = aiohttp.FormData() form.add_field('name', 'текÑÑ‚', content_type='text/plain; charset=koi8-r') r = self.loop.run_until_complete( client.request( 'post', url, data=form, loop=self.loop)) content = self.loop.run_until_complete(r.json()) self.assertEqual(1, len(content['multipart-data'])) field = content['multipart-data'][0] self.assertEqual('name', field['name']) self.assertEqual('текÑÑ‚', field['data']) self.assertEqual(r.status, 200) def test_POST_DATA_with_content_transfer_encoding(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') form = aiohttp.FormData() form.add_field('name', b'123', content_transfer_encoding='base64') r = self.loop.run_until_complete( client.request( 'post', url, data=form, loop=self.loop)) content = self.loop.run_until_complete(r.json()) self.assertEqual(1, len(content['multipart-data'])) field = content['multipart-data'][0] self.assertEqual('name', field['name']) self.assertEqual(b'123', binascii.a2b_base64(field['data'])) # self.assertEqual('base64', field['content-transfer-encoding']) self.assertEqual(r.status, 200) def test_POST_MultiDict(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') r = self.loop.run_until_complete( client.request('post', url, data=MultiDict( [('q', 'test1'), ('q', 'test2')]), loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual({'q': ['test1', 'test2']}, content['form']) self.assertEqual(r.status, 200) r.close() def test_POST_DATA_DEFLATE(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') r = self.loop.run_until_complete( client.request('post', url, data={'some': 'data'}, compress=True, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual('deflate', content['compression']) self.assertEqual({'some': ['data']}, content['form']) self.assertEqual(r.status, 200) r.close() def test_POST_FILES(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname) as f: r = self.loop.run_until_complete( client.request( 'post', url, data={'some': f, 'test': b'data'}, chunked=1024, headers={'Transfer-Encoding': 'chunked'}, loop=self.loop)) content = self.loop.run_until_complete(r.json()) files = list( sorted(content['multipart-data'], key=lambda d: d['name'])) f.seek(0) filename = os.path.split(f.name)[-1] self.assertEqual(2, len(content['multipart-data'])) self.assertEqual('some', files[0]['name']) self.assertEqual(filename, files[0]['filename']) self.assertEqual(f.read(), files[0]['data']) self.assertEqual(r.status, 200) r.close() def test_POST_FILES_DEFLATE(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname) as f: r = self.loop.run_until_complete( client.request('post', url, data={'some': f}, chunked=1024, compress='deflate', loop=self.loop)) content = self.loop.run_until_complete(r.json()) f.seek(0) filename = os.path.split(f.name)[-1] self.assertEqual('deflate', content['compression']) self.assertEqual(1, len(content['multipart-data'])) self.assertEqual( 'some', content['multipart-data'][0]['name']) self.assertEqual( filename, content['multipart-data'][0]['filename']) self.assertEqual( f.read(), content['multipart-data'][0]['data']) self.assertEqual(r.status, 200) r.close() def test_POST_FILES_STR(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname) as f: r = self.loop.run_until_complete( client.request('post', url, data=[('some', f.read())], loop=self.loop)) content = self.loop.run_until_complete(r.json()) f.seek(0) self.assertEqual(1, len(content['form'])) self.assertIn('some', content['form']) self.assertEqual(f.read(), content['form']['some'][0]) self.assertEqual(r.status, 200) r.close() def test_POST_FILES_STR_SIMPLE(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname) as f: r = self.loop.run_until_complete( client.request('post', url, data=f.read(), loop=self.loop)) content = self.loop.run_until_complete(r.json()) f.seek(0) self.assertEqual(f.read(), content['content']) self.assertEqual(r.status, 200) r.close() def test_POST_FILES_LIST(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname) as f: r = self.loop.run_until_complete( client.request('post', url, data=[('some', f)], loop=self.loop)) content = self.loop.run_until_complete(r.json()) f.seek(0) filename = os.path.split(f.name)[-1] self.assertEqual(1, len(content['multipart-data'])) self.assertEqual( 'some', content['multipart-data'][0]['name']) self.assertEqual( filename, content['multipart-data'][0]['filename']) self.assertEqual( f.read(), content['multipart-data'][0]['data']) self.assertEqual(r.status, 200) r.close() def test_POST_FILES_LIST_CT(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname) as f: form = aiohttp.FormData() form.add_field('some', f, content_type='text/plain') r = self.loop.run_until_complete( client.request('post', url, loop=self.loop, data=form)) content = self.loop.run_until_complete(r.json()) f.seek(0) filename = os.path.split(f.name)[-1] self.assertEqual(1, len(content['multipart-data'])) self.assertEqual( 'some', content['multipart-data'][0]['name']) self.assertEqual( filename, content['multipart-data'][0]['filename']) self.assertEqual( f.read(), content['multipart-data'][0]['data']) self.assertEqual( 'text/plain', content['multipart-data'][0]['content-type']) self.assertEqual(r.status, 200) r.close() def test_POST_FILES_SINGLE(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname) as f: with self.assertRaises(ValueError): self.loop.run_until_complete( client.request('post', url, data=f, loop=self.loop)) def test_POST_FILES_SINGLE_BINARY(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: r = self.loop.run_until_complete( client.request('post', url, data=f, loop=self.loop)) content = self.loop.run_until_complete(r.json()) f.seek(0) self.assertEqual(0, len(content['multipart-data'])) self.assertEqual(content['content'], f.read().decode()) # if system cannot determine 'application/pgp-keys' MIME type # then use 'application/octet-stream' default self.assertIn(content['headers']['Content-Type'], ('application/pgp-keys', 'application/octet-stream')) self.assertEqual(r.status, 200) r.close() def test_POST_FILES_IO(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') data = io.BytesIO(b'data') r = self.loop.run_until_complete( client.request('post', url, data=[data], loop=self.loop)) content = self.loop.run_until_complete(r.json()) self.assertEqual(1, len(content['multipart-data'])) self.assertEqual( {'content-type': 'application/octet-stream', 'data': 'data', 'filename': 'unknown', 'filename*': "utf-8''unknown", 'name': 'unknown'}, content['multipart-data'][0]) self.assertEqual(r.status, 200) r.close() def test_POST_MULTIPART(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') with MultipartWriter('form-data') as writer: writer.append('foo') writer.append_json({'bar': 'баз'}) writer.append_form([('теÑÑ‚', '4'), ('ÑетÑ', '2')]) r = self.loop.run_until_complete( client.request('post', url, data=writer, loop=self.loop)) content = self.loop.run_until_complete(r.json()) self.assertEqual(3, len(content['multipart-data'])) self.assertEqual({'content-type': 'text/plain', 'data': 'foo'}, content['multipart-data'][0]) self.assertEqual({'content-type': 'application/json', 'data': '{"bar": "\\u0431\\u0430\\u0437"}'}, content['multipart-data'][1]) self.assertEqual( {'content-type': 'application/x-www-form-urlencoded', 'data': '%D1%82%D0%B5%D1%81%D1%82=4&' '%D1%81%D0%B5%D1%82%D1%81=2'}, content['multipart-data'][2]) self.assertEqual(r.status, 200) r.close() def test_POST_FILES_IO_WITH_PARAMS(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') data = io.BytesIO(b'data') r = self.loop.run_until_complete( client.request('post', url, data=(('test', 'true'), MultiDict( [('q', 't1'), ('q', 't2')]), data), loop=self.loop)) content = self.loop.run_until_complete(r.json()) self.assertEqual(4, len(content['multipart-data'])) self.assertEqual( {'content-type': 'text/plain', 'data': 'true', 'name': 'test'}, content['multipart-data'][0]) self.assertEqual( {'content-type': 'application/octet-stream', 'data': 'data', 'filename': 'unknown', 'filename*': "utf-8''unknown", 'name': 'unknown'}, content['multipart-data'][1]) self.assertEqual( {'content-type': 'text/plain', 'data': 't1', 'name': 'q'}, content['multipart-data'][2]) self.assertEqual( {'content-type': 'text/plain', 'data': 't2', 'name': 'q'}, content['multipart-data'][3]) self.assertEqual(r.status, 200) r.close() def test_POST_FILES_WITH_DATA(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname) as f: r = self.loop.run_until_complete( client.request('post', url, loop=self.loop, data={'test': 'true', 'some': f})) content = self.loop.run_until_complete(r.json()) files = list( sorted(content['multipart-data'], key=lambda d: d['name'])) self.assertEqual(2, len(content['multipart-data'])) self.assertEqual('test', files[1]['name']) self.assertEqual('true', files[1]['data']) f.seek(0) filename = os.path.split(f.name)[-1] self.assertEqual('some', files[0]['name']) self.assertEqual(filename, files[0]['filename']) self.assertEqual(f.read(), files[0]['data']) self.assertEqual(r.status, 200) r.close() def test_POST_STREAM_DATA(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: data = f.read() fut = asyncio.Future(loop=self.loop) @asyncio.coroutine def stream(): yield from fut yield data self.loop.call_later(0.01, fut.set_result, True) r = self.loop.run_until_complete( client.request( 'post', url, data=stream(), headers={'Content-Length': str(len(data))}, loop=self.loop)) content = self.loop.run_until_complete(r.json()) r.close() self.assertEqual(str(len(data)), content['headers']['Content-Length']) self.assertEqual('application/octet-stream', content['headers']['Content-Type']) def test_POST_StreamReader(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: data = f.read() stream = aiohttp.StreamReader(loop=self.loop) stream.feed_data(data) stream.feed_eof() r = self.loop.run_until_complete( client.request( 'post', url, data=stream, headers={'Content-Length': str(len(data))}, loop=self.loop)) content = self.loop.run_until_complete(r.json()) r.close() self.assertEqual(str(len(data)), content['headers']['Content-Length']) def test_POST_DataQueue(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: data = f.read() stream = aiohttp.DataQueue(loop=self.loop) stream.feed_data(data[:100], 100) stream.feed_data(data[100:], len(data[100:])) stream.feed_eof() r = self.loop.run_until_complete( client.request( 'post', url, data=stream, headers={'Content-Length': str(len(data))}, loop=self.loop)) content = self.loop.run_until_complete(r.json()) r.close() self.assertEqual(str(len(data)), content['headers']['Content-Length']) def test_POST_ChunksQueue(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: data = f.read() stream = aiohttp.ChunksQueue(loop=self.loop) stream.feed_data(data[:100], 100) d = data[100:] stream.feed_data(d, len(d)) stream.feed_eof() r = self.loop.run_until_complete( client.request( 'post', url, data=stream, headers={'Content-Length': str(len(data))}, loop=self.loop)) content = self.loop.run_until_complete(r.json()) r.close() self.assertEqual(str(len(data)), content['headers']['Content-Length']) def test_expect_continue(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') r = self.loop.run_until_complete( client.request('post', url, data={'some': 'data'}, expect100=True, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual('100-continue', content['headers']['Expect']) self.assertEqual(r.status, 200) r.close() def test_encoding(self): with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('get', httpd.url('encoding', 'deflate'), loop=self.loop)) self.assertEqual(r.status, 200) r.close() def test_encoding2(self): with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('get', httpd.url('encoding', 'gzip'), loop=self.loop)) self.assertEqual(r.status, 200) r.close() def test_cookies(self): with test_utils.run_server(self.loop, router=Functional) as httpd: c = http.cookies.Morsel() c.set('test3', '456', '456') r = self.loop.run_until_complete( client.request( 'get', httpd.url('method', 'get'), loop=self.loop, cookies={'test1': '123', 'test2': c})) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.content.read()) self.assertIn(b'"Cookie": "test1=123; test3=456"', bytes(content)) r.close() def test_morsel_with_attributes(self): with test_utils.run_server(self.loop, router=Functional) as httpd: c = http.cookies.Morsel() c.set('test3', '456', '456') c['httponly'] = True c['secure'] = True c['max-age'] = 1000 r = self.loop.run_until_complete( client.request( 'get', httpd.url('method', 'get'), loop=self.loop, cookies={'test2': c})) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.content.read()) # No cookie attribute should pass here # they are only used as filters # whether to send particular cookie or not. # E.g. if cookie expires it just becomes thrown away. # Server who sent the cookie with some attributes # already knows them, no need to send this back again and again self.assertIn(b'"Cookie": "test3=456"', bytes(content)) r.close() @mock.patch('aiohttp.client_reqrep.client_logger') def test_set_cookies(self, m_log): with test_utils.run_server(self.loop, router=Functional) as httpd: resp = self.loop.run_until_complete( client.request('get', httpd.url('cookies'), loop=self.loop)) self.assertEqual(resp.status, 200) self.assertEqual(list(sorted(resp.cookies.keys())), ['c1', 'c2']) self.assertEqual(resp.cookies['c1'].value, 'cookie1') self.assertEqual(resp.cookies['c2'].value, 'cookie2') resp.close() m_log.warning.assert_called_with('Can not load response cookies: %s', mock.ANY) @mock.patch('aiohttp.client_reqrep.client_logger') def test_share_cookies(self, m_log): with test_utils.run_server(self.loop, router=Functional) as httpd: with self.assertWarns(DeprecationWarning): conn = aiohttp.TCPConnector(share_cookies=True, loop=self.loop) resp = self.loop.run_until_complete( client.request('get', httpd.url('cookies'), connector=conn, loop=self.loop)) self.assertIn('SET-COOKIE', resp.headers) self.assertEqual(resp.cookies['c1'].value, 'cookie1') self.assertEqual(resp.cookies['c2'].value, 'cookie2') self.assertEqual(conn.cookies, resp.cookies) resp.close() resp2 = self.loop.run_until_complete( client.request('get', httpd.url('method', 'get'), connector=conn, loop=self.loop)) self.assertNotIn('SET-COOKIE', resp2.headers) data = self.loop.run_until_complete(resp2.json()) self.assertEqual(data['headers']['Cookie'], 'c1=cookie1; c2=cookie2') resp2.close() def test_chunked(self): with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('get', httpd.url('chunked'), loop=self.loop)) self.assertEqual(r.status, 200) self.assertEqual(r.headers.getone('TRANSFER-ENCODING'), 'chunked') content = self.loop.run_until_complete(r.json()) self.assertEqual(content['path'], '/chunked') r.close() def test_broken_connection(self): with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('get', httpd.url('broken'), loop=self.loop)) self.assertEqual(r.status, 200) self.assertRaises( aiohttp.ServerDisconnectedError, self.loop.run_until_complete, r.json()) r.close() def test_request_conn_error(self): self.assertRaises( aiohttp.ClientConnectionError, self.loop.run_until_complete, client.request('get', 'http://0.0.0.0:1', loop=self.loop)) def test_request_conn_closed(self): with test_utils.run_server(self.loop, router=Functional) as httpd: httpd['close'] = True self.assertRaises( aiohttp.ClientHttpProcessingError, self.loop.run_until_complete, client.request( 'get', httpd.url('method', 'get'), loop=self.loop)) def test_keepalive(self): from aiohttp import connector with self.assertWarns(DeprecationWarning): c = connector.TCPConnector(share_cookies=True, loop=self.loop) with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request('get', httpd.url('keepalive',), connector=c, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual(content['content'], 'requests=1') r.close() r = self.loop.run_until_complete( client.request('get', httpd.url('keepalive'), connector=c, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual(content['content'], 'requests=2') r.close() c.close() def test_session_close(self): conn = aiohttp.TCPConnector(loop=self.loop) with test_utils.run_server(self.loop, router=Functional) as httpd: r = self.loop.run_until_complete( client.request( 'get', httpd.url('keepalive') + '?close=1', connector=conn, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual(content['content'], 'requests=1') r.close() r = self.loop.run_until_complete( client.request('get', httpd.url('keepalive'), connector=conn, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual(content['content'], 'requests=1') r.close() conn.close() @mock.patch('aiohttp.client_reqrep.client_logger') def test_connector_cookies(self, m_log): from aiohttp import connector with self.assertWarns(DeprecationWarning): conn = connector.TCPConnector(share_cookies=True, loop=self.loop) with test_utils.run_server(self.loop, router=Functional) as httpd: conn.update_cookies({'test': '1'}) r = self.loop.run_until_complete( client.request('get', httpd.url('cookies'), connector=conn, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual(content['headers']['Cookie'], 'test=1') r.close() cookies = sorted([(k, v.value) for k, v in conn.cookies.items()]) self.assertEqual( cookies, [('c1', 'cookie1'), ('c2', 'cookie2'), ('test', '1')]) m_log.warning.assert_called_with( 'Can not load response cookies: %s', mock.ANY) conn.close() def test_multidict_headers(self): with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('method', 'post') data = b'sample data' r = self.loop.run_until_complete( client.request( 'post', url, data=data, headers=MultiDict( {'Content-Length': str(len(data))}), loop=self.loop)) content = self.loop.run_until_complete(r.json()) r.close() self.assertEqual(str(len(data)), content['headers']['Content-Length']) def test_close_implicit_connector(self): @asyncio.coroutine def go(url): r = yield from client.request('GET', url, loop=self.loop) connection = r.connection self.assertIsNotNone(connection) connector = connection._connector self.assertIsNotNone(connector) yield from r.read() self.assertEqual(0, len(connector._conns)) with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('keepalive') self.loop.run_until_complete(go(url)) def test_dont_close_explicit_connector(self): @asyncio.coroutine def go(url): connector = aiohttp.TCPConnector(loop=self.loop) r = yield from client.request('GET', url, connector=connector, loop=self.loop) yield from r.read() self.assertEqual(1, len(connector._conns)) connector.close() with test_utils.run_server(self.loop, router=Functional) as httpd: url = httpd.url('keepalive') self.loop.run_until_complete(go(url)) def test_server_close_keepalive_connection(self): class Proto(asyncio.Protocol): def connection_made(self, transport): self.transp = transport self.data = b'' def data_received(self, data): self.data += data if data.endswith(b'\r\n\r\n'): self.transp.write( b'HTTP/1.1 200 OK\r\n' b'CONTENT-LENGTH: 2\r\n' b'CONNECTION: close\r\n' b'\r\n' b'ok') self.transp.close() def connection_lost(self, exc): self.transp = None @asyncio.coroutine def go(): server = yield from self.loop.create_server( Proto, '127.0.0.1') addr = server.sockets[0].getsockname() connector = aiohttp.TCPConnector(loop=self.loop) url = 'http://{}:{}/'.format(*addr) for i in range(2): r = yield from client.request('GET', url, connector=connector, loop=self.loop) yield from r.read() self.assertEqual(0, len(connector._conns)) connector.close() server.close() yield from server.wait_closed() self.loop.run_until_complete(go()) def test_handle_keepalive_on_closed_connection(self): class Proto(asyncio.Protocol): def connection_made(self, transport): self.transp = transport self.data = b'' def data_received(self, data): self.data += data if data.endswith(b'\r\n\r\n'): self.transp.write( b'HTTP/1.1 200 OK\r\n' b'CONTENT-LENGTH: 2\r\n' b'\r\n' b'ok') self.transp.close() def connection_lost(self, exc): self.transp = None @asyncio.coroutine def go(): server = yield from self.loop.create_server( Proto, '127.0.0.1') addr = server.sockets[0].getsockname() connector = aiohttp.TCPConnector(loop=self.loop) url = 'http://{}:{}/'.format(*addr) r = yield from client.request('GET', url, connector=connector, loop=self.loop) yield from r.read() self.assertEqual(1, len(connector._conns)) with self.assertRaises(aiohttp.ClientError): yield from client.request('GET', url, connector=connector, loop=self.loop) self.assertEqual(0, len(connector._conns)) connector.close() server.close() yield from server.wait_closed() self.loop.run_until_complete(go()) @mock.patch('aiohttp.client_reqrep.client_logger') def test_share_cookie_partial_update(self, m_log): with test_utils.run_server(self.loop, router=Functional) as httpd: with self.assertWarns(DeprecationWarning): conn = aiohttp.TCPConnector(share_cookies=True, loop=self.loop) # Set c1 and c2 cookie resp = self.loop.run_until_complete( client.request('get', httpd.url('cookies'), connector=conn, loop=self.loop)) self.assertEqual(resp.cookies['c1'].value, 'cookie1') self.assertEqual(resp.cookies['c2'].value, 'cookie2') self.assertEqual(conn.cookies, resp.cookies) resp.close() # Update c1 at server side resp = self.loop.run_until_complete( client.request('get', httpd.url('cookies_partial'), connector=conn, loop=self.loop)) self.assertEqual(resp.cookies['c1'].value, 'other_cookie1') resp.close() # Assert, that we send updated cookies in next requests r = self.loop.run_until_complete( client.request('get', httpd.url('method', 'get'), connector=conn, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual( content['headers']['Cookie'], 'c1=other_cookie1; c2=cookie2') r.close() def test_connector_cookie_merge(self): with test_utils.run_server(self.loop, router=Functional) as httpd: with self.assertWarns(DeprecationWarning): conn = aiohttp.TCPConnector(share_cookies=True, loop=self.loop) conn.update_cookies({ "c1": "connector_cookie1", "c2": "connector_cookie2", }) # Update c1 using direct cookies attribute of request r = self.loop.run_until_complete( client.request('get', httpd.url('method', 'get'), cookies={"c1": "direct_cookie1"}, connector=conn, loop=self.loop)) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual( content['headers']['Cookie'], 'c1=direct_cookie1; c2=connector_cookie2') r.close() @mock.patch('aiohttp.client_reqrep.client_logger') def test_session_cookies(self, m_log): with test_utils.run_server(self.loop, router=Functional) as httpd: session = client.ClientSession(loop=self.loop) resp = self.loop.run_until_complete( session.request('get', httpd.url('cookies'))) self.assertEqual(resp.cookies['c1'].value, 'cookie1') self.assertEqual(resp.cookies['c2'].value, 'cookie2') self.assertEqual(session.cookies, resp.cookies) resp.close() # Assert, that we send those cookies in next requests r = self.loop.run_until_complete( session.request('get', httpd.url('method', 'get'))) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertEqual( content['headers']['Cookie'], 'c1=cookie1; c2=cookie2') r.close() session.close() def test_session_headers(self): with test_utils.run_server(self.loop, router=Functional) as httpd: session = client.ClientSession( loop=self.loop, headers={ "X-Real-IP": "192.168.0.1" }) r = self.loop.run_until_complete( session.request('get', httpd.url('method', 'get'))) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertIn( "X-Real-Ip", content['headers']) self.assertEqual( content['headers']["X-Real-Ip"], "192.168.0.1") r.close() session.close() def test_session_headers_merge(self): with test_utils.run_server(self.loop, router=Functional) as httpd: session = client.ClientSession( loop=self.loop, headers=[ ("X-Real-IP", "192.168.0.1"), ("X-Sent-By", "requests")]) r = self.loop.run_until_complete( session.request('get', httpd.url('method', 'get'), headers={"X-Sent-By": "aiohttp"})) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertIn( "X-Real-Ip", content['headers']) self.assertIn( "X-Sent-By", content['headers']) self.assertEqual( content['headers']["X-Real-Ip"], "192.168.0.1") self.assertEqual( content['headers']["X-Sent-By"], "aiohttp") r.close() session.close() def test_session_auth(self): with test_utils.run_server(self.loop, router=Functional) as httpd: session = client.ClientSession( loop=self.loop, auth=helpers.BasicAuth("login", "pass")) r = self.loop.run_until_complete( session.request('get', httpd.url('method', 'get'))) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertIn( "Authorization", content['headers']) self.assertEqual( content['headers']["Authorization"], "Basic bG9naW46cGFzcw==") r.close() session.close() def test_session_auth_override(self): with test_utils.run_server(self.loop, router=Functional) as httpd: session = client.ClientSession( loop=self.loop, auth=helpers.BasicAuth("login", "pass")) r = self.loop.run_until_complete( session.request('get', httpd.url('method', 'get'), auth=helpers.BasicAuth("other_login", "pass"))) self.assertEqual(r.status, 200) content = self.loop.run_until_complete(r.json()) self.assertIn( "Authorization", content['headers']) self.assertEqual( content['headers']["Authorization"], "Basic b3RoZXJfbG9naW46cGFzcw==") r.close() session.close() def test_session_auth_header_conflict(self): with test_utils.run_server(self.loop, router=Functional) as httpd: session = client.ClientSession( loop=self.loop, auth=helpers.BasicAuth("login", "pass")) headers = {'Authorization': "Basic b3RoZXJfbG9naW46cGFzcw=="} with self.assertRaises(ValueError): self.loop.run_until_complete( session.request('get', httpd.url('method', 'get'), headers=headers)) session.close() def test_shortcuts(self): with test_utils.run_server(self.loop, router=Functional) as httpd: for meth in ('get', 'post', 'put', 'delete', 'head', 'patch', 'options'): coro = getattr(client, meth) r = self.loop.run_until_complete( coro(httpd.url('method', meth), loop=self.loop)) content1 = self.loop.run_until_complete(r.read()) content2 = self.loop.run_until_complete(r.read()) content = content1.decode() self.assertEqual(r.status, 200) if meth == 'head': self.assertEqual(b'', content1) else: self.assertIn('"method": "%s"' % meth.upper(), content) self.assertEqual(content1, content2) r.close() class Functional(test_utils.Router): @test_utils.Router.define('/method/([A-Za-z]+)$') def method(self, match): self._response(self._start_response(200)) @test_utils.Router.define('/redirect_err$') def redirect_err(self, match): self._response( self._start_response(302), headers={'Location': 'ftp://127.0.0.1/test/'}) @test_utils.Router.define('/redirect/([0-9]+)$') def redirect(self, match): no = int(match.group(1).upper()) rno = self._props['redirects'] = self._props.get('redirects', 0) + 1 if rno >= no: self._response( self._start_response(302), headers={'Location': '/method/%s' % self._method.lower()}) else: self._response( self._start_response(302), headers={'Location': self._path}) @test_utils.Router.define('/redirect_307/([0-9]+)$') def redirect_307(self, match): no = int(match.group(1).upper()) rno = self._props['redirects'] = self._props.get('redirects', 0) + 1 if rno >= no: self._response( self._start_response(307), headers={'Location': '/method/%s' % self._method.lower()}) else: self._response( self._start_response(307), headers={'Location': self._path}) @test_utils.Router.define('/encoding/(gzip|deflate)$') def encoding(self, match): mode = match.group(1) resp = self._start_response(200) resp.add_compression_filter(mode) resp.add_chunking_filter(100) self._response(resp, headers={'Content-encoding': mode}, chunked=True) @test_utils.Router.define('/chunked$') def chunked(self, match): resp = self._start_response(200) resp.add_chunking_filter(100) self._response(resp, chunked=True) @test_utils.Router.define('/keepalive$') def keepalive(self, match): self._transport._requests = getattr( self._transport, '_requests', 0) + 1 resp = self._start_response(200) if 'close=' in self._query: self._response( resp, 'requests={}'.format(self._transport._requests)) else: self._response( resp, 'requests={}'.format(self._transport._requests), headers={'CONNECTION': 'keep-alive'}) @test_utils.Router.define('/cookies$') def cookies(self, match): cookies = http.cookies.SimpleCookie() cookies['c1'] = 'cookie1' cookies['c2'] = 'cookie2' resp = self._start_response(200) for cookie in cookies.output(header='').split('\n'): resp.add_header('Set-Cookie', cookie.strip()) resp.add_header( 'Set-Cookie', 'ISAWPLB{A7F52349-3531-4DA9-8776-F74BC6F4F1BB}=' '{925EC0B8-CB17-4BEB-8A35-1033813B0523}; HttpOnly; Path=/') self._response(resp) @test_utils.Router.define('/cookies_partial$') def cookies_partial(self, match): cookies = http.cookies.SimpleCookie() cookies['c1'] = 'other_cookie1' resp = self._start_response(200) for cookie in cookies.output(header='').split('\n'): resp.add_header('Set-Cookie', cookie.strip()) self._response(resp) @test_utils.Router.define('/broken$') def broken(self, match): resp = self._start_response(200) def write_body(resp, body): self._transport.close() raise ValueError() self._response( resp, body=json.dumps({'t': (b'0' * 1024).decode('utf-8')}), write_body=write_body) aiohttp-0.20.2/tests/test_parser_buffer.py0000664000175000017500000001302312623705454021436 0ustar andrewandrew00000000000000import pytest from aiohttp import errors, parsers from unittest import mock @pytest.fixture def stream(): return mock.Mock() @pytest.fixture def buf(): return parsers.ParserBuffer() def test_feed_data(buf): buf.feed_data(b'') assert len(buf) == 0 buf.feed_data(b'data') assert len(buf) == 4 assert bytes(buf), b'data' def test_feed_data_after_exception(buf): buf.feed_data(b'data') exc = ValueError() buf.set_exception(exc) buf.feed_data(b'more') assert len(buf) == 4 assert bytes(buf) == b'data' def test_read_exc(buf): p = buf.read(3) next(p) p.send(b'1') exc = ValueError() buf.set_exception(exc) assert buf.exception() is exc with pytest.raises(ValueError): p.send(b'1') def test_read_exc_multiple(buf): p = buf.read(3) next(p) p.send(b'1') exc = ValueError() buf.set_exception(exc) assert buf.exception() is exc p = buf.read(3) with pytest.raises(ValueError): next(p) def test_read(buf): p = buf.read(3) next(p) p.send(b'1') try: p.send(b'234') except StopIteration as exc: res = exc.value assert res == b'123' assert b'4' == bytes(buf) def test_readsome(buf): p = buf.readsome(3) next(p) try: p.send(b'1') except StopIteration as exc: res = exc.value assert res == b'1' p = buf.readsome(2) next(p) try: p.send(b'234') except StopIteration as exc: res = exc.value assert res == b'23' assert b'4' == bytes(buf) def test_readsome_exc(buf): buf.set_exception(ValueError()) p = buf.readsome(3) with pytest.raises(ValueError): next(p) def test_wait(buf): p = buf.wait(3) next(p) p.send(b'1') try: p.send(b'234') except StopIteration as exc: res = exc.value assert res == b'123' assert b'1234' == bytes(buf) def test_wait_exc(buf): buf.set_exception(ValueError()) p = buf.wait(3) with pytest.raises(ValueError): next(p) def test_skip(buf): p = buf.skip(3) next(p) p.send(b'1') try: p.send(b'234') except StopIteration as exc: res = exc.value assert res is None assert b'4' == bytes(buf) def test_skip_exc(buf): buf.set_exception(ValueError()) p = buf.skip(3) with pytest.raises(ValueError): next(p) def test_readuntil_limit(buf): p = buf.readuntil(b'\n', 4) next(p) p.send(b'1') p.send(b'234') with pytest.raises(errors.LineLimitExceededParserError): p.send(b'5') def test_readuntil_limit2(buf): p = buf.readuntil(b'\n', 4) next(p) with pytest.raises(errors.LineLimitExceededParserError): p.send(b'12345\n6') def test_readuntil_limit3(buf): p = buf.readuntil(b'\n', 4) next(p) with pytest.raises(errors.LineLimitExceededParserError): p.send(b'12345\n6') def test_readuntil(buf): p = buf.readuntil(b'\n', 4) next(p) p.send(b'123') try: p.send(b'\n456') except StopIteration as exc: res = exc.value assert res == b'123\n' assert b'456' == bytes(buf) def test_readuntil_exc(buf): buf.set_exception(ValueError()) p = buf.readuntil(b'\n', 4) with pytest.raises(ValueError): next(p) def test_waituntil_limit(buf): p = buf.waituntil(b'\n', 4) next(p) p.send(b'1') p.send(b'234') with pytest.raises(errors.LineLimitExceededParserError): p.send(b'5') def test_waituntil_limit2(buf): p = buf.waituntil(b'\n', 4) next(p) with pytest.raises(errors.LineLimitExceededParserError): p.send(b'12345\n6') def test_waituntil_limit3(buf): p = buf.waituntil(b'\n', 4) next(p) with pytest.raises(errors.LineLimitExceededParserError): p.send(b'12345\n6') def test_waituntil(buf): p = buf.waituntil(b'\n', 4) next(p) p.send(b'123') try: p.send(b'\n456') except StopIteration as exc: res = exc.value assert res == b'123\n' assert b'123\n456' == bytes(buf) def test_waituntil_exc(buf): buf.set_exception(ValueError()) p = buf.waituntil(b'\n', 4) with pytest.raises(ValueError): next(p) def test_skipuntil(buf): p = buf.skipuntil(b'\n') next(p) p.send(b'123') try: p.send(b'\n456\n') except StopIteration: pass assert b'456\n' == bytes(buf) p = buf.skipuntil(b'\n') try: next(p) except StopIteration: pass assert b'' == bytes(buf) def test_skipuntil_exc(buf): buf.set_exception(ValueError()) p = buf.skipuntil(b'\n') with pytest.raises(ValueError): next(p) def test_lines_parser(buf, stream, loop): out = parsers.FlowControlDataQueue(stream, loop=loop) p = parsers.LinesParser()(out, buf) next(p) for d in (b'line1', b'\r\n', b'lin', b'e2\r', b'\ndata'): p.send(d) assert ([(bytearray(b'line1\r\n'), 7), (bytearray(b'line2\r\n'), 7)] == list(out._buffer)) try: p.throw(parsers.EofStream()) except StopIteration: pass assert bytes(buf) == b'data' def test_chunks_parser(stream, loop, buf): out = parsers.FlowControlDataQueue(stream, loop=loop) p = parsers.ChunksParser(5)(out, buf) next(p) for d in (b'line1', b'lin', b'e2d', b'ata'): p.send(d) assert ([(bytearray(b'line1'), 5), (bytearray(b'line2'), 5)] == list(out._buffer)) try: p.throw(parsers.EofStream()) except StopIteration: pass assert bytes(buf) == b'data' aiohttp-0.20.2/tests/test_helpers.py0000664000175000017500000001402112633203053020237 0ustar andrewandrew00000000000000import pytest from unittest import mock from aiohttp import helpers import datetime def test_parse_mimetype_1(): assert helpers.parse_mimetype('') == ('', '', '', {}) def test_parse_mimetype_2(): assert helpers.parse_mimetype('*') == ('*', '*', '', {}) def test_parse_mimetype_3(): assert (helpers.parse_mimetype('application/json') == ('application', 'json', '', {})) def test_parse_mimetype_4(): assert ( helpers.parse_mimetype('application/json; charset=utf-8') == ('application', 'json', '', {'charset': 'utf-8'})) def test_parse_mimetype_5(): assert ( helpers.parse_mimetype('''application/json; charset=utf-8;''') == ('application', 'json', '', {'charset': 'utf-8'})) def test_parse_mimetype_6(): assert( helpers.parse_mimetype('ApPlIcAtIoN/JSON;ChaRseT="UTF-8"') == ('application', 'json', '', {'charset': 'UTF-8'})) def test_parse_mimetype_7(): assert ( helpers.parse_mimetype('application/rss+xml') == ('application', 'rss', 'xml', {})) def test_parse_mimetype_8(): assert ( helpers.parse_mimetype('text/plain;base64') == ('text', 'plain', '', {'base64': ''})) def test_basic_auth1(): # missing password here with pytest.raises(ValueError): helpers.BasicAuth(None) def test_basic_auth2(): with pytest.raises(ValueError): helpers.BasicAuth('nkim', None) def test_basic_auth3(): auth = helpers.BasicAuth('nkim') assert auth.login == 'nkim' assert auth.password == '' def test_basic_auth4(): auth = helpers.BasicAuth('nkim', 'pwd') assert auth.login == 'nkim' assert auth.password == 'pwd' assert auth.encode() == 'Basic bmtpbTpwd2Q=' def test_invalid_formdata_params(): with pytest.raises(TypeError): helpers.FormData('asdasf') def test_invalid_formdata_params2(): with pytest.raises(TypeError): helpers.FormData('as') # 2-char str is not allowed def test_invalid_formdata_content_type(): form = helpers.FormData() invalid_vals = [0, 0.1, {}, [], b'foo'] for invalid_val in invalid_vals: with pytest.raises(TypeError): form.add_field('foo', 'bar', content_type=invalid_val) def test_invalid_formdata_filename(): form = helpers.FormData() invalid_vals = [0, 0.1, {}, [], b'foo'] for invalid_val in invalid_vals: with pytest.raises(TypeError): form.add_field('foo', 'bar', filename=invalid_val) def test_invalid_formdata_content_transfer_encoding(): form = helpers.FormData() invalid_vals = [0, 0.1, {}, [], b'foo'] for invalid_val in invalid_vals: with pytest.raises(TypeError): form.add_field('foo', 'bar', content_transfer_encoding=invalid_val) def test_access_logger_format(): log_format = '%T {%{SPAM}e} "%{ETag}o" %X {X} %%P' mock_logger = mock.Mock() access_logger = helpers.AccessLogger(mock_logger, log_format) expected = '%s {%s} "%s" %%X {X} %%%s' assert expected == access_logger._log_format @mock.patch("aiohttp.helpers.datetime") @mock.patch("os.getpid") def test_access_logger_atoms(mock_getpid, mock_datetime): utcnow = datetime.datetime(1843, 1, 1, 0, 0) mock_datetime.datetime.utcnow.return_value = utcnow mock_getpid.return_value = 42 log_format = '%a %t %P %l %u %r %s %b %O %T %Tf %D' mock_logger = mock.Mock() access_logger = helpers.AccessLogger(mock_logger, log_format) message = mock.Mock(headers={}, method="GET", path="/path", version=(1, 1)) environ = {} response = mock.Mock(headers={}, output_length=123, body_length=42, status=200) transport = mock.Mock() transport.get_extra_info.return_value = ("127.0.0.2", 1234) access_logger.log(message, environ, response, transport, 3.1415926) assert False == mock_logger.exception.called expected = ('127.0.0.2 [01/Jan/1843:00:00:00 +0000] <42> - - ' 'GET /path HTTP/1.1 200 42 123 3 3.141593 3141593') mock_logger.info.assert_called_with(expected) def test_access_logger_dicts(): log_format = '%{User-Agent}i %{Content-Length}o %{SPAM}e %{None}i' mock_logger = mock.Mock() access_logger = helpers.AccessLogger(mock_logger, log_format) message = mock.Mock(headers={"USER-AGENT": "Mock/1.0"}, version=(1, 1)) environ = {"SPAM": "EGGS"} response = mock.Mock(headers={"CONTENT-LENGTH": 123}) transport = mock.Mock() transport.get_extra_info.return_value = ("127.0.0.2", 1234) access_logger.log(message, environ, response, transport, 0.0) assert False == mock_logger.error.called expected = 'Mock/1.0 123 EGGS -' mock_logger.info.assert_called_with(expected) def test_logger_no_message_and_environ(): mock_logger = mock.Mock() mock_transport = mock.Mock() mock_transport.get_extra_info.return_value = ("127.0.0.3", 0) access_logger = helpers.AccessLogger(mock_logger, "%r %{FOOBAR}e") access_logger.log(None, None, None, mock_transport, 0.0) mock_logger.info.assert_called_with("- -") def test_reify(): class A: @helpers.reify def prop(self): return 1 a = A() assert 1 == a.prop def test_reify_class(): class A: @helpers.reify def prop(self): """Docstring.""" return 1 assert isinstance(A.prop, helpers.reify) assert 'Docstring.' == A.prop.__doc__ def test_reify_assignment(): class A: @helpers.reify def prop(self): return 1 a = A() with pytest.raises(AttributeError): a.prop = 123 def test_requote_uri_with_unquoted_percents(): # Ensure we handle unquoted percent signs in redirects. bad_uri = 'http://example.com/fiz?buz=%ppicture' quoted = 'http://example.com/fiz?buz=%25ppicture' assert quoted == helpers.requote_uri(bad_uri) def test_requote_uri_properly_requotes(): # Ensure requoting doesn't break expectations. quoted = 'http://example.com/fiz?buz=%25ppicture' assert quoted == helpers.requote_uri(quoted) aiohttp-0.20.2/tests/test_client_request.py0000664000175000017500000010115112634604626021640 0ustar andrewandrew00000000000000# coding: utf-8 import asyncio import gc import inspect import io import re import unittest import unittest.mock import urllib.parse import zlib from http.cookies import SimpleCookie import pytest import aiohttp from aiohttp import BaseConnector from aiohttp.client_reqrep import ClientRequest, ClientResponse from aiohttp.multidict import CIMultiDict, CIMultiDictProxy, upstr import os.path @pytest.yield_fixture def make_request(loop): request = None def maker(*args, **kwargs): nonlocal request request = ClientRequest(*args, loop=loop, **kwargs) return request yield maker if request is not None: loop.run_until_complete(request.close()) def test_method1(make_request): req = make_request('get', 'http://python.org/') assert req.method == 'GET' def test_method2(make_request): req = make_request('head', 'http://python.org/') assert req.method == 'HEAD' def test_method3(make_request): req = make_request('HEAD', 'http://python.org/') assert req.method == 'HEAD' def test_version_1_0(make_request): req = make_request('get', 'http://python.org/', version='1.0') assert req.version == (1, 0) def test_version_default(make_request): req = make_request('get', 'http://python.org/') assert req.version == (1, 1) def test_version_err(make_request): with pytest.raises(ValueError): make_request('get', 'http://python.org/', version='1.c') def test_host_port_default_http(make_request): 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): req = make_request('get', 'https://python.org/') assert req.host == 'python.org' assert req.port == 443 assert req.ssl def test_host_port_nondefault_http(make_request): req = make_request('get', 'http://python.org:960/') assert req.host == 'python.org' assert req.port == 960 assert not req.ssl def test_host_port_nondefault_https(make_request): req = make_request('get', 'https://python.org:960/') assert req.host == 'python.org' assert req.port == 960 assert req.ssl def test_host_port_default_ws(make_request): req = make_request('get', 'ws://python.org/') assert req.host == 'python.org' assert req.port == 80 assert not req.ssl def test_host_port_default_wss(make_request): req = make_request('get', 'wss://python.org/') assert req.host == 'python.org' assert req.port == 443 assert req.ssl def test_host_port_nondefault_ws(make_request): req = make_request('get', 'ws://python.org:960/') assert req.host == 'python.org' assert req.port == 960 assert not req.ssl def test_host_port_nondefault_wss(make_request): req = make_request('get', 'wss://python.org:960/') assert req.host == 'python.org' assert req.port == 960 assert req.ssl def test_host_port_err(make_request): with pytest.raises(ValueError): make_request('get', 'http://python.org:123e/') def test_hostname_err(make_request): with pytest.raises(ValueError): make_request('get', 'http://:8080/') def test_host_header_host_without_port(make_request): req = make_request('get', 'http://python.org/') assert req.headers['HOST'] == 'python.org' def test_host_header_host_with_default_port(make_request): req = make_request('get', 'http://python.org:80/') assert req.headers['HOST'] == 'python.org:80' def test_host_header_host_with_nondefault_port(make_request): req = make_request('get', 'http://python.org:99/') assert req.headers['HOST'] == 'python.org:99' def test_host_header_explicit_host(make_request): 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): req = make_request('get', 'http://python.org/', headers={'host': 'example.com:99'}) assert req.headers['HOST'] == 'example.com:99' def test_default_loop(loop): asyncio.set_event_loop(loop) req = ClientRequest('get', 'http://python.org/') assert req.loop is loop def test_default_headers_useragent(make_request): 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): req = make_request('get', 'http://python.org/', headers={'user-agent': 'my custom agent'}) assert 'USER-Agent' in req.headers assert 'my custom agent' == req.headers['User-Agent'] def test_skip_default_useragent_header(make_request): req = make_request('get', 'http://python.org/', skip_auto_headers=set([upstr('user-agent')])) assert 'User-Agent' not in req.headers def test_headers(make_request): req = make_request('get', 'http://python.org/', headers={'Content-Type': 'text/plain'}) assert 'CONTENT-TYPE' in req.headers assert req.headers['CONTENT-TYPE'] == 'text/plain' assert req.headers['ACCEPT-ENCODING'] == 'gzip, deflate' def test_headers_list(make_request): req = make_request('get', '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): req = make_request('get', 'http://python.org/', headers={'ACCEPT-ENCODING': 'deflate'}) assert req.headers['ACCEPT-ENCODING'] == 'deflate' def test_invalid_url(make_request): with pytest.raises(ValueError): make_request('get', 'hiwpefhipowhefopw') def test_invalid_idna(make_request): with pytest.raises(ValueError): make_request('get', 'http://\u2061owhefopw.com') def test_no_path(make_request): req = make_request('get', 'http://python.org') assert '/' == req.path def test_ipv6_default_http_port(make_request): 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): req = make_request('get', 'https://[2001:db8::1]/') assert req.host == '2001:db8::1' assert req.port == 443 assert req.ssl def test_ipv6_nondefault_http_port(make_request): req = make_request('get', 'http://[2001:db8::1]:960/') assert req.host == '2001:db8::1' assert req.port == 960 assert not req.ssl def test_ipv6_nondefault_https_port(make_request): req = make_request('get', 'https://[2001:db8::1]:960/') assert req.host == '2001:db8::1' assert req.port == 960 assert req.ssl def test_basic_auth(make_request): req = make_request('get', 'http://python.org', auth=aiohttp.helpers.BasicAuth('nkim', '1234')) assert 'AUTHORIZATION' in req.headers assert 'Basic bmtpbToxMjM0' == req.headers['AUTHORIZATION'] def test_basic_auth_utf8(make_request): req = make_request('get', 'http://python.org', auth=aiohttp.helpers.BasicAuth('nkim', 'Ñекрет', 'utf-8')) assert 'AUTHORIZATION' in req.headers assert 'Basic bmtpbTrRgdC10LrRgNC10YI=' == req.headers['AUTHORIZATION'] def test_basic_auth_tuple_deprecated(make_request, warning): with warning(DeprecationWarning): req = make_request('get', 'http://python.org', auth=('nkim', '1234')) assert 'AUTHORIZATION' in req.headers assert 'Basic bmtpbToxMjM0' == req.headers['AUTHORIZATION'] def test_basic_auth_from_url(make_request): req = make_request('get', 'http://nkim:1234@python.org') assert 'AUTHORIZATION' in req.headers assert 'Basic bmtpbToxMjM0' == req.headers['AUTHORIZATION'] assert 'python.org' == req.netloc def test_basic_auth_from_url_overriden(make_request): req = make_request('get', 'http://garbage@python.org', auth=aiohttp.BasicAuth('nkim', '1234')) assert 'AUTHORIZATION' in req.headers assert 'Basic bmtpbToxMjM0' == req.headers['AUTHORIZATION'] assert 'python.org' == req.netloc def test_path_is_not_double_encoded1(make_request): req = make_request('get', "http://0.0.0.0/get/test case") assert req.path == "/get/test%20case" def test_path_is_not_double_encoded2(make_request): req = make_request('get', "http://0.0.0.0/get/test%2fcase") assert req.path == "/get/test%2fcase" def test_path_is_not_double_encoded3(make_request): req = make_request('get', "http://0.0.0.0/get/test%20case") assert req.path == "/get/test%20case" def test_path_safe_chars_preserved(make_request): req = make_request('get', "http://0.0.0.0/get/%:=") assert req.path == "/get/%:=" def test_params_are_added_before_fragment1(make_request): req = make_request('GET', "http://example.com/path#fragment", params={"a": "b"}) assert req.path == "/path?a=b#fragment" def test_params_are_added_before_fragment2(make_request): req = make_request('GET', "http://example.com/path?key=value#fragment", params={"a": "b"}) assert req.path == "/path?key=value&a=b#fragment" def test_cookies(make_request): req = make_request('get', 'http://test.com/path', cookies={'cookie1': 'val1'}) assert 'COOKIE' in req.headers assert 'cookie1=val1' == req.headers['COOKIE'] def test_cookies_merge_with_headers(make_request): req = make_request('get', 'http://test.com/path', headers={'cookie': 'cookie1=val1'}, cookies={'cookie2': 'val2'}) assert 'cookie1=val1; cookie2=val2' == req.headers['COOKIE'] def test_unicode_get1(make_request): req = make_request('get', 'http://python.org', params={'foo': 'f\xf8\xf8'}) assert '/?foo=f%C3%B8%C3%B8' == req.path def test_unicode_get2(make_request): req = make_request('', 'http://python.org', params={'f\xf8\xf8': 'f\xf8\xf8'}) assert '/?f%C3%B8%C3%B8=f%C3%B8%C3%B8' == req.path def test_unicode_get3(make_request): req = make_request('', 'http://python.org', params={'foo': 'foo'}) assert '/?foo=foo' == req.path def test_unicode_get4(make_request): def join(*suffix): return urllib.parse.urljoin('http://python.org/', '/'.join(suffix)) req = make_request('', join('\xf8'), params={'foo': 'foo'}) assert '/%C3%B8?foo=foo' == req.path def test_query_multivalued_param(make_request): for meth in ClientRequest.ALL_METHODS: req = make_request( meth, 'http://python.org', params=(('test', 'foo'), ('test', 'baz'))) assert req.path == '/?test=foo&test=baz' def test_query_str_param(make_request): for meth in ClientRequest.ALL_METHODS: req = make_request(meth, 'http://python.org', params='test=foo') assert req.path == '/?test=foo' def test_query_bytes_param_raises(make_request): for meth in ClientRequest.ALL_METHODS: with pytest.raises(TypeError) as ctx: make_request(meth, 'http://python.org', params=b'test=foo') assert re.match('not a valid non-string.*or mapping', str(ctx.value)) def test_query_str_param_is_not_encoded(make_request): for meth in ClientRequest.ALL_METHODS: req = make_request(meth, 'http://python.org', params='test=f+oo') assert req.path == '/?test=f+oo' def test_params_update_path_and_url(make_request): req = make_request('get', 'http://python.org', params=(('test', 'foo'), ('test', 'baz'))) assert req.path == '/?test=foo&test=baz' assert req.url == 'http://python.org/?test=foo&test=baz' class TestClientRequest(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) self.transport = unittest.mock.Mock() self.connection = unittest.mock.Mock() self.protocol = unittest.mock.Mock() self.protocol.writer.drain.return_value = () self.stream = aiohttp.StreamParser(loop=self.loop) self.connector = BaseConnector(loop=self.loop) def tearDown(self): self.connector.close() try: self.loop.stop() self.loop.run_forever() except RuntimeError: # loop is already closed pass self.loop.close() gc.collect() def test_no_content_length(self): req = ClientRequest('get', 'http://python.org', loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('0', req.headers.get('CONTENT-LENGTH')) self.loop.run_until_complete(req.close()) resp.close() def test_no_content_length2(self): req = ClientRequest('head', 'http://python.org', loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('0', req.headers.get('CONTENT-LENGTH')) self.loop.run_until_complete(req.close()) resp.close() def test_content_type_auto_header_get(self): req = ClientRequest('get', 'http://python.org', loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertNotIn('CONTENT-TYPE', req.headers) resp.close() def test_content_type_auto_header_form(self): req = ClientRequest('post', 'http://python.org', data={'hey': 'you'}, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('application/x-www-form-urlencoded', req.headers.get('CONTENT-TYPE')) resp.close() def test_content_type_auto_header_bytes(self): req = ClientRequest('post', 'http://python.org', data=b'hey you', loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('application/octet-stream', req.headers.get('CONTENT-TYPE')) resp.close() def test_content_type_skip_auto_header_bytes(self): req = ClientRequest('post', 'http://python.org', data=b'hey you', skip_auto_headers={'CONTENT-TYPE'}, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertNotIn('CONTENT-TYPE', req.headers) resp.close() def test_content_type_skip_auto_header_form(self): req = ClientRequest('post', 'http://python.org', data={'hey': 'you'}, loop=self.loop, skip_auto_headers={'CONTENT-TYPE'}) resp = req.send(self.transport, self.protocol) self.assertNotIn('CONTENT-TYPE', req.headers) resp.close() def test_content_type_auto_header_content_length_no_skip(self): req = ClientRequest('get', 'http://python.org', data=io.BytesIO(b'hey'), skip_auto_headers={'CONTENT-LENGTH'}, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual(req.headers.get('CONTENT-LENGTH'), '3') resp.close() def test_post_data(self): for meth in ClientRequest.POST_METHODS: req = ClientRequest( meth, 'http://python.org/', data={'life': '42'}, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('/', req.path) self.assertEqual(b'life=42', req.body) self.assertEqual('application/x-www-form-urlencoded', req.headers['CONTENT-TYPE']) self.loop.run_until_complete(req.close()) resp.close() @unittest.mock.patch( 'aiohttp.client_reqrep.ClientRequest.update_body_from_data') def test_pass_falsy_data(self, _): req = ClientRequest( 'post', 'http://python.org/', data={}, loop=self.loop) req.update_body_from_data.assert_called_once_with({}, frozenset()) self.loop.run_until_complete(req.close()) def test_get_with_data(self): for meth in ClientRequest.GET_METHODS: req = ClientRequest( meth, 'http://python.org/', data={'life': '42'}, loop=self.loop) self.assertEqual('/', req.path) self.assertEqual(b'life=42', req.body) self.loop.run_until_complete(req.close()) def test_bytes_data(self): for meth in ClientRequest.POST_METHODS: req = ClientRequest( meth, 'http://python.org/', data=b'binary data', loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('/', req.path) self.assertEqual(b'binary data', req.body) self.assertEqual('application/octet-stream', req.headers['CONTENT-TYPE']) self.loop.run_until_complete(req.close()) resp.close() @unittest.mock.patch('aiohttp.client_reqrep.aiohttp') def test_content_encoding(self, m_http): req = ClientRequest('get', 'http://python.org/', compress='deflate', loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual(req.headers['TRANSFER-ENCODING'], 'chunked') self.assertEqual(req.headers['CONTENT-ENCODING'], 'deflate') m_http.Request.return_value\ .add_compression_filter.assert_called_with('deflate') self.loop.run_until_complete(req.close()) resp.close() @unittest.mock.patch('aiohttp.client_reqrep.aiohttp') def test_content_encoding_header(self, m_http): req = ClientRequest( 'get', 'http://python.org/', headers={'Content-Encoding': 'deflate'}, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual(req.headers['TRANSFER-ENCODING'], 'chunked') self.assertEqual(req.headers['CONTENT-ENCODING'], 'deflate') m_http.Request.return_value\ .add_compression_filter.assert_called_with('deflate') m_http.Request.return_value\ .add_chunking_filter.assert_called_with(8192) self.loop.run_until_complete(req.close()) resp.close() def test_chunked(self): req = ClientRequest( 'get', 'http://python.org/', headers={'TRANSFER-ENCODING': 'gzip'}, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('gzip', req.headers['TRANSFER-ENCODING']) self.loop.run_until_complete(req.close()) resp.close() req = ClientRequest( 'get', 'http://python.org/', headers={'Transfer-encoding': 'chunked'}, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('chunked', req.headers['TRANSFER-ENCODING']) self.loop.run_until_complete(req.close()) resp.close() @unittest.mock.patch('aiohttp.client_reqrep.aiohttp') def test_chunked_explicit(self, m_http): req = ClientRequest( 'get', 'http://python.org/', chunked=True, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('chunked', req.headers['TRANSFER-ENCODING']) m_http.Request.return_value\ .add_chunking_filter.assert_called_with(8192) self.loop.run_until_complete(req.close()) resp.close() @unittest.mock.patch('aiohttp.client_reqrep.aiohttp') def test_chunked_explicit_size(self, m_http): req = ClientRequest( 'get', 'http://python.org/', chunked=1024, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('chunked', req.headers['TRANSFER-ENCODING']) m_http.Request.return_value\ .add_chunking_filter.assert_called_with(1024) self.loop.run_until_complete(req.close()) resp.close() def test_chunked_length(self): req = ClientRequest( 'get', 'http://python.org/', headers={'CONTENT-LENGTH': '1000'}, chunked=1024, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual(req.headers['TRANSFER-ENCODING'], 'chunked') self.assertNotIn('CONTENT-LENGTH', req.headers) self.loop.run_until_complete(req.close()) resp.close() def test_file_upload_not_chunked(self): here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: req = ClientRequest( 'post', 'http://python.org/', data=f, loop=self.loop) self.assertFalse(req.chunked) self.assertEqual(req.headers['CONTENT-LENGTH'], str(os.path.getsize(fname))) self.loop.run_until_complete(req.close()) def test_precompressed_data_stays_intact(self): data = zlib.compress(b'foobar') req = ClientRequest( 'post', 'http://python.org/', data=data, headers={'CONTENT-ENCODING': 'deflate'}, compress=False, loop=self.loop) self.assertFalse(req.compress) self.assertFalse(req.chunked) self.assertEqual(req.headers['CONTENT-ENCODING'], 'deflate') self.loop.run_until_complete(req.close()) def test_file_upload_not_chunked_seek(self): here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: f.seek(100) req = ClientRequest( 'post', 'http://python.org/', data=f, loop=self.loop) self.assertEqual(req.headers['CONTENT-LENGTH'], str(os.path.getsize(fname) - 100)) self.loop.run_until_complete(req.close()) def test_file_upload_force_chunked(self): here = os.path.dirname(__file__) fname = os.path.join(here, 'sample.key') with open(fname, 'rb') as f: req = ClientRequest( 'post', 'http://python.org/', data=f, chunked=True, loop=self.loop) self.assertTrue(req.chunked) self.assertNotIn('CONTENT-LENGTH', req.headers) self.loop.run_until_complete(req.close()) def test_expect100(self): req = ClientRequest('get', 'http://python.org/', expect100=True, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('100-continue', req.headers['EXPECT']) self.assertIsNotNone(req._continue) req.terminate() resp.close() def test_expect_100_continue_header(self): req = ClientRequest('get', 'http://python.org/', headers={'expect': '100-continue'}, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('100-continue', req.headers['EXPECT']) self.assertIsNotNone(req._continue) req.terminate() resp.close() def test_data_stream(self): def gen(): yield b'binary data' return b' result' req = ClientRequest( 'POST', 'http://python.org/', data=gen(), loop=self.loop) self.assertTrue(req.chunked) self.assertTrue(inspect.isgenerator(req.body)) self.assertEqual(req.headers['TRANSFER-ENCODING'], 'chunked') resp = req.send(self.transport, self.protocol) self.assertIsInstance(req._writer, asyncio.Future) self.loop.run_until_complete(resp.wait_for_close()) self.assertIsNone(req._writer) self.assertEqual( self.transport.write.mock_calls[-2:], [unittest.mock.call(b'12\r\nbinary data result\r\n'), unittest.mock.call(b'0\r\n\r\n')]) self.loop.run_until_complete(req.close()) def test_data_file(self): req = ClientRequest( 'POST', 'http://python.org/', data=io.BufferedReader(io.BytesIO(b'*' * 2)), loop=self.loop) self.assertTrue(req.chunked) self.assertTrue(isinstance(req.body, io.IOBase)) self.assertEqual(req.headers['TRANSFER-ENCODING'], 'chunked') resp = req.send(self.transport, self.protocol) self.assertIsInstance(req._writer, asyncio.Future) self.loop.run_until_complete(resp.wait_for_close()) self.assertIsNone(req._writer) self.assertEqual( self.transport.write.mock_calls[-2:], [unittest.mock.call(b'2\r\n' + b'*' * 2 + b'\r\n'), unittest.mock.call(b'0\r\n\r\n')]) self.loop.run_until_complete(req.close()) def test_data_stream_exc(self): fut = asyncio.Future(loop=self.loop) def gen(): yield b'binary data' yield from fut req = ClientRequest( 'POST', 'http://python.org/', data=gen(), loop=self.loop) self.assertTrue(req.chunked) self.assertTrue(inspect.isgenerator(req.body)) self.assertEqual(req.headers['TRANSFER-ENCODING'], 'chunked') @asyncio.coroutine def exc(): yield from asyncio.sleep(0.01, loop=self.loop) fut.set_exception(ValueError) asyncio.async(exc(), loop=self.loop) resp = req.send(self.transport, self.protocol) resp._connection = self.connection self.loop.run_until_complete(req._writer) self.assertTrue(self.connection.close.called) self.assertTrue(self.protocol.set_exception.called) self.loop.run_until_complete(req.close()) def test_data_stream_not_bytes(self): @asyncio.coroutine def gen(): yield object() req = ClientRequest( 'POST', 'http://python.org/', data=gen(), loop=self.loop) resp = req.send(self.transport, self.protocol) self.loop.run_until_complete(req._writer) self.assertTrue(self.protocol.set_exception.called) self.loop.run_until_complete(req.close()) resp.close() def test_data_stream_exc_chain(self): fut = asyncio.Future(loop=self.loop) def gen(): yield from fut req = ClientRequest( 'POST', 'http://python.org/', data=gen(), loop=self.loop) inner_exc = ValueError() @asyncio.coroutine def exc(): yield from asyncio.sleep(0.01, loop=self.loop) fut.set_exception(inner_exc) asyncio.async(exc(), loop=self.loop) resp = req.send(self.transport, self.protocol) resp._connection = self.connection self.loop.run_until_complete(req._writer) self.assertTrue(self.connection.close.called) self.assertTrue(self.protocol.set_exception.called) outer_exc = self.protocol.set_exception.call_args[0][0] self.assertIsInstance(outer_exc, aiohttp.ClientRequestError) self.assertIs(inner_exc, outer_exc.__context__) self.assertIs(inner_exc, outer_exc.__cause__) self.loop.run_until_complete(req.close()) def test_data_stream_continue(self): def gen(): yield b'binary data' return b' result' req = ClientRequest( 'POST', 'http://python.org/', data=gen(), expect100=True, loop=self.loop) self.assertTrue(req.chunked) self.assertTrue(inspect.isgenerator(req.body)) def coro(): yield from asyncio.sleep(0.0001, loop=self.loop) req._continue.set_result(1) asyncio.async(coro(), loop=self.loop) resp = req.send(self.transport, self.protocol) self.loop.run_until_complete(req._writer) self.assertEqual( self.transport.write.mock_calls[-2:], [unittest.mock.call(b'12\r\nbinary data result\r\n'), unittest.mock.call(b'0\r\n\r\n')]) self.loop.run_until_complete(req.close()) resp.close() def test_data_continue(self): req = ClientRequest( 'POST', 'http://python.org/', data=b'data', expect100=True, loop=self.loop) def coro(): yield from asyncio.sleep(0.0001, loop=self.loop) req._continue.set_result(1) asyncio.async(coro(), loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual(1, len(self.transport.write.mock_calls)) self.loop.run_until_complete(req._writer) self.assertEqual( self.transport.write.mock_calls[-1], unittest.mock.call(b'data')) self.loop.run_until_complete(req.close()) resp.close() def test_close(self): @asyncio.coroutine def gen(): yield from asyncio.sleep(0.00001, loop=self.loop) return b'result' req = ClientRequest( 'POST', 'http://python.org/', data=gen(), loop=self.loop) resp = req.send(self.transport, self.protocol) self.loop.run_until_complete(req.close()) self.assertEqual( self.transport.write.mock_calls[-2:], [unittest.mock.call(b'6\r\nresult\r\n'), unittest.mock.call(b'0\r\n\r\n')]) self.loop.run_until_complete(req.close()) resp.close() def test_custom_response_class(self): class CustomResponse(ClientResponse): def read(self, decode=False): return 'customized!' req = ClientRequest( 'GET', 'http://python.org/', response_class=CustomResponse, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual('customized!', resp.read()) self.loop.run_until_complete(req.close()) resp.close() def test_terminate(self): req = ClientRequest('get', 'http://python.org', loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertIsNotNone(req._writer) writer = req._writer = unittest.mock.Mock() req.terminate() self.assertIsNone(req._writer) writer.cancel.assert_called_with() resp.close() def test_terminate_with_closed_loop(self): if not hasattr(self.loop, 'is_closed'): self.skipTest("Required asyncio 3.4.2+") req = ClientRequest('get', 'http://python.org', loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertIsNotNone(req._writer) writer = req._writer = unittest.mock.Mock() self.loop.close() req.terminate() self.assertIsNone(req._writer) self.assertFalse(writer.cancel.called) resp.close() def test_terminate_without_writer(self): req = ClientRequest('get', 'http://python.org', loop=self.loop) self.assertIsNone(req._writer) req.terminate() self.assertIsNone(req._writer) def test_custom_req_rep(self): @asyncio.coroutine def go(): conn = None class CustomResponse(ClientResponse): @asyncio.coroutine def start(self, connection, read_until_eof=False): nonlocal conn conn = connection self.status = 123 self.reason = 'Test OK' self.headers = CIMultiDictProxy(CIMultiDict()) self.cookies = SimpleCookie() return called = False class CustomRequest(ClientRequest): def send(self, writer, reader): resp = self.response_class(self.method, self.url, self.host, writer=self._writer, continue100=self._continue) resp._post_init(self.loop) self.response = resp nonlocal called called = True return resp @asyncio.coroutine def create_connection(req): self.assertIsInstance(req, CustomRequest) return self.transport, self.protocol self.connector._create_connection = create_connection resp = yield from aiohttp.request('get', 'http://example.com/path/to', request_class=CustomRequest, response_class=CustomResponse, connector=self.connector, loop=self.loop) self.assertIsInstance(resp, CustomResponse) self.assertTrue(called) resp.close() conn.close() self.loop.run_until_complete(go()) aiohttp-0.20.2/tests/test_web_request.py0000664000175000017500000001475112614354376021152 0ustar andrewandrew00000000000000import pytest from unittest import mock from aiohttp.signals import Signal from aiohttp.web import Request from aiohttp.multidict import MultiDict, CIMultiDict from aiohttp.protocol import HttpVersion from aiohttp.protocol import RawRequestMessage @pytest.fixture def make_request(): def maker(method, path, headers=CIMultiDict(), *, version=HttpVersion(1, 1), closing=False, sslcontext=None, secure_proxy_ssl_header=None): if version < HttpVersion(1, 1): closing = True app = mock.Mock() app._debug = False app.on_response_prepare = Signal(app) message = RawRequestMessage(method, path, version, headers, closing, False) payload = mock.Mock() transport = mock.Mock() def get_extra_info(key): if key == 'sslcontext': return sslcontext else: return None transport.get_extra_info.side_effect = get_extra_info writer = mock.Mock() reader = mock.Mock() req = Request(app, message, payload, transport, reader, writer, secure_proxy_ssl_header=secure_proxy_ssl_header) assert req.app is app assert req.content is payload assert req.transport is transport return req return maker def test_ctor(make_request, warning): req = make_request('GET', '/path/to?a=1&b=2') assert 'GET' == req.method assert HttpVersion(1, 1) == req.version assert req.host is None assert '/path/to?a=1&b=2' == req.path_qs assert '/path/to' == req.path assert 'a=1&b=2' == req.query_string get = req.GET assert MultiDict([('a', '1'), ('b', '2')]) == get # second call should return the same object assert get is req.GET with warning(DeprecationWarning): req.payload assert req.keep_alive def test_doubleslashes(make_request): req = make_request('GET', '//foo/') assert '//foo/' == req.path def test_POST(make_request): req = make_request('POST', '/') with pytest.raises(RuntimeError): req.POST marker = object() req._post = marker assert req.POST is marker assert req.POST is marker def test_content_type_not_specified(make_request): req = make_request('Get', '/') assert 'application/octet-stream' == req.content_type def test_content_type_from_spec(make_request): req = make_request('Get', '/', CIMultiDict([('CONTENT-TYPE', 'application/json')])) assert 'application/json' == req.content_type def test_content_type_from_spec_with_charset(make_request): req = make_request( 'Get', '/', CIMultiDict([('CONTENT-TYPE', 'text/html; charset=UTF-8')])) assert 'text/html' == req.content_type assert 'UTF-8' == req.charset def test_calc_content_type_on_getting_charset(make_request): req = make_request( 'Get', '/', CIMultiDict([('CONTENT-TYPE', 'text/html; charset=UTF-8')])) assert 'UTF-8' == req.charset assert 'text/html' == req.content_type def test_urlencoded_querystring(make_request): req = make_request('GET', '/yandsearch?text=%D1%82%D0%B5%D0%BA%D1%81%D1%82') assert {'text': 'текÑÑ‚'} == req.GET def test_non_ascii_path(make_request): req = make_request('GET', '/путь') assert '/путь' == req.path def test_content_length(make_request): req = make_request('Get', '/', CIMultiDict([('CONTENT-LENGTH', '123')])) assert 123 == req.content_length def test_non_keepalive_on_http10(make_request): req = make_request('GET', '/', version=HttpVersion(1, 0)) assert not req.keep_alive def test_non_keepalive_on_closing(make_request): req = make_request('GET', '/', closing=True) assert not req.keep_alive @pytest.mark.run_loop def test_call_POST_on_GET_request(make_request): req = make_request('GET', '/') ret = yield from req.post() assert CIMultiDict() == ret @pytest.mark.run_loop def test_call_POST_on_weird_content_type(make_request): req = make_request( 'POST', '/', headers=CIMultiDict({'CONTENT-TYPE': 'something/weird'})) ret = yield from req.post() assert CIMultiDict() == ret @pytest.mark.run_loop def test_call_POST_twice(make_request): req = make_request('GET', '/') ret1 = yield from req.post() ret2 = yield from req.post() assert ret1 is ret2 def test_no_request_cookies(make_request): req = make_request('GET', '/') assert req.cookies == {} cookies = req.cookies assert cookies is req.cookies def test_request_cookie(make_request): headers = CIMultiDict(COOKIE='cookie1=value1; cookie2=value2') req = make_request('GET', '/', headers=headers) assert req.cookies == {'cookie1': 'value1', 'cookie2': 'value2'} def test_request_cookie__set_item(make_request): headers = CIMultiDict(COOKIE='name=value') req = make_request('GET', '/', headers=headers) assert req.cookies == {'name': 'value'} with pytest.raises(TypeError): req.cookies['my'] = 'value' def test_match_info(make_request): req = make_request('GET', '/') assert req.match_info is None match = {'a': 'b'} req._match_info = match assert match is req.match_info def test_request_is_dict(make_request): req = make_request('GET', '/') assert isinstance(req, dict) req['key'] = 'value' assert 'value' == req['key'] def test_copy(make_request): req = make_request('GET', '/') with pytest.raises(NotImplementedError): req.copy() def test___repr__(make_request): req = make_request('GET', '/path/to') assert "" == repr(req) def test_http_scheme(make_request): req = make_request('GET', '/') assert "http" == req.scheme def test_https_scheme_by_ssl_transport(make_request): req = make_request('GET', '/', sslcontext=True) assert "https" == req.scheme def test_https_scheme_by_secure_proxy_ssl_header(make_request): req = make_request('GET', '/', secure_proxy_ssl_header=('X-HEADER', '1'), headers=CIMultiDict({'X-HEADER': '1'})) assert "https" == req.scheme def test_https_scheme_by_secure_proxy_ssl_header_false_test(make_request): req = make_request('GET', '/', secure_proxy_ssl_header=('X-HEADER', '1'), headers=CIMultiDict({'X-HEADER': '0'})) assert "http" == req.scheme aiohttp-0.20.2/tests/test_connector.py0000664000175000017500000006665412622421715020617 0ustar andrewandrew00000000000000"""Tests of http client with custom Connector""" import asyncio import http.cookies import gc import socket import unittest import ssl import tempfile import shutil import os.path from unittest import mock import aiohttp from aiohttp import web from aiohttp import client from aiohttp.client import ClientResponse from aiohttp.connector import Connection class TestBaseConnector(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) self.transport = unittest.mock.Mock() self.stream = aiohttp.StreamParser() self.response = ClientResponse('get', 'http://base-conn.org') self.response._post_init(self.loop) def tearDown(self): self.response.close() self.loop.close() gc.collect() def test_del(self): conn = aiohttp.BaseConnector(loop=self.loop) transp = unittest.mock.Mock() conn._conns['a'] = [(transp, 'proto', 123)] conns_impl = conn._conns exc_handler = unittest.mock.Mock() self.loop.set_exception_handler(exc_handler) with self.assertWarns(ResourceWarning): del conn gc.collect() self.assertFalse(conns_impl) transp.close.assert_called_with() msg = {'connector': unittest.mock.ANY, # conn was deleted 'connections': unittest.mock.ANY, 'message': 'Unclosed connector'} if self.loop.get_debug(): msg['source_traceback'] = unittest.mock.ANY exc_handler.assert_called_with(self.loop, msg) def test_del_with_scheduled_cleanup(self): conn = aiohttp.BaseConnector(loop=self.loop, keepalive_timeout=0.01) transp = unittest.mock.Mock() conn._conns['a'] = [(transp, 'proto', 123)] conns_impl = conn._conns conn._start_cleanup_task() exc_handler = unittest.mock.Mock() self.loop.set_exception_handler(exc_handler) with self.assertWarns(ResourceWarning): del conn yield from asyncio.sleep(0.01) gc.collect() self.assertFalse(conns_impl) transp.close.assert_called_with() msg = {'connector': unittest.mock.ANY, # conn was deleted 'message': 'Unclosed connector'} if self.loop.get_debug(): msg['source_traceback'] = unittest.mock.ANY exc_handler.assert_called_with(self.loop, msg) def test_del_with_closed_loop(self): conn = aiohttp.BaseConnector(loop=self.loop) transp = unittest.mock.Mock() conn._conns['a'] = [(transp, 'proto', 123)] conns_impl = conn._conns conn._start_cleanup_task() exc_handler = unittest.mock.Mock() self.loop.set_exception_handler(exc_handler) self.loop.close() with self.assertWarns(ResourceWarning): del conn gc.collect() self.assertFalse(conns_impl) self.assertFalse(transp.close.called) self.assertTrue(exc_handler.called) def test_del_empty_conector(self): conn = aiohttp.BaseConnector(loop=self.loop) exc_handler = unittest.mock.Mock() self.loop.set_exception_handler(exc_handler) del conn self.assertFalse(exc_handler.called) def test_create_conn(self): def go(): conn = aiohttp.BaseConnector(loop=self.loop) with self.assertRaises(NotImplementedError): yield from conn._create_connection(object()) self.loop.run_until_complete(go()) @unittest.mock.patch('aiohttp.connector.asyncio') def test_ctor_loop(self, asyncio): session = aiohttp.BaseConnector() self.assertIs(session._loop, asyncio.get_event_loop.return_value) def test_close(self): tr = unittest.mock.Mock() conn = aiohttp.BaseConnector(loop=self.loop) self.assertFalse(conn.closed) conn._conns[1] = [(tr, object(), object())] conn.close() self.assertFalse(conn._conns) self.assertTrue(tr.close.called) self.assertTrue(conn.closed) def test_get(self): conn = aiohttp.BaseConnector(loop=self.loop) self.assertEqual(conn._get(1), (None, None)) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() conn._conns[1] = [(tr, proto, self.loop.time())] self.assertEqual(conn._get(1), (tr, proto)) conn.close() def test_get_expired(self): conn = aiohttp.BaseConnector(loop=self.loop) self.assertEqual(conn._get(1), (None, None)) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() conn._conns[1] = [(tr, proto, self.loop.time() - 1000)] self.assertEqual(conn._get(1), (None, None)) self.assertFalse(conn._conns) conn.close() def test_release(self): self.loop.time = mock.Mock(return_value=10) conn = aiohttp.BaseConnector(loop=self.loop) conn._start_cleanup_task = unittest.mock.Mock() req = unittest.mock.Mock() resp = req.response = unittest.mock.Mock() resp._should_close = False tr, proto = unittest.mock.Mock(), unittest.mock.Mock() key = 1 conn._acquired[key].add(tr) conn._release(key, req, tr, proto) self.assertEqual(conn._conns[1][0], (tr, proto, 10)) self.assertTrue(conn._start_cleanup_task.called) conn.close() def test_release_close(self): with self.assertWarns(DeprecationWarning): conn = aiohttp.BaseConnector(share_cookies=True, loop=self.loop) req = unittest.mock.Mock() resp = unittest.mock.Mock() resp.message.should_close = True req.response = resp cookies = resp.cookies = http.cookies.SimpleCookie() cookies['c1'] = 'cookie1' cookies['c2'] = 'cookie2' tr, proto = unittest.mock.Mock(), unittest.mock.Mock() key = 1 conn._acquired[key].add(tr) conn._release(key, req, tr, proto) self.assertFalse(conn._conns) self.assertTrue(tr.close.called) def test_get_pop_empty_conns(self): # see issue #473 conn = aiohttp.BaseConnector(loop=self.loop) key = ('127.0.0.1', 80, False) conn._conns[key] = [] tr, proto = conn._get(key) self.assertEqual((None, None), (tr, proto)) self.assertFalse(conn._conns) def test_release_close_do_not_add_to_pool(self): # see issue #473 conn = aiohttp.BaseConnector(loop=self.loop) req = unittest.mock.Mock() resp = unittest.mock.Mock() resp.message.should_close = True req.response = resp key = ('127.0.0.1', 80, False) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() conn._acquired[key].add(tr) conn._release(key, req, tr, proto) self.assertFalse(conn._conns) def test_release_close_do_not_delete_existing_connections(self): key = ('127.0.0.1', 80, False) tr1, proto1 = unittest.mock.Mock(), unittest.mock.Mock() with self.assertWarns(DeprecationWarning): conn = aiohttp.BaseConnector(share_cookies=True, loop=self.loop) conn._conns[key] = [(tr1, proto1, 1)] req = unittest.mock.Mock() resp = unittest.mock.Mock() resp.message.should_close = True req.response = resp tr, proto = unittest.mock.Mock(), unittest.mock.Mock() conn._acquired[key].add(tr1) conn._release(key, req, tr, proto) self.assertEqual(conn._conns[key], [(tr1, proto1, 1)]) self.assertTrue(tr.close.called) conn.close() def test_release_not_started(self): self.loop.time = mock.Mock(return_value=10) conn = aiohttp.BaseConnector(loop=self.loop) req = unittest.mock.Mock() req.response = None tr, proto = unittest.mock.Mock(), unittest.mock.Mock() key = 1 conn._acquired[key].add(tr) conn._release(key, req, tr, proto) self.assertEqual(conn._conns, {1: [(tr, proto, 10)]}) self.assertFalse(tr.close.called) conn.close() def test_release_not_opened(self): conn = aiohttp.BaseConnector(loop=self.loop) req = unittest.mock.Mock() req.response = unittest.mock.Mock() req.response.message = None tr, proto = unittest.mock.Mock(), unittest.mock.Mock() key = 1 conn._acquired[key].add(tr) conn._release(key, req, tr, proto) self.assertTrue(tr.close.called) def test_connect(self): tr, proto = unittest.mock.Mock(), unittest.mock.Mock() proto.is_connected.return_value = True class Req: host = 'host' port = 80 ssl = False response = unittest.mock.Mock() conn = aiohttp.BaseConnector(loop=self.loop) key = ('host', 80, False) conn._conns[key] = [(tr, proto, self.loop.time())] conn._create_connection = unittest.mock.Mock() conn._create_connection.return_value = asyncio.Future(loop=self.loop) conn._create_connection.return_value.set_result((tr, proto)) connection = self.loop.run_until_complete(conn.connect(Req())) self.assertFalse(conn._create_connection.called) self.assertEqual(connection._transport, tr) self.assertEqual(connection._protocol, proto) self.assertIsInstance(connection, Connection) connection.close() def test_connect_timeout(self): conn = aiohttp.BaseConnector(loop=self.loop) conn._create_connection = unittest.mock.Mock() conn._create_connection.return_value = asyncio.Future(loop=self.loop) conn._create_connection.return_value.set_exception( asyncio.TimeoutError()) with self.assertRaises(aiohttp.ClientTimeoutError): req = unittest.mock.Mock() self.loop.run_until_complete(conn.connect(req)) def test_connect_oserr(self): conn = aiohttp.BaseConnector(loop=self.loop) conn._create_connection = unittest.mock.Mock() conn._create_connection.return_value = asyncio.Future(loop=self.loop) err = OSError(1, 'permission error') conn._create_connection.return_value.set_exception(err) with self.assertRaises(aiohttp.ClientOSError) as ctx: req = unittest.mock.Mock() self.loop.run_until_complete(conn.connect(req)) self.assertEqual(1, ctx.exception.errno) self.assertTrue(ctx.exception.strerror.startswith('Cannot connect to')) self.assertTrue(ctx.exception.strerror.endswith('[permission error]')) def test_start_cleanup_task(self): loop = unittest.mock.Mock() loop.time.return_value = 1.5 conn = aiohttp.BaseConnector(loop=loop, keepalive_timeout=10) self.assertIsNone(conn._cleanup_handle) conn._start_cleanup_task() self.assertIsNotNone(conn._cleanup_handle) loop.call_at.assert_called_with( 12, conn._cleanup) def test_cleanup(self): testset = { 1: [(unittest.mock.Mock(), unittest.mock.Mock(), 10), (unittest.mock.Mock(), unittest.mock.Mock(), 300), (None, unittest.mock.Mock(), 300)], } testset[1][0][1].is_connected.return_value = True testset[1][1][1].is_connected.return_value = False loop = unittest.mock.Mock() loop.time.return_value = 300 conn = aiohttp.BaseConnector(loop=loop) conn._conns = testset existing_handle = conn._cleanup_handle = unittest.mock.Mock() conn._cleanup() self.assertTrue(existing_handle.cancel.called) self.assertEqual(conn._conns, {}) self.assertIsNone(conn._cleanup_handle) def test_cleanup2(self): testset = {1: [(unittest.mock.Mock(), unittest.mock.Mock(), 300)]} testset[1][0][1].is_connected.return_value = True loop = unittest.mock.Mock() loop.time.return_value = 300.1 conn = aiohttp.BaseConnector(loop=loop, keepalive_timeout=10) conn._conns = testset conn._cleanup() self.assertEqual(conn._conns, testset) self.assertIsNotNone(conn._cleanup_handle) loop.call_at.assert_called_with( 310, conn._cleanup) conn.close() def test_cleanup3(self): testset = {1: [(unittest.mock.Mock(), unittest.mock.Mock(), 290.1), (unittest.mock.Mock(), unittest.mock.Mock(), 305.1)]} testset[1][0][1].is_connected.return_value = True loop = unittest.mock.Mock() loop.time.return_value = 308.5 conn = aiohttp.BaseConnector(loop=loop, keepalive_timeout=10) conn._conns = testset conn._cleanup() self.assertEqual(conn._conns, {1: [testset[1][1]]}) self.assertIsNotNone(conn._cleanup_handle) loop.call_at.assert_called_with( 316, conn._cleanup) conn.close() def test_tcp_connector_ctor(self): conn = aiohttp.TCPConnector(loop=self.loop) self.assertTrue(conn.verify_ssl) self.assertIs(conn.fingerprint, None) with self.assertWarns(DeprecationWarning): self.assertFalse(conn.resolve) self.assertFalse(conn.use_dns_cache) self.assertEqual(conn.family, 0) with self.assertWarns(DeprecationWarning): self.assertEqual(conn.resolved_hosts, {}) self.assertEqual(conn.resolved_hosts, {}) def test_tcp_connector_ctor_fingerprint_valid(self): valid = b'\xa2\x06G\xad\xaa\xf5\xd8\\J\x99^by;\x06=' conn = aiohttp.TCPConnector(loop=self.loop, fingerprint=valid) self.assertEqual(conn.fingerprint, valid) def test_tcp_connector_fingerprint_invalid(self): invalid = b'\x00' with self.assertRaises(ValueError): aiohttp.TCPConnector(loop=self.loop, fingerprint=invalid) def test_tcp_connector_clear_resolved_hosts(self): conn = aiohttp.TCPConnector(loop=self.loop) info = object() conn._cached_hosts[('localhost', 123)] = info conn._cached_hosts[('localhost', 124)] = info conn.clear_resolved_hosts('localhost', 123) self.assertEqual( conn.resolved_hosts, {('localhost', 124): info}) conn.clear_resolved_hosts('localhost', 123) self.assertEqual( conn.resolved_hosts, {('localhost', 124): info}) with self.assertWarns(DeprecationWarning): conn.clear_resolved_hosts() self.assertEqual(conn.resolved_hosts, {}) def test_tcp_connector_clear_dns_cache(self): conn = aiohttp.TCPConnector(loop=self.loop) info = object() conn._cached_hosts[('localhost', 123)] = info conn._cached_hosts[('localhost', 124)] = info conn.clear_dns_cache('localhost', 123) self.assertEqual( conn.cached_hosts, {('localhost', 124): info}) conn.clear_dns_cache('localhost', 123) self.assertEqual( conn.cached_hosts, {('localhost', 124): info}) conn.clear_dns_cache() self.assertEqual(conn.cached_hosts, {}) def test_tcp_connector_clear_dns_cache_bad_args(self): conn = aiohttp.TCPConnector(loop=self.loop) with self.assertRaises(ValueError): conn.clear_dns_cache('localhost') def test_ambigous_verify_ssl_and_ssl_context(self): with self.assertRaises(ValueError): aiohttp.TCPConnector( verify_ssl=False, ssl_context=ssl.SSLContext(ssl.PROTOCOL_SSLv23), loop=self.loop) def test_dont_recreate_ssl_context(self): conn = aiohttp.TCPConnector(loop=self.loop) ctx = conn.ssl_context self.assertIs(ctx, conn.ssl_context) def test_respect_precreated_ssl_context(self): ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) conn = aiohttp.TCPConnector(loop=self.loop, ssl_context=ctx) self.assertIs(ctx, conn.ssl_context) def test_close_twice(self): tr = unittest.mock.Mock() conn = aiohttp.BaseConnector(loop=self.loop) conn._conns[1] = [(tr, object(), object())] conn.close() self.assertFalse(conn._conns) self.assertTrue(tr.close.called) self.assertTrue(conn.closed) conn._conns = 'Invalid' # fill with garbage conn.close() self.assertTrue(conn.closed) def test_close_cancels_cleanup_handle(self): conn = aiohttp.BaseConnector(loop=self.loop) conn._start_cleanup_task() self.assertIsNotNone(conn._cleanup_handle) conn.close() self.assertIsNone(conn._cleanup_handle) def test_ctor_with_default_loop(self): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) self.addCleanup(loop.close) self.addCleanup(asyncio.set_event_loop, None) conn = aiohttp.BaseConnector() self.assertIs(loop, conn._loop) def test_connect_with_limit(self): @asyncio.coroutine def go(): tr, proto = unittest.mock.Mock(), unittest.mock.Mock() proto.is_connected.return_value = True class Req: host = 'host' port = 80 ssl = False response = unittest.mock.Mock() conn = aiohttp.BaseConnector(loop=self.loop, limit=1) key = ('host', 80, False) conn._conns[key] = [(tr, proto, self.loop.time())] conn._create_connection = unittest.mock.Mock() conn._create_connection.return_value = asyncio.Future( loop=self.loop) conn._create_connection.return_value.set_result((tr, proto)) connection1 = yield from conn.connect(Req()) self.assertEqual(connection1._transport, tr) self.assertEqual(1, len(conn._acquired[key])) acquired = False @asyncio.coroutine def f(): nonlocal acquired connection2 = yield from conn.connect(Req()) acquired = True self.assertEqual(1, len(conn._acquired[key])) connection2.release() task = asyncio.async(f(), loop=self.loop) yield from asyncio.sleep(0.01, loop=self.loop) self.assertFalse(acquired) connection1.release() yield from asyncio.sleep(0, loop=self.loop) self.assertTrue(acquired) yield from task conn.close() self.loop.run_until_complete(go()) def test_connect_with_limit_cancelled(self): @asyncio.coroutine def go(): tr, proto = unittest.mock.Mock(), unittest.mock.Mock() proto.is_connected.return_value = True class Req: host = 'host' port = 80 ssl = False response = unittest.mock.Mock() conn = aiohttp.BaseConnector(loop=self.loop, limit=1) key = ('host', 80, False) conn._conns[key] = [(tr, proto, self.loop.time())] conn._create_connection = unittest.mock.Mock() conn._create_connection.return_value = asyncio.Future( loop=self.loop) conn._create_connection.return_value.set_result((tr, proto)) connection = yield from conn.connect(Req()) self.assertEqual(connection._transport, tr) self.assertEqual(1, len(conn._acquired[key])) with self.assertRaises(asyncio.TimeoutError): # limit exhausted yield from asyncio.wait_for(conn.connect(Req), 0.01, loop=self.loop) connection.close() self.loop.run_until_complete(go()) def test_connect_with_limit_concurrent(self): @asyncio.coroutine def go(): proto = unittest.mock.Mock() proto.is_connected.return_value = True class Req: host = 'host' port = 80 ssl = False response = unittest.mock.Mock(_should_close=False) max_connections = 2 num_connections = 0 conn = aiohttp.BaseConnector(limit=max_connections, loop=self.loop) # Use a real coroutine for _create_connection; a mock would mask # problems that only happen when the method yields. @asyncio.coroutine def create_connection(req): nonlocal num_connections num_connections += 1 yield from asyncio.sleep(0, loop=self.loop) # Make a new transport mock each time because acquired # transports are stored in a set. Reusing the same object # messes with the count. tr = unittest.mock.Mock() return tr, proto conn._create_connection = create_connection # Simulate something like a crawler. It opens a connection, does # something with it, closes it, then creates tasks that make more # connections and waits for them to finish. The crawler is started # with multiple concurrent requests and stops when it hits a # predefined maximum number of requests. max_requests = 10 num_requests = 0 start_requests = max_connections + 1 @asyncio.coroutine def f(start=True): nonlocal num_requests if num_requests == max_requests: return num_requests += 1 if not start: connection = yield from conn.connect(Req()) yield from asyncio.sleep(0, loop=self.loop) connection.release() tasks = [ asyncio.async(f(start=False), loop=self.loop) for i in range(start_requests) ] yield from asyncio.wait(tasks, loop=self.loop) yield from f() conn.close() self.assertEqual(max_connections, num_connections) self.loop.run_until_complete(go()) def test_close_with_acquired_connection(self): @asyncio.coroutine def go(): tr, proto = unittest.mock.Mock(), unittest.mock.Mock() proto.is_connected.return_value = True class Req: host = 'host' port = 80 ssl = False response = unittest.mock.Mock() conn = aiohttp.BaseConnector(loop=self.loop, limit=1) key = ('host', 80, False) conn._conns[key] = [(tr, proto, self.loop.time())] conn._create_connection = unittest.mock.Mock() conn._create_connection.return_value = asyncio.Future( loop=self.loop) conn._create_connection.return_value.set_result((tr, proto)) connection = yield from conn.connect(Req()) self.assertEqual(1, len(conn._acquired)) conn.close() self.assertEqual(0, len(conn._acquired)) self.assertTrue(conn.closed) tr.close.assert_called_with() self.assertFalse(connection.closed) connection.close() self.assertTrue(connection.closed) self.loop.run_until_complete(go()) def test_default_force_close(self): connector = aiohttp.BaseConnector(loop=self.loop) self.assertFalse(connector.force_close) def test_limit_property(self): conn = aiohttp.BaseConnector(loop=self.loop, limit=15) self.assertEqual(15, conn.limit) conn.close() def test_limit_property_default(self): conn = aiohttp.BaseConnector(loop=self.loop) self.assertIsNone(conn.limit) conn.close() class TestHttpClientConnector(unittest.TestCase): def setUp(self): self.handler = None self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): if self.handler: self.loop.run_until_complete(self.handler.finish_connections()) self.loop.stop() self.loop.run_forever() self.loop.close() gc.collect() def find_unused_port(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 0)) port = s.getsockname()[1] s.close() return port @asyncio.coroutine def create_server(self, method, path, handler): app = web.Application(loop=self.loop) app.router.add_route(method, path, handler) port = self.find_unused_port() self.handler = app.make_handler(keep_alive_on=False) srv = yield from self.loop.create_server( self.handler, '127.0.0.1', port) url = "http://127.0.0.1:{}".format(port) + path self.addCleanup(srv.close) return app, srv, url @asyncio.coroutine def create_unix_server(self, method, path, handler): tmpdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, tmpdir) app = web.Application(loop=self.loop) app.router.add_route(method, path, handler) self.handler = app.make_handler(keep_alive_on=False) sock_path = os.path.join(tmpdir, 'socket.sock') srv = yield from self.loop.create_unix_server( self.handler, sock_path) url = "http://127.0.0.1" + path self.addCleanup(srv.close) return app, srv, url, sock_path def test_tcp_connector(self): @asyncio.coroutine def handler(request): return web.HTTPOk() app, srv, url = self.loop.run_until_complete( self.create_server('get', '/', handler)) conn = aiohttp.TCPConnector(loop=self.loop) r = self.loop.run_until_complete( aiohttp.request( 'get', url, connector=conn, loop=self.loop)) self.loop.run_until_complete(r.release()) self.assertEqual(r.status, 200) r.close() conn.close() @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'requires unix') def test_unix_connector(self): @asyncio.coroutine def handler(request): return web.HTTPOk() app, srv, url, sock_path = self.loop.run_until_complete( self.create_unix_server('get', '/', handler)) connector = aiohttp.UnixConnector(sock_path, loop=self.loop) self.assertEqual(sock_path, connector.path) r = self.loop.run_until_complete( client.request( 'get', url, connector=connector, loop=self.loop)) self.assertEqual(r.status, 200) r.close() def test_connector_cookie_deprecation(self): with self.assertWarnsRegex(DeprecationWarning, "^Using `share_cookies` is deprecated"): conn = aiohttp.TCPConnector(share_cookies=True, loop=self.loop) conn.close() def test_ambiguous_ctor_params(self): with self.assertRaises(ValueError): aiohttp.TCPConnector(resolve=True, use_dns_cache=False, loop=self.loop) def test_both_resolve_and_use_dns_cache(self): conn = aiohttp.TCPConnector(resolve=True, use_dns_cache=True, loop=self.loop) self.assertTrue(conn.use_dns_cache) with self.assertWarns(DeprecationWarning): self.assertTrue(conn.resolve) def test_both_use_dns_cache_only(self): conn = aiohttp.TCPConnector(use_dns_cache=True, loop=self.loop) self.assertTrue(conn.use_dns_cache) with self.assertWarns(DeprecationWarning): self.assertTrue(conn.resolve) aiohttp-0.20.2/tests/test_multipart.py0000664000175000017500000017612212624545277020652 0ustar andrewandrew00000000000000import asyncio import functools import io import os import unittest import unittest.mock as mock import zlib import aiohttp.multipart from aiohttp.helpers import parse_mimetype from aiohttp.hdrs import ( CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_TRANSFER_ENCODING, CONTENT_TYPE ) from aiohttp.multipart import ( parse_content_disposition, content_disposition_filename ) def run_in_loop(f): @functools.wraps(f) def wrapper(testcase, *args, **kwargs): coro = asyncio.coroutine(f) future = asyncio.wait_for(coro(testcase, *args, **kwargs), timeout=5) return testcase.loop.run_until_complete(future) return wrapper class MetaAioTestCase(type): def __new__(cls, name, bases, attrs): for key, obj in attrs.items(): if key.startswith('test_'): attrs[key] = run_in_loop(obj) return super().__new__(cls, name, bases, attrs) class TestCase(unittest.TestCase, metaclass=MetaAioTestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) def tearDown(self): self.loop.close() def future(self, obj): fut = asyncio.Future(loop=self.loop) fut.set_result(obj) return fut class Response(object): def __init__(self, headers, content): self.headers = headers self.content = content class Stream(object): def __init__(self, content): self.content = io.BytesIO(content) @asyncio.coroutine def read(self, size=None): return self.content.read(size) @asyncio.coroutine def readline(self): return self.content.readline() class StreamWithShortenRead(Stream): def __init__(self, content): self._first = True super().__init__(content) @asyncio.coroutine def read(self, size=None): if size is not None and self._first: self._first = False size = size // 2 return (yield from super().read(size)) class MultipartResponseWrapperTestCase(TestCase): def setUp(self): super().setUp() wrapper = aiohttp.multipart.MultipartResponseWrapper(mock.Mock(), mock.Mock()) self.wrapper = wrapper def test_at_eof(self): self.wrapper.at_eof() self.assertTrue(self.wrapper.resp.content.at_eof.called) def test_next(self): self.wrapper.stream.next.return_value = self.future(b'') self.wrapper.stream.at_eof.return_value = False yield from self.wrapper.next() self.assertTrue(self.wrapper.stream.next.called) def test_release(self): self.wrapper.resp.release.return_value = self.future(None) yield from self.wrapper.release() self.assertTrue(self.wrapper.resp.release.called) def test_release_when_stream_at_eof(self): self.wrapper.resp.release.return_value = self.future(None) self.wrapper.stream.next.return_value = self.future(b'') self.wrapper.stream.at_eof.return_value = True yield from self.wrapper.next() self.assertTrue(self.wrapper.stream.next.called) self.assertTrue(self.wrapper.resp.release.called) class PartReaderTestCase(TestCase): def setUp(self): super().setUp() self.boundary = b'--:' def test_next(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, Stream(b'Hello, world!\r\n--:')) result = yield from obj.next() self.assertEqual(b'Hello, world!', result) self.assertTrue(obj.at_eof()) def test_next_next(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, Stream(b'Hello, world!\r\n--:')) result = yield from obj.next() self.assertEqual(b'Hello, world!', result) self.assertTrue(obj.at_eof()) result = yield from obj.next() self.assertIsNone(result) def test_read(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, Stream(b'Hello, world!\r\n--:')) result = yield from obj.read() self.assertEqual(b'Hello, world!', result) self.assertTrue(obj.at_eof()) def test_read_chunk_at_eof(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, Stream(b'--:')) obj._at_eof = True result = yield from obj.read_chunk() self.assertEqual(b'', result) def test_read_chunk_requires_content_length(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, Stream(b'Hello, world!\r\n--:')) with self.assertRaises(AssertionError): yield from obj.read_chunk() def test_read_chunk_properly_counts_read_bytes(self): expected = b'.' * 10 size = len(expected) obj = aiohttp.multipart.BodyPartReader( self.boundary, {'CONTENT-LENGTH': size}, StreamWithShortenRead(expected + b'\r\n--:--')) result = bytearray() while True: chunk = yield from obj.read_chunk() if not chunk: break result.extend(chunk) self.assertEqual(size, len(result)) self.assertEqual(b'.' * size, result) self.assertTrue(obj.at_eof()) def test_read_does_reads_boundary(self): stream = Stream(b'Hello, world!\r\n--:') obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, stream) result = yield from obj.read() self.assertEqual(b'Hello, world!', result) self.assertEqual(b'', (yield from stream.read())) self.assertEqual([b'--:'], list(obj._unread)) def test_multiread(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, Stream(b'Hello,\r\n--:\r\n\r\nworld!\r\n--:--')) result = yield from obj.read() self.assertEqual(b'Hello,', result) result = yield from obj.read() self.assertEqual(b'', result) self.assertTrue(obj.at_eof()) def test_read_multiline(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, Stream(b'Hello\n,\r\nworld!\r\n--:--')) result = yield from obj.read() self.assertEqual(b'Hello\n,\r\nworld!', result) result = yield from obj.read() self.assertEqual(b'', result) self.assertTrue(obj.at_eof()) def test_read_respects_content_length(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {'CONTENT-LENGTH': 100500}, Stream(b'.' * 100500 + b'\r\n--:--')) result = yield from obj.read() self.assertEqual(b'.' * 100500, result) self.assertTrue(obj.at_eof()) def test_read_with_content_encoding_gzip(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_ENCODING: 'gzip'}, Stream(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--:--')) result = yield from obj.read(decode=True) self.assertEqual(b'Time to Relax!', result) def test_read_with_content_encoding_deflate(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_ENCODING: 'deflate'}, Stream(b'\x0b\xc9\xccMU(\xc9W\x08J\xcdI\xacP\x04\x00\r\n--:--')) result = yield from obj.read(decode=True) self.assertEqual(b'Time to Relax!', result) def test_read_with_content_encoding_identity(self): 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') obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_ENCODING: 'identity'}, Stream(thing + b'--:--')) result = yield from obj.read(decode=True) self.assertEqual(thing[:-2], result) def test_read_with_content_encoding_unknown(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_ENCODING: 'snappy'}, Stream(b'\x0e4Time to Relax!\r\n--:--')) with self.assertRaises(RuntimeError): yield from obj.read(decode=True) def test_read_with_content_transfer_encoding_base64(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TRANSFER_ENCODING: 'base64'}, Stream(b'VGltZSB0byBSZWxheCE=\r\n--:--')) result = yield from obj.read(decode=True) self.assertEqual(b'Time to Relax!', result) def test_read_with_content_transfer_encoding_quoted_printable(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TRANSFER_ENCODING: 'quoted-printable'}, Stream(b'=D0=9F=D1=80=D0=B8=D0=B2=D0=B5=D1=82,' b' =D0=BC=D0=B8=D1=80!\r\n--:--')) result = yield from obj.read(decode=True) self.assertEqual(b'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82,' b' \xd0\xbc\xd0\xb8\xd1\x80!', result) def test_read_with_content_transfer_encoding_unknown(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TRANSFER_ENCODING: 'unknown'}, Stream(b'\x0e4Time to Relax!\r\n--:--')) with self.assertRaises(RuntimeError): yield from obj.read(decode=True) def test_read_text(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, Stream(b'Hello, world!\r\n--:--')) result = yield from obj.text() self.assertEqual('Hello, world!', result) def test_read_text_encoding(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, Stream('Привет, Мир!\r\n--:--'.encode('cp1251'))) result = yield from obj.text(encoding='cp1251') self.assertEqual('Привет, Мир!', result) def test_read_text_guess_encoding(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TYPE: 'text/plain;charset=cp1251'}, Stream('Привет, Мир!\r\n--:--'.encode('cp1251'))) result = yield from obj.text() self.assertEqual('Привет, Мир!', result) def test_read_text_compressed(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_ENCODING: 'deflate', CONTENT_TYPE: 'text/plain'}, Stream(b'\x0b\xc9\xccMU(\xc9W\x08J\xcdI\xacP\x04\x00\r\n--:--')) result = yield from obj.text() self.assertEqual('Time to Relax!', result) def test_read_text_while_closed(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TYPE: 'text/plain'}, Stream(b'')) obj._at_eof = True result = yield from obj.text() self.assertEqual('', result) def test_read_json(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TYPE: 'application/json'}, Stream(b'{"test": "passed"}\r\n--:--')) result = yield from obj.json() self.assertEqual({'test': 'passed'}, result) def test_read_json_encoding(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TYPE: 'application/json'}, Stream('{"теÑÑ‚": "паÑÑед"}\r\n--:--'.encode('cp1251'))) result = yield from obj.json(encoding='cp1251') self.assertEqual({'теÑÑ‚': 'паÑÑед'}, result) def test_read_json_guess_encoding(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TYPE: 'application/json; charset=cp1251'}, Stream('{"теÑÑ‚": "паÑÑед"}\r\n--:--'.encode('cp1251'))) result = yield from obj.json() self.assertEqual({'теÑÑ‚': 'паÑÑед'}, result) def test_read_json_compressed(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_ENCODING: 'deflate', CONTENT_TYPE: 'application/json'}, Stream(b'\xabV*I-.Q\xb2RP*H,.NMQ\xaa\x05\x00\r\n--:--')) result = yield from obj.json() self.assertEqual({'test': 'passed'}, result) def test_read_json_while_closed(self): stream = Stream(b'') obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TYPE: 'application/json'}, stream) obj._at_eof = True result = yield from obj.json() self.assertEqual(None, result) def test_read_form(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TYPE: 'application/x-www-form-urlencoded'}, Stream(b'foo=bar&foo=baz&boo=zoo\r\n--:--')) result = yield from obj.form() self.assertEqual([('foo', 'bar'), ('foo', 'baz'), ('boo', 'zoo')], result) def test_read_form_encoding(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TYPE: 'application/x-www-form-urlencoded'}, Stream('foo=bar&foo=baz&boo=zoo\r\n--:--'.encode('cp1251'))) result = yield from obj.form(encoding='cp1251') self.assertEqual([('foo', 'bar'), ('foo', 'baz'), ('boo', 'zoo')], result) def test_read_form_guess_encoding(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TYPE: 'application/x-www-form-urlencoded; charset=utf-8'}, Stream('foo=bar&foo=baz&boo=zoo\r\n--:--'.encode('utf-8'))) result = yield from obj.form() self.assertEqual([('foo', 'bar'), ('foo', 'baz'), ('boo', 'zoo')], result) def test_read_form_while_closed(self): stream = Stream(b'') obj = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_TYPE: 'application/x-www-form-urlencoded'}, stream) obj._at_eof = True result = yield from obj.form() self.assertEqual(None, result) def test_release(self): stream = Stream(b'Hello,\r\n--:\r\n\r\nworld!\r\n--:--') obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, stream) yield from obj.release() self.assertTrue(obj.at_eof()) self.assertEqual(b'\r\nworld!\r\n--:--', stream.content.read()) self.assertEqual([b'--:\r\n'], list(obj._unread)) def test_release_respects_content_length(self): obj = aiohttp.multipart.BodyPartReader( self.boundary, {'CONTENT-LENGTH': 100500}, Stream(b'.' * 100500 + b'\r\n--:--')) result = yield from obj.release() self.assertIsNone(result) self.assertTrue(obj.at_eof()) def test_release_release(self): stream = Stream(b'Hello,\r\n--:\r\n\r\nworld!\r\n--:--') obj = aiohttp.multipart.BodyPartReader( self.boundary, {}, stream) yield from obj.release() yield from obj.release() self.assertEqual(b'\r\nworld!\r\n--:--', stream.content.read()) self.assertEqual([b'--:\r\n'], list(obj._unread)) def test_filename(self): part = aiohttp.multipart.BodyPartReader( self.boundary, {CONTENT_DISPOSITION: 'attachment; filename=foo.html'}, None) self.assertEqual('foo.html', part.filename) class MultipartReaderTestCase(TestCase): def test_from_response(self): resp = Response({CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\nhello\r\n--:--')) res = aiohttp.multipart.MultipartReader.from_response(resp) self.assertIsInstance(res, aiohttp.multipart.MultipartResponseWrapper) self.assertIsInstance(res.stream, aiohttp.multipart.MultipartReader) def test_bad_boundary(self): resp = Response( {CONTENT_TYPE: 'multipart/related;boundary=' + 'a' * 80}, Stream(b'')) with self.assertRaises(ValueError): aiohttp.multipart.MultipartReader.from_response(resp) def test_dispatch(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\necho\r\n--:--')) res = reader._get_part_reader({CONTENT_TYPE: 'text/plain'}) self.assertIsInstance(res, reader.part_reader_cls) def test_dispatch_bodypart(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\necho\r\n--:--')) res = reader._get_part_reader({CONTENT_TYPE: 'text/plain'}) self.assertIsInstance(res, reader.part_reader_cls) def test_dispatch_multipart(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'----:--\r\n' b'\r\n' b'test\r\n' b'----:--\r\n' b'\r\n' b'passed\r\n' b'----:----\r\n' b'--:--')) res = reader._get_part_reader( {CONTENT_TYPE: 'multipart/related;boundary=--:--'}) self.assertIsInstance(res, reader.__class__) def test_dispatch_custom_multipart_reader(self): class CustomReader(aiohttp.multipart.MultipartReader): pass reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'----:--\r\n' b'\r\n' b'test\r\n' b'----:--\r\n' b'\r\n' b'passed\r\n' b'----:----\r\n' b'--:--')) reader.multipart_reader_cls = CustomReader res = reader._get_part_reader( {CONTENT_TYPE: 'multipart/related;boundary=--:--'}) self.assertIsInstance(res, CustomReader) def test_emit_next(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\necho\r\n--:--')) res = yield from reader.next() self.assertIsInstance(res, reader.part_reader_cls) def test_invalid_boundary(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'---:\r\n\r\necho\r\n---:--')) with self.assertRaises(ValueError): yield from reader.next() def test_release(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/mixed;boundary=":"'}, Stream(b'--:\r\n' b'Content-Type: multipart/related;boundary=--:--\r\n' b'\r\n' b'----:--\r\n' b'\r\n' b'test\r\n' b'----:--\r\n' b'\r\n' b'passed\r\n' b'----:----\r\n' b'--:--')) yield from reader.release() self.assertTrue(reader.at_eof()) def test_release_release(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\necho\r\n--:--')) yield from reader.release() self.assertTrue(reader.at_eof()) yield from reader.release() self.assertTrue(reader.at_eof()) def test_release_next(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n\r\necho\r\n--:--')) yield from reader.release() self.assertTrue(reader.at_eof()) res = yield from reader.next() self.assertIsNone(res) def test_second_next_releases_previous_object(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n' b'\r\n' b'test\r\n' b'--:\r\n' b'\r\n' b'passed\r\n' b'--:--')) first = yield from reader.next() self.assertIsInstance(first, aiohttp.multipart.BodyPartReader) second = yield from reader.next() self.assertTrue(first.at_eof()) self.assertFalse(second.at_eof()) def test_release_without_read_the_last_object(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n' b'\r\n' b'test\r\n' b'--:\r\n' b'\r\n' b'passed\r\n' b'--:--')) first = yield from reader.next() second = yield from reader.next() third = yield from reader.next() self.assertTrue(first.at_eof()) self.assertTrue(second.at_eof()) self.assertTrue(second.at_eof()) self.assertIsNone(third) def test_read_chunk_doesnt_breaks_reader(self): reader = aiohttp.multipart.MultipartReader( {CONTENT_TYPE: 'multipart/related;boundary=":"'}, Stream(b'--:\r\n' b'Content-Length: 4\r\n\r\n' b'test' b'\r\n--:\r\n' b'Content-Length: 6\r\n\r\n' b'passed' b'\r\n--:--')) while True: part = yield from reader.next() if part is None: break while not part.at_eof(): yield from part.read_chunk(3) class BodyPartWriterTestCase(unittest.TestCase): def setUp(self): self.part = aiohttp.multipart.BodyPartWriter(b'') def test_guess_content_length(self): self.part.headers[CONTENT_TYPE] = 'text/plain; charset=utf-8' self.assertIsNone(self.part._guess_content_length({})) self.assertIsNone(self.part._guess_content_length(object())) self.assertEqual(3, self.part._guess_content_length(io.BytesIO(b'foo'))) self.assertEqual(3, self.part._guess_content_length(io.StringIO('foo'))) self.assertEqual(6, self.part._guess_content_length(io.StringIO('мÑу'))) self.assertEqual(3, self.part._guess_content_length(b'bar')) self.assertEqual(12, self.part._guess_content_length('паÑÑед')) with open(__file__, 'rb') as f: self.assertEqual(os.fstat(f.fileno()).st_size, self.part._guess_content_length(f)) def test_guess_content_type(self): default = 'application/octet-stream' self.assertEqual(default, self.part._guess_content_type(b'foo')) self.assertEqual('text/plain; charset=utf-8', self.part._guess_content_type('foo')) here = os.path.dirname(__file__) filename = os.path.join(here, 'software_development_in_picture.jpg') with open(filename, 'rb') as f: self.assertEqual('image/jpeg', self.part._guess_content_type(f)) def test_guess_filename(self): class Named: name = 'foo' self.assertIsNone(self.part._guess_filename({})) self.assertIsNone(self.part._guess_filename(object())) self.assertIsNone(self.part._guess_filename(io.BytesIO(b'foo'))) self.assertIsNone(self.part._guess_filename(Named())) with open(__file__, 'rb') as f: self.assertEqual(os.path.basename(f.name), self.part._guess_filename(f)) def test_autoset_content_disposition(self): self.part.obj = open(__file__, 'rb') self.addCleanup(self.part.obj.close) self.part._fill_headers_with_defaults() self.assertIn(CONTENT_DISPOSITION, self.part.headers) fname = os.path.basename(self.part.obj.name) self.assertEqual( 'attachment; filename="{0}"; filename*=utf-8\'\'{0}'.format(fname), self.part.headers[CONTENT_DISPOSITION]) def test_set_content_disposition(self): self.part.set_content_disposition('attachment', foo='bar') self.assertEqual( 'attachment; foo="bar"', self.part.headers[CONTENT_DISPOSITION]) def test_set_content_disposition_bad_type(self): with self.assertRaises(ValueError): self.part.set_content_disposition('foo bar') with self.assertRaises(ValueError): self.part.set_content_disposition('теÑÑ‚') with self.assertRaises(ValueError): self.part.set_content_disposition('foo\x00bar') with self.assertRaises(ValueError): self.part.set_content_disposition('') def test_set_content_disposition_bad_param(self): with self.assertRaises(ValueError): self.part.set_content_disposition('inline', **{'foo bar': 'baz'}) with self.assertRaises(ValueError): self.part.set_content_disposition('inline', **{'теÑÑ‚': 'baz'}) with self.assertRaises(ValueError): self.part.set_content_disposition('inline', **{'': 'baz'}) with self.assertRaises(ValueError): self.part.set_content_disposition('inline', **{'foo\x00bar': 'baz'}) def test_serialize_bytes(self): self.assertEqual(b'foo', next(self.part._serialize_bytes(b'foo'))) def test_serialize_str(self): self.assertEqual(b'foo', next(self.part._serialize_str('foo'))) def test_serialize_str_custom_encoding(self): self.part.headers[CONTENT_TYPE] = \ 'text/plain;charset=cp1251' self.assertEqual('привет'.encode('cp1251'), next(self.part._serialize_str('привет'))) def test_serialize_io(self): self.assertEqual(b'foo', next(self.part._serialize_io(io.BytesIO(b'foo')))) self.assertEqual(b'foo', next(self.part._serialize_io(io.StringIO('foo')))) def test_serialize_io_chunk(self): flo = io.BytesIO(b'foobarbaz') self.part._chunk_size = 3 self.assertEqual([b'foo', b'bar', b'baz'], list(self.part._serialize_io(flo))) def test_serialize_json(self): self.assertEqual(b'{"\\u043f\\u0440\\u0438\\u0432\\u0435\\u0442":' b' "\\u043c\\u0438\\u0440"}', next(self.part._serialize_json({'привет': 'мир'}))) def test_serialize_form(self): data = [('foo', 'bar'), ('foo', 'baz'), ('boo', 'zoo')] self.assertEqual(b'foo=bar&foo=baz&boo=zoo', next(self.part._serialize_form(data))) def test_serialize_form_dict(self): data = {'hello': 'мир'} self.assertEqual(b'hello=%D0%BC%D0%B8%D1%80', next(self.part._serialize_form(data))) def test_serialize_multipart(self): multipart = aiohttp.multipart.MultipartWriter(boundary=':') multipart.append('foo-bar-baz') multipart.append_json({'test': 'passed'}) self.assertEqual( [b'--:\r\n', b'CONTENT-TYPE: text/plain; charset=utf-8\r\n' b'CONTENT-LENGTH: 11', b'\r\n\r\n', b'foo-bar-baz', b'\r\n', b'--:\r\n', b'CONTENT-TYPE: application/json', b'\r\n\r\n', b'{"test": "passed"}', b'\r\n', b'--:--\r\n', b''], list(self.part._serialize_multipart(multipart)) ) def test_serialize_default(self): with self.assertRaises(TypeError): self.part.obj = object() list(self.part.serialize()) with self.assertRaises(TypeError): next(self.part._serialize_default(object())) def test_serialize_with_content_encoding_gzip(self): part = aiohttp.multipart.BodyPartWriter( 'Time to Relax!', {CONTENT_ENCODING: 'gzip'}) stream = part.serialize() self.assertEqual(b'CONTENT-ENCODING: gzip\r\n' b'CONTENT-TYPE: text/plain; charset=utf-8', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) result = b''.join(stream) decompressor = zlib.decompressobj(wbits=16+zlib.MAX_WBITS) data = decompressor.decompress(result) self.assertEqual(b'Time to Relax!', data) self.assertIsNone(next(stream, None)) def test_serialize_with_content_encoding_deflate(self): part = aiohttp.multipart.BodyPartWriter( 'Time to Relax!', {CONTENT_ENCODING: 'deflate'}) stream = part.serialize() self.assertEqual(b'CONTENT-ENCODING: deflate\r\n' b'CONTENT-TYPE: text/plain; charset=utf-8', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) thing = b'\x0b\xc9\xccMU(\xc9W\x08J\xcdI\xacP\x04\x00\r\n' self.assertEqual(thing, b''.join(stream)) self.assertIsNone(next(stream, None)) def test_serialize_with_content_encoding_identity(self): thing = b'\x0b\xc9\xccMU(\xc9W\x08J\xcdI\xacP\x04\x00' part = aiohttp.multipart.BodyPartWriter( thing, {CONTENT_ENCODING: 'identity'}) stream = part.serialize() self.assertEqual(b'CONTENT-ENCODING: identity\r\n' b'CONTENT-TYPE: application/octet-stream\r\n' b'CONTENT-LENGTH: 16', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) self.assertEqual(thing, next(stream)) self.assertEqual(b'\r\n', next(stream)) self.assertIsNone(next(stream, None)) def test_serialize_with_content_encoding_unknown(self): part = aiohttp.multipart.BodyPartWriter( 'Time to Relax!', {CONTENT_ENCODING: 'snappy'}) with self.assertRaises(RuntimeError): list(part.serialize()) def test_serialize_with_content_transfer_encoding_base64(self): part = aiohttp.multipart.BodyPartWriter( 'Time to Relax!', {CONTENT_TRANSFER_ENCODING: 'base64'}) stream = part.serialize() self.assertEqual(b'CONTENT-TRANSFER-ENCODING: base64\r\n' b'CONTENT-TYPE: text/plain; charset=utf-8', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) self.assertEqual(b'VGltZSB0byBSZWxh', next(stream)) self.assertEqual(b'eCE=', next(stream)) self.assertEqual(b'\r\n', next(stream)) self.assertIsNone(next(stream, None)) def test_serialize_io_with_content_transfer_encoding_base64(self): part = aiohttp.multipart.BodyPartWriter( io.BytesIO(b'Time to Relax!'), {CONTENT_TRANSFER_ENCODING: 'base64'}) part._chunk_size = 6 stream = part.serialize() self.assertEqual(b'CONTENT-TRANSFER-ENCODING: base64\r\n' b'CONTENT-TYPE: application/octet-stream', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) self.assertEqual(b'VGltZSB0', next(stream)) self.assertEqual(b'byBSZWxh', next(stream)) self.assertEqual(b'eCE=', next(stream)) self.assertEqual(b'\r\n', next(stream)) self.assertIsNone(next(stream, None)) def test_serialize_with_content_transfer_encoding_quote_printable(self): part = aiohttp.multipart.BodyPartWriter( 'Привет, мир!', {CONTENT_TRANSFER_ENCODING: 'quoted-printable'}) stream = part.serialize() self.assertEqual(b'CONTENT-TRANSFER-ENCODING: quoted-printable\r\n' b'CONTENT-TYPE: text/plain; charset=utf-8', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) self.assertEqual(b'=D0=9F=D1=80=D0=B8=D0=B2=D0=B5=D1=82,' b' =D0=BC=D0=B8=D1=80!', next(stream)) self.assertEqual(b'\r\n', next(stream)) self.assertIsNone(next(stream, None)) def test_serialize_with_content_transfer_encoding_unknown(self): part = aiohttp.multipart.BodyPartWriter( 'Time to Relax!', {CONTENT_TRANSFER_ENCODING: 'unknown'}) with self.assertRaises(RuntimeError): list(part.serialize()) def test_filename(self): self.part.set_content_disposition('related', filename='foo.html') self.assertEqual('foo.html', self.part.filename) class MultipartWriterTestCase(unittest.TestCase): def setUp(self): self.writer = aiohttp.multipart.MultipartWriter(boundary=':') def test_default_subtype(self): mtype, stype, *_ = parse_mimetype( self.writer.headers.get(CONTENT_TYPE)) self.assertEqual('multipart', mtype) self.assertEqual('mixed', stype) def test_bad_boundary(self): with self.assertRaises(ValueError): aiohttp.multipart.MultipartWriter(boundary='теÑÑ‚') def test_default_headers(self): self.assertEqual({CONTENT_TYPE: 'multipart/mixed; boundary=":"'}, self.writer.headers) def test_iter_parts(self): self.writer.append('foo') self.writer.append('bar') self.writer.append('baz') self.assertEqual(3, len(list(self.writer))) def test_append(self): self.assertEqual(0, len(self.writer)) self.writer.append('hello, world!') self.assertEqual(1, len(self.writer)) self.assertIsInstance(self.writer.parts[0], self.writer.part_writer_cls) def test_append_with_headers(self): self.writer.append('hello, world!', {'x-foo': 'bar'}) self.assertEqual(1, len(self.writer)) self.assertIn('x-foo', self.writer.parts[0].headers) self.assertEqual(self.writer.parts[0].headers['x-foo'], 'bar') def test_append_json(self): self.writer.append_json({'foo': 'bar'}) self.assertEqual(1, len(self.writer)) part = self.writer.parts[0] self.assertEqual(part.headers[CONTENT_TYPE], 'application/json') def test_append_part(self): part = aiohttp.multipart.BodyPartWriter('test', {CONTENT_TYPE: 'text/plain'}) self.writer.append(part, {CONTENT_TYPE: 'test/passed'}) self.assertEqual(1, len(self.writer)) part = self.writer.parts[0] self.assertEqual(part.headers[CONTENT_TYPE], 'test/passed') def test_append_json_overrides_content_type(self): self.writer.append_json({'foo': 'bar'}, {CONTENT_TYPE: 'test/passed'}) self.assertEqual(1, len(self.writer)) part = self.writer.parts[0] self.assertEqual(part.headers[CONTENT_TYPE], 'application/json') def test_append_form(self): self.writer.append_form({'foo': 'bar'}, {CONTENT_TYPE: 'test/passed'}) self.assertEqual(1, len(self.writer)) part = self.writer.parts[0] self.assertEqual(part.headers[CONTENT_TYPE], 'application/x-www-form-urlencoded') def test_serialize(self): self.assertEqual([b''], list(self.writer.serialize())) def test_with(self): with aiohttp.multipart.MultipartWriter(boundary=':') as writer: writer.append('foo') writer.append(b'bar') writer.append_json({'baz': True}) self.assertEqual(3, len(writer)) class ParseContentDispositionTestCase(unittest.TestCase): # http://greenbytes.de/tech/tc2231/ def test_parse_empty(self): disptype, params = parse_content_disposition(None) self.assertEqual(None, disptype) self.assertEqual({}, params) def test_inlonly(self): disptype, params = parse_content_disposition('inline') self.assertEqual('inline', disptype) self.assertEqual({}, params) def test_inlonlyquoted(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition('"inline"') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_inlwithasciifilename(self): disptype, params = parse_content_disposition( 'inline; filename="foo.html"') self.assertEqual('inline', disptype) self.assertEqual({'filename': 'foo.html'}, params) def test_inlwithfnattach(self): disptype, params = parse_content_disposition( 'inline; filename="Not an attachment!"') self.assertEqual('inline', disptype) self.assertEqual({'filename': 'Not an attachment!'}, params) def test_attonly(self): disptype, params = parse_content_disposition('attachment') self.assertEqual('attachment', disptype) self.assertEqual({}, params) def test_attonlyquoted(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition('"attachment"') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attonlyucase(self): disptype, params = parse_content_disposition('ATTACHMENT') self.assertEqual('attachment', disptype) self.assertEqual({}, params) def test_attwithasciifilename(self): disptype, params = parse_content_disposition( 'attachment; filename="foo.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo.html'}, params) def test_inlwithasciifilenamepdf(self): disptype, params = parse_content_disposition( 'attachment; filename="foo.pdf"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo.pdf'}, params) def test_attwithasciifilename25(self): disptype, params = parse_content_disposition( 'attachment; filename="0000000000111111111122222"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': '0000000000111111111122222'}, params) def test_attwithasciifilename35(self): disptype, params = parse_content_disposition( 'attachment; filename="00000000001111111111222222222233333"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': '00000000001111111111222222222233333'}, params) def test_attwithasciifnescapedchar(self): disptype, params = parse_content_disposition( r'attachment; filename="f\oo.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo.html'}, params) def test_attwithasciifnescapedquote(self): disptype, params = parse_content_disposition( 'attachment; filename="\"quoting\" tested.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': '"quoting" tested.html'}, params) @unittest.skip('need more smart parser which respects quoted text') def test_attwithquotedsemicolon(self): disptype, params = parse_content_disposition( 'attachment; filename="Here\'s a semicolon;.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'Here\'s a semicolon;.html'}, params) def test_attwithfilenameandextparam(self): disptype, params = parse_content_disposition( 'attachment; foo="bar"; filename="foo.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo.html', 'foo': 'bar'}, params) def test_attwithfilenameandextparamescaped(self): disptype, params = parse_content_disposition( 'attachment; foo="\"\\";filename="foo.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo.html', 'foo': '"\\'}, params) def test_attwithasciifilenameucase(self): disptype, params = parse_content_disposition( 'attachment; FILENAME="foo.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo.html'}, params) def test_attwithasciifilenamenq(self): disptype, params = parse_content_disposition( 'attachment; filename=foo.html') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo.html'}, params) def test_attwithtokfncommanq(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo,bar.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attwithasciifilenamenqs(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo.html ;') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attemptyparam(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; ;filename=foo') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attwithasciifilenamenqws(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo bar.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attwithfntokensq(self): disptype, params = parse_content_disposition( "attachment; filename='foo.html'") self.assertEqual('attachment', disptype) self.assertEqual({'filename': "'foo.html'"}, params) def test_attwithisofnplain(self): disptype, params = parse_content_disposition( 'attachment; filename="foo-ä.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo-ä.html'}, params) def test_attwithutf8fnplain(self): disptype, params = parse_content_disposition( 'attachment; filename="foo-ä.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo-ä.html'}, params) def test_attwithfnrawpctenca(self): disptype, params = parse_content_disposition( 'attachment; filename="foo-%41.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo-%41.html'}, params) def test_attwithfnusingpct(self): disptype, params = parse_content_disposition( 'attachment; filename="50%.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': '50%.html'}, params) def test_attwithfnrawpctencaq(self): disptype, params = parse_content_disposition( r'attachment; filename="foo-%\41.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': r'foo-%41.html'}, params) def test_attwithnamepct(self): disptype, params = parse_content_disposition( 'attachment; filename="foo-%41.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo-%41.html'}, params) def test_attwithfilenamepctandiso(self): disptype, params = parse_content_disposition( 'attachment; filename="ä-%41.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'ä-%41.html'}, params) def test_attwithfnrawpctenclong(self): disptype, params = parse_content_disposition( 'attachment; filename="foo-%c3%a4-%e2%82%ac.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo-%c3%a4-%e2%82%ac.html'}, params) def test_attwithasciifilenamews1(self): disptype, params = parse_content_disposition( 'attachment; filename ="foo.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo.html'}, params) def test_attwith2filenames(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename="foo.html"; filename="bar.html"') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attfnbrokentoken(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo[1](2).html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attfnbrokentokeniso(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo-ä.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attfnbrokentokenutf(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo-ä.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attmissingdisposition(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'filename=foo.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attmissingdisposition2(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'x=y; filename=foo.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attmissingdisposition3(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( '"foo; filename=bar;baz"; filename=qux') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attmissingdisposition4(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'filename=foo.html, filename=bar.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_emptydisposition(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( '; filename=foo.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_doublecolon(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( ': inline; attachment; filename=foo.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attandinline(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'inline; attachment; filename=foo.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attandinline2(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; inline; filename=foo.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attbrokenquotedfn(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename="foo.html".txt') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attbrokenquotedfn2(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename="bar') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attbrokenquotedfn3(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo"bar;baz"qux') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attmultinstances(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=foo.html, attachment; filename=bar.html') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attmissingdelim(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; foo=foo filename=bar') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attmissingdelim2(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename=bar foo=foo') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attmissingdelim3(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment filename=bar') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attreversed(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'filename=foo.html; attachment') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attconfusedparam(self): disptype, params = parse_content_disposition( 'attachment; xfilename=foo.html') self.assertEqual('attachment', disptype) self.assertEqual({'xfilename': 'foo.html'}, params) def test_attabspath(self): disptype, params = parse_content_disposition( 'attachment; filename="/foo.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo.html'}, params) def test_attabspathwin(self): disptype, params = parse_content_disposition( 'attachment; filename="\\foo.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo.html'}, params) def test_attcdate(self): disptype, params = parse_content_disposition( 'attachment; creation-date="Wed, 12 Feb 1997 16:29:51 -0500"') self.assertEqual('attachment', disptype) self.assertEqual({'creation-date': 'Wed, 12 Feb 1997 16:29:51 -0500'}, params) def test_attmdate(self): disptype, params = parse_content_disposition( 'attachment; modification-date="Wed, 12 Feb 1997 16:29:51 -0500"') self.assertEqual('attachment', disptype) self.assertEqual( {'modification-date': 'Wed, 12 Feb 1997 16:29:51 -0500'}, params) def test_dispext(self): disptype, params = parse_content_disposition('foobar') self.assertEqual('foobar', disptype) self.assertEqual({}, params) def test_dispextbadfn(self): disptype, params = parse_content_disposition( 'attachment; example="filename=example.txt"') self.assertEqual('attachment', disptype) self.assertEqual({'example': 'filename=example.txt'}, params) def test_attwithisofn2231iso(self): disptype, params = parse_content_disposition( "attachment; filename*=iso-8859-1''foo-%E4.html") self.assertEqual('attachment', disptype) self.assertEqual({'filename*': 'foo-ä.html'}, params) def test_attwithfn2231utf8(self): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''foo-%c3%a4-%e2%82%ac.html") self.assertEqual('attachment', disptype) self.assertEqual({'filename*': 'foo-ä-€.html'}, params) def test_attwithfn2231noc(self): disptype, params = parse_content_disposition( "attachment; filename*=''foo-%c3%a4-%e2%82%ac.html") self.assertEqual('attachment', disptype) self.assertEqual({'filename*': 'foo-ä-€.html'}, params) def test_attwithfn2231utf8comp(self): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''foo-a%cc%88.html") self.assertEqual('attachment', disptype) self.assertEqual({'filename*': 'foo-ä.html'}, params) @unittest.skip('should raise decoding error: %82 is invalid for latin1') def test_attwithfn2231utf8_bad(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=iso-8859-1''foo-%c3%a4-%e2%82%ac.html") self.assertEqual('attachment', disptype) self.assertEqual({}, params) @unittest.skip('should raise decoding error: %E4 is invalid for utf-8') def test_attwithfn2231iso_bad(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=utf-8''foo-%E4.html") self.assertEqual('attachment', disptype) self.assertEqual({}, params) def test_attwithfn2231ws1(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename *=UTF-8''foo-%c3%a4.html") self.assertEqual('attachment', disptype) self.assertEqual({}, params) def test_attwithfn2231ws2(self): disptype, params = parse_content_disposition( "attachment; filename*= UTF-8''foo-%c3%a4.html") self.assertEqual('attachment', disptype) self.assertEqual({'filename*': 'foo-ä.html'}, params) def test_attwithfn2231ws3(self): disptype, params = parse_content_disposition( "attachment; filename* =UTF-8''foo-%c3%a4.html") self.assertEqual('attachment', disptype) self.assertEqual({'filename*': 'foo-ä.html'}, params) def test_attwithfn2231quot(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=\"UTF-8''foo-%c3%a4.html\"") self.assertEqual('attachment', disptype) self.assertEqual({}, params) def test_attwithfn2231quot2(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=\"foo%20bar.html\"") self.assertEqual('attachment', disptype) self.assertEqual({}, params) def test_attwithfn2231singleqmissing(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8'foo-%c3%a4.html") self.assertEqual('attachment', disptype) self.assertEqual({}, params) @unittest.skip('urllib.parse.unquote is tolerate to standalone % chars') def test_attwithfn2231nbadpct1(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''foo%") self.assertEqual('attachment', disptype) self.assertEqual({}, params) @unittest.skip('urllib.parse.unquote is tolerate to standalone % chars') def test_attwithfn2231nbadpct2(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionParam): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''f%oo.html") self.assertEqual('attachment', disptype) self.assertEqual({}, params) def test_attwithfn2231dpct(self): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''A-%2541.html") self.assertEqual('attachment', disptype) self.assertEqual({'filename*': 'A-%41.html'}, params) def test_attwithfn2231abspathdisguised(self): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''%5cfoo.html") self.assertEqual('attachment', disptype) self.assertEqual({'filename*': '\\foo.html'}, params) def test_attfncont(self): disptype, params = parse_content_disposition( 'attachment; filename*0="foo."; filename*1="html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename*0': 'foo.', 'filename*1': 'html'}, params) def test_attfncontqs(self): disptype, params = parse_content_disposition( r'attachment; filename*0="foo"; filename*1="\b\a\r.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename*0': 'foo', 'filename*1': 'bar.html'}, params) def test_attfncontenc(self): disptype, params = parse_content_disposition( 'attachment; filename*0*=UTF-8''foo-%c3%a4; filename*1=".html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename*0*': 'UTF-8''foo-%c3%a4', 'filename*1': '.html'}, params) def test_attfncontlz(self): disptype, params = parse_content_disposition( 'attachment; filename*0="foo"; filename*01="bar"') self.assertEqual('attachment', disptype) self.assertEqual({'filename*0': 'foo', 'filename*01': 'bar'}, params) def test_attfncontnc(self): disptype, params = parse_content_disposition( 'attachment; filename*0="foo"; filename*2="bar"') self.assertEqual('attachment', disptype) self.assertEqual({'filename*0': 'foo', 'filename*2': 'bar'}, params) def test_attfnconts1(self): disptype, params = parse_content_disposition( 'attachment; filename*0="foo."; filename*2="html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename*0': 'foo.', 'filename*2': 'html'}, params) def test_attfncontord(self): disptype, params = parse_content_disposition( 'attachment; filename*1="bar"; filename*0="foo"') self.assertEqual('attachment', disptype) self.assertEqual({'filename*0': 'foo', 'filename*1': 'bar'}, params) def test_attfnboth(self): disptype, params = parse_content_disposition( 'attachment; filename="foo-ae.html";' " filename*=UTF-8''foo-%c3%a4.html") self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo-ae.html', 'filename*': 'foo-ä.html'}, params) def test_attfnboth2(self): disptype, params = parse_content_disposition( "attachment; filename*=UTF-8''foo-%c3%a4.html;" ' filename="foo-ae.html"') self.assertEqual('attachment', disptype) self.assertEqual({'filename': 'foo-ae.html', 'filename*': 'foo-ä.html'}, params) def test_attfnboth3(self): disptype, params = parse_content_disposition( "attachment; filename*0*=ISO-8859-15''euro-sign%3d%a4;" " filename*=ISO-8859-1''currency-sign%3d%a4") self.assertEqual('attachment', disptype) self.assertEqual({'filename*': 'currency-sign=¤', 'filename*0*': "ISO-8859-15''euro-sign%3d%a4"}, params) def test_attnewandfn(self): disptype, params = parse_content_disposition( 'attachment; foobar=x; filename="foo.html"') self.assertEqual('attachment', disptype) self.assertEqual({'foobar': 'x', 'filename': 'foo.html'}, params) def test_attrfc2047token(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionHeader): disptype, params = parse_content_disposition( 'attachment; filename==?ISO-8859-1?Q?foo-=E4.html?=') self.assertEqual(None, disptype) self.assertEqual({}, params) def test_attrfc2047quoted(self): disptype, params = parse_content_disposition( 'attachment; filename="=?ISO-8859-1?Q?foo-=E4.html?="') self.assertEqual('attachment', disptype) self.assertEqual({'filename': '=?ISO-8859-1?Q?foo-=E4.html?='}, params) def test_bad_continuous_param(self): with self.assertWarns(aiohttp.multipart.BadContentDispositionParam): disptype, params = parse_content_disposition( 'attachment; filename*0=foo bar') self.assertEqual('attachment', disptype) self.assertEqual({}, params) class ContentDispositionFilenameTestCase(unittest.TestCase): # http://greenbytes.de/tech/tc2231/ def test_no_filename(self): self.assertIsNone(content_disposition_filename({})) self.assertIsNone(content_disposition_filename({'foo': 'bar'})) def test_filename(self): params = {'filename': 'foo.html'} self.assertEqual('foo.html', content_disposition_filename(params)) def test_filename_ext(self): params = {'filename*': 'файл.html'} self.assertEqual('файл.html', content_disposition_filename(params)) def test_attfncont(self): params = {'filename*0': 'foo.', 'filename*1': 'html'} self.assertEqual('foo.html', content_disposition_filename(params)) def test_attfncontqs(self): params = {'filename*0': 'foo', 'filename*1': 'bar.html'} self.assertEqual('foobar.html', content_disposition_filename(params)) def test_attfncontenc(self): params = {'filename*0*': "UTF-8''foo-%c3%a4", 'filename*1': '.html'} self.assertEqual('foo-ä.html', content_disposition_filename(params)) def test_attfncontlz(self): params = {'filename*0': 'foo', 'filename*01': 'bar'} self.assertEqual('foo', content_disposition_filename(params)) def test_attfncontnc(self): params = {'filename*0': 'foo', 'filename*2': 'bar'} self.assertEqual('foo', content_disposition_filename(params)) def test_attfnconts1(self): params = {'filename*1': 'foo', 'filename*2': 'bar'} self.assertEqual(None, content_disposition_filename(params)) def test_attfnboth(self): params = {'filename': 'foo-ae.html', 'filename*': 'foo-ä.html'} self.assertEqual('foo-ä.html', content_disposition_filename(params)) def test_attfnboth3(self): params = {'filename*0*': "ISO-8859-15''euro-sign%3d%a4", 'filename*': 'currency-sign=¤'} self.assertEqual('currency-sign=¤', content_disposition_filename(params)) def test_attrfc2047quoted(self): params = {'filename': '=?ISO-8859-1?Q?foo-=E4.html?='} self.assertEqual('=?ISO-8859-1?Q?foo-=E4.html?=', content_disposition_filename(params)) aiohttp-0.20.2/tests/test_web_exceptions.py0000664000175000017500000001152212610652253021623 0ustar andrewandrew00000000000000import collections import pytest import re from unittest import mock from aiohttp.multidict import CIMultiDict from aiohttp.web import Request from aiohttp.protocol import RawRequestMessage, HttpVersion11 from aiohttp import signals, web @pytest.fixture def buf(): return bytearray() @pytest.fixture def request(buf): method = 'GET' path = '/' headers = CIMultiDict() transport = mock.Mock() payload = mock.Mock() reader = mock.Mock() writer = mock.Mock() writer.drain.return_value = () def append(data): buf.extend(data) writer.write.side_effect = append app = mock.Mock() app._debug = False app.on_response_prepare = signals.Signal(app) message = RawRequestMessage(method, path, HttpVersion11, headers, False, False) req = Request(app, message, payload, transport, reader, writer) return req def test_all_http_exceptions_exported(): assert 'HTTPException' in web.__all__ for name in dir(web): if name.startswith('_'): continue obj = getattr(web, name) if isinstance(obj, type) and issubclass(obj, web.HTTPException): assert name in web.__all__ @pytest.mark.run_loop def test_HTTPOk(buf, request): resp = web.HTTPOk() yield from resp.prepare(request) yield from resp.write_eof() txt = buf.decode('utf8') assert re.match(('HTTP/1.1 200 OK\r\n' 'CONTENT-TYPE: text/plain; charset=utf-8\r\n' 'CONTENT-LENGTH: 7\r\n' 'CONNECTION: keep-alive\r\n' 'DATE: .+\r\n' 'SERVER: .+\r\n\r\n' '200: OK'), txt) def test_terminal_classes_has_status_code(): terminals = set() for name in dir(web): obj = getattr(web, name) if isinstance(obj, type) and issubclass(obj, web.HTTPException): terminals.add(obj) dup = frozenset(terminals) for cls1 in dup: for cls2 in dup: if cls1 in cls2.__bases__: terminals.discard(cls1) for cls in terminals: assert cls.status_code is not None codes = collections.Counter(cls.status_code for cls in terminals) assert None not in codes assert 1 == codes.most_common(1)[0][1] @pytest.mark.run_loop def test_HTTPFound(buf, request): resp = web.HTTPFound(location='/redirect') assert '/redirect' == resp.location assert '/redirect' == resp.headers['location'] yield from resp.prepare(request) yield from resp.write_eof() txt = buf.decode('utf8') assert re.match('HTTP/1.1 302 Found\r\n' 'CONTENT-TYPE: text/plain; charset=utf-8\r\n' 'CONTENT-LENGTH: 10\r\n' 'LOCATION: /redirect\r\n' 'CONNECTION: keep-alive\r\n' 'DATE: .+\r\n' 'SERVER: .+\r\n\r\n' '302: Found', txt) def test_HTTPFound_empty_location(): with pytest.raises(ValueError): web.HTTPFound(location='') with pytest.raises(ValueError): web.HTTPFound(location=None) @pytest.mark.run_loop def test_HTTPMethodNotAllowed(buf, request): resp = web.HTTPMethodNotAllowed('get', ['POST', 'PUT']) assert 'GET' == resp.method assert ['POST', 'PUT'] == resp.allowed_methods assert 'POST,PUT' == resp.headers['allow'] yield from resp.prepare(request) yield from resp.write_eof() txt = buf.decode('utf8') assert re.match('HTTP/1.1 405 Method Not Allowed\r\n' 'CONTENT-TYPE: text/plain; charset=utf-8\r\n' 'CONTENT-LENGTH: 23\r\n' 'ALLOW: POST,PUT\r\n' 'CONNECTION: keep-alive\r\n' 'DATE: .+\r\n' 'SERVER: .+\r\n\r\n' '405: Method Not Allowed', txt) def test_override_body_with_text(): resp = web.HTTPNotFound(text="Page not found") assert 404 == resp.status assert "Page not found".encode('utf-8') == resp.body assert "Page not found" == resp.text assert "text/plain" == resp.content_type assert "utf-8" == resp.charset def test_override_body_with_binary(): txt = "Page not found" 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 assert "text/html" == resp.content_type assert resp.charset is None def test_default_body(): resp = web.HTTPOk() assert b'200: OK' == resp.body def test_empty_body_204(): resp = web.HTTPNoContent() assert resp.body is None def test_empty_body_205(): resp = web.HTTPNoContent() assert resp.body is None def test_empty_body_304(): resp = web.HTTPNoContent() resp.body is None aiohttp-0.20.2/tests/test_timeout.py0000664000175000017500000000707612640577352020315 0ustar andrewandrew00000000000000import asyncio import time import pytest from aiohttp.helpers import ensure_future, Timeout @pytest.mark.run_loop def test_timeout(loop): canceled_raised = False @asyncio.coroutine def long_running_task(): try: yield from asyncio.sleep(10, loop=loop) except asyncio.CancelledError: nonlocal canceled_raised canceled_raised = True raise with pytest.raises(asyncio.TimeoutError): with Timeout(0.01, loop=loop) as t: yield from long_running_task() assert t._loop is loop assert canceled_raised, 'CancelledError was not raised' @pytest.mark.run_loop def test_timeout_finish_in_time(loop): @asyncio.coroutine def long_running_task(): yield from asyncio.sleep(0.01, loop=loop) return 'done' with Timeout(0.1, loop=loop): resp = yield from long_running_task() assert resp == 'done' def test_timeout_gloabal_loop(loop): asyncio.set_event_loop(loop) @asyncio.coroutine def run(): with Timeout(0.1) as t: yield from asyncio.sleep(0.01) assert t._loop is loop loop.run_until_complete(run()) @pytest.mark.run_loop def test_timeout_not_relevant_exception(loop): yield from asyncio.sleep(0, loop=loop) with pytest.raises(KeyError): with Timeout(0.1, loop=loop): raise KeyError @pytest.mark.run_loop def test_timeout_canceled_error_is_converted_to_timeout(loop): yield from asyncio.sleep(0, loop=loop) with pytest.raises(asyncio.CancelledError): with Timeout(0.001, loop=loop): raise asyncio.CancelledError @pytest.mark.run_loop def test_timeout_blocking_loop(loop): @asyncio.coroutine def long_running_task(): time.sleep(0.1) return 'done' with Timeout(0.01, loop=loop): result = yield from long_running_task() assert result == 'done' @pytest.mark.run_loop def test_for_race_conditions(loop): fut = asyncio.Future(loop=loop) loop.call_later(0.1, fut.set_result('done')) with Timeout(0.2, loop=loop): resp = yield from fut assert resp == 'done' @pytest.mark.run_loop def test_timeout_time(loop): foo_running = None start = loop.time() with pytest.raises(asyncio.TimeoutError): with Timeout(0.1, loop=loop): foo_running = True try: yield from asyncio.sleep(0.2, loop=loop) finally: foo_running = False assert abs(0.1 - (loop.time() - start)) < 0.01 assert not foo_running def test_raise_runtimeerror_if_no_task(loop): with pytest.raises(RuntimeError): with Timeout(0.1, loop=loop): pass @pytest.mark.run_loop def test_outer_coro_is_not_cancelled(loop): has_timeout = False @asyncio.coroutine def outer(): nonlocal has_timeout try: with Timeout(0.001, loop=loop): yield from asyncio.sleep(1, loop=loop) except asyncio.TimeoutError: has_timeout = True task = ensure_future(outer(), loop=loop) yield from task assert has_timeout assert not task.cancelled() assert task.done() @pytest.mark.run_loop def test_cancel_outer_coro(loop): fut = asyncio.Future(loop=loop) @asyncio.coroutine def outer(): fut.set_result(None) yield from asyncio.sleep(1, loop=loop) task = ensure_future(outer(), loop=loop) yield from fut task.cancel() with pytest.raises(asyncio.CancelledError): yield from task assert task.cancelled() assert task.done() aiohttp-0.20.2/tests/sample.key0000664000175000017500000000156712552474754017214 0ustar andrewandrew00000000000000-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQCnt3s+J7L0xP/YdAQOacpPi9phlrzKZhcXL3XMu2LCUg2fNJpx /47Vc5TZSaO11uO7gdwVz3Z7Q2epAgwo59JLffLt5fia8+a/SlPweI/j4+wcIIIi qusnLfpqR8cIAavgZ06cLYCDvb9wMlheIvSJY12skc1nnphWS2YJ0Xm6uQIDAQAB AoGABfm8k19Yue3W68BecKEGS0VBV57GRTPT+MiBGvVGNIQ15gk6w3sGfMZsdD1y bsUkQgcDb2d/4i5poBTpl/+Cd41V+c20IC/sSl5X1IEreHMKSLhy/uyjyiyfXlP1 iXhToFCgLWwENWc8LzfUV8vuAV5WG6oL9bnudWzZxeqx8V0CQQDR7xwVj6LN70Eb DUhSKLkusmFw5Gk9NJ/7wZ4eHg4B8c9KNVvSlLCLhcsVTQXuqYeFpOqytI45SneP lr0vrvsDAkEAzITYiXu6ox5huDCG7imX2W9CAYuX638urLxBqBXMS7GqBzojD6RL 21Q8oPwJWJquERa3HDScq1deiQbM9uKIkwJBAIa1PLslGN216Xv3UPHPScyKD/aF ynXIv+OnANPoiyp6RH4ksQ/18zcEGiVH8EeNpvV9tlAHhb+DZibQHgNr74sCQQC0 zhToplu/bVKSlUQUNO0rqrI9z30FErDewKeCw5KSsIRSU1E/uM3fHr9iyq4wiL6u GNjUtKZ0y46lsT9uW6LFAkB5eqeEQnshAdr3X5GykWHJ8DDGBXPPn6Rce1NX4RSq V9khG2z1bFyfo+hMqpYnF2k32hVq3E54RS8YYnwBsVof -----END RSA PRIVATE KEY----- aiohttp-0.20.2/tests/test_web_request_handler.py0000664000175000017500000000325712610647006022635 0ustar andrewandrew00000000000000import pytest from aiohttp import web from unittest import mock def test_repr(loop): app = web.Application(loop=loop) manager = app.make_handler() handler = manager() assert '' == repr(handler) handler.transport = object() handler._meth = 'GET' handler._path = '/index.html' assert '' == repr(handler) def test_connections(loop): app = web.Application(loop=loop) manager = app.make_handler() assert manager.connections == [] handler = object() transport = object() manager.connection_made(handler, transport) assert manager.connections == [handler] manager.connection_lost(handler, None) assert manager.connections == [] @pytest.mark.run_loop def test_finish_connection_no_timeout(loop): app = web.Application(loop=loop) manager = app.make_handler() handler = mock.Mock() transport = mock.Mock() manager.connection_made(handler, transport) yield from manager.finish_connections() manager.connection_lost(handler, None) assert manager.connections == [] handler.closing.assert_called_with(timeout=None) transport.close.assert_called_with() @pytest.mark.run_loop def test_finish_connection_timeout(loop): app = web.Application(loop=loop) manager = app.make_handler() handler = mock.Mock() transport = mock.Mock() manager.connection_made(handler, transport) yield from manager.finish_connections(timeout=0.1) manager.connection_lost(handler, None) assert manager.connections == [] handler.closing.assert_called_with(timeout=0.09) transport.close.assert_called_with() aiohttp-0.20.2/tests/test_websocket_client.py0000664000175000017500000003650312636357712022151 0ustar andrewandrew00000000000000import asyncio import base64 import hashlib import os import unittest from unittest import mock import aiohttp from aiohttp import errors, hdrs, websocket, websocket_client class TestWebSocketClient(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) self.key_data = os.urandom(16) self.key = base64.b64encode(self.key_data) self.ws_key = base64.b64encode( hashlib.sha1(self.key + websocket.WS_KEY).digest()).decode() def tearDown(self): self.loop.close() @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_ws_connect(self, m_req, m_os): resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key, hdrs.SEC_WEBSOCKET_PROTOCOL: 'chat' } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) res = self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', protocols=('t1', 't2', 'chat'), loop=self.loop)) self.assertIsInstance(res, websocket_client.ClientWebSocketResponse) self.assertEqual(res.protocol, 'chat') self.assertNotIn(hdrs.ORIGIN, m_req.call_args[1]["headers"]) @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_ws_connect_with_origin(self, m_req, m_os): resp = mock.Mock() resp.status = 403 m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) origin = 'https://example.org/page.html' with self.assertRaises(errors.WSServerHandshakeError): self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', loop=self.loop, origin=origin)) self.assertIn(hdrs.ORIGIN, m_req.call_args[1]["headers"]) self.assertEqual(m_req.call_args[1]["headers"][hdrs.ORIGIN], origin) @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_ws_connect_custom_response(self, m_req, m_os): class CustomResponse(websocket_client.ClientWebSocketResponse): def read(self, decode=False): return 'customized!' resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key, } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) res = self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', ws_response_class=CustomResponse, loop=self.loop)) self.assertEqual(res.read(), 'customized!') @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_ws_connect_global_loop(self, m_req, m_os): asyncio.set_event_loop(self.loop) resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) resp = self.loop.run_until_complete( aiohttp.ws_connect('http://test.org')) self.assertIs(resp._loop, self.loop) asyncio.set_event_loop(None) @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_ws_connect_err_status(self, m_req, m_os): resp = mock.Mock() resp.status = 500 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) with self.assertRaises(errors.WSServerHandshakeError) as ctx: self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', protocols=('t1', 't2', 'chat'), loop=self.loop)) self.assertEqual( ctx.exception.message, 'Invalid response status') @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_ws_connect_err_upgrade(self, m_req, m_os): resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: 'test', hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) with self.assertRaises(errors.WSServerHandshakeError) as ctx: self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', protocols=('t1', 't2', 'chat'), loop=self.loop)) self.assertEqual( ctx.exception.message, 'Invalid upgrade header') @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_ws_connect_err_conn(self, m_req, m_os): resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: 'close', hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) with self.assertRaises(errors.WSServerHandshakeError) as ctx: self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', protocols=('t1', 't2', 'chat'), loop=self.loop)) self.assertEqual( ctx.exception.message, 'Invalid connection header') @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_ws_connect_err_challenge(self, m_req, m_os): resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: 'asdfasdfasdfasdfasdfasdf' } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) with self.assertRaises(errors.WSServerHandshakeError) as ctx: self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', protocols=('t1', 't2', 'chat'), loop=self.loop)) self.assertEqual( ctx.exception.message, 'Invalid challenge response') @mock.patch('aiohttp.client.WebSocketWriter') @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_close(self, m_req, m_os, WebSocketWriter): resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key, } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) writer = WebSocketWriter.return_value = mock.Mock() reader = resp.connection.reader.set_parser.return_value = mock.Mock() resp = self.loop.run_until_complete( aiohttp.ws_connect('http://test.org', loop=self.loop)) self.assertFalse(resp.closed) msg = websocket.Message(websocket.MSG_CLOSE, b'', b'') reader.read.return_value = asyncio.Future(loop=self.loop) reader.read.return_value.set_result(msg) res = self.loop.run_until_complete(resp.close()) writer.close.assert_called_with(1000, b'') self.assertTrue(resp.closed) self.assertTrue(res) self.assertIsNone(resp.exception()) # idempotent res = self.loop.run_until_complete(resp.close()) self.assertFalse(res) self.assertEqual(writer.close.call_count, 1) @mock.patch('aiohttp.client.WebSocketWriter') @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_close_exc(self, m_req, m_os, WebSocketWriter): resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key, } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) WebSocketWriter.return_value = mock.Mock() reader = resp.connection.reader.set_parser.return_value = mock.Mock() resp = self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', loop=self.loop)) self.assertFalse(resp.closed) exc = ValueError() reader.read.return_value = asyncio.Future(loop=self.loop) reader.read.return_value.set_exception(exc) self.loop.run_until_complete(resp.close()) self.assertTrue(resp.closed) self.assertIs(resp.exception(), exc) @mock.patch('aiohttp.client.WebSocketWriter') @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_close_exc2(self, m_req, m_os, WebSocketWriter): resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key, } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) writer = WebSocketWriter.return_value = mock.Mock() resp.connection.reader.set_parser.return_value = mock.Mock() resp = self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', loop=self.loop)) self.assertFalse(resp.closed) exc = ValueError() writer.close.side_effect = exc self.loop.run_until_complete(resp.close()) self.assertTrue(resp.closed) self.assertIs(resp.exception(), exc) resp._closed = False writer.close.side_effect = asyncio.CancelledError() self.assertRaises(asyncio.CancelledError, self.loop.run_until_complete, resp.close()) @mock.patch('aiohttp.client.WebSocketWriter') @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_send_data_after_close(self, m_req, m_os, WebSocketWriter): resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key, } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) WebSocketWriter.return_value = mock.Mock() resp = self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', loop=self.loop)) resp._closed = True self.assertRaises(RuntimeError, resp.ping) self.assertRaises(RuntimeError, resp.pong) self.assertRaises(RuntimeError, resp.send_str, 's') self.assertRaises(RuntimeError, resp.send_bytes, b'b') @mock.patch('aiohttp.client.WebSocketWriter') @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_send_data_type_errors(self, m_req, m_os, WebSocketWriter): resp = mock.Mock() resp.status = 101 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key, } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) WebSocketWriter.return_value = mock.Mock() resp = self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', loop=self.loop)) self.assertRaises(TypeError, resp.send_str, b's') self.assertRaises(TypeError, resp.send_bytes, 'b') @mock.patch('aiohttp.client.WebSocketWriter') @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_reader_read_exception(self, m_req, m_os, WebSocketWriter): hresp = mock.Mock() hresp.status = 101 hresp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key, } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(hresp) WebSocketWriter.return_value = mock.Mock() reader = hresp.connection.reader.set_parser.return_value = mock.Mock() resp = self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', loop=self.loop)) exc = ValueError() reader.read.return_value = asyncio.Future(loop=self.loop) reader.read.return_value.set_exception(exc) msg = self.loop.run_until_complete(resp.receive()) self.assertEqual(msg.tp, aiohttp.MsgType.error) self.assertIs(resp.exception(), exc) def test_receive_runtime_err(self): resp = websocket_client.ClientWebSocketResponse( mock.Mock(), mock.Mock(), mock.Mock(), mock.Mock(), 10.0, True, True, self.loop) resp._waiting = True self.assertRaises( RuntimeError, self.loop.run_until_complete, resp.receive()) @mock.patch('aiohttp.client.os') @mock.patch('aiohttp.client.ClientSession.get') def test_ws_connect_close_resp_on_err(self, m_req, m_os): resp = mock.Mock() resp.status = 500 resp.headers = { hdrs.UPGRADE: hdrs.WEBSOCKET, hdrs.CONNECTION: hdrs.UPGRADE, hdrs.SEC_WEBSOCKET_ACCEPT: self.ws_key } m_os.urandom.return_value = self.key_data m_req.return_value = asyncio.Future(loop=self.loop) m_req.return_value.set_result(resp) with self.assertRaises(errors.WSServerHandshakeError): self.loop.run_until_complete( aiohttp.ws_connect( 'http://test.org', protocols=('t1', 't2', 'chat'), loop=self.loop)) resp.close.assert_called_with() aiohttp-0.20.2/tests/hello.txt.gz0000664000175000017500000000005412552474754017472 0ustar andrewandrew00000000000000‹Ð1%Uhello.txtËHÍÉÉWHÌÌÏ())à6¨‚aiohttp-0.20.2/tests/test_classbasedview.py0000664000175000017500000000234112637063114021604 0ustar andrewandrew00000000000000import asyncio import pytest from aiohttp import web from aiohttp.web_urldispatcher import View from unittest import mock def test_ctor(): request = mock.Mock() view = View(request) assert view.request is request @pytest.mark.run_loop def test_render_ok(): resp = web.Response(text='OK') class MyView(View): @asyncio.coroutine def get(self): return resp request = mock.Mock() request.method = 'GET' resp2 = yield from MyView(request) assert resp is resp2 @pytest.mark.run_loop def test_render_unknown_method(): class MyView(View): @asyncio.coroutine def get(self): return web.Response(text='OK') request = mock.Mock() request.method = 'UNKNOWN' with pytest.raises(web.HTTPMethodNotAllowed) as ctx: yield from MyView(request) assert ctx.value.status == 405 @pytest.mark.run_loop def test_render_unsupported_method(): class MyView(View): @asyncio.coroutine def get(self): return web.Response(text='OK') request = mock.Mock() request.method = 'POST' with pytest.raises(web.HTTPMethodNotAllowed) as ctx: yield from MyView(request) assert ctx.value.status == 405 aiohttp-0.20.2/tests/test_protocol.py0000664000175000017500000003352712642271271020461 0ustar andrewandrew00000000000000"""Tests for aiohttp/protocol.py""" import pytest from unittest import mock import zlib from aiohttp import hdrs, protocol @pytest.fixture def transport(): return mock.Mock() compressor = zlib.compressobj(wbits=-zlib.MAX_WBITS) COMPRESSED = b''.join([compressor.compress(b'data'), compressor.flush()]) def test_start_request(transport): msg = protocol.Request( transport, 'GET', '/index.html', close=True) assert msg.transport is transport assert msg.closing assert msg.status_line == 'GET /index.html HTTP/1.1\r\n' def test_start_response(transport): msg = protocol.Response(transport, 200, close=True) assert msg.transport is transport assert msg.status == 200 assert msg.reason == "OK" assert msg.closing assert msg.status_line == 'HTTP/1.1 200 OK\r\n' def test_start_response_with_reason(transport): msg = protocol.Response(transport, 333, close=True, reason="My Reason") assert msg.status == 333 assert msg.reason == "My Reason" assert msg.status_line == 'HTTP/1.1 333 My Reason\r\n' def test_start_response_with_unknown_reason(transport): msg = protocol.Response(transport, 777, close=True) assert msg.status == 777 assert msg.reason == "777" assert msg.status_line == 'HTTP/1.1 777 777\r\n' def test_force_close(transport): msg = protocol.Response(transport, 200) assert not msg.closing msg.force_close() assert msg.closing def test_force_chunked(transport): msg = protocol.Response(transport, 200) assert not msg.chunked msg.enable_chunked_encoding() assert msg.chunked def test_keep_alive(transport): msg = protocol.Response(transport, 200, close=True) assert not msg.keep_alive() msg.keepalive = True assert msg.keep_alive() msg.force_close() assert not msg.keep_alive() def test_keep_alive_http10(transport): msg = protocol.Response(transport, 200, http_version=(1, 0)) assert not msg.keepalive assert not msg.keep_alive() msg = protocol.Response(transport, 200, http_version=(1, 1)) assert msg.keepalive is None def test_add_header(transport): msg = protocol.Response(transport, 200) assert [] == list(msg.headers) msg.add_header('content-type', 'plain/html') assert [('CONTENT-TYPE', 'plain/html')] == list(msg.headers.items()) def test_add_header_with_spaces(transport): msg = protocol.Response(transport, 200) assert [] == list(msg.headers) msg.add_header('content-type', ' plain/html ') assert [('CONTENT-TYPE', 'plain/html')] == list(msg.headers.items()) def test_add_header_non_ascii(transport): msg = protocol.Response(transport, 200) assert [] == list(msg.headers) with pytest.raises(AssertionError): msg.add_header('тип-контента', 'текÑÑ‚/плейн') def test_add_header_invalid_value_type(transport): msg = protocol.Response(transport, 200) assert [] == list(msg.headers) with pytest.raises(AssertionError): msg.add_header('content-type', {'test': 'plain'}) with pytest.raises(AssertionError): msg.add_header(list('content-type'), 'text/plain') def test_add_headers(transport): msg = protocol.Response(transport, 200) assert [] == list(msg.headers) msg.add_headers(('content-type', 'plain/html')) assert [('CONTENT-TYPE', 'plain/html')] == list(msg.headers.items()) def test_add_headers_length(transport): msg = protocol.Response(transport, 200) assert msg.length is None msg.add_headers(('content-length', '42')) assert 42 == msg.length def test_add_headers_upgrade(transport): msg = protocol.Response(transport, 200) assert not msg.upgrade msg.add_headers(('connection', 'upgrade')) assert msg.upgrade def test_add_headers_upgrade_websocket(transport): msg = protocol.Response(transport, 200) msg.add_headers(('upgrade', 'test')) assert [] == list(msg.headers) msg.add_headers(('upgrade', 'websocket')) assert [('UPGRADE', 'websocket')] == list(msg.headers.items()) def test_add_headers_connection_keepalive(transport): msg = protocol.Response(transport, 200) msg.add_headers(('connection', 'keep-alive')) assert [] == list(msg.headers) assert msg.keepalive msg.add_headers(('connection', 'close')) assert not msg.keepalive def test_add_headers_hop_headers(transport): msg = protocol.Response(transport, 200) msg.HOP_HEADERS = (hdrs.TRANSFER_ENCODING,) msg.add_headers(('connection', 'test'), ('transfer-encoding', 't')) assert [] == list(msg.headers) def test_default_headers(transport): msg = protocol.Response(transport, 200) msg._add_default_headers() headers = [r for r, _ in msg.headers.items()] assert 'DATE' in headers assert 'CONNECTION' in headers def test_default_headers_server(transport): msg = protocol.Response(transport, 200) msg._add_default_headers() assert 'SERVER' in msg.headers def test_default_headers_chunked(transport): msg = protocol.Response(transport, 200) msg._add_default_headers() headers = [r for r, _ in msg.headers.items()] assert 'TRANSFER-ENCODING' not in headers msg = protocol.Response(transport, 200) msg.enable_chunked_encoding() msg.send_headers() headers = [r for r, _ in msg.headers.items()] assert 'TRANSFER-ENCODING' in headers def test_default_headers_connection_upgrade(transport): msg = protocol.Response(transport, 200) msg.upgrade = True msg._add_default_headers() headers = [r for r in msg.headers.items() if r[0] == 'CONNECTION'] assert [('CONNECTION', 'upgrade')] == headers def test_default_headers_connection_close(transport): msg = protocol.Response(transport, 200) msg.force_close() msg._add_default_headers() headers = [r for r in msg.headers.items() if r[0] == 'CONNECTION'] assert [('CONNECTION', 'close')] == headers def test_default_headers_connection_keep_alive(transport): msg = protocol.Response(transport, 200) msg.keepalive = True msg._add_default_headers() headers = [r for r in msg.headers.items() if r[0] == 'CONNECTION'] assert [('CONNECTION', 'keep-alive')] == headers def test_send_headers(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.add_headers(('content-type', 'plain/html')) assert not msg.is_headers_sent() msg.send_headers() content = b''.join([arg[1][0] for arg in list(write.mock_calls)]) assert content.startswith(b'HTTP/1.1 200 OK\r\n') assert b'CONTENT-TYPE: plain/html' in content assert msg.headers_sent assert msg.is_headers_sent() # cleanup msg.writer.close() def test_send_headers_non_ascii(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.add_headers(('x-header', 'текÑÑ‚')) assert not msg.is_headers_sent() msg.send_headers() content = b''.join([arg[1][0] for arg in list(write.mock_calls)]) assert content.startswith(b'HTTP/1.1 200 OK\r\n') assert b'X-HEADER: \xd1\x82\xd0\xb5\xd0\xba\xd1\x81\xd1\x82' in content assert msg.headers_sent assert msg.is_headers_sent() # cleanup msg.writer.close() def test_send_headers_nomore_add(transport): msg = protocol.Response(transport, 200) msg.add_headers(('content-type', 'plain/html')) msg.send_headers() with pytest.raises(AssertionError): msg.add_header('content-type', 'plain/html') # cleanup msg.writer.close() def test_prepare_length(transport): msg = protocol.Response(transport, 200) w_l_p = msg._write_length_payload = mock.Mock() w_l_p.return_value = iter([1, 2, 3]) msg.add_headers(('content-length', '42')) msg.send_headers() assert w_l_p.called assert (42,) == w_l_p.call_args[0] def test_prepare_chunked_force(transport): msg = protocol.Response(transport, 200) msg.enable_chunked_encoding() chunked = msg._write_chunked_payload = mock.Mock() chunked.return_value = iter([1, 2, 3]) msg.add_headers(('content-length', '42')) msg.send_headers() assert chunked.called def test_prepare_chunked_no_length(transport): msg = protocol.Response(transport, 200) chunked = msg._write_chunked_payload = mock.Mock() chunked.return_value = iter([1, 2, 3]) msg.send_headers() assert chunked.called def test_prepare_eof(transport): msg = protocol.Response(transport, 200, http_version=(1, 0)) eof = msg._write_eof_payload = mock.Mock() eof.return_value = iter([1, 2, 3]) msg.send_headers() assert eof.called def test_write_auto_send_headers(transport): msg = protocol.Response(transport, 200, http_version=(1, 0)) msg._send_headers = True msg.write(b'data1') assert msg.headers_sent # cleanup msg.writer.close() def test_write_payload_eof(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200, http_version=(1, 0)) msg.send_headers() msg.write(b'data1') assert msg.headers_sent msg.write(b'data2') msg.write_eof() content = b''.join([c[1][0] for c in list(write.mock_calls)]) assert b'data1data2' == content.split(b'\r\n\r\n', 1)[-1] def test_write_payload_chunked(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.enable_chunked_encoding() msg.send_headers() msg.write(b'data') msg.write_eof() content = b''.join([c[1][0] for c in list(write.mock_calls)]) assert b'4\r\ndata\r\n0\r\n\r\n' == content.split(b'\r\n\r\n', 1)[-1] def test_write_payload_chunked_multiple(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.enable_chunked_encoding() msg.send_headers() msg.write(b'data1') msg.write(b'data2') msg.write_eof() content = b''.join([c[1][0] for c in list(write.mock_calls)]) assert (b'5\r\ndata1\r\n5\r\ndata2\r\n0\r\n\r\n' == content.split(b'\r\n\r\n', 1)[-1]) def test_write_payload_length(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.add_headers(('content-length', '2')) msg.send_headers() msg.write(b'd') msg.write(b'ata') msg.write_eof() content = b''.join([c[1][0] for c in list(write.mock_calls)]) assert b'da' == content.split(b'\r\n\r\n', 1)[-1] def test_write_payload_chunked_filter(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.send_headers() msg.add_chunking_filter(2) msg.write(b'data') msg.write_eof() content = b''.join([c[1][0] for c in list(write.mock_calls)]) assert content.endswith(b'2\r\nda\r\n2\r\nta\r\n0\r\n\r\n') def test_write_payload_chunked_filter_mutiple_chunks(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.send_headers() msg.add_chunking_filter(2) msg.write(b'data1') msg.write(b'data2') msg.write_eof() content = b''.join([c[1][0] for c in list(write.mock_calls)]) assert content.endswith( b'2\r\nda\r\n2\r\nta\r\n2\r\n1d\r\n2\r\nat\r\n' b'2\r\na2\r\n0\r\n\r\n') def test_write_payload_chunked_large_chunk(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.send_headers() msg.add_chunking_filter(1024) msg.write(b'data') msg.write_eof() content = b''.join([c[1][0] for c in list(write.mock_calls)]) assert content.endswith(b'4\r\ndata\r\n0\r\n\r\n') def test_write_payload_deflate_filter(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.add_headers(('content-length', '{}'.format(len(COMPRESSED)))) msg.send_headers() msg.add_compression_filter('deflate') msg.write(b'data') msg.write_eof() chunks = [c[1][0] for c in list(write.mock_calls)] assert all(chunks) content = b''.join(chunks) assert COMPRESSED == content.split(b'\r\n\r\n', 1)[-1] def test_write_payload_deflate_and_chunked(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.send_headers() msg.add_compression_filter('deflate') msg.add_chunking_filter(2) msg.write(b'data') msg.write_eof() chunks = [c[1][0] for c in list(write.mock_calls)] assert all(chunks) content = b''.join(chunks) assert (b'2\r\nKI\r\n2\r\n,I\r\n2\r\n\x04\x00\r\n0\r\n\r\n' == content.split(b'\r\n\r\n', 1)[-1]) def test_write_payload_chunked_and_deflate(transport): write = transport.write = mock.Mock() msg = protocol.Response(transport, 200) msg.add_headers(('content-length', '{}'.format(len(COMPRESSED)))) msg.add_chunking_filter(2) msg.add_compression_filter('deflate') msg.send_headers() msg.write(b'data') msg.write_eof() chunks = [c[1][0] for c in list(write.mock_calls)] assert all(chunks) content = b''.join(chunks) assert COMPRESSED == content.split(b'\r\n\r\n', 1)[-1] def test_write_drain(transport): msg = protocol.Response(transport, 200, http_version=(1, 0)) msg._send_headers = True msg.write(b'1' * (64 * 1024 * 2)) assert not transport.drain.called msg.write(b'1', drain=True) assert transport.drain.called assert msg._output_size == 0 def test_dont_override_request_headers_with_default_values(transport): msg = protocol.Request( transport, 'GET', '/index.html', close=True) msg.add_header('USER-AGENT', 'custom') msg._add_default_headers() assert 'custom' == msg.headers['USER-AGENT'] def test_dont_override_response_headers_with_default_values(transport): msg = protocol.Response(transport, 200, http_version=(1, 0)) msg.add_header('DATE', 'now') msg.add_header('SERVER', 'custom') msg._add_default_headers() assert 'custom' == msg.headers['SERVER'] assert 'now' == msg.headers['DATE'] aiohttp-0.20.2/tests/test_web_websocket_functional.py0000664000175000017500000003233512602466630023662 0ustar andrewandrew00000000000000import asyncio import base64 import hashlib import os import socket import unittest import aiohttp from aiohttp import web, websocket WS_KEY = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" class TestWebWebSocketFunctional(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): self.loop.close() def find_unused_port(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 0)) port = s.getsockname()[1] s.close() return port @asyncio.coroutine def create_server(self, method, path, handler): app = web.Application(loop=self.loop) app.router.add_route(method, path, handler) port = self.find_unused_port() srv = yield from self.loop.create_server( app.make_handler(), '127.0.0.1', port) url = "http://127.0.0.1:{}".format(port) + path self.addCleanup(srv.close) return app, srv, url @asyncio.coroutine def connect_ws(self, url, protocol=None): sec_key = base64.b64encode(os.urandom(16)) conn = aiohttp.TCPConnector(loop=self.loop) self.addCleanup(conn.close) headers = { 'UPGRADE': 'WebSocket', 'CONNECTION': 'Upgrade', 'SEC-WEBSOCKET-VERSION': '13', 'SEC-WEBSOCKET-KEY': sec_key.decode(), } if protocol: headers['SEC-WEBSOCKET-PROTOCOL'] = protocol # send request response = yield from aiohttp.request( 'get', url, headers=headers, connector=conn, loop=self.loop) self.addCleanup(response.close, True) self.assertEqual(101, response.status) self.assertEqual(response.headers.get('upgrade', '').lower(), 'websocket') self.assertEqual(response.headers.get('connection', '').lower(), 'upgrade') key = response.headers.get('sec-websocket-accept', '').encode() match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()) self.assertEqual(key, match) # switch to websocket protocol connection = response.connection reader = connection.reader.set_parser(websocket.WebSocketParser) writer = websocket.WebSocketWriter(connection.writer) return response, reader, writer def test_send_recv_text(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) msg = yield from ws.receive_str() ws.send_str(msg+'/answer') yield from ws.close() closed.set_result(1) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp, reader, writer = yield from self.connect_ws(url) writer.send('ask') msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_TEXT) self.assertEqual('ask/answer', msg.data) msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_CLOSE) self.assertEqual(msg.data, 1000) self.assertEqual(msg.extra, '') writer.close() yield from closed resp.close() self.loop.run_until_complete(go()) def test_send_recv_bytes(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) msg = yield from ws.receive_bytes() ws.send_bytes(msg+b'/answer') yield from ws.close() closed.set_result(1) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp, reader, writer = yield from self.connect_ws(url) writer.send(b'ask', binary=True) msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_BINARY) self.assertEqual(b'ask/answer', msg.data) msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_CLOSE) self.assertEqual(msg.data, 1000) self.assertEqual(msg.extra, '') writer.close() yield from closed resp.close() self.loop.run_until_complete(go()) def test_auto_pong_with_closing_by_peer(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) yield from ws.receive() msg = yield from ws.receive() self.assertEqual(msg.tp, web.MsgType.close) self.assertEqual(msg.data, 1000) self.assertEqual(msg.extra, 'exit message') closed.set_result(None) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp, reader, writer = yield from self.connect_ws(url) writer.ping() writer.send('ask') msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_PONG) writer.close(1000, 'exit message') yield from closed resp.close() self.loop.run_until_complete(go()) def test_ping(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) ws.ping('data') yield from ws.receive() closed.set_result(None) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp, reader, writer = yield from self.connect_ws(url) msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_PING) self.assertEqual(msg.data, b'data') writer.pong() writer.close(2, 'exit message') yield from closed resp.close() self.loop.run_until_complete(go()) def test_client_ping(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) yield from ws.receive() closed.set_result(None) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp, reader, writer = yield from self.connect_ws(url) writer.ping('data') msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_PONG) self.assertEqual(msg.data, b'data') writer.pong() writer.close() yield from closed resp.close() self.loop.run_until_complete(go()) def test_pong(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse(autoping=False) yield from ws.prepare(request) msg = yield from ws.receive() self.assertEqual(msg.tp, web.MsgType.ping) ws.pong('data') msg = yield from ws.receive() self.assertEqual(msg.tp, web.MsgType.close) self.assertEqual(msg.data, 1000) self.assertEqual(msg.extra, 'exit message') closed.set_result(None) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp, reader, writer = yield from self.connect_ws(url) writer.ping('data') msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_PONG) self.assertEqual(msg.data, b'data') writer.close(1000, 'exit message') yield from closed resp.close() self.loop.run_until_complete(go()) def test_change_status(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() ws.set_status(200) self.assertEqual(200, ws.status) yield from ws.prepare(request) self.assertEqual(101, ws.status) yield from ws.close() closed.set_result(None) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp, _, writer = yield from self.connect_ws(url) writer.close() yield from closed resp.close() self.loop.run_until_complete(go()) def test_handle_protocol(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse(protocols=('foo', 'bar')) yield from ws.prepare(request) yield from ws.close() self.assertEqual('bar', ws.protocol) closed.set_result(None) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp, _, writer = yield from self.connect_ws(url, 'eggs, bar') writer.close() yield from closed resp.close() self.loop.run_until_complete(go()) def test_server_close_handshake(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse(protocols=('foo', 'bar')) yield from ws.prepare(request) yield from ws.close() closed.set_result(None) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp, reader, writer = yield from self.connect_ws(url, 'eggs, bar') msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_CLOSE) writer.close() yield from closed resp.close() self.loop.run_until_complete(go()) def test_client_close_handshake(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse( autoclose=False, protocols=('foo', 'bar')) yield from ws.prepare(request) msg = yield from ws.receive() self.assertEqual(msg.tp, web.MsgType.close) self.assertFalse(ws.closed) yield from ws.close() self.assertTrue(ws.closed) self.assertEqual(ws.close_code, 1007) msg = yield from ws.receive() self.assertEqual(msg.tp, web.MsgType.closed) closed.set_result(None) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp, reader, writer = yield from self.connect_ws(url, 'eggs, bar') writer.close(code=1007) msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_CLOSE) yield from closed resp.close() self.loop.run_until_complete(go()) def test_server_close_handshake_server_eats_client_messages(self): closed = asyncio.Future(loop=self.loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse(protocols=('foo', 'bar')) yield from ws.prepare(request) yield from ws.close() closed.set_result(None) return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) response, reader, writer = yield from self.connect_ws( url, 'eggs, bar') msg = yield from reader.read() self.assertEqual(msg.tp, websocket.MSG_CLOSE) writer.send('text') writer.send(b'bytes', binary=True) writer.ping() writer.close() yield from closed response.close() self.loop.run_until_complete(go()) def test_receive_msg(self): @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) with self.assertWarns(DeprecationWarning): msg = yield from ws.receive_msg() self.assertEqual(msg.data, b'data') yield from ws.close() return ws @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp = yield from aiohttp.ws_connect(url, loop=self.loop) resp.send_bytes(b'data') yield from resp.close() self.loop.run_until_complete(go()) aiohttp-0.20.2/tests/test_websocket_writer.py0000664000175000017500000000321612610445740022171 0ustar andrewandrew00000000000000import pytest import random from aiohttp import websocket from unittest import mock @pytest.fixture def transport(): return mock.Mock() @pytest.fixture def writer(transport): return websocket.WebSocketWriter(transport, use_mask=False) def test_pong(transport, writer): writer.pong() transport.write.assert_called_with(b'\x8a\x00') def test_ping(transport, writer): writer.ping() transport.write.assert_called_with(b'\x89\x00') def test_send_text(transport, writer): writer.send(b'text') transport.write.assert_called_with(b'\x81\x04text') def test_send_binary(transport, writer): writer.send('binary', True) transport.write.assert_called_with(b'\x82\x06binary') def test_send_binary_long(transport, writer): writer.send(b'b' * 127, True) assert transport.write.call_args[0][0].startswith(b'\x82~\x00\x7fb') def test_send_binary_very_long(transport, writer): writer.send(b'b' * 65537, True) assert (transport.write.call_args_list[0][0][0] == b'\x82\x7f\x00\x00\x00\x00\x00\x01\x00\x01') assert transport.write.call_args_list[1][0][0] == b'b' * 65537 def test_close(transport, writer): writer.close(1001, 'msg') transport.write.assert_called_with(b'\x88\x05\x03\xe9msg') writer.close(1001, b'msg') transport.write.assert_called_with(b'\x88\x05\x03\xe9msg') def test_send_text_masked(transport, writer): writer = websocket.WebSocketWriter(transport, use_mask=True, random=random.Random(123)) writer.send(b'text') transport.write.assert_called_with(b'\x81\x84\rg\xb3fy\x02\xcb\x12') aiohttp-0.20.2/tests/test_client_connection.py0000664000175000017500000000514112607421062022300 0ustar andrewandrew00000000000000import gc import pytest from unittest import mock from aiohttp.connector import Connection @pytest.fixture def key(): return object() @pytest.fixture def connector(): return mock.Mock() @pytest.fixture def request(): return mock.Mock() @pytest.fixture def transport(): return mock.Mock() @pytest.fixture def protocol(): return mock.Mock() def test_del(connector, key, request, transport, protocol, loop, warning): conn = Connection(connector, key, request, transport, protocol, loop) exc_handler = mock.Mock() loop.set_exception_handler(exc_handler) with warning(ResourceWarning): del conn gc.collect() connector._release.assert_called_with(key, request, transport, protocol, should_close=True) msg = {'client_connection': mock.ANY, # conn was deleted 'message': 'Unclosed connection'} if loop.get_debug(): msg['source_traceback'] = mock.ANY exc_handler.assert_called_with(loop, msg) def test_close(connector, key, request, transport, protocol, loop): conn = Connection(connector, key, request, transport, protocol, loop) assert not conn.closed conn.close() assert conn._transport is None connector._release.assert_called_with( key, request, transport, protocol, should_close=True) assert conn.closed def test_release(connector, key, request, transport, protocol, loop): conn = Connection(connector, key, request, transport, protocol, loop) assert not conn.closed conn.release() assert not transport.close.called assert conn._transport is None connector._release.assert_called_with( key, request, transport, protocol, should_close=False) assert conn.closed def test_release_released(connector, key, request, transport, protocol, loop): conn = Connection(connector, key, request, transport, protocol, loop) conn.release() connector._release.reset_mock() conn.release() assert not transport.close.called assert conn._transport is None assert not connector._release.called def test_detach(connector, key, request, transport, protocol, loop): conn = Connection(connector, key, request, transport, protocol, loop) assert not conn.closed conn.detach() assert conn._transport is None assert not connector._release.called assert conn.closed aiohttp-0.20.2/tests/test_flowcontrol_streams.py0000664000175000017500000001602612552474754022734 0ustar andrewandrew00000000000000import asyncio import unittest import unittest.mock from aiohttp import streams class TestFlowControlStreamReader(unittest.TestCase): def setUp(self): self.stream = unittest.mock.Mock() self.transp = self.stream.transport self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): self.loop.close() def _make_one(self, *args, **kwargs): return streams.FlowControlStreamReader( self.stream, limit=1, loop=self.loop, *args, **kwargs) def test_read(self): r = self._make_one() r.paused = True r.feed_data(b'da', 2) res = self.loop.run_until_complete(r.read(1)) self.assertEqual(res, b'd') self.assertTrue(self.transp.resume_reading.called) def test_readline(self): r = self._make_one() r.paused = True r.feed_data(b'data\n', 5) res = self.loop.run_until_complete(r.readline()) self.assertEqual(res, b'data\n') self.assertTrue(self.transp.resume_reading.called) def test_readany(self): r = self._make_one() r.paused = True r.feed_data(b'data', 4) res = self.loop.run_until_complete(r.readany()) self.assertEqual(res, b'data') self.assertTrue(self.transp.resume_reading.called) def test_readexactly(self): r = self._make_one() r.paused = True r.feed_data(b'datadata', 8) res = self.loop.run_until_complete(r.readexactly(2)) self.assertEqual(res, b'da') self.assertTrue(self.transp.resume_reading.called) def test_feed_data(self): r = self._make_one() r._stream.paused = False r.feed_data(b'datadata', 8) self.assertTrue(self.transp.pause_reading.called) class FlowControlMixin: def test_resume_on_init(self): stream = unittest.mock.Mock() stream.paused = True streams.FlowControlDataQueue(stream, limit=1, loop=self.loop) self.assertTrue(stream.transport.resume_reading.called) self.assertFalse(stream.paused) def test_no_transport_in_init(self): stream = unittest.mock.Mock() stream.paused = True stream.transport = None streams.FlowControlDataQueue(stream, limit=1, loop=self.loop) self.assertTrue(stream.paused) def test_feed_no_waiter(self): out = self._make_one() out.feed_data(object(), 100) self.assertTrue(self.stream.transport.pause_reading.called) def test_feed_no_transport(self): self.stream.transport = None out = self._make_one() self.stream.paused = False out.feed_data(object(), 100) self.assertFalse(self.stream.paused) def test_feed_with_waiter(self): self.stream.paused = False out = self._make_one() read_task = asyncio.Task(out.read(), loop=self.loop) def cb(): out.feed_data(object(), 100) self.loop.call_soon(cb) self.loop.run_until_complete(read_task) self.assertFalse(self.stream.transport.pause_reading.called) self.assertFalse(self.stream.paused) def test_resume_on_read(self): out = self._make_one() out.feed_data(object(), 100) self.assertTrue(self.stream.paused) self.loop.run_until_complete(out.read()) self.assertTrue(self.stream.transport.resume_reading.called) self.assertFalse(self.stream.paused) def test_resume_on_read_no_transport(self): item = object() out = self._make_one() out.feed_data(item, 100) self.assertTrue(self.stream.paused) self.stream.transport = None res = self.loop.run_until_complete(out.read()) self.assertIs(res, item) self.assertTrue(self.stream.paused) def test_no_resume_on_read(self): out = self._make_one() out.feed_data(object(), 100) out.feed_data(object(), 100) out.feed_data(object(), 100) self.assertTrue(self.stream.paused) self.stream.transport.reset_mock() self.loop.run_until_complete(out.read()) self.assertFalse(self.stream.transport.resume_reading.called) self.assertTrue(self.stream.paused) def test_pause_on_read(self): out = self._make_one() out._buffer.append((object(), 100)) out._buffer.append((object(), 100)) out._buffer.append((object(), 100)) out._size = 300 self.stream.paused = False self.loop.run_until_complete(out.read()) self.assertTrue(self.stream.transport.pause_reading.called) self.assertTrue(self.stream.paused) def test_no_pause_on_read(self): item = object() out = self._make_one() out._buffer.append((item, 100)) out._size = 100 self.stream.paused = False res = self.loop.run_until_complete(out.read()) self.assertIs(res, item) self.assertFalse(self.stream.transport.pause_reading.called) self.assertFalse(self.stream.paused) def test_no_pause_on_read_no_transport(self): item = object() out = self._make_one() out._buffer.append((item, 100)) out._buffer.append((object(), 100)) out._buffer.append((object(), 100)) out._size = 300 self.stream.paused = False self.stream.transport = None res = self.loop.run_until_complete(out.read()) self.assertIs(res, item) self.assertFalse(self.stream.paused) class TestFlowControlDataQueue(unittest.TestCase, FlowControlMixin): def setUp(self): self.stream = unittest.mock.Mock() self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): self.loop.close() def _make_one(self, *args, **kwargs): return streams.FlowControlDataQueue( self.stream, limit=1, loop=self.loop, *args, **kwargs) class TestFlowControlChunksQueue(unittest.TestCase, FlowControlMixin): def setUp(self): self.stream = unittest.mock.Mock() self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): self.loop.close() def _make_one(self, *args, **kwargs): return streams.FlowControlChunksQueue( self.stream, limit=1, loop=self.loop, *args, **kwargs) def test_read_eof(self): out = self._make_one() read_task = asyncio.Task(out.read(), loop=self.loop) def cb(): out.feed_eof() self.loop.call_soon(cb) self.loop.run_until_complete(read_task) self.assertTrue(out.at_eof()) def test_read_until_eof(self): item = object() out = self._make_one() out.feed_data(item, 1) out.feed_eof() data = self.loop.run_until_complete(out.read()) self.assertIs(data, item) thing = self.loop.run_until_complete(out.read()) self.assertEqual(thing, b'') self.assertTrue(out.at_eof()) def test_readany(self): out = self._make_one() self.assertIs(out.read.__func__, out.readany.__func__) aiohttp-0.20.2/tests/test_websocket_handshake.py0000664000175000017500000001164012610463430022577 0ustar andrewandrew00000000000000"""Tests for http/websocket.py""" import base64 import hashlib import os import pytest from aiohttp import websocket, multidict, protocol, errors from unittest import mock @pytest.fixture() def transport(): return mock.Mock() @pytest.fixture() def message(): headers = multidict.MultiDict() return protocol.RawRequestMessage( 'GET', '/path', (1, 0), headers, True, None) def gen_ws_headers(protocols=''): key = base64.b64encode(os.urandom(16)).decode() hdrs = [('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'), ('SEC-WEBSOCKET-VERSION', '13'), ('SEC-WEBSOCKET-KEY', key)] if protocols: hdrs += [('SEC-WEBSOCKET-PROTOCOL', protocols)] return hdrs, key def test_not_get(message, transport): with pytest.raises(errors.HttpProcessingError): websocket.do_handshake('POST', message.headers, transport) def test_no_upgrade(message, transport): with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) def test_no_connection(message, transport): message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'keep-alive')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) def test_protocol_version(message, transport): message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'), ('SEC-WEBSOCKET-VERSION', '1')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) def test_protocol_key(message, transport): message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'), ('SEC-WEBSOCKET-VERSION', '13')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'), ('SEC-WEBSOCKET-VERSION', '13'), ('SEC-WEBSOCKET-KEY', '123')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) sec_key = base64.b64encode(os.urandom(2)) message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'), ('SEC-WEBSOCKET-VERSION', '13'), ('SEC-WEBSOCKET-KEY', sec_key.decode())]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) def test_handshake(message, transport): hdrs, sec_key = gen_ws_headers() message.headers.extend(hdrs) status, headers, parser, writer, protocol = websocket.do_handshake( message.method, message.headers, transport) assert status == 101 assert protocol is None key = base64.b64encode( hashlib.sha1(sec_key.encode() + websocket.WS_KEY).digest()) headers = dict(headers) assert headers['SEC-WEBSOCKET-ACCEPT'] == key.decode() def test_handshake_protocol(message, transport): '''Tests if one protocol is returned by do_handshake''' proto = 'chat' message.headers.extend(gen_ws_headers(proto)[0]) _, resp_headers, _, _, protocol = websocket.do_handshake( message.method, message.headers, transport, protocols=[proto]) assert protocol == proto # also test if we reply with the protocol resp_headers = dict(resp_headers) assert resp_headers['SEC-WEBSOCKET-PROTOCOL'] == proto def test_handshake_protocol_agreement(message, transport): '''Tests if the right protocol is selected given multiple''' best_proto = 'worse_proto' wanted_protos = ['best', 'chat', 'worse_proto'] server_protos = 'worse_proto,chat' message.headers.extend(gen_ws_headers(server_protos)[0]) _, resp_headers, _, _, protocol = websocket.do_handshake( message.method, message.headers, transport, protocols=wanted_protos) assert protocol == best_proto def test_handshake_protocol_unsupported(log, message, transport): '''Tests if a protocol mismatch handshake warns and returns None''' proto = 'chat' message.headers.extend(gen_ws_headers('test')[0]) with log('aiohttp.websocket') as ctx: _, _, _, _, protocol = websocket.do_handshake( message.method, message.headers, transport, protocols=[proto]) assert protocol is None assert (ctx.records[-1].msg == 'Client protocols %r don’t overlap server-known ones %r') aiohttp-0.20.2/tests/test_proxy_connector.py0000664000175000017500000004454012631071601022041 0ustar andrewandrew00000000000000import unittest import asyncio import gc import aiohttp from aiohttp.client_reqrep import ClientRequest, ClientResponse from unittest import mock class TestProxyConnector(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): # just in case if we have transport close callbacks self.loop.stop() self.loop.run_forever() self.loop.close() gc.collect() def _fake_coroutine(self, mock, return_value): def coro(*args, **kw): if isinstance(return_value, Exception): raise return_value return return_value yield # pragma: no cover mock.side_effect = coro def test_ctor(self): with self.assertRaises(AssertionError): aiohttp.ProxyConnector('https://localhost:8118', loop=self.loop) def test_ctor2(self): connector = aiohttp.ProxyConnector('http://localhost:8118', loop=self.loop) self.assertEqual('http://localhost:8118', connector.proxy) self.assertTrue(connector.force_close) @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_connect(self, ClientRequestMock): req = ClientRequest('GET', 'http://www.python.org', loop=self.loop) self.assertEqual(req.path, '/') loop_mock = unittest.mock.Mock() connector = aiohttp.ProxyConnector('http://proxy.example.com', loop=loop_mock) self.assertIs(loop_mock, connector._loop) resolve_host = unittest.mock.Mock() self._fake_coroutine(resolve_host, [unittest.mock.MagicMock()]) connector._resolve_host = resolve_host tr, proto = unittest.mock.Mock(), unittest.mock.Mock() self._fake_coroutine(loop_mock.create_connection, (tr, proto)) conn = self.loop.run_until_complete(connector.connect(req)) self.assertEqual(req.path, 'http://www.python.org/') self.assertIs(conn._transport, tr) self.assertIs(conn._protocol, proto) # resolve_host.assert_called_once_with('proxy.example.com', 80) tr.get_extra_info.assert_called_once_with('sslcontext') ClientRequestMock.assert_called_with( 'GET', 'http://proxy.example.com', auth=None, headers={'HOST': 'www.python.org'}, loop=loop_mock) conn.close() def test_proxy_auth(self): with self.assertRaises(AssertionError) as ctx: aiohttp.ProxyConnector('http://proxy.example.com', proxy_auth=('user', 'pass'), loop=unittest.mock.Mock()) self.assertEqual(ctx.exception.args[0], ("proxy_auth must be None or BasicAuth() tuple", ('user', 'pass'))) def test_proxy_connection_error(self): connector = aiohttp.ProxyConnector('http://proxy.example.com', loop=self.loop) connector._resolve_host = resolve_mock = unittest.mock.Mock() self._fake_coroutine(resolve_mock, OSError('dont take it serious')) req = ClientRequest('GET', 'http://www.python.org', loop=self.loop) expected_headers = dict(req.headers) with self.assertRaises(aiohttp.ProxyConnectionError): self.loop.run_until_complete(connector.connect(req)) self.assertEqual(req.path, '/') self.assertEqual(dict(req.headers), expected_headers) @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_auth(self, ClientRequestMock): proxy_req = ClientRequest('GET', 'http://proxy.example.com', auth=aiohttp.helpers.BasicAuth('user', 'pass'), loop=self.loop) ClientRequestMock.return_value = proxy_req self.assertIn('AUTHORIZATION', proxy_req.headers) self.assertNotIn('PROXY-AUTHORIZATION', proxy_req.headers) loop_mock = unittest.mock.Mock() connector = aiohttp.ProxyConnector( 'http://proxy.example.com', loop=loop_mock, proxy_auth=aiohttp.helpers.BasicAuth('user', 'pass')) connector._resolve_host = resolve_mock = unittest.mock.Mock() self._fake_coroutine(resolve_mock, [unittest.mock.MagicMock()]) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() self._fake_coroutine(loop_mock.create_connection, (tr, proto)) req = ClientRequest('GET', 'http://www.python.org', loop=self.loop) self.assertNotIn('AUTHORIZATION', req.headers) self.assertNotIn('PROXY-AUTHORIZATION', req.headers) conn = self.loop.run_until_complete(connector.connect(req)) self.assertEqual(req.path, 'http://www.python.org/') self.assertNotIn('AUTHORIZATION', req.headers) self.assertIn('PROXY-AUTHORIZATION', req.headers) self.assertNotIn('AUTHORIZATION', proxy_req.headers) self.assertNotIn('PROXY-AUTHORIZATION', proxy_req.headers) ClientRequestMock.assert_called_with( 'GET', 'http://proxy.example.com', auth=aiohttp.helpers.BasicAuth('user', 'pass'), loop=unittest.mock.ANY, headers=unittest.mock.ANY) conn.close() def test_auth_utf8(self): proxy_req = ClientRequest( 'GET', 'http://proxy.example.com', auth=aiohttp.helpers.BasicAuth('юзер', 'паÑÑ', 'utf-8'), loop=self.loop) self.assertIn('AUTHORIZATION', proxy_req.headers) @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_auth_from_url(self, ClientRequestMock): proxy_req = ClientRequest('GET', 'http://user:pass@proxy.example.com', loop=self.loop) ClientRequestMock.return_value = proxy_req self.assertIn('AUTHORIZATION', proxy_req.headers) self.assertNotIn('PROXY-AUTHORIZATION', proxy_req.headers) loop_mock = unittest.mock.Mock() connector = aiohttp.ProxyConnector( 'http://user:pass@proxy.example.com', loop=loop_mock) connector._resolve_host = resolve_mock = unittest.mock.Mock() self._fake_coroutine(resolve_mock, [unittest.mock.MagicMock()]) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() self._fake_coroutine(loop_mock.create_connection, (tr, proto)) req = ClientRequest('GET', 'http://www.python.org', loop=self.loop) self.assertNotIn('AUTHORIZATION', req.headers) self.assertNotIn('PROXY-AUTHORIZATION', req.headers) conn = self.loop.run_until_complete(connector.connect(req)) self.assertEqual(req.path, 'http://www.python.org/') self.assertNotIn('AUTHORIZATION', req.headers) self.assertIn('PROXY-AUTHORIZATION', req.headers) self.assertNotIn('AUTHORIZATION', proxy_req.headers) self.assertNotIn('PROXY-AUTHORIZATION', proxy_req.headers) ClientRequestMock.assert_called_with( 'GET', 'http://user:pass@proxy.example.com', auth=None, loop=unittest.mock.ANY, headers=unittest.mock.ANY) conn.close() @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_auth__not_modifying_request(self, ClientRequestMock): proxy_req = ClientRequest('GET', 'http://user:pass@proxy.example.com', loop=self.loop) ClientRequestMock.return_value = proxy_req proxy_req_headers = dict(proxy_req.headers) loop_mock = unittest.mock.Mock() connector = aiohttp.ProxyConnector( 'http://user:pass@proxy.example.com', loop=loop_mock) connector._resolve_host = resolve_mock = unittest.mock.Mock() self._fake_coroutine(resolve_mock, OSError('nothing personal')) req = ClientRequest('GET', 'http://www.python.org', loop=self.loop) req_headers = dict(req.headers) with self.assertRaises(aiohttp.ProxyConnectionError): self.loop.run_until_complete(connector.connect(req)) self.assertEqual(req.headers, req_headers) self.assertEqual(req.path, '/') self.assertEqual(proxy_req.headers, proxy_req_headers) @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_https_connect(self, ClientRequestMock): loop_mock = unittest.mock.Mock() proxy_req = ClientRequest('GET', 'http://proxy.example.com', loop=loop_mock) ClientRequestMock.return_value = proxy_req proxy_resp = ClientResponse('get', 'http://proxy.example.com') proxy_resp._loop = loop_mock proxy_req.send = send_mock = unittest.mock.Mock() send_mock.return_value = proxy_resp proxy_resp.start = start_mock = unittest.mock.Mock() self._fake_coroutine(start_mock, unittest.mock.Mock(status=200)) connector = aiohttp.ProxyConnector( 'http://proxy.example.com', loop=loop_mock) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() self._fake_coroutine(loop_mock.create_connection, (tr, proto)) req = ClientRequest('GET', 'https://www.python.org', loop=self.loop) self.loop.run_until_complete(connector._create_connection(req)) self.assertEqual(req.path, '/') self.assertEqual(proxy_req.method, 'CONNECT') self.assertEqual(proxy_req.path, 'www.python.org:443') tr.pause_reading.assert_called_once_with() tr.get_extra_info.assert_called_with('socket', default=None) self.loop.run_until_complete(proxy_req.close()) proxy_resp.close() self.loop.run_until_complete(req.close()) @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_https_connect_runtime_error(self, ClientRequestMock): loop_mock = unittest.mock.Mock() proxy_req = ClientRequest('GET', 'http://proxy.example.com', loop=loop_mock) ClientRequestMock.return_value = proxy_req proxy_resp = ClientResponse('get', 'http://proxy.example.com') proxy_resp._loop = loop_mock proxy_req.send = send_mock = unittest.mock.Mock() send_mock.return_value = proxy_resp proxy_resp.start = start_mock = unittest.mock.Mock() self._fake_coroutine(start_mock, unittest.mock.Mock(status=200)) connector = aiohttp.ProxyConnector( 'http://proxy.example.com', loop=loop_mock) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() tr.get_extra_info.return_value = None self._fake_coroutine(loop_mock.create_connection, (tr, proto)) req = ClientRequest('GET', 'https://www.python.org', loop=self.loop) with self.assertRaisesRegex( RuntimeError, "Transport does not expose socket instance"): self.loop.run_until_complete(connector._create_connection(req)) self.loop.run_until_complete(proxy_req.close()) proxy_resp.close() self.loop.run_until_complete(req.close()) @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_https_connect_http_proxy_error(self, ClientRequestMock): loop_mock = unittest.mock.Mock() proxy_req = ClientRequest('GET', 'http://proxy.example.com', loop=loop_mock) ClientRequestMock.return_value = proxy_req proxy_resp = ClientResponse('get', 'http://proxy.example.com') proxy_resp._loop = loop_mock proxy_req.send = send_mock = unittest.mock.Mock() send_mock.return_value = proxy_resp proxy_resp.start = start_mock = unittest.mock.Mock() self._fake_coroutine( start_mock, unittest.mock.Mock(status=400, reason='bad request')) connector = aiohttp.ProxyConnector( 'http://proxy.example.com', loop=loop_mock) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() tr.get_extra_info.return_value = None self._fake_coroutine(loop_mock.create_connection, (tr, proto)) req = ClientRequest('GET', 'https://www.python.org', loop=self.loop) with self.assertRaisesRegex( aiohttp.HttpProxyError, "400, message='bad request'"): self.loop.run_until_complete(connector._create_connection(req)) self.loop.run_until_complete(proxy_req.close()) proxy_resp.close() self.loop.run_until_complete(req.close()) @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_https_connect_resp_start_error(self, ClientRequestMock): loop_mock = unittest.mock.Mock() proxy_req = ClientRequest('GET', 'http://proxy.example.com', loop=loop_mock) ClientRequestMock.return_value = proxy_req proxy_resp = ClientResponse('get', 'http://proxy.example.com') proxy_resp._loop = loop_mock proxy_req.send = send_mock = unittest.mock.Mock() send_mock.return_value = proxy_resp proxy_resp.start = start_mock = unittest.mock.Mock() self._fake_coroutine(start_mock, OSError("error message")) connector = aiohttp.ProxyConnector( 'http://proxy.example.com', loop=loop_mock) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() tr.get_extra_info.return_value = None self._fake_coroutine(loop_mock.create_connection, (tr, proto)) req = ClientRequest('GET', 'https://www.python.org', loop=self.loop) with self.assertRaisesRegex(OSError, "error message"): self.loop.run_until_complete(connector._create_connection(req)) @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_request_port(self, ClientRequestMock): proxy_req = ClientRequest('GET', 'http://proxy.example.com', loop=self.loop) ClientRequestMock.return_value = proxy_req loop_mock = unittest.mock.Mock() connector = aiohttp.ProxyConnector('http://proxy.example.com', loop=loop_mock) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() tr.get_extra_info.return_value = None self._fake_coroutine(loop_mock.create_connection, (tr, proto)) req = ClientRequest('GET', 'http://localhost:1234/path', loop=self.loop) self.loop.run_until_complete(connector._create_connection(req)) self.assertEqual(req.path, 'http://localhost:1234/path') def test_proxy_auth_property(self): connector = aiohttp.ProxyConnector( 'http://proxy.example.com', proxy_auth=aiohttp.helpers.BasicAuth('user', 'pass'), loop=self.loop) self.assertEqual(('user', 'pass', 'latin1'), connector.proxy_auth) connector.close() def test_proxy_auth_property_default(self): connector = aiohttp.ProxyConnector('http://proxy.example.com', loop=self.loop) self.assertIsNone(connector.proxy_auth) connector.close() @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_https_connect_pass_ssl_context(self, ClientRequestMock): loop_mock = unittest.mock.Mock() proxy_req = ClientRequest('GET', 'http://proxy.example.com', loop=loop_mock) ClientRequestMock.return_value = proxy_req proxy_resp = ClientResponse('get', 'http://proxy.example.com') proxy_resp._loop = loop_mock proxy_req.send = send_mock = unittest.mock.Mock() send_mock.return_value = proxy_resp proxy_resp.start = start_mock = unittest.mock.Mock() self._fake_coroutine(start_mock, unittest.mock.Mock(status=200)) connector = aiohttp.ProxyConnector( 'http://proxy.example.com', loop=loop_mock) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() self._fake_coroutine(loop_mock.create_connection, (tr, proto)) req = ClientRequest('GET', 'https://www.python.org', loop=self.loop) self.loop.run_until_complete(connector._create_connection(req)) loop_mock.create_connection.assert_called_with( mock.ANY, ssl=connector.ssl_context, sock=mock.ANY, server_hostname='www.python.org') self.assertEqual(req.path, '/') self.assertEqual(proxy_req.method, 'CONNECT') self.assertEqual(proxy_req.path, 'www.python.org:443') tr.pause_reading.assert_called_once_with() tr.get_extra_info.assert_called_with('socket', default=None) self.loop.run_until_complete(proxy_req.close()) proxy_resp.close() self.loop.run_until_complete(req.close()) @unittest.mock.patch('aiohttp.connector.ClientRequest') def test_https_auth(self, ClientRequestMock): loop_mock = unittest.mock.Mock() proxy_req = ClientRequest('GET', 'http://proxy.example.com', auth=aiohttp.helpers.BasicAuth('user', 'pass'), loop=loop_mock) ClientRequestMock.return_value = proxy_req proxy_resp = ClientResponse('get', 'http://proxy.example.com') proxy_resp._loop = loop_mock proxy_req.send = send_mock = unittest.mock.Mock() send_mock.return_value = proxy_resp proxy_resp.start = start_mock = unittest.mock.Mock() self._fake_coroutine(start_mock, unittest.mock.Mock(status=200)) connector = aiohttp.ProxyConnector( 'http://proxy.example.com', loop=loop_mock) tr, proto = unittest.mock.Mock(), unittest.mock.Mock() self._fake_coroutine(loop_mock.create_connection, (tr, proto)) self.assertIn('AUTHORIZATION', proxy_req.headers) self.assertNotIn('PROXY-AUTHORIZATION', proxy_req.headers) req = ClientRequest('GET', 'https://www.python.org', loop=self.loop) self.assertNotIn('AUTHORIZATION', req.headers) self.assertNotIn('PROXY-AUTHORIZATION', req.headers) self.loop.run_until_complete(connector._create_connection(req)) self.assertEqual(req.path, '/') self.assertNotIn('AUTHORIZATION', req.headers) self.assertNotIn('PROXY-AUTHORIZATION', req.headers) self.assertNotIn('AUTHORIZATION', proxy_req.headers) self.assertIn('PROXY-AUTHORIZATION', proxy_req.headers) self.loop.run_until_complete(proxy_req.close()) proxy_resp.close() self.loop.run_until_complete(req.close()) aiohttp-0.20.2/tests/test_websocket_parser.py0000664000175000017500000003431212637524575022167 0ustar andrewandrew00000000000000import aiohttp import pytest import random import struct from unittest import mock from aiohttp.websocket import Message from aiohttp import websocket def build_frame(message, opcode, use_mask=False, noheader=False): """Send a frame over the websocket with message as its payload.""" msg_length = len(message) if use_mask: # pragma: no cover mask_bit = 0x80 else: mask_bit = 0 if msg_length < 126: header = websocket.PACK_LEN1( 0x80 | opcode, msg_length | mask_bit) elif msg_length < (1 << 16): # pragma: no cover header = websocket.PACK_LEN2( 0x80 | opcode, 126 | mask_bit, msg_length) else: header = websocket.PACK_LEN3( 0x80 | opcode, 127 | mask_bit, msg_length) if use_mask: # pragma: no cover mask = random.randrange(0, 0xffffffff) mask = mask.to_bytes(4, 'big') message = websocket._websocket_mask(mask, bytearray(message)) if noheader: return message else: return header + mask + message else: if noheader: return message else: return header + message def build_close_frame(code=1000, message=b'', noheader=False): """Close the websocket, sending the specified code and message.""" if isinstance(message, str): # pragma: no cover message = message.encode('utf-8') return build_frame( websocket.PACK_CLOSE_CODE(code) + message, opcode=websocket.OPCODE_CLOSE, noheader=noheader) @pytest.fixture() def buf(): return aiohttp.ParserBuffer() @pytest.fixture() def out(loop): return aiohttp.DataQueue(loop=loop) @pytest.fixture() def parser(buf, out): return websocket.WebSocketParser(out, buf) def test_parse_frame(buf): p = websocket.parse_frame(buf) next(p) p.send(struct.pack('!BB', 0b00000001, 0b00000001)) try: p.send(b'1') except StopIteration as exc: fin, opcode, payload = exc.value assert (0, 1, b'1') == (fin, opcode, payload) def test_parse_frame_length0(buf): p = websocket.parse_frame(buf) next(p) try: p.send(struct.pack('!BB', 0b00000001, 0b00000000)) except StopIteration as exc: fin, opcode, payload = exc.value assert (0, 1, b'') == (fin, opcode, payload) def test_parse_frame_length2(buf): p = websocket.parse_frame(buf) next(p) p.send(struct.pack('!BB', 0b00000001, 126)) p.send(struct.pack('!H', 4)) try: p.send(b'1234') except StopIteration as exc: fin, opcode, payload = exc.value assert (0, 1, b'1234') == (fin, opcode, payload) def test_parse_frame_length4(buf): p = websocket.parse_frame(buf) next(p) p.send(struct.pack('!BB', 0b00000001, 127)) p.send(struct.pack('!Q', 4)) try: p.send(b'1234') except StopIteration as exc: fin, opcode, payload = exc.value assert (0, 1, b'1234') == (fin, opcode, payload) def test_parse_frame_mask(buf): p = websocket.parse_frame(buf) next(p) p.send(struct.pack('!BB', 0b00000001, 0b10000001)) p.send(b'0001') try: p.send(b'1') except StopIteration as exc: fin, opcode, payload = exc.value assert (0, 1, b'\x01') == (fin, opcode, payload) def test_parse_frame_header_reversed_bits(buf): p = websocket.parse_frame(buf) next(p) with pytest.raises(websocket.WebSocketError): p.send(struct.pack('!BB', 0b01100000, 0b00000000)) def test_parse_frame_header_control_frame(buf): p = websocket.parse_frame(buf) next(p) with pytest.raises(websocket.WebSocketError): p.send(struct.pack('!BB', 0b00001000, 0b00000000)) def test_parse_frame_header_continuation(buf): p = websocket.parse_frame(buf) next(p) with pytest.raises(websocket.WebSocketError): p.send(struct.pack('!BB', 0b00000000, 0b00000000)) def test_parse_frame_header_new_data_err(buf): p = websocket.parse_frame(buf) next(p) with pytest.raises(websocket.WebSocketError): p.send(struct.pack('!BB', 0b000000000, 0b00000000)) def test_parse_frame_header_payload_size(buf): p = websocket.parse_frame(buf) next(p) with pytest.raises(websocket.WebSocketError): p.send(struct.pack('!BB', 0b10001000, 0b01111110)) def test_ping_frame(out, parser): def parse_frame(buf): yield return (1, websocket.OPCODE_PING, b'data') with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') res = out._buffer[0] assert res == ((websocket.OPCODE_PING, b'data', ''), 4) def test_pong_frame(out, parser): def parse_frame(buf): yield return (1, websocket.OPCODE_PONG, b'data') with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') res = out._buffer[0] assert res == ((websocket.OPCODE_PONG, b'data', ''), 4) def test_close_frame(out, parser): def parse_frame(buf): yield return (1, websocket.OPCODE_CLOSE, b'') with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') res = out._buffer[0] assert res == ((websocket.OPCODE_CLOSE, 0, ''), 0) def test_close_frame_info(out, parser): def parse_frame(buf): yield return (1, websocket.OPCODE_CLOSE, b'0112345') with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') res = out._buffer[0] assert res == (Message(websocket.OPCODE_CLOSE, 12337, '12345'), 0) def test_close_frame_invalid(out, parser): def parse_frame(buf): yield return (1, websocket.OPCODE_CLOSE, b'1') with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) with pytest.raises(websocket.WebSocketError) as ctx: next(parser) assert ctx.value.code == websocket.CLOSE_PROTOCOL_ERROR def test_close_frame_invalid_2(buf, parser): buf.extend(build_close_frame(code=1)) with pytest.raises(websocket.WebSocketError) as ctx: next(parser) assert ctx.value.code == websocket.CLOSE_PROTOCOL_ERROR def test_close_frame_unicode_err(buf, parser): buf.extend(build_close_frame( code=1000, message=b'\xf4\x90\x80\x80')) with pytest.raises(websocket.WebSocketError) as ctx: next(parser) assert ctx.value.code == websocket.CLOSE_INVALID_TEXT def test_unknown_frame(out, parser): def parse_frame(buf): yield return (1, websocket.OPCODE_CONTINUATION, b'') with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) with pytest.raises(websocket.WebSocketError): parser.send(b'') def test_simple_text(buf, out, parser): buf.extend(build_frame(b'text', websocket.OPCODE_TEXT)) next(parser) parser.send(b'') res = out._buffer[0] assert res == ((websocket.OPCODE_TEXT, 'text', ''), 4) def test_simple_text_unicode_err(buf, parser): buf.extend( build_frame(b'\xf4\x90\x80\x80', websocket.OPCODE_TEXT)) with pytest.raises(websocket.WebSocketError) as ctx: next(parser) assert ctx.value.code == websocket.CLOSE_INVALID_TEXT def test_simple_binary(out, parser): def parse_frame(buf): yield return (1, websocket.OPCODE_BINARY, b'binary') with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') res = out._buffer[0] assert res == ((websocket.OPCODE_BINARY, b'binary', ''), 6) def test_continuation(out, parser): cur = 0 def parse_frame(buf, cont=False): nonlocal cur yield if cur == 0: cur = 1 return (0, websocket.OPCODE_TEXT, b'line1') else: return (1, websocket.OPCODE_CONTINUATION, b'line2') with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') parser.send(b'') res = out._buffer[0] assert res == (Message(websocket.OPCODE_TEXT, 'line1line2', ''), 10) def test_continuation_with_ping(out, parser): frames = [ (0, websocket.OPCODE_TEXT, b'line1'), (0, websocket.OPCODE_PING, b''), (1, websocket.OPCODE_CONTINUATION, b'line2'), ] def parse_frame(buf, cont=False): yield return frames.pop(0) with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') parser.send(b'') parser.send(b'') res = out._buffer[0] assert res == (Message(websocket.OPCODE_PING, b'', ''), 0) res = out._buffer[1] assert res == (Message(websocket.OPCODE_TEXT, 'line1line2', ''), 10) def test_continuation_err(out, parser): cur = 0 def parse_frame(buf, cont=False): nonlocal cur yield if cur == 0: cur = 1 return (0, websocket.OPCODE_TEXT, b'line1') else: return (1, websocket.OPCODE_TEXT, b'line2') with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') with pytest.raises(websocket.WebSocketError): parser.send(b'') def test_continuation_with_close(out, parser): frames = [ (0, websocket.OPCODE_TEXT, b'line1'), (0, websocket.OPCODE_CLOSE, build_close_frame(1002, b'test', noheader=True)), (1, websocket.OPCODE_CONTINUATION, b'line2'), ] def parse_frame(buf, cont=False): yield return frames.pop(0) with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') parser.send(b'') parser.send(b'') res = out._buffer[0] assert res, (Message(websocket.OPCODE_CLOSE, 1002, 'test'), 0) res = out._buffer[1] assert res == (Message(websocket.OPCODE_TEXT, 'line1line2', ''), 10) def test_continuation_with_close_unicode_err(out, parser): frames = [ (0, websocket.OPCODE_TEXT, b'line1'), (0, websocket.OPCODE_CLOSE, build_close_frame(1000, b'\xf4\x90\x80\x80', noheader=True)), (1, websocket.OPCODE_CONTINUATION, b'line2')] def parse_frame(buf, cont=False): yield return frames.pop(0) with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') with pytest.raises(websocket.WebSocketError) as ctx: parser.send(b'') assert ctx.value.code == websocket.CLOSE_INVALID_TEXT def test_continuation_with_close_bad_code(out, parser): frames = [ (0, websocket.OPCODE_TEXT, b'line1'), (0, websocket.OPCODE_CLOSE, build_close_frame(1, b'test', noheader=True)), (1, websocket.OPCODE_CONTINUATION, b'line2')] def parse_frame(buf, cont=False): yield return frames.pop(0) with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') with pytest.raises(websocket.WebSocketError) as ctx: parser.send(b'') assert ctx.value.code == websocket.CLOSE_PROTOCOL_ERROR def test_continuation_with_close_bad_payload(out, parser): frames = [ (0, websocket.OPCODE_TEXT, b'line1'), (0, websocket.OPCODE_CLOSE, b'1'), (1, websocket.OPCODE_CONTINUATION, b'line2')] def parse_frame(buf, cont=False): yield return frames.pop(0) with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') with pytest.raises(websocket.WebSocketError) as ctx: parser.send(b'') assert ctx.value.code, websocket.CLOSE_PROTOCOL_ERROR def test_continuation_with_close_empty(out, parser): frames = [ (0, websocket.OPCODE_TEXT, b'line1'), (0, websocket.OPCODE_CLOSE, b''), (1, websocket.OPCODE_CONTINUATION, b'line2'), ] def parse_frame(buf, cont=False): yield return frames.pop(0) with mock.patch('aiohttp.websocket.parse_frame') as m_parse_frame: m_parse_frame.side_effect = parse_frame next(parser) parser.send(b'') parser.send(b'') parser.send(b'') res = out._buffer[0] assert res, (Message(websocket.OPCODE_CLOSE, 0, ''), 0) res = out._buffer[1] assert res == (Message(websocket.OPCODE_TEXT, 'line1line2', ''), 10) websocket_mask_data = bytearray( b'some very long data for masking by websocket') websocket_mask_mask = b'1234' 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(): ret = websocket._websocket_mask_python(websocket_mask_mask, websocket_mask_data) assert ret == websocket_mask_masked @pytest.mark.skipif(not hasattr(websocket, '_websocket_mask_cython'), reason='Requires Cython') def test_websocket_mask_cython(): ret = websocket._websocket_mask_cython(websocket_mask_mask, websocket_mask_data) assert ret == websocket_mask_masked def test_websocket_mask_python_empty(): ret = websocket._websocket_mask_python(websocket_mask_mask, bytearray()) assert ret == bytearray() @pytest.mark.skipif(not hasattr(websocket, '_websocket_mask_cython'), reason='Requires Cython') def test_websocket_mask_cython_empty(): ret = websocket._websocket_mask_cython(websocket_mask_mask, bytearray()) assert ret == bytearray() aiohttp-0.20.2/tests/test_web_websocket.py0000664000175000017500000003301512610121516021422 0ustar andrewandrew00000000000000import asyncio import unittest from unittest import mock from aiohttp import CIMultiDict from aiohttp.web import ( MsgType, Request, WebSocketResponse, HTTPMethodNotAllowed, HTTPBadRequest) from aiohttp.protocol import RawRequestMessage, HttpVersion11 from aiohttp import errors, signals, websocket class TestWebWebSocket(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): self.loop.close() def make_request(self, method, path, headers=None, protocols=False): self.app = mock.Mock() self.app._debug = False if headers is None: headers = CIMultiDict( {'HOST': 'server.example.com', 'UPGRADE': 'websocket', 'CONNECTION': 'Upgrade', 'SEC-WEBSOCKET-KEY': 'dGhlIHNhbXBsZSBub25jZQ==', 'ORIGIN': 'http://example.com', 'SEC-WEBSOCKET-VERSION': '13'}) if protocols: headers['SEC-WEBSOCKET-PROTOCOL'] = 'chat, superchat' message = RawRequestMessage(method, path, HttpVersion11, headers, False, False) self.payload = mock.Mock() self.transport = mock.Mock() self.reader = mock.Mock() self.writer = mock.Mock() self.app.loop = self.loop self.app.on_response_prepare = signals.Signal(self.app) req = Request(self.app, message, self.payload, self.transport, self.reader, self.writer) return req def test_nonstarted_ping(self): ws = WebSocketResponse() with self.assertRaises(RuntimeError): ws.ping() def test_nonstarted_pong(self): ws = WebSocketResponse() with self.assertRaises(RuntimeError): ws.pong() def test_nonstarted_send_str(self): ws = WebSocketResponse() with self.assertRaises(RuntimeError): ws.send_str('string') def test_nonstarted_send_bytes(self): ws = WebSocketResponse() with self.assertRaises(RuntimeError): ws.send_bytes(b'bytes') def test_nonstarted_close(self): ws = WebSocketResponse() with self.assertRaises(RuntimeError): self.loop.run_until_complete(ws.close()) def test_nonstarted_receive_str(self): @asyncio.coroutine def go(): ws = WebSocketResponse() with self.assertRaises(RuntimeError): yield from ws.receive_str() self.loop.run_until_complete(go()) def test_nonstarted_receive_bytes(self): @asyncio.coroutine def go(): ws = WebSocketResponse() with self.assertRaises(RuntimeError): yield from ws.receive_bytes() self.loop.run_until_complete(go()) def test_receive_str_nonstring(self): @asyncio.coroutine def go(): req = self.make_request('GET', '/') ws = WebSocketResponse() yield from ws.prepare(req) @asyncio.coroutine def receive(): return websocket.Message(websocket.MSG_BINARY, b'data', b'') ws.receive = receive with self.assertRaises(TypeError): yield from ws.receive_str() self.loop.run_until_complete(go()) def test_receive_bytes_nonsbytes(self): @asyncio.coroutine def go(): req = self.make_request('GET', '/') ws = WebSocketResponse() yield from ws.prepare(req) @asyncio.coroutine def receive(): return websocket.Message(websocket.MSG_TEXT, 'data', b'') ws.receive = receive with self.assertRaises(TypeError): yield from ws.receive_bytes() self.loop.run_until_complete(go()) def test_send_str_nonstring(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) with self.assertRaises(TypeError): ws.send_str(b'bytes') def test_send_bytes_nonbytes(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) with self.assertRaises(TypeError): ws.send_bytes('string') def test_write(self): ws = WebSocketResponse() with self.assertRaises(RuntimeError): ws.write(b'data') def test_can_prepare_ok(self): req = self.make_request('GET', '/', protocols=True) ws = WebSocketResponse(protocols=('chat',)) self.assertEqual((True, 'chat'), ws.can_prepare(req)) def test_can_prepare_unknown_protocol(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.assertEqual((True, None), ws.can_prepare(req)) def test_can_prepare_invalid_method(self): req = self.make_request('POST', '/') ws = WebSocketResponse() self.assertEqual((False, None), ws.can_prepare(req)) def test_can_prepare_without_upgrade(self): req = self.make_request('GET', '/', headers=CIMultiDict({})) ws = WebSocketResponse() self.assertEqual((False, None), ws.can_prepare(req)) def test_can_prepare_started(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) with self.assertRaisesRegex(RuntimeError, 'Already started'): ws.can_prepare(req) def test_closed_after_ctor(self): ws = WebSocketResponse() self.assertFalse(ws.closed) self.assertIsNone(ws.close_code) def test_send_str_closed(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) self.loop.run_until_complete(ws.close()) with self.assertRaises(RuntimeError): ws.send_str('string') def test_send_bytes_closed(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) self.loop.run_until_complete(ws.close()) with self.assertRaises(RuntimeError): ws.send_bytes(b'bytes') def test_ping_closed(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) self.loop.run_until_complete(ws.close()) with self.assertRaises(RuntimeError): ws.ping() def test_pong_closed(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) self.loop.run_until_complete(ws.close()) with self.assertRaises(RuntimeError): ws.pong() def test_close_idempotent(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) writer = mock.Mock() ws._writer = writer self.assertTrue( self.loop.run_until_complete(ws.close(code=1, message='message1'))) self.assertTrue(ws.closed) self.assertFalse( self.loop.run_until_complete(ws.close(code=2, message='message2'))) def test_start_invalid_method(self): req = self.make_request('POST', '/') ws = WebSocketResponse() with self.assertRaises(HTTPMethodNotAllowed): self.loop.run_until_complete(ws.prepare(req)) def test_start_without_upgrade(self): req = self.make_request('GET', '/', headers=CIMultiDict({})) ws = WebSocketResponse() with self.assertRaises(HTTPBadRequest): self.loop.run_until_complete(ws.prepare(req)) def test_wait_closed_before_start(self): @asyncio.coroutine def go(): ws = WebSocketResponse() with self.assertRaises(RuntimeError): yield from ws.close() self.loop.run_until_complete(go()) def test_write_eof_not_started(self): @asyncio.coroutine def go(): ws = WebSocketResponse() with self.assertRaises(RuntimeError): yield from ws.write_eof() self.loop.run_until_complete(go()) def test_write_eof_idempotent(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) self.loop.run_until_complete(ws.close()) @asyncio.coroutine def go(): yield from ws.write_eof() yield from ws.write_eof() yield from ws.write_eof() self.loop.run_until_complete(go()) def test_receive_exc_in_reader(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) exc = ValueError() res = asyncio.Future(loop=self.loop) res.set_exception(exc) ws._reader.read.return_value = res @asyncio.coroutine def go(): msg = yield from ws.receive() self.assertTrue(msg.tp, MsgType.error) self.assertIs(msg.data, exc) self.assertIs(ws.exception(), exc) self.loop.run_until_complete(go()) def test_receive_cancelled(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) res = asyncio.Future(loop=self.loop) res.set_exception(asyncio.CancelledError()) ws._reader.read.return_value = res self.assertRaises( asyncio.CancelledError, self.loop.run_until_complete, ws.receive()) def test_receive_timeouterror(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) res = asyncio.Future(loop=self.loop) res.set_exception(asyncio.TimeoutError()) ws._reader.read.return_value = res self.assertRaises( asyncio.TimeoutError, self.loop.run_until_complete, ws.receive()) def test_receive_client_disconnected(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) exc = errors.ClientDisconnectedError() res = asyncio.Future(loop=self.loop) res.set_exception(exc) ws._reader.read.return_value = res @asyncio.coroutine def go(): msg = yield from ws.receive() self.assertTrue(ws.closed) self.assertTrue(msg.tp, MsgType.close) self.assertIs(msg.data, None) self.assertIs(ws.exception(), None) self.loop.run_until_complete(go()) def test_multiple_receive_on_close_connection(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) self.loop.run_until_complete(ws.close()) self.loop.run_until_complete(ws.receive()) self.loop.run_until_complete(ws.receive()) self.loop.run_until_complete(ws.receive()) self.loop.run_until_complete(ws.receive()) self.assertRaises( RuntimeError, self.loop.run_until_complete, ws.receive()) def test_concurrent_receive(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) ws._waiting = True self.assertRaises( RuntimeError, self.loop.run_until_complete, ws.receive()) def test_close_exc(self): req = self.make_request('GET', '/') reader = self.reader.set_parser.return_value = mock.Mock() ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) exc = ValueError() reader.read.return_value = asyncio.Future(loop=self.loop) reader.read.return_value.set_exception(exc) self.loop.run_until_complete(ws.close()) self.assertTrue(ws.closed) self.assertIs(ws.exception(), exc) ws._closed = False reader.read.return_value = asyncio.Future(loop=self.loop) reader.read.return_value.set_exception(asyncio.CancelledError()) self.assertRaises(asyncio.CancelledError, self.loop.run_until_complete, ws.close()) self.assertEqual(ws.close_code, 1006) def test_close_exc2(self): req = self.make_request('GET', '/') ws = WebSocketResponse() self.loop.run_until_complete(ws.prepare(req)) exc = ValueError() self.writer.close.side_effect = exc ws._writer = self.writer self.loop.run_until_complete(ws.close()) self.assertTrue(ws.closed) self.assertIs(ws.exception(), exc) ws._closed = False self.writer.close.side_effect = asyncio.CancelledError() self.assertRaises(asyncio.CancelledError, self.loop.run_until_complete, ws.close()) def test_start_twice_idempotent(self): req = self.make_request('GET', '/') ws = WebSocketResponse() with self.assertWarns(DeprecationWarning): impl1 = ws.start(req) impl2 = ws.start(req) self.assertIs(impl1, impl2) def test_can_start_ok(self): req = self.make_request('GET', '/', protocols=True) ws = WebSocketResponse(protocols=('chat',)) with self.assertWarns(DeprecationWarning): self.assertEqual((True, 'chat'), ws.can_start(req)) aiohttp-0.20.2/tests/test_websocket_client_functional.py0000664000175000017500000001566512613272676024401 0ustar andrewandrew00000000000000import aiohttp import asyncio import pytest from aiohttp import web @pytest.mark.run_loop def test_send_recv_text(create_app_and_client): @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) msg = yield from ws.receive_str() ws.send_str(msg+'/answer') yield from ws.close() return ws app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.ws_connect('/') resp.send_str('ask') msg = yield from resp.receive() assert msg.data == 'ask/answer' yield from resp.close() @pytest.mark.run_loop def test_send_recv_bytes(create_app_and_client): @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) msg = yield from ws.receive_bytes() ws.send_bytes(msg+b'/answer') yield from ws.close() return ws app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.ws_connect('/') resp.send_bytes(b'ask') msg = yield from resp.receive() assert msg.data == b'ask/answer' yield from resp.close() @pytest.mark.run_loop def test_ping_pong(create_app_and_client, loop): closed = asyncio.Future(loop=loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) msg = yield from ws.receive_bytes() ws.ping() ws.send_bytes(msg+b'/answer') try: yield from ws.close() finally: closed.set_result(1) return ws app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.ws_connect('/') resp.ping() resp.send_bytes(b'ask') msg = yield from resp.receive() assert msg.tp == aiohttp.MsgType.binary assert msg.data == b'ask/answer' msg = yield from resp.receive() assert msg.tp == aiohttp.MsgType.close yield from resp.close() yield from closed @pytest.mark.run_loop def test_ping_pong_manual(create_app_and_client, loop): closed = asyncio.Future(loop=loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) msg = yield from ws.receive_bytes() ws.ping() ws.send_bytes(msg+b'/answer') try: yield from ws.close() finally: closed.set_result(1) return ws app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.ws_connect('/', autoping=False) resp.ping() resp.send_bytes(b'ask') msg = yield from resp.receive() assert msg.tp == aiohttp.MsgType.pong msg = yield from resp.receive() assert msg.tp == aiohttp.MsgType.ping resp.pong() msg = yield from resp.receive() assert msg.data == b'ask/answer' msg = yield from resp.receive() assert msg.tp == aiohttp.MsgType.close yield from closed @pytest.mark.run_loop def test_close(create_app_and_client): @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) yield from ws.receive_bytes() ws.send_str('test') yield from ws.receive() return ws app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.ws_connect('/') resp.send_bytes(b'ask') closed = yield from resp.close() assert closed assert resp.closed assert resp.close_code == 1000 msg = yield from resp.receive() assert msg.tp == aiohttp.MsgType.closed @pytest.mark.run_loop def test_close_from_server(create_app_and_client, loop): closed = asyncio.Future(loop=loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) try: yield from ws.receive_bytes() yield from ws.close() finally: closed.set_result(1) return ws app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.ws_connect('/') resp.send_bytes(b'ask') msg = yield from resp.receive() assert msg.tp == aiohttp.MsgType.close assert resp.closed msg = yield from resp.receive() assert msg.tp == aiohttp.MsgType.closed yield from closed @pytest.mark.run_loop def test_close_manual(create_app_and_client, loop): closed = asyncio.Future(loop=loop) @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) yield from ws.receive_bytes() ws.send_str('test') try: yield from ws.close() finally: closed.set_result(1) return ws app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.ws_connect('/', autoclose=False) resp.send_bytes(b'ask') msg = yield from resp.receive() assert msg.data == 'test' msg = yield from resp.receive() assert msg.tp == aiohttp.MsgType.close assert msg.data == 1000 assert msg.extra == '' assert not resp.closed yield from resp.close() yield from closed assert resp.closed @pytest.mark.run_loop def test_close_timeout(create_app_and_client, loop): @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) yield from ws.receive_bytes() ws.send_str('test') yield from asyncio.sleep(10, loop=loop) app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.ws_connect('/', timeout=0.2, autoclose=False) resp.send_bytes(b'ask') msg = yield from resp.receive() assert msg.data == 'test' assert msg.tp == aiohttp.MsgType.text msg = yield from resp.close() assert resp.closed assert isinstance(resp.exception(), asyncio.TimeoutError) @pytest.mark.run_loop def test_close_cancel(create_app_and_client, loop): @asyncio.coroutine def handler(request): ws = web.WebSocketResponse() yield from ws.prepare(request) yield from ws.receive_bytes() ws.send_str('test') yield from asyncio.sleep(10, loop=loop) app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.ws_connect('/', autoclose=False) resp.send_bytes(b'ask') text = yield from resp.receive() assert text.data == 'test' t = loop.create_task(resp.close()) yield from asyncio.sleep(0.1, loop=loop) t.cancel() yield from asyncio.sleep(0.1, loop=loop) assert resp.closed assert resp.exception() is None aiohttp-0.20.2/tests/test_signals.py0000664000175000017500000000710112610642024020236 0ustar andrewandrew00000000000000import asyncio from unittest import mock from aiohttp.multidict import CIMultiDict from aiohttp.signals import Signal from aiohttp.web import Application from aiohttp.web import Request, Response from aiohttp.protocol import HttpVersion11 from aiohttp.protocol import RawRequestMessage import pytest @pytest.fixture def app(loop): return Application(loop=loop) @pytest.fixture def debug_app(loop): return Application(loop=loop, debug=True) def make_request(app, method, path, headers=CIMultiDict()): message = RawRequestMessage(method, path, HttpVersion11, headers, False, False) return request_from_message(message, app) def request_from_message(message, app): payload = mock.Mock() transport = mock.Mock() reader = mock.Mock() writer = mock.Mock() req = Request(app, message, payload, transport, reader, writer) return req def test_add_response_prepare_signal_handler(loop, app): callback = asyncio.coroutine(lambda request, response: None) app.on_response_prepare.append(callback) def test_add_signal_handler_not_a_callable(loop, app): callback = True app.on_response_prepare.append(callback) with pytest.raises(TypeError): app.on_response_prepare(None, None) def test_function_signal_dispatch(loop, app): signal = Signal(app) kwargs = {'foo': 1, 'bar': 2} callback_mock = mock.Mock() @asyncio.coroutine def callback(**kwargs): callback_mock(**kwargs) signal.append(callback) loop.run_until_complete(signal.send(**kwargs)) callback_mock.assert_called_once_with(**kwargs) def test_function_signal_dispatch2(loop, app): signal = Signal(app) args = {'a', 'b'} kwargs = {'foo': 1, 'bar': 2} callback_mock = mock.Mock() @asyncio.coroutine def callback(*args, **kwargs): callback_mock(*args, **kwargs) signal.append(callback) loop.run_until_complete(signal.send(*args, **kwargs)) callback_mock.assert_called_once_with(*args, **kwargs) def test_response_prepare(loop, app): callback = mock.Mock() @asyncio.coroutine def cb(*args, **kwargs): callback(*args, **kwargs) app.on_response_prepare.append(cb) request = make_request(app, 'GET', '/') response = Response(body=b'') loop.run_until_complete(response.prepare(request)) callback.assert_called_once_with(request, response) def test_non_coroutine(loop, app): signal = Signal(app) kwargs = {'foo': 1, 'bar': 2} callback = mock.Mock() signal.append(callback) loop.run_until_complete(signal.send(**kwargs)) callback.assert_called_once_with(**kwargs) def test_copy_forbidden(app): signal = Signal(app) with pytest.raises(NotImplementedError): signal.copy() def test_sort_forbidden(app): l1 = lambda: None l2 = lambda: None l3 = lambda: None signal = Signal(app) signal.extend([l1, l2, l3]) with pytest.raises(NotImplementedError): signal.sort() assert signal == [l1, l2, l3] def test_debug_signal(loop, debug_app): assert debug_app.debug, "Should be True" signal = Signal(debug_app) callback = mock.Mock() pre = mock.Mock() post = mock.Mock() signal.append(callback) debug_app.on_pre_signal.append(pre) debug_app.on_post_signal.append(post) loop.run_until_complete(signal.send(1, a=2)) callback.assert_called_once_with(1, a=2) pre.assert_called_once_with(1, 'aiohttp.signals:Signal', 1, a=2) post.assert_called_once_with(1, 'aiohttp.signals:Signal', 1, a=2) aiohttp-0.20.2/tests/test_wsgi.py0000664000175000017500000002635512643024604017567 0ustar andrewandrew00000000000000"""Tests for http/wsgi.py""" import io import asyncio import socket import unittest import unittest.mock import aiohttp from aiohttp import multidict from aiohttp import wsgi from aiohttp import protocol class TestHttpWsgiServerProtocol(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) self.wsgi = unittest.mock.Mock() self.reader = unittest.mock.Mock() self.writer = unittest.mock.Mock() self.writer.drain.return_value = () self.transport = unittest.mock.Mock() self.transport.get_extra_info.side_effect = [ unittest.mock.Mock(family=socket.AF_INET), ('1.2.3.4', 1234), ('2.3.4.5', 80)] self.headers = multidict.MultiDict({"HOST": "python.org"}) self.message = protocol.RawRequestMessage( 'GET', '/path', (1, 0), self.headers, True, 'deflate') self.payload = aiohttp.FlowControlDataQueue(self.reader) self.payload.feed_data(b'data', 4) self.payload.feed_data(b'data', 4) self.payload.feed_eof() def tearDown(self): self.loop.close() def test_ctor(self): srv = wsgi.WSGIServerHttpProtocol(self.wsgi, loop=self.loop) self.assertIs(srv.wsgi, self.wsgi) self.assertFalse(srv.readpayload) def _make_one(self, **kw): srv = wsgi.WSGIServerHttpProtocol(self.wsgi, loop=self.loop, **kw) srv.reader = self.reader srv.writer = self.writer srv.transport = self.transport return srv.create_wsgi_environ(self.message, self.payload) def _make_srv(self, app=None, **kw): if app is None: app = self.wsgi srv = wsgi.WSGIServerHttpProtocol(app, loop=self.loop, **kw) srv.reader = self.reader srv.writer = self.writer srv.transport = self.transport return srv def test_environ(self): environ = self._make_one() self.assertEqual(environ['RAW_URI'], '/path') self.assertEqual(environ['wsgi.async'], True) def test_environ_headers(self): self.headers.extend( (('SCRIPT_NAME', 'script'), ('CONTENT-TYPE', 'text/plain'), ('CONTENT-LENGTH', '209'), ('X_TEST', '123'), ('X_TEST', '456'))) environ = self._make_one() self.assertEqual(environ['CONTENT_TYPE'], 'text/plain') self.assertEqual(environ['CONTENT_LENGTH'], '209') self.assertEqual(environ['HTTP_X_TEST'], '123,456') self.assertEqual(environ['SCRIPT_NAME'], 'script') self.assertEqual(environ['SERVER_NAME'], 'python.org') self.assertEqual(environ['SERVER_PORT'], '80') get_extra_info_calls = self.transport.get_extra_info.mock_calls expected_calls = [ unittest.mock.call('socket'), unittest.mock.call('peername'), ] self.assertEqual(expected_calls, get_extra_info_calls) def test_environ_host_header_alternate_port(self): self.headers.update({'HOST': 'example.com:9999'}) environ = self._make_one() self.assertEqual(environ['SERVER_PORT'], '9999') def test_environ_host_header_alternate_port_ssl(self): self.headers.update({'HOST': 'example.com:9999'}) environ = self._make_one(is_ssl=True) self.assertEqual(environ['SERVER_PORT'], '9999') def test_wsgi_response(self): srv = self._make_srv() resp = srv.create_wsgi_response(self.message) self.assertIsInstance(resp, wsgi.WsgiResponse) def test_wsgi_response_start_response(self): srv = self._make_srv() resp = srv.create_wsgi_response(self.message) resp.start_response( '200 OK', [('CONTENT-TYPE', 'text/plain')]) self.assertEqual(resp.status, '200 OK') self.assertIsInstance(resp.response, protocol.Response) def test_wsgi_response_start_response_exc(self): srv = self._make_srv() resp = srv.create_wsgi_response(self.message) resp.start_response( '200 OK', [('CONTENT-TYPE', 'text/plain')], ['', ValueError()]) self.assertEqual(resp.status, '200 OK') self.assertIsInstance(resp.response, protocol.Response) def test_wsgi_response_start_response_exc_status(self): srv = self._make_srv() resp = srv.create_wsgi_response(self.message) resp.start_response('200 OK', [('CONTENT-TYPE', 'text/plain')]) self.assertRaises( ValueError, resp.start_response, '500 Err', [('CONTENT-TYPE', 'text/plain')], ['', ValueError()]) @unittest.mock.patch('aiohttp.wsgi.aiohttp') def test_wsgi_response_101_upgrade_to_websocket(self, m_asyncio): srv = self._make_srv() resp = srv.create_wsgi_response(self.message) resp.start_response( '101 Switching Protocols', (('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'))) self.assertEqual(resp.status, '101 Switching Protocols') self.assertTrue(m_asyncio.Response.return_value.send_headers.called) def test_file_wrapper(self): fobj = io.BytesIO(b'data') wrapper = wsgi.FileWrapper(fobj, 2) self.assertIs(wrapper, iter(wrapper)) self.assertTrue(hasattr(wrapper, 'close')) self.assertEqual(next(wrapper), b'da') self.assertEqual(next(wrapper), b'ta') self.assertRaises(StopIteration, next, wrapper) wrapper = wsgi.FileWrapper(b'data', 2) self.assertFalse(hasattr(wrapper, 'close')) def test_handle_request_futures(self): def wsgi_app(env, start): start('200 OK', [('Content-Type', 'text/plain')]) f1 = asyncio.Future(loop=self.loop) f1.set_result(b'data') fut = asyncio.Future(loop=self.loop) fut.set_result([f1]) return fut srv = self._make_srv(wsgi_app) self.loop.run_until_complete( srv.handle_request(self.message, self.payload)) content = b''.join( [c[1][0] for c in self.writer.write.mock_calls]) self.assertTrue(content.startswith(b'HTTP/1.0 200 OK')) self.assertTrue(content.endswith(b'data')) def test_handle_request_simple(self): def wsgi_app(env, start): start('200 OK', [('Content-Type', 'text/plain')]) return [b'data'] stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(b'data') stream.feed_eof() self.message = protocol.RawRequestMessage( 'GET', '/path', (1, 1), self.headers, True, 'deflate') srv = self._make_srv(wsgi_app, readpayload=True) self.loop.run_until_complete( srv.handle_request(self.message, self.payload)) content = b''.join( [c[1][0] for c in self.writer.write.mock_calls]) self.assertTrue(content.startswith(b'HTTP/1.1 200 OK')) self.assertTrue(content.endswith(b'data\r\n0\r\n\r\n')) self.assertFalse(srv._keep_alive) def test_handle_request_io(self): def wsgi_app(env, start): start('200 OK', [('Content-Type', 'text/plain')]) return io.BytesIO(b'data') srv = self._make_srv(wsgi_app) self.loop.run_until_complete( srv.handle_request(self.message, self.payload)) content = b''.join( [c[1][0] for c in self.writer.write.mock_calls]) self.assertTrue(content.startswith(b'HTTP/1.0 200 OK')) self.assertTrue(content.endswith(b'data')) def test_handle_request_keep_alive(self): def wsgi_app(env, start): start('200 OK', [('Content-Type', 'text/plain')]) return [b'data'] stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(b'data') stream.feed_eof() self.message = protocol.RawRequestMessage( 'GET', '/path', (1, 1), self.headers, False, 'deflate') srv = self._make_srv(wsgi_app, readpayload=True) self.loop.run_until_complete( srv.handle_request(self.message, self.payload)) content = b''.join( [c[1][0] for c in self.writer.write.mock_calls]) self.assertTrue(content.startswith(b'HTTP/1.1 200 OK')) self.assertTrue(content.endswith(b'data\r\n0\r\n\r\n')) self.assertTrue(srv._keep_alive) def test_handle_request_readpayload(self): def wsgi_app(env, start): start('200 OK', [('Content-Type', 'text/plain')]) return [env['wsgi.input'].read()] srv = self._make_srv(wsgi_app, readpayload=True) self.loop.run_until_complete( srv.handle_request(self.message, self.payload)) content = b''.join( [c[1][0] for c in self.writer.write.mock_calls]) self.assertTrue(content.startswith(b'HTTP/1.0 200 OK')) self.assertTrue(content.endswith(b'data')) def test_dont_unquote_environ_path_info(self): path = '/path/some%20text' self.message = protocol.RawRequestMessage( 'GET', path, (1, 0), self.headers, True, 'deflate') environ = self._make_one() self.assertEqual(environ['PATH_INFO'], path) def test_authorization(self): # This header should be removed according to CGI/1.1 and WSGI but # in our case basic auth is not handled by server, so should # not be removed self.headers.extend({'AUTHORIZATION': 'spam'}) self.message = protocol.RawRequestMessage( 'GET', '/', (1, 1), self.headers, True, 'deflate') environ = self._make_one() self.assertEqual('spam', environ['HTTP_AUTHORIZATION']) def test_http_1_0_no_host(self): headers = multidict.MultiDict({}) self.message = protocol.RawRequestMessage( 'GET', '/', (1, 0), headers, True, 'deflate') environ = self._make_one() self.assertEqual(environ['SERVER_NAME'], '2.3.4.5') self.assertEqual(environ['SERVER_PORT'], '80') def test_family_inet6(self): self.transport.get_extra_info.side_effect = [ unittest.mock.Mock(family=socket.AF_INET6), ("::", 1122, 0, 0), ('2.3.4.5', 80)] self.message = protocol.RawRequestMessage( 'GET', '/', (1, 0), self.headers, True, 'deflate') environ = self._make_one() self.assertEqual(environ['SERVER_NAME'], 'python.org') self.assertEqual(environ['SERVER_PORT'], '80') self.assertEqual(environ['REMOTE_ADDR'], '::') self.assertEqual(environ['REMOTE_PORT'], '1122') def test_family_unix(self): if not hasattr(socket, "AF_UNIX"): self.skipTest("No UNIX address family. (Windows?)") self.transport.get_extra_info.side_effect = [ unittest.mock.Mock(family=socket.AF_UNIX)] headers = multidict.MultiDict({ 'SERVER_NAME': '1.2.3.4', 'SERVER_PORT': '5678', 'REMOTE_ADDR': '4.3.2.1', 'REMOTE_PORT': '8765'}) self.message = protocol.RawRequestMessage( 'GET', '/', (1, 0), headers, True, 'deflate') environ = self._make_one() self.assertEqual(environ['SERVER_NAME'], '1.2.3.4') self.assertEqual(environ['SERVER_PORT'], '5678') self.assertEqual(environ['REMOTE_ADDR'], '4.3.2.1') self.assertEqual(environ['REMOTE_PORT'], '8765') aiohttp-0.20.2/tests/test_web_application.py0000664000175000017500000000401512643552137021752 0ustar andrewandrew00000000000000import asyncio import pytest from aiohttp import web, log from unittest import mock def test_app_ctor(loop): app = web.Application(loop=loop) assert loop is app.loop assert app.logger is log.web_logger def test_app_call(loop): app = web.Application(loop=loop) assert app is app() def test_app_copy(loop): app = web.Application(loop=loop) with pytest.raises(NotImplementedError): app.copy() def test_app_default_loop(loop): asyncio.set_event_loop(loop) app = web.Application() assert loop is app.loop @pytest.mark.run_loop def test_app_register_on_finish(loop): app = web.Application(loop=loop) cb1 = mock.Mock() cb2 = mock.Mock() app.register_on_finish(cb1, 1, b=2) app.register_on_finish(cb2, 2, c=3) yield from app.finish() cb1.assert_called_once_with(app, 1, b=2) cb2.assert_called_once_with(app, 2, c=3) @pytest.mark.run_loop def test_app_register_coro(loop): app = web.Application(loop=loop) fut = asyncio.Future(loop=loop) @asyncio.coroutine def cb(app): yield from asyncio.sleep(0.001, loop=loop) fut.set_result(123) app.register_on_finish(cb) yield from app.finish() assert fut.done() assert 123 == fut.result() @pytest.mark.run_loop def test_app_error_in_finish_callbacks(loop): app = web.Application(loop=loop) err = RuntimeError('bad call') app.register_on_finish(mock.Mock(side_effect=err)) handler = mock.Mock() loop.set_exception_handler(handler) yield from app.finish() exc_info = {'exception': err, 'application': app, 'message': 'Error in finish callback'} handler.assert_called_once_with(loop, exc_info) def test_non_default_router(loop): router = web.UrlDispatcher() app = web.Application(loop=loop, router=router) assert router is app.router def test_logging(self): logger = mock.Mock() app = web.Application(loop=self.loop) app.logger = logger self.assertIs(app.logger, logger) aiohttp-0.20.2/tests/autobahn/0000775000175000017500000000000012643555674017013 5ustar andrewandrew00000000000000aiohttp-0.20.2/tests/autobahn/server.py0000664000175000017500000000273712602466630020670 0ustar andrewandrew00000000000000#!/usr/bin/env python3 import asyncio import logging from aiohttp import web @asyncio.coroutine def wshandler(request): ws = web.WebSocketResponse(autoclose=False) ok, protocol = ws.can_start(request) if not ok: return web.HTTPBadRequest() yield from ws.prepare(request) while True: msg = yield from ws.receive() if msg.tp == web.MsgType.text: ws.send_str(msg.data) elif msg.tp == web.MsgType.binary: ws.send_bytes(msg.data) elif msg.tp == web.MsgType.close: yield from ws.close() break else: break return ws @asyncio.coroutine def main(loop): app = web.Application(loop=loop) app.router.add_route('GET', '/', wshandler) handler = app.make_handler() srv = yield from loop.create_server(handler, '127.0.0.1', 9001) print("Server started at http://127.0.0.1:9001") return app, srv, handler @asyncio.coroutine def finish(app, srv, handler): srv.close() yield from handler.finish_connections() yield from srv.wait_closed() 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() except KeyboardInterrupt: loop.run_until_complete(finish(app, srv, handler)) aiohttp-0.20.2/tests/autobahn/fuzzingclient.json0000664000175000017500000000042412552474754022577 0ustar andrewandrew00000000000000{ "options": {"failByDrop": false}, "outdir": "./reports/servers", "servers": [{"agent": "AutobahnServer", "url": "ws://localhost:9001", "options": {"version": 18}}], "cases": ["*"], "exclude-cases": ["12.*", "13.*"], "exclude-agent-cases": {} } aiohttp-0.20.2/tests/autobahn/client.py0000664000175000017500000000250512552474754020643 0ustar andrewandrew00000000000000#!/usr/bin/env python3 import asyncio import aiohttp def client(loop, url, name): ws = yield from aiohttp.ws_connect(url + '/getCaseCount') num_tests = int((yield from ws.receive()).data) print('running %d cases' % num_tests) yield from ws.close() for i in range(1, num_tests + 1): print('running test case:', i) text_url = url + '/runCase?case=%d&agent=%s' % (i, name) ws = yield from aiohttp.ws_connect(text_url) while True: msg = yield from ws.receive() if msg.tp == aiohttp.MsgType.text: ws.send_str(msg.data) elif msg.tp == aiohttp.MsgType.binary: ws.send_bytes(msg.data) elif msg.tp == aiohttp.MsgType.close: yield from ws.close() break else: break url = url + '/updateReports?agent=%s' % name ws = yield from aiohttp.ws_connect(url) yield from ws.close() def run(loop, url, name): try: yield from client(loop, url, name) except: import traceback traceback.print_exc() if __name__ == '__main__': loop = asyncio.get_event_loop() try: loop.run_until_complete(run(loop, 'http://localhost:9001', 'aiohttp')) except KeyboardInterrupt: pass finally: loop.close() aiohttp-0.20.2/tests/autobahn/fuzzingserver.json0000664000175000017500000000033112552474754022624 0ustar andrewandrew00000000000000 { "url": "ws://localhost:9001", "options": {"failByDrop": false}, "outdir": "./reports/clients", "webport": 8080, "cases": ["*"], "exclude-cases": ["12.*", "13.*"], "exclude-agent-cases": {} } aiohttp-0.20.2/tests/test_server.py0000664000175000017500000003351712635327571020134 0ustar andrewandrew00000000000000"""Tests for aiohttp/server.py""" import asyncio import pytest import socket from html import escape from unittest import mock from aiohttp import server from aiohttp import errors @pytest.yield_fixture def make_srv(loop): srv = None def maker(**kwargs): nonlocal srv srv = server.ServerHttpProtocol(loop=loop, **kwargs) return srv yield maker if srv is not None: srv.connection_lost(None) @pytest.fixture def srv(make_srv): return make_srv() def test_http_error_exception(): exc = errors.HttpProcessingError(code=500, message='Internal error') assert exc.code == 500 assert exc.message == 'Internal error' def test_handle_request(srv): transport = mock.Mock() srv.connection_made(transport) srv.writer = mock.Mock() message = mock.Mock() message.headers = [] message.version = (1, 1) srv.handle_request(message, mock.Mock()) content = b''.join( [c[1][0] for c in list(srv.writer.write.mock_calls)]) assert content.startswith(b'HTTP/1.1 404 Not Found\r\n') def test_closing(srv): srv._keep_alive = True keep_alive_handle = mock.Mock() srv._keep_alive_handle = keep_alive_handle timeout_handle = mock.Mock() srv._timeout_handle = timeout_handle transport = srv.transport = mock.Mock() request_handler = srv._request_handler = mock.Mock() srv.writer = mock.Mock() srv.closing() assert transport.close.called assert srv.transport is None assert srv._keep_alive_handle is not None assert not keep_alive_handle.cancel.called assert srv._timeout_handle is not None assert not timeout_handle.cancel.called assert srv._request_handler is None assert request_handler.cancel.called def test_closing_during_reading(srv): srv._keep_alive = True srv._keep_alive_on = True srv._reading_request = True srv._timeout_handle = timeout_handle = mock.Mock() transport = srv.transport = mock.Mock() srv.closing() assert not transport.close.called assert srv.transport is not None # cancel existing slow request handler assert srv._timeout_handle is not None assert timeout_handle.cancel.called assert timeout_handle is not srv._timeout_handle def test_double_closing(srv): srv._keep_alive = True keep_alive_handle = mock.Mock() srv._keep_alive_handle = keep_alive_handle timeout_handle = mock.Mock() srv._timeout_handle = timeout_handle transport = srv.transport = mock.Mock() srv.writer = mock.Mock() srv.closing() assert transport.close.called assert srv.transport is None transport.reset_mock() srv.closing() assert not transport.close.called assert srv.transport is None assert srv._keep_alive_handle is not None assert not keep_alive_handle.cancel.called assert srv._timeout_handle is not None assert not timeout_handle.cancel.called def test_connection_made(srv): assert srv._request_handler is None srv.connection_made(mock.Mock()) assert srv._request_handler is not None assert srv._timeout_handle is None def test_connection_made_without_timeout(srv): srv.connection_made(mock.Mock()) assert srv._timeout_handle is None def test_connection_made_with_keepaplive(srv): sock = mock.Mock() transport = mock.Mock() transport.get_extra_info.return_value = sock srv.connection_made(transport) sock.setsockopt.assert_called_with(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) def test_connection_made_without_keepaplive(make_srv): srv = make_srv(keep_alive_on=False) sock = mock.Mock() transport = mock.Mock() transport.get_extra_info.return_value = sock srv.connection_made(transport) assert not sock.setsockopt.called def test_data_received(srv): srv.connection_made(mock.Mock()) srv.data_received(b'123') assert b'123' == bytes(srv.reader._buffer) srv.data_received(b'456') assert b'123456' == bytes(srv.reader._buffer) def test_eof_received(srv): srv.connection_made(mock.Mock()) srv.eof_received() assert srv.reader._eof @pytest.mark.run_loop def test_connection_lost(srv, loop): srv.connection_made(mock.Mock()) srv.data_received(b'123') timeout_handle = srv._timeout_handle = mock.Mock() keep_alive_handle = srv._keep_alive_handle = mock.Mock() handle = srv._request_handler srv.connection_lost(None) yield from asyncio.sleep(0, loop=loop) assert srv._request_handler is None assert handle.cancelled() assert srv._keep_alive_handle is None assert keep_alive_handle.cancel.called assert srv._timeout_handle is None assert timeout_handle.cancel.called srv.connection_lost(None) assert srv._request_handler is None assert srv._keep_alive_handle is None def test_srv_keep_alive(srv): assert not srv._keep_alive srv.keep_alive(True) assert srv._keep_alive srv.keep_alive(False) assert not srv._keep_alive def test_srv_slow_request(make_srv, loop): transport = mock.Mock() srv = make_srv(timeout=0.01) srv.connection_made(transport) srv.reader.feed_data( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n') loop.run_until_complete(srv._request_handler) assert transport.close.called srv.connection_lost(None) assert srv._timeout_handle is None def test_bad_method(srv, loop): transport = mock.Mock() srv.connection_made(transport) srv.reader.feed_data( b'!@#$ / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') loop.run_until_complete(srv._request_handler) assert transport.write.mock_calls[0][1][0].startswith( b'HTTP/1.1 400 Bad Request\r\n') def test_line_too_long(srv, loop): transport = mock.Mock() srv.connection_made(transport) srv.reader.feed_data(b''.join([b'a' for _ in range(10000)])) loop.run_until_complete(srv._request_handler) assert transport.write.mock_calls[0][1][0].startswith( b'HTTP/1.1 400 Bad Request\r\n') def test_handle_error(srv): transport = mock.Mock() srv.connection_made(transport) srv.keep_alive(True) srv.writer = mock.Mock() srv.handle_error(404, headers=(('X-Server', 'asyncio'),)) content = b''.join( [c[1][0] for c in list(srv.writer.write.mock_calls)]) assert b'HTTP/1.1 404 Not Found' in content assert b'X-SERVER: asyncio' in content assert not srv._keep_alive def test_handle_error__utf(make_srv): transport = mock.Mock() srv = make_srv(debug=True) srv.connection_made(transport) srv.keep_alive(True) srv.writer = mock.Mock() srv.logger = mock.Mock() try: raise RuntimeError('что-то пошло не так') except RuntimeError as exc: srv.handle_error(exc=exc) content = b''.join( [c[1][0] for c in list(srv.writer.write.mock_calls)]) assert b'HTTP/1.1 500 Internal Server Error' in content assert b'CONTENT-TYPE: text/html; charset=utf-8' in content pattern = escape("raise RuntimeError('что-то пошло не так')") assert pattern.encode('utf-8') in content assert not srv._keep_alive srv.logger.exception.assert_called_with("Error handling request") def test_handle_error_traceback_exc(make_srv): log = mock.Mock() srv = make_srv(debug=True, logger=log) srv.transport = mock.Mock() srv.transport.get_extra_info.return_value = '127.0.0.1' srv.writer = mock.Mock() srv._request_handler = mock.Mock() with mock.patch('aiohttp.server.traceback') as m_trace: m_trace.format_exc.side_effect = ValueError srv.handle_error(500, exc=object()) content = b''.join( [c[1][0] for c in list(srv.writer.write.mock_calls)]) assert content.startswith(b'HTTP/1.1 500 Internal Server Error') assert log.exception.called def test_handle_error_debug(srv): transport = mock.Mock() srv.debug = True srv.connection_made(transport) srv.writer = mock.Mock() try: raise ValueError() except Exception as exc: srv.handle_error(999, exc=exc) content = b''.join( [c[1][0] for c in list(srv.writer.write.mock_calls)]) assert b'HTTP/1.1 500 Internal' in content assert b'Traceback (most recent call last):' in content def test_handle_error_500(make_srv): log = mock.Mock() transport = mock.Mock() srv = make_srv(logger=log) srv.connection_made(transport) srv.writer = mock.Mock() srv.handle_error(500) assert log.exception.called def test_handle(srv, loop): def get_mock_coro(return_value): @asyncio.coroutine def mock_coro(*args, **kwargs): return return_value return mock.Mock(wraps=mock_coro) transport = mock.Mock() srv.connection_made(transport) handle = srv.handle_request = get_mock_coro(return_value=None) srv.reader.feed_data( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') loop.run_until_complete(srv._request_handler) assert handle.called assert transport.close.called def test_handle_uncompleted(srv, loop): transport = mock.Mock() srv.connection_made(transport) srv.logger.exception = mock.Mock() handle = srv.handle_request = mock.Mock() handle.side_effect = ValueError srv.reader.feed_data( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n' b'Content-Length: 50000\r\n\r\n') loop.run_until_complete(srv._request_handler) assert handle.called assert transport.close.called srv.logger.exception.assert_called_with("Error handling request") def test_handle_coro(srv, loop): transport = mock.Mock() called = False @asyncio.coroutine def coro(message, payload): nonlocal called called = True srv.eof_received() srv.handle_request = coro srv.connection_made(transport) srv.reader.feed_data( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') loop.run_until_complete(srv._request_handler) assert called def test_handle_cancel(make_srv, loop): log = mock.Mock() transport = mock.Mock() srv = make_srv(logger=log, debug=True) srv.connection_made(transport) srv.writer = mock.Mock() srv.handle_request = mock.Mock() @asyncio.coroutine def cancel(): srv._request_handler.cancel() loop.run_until_complete( asyncio.wait([srv._request_handler, cancel()], loop=loop)) assert log.debug.called def test_handle_cancelled(make_srv, loop): log = mock.Mock() transport = mock.Mock() srv = make_srv(logger=log, debug=True) srv.connection_made(transport) srv.handle_request = mock.Mock() # start request_handler task loop.run_until_complete(asyncio.sleep(0, loop=loop)) srv.reader.feed_data( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') r_handler = srv._request_handler srv._request_handler = None # emulate srv.connection_lost() assert loop.run_until_complete(r_handler) is None def test_handle_400(srv, loop): transport = mock.Mock() srv.connection_made(transport) srv.handle_error = mock.Mock() srv.keep_alive(True) srv.reader.feed_data(b'GET / HT/asd\r\n\r\n') loop.run_until_complete(srv._request_handler) assert srv.handle_error.called assert 400 == srv.handle_error.call_args[0][0] assert transport.close.called def test_handle_500(srv, loop): transport = mock.Mock() srv.connection_made(transport) handle = srv.handle_request = mock.Mock() handle.side_effect = ValueError srv.handle_error = mock.Mock() srv.reader.feed_data( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') loop.run_until_complete(srv._request_handler) assert srv.handle_error.called assert 500 == srv.handle_error.call_args[0][0] def test_handle_error_no_handle_task(srv): transport = mock.Mock() srv.keep_alive(True) srv.connection_made(transport) srv.connection_lost(None) srv.handle_error(300) assert not srv._keep_alive def test_keep_alive(make_srv, loop): srv = make_srv(keep_alive=0.1) transport = mock.Mock() closed = False def close(): nonlocal closed closed = True srv.connection_lost(None) loop.stop() transport.close = close srv.connection_made(transport) handle = srv.handle_request = mock.Mock() srv.reader.feed_data( b'GET / HTTP/1.1\r\n' b'CONNECTION: keep-alive\r\n' b'HOST: example.com\r\n\r\n') loop.run_forever() assert handle.called assert closed def test_keep_alive_close_existing(make_srv, loop): transport = mock.Mock() srv = make_srv(keep_alive=0) srv.connection_made(transport) assert srv._keep_alive_handle is None srv._keep_alive_period = 15 keep_alive_handle = srv._keep_alive_handle = mock.Mock() srv.handle_request = mock.Mock() srv.handle_request.return_value = asyncio.Future(loop=loop) srv.handle_request.return_value.set_result(1) srv.data_received( b'GET / HTTP/1.0\r\n' b'HOST: example.com\r\n\r\n') loop.run_until_complete(srv._request_handler) assert keep_alive_handle.cancel.called assert srv._keep_alive_handle is None assert transport.close.called def test_cancel_not_connected_handler(srv): srv.cancel_slow_request() def test_srv_process_request_without_timeout(make_srv, loop): transport = mock.Mock() srv = make_srv(timeout=0) srv.connection_made(transport) assert srv._timeout_handle is None srv.reader.feed_data( b'GET / HTTP/1.0\r\n' b'Host: example.com\r\n\r\n') loop.run_until_complete(srv._request_handler) assert transport.close.called assert srv._timeout_handle is None def test_keep_alive_timeout_default(srv): assert 75 == srv.keep_alive_timeout def test_keep_alive_timeout_nondefault(make_srv): srv = make_srv(keep_alive=10) assert 10 == srv.keep_alive_timeout aiohttp-0.20.2/tests/conftest.py0000664000175000017500000002070212626356514017403 0ustar andrewandrew00000000000000import asyncio import aiohttp import collections import gc import logging import pytest import re import socket import sys import warnings from aiohttp import web class _AssertWarnsContext: """A context manager used to implement TestCase.assertWarns* methods.""" def __init__(self, expected, expected_regex=None): self.expected = expected if expected_regex is not None: expected_regex = re.compile(expected_regex) self.expected_regex = expected_regex self.obj_name = None def __enter__(self): # The __warningregistry__'s need to be in a pristine state for tests # to work properly. for v in sys.modules.values(): if getattr(v, '__warningregistry__', None): v.__warningregistry__ = {} self.warnings_manager = warnings.catch_warnings(record=True) self.warnings = self.warnings_manager.__enter__() warnings.simplefilter("always", self.expected) return self def __exit__(self, exc_type, exc_value, tb): self.warnings_manager.__exit__(exc_type, exc_value, tb) if exc_type is not None: # let unexpected exceptions pass through return try: exc_name = self.expected.__name__ except AttributeError: exc_name = str(self.expected) first_matching = None for m in self.warnings: w = m.message if not isinstance(w, self.expected): continue if first_matching is None: first_matching = w if (self.expected_regex is not None and not self.expected_regex.search(str(w))): continue # store warning for later retrieval self.warning = w self.filename = m.filename self.lineno = m.lineno return # Now we simply try to choose a helpful failure message if first_matching is not None: __tracebackhide__ = True assert 0, '"{}" does not match "{}"'.format( self.expected_regex.pattern, str(first_matching)) if self.obj_name: __tracebackhide__ = True assert 0, "{} not triggered by {}".format(exc_name, self.obj_name) else: __tracebackhide__ = True assert 0, "{} not triggered".format(exc_name) _LoggingWatcher = collections.namedtuple("_LoggingWatcher", ["records", "output"]) class _CapturingHandler(logging.Handler): """ A logging handler capturing all (raw and formatted) logging output. """ def __init__(self): logging.Handler.__init__(self) self.watcher = _LoggingWatcher([], []) def flush(self): pass def emit(self, record): self.watcher.records.append(record) msg = self.format(record) self.watcher.output.append(msg) class _AssertLogsContext: """A context manager used to implement TestCase.assertLogs().""" LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s" def __init__(self, logger_name=None, level=None): self.logger_name = logger_name if level: self.level = logging._nameToLevel.get(level, level) else: self.level = logging.INFO self.msg = None def __enter__(self): if isinstance(self.logger_name, logging.Logger): logger = self.logger = self.logger_name else: logger = self.logger = logging.getLogger(self.logger_name) formatter = logging.Formatter(self.LOGGING_FORMAT) handler = _CapturingHandler() handler.setFormatter(formatter) self.watcher = handler.watcher self.old_handlers = logger.handlers[:] self.old_level = logger.level self.old_propagate = logger.propagate logger.handlers = [handler] logger.setLevel(self.level) logger.propagate = False return handler.watcher def __exit__(self, exc_type, exc_value, tb): self.logger.handlers = self.old_handlers self.logger.propagate = self.old_propagate self.logger.setLevel(self.old_level) if exc_type is not None: # let unexpected exceptions pass through return False if len(self.watcher.records) == 0: __tracebackhide__ = True assert 0, ("no logs of level {} or higher triggered on {}" .format(logging.getLevelName(self.level), self.logger.name)) @pytest.yield_fixture def warning(): yield _AssertWarnsContext @pytest.yield_fixture def log(): yield _AssertLogsContext @pytest.fixture def unused_port(): def f(): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind(('127.0.0.1', 0)) return s.getsockname()[1] return f @pytest.yield_fixture def loop(request): loop = asyncio.new_event_loop() asyncio.set_event_loop(None) yield loop if not loop._closed: loop.stop() loop.run_forever() loop.close() gc.collect() asyncio.set_event_loop(None) @pytest.yield_fixture def create_server(loop, unused_port): app = handler = srv = None @asyncio.coroutine def create(*, debug=False, ssl_ctx=None, proto='http'): nonlocal app, handler, srv app = web.Application(loop=loop) port = unused_port() handler = app.make_handler(debug=debug, keep_alive_on=False) srv = yield from loop.create_server(handler, '127.0.0.1', port, ssl=ssl_ctx) if ssl_ctx: proto += 's' url = "{}://127.0.0.1:{}".format(proto, port) return app, url yield create @asyncio.coroutine def finish(): yield from handler.finish_connections() yield from app.finish() srv.close() yield from srv.wait_closed() loop.run_until_complete(finish()) class Client: def __init__(self, session, url): self._session = session if not url.endswith('/'): url += '/' self._url = url def close(self): self._session.close() def get(self, path, **kwargs): while path.startswith('/'): path = path[1:] url = self._url + path return self._session.get(url, **kwargs) def post(self, path, **kwargs): while path.startswith('/'): path = path[1:] url = self._url + path return self._session.post(url, **kwargs) def ws_connect(self, path, **kwargs): while path.startswith('/'): path = path[1:] url = self._url + path return self._session.ws_connect(url, **kwargs) @pytest.yield_fixture def create_app_and_client(create_server, loop): client = None @asyncio.coroutine def maker(*, server_params=None, client_params=None): nonlocal client if server_params is None: server_params = {} server_params.setdefault('debug', False) server_params.setdefault('ssl_ctx', None) app, url = yield from create_server(**server_params) if client_params is None: client_params = {} client = Client(aiohttp.ClientSession(loop=loop, **client_params), url) return app, client yield maker client.close() @pytest.mark.tryfirst def pytest_pycollect_makeitem(collector, name, obj): if collector.funcnamefilter(name): if not callable(obj): return item = pytest.Function(name, parent=collector) if 'run_loop' in item.keywords: return list(collector._genfunctions(name, obj)) @pytest.mark.tryfirst def pytest_pyfunc_call(pyfuncitem): """ Run asyncio marked test functions in an event loop instead of a normal function call. """ if 'run_loop' in pyfuncitem.keywords: funcargs = pyfuncitem.funcargs loop = funcargs['loop'] testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames} loop.run_until_complete(pyfuncitem.obj(**testargs)) return True def pytest_runtest_setup(item): if 'run_loop' in item.keywords and 'loop' not in item.fixturenames: # inject an event loop fixture for all async tests item.fixturenames.append('loop') def pytest_ignore_collect(path, config): if 'test_py35' in str(path): if sys.version_info < (3, 5, 0): return True aiohttp-0.20.2/tests/test_web_functional.py0000664000175000017500000010631312624767531021622 0ustar andrewandrew00000000000000import asyncio import gc import json import os import os.path import socket import unittest from aiohttp import log, web, request, FormData, ClientSession, TCPConnector from aiohttp.multidict import MultiDict from aiohttp.protocol import HttpVersion, HttpVersion10, HttpVersion11 from aiohttp.streams import EOF_MARKER from unittest import mock try: import ssl except: ssl = False class WebFunctionalSetupMixin: def setUp(self): self.handler = None self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): if self.handler: self.loop.run_until_complete(self.handler.finish_connections()) self.loop.stop() self.loop.run_forever() self.loop.close() gc.collect() def find_unused_port(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 0)) port = s.getsockname()[1] s.close() return port @asyncio.coroutine def create_server(self, method, path, handler=None, ssl_ctx=None): app = web.Application(loop=self.loop) if handler: app.router.add_route(method, path, handler) port = self.find_unused_port() self.handler = app.make_handler( keep_alive_on=False, access_log=log.access_logger) srv = yield from self.loop.create_server( self.handler, '127.0.0.1', port, ssl=ssl_ctx) protocol = "https" if ssl_ctx else "http" url = "{}://127.0.0.1:{}".format(protocol, port) + path self.addCleanup(srv.close) return app, srv, url class TestWebFunctional(WebFunctionalSetupMixin, unittest.TestCase): def test_simple_get(self): @asyncio.coroutine def handler(request): body = yield from request.read() self.assertEqual(b'', body) return web.Response(body=b'OK') @asyncio.coroutine def go(): _, srv, url = yield from self.create_server('GET', '/', handler) resp = yield from request('GET', url, loop=self.loop) self.assertEqual(200, resp.status) txt = yield from resp.text() self.assertEqual('OK', txt) self.loop.run_until_complete(go()) def test_handler_returns_not_response(self): @asyncio.coroutine def handler(request): return 'abc' @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp = yield from request('GET', url, loop=self.loop) self.assertEqual(500, resp.status) resp.close() with mock.patch('aiohttp.server.server_logger'): self.loop.run_until_complete(go()) def test_post_form(self): @asyncio.coroutine def handler(request): data = yield from request.post() self.assertEqual({'a': '1', 'b': '2'}, dict(data)) return web.Response(body=b'OK') @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) resp = yield from request('POST', url, data={'a': 1, 'b': 2}, loop=self.loop) self.assertEqual(200, resp.status) txt = yield from resp.text() self.assertEqual('OK', txt) self.loop.run_until_complete(go()) def test_post_text(self): @asyncio.coroutine def handler(request): data = yield from request.text() self.assertEqual('руÑÑкий', data) data2 = yield from request.text() self.assertEqual(data, data2) return web.Response(text=data) @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) resp = yield from request('POST', url, data='руÑÑкий', loop=self.loop) self.assertEqual(200, resp.status) txt = yield from resp.text() self.assertEqual('руÑÑкий', txt) self.loop.run_until_complete(go()) def test_post_json(self): dct = {'key': 'текÑÑ‚'} @asyncio.coroutine def handler(request): data = yield from request.json() self.assertEqual(dct, data) data2 = yield from request.json() self.assertEqual(data, data2) resp = web.Response() resp.content_type = 'application/json' resp.body = json.dumps(data).encode('utf8') return resp @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) headers = {'Content-Type': 'application/json'} resp = yield from request('POST', url, data=json.dumps(dct), headers=headers, loop=self.loop) self.assertEqual(200, resp.status) data = yield from resp.json() self.assertEqual(dct, data) self.loop.run_until_complete(go()) def test_render_redirect(self): @asyncio.coroutine def handler(request): raise web.HTTPMovedPermanently(location='/path') @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp = yield from request('GET', url, loop=self.loop, allow_redirects=False) self.assertEqual(301, resp.status) txt = yield from resp.text() self.assertEqual('301: Moved Permanently', txt) self.assertEqual('/path', resp.headers['location']) self.loop.run_until_complete(go()) def test_post_single_file(self): here = os.path.dirname(__file__) def check_file(fs): fullname = os.path.join(here, fs.filename) with open(fullname, 'r') as f: test_data = f.read().encode() data = fs.file.read() self.assertEqual(test_data, data) @asyncio.coroutine def handler(request): data = yield from request.post() self.assertEqual(['sample.crt'], list(data.keys())) for fs in data.values(): check_file(fs) fs.file.close() resp = web.Response(body=b'OK') return resp @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) f = open(os.path.join(here, 'sample.crt')) resp = yield from request('POST', url, data=[f], loop=self.loop) self.assertEqual(200, resp.status) resp.close() f.close() self.loop.run_until_complete(go()) def test_files_upload_with_same_key(self): @asyncio.coroutine def handler(request): data = yield from request.post() files = data.getall('file') _file_names = [] for _file in files: self.assertFalse(_file.file.closed) if _file.filename == 'test1.jpeg': self.assertEqual(_file.file.read(), b'binary data 1') if _file.filename == 'test2.jpeg': self.assertEqual(_file.file.read(), b'binary data 2') _file_names.append(_file.filename) self.assertCountEqual(_file_names, ['test1.jpeg', 'test2.jpeg']) resp = web.Response(body=b'OK') return resp @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) _data = FormData() _data.add_field('file', b'binary data 1', content_type='image/jpeg', filename='test1.jpeg') _data.add_field('file', b'binary data 2', content_type='image/jpeg', filename='test2.jpeg') resp = yield from request('POST', url, data=_data, loop=self.loop) self.assertEqual(200, resp.status) resp.close() self.loop.run_until_complete(go()) def test_post_files(self): here = os.path.dirname(__file__) f1 = open(os.path.join(here, 'sample.crt')) f2 = open(os.path.join(here, 'sample.key')) def check_file(fs): fullname = os.path.join(here, fs.filename) with open(fullname, 'r') as f: test_data = f.read().encode() data = fs.file.read() self.assertEqual(test_data, data) @asyncio.coroutine def handler(request): data = yield from request.post() self.assertEqual(['sample.crt', 'sample.key'], list(data.keys())) for fs in data.values(): check_file(fs) fs.file.close() resp = web.Response(body=b'OK') return resp @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) resp = yield from request('POST', url, data=[f1, f2], loop=self.loop) self.assertEqual(200, resp.status) resp.close() self.loop.run_until_complete(go()) f1.close() f2.close() def test_release_post_data(self): @asyncio.coroutine def handler(request): yield from request.release() chunk = yield from request.content.readany() self.assertIs(EOF_MARKER, chunk) return web.Response(body=b'OK') @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) resp = yield from request('POST', url, data='post text', loop=self.loop) self.assertEqual(200, resp.status) resp.close() self.loop.run_until_complete(go()) def test_POST_DATA_with_content_transfer_encoding(self): @asyncio.coroutine def handler(request): data = yield from request.post() self.assertEqual(b'123', data['name']) return web.Response() @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) form = FormData() form.add_field('name', b'123', content_transfer_encoding='base64') resp = yield from request( 'post', url, data=form, loop=self.loop) self.assertEqual(200, resp.status) resp.close() self.loop.run_until_complete(go()) def test_post_form_with_duplicate_keys(self): @asyncio.coroutine def handler(request): data = yield from request.post() lst = list(sorted(data.items())) self.assertEqual([('a', '1'), ('a', '2')], lst) return web.Response(body=b'OK') @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) resp = yield from request( 'POST', url, data=MultiDict([('a', 1), ('a', 2)]), loop=self.loop) self.assertEqual(200, resp.status) txt = yield from resp.text() self.assertEqual('OK', txt) self.loop.run_until_complete(go()) def test_repr_for_application(self): @asyncio.coroutine def go(): app, _, _ = yield from self.create_server('POST', '/') self.assertEqual("", repr(app)) self.loop.run_until_complete(go()) def test_100_continue(self): @asyncio.coroutine def handler(request): data = yield from request.post() self.assertEqual(b'123', data['name']) return web.Response() @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) form = FormData() form.add_field('name', b'123', content_transfer_encoding='base64') resp = yield from request( 'post', url, data=form, expect100=True, # wait until server returns 100 continue loop=self.loop) self.assertEqual(200, resp.status) resp.close() self.loop.run_until_complete(go()) def test_100_continue_custom(self): expect_received = False @asyncio.coroutine def handler(request): data = yield from request.post() self.assertEqual(b'123', data['name']) return web.Response() @asyncio.coroutine def expect_handler(request): nonlocal expect_received expect_received = True if request.version == HttpVersion11: request.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n") @asyncio.coroutine def go(): nonlocal expect_received app, _, url = yield from self.create_server('POST', '/') app.router.add_route( 'POST', '/', handler, expect_handler=expect_handler) form = FormData() form.add_field('name', b'123', content_transfer_encoding='base64') resp = yield from request( 'post', url, data=form, expect100=True, # wait until server returns 100 continue loop=self.loop) self.assertEqual(200, resp.status) self.assertTrue(expect_received) resp.close() self.loop.run_until_complete(go()) def test_100_continue_custom_response(self): auth_err = False @asyncio.coroutine def handler(request): data = yield from request.post() self.assertEqual(b'123', data['name']) return web.Response() @asyncio.coroutine def expect_handler(request): if request.version == HttpVersion11: if auth_err: return web.HTTPForbidden() request.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n") @asyncio.coroutine def go(): nonlocal auth_err app, _, url = yield from self.create_server('POST', '/') app.router.add_route( 'POST', '/', handler, expect_handler=expect_handler) form = FormData() form.add_field('name', b'123', content_transfer_encoding='base64') resp = yield from request( 'post', url, data=form, expect100=True, # wait until server returns 100 continue loop=self.loop) self.assertEqual(200, resp.status) resp.close(force=True) auth_err = True resp = yield from request( 'post', url, data=form, expect100=True, # wait until server returns 100 continue loop=self.loop) self.assertEqual(403, resp.status) resp.close(force=True) self.loop.run_until_complete(go()) def test_100_continue_for_not_found(self): @asyncio.coroutine def handler(request): return web.Response() @asyncio.coroutine def go(): app, _, url = yield from self.create_server('POST', '/') app.router.add_route('POST', '/', handler) form = FormData() form.add_field('name', b'123', content_transfer_encoding='base64') resp = yield from request( 'post', url + 'not_found', data=form, expect100=True, # wait until server returns 100 continue loop=self.loop) self.assertEqual(404, resp.status) resp.close() self.loop.run_until_complete(go()) def test_100_continue_for_not_allowed(self): @asyncio.coroutine def handler(request): return web.Response() @asyncio.coroutine def go(): app, _, url = yield from self.create_server('POST', '/') app.router.add_route('POST', '/', handler) form = FormData() form.add_field('name', b'123', content_transfer_encoding='base64') resp = yield from request( 'GET', url, data=form, expect100=True, # wait until server returns 100 continue loop=self.loop) self.assertEqual(405, resp.status) resp.close() self.loop.run_until_complete(go()) def test_http10_keep_alive_default(self): @asyncio.coroutine def handler(request): yield from request.read() return web.Response(body=b'OK') @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) resp = yield from request('GET', url, loop=self.loop, version=HttpVersion10) self.assertEqual('close', resp.headers['CONNECTION']) resp.close() self.loop.run_until_complete(go()) def test_http09_keep_alive_default(self): @asyncio.coroutine def handler(request): yield from request.read() return web.Response(body=b'OK') @asyncio.coroutine def go(): headers = {'Connection': 'keep-alive'} # should be ignored _, _, url = yield from self.create_server('GET', '/', handler) resp = yield from request('GET', url, loop=self.loop, headers=headers, version=HttpVersion(0, 9)) self.assertEqual('close', resp.headers['CONNECTION']) resp.close() self.loop.run_until_complete(go()) def test_http10_keep_alive_with_headers_close(self): @asyncio.coroutine def handler(request): yield from request.read() return web.Response(body=b'OK') @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) headers = {'Connection': 'close'} resp = yield from request('GET', url, loop=self.loop, headers=headers, version=HttpVersion10) self.assertEqual('close', resp.headers['CONNECTION']) resp.close() self.loop.run_until_complete(go()) def test_http10_keep_alive_with_headers(self): @asyncio.coroutine def handler(request): yield from request.read() return web.Response(body=b'OK') @asyncio.coroutine def go(): _, _, url = yield from self.create_server('GET', '/', handler) headers = {'Connection': 'keep-alive'} resp = yield from request('GET', url, loop=self.loop, headers=headers, version=HttpVersion10) self.assertEqual('keep-alive', resp.headers['CONNECTION']) resp.close() self.loop.run_until_complete(go()) def test_upload_file(self): here = os.path.dirname(__file__) fname = os.path.join(here, 'software_development_in_picture.jpg') with open(fname, 'rb') as f: data = f.read() @asyncio.coroutine def handler(request): form = yield from request.post() raw_data = form['file'].file.read() self.assertEqual(data, raw_data) return web.Response(body=b'OK') @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) resp = yield from request('POST', url, data={'file': data}, loop=self.loop) self.assertEqual(200, resp.status) resp.close() self.loop.run_until_complete(go()) def test_upload_file_object(self): here = os.path.dirname(__file__) fname = os.path.join(here, 'software_development_in_picture.jpg') with open(fname, 'rb') as f: data = f.read() @asyncio.coroutine def handler(request): form = yield from request.post() raw_data = form['file'].file.read() self.assertEqual(data, raw_data) return web.Response(body=b'OK') @asyncio.coroutine def go(): _, _, url = yield from self.create_server('POST', '/', handler) f = open(fname, 'rb') resp = yield from request('POST', url, data={'file': f}, loop=self.loop) self.assertEqual(200, resp.status) resp.close() f.close() self.loop.run_until_complete(go()) def test_empty_content_for_query_without_body(self): @asyncio.coroutine def handler(request): self.assertFalse(request.has_body) return web.Response(body=b'OK') @asyncio.coroutine def go(): _, srv, url = yield from self.create_server('GET', '/', handler) resp = yield from request('GET', url, loop=self.loop) self.assertEqual(200, resp.status) txt = yield from resp.text() self.assertEqual('OK', txt) self.loop.run_until_complete(go()) def test_empty_content_for_query_with_body(self): @asyncio.coroutine def handler(request): self.assertTrue(request.has_body) body = yield from request.read() return web.Response(body=body) @asyncio.coroutine def go(): _, srv, url = yield from self.create_server('POST', '/', handler) resp = yield from request('POST', url, data=b'data', loop=self.loop) self.assertEqual(200, resp.status) txt = yield from resp.text() self.assertEqual('data', txt) self.loop.run_until_complete(go()) def test_get_with_empty_arg(self): @asyncio.coroutine def handler(request): self.assertIn('arg', request.GET) self.assertEqual('', request.GET['arg']) return web.Response() @asyncio.coroutine def go(): _, srv, url = yield from self.create_server('GET', '/', handler) resp = yield from request('GET', url+'?arg', loop=self.loop) self.assertEqual(200, resp.status) yield from resp.release() self.loop.run_until_complete(go()) def test_get_with_empty_arg_with_equal(self): @asyncio.coroutine def handler(request): self.assertIn('arg', request.GET) self.assertEqual('', request.GET['arg']) return web.Response() @asyncio.coroutine def go(): _, srv, url = yield from self.create_server('GET', '/', handler) resp = yield from request('GET', url+'?arg=', loop=self.loop) self.assertEqual(200, resp.status) yield from resp.release() self.loop.run_until_complete(go()) def test_stream_response_multiple_chunks(self): @asyncio.coroutine def handler(request): resp = web.StreamResponse() resp.enable_chunked_encoding() yield from resp.prepare(request) resp.write(b'x') resp.write(b'y') resp.write(b'z') return resp @asyncio.coroutine def go(): _, srv, url = yield from self.create_server('GET', '/', handler) client = ClientSession(loop=self.loop) resp = yield from client.get(url) self.assertEqual(200, resp.status) data = yield from resp.read() self.assertEqual(b'xyz', data) yield from resp.release() client.close() self.loop.run_until_complete(go()) class StaticFileMixin(WebFunctionalSetupMixin): @asyncio.coroutine def create_server(self, method, path, ssl_ctx=None): app, srv, url = yield from super().create_server( method, path, ssl_ctx=ssl_ctx ) app.router.add_static = self.patch_sendfile(app.router.add_static) return app, srv, url def test_static_file(self): @asyncio.coroutine def go(dirname, filename): app, _, url = yield from self.create_server( 'GET', '/static/' + filename ) app.router.add_static('/static', dirname) resp = yield from request('GET', url, loop=self.loop) self.assertEqual(200, resp.status) txt = yield from resp.text() self.assertEqual('file content', txt.rstrip()) ct = resp.headers['CONTENT-TYPE'] self.assertEqual('application/octet-stream', ct) self.assertEqual(resp.headers.get('CONTENT-ENCODING'), None) resp.close() resp = yield from request('GET', url + 'fake', loop=self.loop) self.assertEqual(404, resp.status) resp.close() resp = yield from request('GET', url + '/../../', loop=self.loop) self.assertEqual(404, resp.status) resp.close() here = os.path.dirname(__file__) filename = 'data.unknown_mime_type' self.loop.run_until_complete(go(here, filename)) @unittest.skipUnless(ssl, "ssl not supported") def test_static_file_ssl(self): @asyncio.coroutine def go(dirname, filename): ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_ctx.load_cert_chain( os.path.join(dirname, 'sample.crt'), os.path.join(dirname, 'sample.key') ) app, _, url = yield from self.create_server( 'GET', '/static/' + filename, ssl_ctx=ssl_ctx ) app.router.add_static('/static', dirname) conn = TCPConnector(verify_ssl=False, loop=self.loop) session = ClientSession(connector=conn) resp = yield from session.request('GET', url) self.assertEqual(200, resp.status) txt = yield from resp.text() self.assertEqual('file content', txt.rstrip()) ct = resp.headers['CONTENT-TYPE'] self.assertEqual('application/octet-stream', ct) self.assertEqual(resp.headers.get('CONTENT-ENCODING'), None) resp.close() session.close() here = os.path.dirname(__file__) filename = 'data.unknown_mime_type' self.loop.run_until_complete(go(here, filename)) def test_static_file_with_content_type(self): @asyncio.coroutine def go(dirname, filename): app, _, url = yield from self.create_server( 'GET', '/static/' + filename ) app.router.add_static('/static', dirname, chunk_size=16) resp = yield from request('GET', url, loop=self.loop) self.assertEqual(200, resp.status) body = yield from resp.read() with open(os.path.join(dirname, filename), 'rb') as f: content = f.read() self.assertEqual(content, body) ct = resp.headers['CONTENT-TYPE'] self.assertEqual('image/jpeg', ct) self.assertEqual(resp.headers.get('CONTENT-ENCODING'), None) resp.close() here = os.path.dirname(__file__) filename = 'software_development_in_picture.jpg' self.loop.run_until_complete(go(here, filename)) def test_static_file_with_content_encoding(self): @asyncio.coroutine def go(dirname, filename): app, _, url = yield from self.create_server( 'GET', '/static/' + filename ) app.router.add_static('/static', dirname) resp = yield from request('GET', url, loop=self.loop) self.assertEqual(200, resp.status) body = yield from resp.read() self.assertEqual(b'hello aiohttp\n', body) ct = resp.headers['CONTENT-TYPE'] self.assertEqual('text/plain', ct) encoding = resp.headers['CONTENT-ENCODING'] self.assertEqual('gzip', encoding) resp.close() here = os.path.dirname(__file__) filename = 'hello.txt.gz' self.loop.run_until_complete(go(here, filename)) def test_static_file_directory_traversal_attack(self): @asyncio.coroutine def go(dirname, relpath): self.assertTrue(os.path.isfile(os.path.join(dirname, relpath))) app, _, url = yield from self.create_server('GET', '/static/') app.router.add_static('/static', dirname) url_relpath = url + relpath resp = yield from request('GET', url_relpath, loop=self.loop) self.assertEqual(404, resp.status) resp.close() url_relpath2 = url + 'dir/../' + filename resp = yield from request('GET', url_relpath2, loop=self.loop) self.assertEqual(404, resp.status) resp.close() url_abspath = \ url + os.path.abspath(os.path.join(dirname, filename)) resp = yield from request('GET', url_abspath, loop=self.loop) self.assertEqual(404, resp.status) resp.close() here = os.path.dirname(__file__) filename = '../README.rst' self.loop.run_until_complete(go(here, filename)) def test_static_file_if_modified_since(self): @asyncio.coroutine def go(dirname, filename): app, _, url = yield from self.create_server( 'GET', '/static/' + filename ) app.router.add_static('/static', dirname) resp = yield from request('GET', url, loop=self.loop) self.assertEqual(200, resp.status) lastmod = resp.headers.get('Last-Modified') self.assertIsNotNone(lastmod) resp.close() resp = yield from request('GET', url, loop=self.loop, headers={'If-Modified-Since': lastmod}) self.assertEqual(304, resp.status) resp.close() here = os.path.dirname(__file__) filename = 'data.unknown_mime_type' self.loop.run_until_complete(go(here, filename)) def test_static_file_if_modified_since_past_date(self): @asyncio.coroutine def go(dirname, filename): app, _, url = yield from self.create_server( 'GET', '/static/' + filename ) app.router.add_static('/static', dirname) lastmod = 'Mon, 1 Jan 1990 01:01:01 GMT' resp = yield from request('GET', url, loop=self.loop, headers={'If-Modified-Since': lastmod}) self.assertEqual(200, resp.status) resp.close() here = os.path.dirname(__file__) filename = 'data.unknown_mime_type' self.loop.run_until_complete(go(here, filename)) def test_static_file_if_modified_since_future_date(self): @asyncio.coroutine def go(dirname, filename): app, _, url = yield from self.create_server( 'GET', '/static/' + filename ) app.router.add_static('/static', dirname) lastmod = 'Fri, 31 Dec 9999 23:59:59 GMT' resp = yield from request('GET', url, loop=self.loop, headers={'If-Modified-Since': lastmod}) self.assertEqual(304, resp.status) resp.close() here = os.path.dirname(__file__) filename = 'data.unknown_mime_type' self.loop.run_until_complete(go(here, filename)) def test_static_file_if_modified_since_invalid_date(self): @asyncio.coroutine def go(dirname, filename): app, _, url = yield from self.create_server( 'GET', '/static/' + filename ) app.router.add_static('/static', dirname) lastmod = 'not a valid HTTP-date' resp = yield from request('GET', url, loop=self.loop, headers={'If-Modified-Since': lastmod}) self.assertEqual(200, resp.status) resp.close() here = os.path.dirname(__file__) filename = 'data.unknown_mime_type' self.loop.run_until_complete(go(here, filename)) def test_static_route_path_existence_check(self): directory = os.path.dirname(__file__) web.StaticRoute(None, "/", directory) nodirectory = os.path.join(directory, "nonexistent-uPNiOEAg5d") with self.assertRaises(ValueError): web.StaticRoute(None, "/", nodirectory) def test_static_file_huge(self): @asyncio.coroutine def go(dirname, filename): app, _, url = yield from self.create_server( 'GET', '/static/' + filename ) app.router.add_static('/static', dirname) resp = yield from request('GET', url, loop=self.loop) self.assertEqual(200, resp.status) ct = resp.headers['CONTENT-TYPE'] self.assertEqual('application/octet-stream', ct) self.assertIsNone(resp.headers.get('CONTENT-ENCODING')) self.assertEqual(int(resp.headers.get('CONTENT-LENGTH')), file_st.st_size) f = open(fname, 'rb') off = 0 cnt = 0 while off < file_st.st_size: chunk = yield from resp.content.readany() expected = f.read(len(chunk)) self.assertEqual(chunk, expected) off += len(chunk) cnt += 1 f.close() resp.close() here = os.path.dirname(__file__) filename = 'huge_data.unknown_mime_type' # fill 100MB file fname = os.path.join(here, filename) with open(fname, 'w') as f: for i in range(1024*20): f.write(chr(i % 64 + 0x20) * 1024) self.addCleanup(os.unlink, fname) file_st = os.stat(fname) self.loop.run_until_complete(go(here, filename)) def test_env_nosendfile(self): directory = os.path.dirname(__file__) with mock.patch.dict(os.environ, {'AIOHTTP_NOSENDFILE': '1'}): route = web.StaticRoute(None, "/", directory) self.assertEqual(route._sendfile, route._sendfile_fallback) class TestStaticFileSendfileFallback(StaticFileMixin, unittest.TestCase): def patch_sendfile(self, add_static): def f(*args, **kwargs): route = add_static(*args, **kwargs) route._sendfile = route._sendfile_fallback return route return f @unittest.skipUnless(hasattr(os, "sendfile"), "sendfile system call not supported") class TestStaticFileSendfile(StaticFileMixin, unittest.TestCase): def patch_sendfile(self, add_static): def f(*args, **kwargs): route = add_static(*args, **kwargs) route._sendfile = route._sendfile_system return route return f aiohttp-0.20.2/tests/sample.crt0000664000175000017500000000146612552474754017212 0ustar andrewandrew00000000000000-----BEGIN CERTIFICATE----- MIICMzCCAZwCCQDFl4ys0fU7iTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJV UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuLUZyYW5jaXNjbzEi MCAGA1UECgwZUHl0aG9uIFNvZnR3YXJlIEZvbmRhdGlvbjAeFw0xMzAzMTgyMDA3 MjhaFw0yMzAzMTYyMDA3MjhaMF4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp Zm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMSIwIAYDVQQKDBlQeXRob24g U29mdHdhcmUgRm9uZGF0aW9uMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn t3s+J7L0xP/YdAQOacpPi9phlrzKZhcXL3XMu2LCUg2fNJpx/47Vc5TZSaO11uO7 gdwVz3Z7Q2epAgwo59JLffLt5fia8+a/SlPweI/j4+wcIIIiqusnLfpqR8cIAavg Z06cLYCDvb9wMlheIvSJY12skc1nnphWS2YJ0Xm6uQIDAQABMA0GCSqGSIb3DQEB BQUAA4GBAE9PknG6pv72+5z/gsDGYy8sK5UNkbWSNr4i4e5lxVsF03+/M71H+3AB MxVX4+A+Vlk2fmU+BrdHIIUE0r1dDcO3josQ9hc9OJpp5VLSQFP8VeuJCmzYPp9I I8WbW93cnXnChTrYQVdgVoFdv7GE9YgU7NYkrGIM0nZl1/f/bHPB -----END CERTIFICATE----- aiohttp-0.20.2/tests/test_worker.py0000664000175000017500000001017712643552137020131 0ustar andrewandrew00000000000000"""Tests for aiohttp/worker.py""" import asyncio import pytest from unittest import mock base_worker = pytest.importorskip('aiohttp.worker') class MyWorker(base_worker.GunicornWebWorker): def __init__(self): self.servers = [] self.exit_code = 0 self.cfg = mock.Mock() self.cfg.graceful_timeout = 100 @pytest.fixture def worker(): return MyWorker() def test_init_process(worker): with mock.patch('aiohttp.worker.asyncio') as m_asyncio: try: worker.init_process() except TypeError: pass assert m_asyncio.get_event_loop.return_value.close.called assert m_asyncio.new_event_loop.called assert m_asyncio.set_event_loop.called def test_run(worker, loop): worker.loop = loop worker._run = mock.Mock( wraps=asyncio.coroutine(lambda: None)) with pytest.raises(SystemExit): worker.run() assert worker._run.called assert loop._closed def test_handle_quit(worker): worker.handle_quit(object(), object()) assert not worker.alive assert worker.exit_code == 0 def test_handle_abort(worker): worker.handle_abort(object(), object()) assert not worker.alive assert worker.exit_code == 1 def test_init_signal(worker): worker.loop = mock.Mock() worker.init_signal() assert worker.loop.add_signal_handler.called def test_make_handler(worker): worker.wsgi = mock.Mock() worker.loop = mock.Mock() worker.log = mock.Mock() worker.cfg = mock.Mock() f = worker.make_handler( worker.wsgi, 'localhost', 8080) assert f is worker.wsgi.make_handler.return_value def test__run_ok(worker, loop): worker.ppid = 1 worker.alive = True worker.servers = {} sock = mock.Mock() sock.cfg_addr = ('localhost', 8080) worker.sockets = [sock] worker.wsgi = mock.Mock() worker.close = mock.Mock() worker.close.return_value = asyncio.Future(loop=loop) worker.close.return_value.set_result(()) worker.log = mock.Mock() worker.notify = mock.Mock() worker.loop = loop ret = asyncio.Future(loop=loop) loop.create_server = mock.Mock( wraps=asyncio.coroutine(lambda *a, **kw: ret)) ret.set_result(sock) worker.wsgi.make_handler.return_value.num_connections = 1 worker.cfg.max_requests = 100 with mock.patch('aiohttp.worker.asyncio') as m_asyncio: m_asyncio.sleep = mock.Mock( wraps=asyncio.coroutine(lambda *a, **kw: None)) loop.run_until_complete(worker._run()) assert worker.notify.called assert worker.log.info.called def test__run_exc(worker, loop): with mock.patch('aiohttp.worker.os') as m_os: m_os.getpid.return_value = 1 m_os.getppid.return_value = 1 worker.servers = [mock.Mock()] worker.ppid = 1 worker.alive = True worker.sockets = [] worker.log = mock.Mock() worker.loop = mock.Mock() worker.notify = mock.Mock() with mock.patch('aiohttp.worker.asyncio.sleep') as m_sleep: slp = asyncio.Future(loop=loop) slp.set_exception(KeyboardInterrupt) m_sleep.return_value = slp worker.close = mock.Mock() worker.close.return_value = asyncio.Future(loop=loop) worker.close.return_value.set_result(1) loop.run_until_complete(worker._run()) assert m_sleep.called assert worker.close.called def test_close(worker, loop): srv = mock.Mock() handler = mock.Mock() worker.servers = {srv: handler} worker.log = mock.Mock() worker.loop = loop app = worker.wsgi = mock.Mock() app.finish.return_value = asyncio.Future(loop=loop) app.finish.return_value.set_result(1) handler.connections = [object()] handler.finish_connections.return_value = asyncio.Future( loop=loop) handler.finish_connections.return_value.set_result(1) loop.run_until_complete(worker.close()) app.finish.assert_called_with() handler.finish_connections.assert_called_with(timeout=95.0) srv.close.assert_called_with() assert worker.servers is None loop.run_until_complete(worker.close()) aiohttp-0.20.2/tests/sample.crt.der0000664000175000017500000000106712552474754017760 0ustar andrewandrew000000000000000‚30‚œ Å—Œ¬Ñõ;‰0  *†H†÷ 0^1 0 UUS10U California10U San-Francisco1"0 U Python Software Fondation0 130318200728Z 230316200728Z0^1 0 UUS10U California10U San-Francisco1"0 U Python Software Fondation0Ÿ0  *†H†÷ 0‰§·{>'²ôÄÿØtiÊO‹Úa–¼Êf/uÌ»bÂR Ÿ4šqÿŽÕs”ÙI£µÖã»ÜÏv{Cg© (çÒK}òíåøšóæ¿JSðxããì ‚"ªë'-újGÇ«àgNœ-€ƒ½¿p2X^"ô‰c]¬‘Ígž˜VKf Ñyº¹0  *†H†÷ OO’qº¦þöûœÿ‚ÀÆc/,+• ‘µ’6¾"áîeÅ[Ó¿3½Gûp3Wãà>VY6~e>·G …Ò½] Ã·Ž‹ö=8šiåRÒ@SüUë‰ lØ>ŸH#Å›[ÝÜyÂ…:ØAW`V]¿±„õˆìÖ$¬b Òve×÷ÿlsÁaiohttp-0.20.2/tests/test_streams.py0000664000175000017500000005442612640574137020304 0ustar andrewandrew00000000000000"""Tests for streams.py""" import asyncio import unittest from unittest import mock from aiohttp import streams from aiohttp import test_utils class TestStreamReader(unittest.TestCase): DATA = b'line1\nline2\nline3\n' def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): self.loop.close() def _make_one(self, *args, **kwargs): return streams.StreamReader(loop=self.loop, *args, **kwargs) def test_create_waiter(self): stream = self._make_one() stream._waiter = asyncio.Future(loop=self.loop) self.assertRaises(RuntimeError, stream._create_waiter, 'test') @mock.patch('aiohttp.streams.asyncio') def test_ctor_global_loop(self, m_asyncio): stream = streams.StreamReader() self.assertIs(stream._loop, m_asyncio.get_event_loop.return_value) def test_at_eof(self): stream = self._make_one() self.assertFalse(stream.at_eof()) stream.feed_data(b'some data\n') self.assertFalse(stream.at_eof()) self.loop.run_until_complete(stream.readline()) self.assertFalse(stream.at_eof()) stream.feed_data(b'some data\n') stream.feed_eof() self.loop.run_until_complete(stream.readline()) self.assertTrue(stream.at_eof()) def test_wait_eof(self): stream = self._make_one() wait_task = asyncio.Task(stream.wait_eof(), loop=self.loop) def cb(): yield from asyncio.sleep(0.1, loop=self.loop) stream.feed_eof() asyncio.Task(cb(), loop=self.loop) self.loop.run_until_complete(wait_task) self.assertTrue(stream.is_eof()) self.assertIsNone(stream._eof_waiter) def test_wait_eof_eof(self): stream = self._make_one() stream.feed_eof() wait_task = asyncio.Task(stream.wait_eof(), loop=self.loop) self.loop.run_until_complete(wait_task) self.assertTrue(stream.is_eof()) def test_feed_empty_data(self): stream = self._make_one() stream.feed_data(b'') stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'', data) def test_feed_nonempty_data(self): stream = self._make_one() stream.feed_data(self.DATA) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(self.DATA, data) def test_read_zero(self): # Read zero bytes. stream = self._make_one() stream.feed_data(self.DATA) data = self.loop.run_until_complete(stream.read(0)) self.assertEqual(b'', data) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(self.DATA, data) def test_read(self): # Read bytes. stream = self._make_one() read_task = asyncio.Task(stream.read(30), loop=self.loop) def cb(): stream.feed_data(self.DATA) self.loop.call_soon(cb) data = self.loop.run_until_complete(read_task) self.assertEqual(self.DATA, data) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'', data) def test_read_line_breaks(self): # Read bytes without line breaks. stream = self._make_one() stream.feed_data(b'line1') stream.feed_data(b'line2') data = self.loop.run_until_complete(stream.read(5)) self.assertEqual(b'line1', data) data = self.loop.run_until_complete(stream.read(5)) self.assertEqual(b'line2', data) def test_read_eof(self): # Read bytes, stop at eof. stream = self._make_one() read_task = asyncio.Task(stream.read(1024), loop=self.loop) def cb(): stream.feed_eof() self.loop.call_soon(cb) data = self.loop.run_until_complete(read_task) self.assertEqual(b'', data) data = self.loop.run_until_complete(stream.read()) self.assertIs(data, streams.EOF_MARKER) @mock.patch('aiohttp.streams.internal_logger') def test_read_eof_infinit(self, internal_logger): # Read bytes. stream = self._make_one() stream.feed_eof() self.loop.run_until_complete(stream.read()) self.loop.run_until_complete(stream.read()) self.loop.run_until_complete(stream.read()) self.loop.run_until_complete(stream.read()) self.loop.run_until_complete(stream.read()) self.loop.run_until_complete(stream.read()) self.assertTrue(internal_logger.warning.called) def test_read_until_eof(self): # Read all bytes until eof. stream = self._make_one() read_task = asyncio.Task(stream.read(-1), loop=self.loop) def cb(): stream.feed_data(b'chunk1\n') stream.feed_data(b'chunk2') stream.feed_eof() self.loop.call_soon(cb) data = self.loop.run_until_complete(read_task) self.assertEqual(b'chunk1\nchunk2', data) data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'', data) def test_read_exception(self): stream = self._make_one() stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.read(2)) self.assertEqual(b'li', data) stream.set_exception(ValueError()) self.assertRaises( ValueError, self.loop.run_until_complete, stream.read(2)) def test_readline(self): # Read one line. 'readline' will need to wait for the data # to come from 'cb' stream = self._make_one() stream.feed_data(b'chunk1 ') read_task = asyncio.Task(stream.readline(), loop=self.loop) def cb(): stream.feed_data(b'chunk2 ') stream.feed_data(b'chunk3 ') stream.feed_data(b'\n chunk4') self.loop.call_soon(cb) line = self.loop.run_until_complete(read_task) self.assertEqual(b'chunk1 chunk2 chunk3 \n', line) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(b' chunk4', data) def test_readline_limit_with_existing_data(self): # Read one line. The data is in StreamReader's buffer # before the event loop is run. stream = self._make_one(limit=3) stream.feed_data(b'li') stream.feed_data(b'ne1\nline2\n') self.assertRaises( ValueError, self.loop.run_until_complete, stream.readline()) # The buffer should contain the remaining data after exception stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'line2\n', data) def test_readline_limit(self): # Read one line. StreamReaders are fed with data after # their 'readline' methods are called. stream = self._make_one(limit=7) def cb(): stream.feed_data(b'chunk1') stream.feed_data(b'chunk2') stream.feed_data(b'chunk3\n') stream.feed_eof() self.loop.call_soon(cb) self.assertRaises( ValueError, self.loop.run_until_complete, stream.readline()) stream = self._make_one(limit=7) def cb(): stream.feed_data(b'chunk1') stream.feed_data(b'chunk2\n') stream.feed_data(b'chunk3\n') stream.feed_eof() self.loop.call_soon(cb) self.assertRaises( ValueError, self.loop.run_until_complete, stream.readline()) data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'chunk3\n', data) def test_readline_nolimit_nowait(self): # All needed data for the first 'readline' call will be # in the buffer. stream = self._make_one() stream.feed_data(self.DATA[:6]) stream.feed_data(self.DATA[6:]) line = self.loop.run_until_complete(stream.readline()) self.assertEqual(b'line1\n', line) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'line2\nline3\n', data) def test_readline_eof(self): stream = self._make_one() stream.feed_data(b'some data') stream.feed_eof() line = self.loop.run_until_complete(stream.readline()) self.assertEqual(b'some data', line) def test_readline_empty_eof(self): stream = self._make_one() stream.feed_eof() line = self.loop.run_until_complete(stream.readline()) self.assertEqual(b'', line) self.assertIs(line, streams.EOF_MARKER) def test_readline_read_byte_count(self): stream = self._make_one() stream.feed_data(self.DATA) self.loop.run_until_complete(stream.readline()) data = self.loop.run_until_complete(stream.read(7)) self.assertEqual(b'line2\nl', data) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'ine3\n', data) def test_readline_exception(self): stream = self._make_one() stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.readline()) self.assertEqual(b'line\n', data) stream.set_exception(ValueError()) self.assertRaises( ValueError, self.loop.run_until_complete, stream.readline()) def test_readexactly_zero_or_less(self): # Read exact number of bytes (zero or less). stream = self._make_one() stream.feed_data(self.DATA) data = self.loop.run_until_complete(stream.readexactly(0)) self.assertEqual(b'', data) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(self.DATA, data) stream = self._make_one() stream.feed_data(self.DATA) data = self.loop.run_until_complete(stream.readexactly(-1)) self.assertEqual(b'', data) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(self.DATA, data) def test_readexactly(self): # Read exact number of bytes. stream = self._make_one() n = 2 * len(self.DATA) read_task = asyncio.Task(stream.readexactly(n), loop=self.loop) def cb(): stream.feed_data(self.DATA) stream.feed_data(self.DATA) stream.feed_data(self.DATA) self.loop.call_soon(cb) data = self.loop.run_until_complete(read_task) self.assertEqual(self.DATA + self.DATA, data) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(self.DATA, data) def test_readexactly_eof(self): # Read exact number of bytes (eof). stream = self._make_one() n = 2 * len(self.DATA) read_task = asyncio.Task(stream.readexactly(n), loop=self.loop) def cb(): stream.feed_data(self.DATA) stream.feed_eof() self.loop.call_soon(cb) with self.assertRaises(asyncio.IncompleteReadError) as cm: self.loop.run_until_complete(read_task) self.assertEqual(cm.exception.partial, self.DATA) self.assertEqual(cm.exception.expected, n) self.assertEqual(str(cm.exception), '18 bytes read on a total of 36 expected bytes') data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'', data) def test_readexactly_exception(self): stream = self._make_one() stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.readexactly(2)) self.assertEqual(b'li', data) stream.set_exception(ValueError()) self.assertRaises( ValueError, self.loop.run_until_complete, stream.readexactly(2)) def test_exception(self): stream = self._make_one() self.assertIsNone(stream.exception()) exc = ValueError() stream.set_exception(exc) self.assertIs(stream.exception(), exc) def test_exception_waiter(self): stream = self._make_one() @asyncio.coroutine def set_err(): stream.set_exception(ValueError()) t1 = asyncio.Task(stream.readline(), loop=self.loop) t2 = asyncio.Task(set_err(), loop=self.loop) self.loop.run_until_complete(asyncio.wait([t1, t2], loop=self.loop)) self.assertRaises(ValueError, t1.result) def test_exception_cancel(self): stream = self._make_one() @asyncio.coroutine def read_a_line(): yield from stream.readline() t = asyncio.Task(read_a_line(), loop=self.loop) test_utils.run_briefly(self.loop) t.cancel() test_utils.run_briefly(self.loop) # The following line fails if set_exception() isn't careful. stream.set_exception(RuntimeError('message')) test_utils.run_briefly(self.loop) self.assertIs(stream._waiter, None) def test_readany_eof(self): stream = self._make_one() read_task = asyncio.Task(stream.readany(), loop=self.loop) self.loop.call_soon(stream.feed_data, b'chunk1\n') data = self.loop.run_until_complete(read_task) self.assertEqual(b'chunk1\n', data) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'', data) def test_readany_empty_eof(self): stream = self._make_one() stream.feed_eof() read_task = asyncio.Task(stream.readany(), loop=self.loop) data = self.loop.run_until_complete(read_task) self.assertEqual(b'', data) self.assertIs(data, streams.EOF_MARKER) def test_readany_exception(self): stream = self._make_one() stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.readany()) self.assertEqual(b'line\n', data) stream.set_exception(ValueError()) self.assertRaises( ValueError, self.loop.run_until_complete, stream.readany()) def test_read_nowait(self): stream = self._make_one() stream.feed_data(b'line1\nline2\n') self.assertEqual( stream.read_nowait(), b'line1\nline2\n') self.assertIs( stream.read_nowait(), streams.EOF_MARKER) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'', data) def test_read_nowait_n(self): stream = self._make_one() stream.feed_data(b'line1\nline2\n') self.assertEqual( stream.read_nowait(4), b'line') self.assertEqual( stream.read_nowait(), b'1\nline2\n') self.assertIs( stream.read_nowait(), streams.EOF_MARKER) stream.feed_eof() data = self.loop.run_until_complete(stream.read()) self.assertEqual(b'', data) def test_read_nowait_exception(self): stream = self._make_one() stream.feed_data(b'line\n') stream.set_exception(ValueError()) self.assertRaises(ValueError, stream.read_nowait) def test_read_nowait_waiter(self): stream = self._make_one() stream.feed_data(b'line\n') stream._waiter = stream._create_waiter('readany') self.assertRaises(RuntimeError, stream.read_nowait) def test___repr__(self): stream = self._make_one() self.assertEqual("", repr(stream)) def test___repr__nondefault_limit(self): stream = self._make_one(limit=123) self.assertEqual("", repr(stream)) def test___repr__eof(self): stream = self._make_one() stream.feed_eof() self.assertEqual("", repr(stream)) def test___repr__data(self): stream = self._make_one() stream.feed_data(b'data') self.assertEqual("", repr(stream)) def test___repr__exception(self): stream = self._make_one() exc = RuntimeError() stream.set_exception(exc) self.assertEqual("", repr(stream)) def test___repr__waiter(self): stream = self._make_one() stream._waiter = stream._create_waiter('test_waiter') self.assertRegex( repr(stream), ">") stream._waiter.set_result(None) self.loop.run_until_complete(stream._waiter) stream._waiter = None self.assertEqual("", repr(stream)) class TestEmptyStreamReader(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): self.loop.close() def test_empty_stream_reader(self): s = streams.EmptyStreamReader() self.assertIsNone(s.set_exception(ValueError())) self.assertIsNone(s.exception()) self.assertIsNone(s.feed_eof()) self.assertIsNone(s.feed_data(b'data')) self.assertTrue(s.at_eof()) self.assertIsNone( self.loop.run_until_complete(s.wait_eof())) self.assertIs( self.loop.run_until_complete(s.read()), streams.EOF_MARKER) self.assertIs( self.loop.run_until_complete(s.readline()), streams.EOF_MARKER) self.assertIs( self.loop.run_until_complete(s.readany()), streams.EOF_MARKER) self.assertRaises( asyncio.IncompleteReadError, self.loop.run_until_complete, s.readexactly(10)) self.assertIs(s.read_nowait(), streams.EOF_MARKER) class DataQueueMixin: def test_is_eof(self): self.assertFalse(self.buffer.is_eof()) self.buffer.feed_eof() self.assertTrue(self.buffer.is_eof()) def test_at_eof(self): self.assertFalse(self.buffer.at_eof()) self.buffer.feed_eof() self.assertTrue(self.buffer.at_eof()) self.buffer._buffer.append(object()) self.assertFalse(self.buffer.at_eof()) def test_feed_data(self): item = object() self.buffer.feed_data(item, 1) self.assertEqual([(item, 1)], list(self.buffer._buffer)) def test_feed_eof(self): self.buffer.feed_eof() self.assertTrue(self.buffer._eof) def test_read(self): item = object() read_task = asyncio.Task(self.buffer.read(), loop=self.loop) def cb(): self.buffer.feed_data(item, 1) self.loop.call_soon(cb) data = self.loop.run_until_complete(read_task) self.assertIs(item, data) def test_read_eof(self): read_task = asyncio.Task(self.buffer.read(), loop=self.loop) def cb(): self.buffer.feed_eof() self.loop.call_soon(cb) self.assertRaises( streams.EofStream, self.loop.run_until_complete, read_task) def test_read_cancelled(self): read_task = asyncio.Task(self.buffer.read(), loop=self.loop) test_utils.run_briefly(self.loop) waiter = self.buffer._waiter self.assertIsInstance(waiter, asyncio.Future) read_task.cancel() self.assertRaises( asyncio.CancelledError, self.loop.run_until_complete, read_task) self.assertTrue(waiter.cancelled()) self.assertIsNone(self.buffer._waiter) self.buffer.feed_data(b'test', 4) self.assertIsNone(self.buffer._waiter) def test_read_until_eof(self): item = object() self.buffer.feed_data(item, 1) self.buffer.feed_eof() data = self.loop.run_until_complete(self.buffer.read()) self.assertIs(data, item) self.assertRaises( streams.EofStream, self.loop.run_until_complete, self.buffer.read()) def test_read_exception(self): self.buffer.set_exception(ValueError()) self.assertRaises( ValueError, self.loop.run_until_complete, self.buffer.read()) def test_read_exception_with_data(self): val = object() self.buffer.feed_data(val, 1) self.buffer.set_exception(ValueError()) self.assertIs(val, self.loop.run_until_complete(self.buffer.read())) self.assertRaises( ValueError, self.loop.run_until_complete, self.buffer.read()) def test_read_exception_on_wait(self): read_task = asyncio.Task(self.buffer.read(), loop=self.loop) test_utils.run_briefly(self.loop) self.assertIsInstance(self.buffer._waiter, asyncio.Future) self.buffer.feed_eof() self.buffer.set_exception(ValueError()) self.assertRaises( ValueError, self.loop.run_until_complete, read_task) def test_exception(self): self.assertIsNone(self.buffer.exception()) exc = ValueError() self.buffer.set_exception(exc) self.assertIs(self.buffer.exception(), exc) def test_exception_waiter(self): @asyncio.coroutine def set_err(): self.buffer.set_exception(ValueError()) t1 = asyncio.Task(self.buffer.read(), loop=self.loop) t2 = asyncio.Task(set_err(), loop=self.loop) self.loop.run_until_complete(asyncio.wait([t1, t2], loop=self.loop)) self.assertRaises(ValueError, t1.result) class TestDataQueue(unittest.TestCase, DataQueueMixin): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) self.buffer = streams.DataQueue(loop=self.loop) def tearDown(self): self.loop.close() class TestChunksQueue(unittest.TestCase, DataQueueMixin): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) self.buffer = streams.ChunksQueue(loop=self.loop) def tearDown(self): self.loop.close() def test_read_eof(self): read_task = asyncio.Task(self.buffer.read(), loop=self.loop) def cb(): self.buffer.feed_eof() self.loop.call_soon(cb) self.loop.run_until_complete(read_task) self.assertTrue(self.buffer.at_eof()) def test_read_until_eof(self): item = object() self.buffer.feed_data(item, 1) self.buffer.feed_eof() data = self.loop.run_until_complete(self.buffer.read()) self.assertIs(data, item) thing = self.loop.run_until_complete(self.buffer.read()) self.assertEqual(thing, b'') self.assertTrue(self.buffer.at_eof()) def test_readany(self): self.assertIs(self.buffer.read.__func__, self.buffer.readany.__func__) aiohttp-0.20.2/tests/test_http_parser.py0000664000175000017500000005106412552474754021162 0ustar andrewandrew00000000000000"""Tests for aiohttp/protocol.py""" import asyncio import zlib import unittest import unittest.mock import aiohttp from aiohttp import errors from aiohttp import protocol from aiohttp import CIMultiDict class TestParseHeaders(unittest.TestCase): def setUp(self): asyncio.set_event_loop(None) self.parser = protocol.HttpParser(8190, 32768, 8190) def test_parse_headers(self): hdrs = ('', 'test: line', ' continue', 'test2: data', '', '') headers, close, compression = self.parser.parse_headers(hdrs) self.assertEqual(list(headers.items()), [('TEST', 'line\r\n continue'), ('TEST2', 'data')]) self.assertIsNone(close) self.assertIsNone(compression) def test_parse_headers_multi(self): hdrs = ('', 'Set-Cookie: c1=cookie1', 'Set-Cookie: c2=cookie2', '') headers, close, compression = self.parser.parse_headers(hdrs) self.assertEqual(list(headers.items()), [('SET-COOKIE', 'c1=cookie1'), ('SET-COOKIE', 'c2=cookie2')]) self.assertIsNone(close) self.assertIsNone(compression) def test_conn_close(self): headers, close, compression = self.parser.parse_headers( ['', 'connection: close', '']) self.assertTrue(close) def test_conn_keep_alive(self): headers, close, compression = self.parser.parse_headers( ['', 'connection: keep-alive', '']) self.assertFalse(close) def test_conn_other(self): headers, close, compression = self.parser.parse_headers( ['', 'connection: test', '', '']) self.assertIsNone(close) def test_compression_gzip(self): headers, close, compression = self.parser.parse_headers( ['', 'content-encoding: gzip', '', '']) self.assertEqual('gzip', compression) def test_compression_deflate(self): headers, close, compression = self.parser.parse_headers( ['', 'content-encoding: deflate', '', '']) self.assertEqual('deflate', compression) def test_compression_unknown(self): headers, close, compression = self.parser.parse_headers( ['', 'content-encoding: compress', '', '']) self.assertIsNone(compression) def test_max_field_size(self): with self.assertRaises(errors.LineTooLong) as cm: parser = protocol.HttpParser(8190, 32768, 5) parser.parse_headers( ['', 'test: line data data\r\n', 'data\r\n', '\r\n']) self.assertIn("limit request headers fields size", str(cm.exception)) def test_max_continuation_headers_size(self): with self.assertRaises(errors.LineTooLong) as cm: parser = protocol.HttpParser(8190, 32768, 5) parser.parse_headers(['', 'test: line\r\n', ' test\r\n', '\r\n']) self.assertIn("limit request headers fields size", str(cm.exception)) def test_invalid_header(self): with self.assertRaisesRegex( errors.InvalidHeader, "(400, message='Invalid HTTP Header: test line)"): self.parser.parse_headers(['', 'test line\r\n', '\r\n']) def test_invalid_name(self): with self.assertRaisesRegex( errors.InvalidHeader, "(400, message='Invalid HTTP Header: TEST..)"): self.parser.parse_headers(['', 'test[]: line\r\n', '\r\n']) class TestDeflateBuffer(unittest.TestCase): def setUp(self): self.stream = unittest.mock.Mock() asyncio.set_event_loop(None) def test_feed_data(self): buf = aiohttp.FlowControlDataQueue(self.stream) dbuf = protocol.DeflateBuffer(buf, 'deflate') dbuf.zlib = unittest.mock.Mock() dbuf.zlib.decompress.return_value = b'line' dbuf.feed_data(b'data', 4) self.assertEqual([b'line'], list(d for d, _ in buf._buffer)) def test_feed_data_err(self): buf = aiohttp.FlowControlDataQueue(self.stream) dbuf = protocol.DeflateBuffer(buf, 'deflate') exc = ValueError() dbuf.zlib = unittest.mock.Mock() dbuf.zlib.decompress.side_effect = exc self.assertRaises( errors.ContentEncodingError, dbuf.feed_data, b'data', 4) def test_feed_eof(self): buf = aiohttp.FlowControlDataQueue(self.stream) dbuf = protocol.DeflateBuffer(buf, 'deflate') dbuf.zlib = unittest.mock.Mock() dbuf.zlib.flush.return_value = b'line' dbuf.feed_eof() self.assertEqual([b'line'], list(d for d, _ in buf._buffer)) self.assertTrue(buf._eof) def test_feed_eof_err(self): buf = aiohttp.FlowControlDataQueue(self.stream) dbuf = protocol.DeflateBuffer(buf, 'deflate') dbuf.zlib = unittest.mock.Mock() dbuf.zlib.flush.return_value = b'line' dbuf.zlib.eof = False self.assertRaises(errors.ContentEncodingError, dbuf.feed_eof) class TestParsePayload(unittest.TestCase): def setUp(self): self.stream = unittest.mock.Mock() asyncio.set_event_loop(None) def test_parse_eof_payload(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(None).parse_eof_payload(out, buf) next(p) p.send(b'data') try: p.throw(aiohttp.EofStream()) except StopIteration: pass self.assertEqual([(bytearray(b'data'), 4)], list(out._buffer)) def test_parse_length_payload(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(None).parse_length_payload(out, buf, 4) next(p) p.send(b'da') p.send(b't') try: p.send(b'aline') except StopIteration: pass self.assertEqual(3, len(out._buffer)) self.assertEqual(b'data', b''.join(d for d, _ in out._buffer)) self.assertEqual(b'line', bytes(buf)) def test_parse_length_payload_eof(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(None).parse_length_payload(out, buf, 4) next(p) p.send(b'da') self.assertRaises(aiohttp.EofStream, p.throw, aiohttp.EofStream) def test_parse_chunked_payload(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(None).parse_chunked_payload(out, buf) next(p) try: p.send(b'4\r\ndata\r\n4\r\nline\r\n0\r\ntest\r\n') except StopIteration: pass self.assertEqual(b'dataline', b''.join(d for d, _ in out._buffer)) self.assertEqual(b'', bytes(buf)) def test_parse_chunked_payload_chunks(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(None).parse_chunked_payload(out, buf) next(p) p.send(b'4\r\ndata\r') p.send(b'\n4') p.send(b'\r') p.send(b'\n') p.send(b'line\r\n0\r\n') self.assertRaises(StopIteration, p.send, b'test\r\n') self.assertEqual(b'dataline', b''.join(d for d, _ in out._buffer)) def test_parse_chunked_payload_incomplete(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(None).parse_chunked_payload(out, buf) next(p) p.send(b'4\r\ndata\r\n') self.assertRaises(aiohttp.EofStream, p.throw, aiohttp.EofStream) def test_parse_chunked_payload_extension(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(None).parse_chunked_payload(out, buf) next(p) try: p.send(b'4;test\r\ndata\r\n4\r\nline\r\n0\r\ntest\r\n') except StopIteration: pass self.assertEqual(b'dataline', b''.join(d for d, _ in out._buffer)) def test_parse_chunked_payload_size_error(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(None).parse_chunked_payload(out, buf) next(p) self.assertRaises(errors.TransferEncodingError, p.send, b'blah\r\n') def test_http_payload_parser_length_broken(self): msg = protocol.RawRequestMessage( 'GET', '/', (1, 1), CIMultiDict([('CONTENT-LENGTH', 'qwe')]), None, None) out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(msg)(out, buf) self.assertRaises(errors.InvalidHeader, next, p) def test_http_payload_parser_length_wrong(self): msg = protocol.RawRequestMessage( 'GET', '/', (1, 1), CIMultiDict([('CONTENT-LENGTH', '-1')]), None, None) out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(msg)(out, buf) self.assertRaises(errors.InvalidHeader, next, p) def test_http_payload_parser_length(self): msg = protocol.RawRequestMessage( 'GET', '/', (1, 1), CIMultiDict([('CONTENT-LENGTH', '2')]), None, None) out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(msg)(out, buf) next(p) try: p.send(b'1245') except StopIteration: pass self.assertEqual(b'12', b''.join(d for d, _ in out._buffer)) self.assertEqual(b'45', bytes(buf)) def test_http_payload_parser_no_length(self): msg = protocol.RawRequestMessage( 'GET', '/', (1, 1), CIMultiDict(), None, None) out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(msg, readall=False)(out, buf) self.assertRaises(StopIteration, next, p) self.assertEqual(b'', b''.join(out._buffer)) self.assertTrue(out._eof) _comp = zlib.compressobj(wbits=-zlib.MAX_WBITS) _COMPRESSED = b''.join([_comp.compress(b'data'), _comp.flush()]) def test_http_payload_parser_deflate(self): msg = protocol.RawRequestMessage( 'GET', '/', (1, 1), CIMultiDict([('CONTENT-LENGTH', len(self._COMPRESSED))]), None, 'deflate') out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(msg)(out, buf) next(p) self.assertRaises(StopIteration, p.send, self._COMPRESSED) self.assertEqual(b'data', b''.join(d for d, _ in out._buffer)) def test_http_payload_parser_deflate_disabled(self): msg = protocol.RawRequestMessage( 'GET', '/', (1, 1), CIMultiDict([('CONTENT-LENGTH', len(self._COMPRESSED))]), None, 'deflate') out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(msg, compression=False)(out, buf) next(p) self.assertRaises(StopIteration, p.send, self._COMPRESSED) self.assertEqual(self._COMPRESSED, b''.join(d for d, _ in out._buffer)) def test_http_payload_parser_websocket(self): msg = protocol.RawRequestMessage( 'GET', '/', (1, 1), CIMultiDict([('SEC-WEBSOCKET-KEY1', '13')]), None, None) out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(msg)(out, buf) next(p) self.assertRaises(StopIteration, p.send, b'1234567890') self.assertEqual(b'12345678', b''.join(d for d, _ in out._buffer)) def test_http_payload_parser_chunked(self): msg = protocol.RawRequestMessage( 'GET', '/', (1, 1), CIMultiDict([('TRANSFER-ENCODING', 'chunked')]), None, None) out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(msg)(out, buf) next(p) self.assertRaises(StopIteration, p.send, b'4;test\r\ndata\r\n4\r\nline\r\n0\r\ntest\r\n') self.assertEqual(b'dataline', b''.join(d for d, _ in out._buffer)) def test_http_payload_parser_eof(self): msg = protocol.RawRequestMessage( 'GET', '/', (1, 1), CIMultiDict(), None, None) out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(msg, readall=True)(out, buf) next(p) p.send(b'data') p.send(b'line') self.assertRaises(StopIteration, p.throw, aiohttp.EofStream()) self.assertEqual(b'dataline', b''.join(d for d, _ in out._buffer)) def test_http_payload_parser_length_zero(self): msg = protocol.RawRequestMessage( 'GET', '/', (1, 1), CIMultiDict([('CONTENT-LENGTH', '0')]), None, None) out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpPayloadParser(msg)(out, buf) self.assertRaises(StopIteration, next, p) self.assertEqual(b'', b''.join(out._buffer)) class TestParseRequest(unittest.TestCase): def setUp(self): self.stream = unittest.mock.Mock() asyncio.set_event_loop(None) def test_http_request_parser_max_headers(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpRequestParser(8190, 20, 8190)(out, buf) next(p) self.assertRaises( errors.LineTooLong, p.send, b'get /path HTTP/1.1\r\ntest: line\r\ntest2: data\r\n\r\n') def test_http_request_parser(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpRequestParser()(out, buf) next(p) try: p.send(b'get /path HTTP/1.1\r\n\r\n') except StopIteration: pass result = out._buffer[0][0] self.assertEqual( ('GET', '/path', (1, 1), CIMultiDict(), False, None), result) def test_http_request_parser_utf8(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpRequestParser()(out, buf) next(p) msg = 'get /path HTTP/1.1\r\nx-test:теÑÑ‚\r\n\r\n'.encode('utf-8') try: p.send(msg) except StopIteration: pass result, length = out._buffer[0] self.assertEqual(len(msg), length) self.assertEqual( ('GET', '/path', (1, 1), CIMultiDict([('X-TEST', 'теÑÑ‚')]), False, None), result) def test_http_request_parser_eof(self): # HttpRequestParser does fail on EofStream() out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpRequestParser()(out, buf) next(p) p.send(b'get /path HTTP/1.1\r\n') try: p.throw(aiohttp.EofStream()) except aiohttp.EofStream: pass self.assertFalse(out._buffer) def test_http_request_parser_two_slashes(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpRequestParser()(out, buf) next(p) try: p.send(b'get //path HTTP/1.1\r\n\r\n') except StopIteration: pass self.assertEqual( ('GET', '//path', (1, 1), CIMultiDict(), False, None), out._buffer[0][0]) def test_http_request_parser_bad_status_line(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpRequestParser()(out, buf) next(p) self.assertRaises( errors.BadStatusLine, p.send, b'\r\n\r\n') def test_http_request_parser_bad_method(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpRequestParser()(out, buf) next(p) self.assertRaises( errors.BadStatusLine, p.send, b'!12%()+=~$ /get HTTP/1.1\r\n\r\n') def test_http_request_parser_bad_version(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpRequestParser()(out, buf) next(p) self.assertRaises( errors.BadStatusLine, p.send, b'GET //get HT/11\r\n\r\n') class TestParseResponse(unittest.TestCase): def setUp(self): self.stream = unittest.mock.Mock() asyncio.set_event_loop(None) def test_http_response_parser_utf8(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpResponseParser()(out, buf) next(p) msg = 'HTTP/1.1 200 Ok\r\nx-test:теÑÑ‚\r\n\r\n'.encode('utf-8') try: p.send(msg) except StopIteration: pass v, s, r, h = out._buffer[0][0][:4] self.assertEqual(v, (1, 1)) self.assertEqual(s, 200) self.assertEqual(r, 'Ok') self.assertEqual(h, CIMultiDict([('X-TEST', 'теÑÑ‚')])) def test_http_response_parser_bad_status_line(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpResponseParser()(out, buf) next(p) self.assertRaises(errors.BadStatusLine, p.send, b'\r\n\r\n') def test_http_response_parser_bad_status_line_too_long(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpResponseParser( max_headers=2, max_line_size=2)(out, buf) next(p) self.assertRaises( errors.LineTooLong, p.send, b'HTTP/1.1 200 Ok\r\n\r\n') def test_http_response_parser_bad_status_line_eof(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpResponseParser()(out, buf) next(p) self.assertRaises(aiohttp.EofStream, p.throw, aiohttp.EofStream()) def test_http_response_parser_bad_version(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpResponseParser()(out, buf) next(p) with self.assertRaises(errors.BadStatusLine) as cm: p.send(b'HT/11 200 Ok\r\n\r\n') self.assertEqual('HT/11 200 Ok', cm.exception.args[0]) def test_http_response_parser_no_reason(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpResponseParser()(out, buf) next(p) try: p.send(b'HTTP/1.1 200\r\n\r\n') except StopIteration: pass v, s, r = out._buffer[0][0][:3] self.assertEqual(v, (1, 1)) self.assertEqual(s, 200) self.assertEqual(r, '') def test_http_response_parser_bad(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpResponseParser()(out, buf) next(p) with self.assertRaises(errors.BadStatusLine) as cm: p.send(b'HTT/1\r\n\r\n') self.assertIn('HTT/1', str(cm.exception)) def test_http_response_parser_code_under_100(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpResponseParser()(out, buf) next(p) with self.assertRaises(errors.BadStatusLine) as cm: p.send(b'HTTP/1.1 99 test\r\n\r\n') self.assertIn('HTTP/1.1 99 test', str(cm.exception)) def test_http_response_parser_code_above_999(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpResponseParser()(out, buf) next(p) with self.assertRaises(errors.BadStatusLine) as cm: p.send(b'HTTP/1.1 9999 test\r\n\r\n') self.assertIn('HTTP/1.1 9999 test', str(cm.exception)) def test_http_response_parser_code_not_int(self): out = aiohttp.FlowControlDataQueue(self.stream) buf = aiohttp.ParserBuffer() p = protocol.HttpResponseParser()(out, buf) next(p) with self.assertRaises(errors.BadStatusLine) as cm: p.send(b'HTTP/1.1 ttt test\r\n\r\n') self.assertIn('HTTP/1.1 ttt test', str(cm.exception)) aiohttp-0.20.2/tests/test_urldispatch.py0000664000175000017500000006355612621663613021151 0ustar andrewandrew00000000000000import asyncio import os import unittest from collections.abc import Sized, Container, Iterable, Mapping, MutableMapping from unittest import mock from urllib.parse import unquote import aiohttp.web from aiohttp import hdrs from aiohttp.web import (UrlDispatcher, Request, Response, HTTPMethodNotAllowed, HTTPNotFound) from aiohttp.multidict import CIMultiDict from aiohttp.protocol import HttpVersion, RawRequestMessage from aiohttp.web_urldispatcher import (_defaultExpectHandler, DynamicRoute, PlainRoute, SystemRoute) class TestUrlDispatcher(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) self.router = UrlDispatcher() def tearDown(self): self.loop.close() def make_request(self, method, path): self.app = mock.Mock() message = RawRequestMessage(method, path, HttpVersion(1, 1), CIMultiDict(), False, False) self.payload = mock.Mock() self.transport = mock.Mock() self.reader = mock.Mock() self.writer = mock.Mock() req = Request(self.app, message, self.payload, self.transport, self.reader, self.writer) return req def make_handler(self): @asyncio.coroutine def handler(request): return Response(request) # pragma: no cover return handler def test_system_route(self): route = SystemRoute(201, 'test') self.assertIsNone(route.match('any')) with self.assertRaises(RuntimeError): route.url() self.assertEqual("", repr(route)) self.assertEqual(201, route.status) self.assertEqual('test', route.reason) def test_register_route(self): handler = self.make_handler() route = PlainRoute('GET', handler, 'test', '/handler/to/path') self.router.register_route(route) req = self.make_request('GET', '/handler/to/path') info = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsNotNone(info) self.assertEqual(0, len(info)) self.assertIs(route, info.route) self.assertIs(handler, info.handler) self.assertEqual(info.route.name, 'test') def test_register_route_checks(self): self.assertRaises( AssertionError, self.router.register_route, object()) handler = self.make_handler() route = PlainRoute('GET', handler, 'test', '/handler/to/path') self.router.register_route(route) self.assertRaises(ValueError, self.router.register_route, route) route = PlainRoute('GET', handler, '1bad name', '/handler/to/path') self.assertRaises(ValueError, self.router.register_route, route) route = PlainRoute('GET', handler, 'return', '/handler/to/path') self.assertRaises(ValueError, self.router.register_route, route) route = PlainRoute('GET', handler, 'test.test:test-test', '/handler/to/path') self.router.register_route(route) def test_add_route_root(self): handler = self.make_handler() self.router.add_route('GET', '/', handler) req = self.make_request('GET', '/') info = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsNotNone(info) self.assertEqual(0, len(info)) self.assertIs(handler, info.handler) self.assertIsNone(info.route.name) def test_add_route_simple(self): handler = self.make_handler() self.router.add_route('GET', '/handler/to/path', handler) req = self.make_request('GET', '/handler/to/path') info = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsNotNone(info) self.assertEqual(0, len(info)) self.assertIs(handler, info.handler) self.assertIsNone(info.route.name) def test_add_with_matchdict(self): handler = self.make_handler() self.router.add_route('GET', '/handler/{to}', handler) req = self.make_request('GET', '/handler/tail') info = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsNotNone(info) self.assertEqual({'to': 'tail'}, info) self.assertIs(handler, info.handler) self.assertIsNone(info.route.name) def test_add_with_name(self): handler = self.make_handler() self.router.add_route('GET', '/handler/to/path', handler, name='name') req = self.make_request('GET', '/handler/to/path') info = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsNotNone(info) self.assertEqual('name', info.route.name) def test_add_with_tailing_slash(self): handler = self.make_handler() self.router.add_route('GET', '/handler/to/path/', handler) req = self.make_request('GET', '/handler/to/path/') info = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsNotNone(info) self.assertEqual({}, info) self.assertIs(handler, info.handler) def test_add_invalid_path(self): handler = self.make_handler() with self.assertRaises(ValueError): self.router.add_route('GET', '/{/', handler) def test_add_url_invalid1(self): handler = self.make_handler() with self.assertRaises(ValueError): self.router.add_route('post', '/post/{id', handler) def test_add_url_invalid2(self): handler = self.make_handler() with self.assertRaises(ValueError): self.router.add_route('post', '/post/{id{}}', handler) def test_add_url_invalid3(self): handler = self.make_handler() with self.assertRaises(ValueError): self.router.add_route('post', '/post/{id{}', handler) def test_add_url_invalid4(self): handler = self.make_handler() with self.assertRaises(ValueError): self.router.add_route('post', '/post/{id"}', handler) def test_add_url_escaping(self): handler = self.make_handler() self.router.add_route('GET', '/+$', handler) req = self.make_request('GET', '/+$') info = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsNotNone(info) self.assertIs(handler, info.handler) def test_any_method(self): handler = self.make_handler() route = self.router.add_route(hdrs.METH_ANY, '/', handler) req = self.make_request('GET', '/') info1 = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsNotNone(info1) self.assertIs(route, info1.route) req = self.make_request('POST', '/') info2 = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsNotNone(info2) self.assertIs(info1.route, info2.route) def test_match_second_result_in_table(self): handler1 = self.make_handler() handler2 = self.make_handler() self.router.add_route('GET', '/h1', handler1) self.router.add_route('POST', '/h2', handler2) req = self.make_request('POST', '/h2') info = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsNotNone(info) self.assertEqual({}, info) self.assertIs(handler2, info.handler) def test_raise_method_not_allowed(self): handler1 = self.make_handler() handler2 = self.make_handler() self.router.add_route('GET', '/', handler1) self.router.add_route('POST', '/', handler2) req = self.make_request('PUT', '/') match_info = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsInstance(match_info.route, SystemRoute) self.assertEqual({}, match_info) with self.assertRaises(HTTPMethodNotAllowed) as ctx: self.loop.run_until_complete(match_info.handler(req)) exc = ctx.exception self.assertEqual('PUT', exc.method) self.assertEqual(405, exc.status) self.assertEqual({'POST', 'GET'}, exc.allowed_methods) def test_raise_method_not_found(self): handler = self.make_handler() self.router.add_route('GET', '/a', handler) req = self.make_request('GET', '/b') match_info = self.loop.run_until_complete(self.router.resolve(req)) self.assertIsInstance(match_info.route, SystemRoute) self.assertEqual({}, match_info) with self.assertRaises(HTTPNotFound) as ctx: self.loop.run_until_complete(match_info.handler(req)) exc = ctx.exception self.assertEqual(404, exc.status) def test_double_add_url_with_the_same_name(self): handler1 = self.make_handler() handler2 = self.make_handler() self.router.add_route('GET', '/get', handler1, name='name') regexp = ("Duplicate 'name', already handled by") with self.assertRaisesRegex(ValueError, regexp): self.router.add_route('GET', '/get_other', handler2, name='name') def test_route_plain(self): handler = self.make_handler() route = self.router.add_route('GET', '/get', handler, name='name') route2 = self.router['name'] url = route2.url() self.assertEqual('/get', url) self.assertIs(route, route2) def test_route_unknown_route_name(self): with self.assertRaises(KeyError): self.router['unknown'] def test_route_dynamic(self): handler = self.make_handler() route = self.router.add_route('GET', '/get/{name}', handler, name='name') route2 = self.router['name'] url = route2.url(parts={'name': 'John'}) self.assertEqual('/get/John', url) self.assertIs(route, route2) def test_route_with_qs(self): handler = self.make_handler() self.router.add_route('GET', '/get', handler, name='name') url = self.router['name'].url(query=[('a', 'b'), ('c', 1)]) self.assertEqual('/get?a=b&c=1', url) def test_add_static(self): route = self.router.add_static('/st', os.path.dirname(aiohttp.__file__), name='static') route2 = self.router['static'] url = route2.url(filename='/dir/a.txt') self.assertEqual('/st/dir/a.txt', url) self.assertIs(route, route2) def test_plain_not_match(self): handler = self.make_handler() self.router.add_route('GET', '/get/path', handler, name='name') route = self.router['name'] self.assertIsNone(route.match('/another/path')) def test_dynamic_not_match(self): handler = self.make_handler() self.router.add_route('GET', '/get/{name}', handler, name='name') route = self.router['name'] self.assertIsNone(route.match('/another/path')) def test_static_not_match(self): self.router.add_static('/pre', os.path.dirname(aiohttp.__file__), name='name') route = self.router['name'] self.assertIsNone(route.match('/another/path')) def test_dynamic_with_trailing_slash(self): handler = self.make_handler() self.router.add_route('GET', '/get/{name}/', handler, name='name') route = self.router['name'] self.assertEqual({'name': 'John'}, route.match('/get/John/')) def test_len(self): handler = self.make_handler() self.router.add_route('GET', '/get1', handler, name='name1') self.router.add_route('GET', '/get2', handler, name='name2') self.assertEqual(2, len(self.router)) def test_iter(self): handler = self.make_handler() self.router.add_route('GET', '/get1', handler, name='name1') self.router.add_route('GET', '/get2', handler, name='name2') self.assertEqual({'name1', 'name2'}, set(iter(self.router))) def test_contains(self): handler = self.make_handler() self.router.add_route('GET', '/get1', handler, name='name1') self.router.add_route('GET', '/get2', handler, name='name2') self.assertIn('name1', self.router) self.assertNotIn('name3', self.router) def test_plain_repr(self): handler = self.make_handler() self.router.add_route('GET', '/get/path', handler, name='name') self.assertRegex(repr(self.router['name']), r"+++)': nothing to repeat"), s) self.assertIsNone(ctx.exception.__cause__) def test_route_dynamic_with_regex_spec(self): handler = self.make_handler() route = self.router.add_route('GET', '/get/{num:^\d+}', handler, name='name') url = route.url(parts={'num': '123'}) self.assertEqual('/get/123', url) def test_route_dynamic_with_regex_spec_and_trailing_slash(self): handler = self.make_handler() route = self.router.add_route('GET', '/get/{num:^\d+}/', handler, name='name') url = route.url(parts={'num': '123'}) self.assertEqual('/get/123/', url) def test_route_dynamic_with_regex(self): handler = self.make_handler() route = self.router.add_route('GET', r'/{one}/{two:.+}', handler) url = route.url(parts={'one': 1, 'two': 2}) self.assertEqual('/1/2', url) def test_regular_match_info(self): @asyncio.coroutine def go(): handler = self.make_handler() self.router.add_route('GET', '/get/{name}', handler) req = self.make_request('GET', '/get/john') match_info = yield from self.router.resolve(req) self.maxDiff = None self.assertRegex(repr(match_info), ">") self.loop.run_until_complete(go()) def test_not_found_repr(self): @asyncio.coroutine def go(): req = self.make_request('POST', '/path/to') match_info = yield from self.router.resolve(req) self.assertEqual("", repr(match_info)) self.loop.run_until_complete(go()) def test_not_allowed_repr(self): @asyncio.coroutine def go(): handler = self.make_handler() self.router.add_route('GET', '/path/to', handler) handler2 = self.make_handler() self.router.add_route('POST', '/path/to', handler2) req = self.make_request('PUT', '/path/to') match_info = yield from self.router.resolve(req) self.assertEqual("", repr(match_info)) self.loop.run_until_complete(go()) def test_default_expect_handler(self): route = self.router.add_route('GET', '/', self.make_handler()) self.assertIs(route._expect_handler, _defaultExpectHandler) def test_custom_expect_handler_plain(self): @asyncio.coroutine def handler(request): pass route = self.router.add_route( 'GET', '/', self.make_handler(), expect_handler=handler) self.assertIs(route._expect_handler, handler) self.assertIsInstance(route, PlainRoute) def test_custom_expect_handler_dynamic(self): @asyncio.coroutine def handler(request): pass route = self.router.add_route( 'GET', '/get/{name}', self.make_handler(), expect_handler=handler) self.assertIs(route._expect_handler, handler) self.assertIsInstance(route, DynamicRoute) def test_expect_handler_non_coroutine(self): def handler(request): pass self.assertRaises( AssertionError, self.router.add_route, 'GET', '/', self.make_handler(), expect_handler=handler) def test_dynamic_match_non_ascii(self): @asyncio.coroutine def go(): handler = self.make_handler() self.router.add_route('GET', '/{var}', handler) req = self.make_request( 'GET', '/%D1%80%D1%83%D1%81%20%D1%82%D0%B5%D0%BA%D1%81%D1%82') match_info = yield from self.router.resolve(req) self.assertEqual({'var': 'Ñ€ÑƒÑ Ñ‚ÐµÐºÑÑ‚'}, match_info) self.loop.run_until_complete(go()) def test_dynamic_match_with_static_part(self): @asyncio.coroutine def go(): handler = self.make_handler() self.router.add_route('GET', '/{name}.html', handler) req = self.make_request('GET', '/file.html') match_info = yield from self.router.resolve(req) self.assertEqual({'name': 'file'}, match_info) self.loop.run_until_complete(go()) def test_dynamic_match_two_part2(self): @asyncio.coroutine def go(): handler = self.make_handler() self.router.add_route('GET', '/{name}.{ext}', handler) req = self.make_request('GET', '/file.html') match_info = yield from self.router.resolve(req) self.assertEqual({'name': 'file', 'ext': 'html'}, match_info) self.loop.run_until_complete(go()) def test_dynamic_match_unquoted_path(self): @asyncio.coroutine def go(): handler = self.make_handler() self.router.add_route('GET', '/{path}/{subpath}', handler) resource_id = 'my%2Fpath%7Cwith%21some%25strange%24characters' req = self.make_request('GET', '/path/{0}'.format(resource_id)) match_info = yield from self.router.resolve(req) self.assertEqual(match_info, { 'path': 'path', 'subpath': unquote(resource_id) }) self.loop.run_until_complete(go()) def test_add_route_not_started_with_slash(self): with self.assertRaises(ValueError): handler = self.make_handler() self.router.add_route('GET', 'invalid_path', handler) def test_add_route_invalid_method(self): with self.assertRaises(ValueError): handler = self.make_handler() self.router.add_route('INVALID_METHOD', '/path', handler) def test_static_handle_eof(self): loop = mock.Mock() route = self.router.add_static('/st', os.path.dirname(aiohttp.__file__)) with mock.patch('aiohttp.web_urldispatcher.os') as m_os: out_fd = 30 in_fd = 31 fut = asyncio.Future(loop=self.loop) m_os.sendfile.return_value = 0 route._sendfile_cb(fut, out_fd, in_fd, 0, 100, loop, False) m_os.sendfile.assert_called_with(out_fd, in_fd, 0, 100) self.assertTrue(fut.done()) self.assertIsNone(fut.result()) self.assertFalse(loop.add_writer.called) self.assertFalse(loop.remove_writer.called) def test_static_handle_again(self): loop = mock.Mock() route = self.router.add_static('/st', os.path.dirname(aiohttp.__file__)) with mock.patch('aiohttp.web_urldispatcher.os') as m_os: out_fd = 30 in_fd = 31 fut = asyncio.Future(loop=self.loop) m_os.sendfile.side_effect = BlockingIOError() route._sendfile_cb(fut, out_fd, in_fd, 0, 100, loop, False) m_os.sendfile.assert_called_with(out_fd, in_fd, 0, 100) self.assertFalse(fut.done()) loop.add_writer.assert_called_with(out_fd, route._sendfile_cb, fut, out_fd, in_fd, 0, 100, loop, True) self.assertFalse(loop.remove_writer.called) def test_static_handle_exception(self): loop = mock.Mock() route = self.router.add_static('/st', os.path.dirname(aiohttp.__file__)) with mock.patch('aiohttp.web_urldispatcher.os') as m_os: out_fd = 30 in_fd = 31 fut = asyncio.Future(loop=self.loop) exc = OSError() m_os.sendfile.side_effect = exc route._sendfile_cb(fut, out_fd, in_fd, 0, 100, loop, False) m_os.sendfile.assert_called_with(out_fd, in_fd, 0, 100) self.assertTrue(fut.done()) self.assertIs(exc, fut.exception()) self.assertFalse(loop.add_writer.called) self.assertFalse(loop.remove_writer.called) def fill_routes(self): route1 = self.router.add_route('GET', '/plain', self.make_handler()) route2 = self.router.add_route('GET', '/variable/{name}', self.make_handler()) route3 = self.router.add_static('/static', os.path.dirname(aiohttp.__file__)) return route1, route2, route3 def test_routes_view_len(self): self.fill_routes() self.assertEqual(3, len(self.router.routes())) def test_routes_view_iter(self): routes = self.fill_routes() self.assertEqual(list(routes), list(self.router.routes())) def test_routes_view_contains(self): routes = self.fill_routes() for route in routes: self.assertIn(route, self.router.routes()) def test_routes_abc(self): self.assertIsInstance(self.router.routes(), Sized) self.assertIsInstance(self.router.routes(), Iterable) self.assertIsInstance(self.router.routes(), Container) def fill_named_routes(self): route1 = self.router.add_route('GET', '/plain', self.make_handler(), name='route1') route2 = self.router.add_route('GET', '/variable/{name}', self.make_handler(), name='route2') route3 = self.router.add_static('/static', os.path.dirname(aiohttp.__file__), name='route3') return route1, route2, route3 def test_named_routes_abc(self): self.assertIsInstance(self.router.named_routes(), Mapping) self.assertNotIsInstance(self.router.named_routes(), MutableMapping) def test_named_routes(self): named_routes = self.fill_named_routes() self.assertEqual(3, len(self.router.named_routes())) for route in named_routes: self.assertIn(route.name, self.router.named_routes()) self.assertEqual(route, self.router.named_routes()[route.name]) aiohttp-0.20.2/tests/test_client_functional.py0000664000175000017500000002674512634502617022326 0ustar andrewandrew00000000000000"""Http client functional tests against aiohttp.web server""" import aiohttp import asyncio import io import os import os.path import pytest import ssl from aiohttp import hdrs, web from aiohttp.errors import FingerprintMismatch @pytest.fixture def ssl_ctx(): here = os.path.dirname(__file__) ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_ctx.load_cert_chain( os.path.join(here, 'sample.crt'), os.path.join(here, 'sample.key')) return ssl_ctx @pytest.mark.run_loop def test_keepalive_two_requests_success(create_app_and_client): @asyncio.coroutine def handler(request): body = yield from request.read() assert b'' == body return web.Response(body=b'OK') app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp1 = yield from client.get('/') yield from resp1.read() resp2 = yield from client.get('/') yield from resp2.read() assert 1 == len(client._session.connector._conns) @pytest.mark.run_loop def test_keepalive_response_released(create_app_and_client): @asyncio.coroutine def handler(request): body = yield from request.read() assert b'' == body return web.Response(body=b'OK') app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp1 = yield from client.get('/') yield from resp1.release() resp2 = yield from client.get('/') yield from resp2.release() assert 1 == len(client._session.connector._conns) @pytest.mark.run_loop def test_keepalive_server_force_close_connection(create_app_and_client): @asyncio.coroutine def handler(request): body = yield from request.read() assert b'' == body response = web.Response(body=b'OK') response.force_close() return response app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp1 = yield from client.get('/') resp1.close() resp2 = yield from client.get('/') resp2.close() assert 0 == len(client._session.connector._conns) @pytest.mark.run_loop def test_HTTP_304(create_app_and_client): @asyncio.coroutine def handler(request): body = yield from request.read() assert b'' == body return web.Response(status=304) app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.get('/') assert resp.status == 304 content = yield from resp.read() assert content == b'' @pytest.mark.run_loop def test_HTTP_304_WITH_BODY(create_app_and_client): @asyncio.coroutine def handler(request): body = yield from request.read() assert b'' == body return web.Response(body=b'test', status=304) app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.get('/') assert resp.status == 304 content = yield from resp.read() assert content == b'' @pytest.mark.run_loop def test_auto_header_user_agent(create_app_and_client): @asyncio.coroutine def handler(request): assert 'aiohttp' in request.headers['user-agent'] return web.Response() app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.get('/') try: assert 200, resp.status finally: yield from resp.release() @pytest.mark.run_loop def test_skip_auto_headers_user_agent(create_app_and_client): @asyncio.coroutine def handler(request): assert hdrs.USER_AGENT not in request.headers return web.Response() app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.get('/', skip_auto_headers=['user-agent']) try: assert 200 == resp.status finally: yield from resp.release() @pytest.mark.run_loop def test_skip_default_auto_headers_user_agent(create_app_and_client): @asyncio.coroutine def handler(request): assert hdrs.USER_AGENT not in request.headers return web.Response() app, client = yield from create_app_and_client(client_params=dict( skip_auto_headers=['user-agent'])) app.router.add_route('GET', '/', handler) resp = yield from client.get('/') try: assert 200 == resp.status finally: yield from resp.release() @pytest.mark.run_loop def test_skip_auto_headers_content_type(create_app_and_client): @asyncio.coroutine def handler(request): assert hdrs.CONTENT_TYPE not in request.headers return web.Response() app, client = yield from create_app_and_client() app.router.add_route('GET', '/', handler) resp = yield from client.get('/', skip_auto_headers=['content-type']) try: assert 200 == resp.status finally: yield from resp.release() @pytest.mark.run_loop def test_post_data_bytesio(create_app_and_client): data = b'some buffer' @asyncio.coroutine def handler(request): assert len(data) == request.content_length val = yield from request.read() assert data == val return web.Response() app, client = yield from create_app_and_client() app.router.add_route('POST', '/', handler) resp = yield from client.post('/', data=io.BytesIO(data)) try: assert 200 == resp.status finally: yield from resp.release() @pytest.mark.run_loop def test_post_data_with_bytesio_file(create_app_and_client): data = b'some buffer' @asyncio.coroutine def handler(request): post_data = yield from request.post() assert ['file'] == list(post_data.keys()) assert data == post_data['file'].file.read() return web.Response() app, client = yield from create_app_and_client() app.router.add_route('POST', '/', handler) resp = yield from client.post('/', data={'file': io.BytesIO(data)}) try: assert 200 == resp.status finally: yield from resp.release() @pytest.mark.run_loop def test_client_ssl(create_app_and_client, loop, ssl_ctx): connector = aiohttp.TCPConnector(verify_ssl=False, loop=loop) @asyncio.coroutine def handler(request): return web.HTTPOk(text='Test message') app, client = yield from create_app_and_client( server_params=dict(ssl_ctx=ssl_ctx), client_params=dict(connector=connector)) app.router.add_route('GET', '/', handler) resp = yield from client.get('/') try: assert 200 == resp.status txt = yield from resp.text() assert txt == 'Test message' finally: yield from resp.release() @pytest.mark.parametrize('fingerprint', [ b'\xa2\x06G\xad\xaa\xf5\xd8\\J\x99^by;\x06=', b's\x93\xfd:\xed\x08\x1do\xa9\xaeq9\x1a\xe3\xc5\x7f\x89\xe7l\xf9', b'0\x9a\xc9D\x83\xdc\x91\'\x88\x91\x11\xa1d\x97\xfd\xcb~7U\x14D@L' b'\x11\xab\x99\xa8\xae\xb7\x14\xee\x8b'], ids=['md5', 'sha1', 'sha256']) @pytest.mark.run_loop def test_tcp_connector_fingerprint_ok(create_app_and_client, loop, ssl_ctx, fingerprint): @asyncio.coroutine def handler(request): return web.HTTPOk(text='Test message') connector = aiohttp.TCPConnector(loop=loop, verify_ssl=False, fingerprint=fingerprint) app, client = yield from create_app_and_client( server_params=dict(ssl_ctx=ssl_ctx), client_params=dict(connector=connector)) app.router.add_route('GET', '/', handler) resp = yield from client.get('/') assert resp.status == 200 resp.close() @pytest.mark.parametrize('fingerprint', [ b'\xa2\x06G\xad\xaa\xf5\xd8\\J\x99^by;\x06=', b's\x93\xfd:\xed\x08\x1do\xa9\xaeq9\x1a\xe3\xc5\x7f\x89\xe7l\xf9', b'0\x9a\xc9D\x83\xdc\x91\'\x88\x91\x11\xa1d\x97\xfd\xcb~7U\x14D@L' b'\x11\xab\x99\xa8\xae\xb7\x14\xee\x8b'], ids=['md5', 'sha1', 'sha256']) @pytest.mark.run_loop def test_tcp_connector_fingerprint_fail(create_app_and_client, loop, ssl_ctx, fingerprint): @asyncio.coroutine def handler(request): return web.HTTPOk(text='Test message') bad_fingerprint = b'\x00' * len(fingerprint) connector = aiohttp.TCPConnector(loop=loop, verify_ssl=False, fingerprint=bad_fingerprint) app, client = yield from create_app_and_client( server_params=dict(ssl_ctx=ssl_ctx), client_params=dict(connector=connector)) app.router.add_route('GET', '/', handler) with pytest.raises(FingerprintMismatch) as cm: yield from client.get('/') exc = cm.value assert exc.expected == bad_fingerprint assert exc.got == fingerprint @pytest.mark.run_loop def test_format_task_get(create_server, loop): @asyncio.coroutine def handler(request): return web.Response(body=b'OK') app, url = yield from create_server() app.router.add_route('GET', '/', handler) client = aiohttp.ClientSession(loop=loop) task = loop.create_task(client.get(url)) assert "{}".format(task)[:18] == "û•ÿÿÿ"KlO^Yæ•ÿÿÿO^ ôÿÿôÿÿôÿÿôÿÿôÿÿôÿÿ/èþÿÿ0«éþÿÿ/Àò¼òùéþÿÿ/(£,Ž£Yl[•ÿÿÿÿºøÿPi ª«¬©ªª¨©ªÿÿ Ò÷pk` æ)))))))))ìþìþìþÖÿÖÿÖÿ***1 Š €à€±Uʰ ™“p x (€ ”´´ÿØÿÛC      ÿÛC  ÿÀ x"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ý®Ót¬B¬S EY6˜vã:Þ2Ĩ)Kî?6)¦ÌÆÃ§íýj±óüª¡×!]f-<ÈÔдè˜ûȤ#èY1Zö–ø2uª¸îÇZAƒÆ?*Ö²b@BÎ~\WmÎç’j[¹H¾ð—A‘ÍW|ÄØ5e&Ú<“Q]Ä^AŠCo(#æ뉄KÛ&¢KvP3ÐTWçËBÒv î®ZE¬ùkEGq¨’ØQQ5Ñn¿Î€-Á{†ˆ§]Üy©–Çœ.@=)’ÝqÆhäŒdzt¢³o5A'=zQT˜X³5¢‚Ü~T†ÕW¨Ô‘]ar½H \~÷j“3ÂiŸ‹ž:ø%ñŸÁú¯ƒ~Ýx÷ÃZ\éò¶•©Å§ ̸••m¦ÂÊ¢+=ÃkK0Çš—ŸðUσÒ/åøÁ­jßu-2Õï'Ò<[¥O¤ßU,V5‘vJÇ 1$ŒUoÛà‰ñ'ÂH4Ojºn•&ŽÌåT£ ó0ÇâÁO>,ýžü;áýgÆ>½Ò®v»ŽJ Þ3Ô'Ô›ª[@LVÒc°EËK×ø‹¥kh³K4%•´:}ªJ »µpþ<ã¥jjú6—àuó<{¨Ãi,®[[mžàû?%W®>vo÷EaÏñ¦K[ÃcðïN[IX“>énOl…Æñe@2y¯#tz‰(”>7ør}3ÀÓ›ˆ®#k¨Ë‰eR¨’©€p7Hzúxµ­â‹tó•[»N}3Ö½/ÇÚ–¡ªèדø’æk»„Œ™db%hËSµz“¸³ÎEx¬š¥õÂf;ˆÏÈ9/ä`tÇSù}+» ð³“ñ+Öá’Sö­>p6«:Œè5vÇZ’HÙXí òlˆ¾Ò=šæl5iéL„ãóbqש«VÚÒK·Ìùƒ òŽå]©œü;ÿðoUúßÁ74èÕJ=Ÿˆuw’r6ç=ÍÒ¾Þh®æ {WÀðn_ˆ~Ûûj¶‘Ï ©iâ»ÆE@¡¢' Uˆ9Ç>•÷ÄÒïn¸=ý«² 9g¹Ëæ˜äT-b޼¥LˉÎsúÔà ¸`Aêˆ2Îã4UÙ>fàÑTŠV94ÔA× ïR ìžµÏC¨åÌsŽ•b-DƒŠI\“/â_ÂÄø¯â/ Iâé… ]6£>”÷zÊíû3LÙå"`ï³fØOÝÁü²ÿ‚‘ëúÆ£ð£áØ»·›MÕ´¯ø·I¼Kl²@ïz—%Û H'°èq_­)©ay$wù ÿ}ñåÔµ<Þ±ŠXtë}OûI$NÄ’çNÍåͰcÈ)'­qãcË ÷þ¿C« ï$¿¯ëSäÇм™±vd7¤jïæ‘üY`7Ž1ÂÁõ5fÛG[XZÞÚYŽé/œ±ê $gð3#ŸqNšÁµk9&¶ÒØõeÄi)Ϥ8CèB‡4ïìÈ­âE¾šâExð¶°3GÇç#¯!Wë^=üÏU%¹›â]@Iá{»x£†5òKF<¸å(ŽTDŒ?Ù­|ØuÆ’yLo!eb<¹<ÒTzdÿZúƒVñË \ŧYZÛâ)T¤_½¿–ØÜ# yã’Û‰¯˜Œv§p÷Z¤Ïݱùâ;Û*p+³ ³91;¢í‡ˆ®ar-ÖÒ|¡wËdzÔ÷¸•#f’p[ CÌ1ÿý*+KKg!®."”îçË“g·+W]:Ve·Š}§ÖsÁü«²ýŽ]ÏÛ_ø6cÄßný•¯n>üX±´2)‹TÓ¦ÚÜü¦†sŽyú¡$œ‘“ޕӅÍ{ÅË_ô§éš¹öo2@ŠHÇZ¡§Éä)-Z_ƒÏÿ*¡$6òÁQ2™'ùÑKw©¤`ï#š(°hxªÈ2gV’j*>éÏÖ¹5 ¨0p©ßTh±åœæ´ØÇ˜ê%×p»Tàú×ä×üׯí-®épÛ¡kGBŸÏ1‰ ixYUOVaÜsÔ’>Zý9[ÙGÌÕù]ÿf¾×´¿ˆ¶÷ÚÓi¯¨·Šà‚(àR&–´¹32Ê€ê9ozãÆ¿ÝÛúØéÂJó¹óýIªÍþq„nó.7,ŠOëÿ(¦²þÛ3¬Ó¾ ß3<(‡¸}¬!ÿnFúv¬Ío[ŽÏW†×PœË6N`o.ã2{@„B™?ßf5³®ü;ÔŽ“kªøÆÓR[Y?wn’²ì u¸XÔ@§ŠðÕ£kžÅÛØ‚ÓÄÃVÿF±hnáÝɺ R% ü¾aUç¦{×Í*´¸Ò|kªÅeÍûòÿ¹’6Q»’ 'Êpwp¼•ôׇ´ÝCWƒÍŠÚÞÚÎ qpíŒö%—!žÕó‡Æï#Oø©rÂøÜ4ч‘”0F9'*3ÁíÇa]˜_‰¤sâWº›($s²se³{eY˜€ÃÔÔѱ…˜ xB’•¸ä{t棴‘%µ_&9?Ååg öÉ>Õ!i"á#S.ÜpMvœ‡éçü-ñNçIý£~ ø][-wC†ûË$±ó-äa¸sÇã ý°¶œˆÁêkùâÿ‚ |B—ÀÿðQO ÛÛÉ%¬zæy§H3òO”Áé÷3Ç5ûõˆ™—ä5ÑOX˜TÜë㑈Fyéõ€†¹üA+ôlÔéª<Ÿ|æ´³"÷55P¾FsEd½á'æô¢«`GŽÙi2y œž\±±vlylO`léA§¨%̹ôâµa¼K:Ï¢ê)s8ß©‘m¥ËwÙ£ÚGÅ~KÿÁPe‹¿ü]ñsž'›Â7ðmÝ´°Ío3Ûßà ÃÛ)M›d ¬7åî3_±7:N ñ£\0éÇ#ߊùwã7ÂkÏŽß¿j}+Ãòƒ}{3鶤61<:5œ‹‚<<¾†±¯V)Q~Í󳇈ôik®¡¹Ò®ùkm*>pxk™iê (O½wßÚ×?5´ßÝXé p Åë´—'û%ÃÌì8à*W û%|ºøÁik{i5ÜZ<áCˆIŠYûÑÆ‘«ÎøÐ/_Z¹M±K©N¶j nûGo¯Jþž´ý[¸Hp#V=ÁäþW´ÚivÚŽŒ¬f±d¹‹b Edpã?»à|¾ÕýKxCÄÃ\ðfyg:MÝŒ+)áƒF§ ­mE½Q•[hÙ³c``ŸiÕCdö¬Èî./N-¢wÇ¡&¯iº5ôß1‚L‡«Ós%äX¶Ò„Ò’ÛŽG~”V¥†p¤,ÈÀž=3øÑG;]Mb™¥|1³ÒÚs]ÈÝqŠë,4XtØÞKx#ŒžÀdÓmµÊ­,ˆ½[¤ Õ‘y89®~gÔ|©.ð»ø«J»³¾Ⱦà}­µ‚:•!Oc‚y¯g¯êÿ³=ÿ›Ä:Eþ½ðÊ__ØÝê‘oº¾Óe„GnóN9/Ø‘OuØzöû†]JHù·0îMx§ì3,~(ý›Q»*á#ñ¿©È‘fÕï 䠦Ϣqæ’kGÿ \IßSñÏVñŸì¿ãO‰z6‹âØ¡ðˆñóé–Vl®`™ÌÊãìß¼0(ß"`œâ“áOí{ãBt½ÚC¨2¤«%<ÁÐ3Gj­6î¿4’œ×YÿDð?ƒôÛgÄsèzZ5¦Ñk²>Do´y FU;±‚ź’8¯ðçÇkÝ"ðXxOB·ÓíãÇŠÚHÈuŒ¶åÏ8 3“_9QÇžI&Ýõíýzí8·&ì­§ëÔõÏÿ|i«ºK£M5¤Ñl¸¹Õ<½=îGR HÍpày°x¯‡k‡.‘t÷”zŽ£f¤°³‹F¹å·;yéÜ×Ü¿ð™ø³âFjhpØ4gñiRÝDǧ / Ç=+æÚûÃÏ…¾Þo’S¦ßeeT¶·´@pHÚ¤î ëüGµo‡›„ÕŒëFðw>=Ðü å¤Rj3[&ñ¸íFüAé[©á‹K;uu¤3•çaúã§é\ÿƒmç×áÛm,ª±‰<¸ñþó.µÛx[LУ†ý¼_ ×?c·ßÇpñ³8ÈÆX|Ý;cñ¯f­UJ<Ò<Ê^"Jü~ó>ÂÊþhäŠæKHmü²y ³Œyu¯è»þ E®Oâ bçÃ^+ÕuZßBð…õ…’âú9­Y¯mdgİ©ÉeÜœ’NOξ¡¨i³Þ2xZ - HÔ²Ü ˆØç?/äs_Q~ÊÿðV~Îú©¸ÑµÃ£¥¿†ô¿ nòỆÎ)Qw¶ÒHùÉÇ×Ò¢uÝ8s¨·ä·"¬=ÓÖÇô×§Zi1Û¬º[A,oÀhØ0.:ê±OqöˆNäpù*žƒ¦3Oë1{EßÔò~±;ô?}µ?ø*ŸÁÛIØ]ë^lhÛTØ¿,2+€ýˆà£? þþÉ4êšê6Ú»^°»;¨’O›¡ù¹¯ÅMOâæµ­WOÔ®Å<–ïòáDeN0qœ ì4Ÿ-á{KM>Ü;Gi[îÛÁ!ãÐd q­ ½žˆ¯¬ÍC§ü7ü9ô‡ü3ãÃ¿Š¿µ÷4ăÈR¤îÆã½² I4Ú¹¤®¢Ï‡´Ûé, hín/’r GEP«~^¶Ö¯,Gb—ÎG;üÍÄN…Ph"±×®’13H³:…òÉ‘Nzè·jéôˆ56µk™a¸1×7-¹ïµzW¿}5¦¨MªX¶«+YéÆ_? ÆÀžäŸ§Jê§^¤eu{‘©R Y³¡Ðþ#j6]o¦y‘6ÆK–bp9<ž8«7?¯õ] ×`Žè4m¢E*Ò1ó峃ëÞ¹ïÝÃynˆ#[}ä!É~Žî~AéS®ššÇŒ¾Ékór¨¿Â«Œ‚N8?ãNUªS•ù™«ÄÕ„—,ÙÉéÞ¶Ó.e¹²·ŒK$+1äçbÀP=þµgþÛÙïöÛ(FÆìdg¿È®µ‘¯…ŽªÇpì Ž[¾3ŽÜVµÕµÕ”1 ÏôTÛ”i#9cŽûsW•¯Ò2— òùî€üy÷4£­½ÿ3%R]ÌïìKÈmJ^/—|§iä›å>ƒ,iþ øye£êaÖÒY-˜…’b¦Aœç8õý+&æÿÄЙÿ²ìd¼²IUf“åœ×ÔŠÞÐü_xÅ,î­XÝ4̨Ûx\äzô­+b+¸jÓ^¦Ú5y=îÿ`Ñ¥ðì ©Í¦Ü_>^bcPÙôÁ¢¼ËFðÝæ¡i¶ý®qº5þ7`3éì?:+Æ|ómÆ£ûÌÔe-R¹ªžyt™®/­¥[®XùФÐûãböïÛŠñ¡^½FÔ6-ÉßVrš‘u­ý¦ÄMä “K·’3ƒÓ§ãŸjçÕèš6‡ötdÔr áT„!¸ÚGGjè,-cÒÝ­m!Fq<Àx# ’3×:ÏûbqMZý¿¢YF<\òßü ·½×m“Äö®!X‘£Å~usÐñÌl}rG½tž"øŸâ„¸Òd¸tŒ1•Q´ ¯¿Ë“žæ½É"Aq Y[bGy+g©û§‘úw¬Í_SÔâ¼¹{ˆí"€£;2^O }:÷éYO_ðìk씩ۗS—±øq+]ÜÉuoBsü*1_Ã?ˆª¶Þd»WóóGæÜeU½¾ª*ç‹×ůwfú=ü&ÙnÊùòí–$8•ÁzªÙ|"Ö5iQip<ÄY&“̘¦GN¸Íf¥Q|RßærºU\­š–ß ­üKa ú¨6Ž‚C8+ÈëþEK¨|¶EF‹`Á‘ŒÃ`àûó]'…ü+}ae$7—ò‰vîÙl"’L–ËdއóÎjæ“ð·Wa(·†îEžS"Œ‚O˜…H\­)}khÞËc¥a*I|î8Iü…¥5µË,pÜ®ÖA'žþß(9ªÒø"×N¾¶m0Ûþö9‘·åsÏRNy¯ZÔ¾ ëšÊ)ºŠƒ®Ý¤ …Ï#Û5SþÒþâêÔõ+[Sj>Eßž1Œ}>µ´hâç²fßÙX‡+FÞg¡ü7–æx.ÒHäw#‘À*H#ò¢»è¾>1 ׈^4,Î|‘œg»p8¢º#–âª$ù¬zÔryÆ:èÏÿÙÿÛC  !"$"$ÿÛCÿÀ›ô"ÿÄ ÿÄN !1AQa"q‘¡2±Á#BÑðRbrá$3‚’CS¢ñ4sÂ%Dc²&5ƒ“TdâÿÄÿÄ+!1AQ"aq2B#3RðbÿÚ ?úˆ/J(€4@U €¢œ 0´‘MŠ‘‡ ¥HS㊇ZqKàP£Šqš@Q@!N)†)èô4B€qN)¨…âˆPŠ!@£SQŠ5¨ A¢£(â€<ÓÐæh О”TÆ€@Ò"–(Í*Y  4àÐfŸ4ƒN(3D T© T¥J•©f…6hÈ¡-Cº„šËP¤M 49æœô¡4R Í4SÐfœóF­PŠ h -ŒÐÅ,Ð h‰P ãOL)ù 4ôÆ‘ª=iSÍ*5FjE‘ju<Ô!^h€4epi@ PÍJhH  |sOHUb‹€¢Š±OŠT¨¥OKÆ€Tââ€p)Å6(€ œR§N) z…fˆu¦Z5  %¦ŒPS7Z*b3@ ÄQâ˜Ði¨ *jz¢€Q §Í ÐLÝ)Šj‰¦&˜šjSSÓPÐÑ@ ¦¢¦4ÓQfœJ€=Ô@ÔbˆPšY¦Í6h¡zphÐ x B€z¤M1 Ò¤zÒª£NjqQ« R&¡b3Qž´@ŒxSxÐ☊DóLOã4ÀRô)é³Oš ^4©‰¥šéi¨–€0(‚ÒZ!P¶œ #C@8@PƒÍhT4â…Q­ Ñt  ÆŒhÅb•0§ 1§¦4šŒÔ†€ÐJ•>(äÐÒë@84`â€QPšEáLEÔæ˜Ð ˜šbqBMù¦&‡4ÄКDÐf–h&•6iP •*T§¡ñ§Íù¦Ï4Ù¦ 4$óMšj…>h¢Ójbq@ šU74ªK4±MŠ„&Ÿ4Ý8¤(@³šT±HÐFš•P=*jÍ,W1>±uÚU¾ŒÒiq§´ˆ˜ë cÎ}À×R.ÊÕ Š@yѨæ€%X¤)5Æ©P ÓŠ*€§ô¨QÅ9ð¦ô­ô£ŠzjNh¥ŒÐƒÍ… Qœæ¥4$PãN)ñÍâ–(À§Å"œÒÅ,P Å 4DS6 cG%@í@&jÓC@i³MšY •*T¥J•³K4ÔÔf–hsJ€*cMšY 6iC@4àÐÓn  š P“Љ‹sJƒŠT)l©Ʀ"„C$%M>Þ•.)ˆ –3F"1Bí§Œ |P¤x¥Šð­×ç]M—íE Ü#Iû¿b©ÁÞÿ¥XTä‹ÅŸDÒ¯ƒö§ìFð·—Jó¡Èú€~•mj³æ”·›=­¼‡ûÒЦ{¥=y5ŸÛÿÙõÌjñ^»îèk7Ä‘ñ­ë?µnÊÝ ’'¼Ú|L=>Í-„½êõ£ÈçºßÚßcô»#r÷7¸#øF˜>>ÑßC¤ý¯öR„K¦È:••6°÷Ž´´8¿G¢f®bÛ·}””ºÄC>jÃô­;SÙé[jk6AƒJýih”Íž”‰â¹k´>Æ_Ìööºý³MhÙY\cЀqëÒ´S´ºçn­h=òùÕ±LÖÍ?…e®·£žš­þÝ­(ûC ¾vk:{`àâáO?:Y(Ô¢’ý¤ÐᵋúÊi/itxÕìÿþ襖™¯J²‡i425{3î”S¯ht6ü:­¡ÿú‚–J5(I¨mï-n“}½Är¯š°5)4šéK4,x "lš”Ô½M P‘Í1©怊i¨ ôô4ô¥J›Â€F˜Óâ–(§ÔôlÓšÖ€v3NšjTDRÅÀR4²AÅ*ª—hD¿¸5»ÈñÍ÷Y;·C†VÚpG®jö)`<|hõ?¶NÕjÚ<Ú²¶÷».%(@U²0WÃÄöÈ~Ð=“šÊÚßY‚úÂTEG”§x…€Á<{Cå[ßhc½ˆÖ4[éíthì5Þ ­ ‘•Éô¯ ì§Ø—h5þÅÇÚ [´¹¸2H­er…9V#óÔðyW&¤žŽºhú³@í‹¯Û Tµ½ŒŒæ)#Þ:jŠøwVì/ÚWe'ýá?g5[` "k 7„õÌdããŠÚìÇÛomôUHåÖú/øòÜy· õ­sk´g‡£ìsLkÁ»-ûEXO(‹´šCÚƒÿjw¨>ªy3^§ÙþÞöC]÷n¿e#‘ÿ-äîßþÖÁª¦ŸFi£[´½†…£]jú¥ÂÛÙÚÆd•π̞€x“_Ÿßnh:·oû_>¥;¬61žîÎØŒˆ£#«¤ùŸ,WyûU}¯ÍÚ]pvo³ÓÐì\÷’£ñu0ãwúW<ù>XùúâúrÀw néƒÖeZòͰlÇ+ Òìc8@­$™áWõ>OCÓn.XV,s^ƒÙ½1`w‹™Ge#>lÝÔד­„m•l»3%ݶ.‚±ÀÚÑïê¾*;ŽÆØRüêÛMlèwÚ 7çøƒ'Ï*Ì+ûåœ#pÔãQÓ |¬>OUÛSÒçS±Rz’ÊÿrÑQÖY^Ç 1ÂÁG]¡Õ‡Ë*k¢²íν§ [{Ç(£tŽª>¹kÍU°(GïkyPô{ŠAÿ«ëO¥§§´5ý2‡ÍIäÈãÙìúGÚÆ´"yŽÚ䎅V'ݱ‡å]§ÚÝ‘ _i3B›\bªÈsxW³ëÑÈÈ çÆ……|oÚ;Ëvþ¢Ðãüiÿ¹ t]ŸûOÖ´·e:ªÞÆ#¸ºã[°ÃçZ挼,ú-…5y‡Û0ïM†Aâcr€ûÃë]Ÿö©Ù«€ýõ¹ñ>˨ùý*òF^9/yJ²ôþÑh×ñ«Ûß&×S"”ÈôÜj) yVŒMOJ„•>)P ŠX§¦ ô jšŒŠZbij§Í  šsMÍ©SR¡MVjsOMãB¢œƒL¦œŸZ |PƒŠDИ:DÒ zÓ3*ÎÁTu$àSŠ¥¯Y.£¢_X8 ·6òDAéí)­y°ñ²äF+Í~À$î4Ý{FfìuIQàÕM|«§öïµ=›¿Eҵ˻^íʲ‰ILƒŒ2œƒò®·ìÃí–÷³î­¨]Ø&¢Ú¬¢[¢¯Ýå<¨ñ1\¹Ûèè¢é£ìªæûSØnÈvu¾ÏØÝ³â˜öÈ?ë\7Ö¼ÿ³_´d5m^ßO»‚ãKYAÌ÷wq·€$x:õ›+ë;ûu¸±»‚êY!:Ÿˆ®ŠIôchñÐþÍ=ž¸bÚh5=4s²)@ž5ô_7ý³èŸÙÖ°ýž“V´Ô¦dÒZî0•18àúר_nßiúoÙ¯eܬ’ê—YKlä³x»ð¯Ôàx×Àý§í3kڽΧu,×]Ùú’NMF—£JNŒV¿e<#“Vô›Y/&wG>ËÖªFRê|!öº»MÖYV$/‡?α9RVͽM´µ$¾àŽ"PpÇË–ü«¥µžü°Ù¶q(öI@Òcüª=•øçÝT-c¶±a¤»#•R^Cï>ä+M-5;ÇWK8Àæ8ý§øžƒë^3ЕGû¶ÉRæâLNã—•Œ’±òÏ_€TÈ×÷΢ÖÈ’aí°ôO‰øR†-'E^öWe>ÎæmÒ7 ñ>áCsu$GîöÂÊ&妺%N={GâV©K?tÓ¬ó=ì«+/´^R ¸è+Öu—¸búl ¨GÉì+{Sð«jÖ10Á{ûœådŸ•Ïù#?jŒóMup>õ˜åc‚f<þ‘ÓâGºA{— ©J÷(0{¼íŒ{ÇÄÖî¨D÷vZwz1ìím‘ƒïÇÿ»š¬¶e¼Bêöö.ìãJÀ %éŸpÍ]·ºk¬&dÍCsp !õ ø›éYìh™¬g¼ˆ›Ë¬x´1 ‘ãÔŽOÄãÒ±îm´ùg)£E3Î8/hÛO«tüëzMdˆË¨Ï%áUÉVö#Q裞k'Sí¿f´¸jד¨ÀŠà|kQ‹ðFד=´ZR^ïU¼lŽ#Yν¼~B¹}f³Fuk‘08îÄåøUÝCµÖ±r¶ÑOm§Ç'c9~GCãùPÇÙr÷ }Ï·,ûqù×x¦»g6ï£ ÝUaR»ŒŒŽ&aúÕ‰S[ —ÔnÈêI¿­n§en¾ð{¹ y||iâì­É\ê,ùod«ò>•®hœYËMiw.KÎÒx’[&ª½¬«×$ƒÔWf’$Kßêm•E/c— -ÔÇÅײS9ÿù²Ašt±»tÜÓ†=ÜI®’ç±·0—nÿRž.ÇÊSwßÞ k\ÕvN,åÚÊé069•m4é§ yÏtqvKÚØ×ržâ1õ©“²pÊïäßÏO‘Qx³—:q ’ØãΡ’É‚ƒ»Ï5×ÉØõ# <€tüf”}ŽƒÙÝÁ8Îx¼Ô潎,ãEœœa·gÖ£º… ÆòÀ2wvBÙ^ñI#Іç²öâ"NXu,+óâ¯4G^ì‡Ø÷lûYØãÚnÍÅ¥n’´2A¡g”ʶ3Á ®WQìþ³¤ßMWN¼³™N'‰‘‡ÀŠúö)íN‡–£Ùs¡,ßz€:s2…à Ž=œÏŸ¥}¨YYjío}iou ~(æŒ:Ÿâº­¢7Lù×ö$:œºF¾—O,š|RB IA*’a·mÏN1=+èÞê,ç»O•TÑ4}/C²6Z>Ÿocl\¿u]Ç©À÷ »DFìCÇ•8¦§LŠ•,R * T(4ƈГŠ¡õ4F‡­Æ…Hh€Bh6(#šDQÍ7$zR¢¥We/gŠYëB >j,Ófš˜Ð“K&š•Bž„SÐN=i…8é@rïÙ—`5©Z]G²ºl’;gHû¦b|IL^ÚŸ±þ˶»>ÍÚ›­/MÔ,Œ°¬2î)"†<ÏÉâ¾ äläiŸi]†×}Ø·rGò—Qù9¬Ë£¤º<û[ýšuø®î.ÔY\Ûà_FѺŸ,¨l—º¼ëµžûJû+•u DIgk»b^ÙÝ ŸÁä@¯¶u;ëM7O¸Ô/î#¶µ·ŒÉ,²*($šøcö‚ûJ›í´c.š5£³·<ýFâo ÀóÌq‰™ÂöÛµjµ}­êRßΨ¼™÷£¢Œôüy5ËÊ‘É*¢$ôÀ¢»†ÝG_Ñ4äln,s…ëî¨ôˆ[ìöžÕ'‘‰ÊIý+дᙜ[D8 a½ºü«;DX`Aœ <ç¯t }[ øü«£·µ“¼¿ºÄ£,±>Ð?Õ!ÿí¼Ó|ŽñŠEÛi4í4{hL“‘žê.çÔ㟉ÅAsu©\ÄXKŸ2B0i¼þ÷sJ×Q·ŽÙ­tm5®Ç/ð¢Ïžþ­ð©¶“ËÞë—ʱ'=ÄmÝÄ=O<ÿ|V ·frj¶¶÷M•o%íÛpòòçâÇý…X}'U¾F½Õg–(W’‘Œ±þŸ}õ«o:CuÙí!Lc¤Òí¨Ï${‡Æ­&˜÷|jRÜr`ˆ˜âúrßV×€‘Å=Äbw·Ó¬ßÅÝîÔßÔŠÓÓ»=©j ²HÐéè=7È~cëZzþ¿¡hVÂ41LŸ‚9õ§ÇÄj¸×µ2-´«qñe\ãמÖª‹–Ì¶ŽŠã@Ò4‘÷½KPÞÀdI,ŸAžO³¯~Ð"*,´;.œ{*ÄmAú‘ïÅaÚv_VÕî>ñ©ÜÌìy-+}y®ŠÇCÓ E†Ô›É±¯ÔùUú®öTŸèÌ¿±í±hׯ¥ÝÛðE´-ìàŸqãëR~ëÒt8 –K#;HX!ÇLc9Ít¯¦Ý5£Éqp±¨S¶NXãÃwAåãYZ´Zt m}sháy+ ’{L|wxãýꞈÕΣo÷ÍMu+vŽÐ‰³×ò8Å]:¤—k¦ËìäN@ëáU»Ogu}wä0ÛÃÑ´DxÝEýäZ„m÷+f˜‚ªK°÷×d¾«G>™¤ÖÚÄÊÑ®¸Ç#’b?QUåÒ5g#v»ÛÓ#ó«o¨j‰ÒÊͱ×lßÔTS_ê¸i§Ç?*Í2½çÓ{FU5¥9ðe'Ÿ4è]ª\Þ±?ÏŸ¥i¦§vÊ©.*m/>*iuÉ–D´†pHÎÇZÏÛÁ­yF'î.×0¯”ã•äæƒ÷OkÚ2ø+žÏ? éãÖïßô›˜Ôt;‡#âÕVãYx›¼ýÛpƒ9Â…lýM/Á%ÇÁɽŸlãw\K!_󺪳öÆ6 Û\ä†<×^{YÍg|¤žOr¼}(áí›,³\Mg+¾ö­_à‰~NmKµHÚñjý*¬šÖ¸‡ÛšhØ L~•é°êÚ<êŸþ`¦@99}qVÒçHgÏÞàb?Æã9ùù<•5`ß}—¯S]e4­µšŒzvö¡s#…î`VE¥Í,ÓŠ!@¥š`i@¢Íiü:МW”~ÓVÜv:ÆþÙY¦²¾W”`’}9Q^«ž+Ä¿k^ÞÙök°çB¶>³©c¹AƒÝFµ!ü‡Ÿ>F³%hÔ]3ÍkoµK]gO´ì¦‡|ïfUe¾’ÂÊøSÔ/SëÇU¯—& 1Ä“zsVn.ï‰bßPÛ‹‹‰½®@iûšMœ×7jC1@›Æ½ BÑmaE{ÉÝÑ3€Þ˜·º²»;§JàÄcÄÎ?JìtI-í¤qk]N8b‡'×,xì×›,í!R[‰!HlíþíøÈ¡xÿ@ð÷‘Eug¦[}RèÝMÕý¶'ü±Ð|h‹ß^ŽíåÑü8Ú>÷þ€{è÷éš5³M-Äá·#6]–O$üë‘ÑÚͲâ8ôÛeP»¤Ûñà£õ? —NÓ,-ñ{yt— °šáÁUõ¢×1«vî÷z=‹Näág˜ásè:Ÿ¥dÍ£ö—´júœ†(˜änàè~x­qö9z:ís¶ú‚²ZÈú…À.V<|³\ƧÚí}?áÃYÚ7Ã=[©øq[Ú?e´½" ÷ &u»éùǸt¬³¬€Gm 2ž…Œû¼þªš]œŽWKì5²mkÙv<±c…ùWA§ÛZÁ˜ìíL̬Ø€*ûϯýÞÞÝ3u9Ÿ'þPÈAîÉøüª¬—÷±·°´Ê¡*ª<ùý:Ö\›*UФ±¤—S»fÏITß×§þõ×$·s§eF¯ÏSýMZ‹OyYd¸t˜õ<ƒÐ§ßÅ6¡5¼/0ìE$¤X]¼uljõëPtS½{èì÷϶ [h‰-“æz |h{A§èÍg¸2Á†ÊÊ2ï!õëôâ¯&Õ¢ht½4Éþ)ÙUõ$ñEwe,ñ$Ú¦¯o¶7 V$c±Ç5¤èmœ~¯i{%ôi`/ÍvíïF­vo+mßÄ?ó8ùT½¤ºX¥Š .æSlT–”¡ ¶yÁÇåP,‘µÚÊÖWÕHa·=|qÖ½èàû4Ž£x¸Y4Ñ'ù–`M:^Ü0ÞtÙNx ȧZ¯÷¸P3 ;œÿ`ÜT'Q´òŒ‘Ü0ý)Ä­ì(ï$†v”i·…º{*1ô5i5«¢7}ÆU‚ZÄzzUQ¨ÚÆÇ&vɈ[Œü*ÄZ“¦{â=29éQ ˜gXîPHÚläu$BW?*×l˜w†Ñ£É#!N=Üõ­¨X¯ò$#üØ?ZŠ ¬å,VêÛž†õ¨¨Y:î•B(ƒ¡ë¹œœŸôãfÛ´6nÌÐ;7³‡ÊŒ|),6Ò }æÌŒtÜ|¨…»8%â$*R-²ä7+IÝD¤ç ÊF<º@ñhóø9‘\·þ,Jʧ©Ma¦É6É`„ ã [×¥éZb±Àœù•^Kv­›i¥ha‹=½“ÈËÉPgâ+x4Èî™VÆ"Fá‘v([M´,BFê½8‘ºüͪ)Ùß«d&'Ÿq­GF[ÑÙþÏ3Úh¿lV¢Îs÷"ûJ÷‹Ýî9Î@Ýœ}kîLŠø#ì3E’o¶Ï nãX㼎P\nÎÓ¸)Æ3ê+ïp+¬NrÆŸšjѦ4TÆ„•!OŠ©R4&€gô¨Ú¤Å tø¢Å5 šœÔ¤¦€„Ó`æ¥+MŽ(¨±MŠiS‘J¨&§¡äSæ žš–h¢˜Sæ€X¤if˜šü)gŠÒ 9ï´nØi}‡ì•çhugþ ˆâÚšCøQ}OÐdøWço»iªö»´÷šî¬Ë,÷.[nNÔ_åEz×í+ÚnÒvÓ¶sië¦jiºd ½¹…¹ á¤oS€Ç­xìݘí1îômA¸þ[v?¥K³\]ow$¯±cŸZÖÒ!8¹'¯ªQXÜErÑÝA,r¡*QÁOŽAèk¢Ò!1Xm縕W&8#.Ø÷ Ľ"¥³I±’TU¹rSÿ-=•øùÖä×¶U¸73Åmf$üGÜ+Ž]GY’äYCÓÃ1Sü2óqþ^ ñéW4-\_K%IJ¼°’@Ó1Î9?Éõ>µÂQ®Î¿¢Ý÷lî¤NëHµ[T< §]Î}ËÏ>üÕKNÎjšµÒÝj-6$l¼³œ¾=Ãã]]•Ž›¥b(UØã íJçÞy5l¥äŸÃ`¶;œôŽŸÏ*èª7¶Ca¢éZ\kpÆ4(6¬Œw;{½}ÕrãïR¦ÛH;”ñšá¶çܽOÒª ô­,4ÅIJò ®ÛŸáÃîV­«jûîFÛ;^Ë8;ß>!züð=k&—d’[éöm·sÉ¿Ç(öAÿ*ôùæ†ò[ùT; ·Wá$—!˜gùW’~Xõ¬ÛÖ´³;a=ôÀó<íì©ô3ð'Ö«iú¦ eqk$—²ž7§.G€ÉÈQï«EF³ÂÑ>ù÷ ;ÏžÑÀ÷Ô½ µVv™nÀ§’|U¾=Ó™õ[Öˆ–ŠY‰õcÀúÖ”vqo»[Å:¹ügÞÇš…)<ÕúåÜ =ZS—ø/Qî⤵Ðôè§u3Ý9ñ˜ägÏhã皸n®nµ”Оfsµ>}OÂ¤ŽÆÞ 5Üßz~½ F£ÝœŸÊ– Yá$[ZÃ-û!äc(¹éŸåU;ëu¿ÐeoÞ±£û(©Ú·;›áó=Ö¶¶·Y$P0±Û§?¥dIc|ti4ØRÎÖ6%]^PósÎ0¤…ëãÍTˆÙÎëO“C§Ü%àmí$ˆ¹PÜ` «orÆ(gšûœ²¯ ´¤ÒäÐôYï/dSÞº¤QÆì+%î`–8LÒ´r+eƒÇz"ôqzeèµ#Ò̼ñ˜Ïþ).¥aÞ`H9ÿhxY³gï8œdRûå“··8oÏh…±}hà¼@}7æ…®lÕï£çŽM§Ó›J¥‡S€I¦abÜ»@F?™(Yuom_ˆ<5L>æÃ½fsÈñ¬W¶Óñ‘ $g’8ð¥÷; ÆJ¹ÏIOO(Y°ñÙι*ÏŒcZ£=µ¸†‚ߟÀÐ%Œ 6›©SÏΜi°9a÷¹XŸ÷5cËkmpq D§È;)©¿rmÛW>Gï$‘õ¨N †ŽîD åNåëò©„ZžâWU”Ž?*;ðZO²hlÕIC{ñV`Wò5°Hí½®®ËÆâ¤~TO¢©¹/Õ¼·¡?­ §SHò^&Ç<ä}(¯²>Ͳ½'ïÿj:%½Î­Ý+^ÅüTÁ‘H`W~>uú£Šüèìf™¯j=¾Òà±–+{ÉîâKiÄ…B6à$r<<+ôaÚ3××H˜b4>´mCZ20¥ŒÓD (Xb„#4ÔF„Ð ˜ÓÒÅ8¥ŠzB€`)D)6Zµ.)¶Ð•¦ÛR✠"*¯=)U) =§ÍBšY¦¤()óÅ,ÐM6h|izО)f†•TÄRð¤(ŠþÖ>Í»G7Ú•Þƒ£ÊºíÛÉ'$øükÈîmgÔ»rÒYM4jW}Ñ‹€<¾u×}®vŵoRÕÜ\¹Øˆ0cèÏs]ŽÒui´ÎòiÞÎ9$ÞòŽ^^qìøz|+ÎÝ7#´ci#y®ì´‹…XÚ8å'i‘ý ê}ÕjúmÒ2iö¹æV‹áñÅ\HltˆšhÇtØö¦wÝ#znðϨ”êWíìÄ–Ð>‹>GÉzŸÊ±fΗ¤ox¢Y%èe”†lûü>ÕïuP·Ý#s82»l~=O»éZ£JÓ-È’v7R âI€Ú¢ôùæ”—êfÙ u1*ŠNßè)¡û(A¢GÃ]¹¼>+’‘w‰«¯sgduðÃn¡r|±S ›•u|mÐä÷Q ·Ìð>´ÑK¦éÄ 8™Ž2¹yd'Ã'Ÿ€«e§r£îÖÑØÂG/9̇ܽsïÅ;[iÖ€Mw)º˜sü|qî^Ÿjܺ¥Ìᮀ²‰Ç²„•½È9ùü«fÆÕVi¢Ž"¼ï¹"Y3è¿…O¯& FrjZˆÝc XOÿª¹ö"QèxÏÃ5¡§vR[ˆ÷ß^K:[ƒGÓ¾žú»uÚ:ÆEhã–êä~F÷> xp²õ=vþñ‚» U<÷jwÉôà}}ÔB†ýѢػžÇ;"PãÓÄûò}k޹6÷÷sÚÇ*K4E‡{ Sœ`0O>xñ¦–ò4&{†È2òÿEøb±ä»†MBãR°[‡qlË,ŒTÀÎáž<:xÕ[#e.ÐÙÜYé 6©¶ýžUHÃ9þÁ9ÏÀp*ŽŸ©Z¶œ¥KgLƒ¦­K»F{3¨jªó[,`–•Û;‰àáUlÎ[{)#HCÛœøõ>µÞ=¥ÙY/àiVŒçŽG4O5»°Ì‘‚<6ƒNd‡¹îæ[iN=•\ûóŠ{> †Ýp<@­wANÄ·R˜Å-ïoŒõâˆMk³ÚÜñ×`5bË}ÒÔç«A: îp‘Ť<ôöQBm£ U –ÇÖ¦Aj[›[rqà‚‘‚×ÚÝjy ä¡©BÈÊ̦RÝÔäŸù§†ß]dLùJÃõ©»»` ,s|%oëEÜZóü)=âVÏçAú+-¬á&¸P<¤â¦û¼hŠMÅÀ=G´?QRˆ Ïtž›©¤µ€JB\\ä0GåA×DQÂ’HWï·KŸE+ùU¨í›ÚU»Ý‘j<ãäjºÈŠv]²’8ï! ¶»ïT¥ô%‡L‚?ZZ®©mÚK;‹9{¹–Dî®b%;¶Ï qÈÁÇJýÒVí4«D¿t{µì‡!¤Ú7ÓŒæ¿<"ƒX:µ»Ã¬2c|)ç¡Í~‹DÁ FÁPFGεÈúÓSdÒÍlÈBŸ PøP1  ¿…bx¦¡M6ic@9¥MO@*qHS@55Ý(MEM@5!Hšš#Ö•iPéRð¦4 ùñ§9§ t¥šlÓgÊ€,ÒÍ6i ³Jš–h¢PÓæ€ñ¯Ún&† #UˆòܳêþêåþØ;usÚbÏh*óDeÛÆ‡ÿ˜˜ñ¸úu¿´‡h4û].×NYïQÌÌ8"4ÚG>¤@ô¬ÏÙŸ±é5¹íö¥ÝÍ5ÎøôõÎ{¤ UßýD‚=Ùó¯<®Rq]Õ(¦ÏûJìm¯c{_Ÿ©ÝK©Üá’EE< X(ñçv–3VŒw:Œ1ía§Z®vGóæG†k´ý¥uK´‡{˜÷L¡¹#ÆIõ<Ÿ•yê_M©LbÑâS¨c,¹EÁ=G‰øW,‘Vn2ÖÍŠÆÌER@ÿ1ÜÀüz|g%ÕÍ̤ØÅ-À' ÿ†5óËýêÄ––vÎ$Ôîcº˜~"â1î_ŽEO jZ¥¨‡F°&!ì¬Ç؉}ÇÇÜ+&ŠðéKŸ¼j·f`Çò¨=íÔý*k‹’³Ò,Dü{œ/«S[:ocHQq®Þ½ãŽ{µ&8Gÿs}*ôÚ†“£@°E$jÙÄ¡T)ÚßQy=”Fä÷˜üÅhÈ2#mj[ü#2+0öá„x'‡ÀS­¶§ Ær$?J÷V °Û“ۇέØÚ,¼aöDbE9çj0'Ò®E ’FªmîKàíΨƒª‰D¡¢é“‡ö³ò¤Ó긂1‘Ô?>ú–Ëíol±{2]FO‡µÇ»ŠŒ[Û’H½ºæ<ãéUŒú‡óÀ¸¢ßxP„9)¸ zzÕ2X1# +ª:ó(É?Jt‚@CG¨DÞ8d8ø`Õx于0ÐõÏQ“E#±Â¦»'’S8¨RÑKæêá|»³ýh Šù€Aqn}vœÕE’.wZL1ã´Õˆn­×K„Áợý*”ƒS¿Ôì&·Ýs“¼•1©\ãÃ9æ¿A¾Ìõ;cìÿBÔ¯`K{‹‹(ÝãU )ÛÐȯfÕ#‚…ºÇ!.w±œG>U÷ï`¦‡Ð®^õdÓ `øÆsÕ‰—Ѻô!¹¡&•lÉ&x¡"„qNM6i©é@55¡4øÑ ju Q- éHð àÑŘӓLh4…=*sJŸçJ©J€Ò4 Ò¨AéóBM6h¤)³Í,ÐOCžif€:qÒƒ4àÐ\ÿoûIf;3u©>p…mã?Ï&8ø§Ý[7·VöVrÝÝLÁ—wc€ x×͵×5´¾ÝC¡èâNåÛdxA‘ºVþü…c$ëK³Qörú½Û»k´]󭕃£\ÎÝg‘Cªÿ¥KL:÷ŸÙ‹|_f+`Î¥,o§‚5öW!°O‰ö‰çκîÌéú7Ù}ïgt¨6[Ãa" =]¶’Xù’y®;ög¸o¸v†ÄÉ‘òÊñŽôVa #mòMœGí{¢i±v‡K×n%š7žÝ¢e^C”<{¿^|8®N¶Ô5KH¿îèŠ(y® ŒtTŸBq^±ûYýÆK=u« fWWÜA$í@z ò}?Q‚%ï4ç’òà   #üLxÏ¥qËþŽ˜ÿÉÐYö_J²{Ð×søî0À{“ øæ¤¿í%žË[g áP`šäu=Böä¼ê Œs·Ÿ«‘ù ¼Ôlmo(yXÇ'ýMÕ«™»:]S^Ôî ]â1ž<;cÔçhú×/ªO3I{vP±ÄÞÑ÷·Sî”J5}^0bU°³ð–OgpôOåRǦèÚC‰®º˜ ‰'ä|¥T¨…K)¯®`Ù¤iíù¤lAë“×áD4ÔVߨÝ=ãíG *‹ïn§áŠ{ÎÓ¬ÏÝ®ùyöcQŒŸ, l5›¨ÖkÙ“KµÿIi1被T[±îu(tø»¸DPF:Ɖ€O¯ŸÆ†ÆMcP]––BÝ\翟*ôñ?ZšNŸcpZ\ÁÌ2ß^Ÿ T—:ä6Hª¬fr0ˆÛ¹Àã?=‘ƒ§önÊᤓTÔ%¾•=ÐSX÷çŸhMqgm§Im¤`‘€ª>^>µ“ 뺊J}À:á]œ†¡züñV,û=cn¡¯${Éz³ËøIÿHëñÍF Í}4‹³M77S eå}ÍྯÚ\HZ[µ³Þõµ“§ŸAõ¢:šE/Ýtûy. áÛÇÂùç ’5Ë›žîKøt´#vÅ;åaèýhÇG-qm§iqÜÞJ[‹ü7r!BûXž­€~g‹¦ê»æ’ã¼›wá2n×bº¡Ù»ËmZ{ÖºòΘîðÈàgõ®Pkwí:+¼R#ç1‘œŸ{íg)-’K1.ò íãfoóuùT‘^c™br8ä°ý*¼÷·Da-®z.0> 7Sº€lÙW•\äü+tK¢ì÷­*îŽ(Ÿ42^ty>Ž1U»ÉHSûºb¾º'ãH;£ãîW#Ä‘ûT¡ÈšÞåÞL›l äû`ëÖ¦’ûa´lñN~XÝåm¤ÊÿŠ×Ï¥ž¡4edx™ðÀ•’Ò« Ña/¶åbŒÊ1U濸•†ËÆõ9úÕ¶Ô–Fv{ ÝFálC|8ª×P’¬!bqÁ1(…è4–Bßųv‘œ©Œã¡óâ†I¤B»í笿¡ª†ýP’QGý4˨Áø\täñTš/‹‡BwÃ(cÓkCG÷©£RVÖó„þF¨Ë¨Ú— ›<û©Az Ü?‰dÅBZ³Ä¨Âň݇ïãl| }Ýö1©Gªý–vvö"Jµ’§>}’>b¾k«8­XO ]!a”ï1“ç‘_r}„ÏeqöS¡Éa%³Äa9ñwj­¸î\`rA8äóãZ]‡ÑÜšB‡4­˜ Ž(Z,Ðä@8¥œSÓPž(M=* Ò"’ÐŽ”ÄSŠziéÏZbh"š‹9ØÍÔ©)…ø¥MÍ*Žif£Í-Ô™¥žj<Ÿ Y $Í,Ðf–h@óK&„ZY 4³CšT)ä_´~¿qecg¤ªºA82±ø¬ÇûÅný‡ö%»/ 6¡¨ :ƤK‚F )Œ¬^˜ñõ÷ ìõ-'LÔ®-./ì`¹–ÎNöݤ\˜ßÈþü¼«CáXPûrf¹}i}¨Õ´ÝH’}Rq 8É%¸é^Kû:ÌöÇ´vA²eµ¶—¯]¥Á?ú«§ûyÒ¦½ìÂ^Äï‹f*ê9Àla¾ñ¯4ýîÒÓíGîlå~ñ¥ËSâÉ"°ÇÀ7ÈÖ¿ê$n+êΟö±·‚} Ei‰Cò°søq´d{Ï÷ùòóQ­a´²i¯.ÊÁ “³Ã<¼«é?Ú’Ñnûb Âè}Ì8ÇvàþyøWÍ–wqèúy¹Šâ3m/°›Ï9ÿó­ƒBÒQdŽóÅ4ç{æ3Ò«-Ö­©²ýÖÐÃqßL0óçô,Z ¬l×Ú­ó_H¼•ÎÈ—ážk›:Ò*Üë7Z†bÒ­ä²`2|Éà|j[nͽÄãY¾“nì´Quø·ô~ÛU·HZ×MV“ǹ†>§Ðž¾톭¨.ë™`Ó£'ŽwÊÄqÀùÔOÑ þñ¢é°lÄVÛs¸§,ÔÝI¬Èîîu)H°³’h2ˆìB/žŽ<: ¹i§hö„‡ˆÜº¯] ß!Óõ ¸í,k0·‚6¸— Ž,Gʯè~ÉÓ@i˜K}y&Ïå†Üà|XŽ~§-¢hѶÞî Ëg,}ìy5Aá×uÞÈñéVç®îd#ÏõÅž‘ao0˜»™g;ˆõ Ò¥— ­©jcN²ÿ *¾üÿLÔ©a¼çR¼–峞êU>8äÕN÷O´‡½¹¹ÜF2¹äü«*M_Q¾&=&Á£N¢i}„ÿzv]q…µMì[qˆ×óœŸ_}U‹YÒàÔ¤–H幟»¢`–êzOQHyHýë¨ÉpIÉŽ2UGǯåZͤXDѤööäŽDDn>óâ}ôäûA÷C^¼þÚ‚«ÿ ’ÁNÑÔ™àüjðÒ,¯Ê45È%YQ1±¼p+wUí$ñêF×O€{J?E¤Î=xéƒÓ¥r×±™õ .§º2ÈrrŠKq׎+´-öp‘ `G<’\@Â#’ °R=üÓýêÔÈP¸&RGÐÓÃo;89ÃGÇÒˆÛ¦à#K|“ÏðÁúšéfPB{PŠáSŽp®ÜÔÑÝØ(9h”‘ÆI?­S–Õ²ZÝ t¨ÏË­5Ïáï"ÿ“})A{B¤¬k ŒõÉ2ê‘“8æö¿:Îî.7e®x S²^CåTS=áÁŒr F4f":4˜óº1¨ÅDBäͦÝÀ¥Ž7 Ÿd Ãý«ì¯ÙFãì‚ÕW½1›©™ÁÁ#•φr8ã ׯRÂØ}íb…UÆ(TN@æ¾Óý˜5n¾Êlí-ÔwV2¼Á·oï'>ycÇ…UØ}£šY¦¡ñë[0jJhE zYÅTù¡ N9 ‰FhEJ‹ÆM‚ÑcŠ|ã­ìŸJÓ`š/5t .h‚⤑N¼t¨È«󨞀 T$Ò 2¥ŸZióB0óJ„Y¡Í84¥@iÁ ð§Ítù¨è ßN(3Oš­­YG©ivclñ2sàHàü5ó'cmΛöÍÙÙ^6;Ù p-®¹¿:ú—5àh¶  }¨Û_ŸfÙ¯a¿Ü8Àß–ú†®9tÔŽ˜÷hêj} cìØ EìŽÒȈ#,'}¬Ú9Îyé_4i~Ÿ¤é1«µ¿~ þíìy “ƒÇ…}+ûQ¾ ÿgG§:•–ö5™2¹dÚÇ‚}qÓÃÓ5óÿgmJ±s§ÄŒÙf™¹!½þUŒÝ›ÅЯïãQ 7®Üwó¹Lz€9úQ.UkÙe¾# ü }9#â=Õ÷ib2÷Iy18 Š[*¬ö]¢¾v7¥”L0#Î÷ý#€}æ¸Sôh^ß[iöåbxmQz$J?ßžMfCwª_‘û¾ÊM¹æixAñ<|…[µÑ¬,Ÿ½I½B2ó€Íôôæžï´Ö„[§}ypÄ<Ðgå¸emZþKÌgø0ä/Ï©úVÂÜéÚE¸Ž$´¶Eϲ¸ }qçst·r‹5Õâiñ±ÀF`Š?Z=;J°·&ž¾t9 xv¡ÿ£Çâ*¿ØVJúøºv]>Î[·RA;}…ýDÖš¥ü¥¦¸ŽÐà{/xçߎ[Ô/a´Æù¢Ïò¢( Ÿ-£úÓ~ÿºHvÖqYø™Ædçü£‘ñÀõ©ú*·gìmã3Ϋ¸{FK“¹ÉôÊ¢:‰’ঠܺõÀÜô ÀBßx½3_Ìç¤Í…ä_Ôš†îíû°n¯­¸Ãì§éŠ¿±zÑbdºšVŽâx¢aø£BÇ¿)ùÕm6‡^6Ö–`æýû ¾íØêzqåSé0êw‰ÿäÚC÷g¼Iü5ǘ'¯Ã5§>‡,RÀº–§5Ä×cEfv s–ê|:b§à†.µ©#T6ðÅi,ò¢³Ê}£ž˜lrq:à®ì̽ôw2ç(6‘€|:šôžÒAÙíV·‘ô³3´B¤¸ÙÎâ|É®#´ïXí¼²‚XmJ¯r €±¢ãËÃÇã]±þ2Z1÷Å…bqÁuÆò5e!»UÏÝK ò«Ž²=Ìp}âY“…Qø|ÈÍ±ÜÆÛºLôe@3]L¢©Šå@ àŒóŒããR¥µÒ°f·Ræ@5$m!;]nœŸ@?J—8ÀŽûŽþ•v‹ÝF0ÖQíÇ$ §Tg ɧC*Ÿ 㟕n 9m‘—^(>í"{,.Ãÿ•ý* aEk2¢ÎÝ7æmØçßW¤Ä®ÛkRÞ1ýj¢[Ü«] x»¾}*aØ ˜ç'ÿ¨>|Q-¦%‘¬àBßëSýÒábTî pøÛúÔ=ÍÚO¸V\‚~ðÇ—Z‘ ˜¾JG’z5ÉçÿU ðËÀû¬)ë–çëQàÆãøp×ñ6=Õ5ÄW ½áTgüÇüèÒP´i·ÿÄž=e™íf»±|%´1`߇Ì×Õ?±þ°ÏØû¾Î;E/Ü%ï’T“vá!9Çsã_*ÚéÂ{Ybc%9çÄú×Ó¿±œ aÙýzÅŠ³‹˜åÞ?˜2‘ïþ_­UÙGÐ9¦Í04j3] Sô§ÇÕ³LiqNÇ¥£Nj>hã4 Tˆ<(¤QŠv^(æ¤ð¡"€e5"ŠQ-ô,Ò4šŒƒRSb€Œ­*rNiPø4³@ >}h@Á¥CŸZY¡Ÿ54³@Iž)óQgåOº¨$Í>j0Ôù $ÝH Óæ…$¼§ö‡¶C¦i×}°ï oB2?#ó¯RÝ^_ûIË÷nÁÛÞá±o}yÀ×<ªàÍcÿHã»}®^jÿ³Už©HÚ”énåqIC×ü¸9¯ìäueë…ì€1[vöcNOõ'Ç»Ðë£Jû'Ö,ñ[Øn­†}•'*ÙôÁÅv#÷®§§/{«¥¼&FfŠ(€•>-à=+Ï'qLïMZ¦›¤BÐÄÖðŒeÑ8Å WºÖ¡~ï±îm˜`O!î×ߓɸ {m;HÓY¥dYæ'=ä 9Sת·úì"ãb“4¤û*£y5ƒb—Kg{©ÝϰçdM²0}Xò~^k˜ícqm5ž÷ ¹Èò,i>™­jÎ{×6¹ádåþ ?\V”]ŸÑ4¨”Ê>÷qŒ÷“6à¾?‡¦}õcôaiëuxå´Û¸|Ÿø‰[Œz“ÇÖµ$Óçp¯©·‚Õz{ØÓãPêÝ Š2aŽgÀD€¨ì4ý{TNòSiÿƹ''Ü:Ô\Åm2ìR? ' W>ÑùãÒ‚ ØçHítËf‘óø-ÓscÔøVä]•Óãÿ‰Ö/^òCŒ§àN='çSÐé–ðUº—ÁÙ úEE³>Ó³z­Ò–¼ž=63ày+{ùÀùš×´°ìžaÇ}pýä™ó+&êûX»`.¦zŠ7ÈÃÜÄŠŠÚ(£"Y 2’x’å÷–0>#ãMÚŸ^Ô5Ù¦YK4cÙï[ÙŒzç§Â³µ–Ú{xuGuÅÃ6Èà$(ÀÎK<÷Ô}  r‘àchû‡€÷æ¨Ås%åê^Áe5у¤·-„R|Iá~š‰lôhkü)l–ß~·ÞFH*¬L§¡ÜÓ}p½¶Ô,æÔ–M. ‹H ¢.ë`£Ðñ]ol"Õ¯c†[ƒmq±YvÈq8>óÒ¹ÓêÒÉ,äÓ$†NíFùNÖo €<:ø×ltc%™­#~õ9ÿ—·ò©D“žê,Á ¾°³]›obœä@Çš—¹³—„-žžÈ&ºÙÌšQ&ÓþjÝzp½ä$sƒÇ¦ X7W‰Í°ÀÏŸ…:ÜÝ0Ü%´Èÿ9ò¢› ûXäË@áão`ƒÏ÷Ô{«é?ؽÛ÷gha“™KvÏŽ0üWÏ u}$22­™ îw<{¸¯ ÿb«€l;AÔ…ïÄɽù1û^‡ÇÔU]‡Ó>‹^µ2ÔKR©âºÃ'Š)³Í8(áiØqN1Läb€ŒðjEÁ¨Ï&r:Є¨y© ð¨ÔqOœt¡I7A½*<çŠ5  ~(À¥šóŠlÓf—Jéç@Z„µç“J›u*šÏ‹sAº‡w42L§Ï…BŸu.êlñ@M j‚@}ióQsN .ê|ñQ©¢Ý@ióAšDКóÚB1/Ù>¤Çÿ ãaÿv?ZôLלþÑ(dû0½°ŠO¯³?òËÏœmb—Yû;,±‘4q°¼X£qóÏvJ{»èæû¦Ÿ/zÕu`±¨õcÔúW¬}›iÂçì=5@^ÓV™ð0O×:ó»)l{;Ú OJ»iìæKxâBÝâ·  ¯#\m#Ò¾ÅæÒç¸?y_6Õ縷]£âÇ“ð’\iº<-ÜG@Ÿh¨ËŸyêh¬tÞÒk!ž^ïM²$fYÁ Ày/SñÅ_µÑû?¦0k¤mJ\ä½Ë{ ú ýsï¬Yª£"VûUf]*ÖIöŸiËmEóË(­ÏKtF«œwv`°>…Ï*³}Ú;Gaoij÷ áQrÜ«ÀøÕ9×YÔöåã²¹ûmïÀà|é¤RÎíE%í †6^’ÊÁœüO5Wÿˆ¯o·ÇaËã½|$Kñ=~†…¥Û5ã‰ä<í“ðʔڜ æ-6Ñî¥ÁKm÷ž€|E 1Òn®e¾¹–pý3ÝÇñcí0÷b†Ca`‡¼ºŽ(ÇâŽ}ç©÷æíu{¡›É"´€«í±vZnž›åŽÇžúb$sêà|*$GѼ¸¼rº~Ÿ.Ìed”á}äž´£MtUõ=Q³ÿ“cÞ}Þ^4µNÐÛC Es3@98ð•´=£ÔÉ’ÚÓîª@þ-ÉÁÇ ëZÙ3VÖÃGÓS+o ¶2^C¹‡Å³…Qí³m¨i¿sï$Þì;±-’¤ï¥g!Y·j7óÞ89ÚÄëýøÕÙ…»Áž-m¡c¶W†öë>|ªZ²ø2{SªêðZµ¤3é¨K=áï$àGQÐùW%­Ik ‚]_ï;¦rìÇv†êíõ›ë]:6Ÿoó‡vFÚ=çŽ~5Çö¶â]f.uRMÂ.íJ)gÉ>Úg9¡ã¿I;—Ý  û'<±Ò‰ï­™ãÎíý~ÎäX¡ß´.ÉõjÚ{8]ç,íË„z×Z9Ù®š­¸QÁ³M5ô-)bÓmÜsëÅg5º÷˜Y]“ƒ»g?.æ%\´²‘â2>´¤ Q¨B‘É&OµÇ¨¥ûÂÛ«E9P9 Äs!MϳӨ⧊M5S Ï!ÆGµÇÒ¥ûOnÍžâFçÄÿSM,±Å°féÃ>µžÒZd©„àù&îmÀU[NGí|Ÿ™«D-G6u‹ËÚuÇÔÓ9/'ñ!@<•ÓŸ­Wfåmˆ#ÃkQ#ƒÂÙ7_Å [&‹$ã“üUÉø§3²9ns¹xúÔä)ÿÊÇøWúÒF¹f`°B|-GÖƒÁnˆŒ9ØÒ7SîÍ{Wìa~ÍÛMVÖífY[O&"À*w c“È?^'¹Ž ‰n¹=fP~`שþÉWƵ€—·2ÆVÚS™@V~›O×ãtñ¢²¢€QfºÂš0x¨Á¢ƒK4ÀÑBŽh”ô¤) Pšl愚lùP>ãQ/Z:@}ióQƒNM 4,Ô94%¨f¡ ëBÇŠ…˜Ž´!)çŠUZUA€Z˜µCº–j˜7Ÿ4`ÔHjEª§˜}ÜЊzÔù¡&5¸™ª²Ü¸X#–y¦ì|ª^ƒ5DÁƒO¿Pqœo8‰~ƒõª÷šXšF½Š8#ÿÈ*÷þøªïmª_÷}äËm q¹Û×hþµvßIÑí^]²ÉÜdœ“ƒî<•ZBÛ2ã¿Õ5 Ý4¸nfŒãt­Âúä*ÝŸfÚñ?üÞýñÏðíßÇÔœþ•4š·}/sc·â°F[üqŠtµíÖ;ÎãOŒñµ½§?ôŽŸTQ~Øè8u‚Ü; Ò‰ª—=¢¹¸¸1ÙÇqu\àã¡ÇAN4m&ÉEÆ£;ÝËÿí¹R}~¹ªÚimP¬1#GábŒHõÇOpùÔ[H–šµÛ¼Ï°êcS½‡©Ççð«²Á¤éæ3"O)á²÷cJÅ[ný6XéòEW•v/^¼òO­:ö]§o½kï6Õ$ÅÀàtÓ^FÍOWÓ&´ =Ê\ª6è­¢É0ãýë’íΦ5­6ƒOKx`|£îöŽs×O¥vͬÚowa§Ekm4;ZH°$äFìdŸ Ö£yÙ¸4‹+#K24hÑ£6FÚêÍNÃË)f ¾ì~µÉhö:Æ—dñ#¢ÜJá›f Ç:W }œXêQ}öòþiI÷w´¶F›vÜõÆá^yÙË;‡2ë³j}íÄ‹¶Þ)÷ÇüÇ“ðÅyæô½á¶Í™ueDQy¨½ÕÁ8KX2Ç㎠v§Ôw5¶Ÿ „Æé¸ot–ƒ³ý·ï-m]x!HyzòyúÔ#[Ôõ5dÒôÙ-ÿê.[d`yçŒü+…ÙÕ¥äÂ=œ†9Lšä×’¤ˆ>¹5m5-6Ê.âß`8©ørjÂiŽÙÕõI®È<ÇoìF?ê<Ÿ†*W»Òt¸;K{eaËŽ\üMW°©vVHu»ÀZo‰&ügÜOÏë¡ið³I}q6¡&rL­±=ûG'âk6^ÒKtE®›m$ó¹ÂÇv£]´÷¿ÿ5uÓ"nªþÔ›Ò?Z»ò;4î{AaahËl"XÓÙÛ ÷V=¥Ôµ9š2ÖIrq•^Æ´âìæ…`«<æ[¢ æwGý#ýèY°LjÈø¬chÞ(šðˆVÿáëé—:–ªÏ%"ˆéX‘Ž•©¤[išD¡ílÖYI,NXùIÅ`Ýkw›¡Òážá{2;÷®º&±{üK›¸á=UcË0øÖªû%úFî£Ú‹.æF`:1Ÿ,VUƹy¨2Åc ³Œgvñò«–]žÒlbïnöI'Rdö³ðéE>¹c½Õ²4ÏÈTׂÓ}‡¥Xêéj-¡ŸRÅ Œ»õÉö²1Éð¨²Ö³¼wú”pÂÅ7c~©èsååZPy‡ÞV(´Ø£BL·Ä…?:Ãí6“yª]©‚éõ)eˆ‰&Æ<0<…Tö¤qÝ¢†[~Ó\GhI²žìŒ•*FAõ¨>îÎÄýåFPŸß[í:^h÷BÂå•JF¡]Fw uçåð©[Y#B-ß;Fv8ö¾µè]#@@Ò’@è¦TR§nüÎ1ý+Af‰ìâRŸýê/¼m•ž(­ÁÓ}RÇŸ 5‹'ÙV÷æ´"Ôdv¢Úò<¸úÔ2_]üVß°:l$Rp 1ç#ÇJ³÷[ŒÿÈOûFj?¼Ü9JŸOw5 —$1ÿ‹q€sõÅ6  ¢ XUW?áÓEotÇhúD%g ¶i]GƒEÏ–%¦“'¦`Scc÷W ÄwŠ dð:Ò"㨗Ù<޵ ÷d㾜g‚2~”y_ø£Ç#ÿóJGßn;åày©æ‰ÒXwl*sÁôëO ) ;`“æ‚òÌrFð2¸é)¶ßëU³?e[ƺû$·R\¬RÆ¥ŽxÈcîåz²õ¯ý/ÙTѤ&ÝJ\’8ü ÐøŠö•5¨ôaí’%¨óD¦¨ ÂÙ§Pªó’(óÅGºzóK5þ)n $‘n*=Ô%¨@‹PLO4Ù  4ŨI¡cŘùГJ–9ªÏ ¥Hÿ|Òªp!ÅF‘§ÝëPË š}ÕI4@ùÕ `ñšprhG Mœ Pinâ¡/Å1o €‘ÞƒuGšaš¤&ÜiÃsQçKw4)>êàþÒõ[=K°šÂ[¹&ÚeŠ@|÷}ÇκíMîFq÷@ ÀŒ÷~üq^Ú+NQû·¶Äÿ3üèï˜çë^|Ù8ÒöuÇÙÐ[L¶_²¬·[†‘ w rßy#&¾}ìž§}¨]Ì×w’¯xÀlHÁ<(¯nÒ§’OÙXÊn(ãiÚ3½ ÉHò;¾•á=Ôí༺h,Þy;¢p9-åÎ*dZÿѸ=Û= DÐôˆ÷­¿r “·xß^ÀVM÷hœº›¹‘“>Ìa°>k:ËI¿ÖåÝ5ØvÛ°çjõé]]ž™Ù½ Ý'»hf•æ &|3âß:ótv»9Hn5½VG[ka`‘¾vظUÛ^Ïip¸¸×5)oä'˜-ÉUt-ý)kݬ‚òeK3ß&v¬Vñ´úø¡ §hu;Š‹e>sð⶯ôNŽ¢=vËLµ{m.Ê (ñɉ}¯ú›¯Æ±´ÒÝ]˜lk¹ÉURÿ—O}_‹²Z=”"mR~òBA/<¼Ú8Å4¢Ñ,£xôá * ¡sð¬Úð¬[òc^ÚkWCuýÄvPä‘mÎ?JVö¸•bïù“çà:•Z²}wRf™¬#HHâIý…ǘÏ'à*Üž·%›S½’éØÿɇØLzž§æ*Ýv(Ï:¬9) ™%ÆQI'àY†=zuY#,pÍpØ'à9ü«fg¦ÂEºÛÚŒÝÆ€ï=Oưu>ÔZÄq+K&yÉÏ¥T¯¢—í»? ÏÞê7³Þ•(u>Ÿh¤úvŸ- ·¶ BäzžµÍ,ý¡½BÑÛ XÀyÛnG»¯ÒžÛIˆÊ õÕÍëåÆv§Ï¯Ò¥{*ßE­[YŠæ),ÚBVPT¤c,sǼÔª¼¿‹O´)kwc 6Åf+IÇøG qZ‘Ëi§©Ž Hl³ÁrøóÉäõ¬ZóM´Ñ¦{+©.5NHWy#9'К«²3‹× Ém ÷œ´¬áú ,n¦ ó¨7Q %Í,ñQæ›4 dÒÍ4Ù@`æ‘4 ÒÍæ•6iU4s üédPf‘>µlM;Ta½in=h •¼éQ©§ ¤ô¡X4ÀsT¢§Å8Sš=‡¡Ç.3E·šfSÖ€lŠó.Þé e¬›€1m{’8YÄÉ"Žnož¼ð>5'd{'Û]yâÇB•-³Ÿ¼^žâyå¹aþkÐm>ÍmÌ@ö«´óʨûM:=‘C#ŽG¸ Ì¥Z³qœ=Þ¥£ØÛ¹¼ÕåÔ'èb@AåƒãóFê.Òj½°Ñe²´`3…SêõøWªI?bûh_FÒìmæQÄ¢3<ß'å^uÚ>Ú[ÝÞ=Ì÷-;±À ϸb³f#.N«ª¼ìN VùÇÄõüªÊ-†–Í÷8b¶«0Üÿ>OÖ£ýá®_K].H‘ÎÙJñççRAÙ~ø÷ºÆ¢îÓ¹éïjÞü™è¡u«Æîfyä'0rI÷ ÓÓôŽÐj1÷¢Ùl =åÃmù(úVöŸk¦i±Ýú}½¢c&Y9sïñùš¯«ö£I´'º’òCøQOoкìh;%`Û¦ºš]VeÌkìDóÇ_GqEÙë™_I†ÞÞ¹¶)…bu=[ ›Q ¬¾Ñ$cË>•ÉØÊm-ž2¤Û¸$bº BÛO–Ö`—M.M¨Q¼ŸZæa¶ž&ô ÏŸ—5è…VŽ3»5>ô$ Ê¤Ž¼½ JŒÙ1‚ÞYý*µ´}òï8/JšÚûÖãT䟭%Cз« qpœ•Žô *xͱ;;>q­YA‚’Et<åP¶T†i&Ä‹ìõÀàQ}âí Â9çœ qÜV/¾·™ÀùTñÚ³!·¸8=LØ&‚Ês|Ãþ\ÙxÒ~v—ÊЗÖ¬IBÊlܺø›Ž)¢!w 6<ž,Íš½Jó /Þ#{Ži¡’p0/"PzáȫӸÏîË`ze—Ÿ©¡N͹Y§Áj”‹¼ƒ#¾¾‘ü¾:BhUC ¢®²AÏ<ÐL@ÄV ç<*ÿJ–æK²›]mˆÈ'j/‡¸T!ØþÏzŒßþ0hP­ËˆŒ®»¼Á†1ëÓã_l«WÀ=‘×ãìïkì5"E{{ˆæ%c€Àà…}ëgsÕ¬WVò,Ì‚HÜte# ü«q3"Øj-Õj}Ù5º2KºŸuGš@Ô€ÒÍÍ>ióCãGƒBˆh³Å0SN΀|ÒÍ6Úpîv•™Âüøzד}¢[Þ?hâžö饊EXã2…íù »aÛÎÒéšpÑa¿-¤–þ%³ e#vã‚FAÉ'ÖÖ-á×ôéí••¤Ú%üzd—ã^^<'kÉéO”i˜&ùmòÖòÛ,L8DA}1V,´ÎÐêJ,¤X‰â[ƒÝ¨x<Ÿ…GØ ›[9Ö+•ŽÖxœ™.‘ž3áÎ8®ƒXÖtÙ½–ær9Œ¶ïöªÝ:EI5dÚ‡o2~ý׿󆷱ˆœ-Çý«»ìÖ¥ÙÝV}'³öòõ[›ÏâKïŠàôÛëûû䋳,÷NWÚrœêÙÀÕé¿gšî£qÞv“[ŽÒ<ûQ[ ÌGúäkœÚÿ“6¿éoþÑÔ+=æ©!'$‘À€sX×ZÏj»H÷‘wÜ~÷6cÞÿJÜýÅÙ>ËÄee—C¥ÅÐïdÏž[…øYzçm£…v\Þ¬œr«œLÖ¾‘¦Ò2eì­ÓJXÖÌ’7ã†ÍNß‹·_•hiúN£áâ´·ŠEÃo‘·7¿œÖ4ºî±©ÄÉ¥éï牤<Æy?YÃEÔî¦-¨jLsÂÇÀÏå[£7½:÷hìâb¦bÀôE*ÍmOV»@ºuœqEŒ÷·»J⵸¶ÖžÚgï9v6Ñ€Ã5Þv–ÏP¼ÖUŽœÐ÷Ñf8ÄÊ@Ž|r=¦i:‚ÚÜF²KÝ«³g#>>úïìã%DÉXm¢ŽìÊyééÓ¥)1¹"µ;\äý* Ìr’™Êÿ…<ÑwE×k] œc­ D¦ ç2\H_?*pZ?d\LP›úTFÚÓ¤mØÿ.qõ¤ßpHóÀþ´ OÆ«“#1>r$ ¥X‡ÎBj“OÞ{§—Ÿ%25¹P»ä$ø?¥*ÞZ#ȬǸ¨Áýkí¿°=]µŸ²­WüvÑ}Мçwwìƒò¾-ºHdˆ¢4áº{oÀÇN+êÏÙg´éªv(vwîû%ÑÑCLbmîì1Æ:xæµ³3=ŒQŒÐR/Jès…8¤ic5âˆSš,q@8Ô¨3@¢¤\Уã¦" Ó1ðæ­PA@ÄÔ¤f›nh”š‘E ÍL‰ç@A·Ò•X(3J­š9$O Qì£\¼Q¯&¡Ì˜,9©öóŠOG„*h•xéSwGÊœFHéT¯YâcÉÅK±n|* *í犕UŸ»b—rE T -¹ð©Q0:Q„ó¡hˆ ò¯ûpû'ìe†…q­i–wš„“w[—eç$û,O\~uïÒ£–<*×ý¾/wØ“—k…,qÔíjÆOòj=žEØÙûGíOatÝr]{Q´»ºWgPˆè0죃Ð:§ö‡öY¨}évšŒ©ÕmØË÷ÑAÔ)ö›>?*÷ß± öU /ÿë“óv5ÛËÃÙN³q<2ĈØ^£øŠ3ðÍfQ¸›Œš‘ñol4Ö’uÔm%G:æLxÿ¥_ì-–†ÒwšŒ_z*ü˜E>£Æ¢ÖoXl`ŒM1¹…îñž}EW·ìÜ÷R™ïu‡w; Rß âÚQÛ:Ó½®³ìþ–Õ½ìQ*˜ã‡Ÿ/+*ﶢפH4>v‹ÌFÄÿ¸ÖWg4þÏèЛ—µŠêo .Hr¢ô>§Úë»·î`ƒ¾e ,kŒÿÚ+‚I½#®ü–[GÔo:浃· ¯´Aò.xúUQg´‰¹%^’HÛß>óÓኢÖúíü¹º¹ŠÊ"?âoûG3V¬ôMÖR÷÷“Y®‘Ÿô®Ï5¤ëÉ›,Zö‚mF»hzMæ¥6pDQ–Ç©Åk[vg´÷ާWÔ´í &?òÔýâ‚§3E¹EÇsE#OBßµò´ïm§X›§u ¬qŸdŸ­Mø4¨ítÞÃö3L{ÔÒóZ| ~ðœG>b4ëÿViv‡µi¦Ú­®˜-l-1ìÅgE?/Ò¹;x5‹Éº­ìvÜç¹CÞHÞÿ ’MÍäÛ“ÏídÉu&BûÔqô©[ ™÷}¦»»•ÖΧ“Ço$zŸìU|ê*µåÊÁÏáümò}kRòÞ nSʵGÀU1Û 6Èw6Ÿ%ÍÆ1¾(òsêzÖ’°ß²]?GK^{y¹ä=ψ÷V–¡o¤Úi[¥ÚAq"˜@>êÃfíf¦»æX´ø_ù¤mο}VƒDÒmYof¹Õ§U'`l.G ýM:3nŠÝ£Õ­í¬!]ÃK{f+½qŽzúשê¾lžûUhÚxd ÚZ<ƒàz{ý+¸·ŽþóO>í ­†ÂZÐtô9é@^+;«#@Ùaàâ¾…ýï4ølõ]6y!]NiHƒÞ¼ay<`S_8<“ÆÜ±`â'é³f§4?lúB† ­,-þ(ÛõÅU ö³ÕO•H¨MYŒÑ…P+¥œè¬±fº©Æ)( û1H-JiT°0qD5?àfœŠâ…¥UêÀ{è>t€ÍŠÇáN¥Ï‚¯Ö€)£– {Í6ÜŽXŸN”jª½B‚§Ÿeúô©@sÔ…÷sHQ-=Úø–Ïú*’•,§"y÷QÆx¦ÊGóÿÞjX­À<—?õš¦ #BMN#éšâAâÿ÷˜"y·ýçúÔ(Ýß•Š¥Ø˜êß÷b‹æß÷ ÄÍNª¨ŠŽ»˜|iŽsøÞ€˜ô¦â 9ÿÌo¥3L¬OéUrFj)& v(Üç þµ\´²qŒüd§þ^úxãØ0$rO$œdý(BxÆÒYŽç=Oè+Ì?i ];w3FL¤¼W¥…oüÇúJò/Úm™t :=Ìs$ŒsŒ ýkžOòÍÃýŸØÊw?eÝž\çuš¿\þ,·ëR}­À.¾Îu¨ÙK¢Û÷Ž¡s•R† Ô®4­Zà¢ÄÐýÙNÕñéÉù k&ÖÞ.íR;X<ÎÞ?:¬Ö¶V=«¹Ó®n²9ùW™Æ´z›Ù¥i§ÙÅ*=ýÓݱ9(¾Ê|úÖ¤—ö61wqEy*€a[iZä¹–W[fnvîo\V–› BÒ¯zíu)9þ! ϪôÃHÒü ~[‰{«;v—ž Œ‰ð«ÚëW¶Ä½ÌVj[G¶íòéó®ÛKìÍ´vÂêòx¡DàÃçÀ­=*[9ÖX;9¦OªÜ.AhàÊêÄ`sî®o"F”}œn•ÙBYn.cšãÄ5ËmOûF3õ­™b·µ·½êÅ9îmÀEúrk¯³ìjõh’MS´Òaêb{×Ç‘äïÉ­Ë^ÅöC@_¼½›jW ;q&O˜NéXù/£\hóKkÉZ2ºV“ur©Õ¢C±ÔÇÙYò[ë—êàÝÛÙ*€Lií±¾tÝ¿íZ÷¢.üPa#_e@W sÚ˜n¥Q½Á@„à°f·dz'ýÓb‹Û‰§=[¼|ÿJà|êÌW6V«Ý[$P¨è0ÐV ój7o‹KNy ·h÷Õ‹NÍj÷L^îæÞÎJlŸÒ´ÿ$ýêºìJ… ÂÍ 8*O²ÃÂ²Ž³wq.Ëç™úŒmAé“ÅoFÓÓtên¤êZråT:¦³co£Qü£ŒÕµàS*Û[v­]ß­…³¾;¸@,IõÏÏ£Ées,’j:}¿²Ê†I} `àqχCZ£]¿ºC`ÏŸÅ.3ÿw_…cÏØÝw[ÕÙ‘! ÉžN˨þY‰-lß}’c XF Å;E9ŒNÍ]¾»{ké­fƒÛŽCa¸È8­Eh-£VKg·ó?C^›8Ñ WQ¦ (Éçž•fÚÎúV=ÜyÉçÙÍmw–ùæÌ9n¤¸8úÔ¿}dQ!U:>”±TcÉ£ê$òø ’ ñøiB3ùV¤ºƒ³•Ì Ÿ2¥B/? ‘Ï>ÉüêlQÐ&Ü»®‡¹FhäÐ@;Œò1ñ©Mâ7&U={¿÷©ö0ØÛÿÑÉüêl£[è¸ÊçŒÏ_¸l6ž_¯$?Jxî÷á_RaÿôZ#,gðê®Ëž¢l[é¶‘ùeÀólƒL`³c‘ j|r:Ã1÷û‡ Ñ–,~”šÊÌ“ÿyÉỿö h;K{C.-Ï Šô/Ùͬ->Ùt´€âBò§N9ÁÁ® ßDµ0;ýâåÛÈ0kKì²s¥öÿB»µi Ç}#oâ]Àqæ gß9¥º ÃÆ„•a?!]NdåÔu P÷©þ }Æ¢F< ÿÒ@§+~Üh ;Áäß#H¹ÿøâ‡u&j%ÒfcÕñî¨sV€|É'Þi.@G“N ¡,”,ÔkÅ& $V£^|j%©€2Húf¤QP©-øŸSÀ©3øÎãåáò¡J·ºµ…œÝÌò¾üg ?ÔJ®´lNQ¶ƒáŠTÙLB 7þ[ý?­?xßùOôþ´2éWª‰ùx?#ýh…Äcñ6ÃþqΣïÿ)¾cúÒïÿ-¾cúÐ… # ‚<é·Õc1$Ú‚|ÈZ]Êþ9ùë@X/Qˆ³€àŸ%äü… ÛÆOÿ,3þ‘Vâ·sÀ‰Ç€¬Wüíoý:þTqÛ–ÃJK‘ÈÏAîz;~yþUe ÿÚie£8ÇŽ´x­ ¢Pz?ý¦¢Ø¹á_þÃKU ^%ûSÎ#´ÓaÇ;$n¾é^ðUAèßöšùÃö«¾Y»Ka§F¬;›PXFK1àyÖ2¿©¨-žñÙ‹^ã³zdÿ—iü Ôî8Í=°HíãEW¨Ø>^ê˜:ÿ°ÿJÙ„>Ý;"{)öŸ©AZÝ¥ûÜ ãù_Úøàäzâ‚ÖâèiñµÔñÅ"g2KžG†<ûW¤þÛ:ˮ頌È!¸¶6Íœà:1o¨o¡¯ìÕ¨Ö/,í¯¾ór½òÇ3É&U·P<8®–uÆÙ°Ú¬w ]=.u Ë`,h_qñÀ|Mv—ìÏl¯Üw¦'bØyˆ÷Çå[Úmÿdû)³Ò­£I ›;{Û¯Ö¯ SYד»Ñ4û‰œ‰\ú±Àùâ¼sÉèôÆ%í;²Ý”ÑÐ>©w.§62~÷&ñŸô+töÏHÒ­1¡@R¡€W=gØ>Ó\2É{}o¦†9lþP=:*ŸiÚ}öcOquªÃ>« }ÆkÙZ@ª úåÛ³{£/QûRK“Ýh¶7šœÙ­¼EÀ>¸Î+{O´.аšê}"ëß˹ñþ•ñ÷×§¶¯ éöÅ~ñomÀŠ~B¹«ŽÒjv·ììwª‡÷XŽÑï~ƒâkkF{8Vû8·y»íZúâíüƒl_^*ÚvoMµp`²T*«“æzšëGg;CŸ½ýÛIŒK/!õÚ§6­ NÉX"*ÜÏ{©0Ñi;¤Ï¹1ò$ÕR±G©-½•€ßÏP\¹÷I¬¡¢ö·W >›¥Éknñ.ŸºãÏçä+Ùá‹NÒ¡Ä_r²SÆ"@8õ#©÷“\ßh»YÙ«BÆâÿïR(;c,Ϫ%ž{7`J¹íiâE<÷VkŸ†öþ•FÂÓ³ö׬šfÒ…?üÅËoŽ>•­ª^Ϭ\wúofî£ûJ™÷¶=ÕS÷]À\j:¥Žã•Ž$ïŸzsך_‚R!ÖRÚxÀ71+#‰@Ç´:r<¾=+µý´½´’k-$E@Žî}¹gëâ #áZ—iÖѼëmßʪJýâNð±Çø©yclma¼í¡±T#Œ*”Ï$(8Ít…Y$yÅîÃ'ÞoBGq.YÚQí9Ï^ha‹½*âe1l$s…Ç¥]íž¡:ßil€@{Â7çÇ‚=Ý+";(– òJÌôSìuz¢í$»ãÞ}¸ÎPj)3ƒ½yœÕ…KªÏsQ©†<¾Ôãñz Ñ:!€£‘½ˆó!sÅZoºp'f<ž:ý*(îäa…M-Õ°á™Ç†8ÍÌ‘Û-¥n:îÅ8!b lÎvõgªñ^ì]29‹&à1.eö|( ±!DpƬìš•î¦g ^$#¨AY~ÁÜþyéQMt$rÀŒyRˆÍĸ›9Žz’)3—lÉ6ìx*ÿ½d[^mS‚ΦF–k¼Øè½jQlÖ·”¡Ç"޾ÉåQéÒÜ[v¢ÓP‚í£–ã‘d=ARäU­Ü‘‰&>ÃcSE,¶7öÓBÂM‡$úwt JsBUGAqÅ7=°üþtàD¨Hé@·àÃâ´¿‰þ?± Þ7ÝX.OPrÞ1°ùQ©9Ô¶"aAcè*xí\øÏÄÔ²ÑE6±Àe'ÐÔƒ€ Jºlâ?Û#Àóô¢ª8H¶üqùT²ÑPE! =94k¦ÏÅ\¬8ÞãÝþù¦û± •lŸ64±D*F=•'è)¹9-@*cŽSñÅ#ç ÷B‘„Lr€ûù¥VB r¬úiRÊqƒ½ÇUùp%ð+ò©Ö2jÕ½©'ðš¶bŠ!eÏUùT±Á3p6ü«R!Îê¹ ®*XâfCg1_ä©ÒCvü«\  QíÁÀëRËEkk2§™÷Uĉ±Æß•çÊ‹$P£ÙGòü¨$yp gÝDò*»1ë@DÂByeù½Þ å?íÿz•›¡s‘T‡Œë´í™Úû½JÚ¼éÌû~èçØ(¼¾*|N>µæßj£¶ínt»›Hå%’Þ²¦â럑ϯnígbPo½ÒaïG%í‰äg©ŒŸÿwåå^1®X5ž±ÀŒ#C*¼KÜçdŠÀŽFÏO…xæçöèï{GÔ#½Çâ_ûÞˆ ?Æ¿öÿ½pghV½¡ÆŸ©ˆìõE;@ä$Þ«ž‡ü§áŸATo*õÆJJÑŦ»<Óö‘ìêvƒì“V.7\iñýòÝ”U“ñ| –¯¾Ìm^û´ðisß¶Ÿou2Æfn!‰ÇŸz×è~¥cþsc0=ÝÄ/ãÉó¯Îó.££vº{g¶“¾µ™£1mÁGVê|ŽEsÊ´ÍãtϦ´ÎÌv'B…êD¿¼NL—luã Œ•kÝv§G±µ.‘#Œp8XñååŠùçI´íWh#¹¼:•´„² Ü란ø…wÝ›ìv¤À—záK¹ø}÷®Xgý'ÙúWÎiE×löÝ콫ý¨^_9‡³Ösß8ö"Õ*§ceÛ®ÐI¶ÿQM&9=Ð.ÞîpùÔšßn{=§J#²•e›Xí×q÷qX²ö˶W¥ Ñôv·I¸) G—ìki6¶a´w`û;a!’þ7Õe³ßɽí>ÈùWE©v‡CÓmV%Ô-"}•Da…LJW–GÙ>Òß¶þÐvª;xz´peÙ½pÊ´¬´nÊi’º|š„ÉÈ’öMÿ%á~”â‹eíKíÌÝ4¸®/§ÎC v'Ë8«j]³ÔNN“›uk»€‡ß±rß0+>ç[¼’RÅel<#ÂÅa\öšÒÖç»ýá$Óã `œü8¦†kCŸVí-ìÁ¹0ÙÆ#øbÇò¬ˆpiXýÙ¤F޹"âvï$Ïú›§Ã Õ×iõ!;@¸ŒŽòe+ôëô®oQÓ/c®¹u9‘¿ð¢ýǟʪֈÍ_´…}îñJŸåVàü+2]ZòêF·Ó´‰¥|pÛ6)õç­…½›n‚ßÌw1ÿ©¹¨u^Ôj1ŠŠyŸ~k¢‰¯lµ„‰¦Ôî>èŠ2c‚íÿqÂü+޾¸·ºw[Iäü>ѸǴÙÏLàtúšÖÔõC|1{«ã„œúu¬{K[›eY­ ”¤¬C³¡UñÀÉUÒ1£›1n¥¹·±"2#S ʨ<œrz{ª´WR’º·# ÅK{ÐÈÆä”BÄ+AÁ¨âŸ{W,œ^…ÑÅö.IȇæjM—oÔ.sÏSV¡Ý#`(Éð-ÖŠLÂÝÜ®ªP¤qVÉEAÆ@3(Ç-?ÝdÞzØñÀ©ÃD¤°— yQs1+ÈTÿ…  Ú¦ÜÉ3žzf”°Ä u{DÖÅ¥¬q¦Æy†2ä((# œõ.üÅg–ËFÔöëÆýê¼ÊT÷S*¾J£­[CX½ôyðF€hìZ–y+ó…KìÿJ®÷©v÷—3ú †[ˆ? BØëí9'éB›¢/%̤Ædñ¬æ–+U dGcÔ)éëš« £¼ ¶ñ×ÚP:»vâÅÄh Äo ¥ûKöÕ-¯¾Èô›Øî—¸¶…¡‘¦=›³“’0ùsÅtðvDzs\´º;È0/S¯—$f¼+ìW±·h_b›µ×&ÐáƒT2H÷™Çv=–Ég.•¼~ÁûÙ^É™ZúûUÕïfŠi¤˜À±îa“±NÕÜÇq=<*òÑš^Ov…!UPèÃ*Ê=ã5'Ý¢'¶{ØŠ¯ØŽÇé½’ÑF“¦=ì¶Û˨¹˜9RzãÀñÆ+£Š ÝVÉFJX“Ê;°ôž*u´˜ˆ¨æ´û€Ü¶ÀS‹h³’ ÿ¨Ô²ÑJ>ÖÓæÿµNÑg±æØþ¹«A08f*pÌ|¨ ‚3´¤þf¤X£Âð‹h¦Äcùqë‚)ŸË'?ê͘ ¼Sàø9øŠ^Þ?”ü1@0AR*B7x¨ø[±ÕXPàyR¨»ÑþoûM* Ë†ÍjÊDª¤ñÒŽ5dõɬ”†I0N),„Œ Œ“ÐÕˆ¡sÖ„KñÆ*HÔùQmÆ1Ö¤^ 0\ öx5.sÔT¤¶jÎx§2Ï'š2…EГÅrÞ¯ìb™Ž[ cŠù‡_}GPý¡fÐm¥Cõëlj2UQ½®?Ó_V¤`sã_.v3n¡ûT$Ç$-åä û’\W,Šé3xõl›µ=‘¹²¸’)£{[¸Æìg!±üÈzîéãŠê>ÌþÔfÒž-¶“±L„¶¿|£ÊcŸý_?:ösG°ÖlÚÓP‡¼Cʰ8d>j| xÚ`nt¨å3–žÑß1]¨À à~Ç^‡é\ebwŽŠJz‘ï*Ë"«ÆÁ•†UÈ#ξ/ý§µ[};ísVkM?7bïZ~T¿v¼å·o_ôϲÎÞj=Ž“÷.¼³]hæ~Yí2p8ñCä:s*æ¾Þ¢ìž«ÚíOZµÔ´©¦š&7 €@ G'°¿ZܲÆQ±8ÈÃìÎÚCHìíô+˜ÕåšIZY‰Ç]½»‚*ÛöI’ä~ÿí¯«:knØc÷äã×4'_²Ðt+d“VŠxÚ1÷d„–‘¸ò<ükÕ»K«_{v–2D­ÿ‹pÛ~~•ä‚}äÑÛ\¿d4ˆ„Vv ÁØvîüNy5•qÛM ÊÐǧµ´$“.ß3ýkÏ%Òõ=^Q.¡|Î3í(8P?¿JÓƒDìæši¤ŽiùCnÉô®œR3lÔ=°º¼%tû›‡#y?ïWìtþÚê@´²Ûi°°Ü]ŽHJÍÿâÍ?O·1ÃÆ:œŸ…V~Ùë:‚ˆl,î%CìŽâ3!>›¹«Å‹=Eû9ÒØÇ.³}y©;`í2”SÿJóŠî¬¬û3Ù»s,6}˜QÁÚ7œzœšòžÈö_íîE‘¡e£Œ u ÷:{‘NI÷×oÙE¦¡†ÖûCªßù¤`ãÁ?Zæè¦l>×`I%´±Ž)p]åÀù*á#º×µÙÞm;Iºœ·*Ð[O‹·kßt^Ãv/@A÷ Ð̇+#ŽúLùîlŸ–*Kýb BĦr2¸q·Ðÿf´¥é³û;íæ«q‰c´Óãa¸´³÷»}=œŒÕ´û-°°MwU’òR}¤‰ö¯'Èsõ¯CÖµû‹×x!ï'u80Ú©‘‡¼.kž½³Ö&ÀX¢±n»®¤€ÿJäƒïÅ^lq0d±ÐtT1iúdHÇzÇÿ¨ž~U­ëÖv62 äK—#þZdî«Ú½ž‘ ÖÍgX½» ÷˳ôÉðñêEb `Ô$¾Òt­ÚÆÔ(M S!N92HÏ¡¢üƒŠÕoSZŒÄ°­¸Lº·,Iúb±b³XXâGçÓÛö³KÒl»>ÃM¹W¼ÜðAlŒóí­qZY•.KÏí&ÓøÉÆs^¸;Z<ó[ÙnÖÁ¤˜¬{–NqW£Ðîÿvž¤Œæ¬­Û Í”j?ò£9üÓIp¤âKÉ‹6íLsçVÙDÐY¼Q…=Ҩ䀕8N%Î:€@œ&n{¦Ï S´qlNîPXš¢Æc¨ü@ÿ‹"«¸·W;¤þóò¢Vˆ ¦0rx'¥Ì~Єc>ÑÀéM‹E ZÔ£22‚8Î ¨{µe —|6F~µ²ÏxÅ¢XÕ¼ª'¹‰_ "ŒtéƒT†;[HªXC3ð6‘J”nÎLy[v÷·˜£yº”\þŸ•YT¸Töm'QË!Qõ¥Š3m¬îÜ16Ž‹·€_4ñ^Gl!6ì8ö‡âùÖ‡ÞfQ•T“ž]AÝœÔW7׋lÆ7·O$œ°óàñŠlU\~Æ:uŇÙDóJ%Þ£$‘€N@ ªs땯Ÿ{rì;s¬91ê×׉š¾“ý»ù~Çb–â]åïf*<aFÈ×Íÿjh ûFímÕî±ÿ÷Z£WPìû¾ÌæÞ6 >UeXtÅUÒI¤ÚH?šošŠ-BäÚ@²ˆ÷ƒ"«rPN3ÍhÁo>”õ^Úê „-ªÀuå}㤎E‘CÆÊêy § ÕL“M¸P»ÆâN­Dr[=1p)w‹Ž¢«°ÏJŽAŒ Ð$˜æ£yÆ0Fj €i˜xÐFèz ÐTà pX}TAÎj`Þ´»0á\çÔ ŽK©>ìSgžh·€ 45Ú=^{}HÃÀTÁñëJ¸îÒë–ñjò™¦ Òà:dãò¥^Id•èõÇkg«*Qà(wÒÝ^£ÊAEÅF  cþ**@1Í 0§qÅ,@ìhT–êh”Ž´ Þ´”Tƒ–ɦ\ç¥N)Í !T»tQ“_,}€#j_nw绵¸›>ö ÿÝ_Kö–àZvoSºÝŽêÒWϹ ¯¿d轸×/:÷V<ÿª@û+”¿ÒFãÓ>“#ÂE4M ñ¬‘ºídaAê£læ¡}Û«©Ìò®ÝýžÜÛ¤·Ý—^ò7âK&äŸä>#ü§áå^5ÛnÅXêV,mÖý^ì ÇSƒÈ÷tø××#w"»Æí¼K`©€J†Ÿ’Ù㊞GP»‰mâ’áãÇ1ªìîjK'²Æº(ÃØŽÍÙiK¯Mcix\“fž9l“Ǿ» }2ÎÜ[iö‰omášVלð‰i§ÍçÞ¥’=<¹]w€{ù?*©3öbéä…î^öbÙ`¦i>±sïÅy¿³ J–ÏGõæ£oGUuöƒ¡i’}Ö}bÖIW‘ŸiÉ­[.Ökºõ¼ri:&¢ð‘ÿ6àwHÞ£~=Ù®[³Ú®…¢·y§vu‰Á{[L;ŸWvÝšè¦í{JªÉí—¦f¸Ecè:滺8¤Ùu?MÞ®¥}š¥ ïú—`9ã͹]"Ú^öè·^w\¾ìŸP0¿J«ªö‚´› ©Ô޾eU=zõ¬ö¿ÑÚ†Œ¢CŸfy{ÝÃÀõ4«@£®öÎãÚ‚Á†¼(BGËÈj+ÚËçâ;±Þµ»Ÿ›Åzï» xÁÓ´Ý>ÌŽ,j1òÎj´¹µ™–êðo &úŒxQsö½’í ïkol:´—®ïˆ?J°—•`–)õÈ{Ù"+ÝEo쑜€\ÀgÖF©Ú‹yâ[i.ÉÌäÙ!mølàûüªÂërM:ÏŸ¨Lûq¸Ä@çÞ:UèÏfj,wÙÏs=Ôr eÜ"Ž6“…Æãï'§…p_G=ÑwÂsŽMt= Õ;SªÏ-…í©h÷…1à óçÉúÖL§Ç;wfppé^¬z[<ó{ÐV°£¹aŠ„‡ñ}x«b€¨ °ëáT¤¹dfÙ'×QÉw67UòÐÉ­x–ERü{#8xÃ2Óƒ·?gG4®¤>@ùTðé÷“ÒG2ƒÓØ=*Pð_’[HÀGW㓺CþÔ/l¸î R<‹·êh†–”>@伪µ<:dr/ðc†pHfl})ivT›z(=äl=˜"'9åA#éR®©*þcÏ—¶!ìøêÁàà÷,QNÝœ¸Â¹¬½V ùšÇÉgO‡#ðb½åü™#¼Áñð4kë®þô õk«h°\vòÆëR¹–íŸl|÷dœ†ö˜gÙãÀà‘‘Æ<«ùp·“’³Ðtk™ì{8uX´ô¼–ß(!CÝ— vx±Úç‚NAò±ö[ÚVÔîf´Ž-¶„3ÆÎJ¸°AY2‘â>B¾eÔû]«Ýê…õ}BêâÊI;© yAQŒûÎ;XR2E{—i4öìŒWz~w=¸‘Z¾GøxÈ#ƒá^¨NÛ-až<â&[ðû]i›-Šâ»o}©ÌÓ^Kq'Þ#€§åyÇÁMw‰WDì¤1Ö˜ƒš²TPíl€1DŽh°)@*¦·7Ýô¹äÎ ]£Þx«uÌ} _-®žªÏ…PÒ·¸ýêMñ‹f¢­ÑóÚ†­4ý°¹H$Â@«c“ùÒ®‡°=ƒ—¶ºeæ»4› —²(Éü\)ÏÌ‘ð¥^d¥à۞ϣ“-EŒPÅÓ&#ν'1Ôbh7 }àPƒNOj ÏZFAç@Kï¥éP™8P„›ÆŸ*’€½;=þjz[ÏZsßj×FÛìç]”6Ó÷7\óqú×~È0‡¾í=áϲ¶ñ/½ö€»6ÿeš¢©ö¦1F=}µ?5ÉþÈöÊ•Öï@ K¨ˆÆ|’5?ýõÍÿ´m?«=Ã4¶ääЩ×F`@Wöëq÷/²½ní-ÖwŠ8ÙQ†r{ÅÇ>êíÙ¸â¼gí_¶©¦þçÖmgµˆ¸•Ë%O€^£Àó\òIF;7¶ôx?fµ­Ršê]_F±¶´1âhÊÞapIøíW:u½ýß}5ÕÔ¡S.ѨŽ5ÌœŸ¨ ×µå“DÓ/ ª±1¨Né@ð9n¹ÏÖU¤ºó¤¡lm-ò?šffÉõËÒ¾l”Û¸Ò>„%/¶ÍùmmôØ{-ÉÝí0ÿ3œñï? ûA¨Ëµ³Hô;b¸˜ÆÂGqä2hñã=kšk~Ðܶé¯mÔŽUi1óÅU“³÷’{VìÿôÔõÍf?ÆWsvn_ÊuPT\˜èHY®¦¾q!º•‰opëSÏÚ‹[mýÕmö€" qùVböJÄÀd¸i_pá™Ø“ê1Zº_g´»U1ÅgjÞÏWLürk¿Ç£ƒÉ9vUƒ¶vó¢ i&i@Xb$ûzUë}gV¸ˆ%®›¨Ë;s¹ù¶1ó­-9­  â>U©kªØE†k›uåƒ Š¿£&\ÕË{6ÞÆ:±9ÇçDÒÚ[Æ{–b9Àó5,´T†™‹FCFØÈ€j}k#Z`ó+Y@àµ_Bd-\àí˹ E£Ï—Îeµ‚le°ÄxõçÖ±“qvvÃÿqàÖ~ñ`…3(Èðë\ëöZqjÐ:…rÆC’¤ž µ+Oi"w$¨ãñ)ü³\uíÌâúdT/†Àbx>½9¯ññFÚ>—ò³8%Gswš{¨ÚÅ”ôÁ9År/=ûaû©vþHsU’þåyh_çŠ5M¿‰\{ÇìÅcM#ÁŸ/ÊÓz þ!Î]®nšL†8Y»ÈÆHË7éS&©jNJƒŽ "uK!>ÐUT©È÷×C‡_ì&¯u¡ÞÛj–¯ ’=ûLnQ²r‡5NúYoõíC³Ë4„»y³“ùÕ{½Z0†;eÇ;EeÛÞ˜. ßy\ôp7•ƒ¥J{hŽ’Ñìs_iös˜¬%ºª„°Ã6€cÃ#Π¸»¹¸¸ŽÞ0Ê%Ʊ’wøãÇŸ,×®²žb÷0ÈÒ:‚ÎËѳœã'>\úÕ«nÛÛ[ßÅp¶×K`Ûa‘ gБ†+Àÿ‰'+hãÅžaªAo¦ýÖêrÑL q€oUÏQó£ì®£a­ ŒýâTîᓃ/Œï¸ljê<|Þã_+"¢ØßÇÀ÷jШÈ$øÅÔséŽ0+¯Ó-éBe¶qrbÜf|!LÚU³Á @ÏNyéZpp”RA¦Ž¯Q½³Šþòíîf’énahRIöŸ NWŒ‚:Mhö{¶„·öÚ_ÞdPû”DB® · 7uÏ9öŠøWšé—Ò,ÑÀ.PÌ…f ’Î9¹gŠØìþ­‰¯[^E M%¼»ÁŒ–Àñ#x#œq\¥‘Æ|ŒÞÏ·td:d=ùp¿ÅÊm;¼r2qS­ìOvÖªàʪ¨<€I#Ã¥xoÙ¿iuþÐÍ+XÜÅn–Ìeï%¶í«¬|FXgÞN|ô{YÚ‹4íD¶Ú†´öC|,­õ›`ª°øcqb3Î3œ|s'^‰žÏ¸ŸpxëU¬YZÒ6IZPTíÔæ¦Èó®åšÓ)†j€³ÍyÛ®¬-ô{ý¯í8[d¤óú׬ÜʰÀò·DRÇá^ ÛµnÑvß@ìû.~ñqßNøKuù5Ë+醭ž±öW£°E“.Ù;,£üïíŸÏ UÒ(Ú¡@ÀR®©R0R[‚9Í9¹$Õo†)`ùhËl´&'¥.õüx¨QH¢… ²NðJížzP*}­ÓЛ%ßE¿Ö¡Xä>b'ñâ–‹²Nó-&|i„^y¢î¼qKB˜ɧÉ>4]Ý!&–…3É?j;¾çìþÞß~Ó=êcà¬jÏìÁoÜ}•Å(ÿõ“ÉŸ<6ÏþÊæl š 7Bƒq ^iœ€ ~f½ ö³¿c½žR0Ò@Òÿß#7ë\ÓûÙÒªn¦wHƒ#4[A< ݘ¢=ƼíÚ };žÖêéñ¤i3Àœìôg‡¦z׳mQášóßÚÄê¿g7gvZ;™âI6œ0îãâ sç\²¨Ê;7Ô´|¥}Û}ç|útrF¸ÂÇs…a‚óÎxÏ…f[ö¢[ËÎêÎÒâW`Ha/»åšé4nÄEm=Õ´PDÑ;¯z’íN3žO–k¯’ºKFhu·‹vÅ*vPÃ^;„4Jäû<ÂK½b3˜ô˘Aá¾ðêƒÇüG#®ZIªÞ¡Aw¥[?øLûØâº)ô-,NÆYêDRT¾N}sšäµo»Xâkt´$’Î2)rè­We¤Òî&ɹí”T‹qú“Å^±Ò-UOÞµ»Ûž0"6þUÏÇÚyäÂ*—q Qž¾½j[ST2dYNùã.6ãæk_jÙ-öÚ.†[yµ¾ÅÞÎ0ßÕ~ÓMÑ¡”µÍÌÌ‘)†M̘ät51ºÊ©$ç×ÀWZ9¦o½Â å•Hã=àçåšïêŒ ‡$q’ÇJÃ{X°eàøš½d'´QJ%›‘\Û$ÍŸH‰'Ò¡K›y.ÙÞI6íÂÿók,<’¶3žN1SÄ“¯´-Ø6:ÔqMQ¨ÉÅÚ5ÐZLÛcŠ^Ÿ‰ÈéR›3iÉH¤Ïµ–cDz;Û¼‚ÚÏ@Ý(Ý¯Ý ï\ç<±5ÍbGG™Ëe«és .ËtGÈÊŽ:¡t.F¡ØÃ#ëÅM÷;†äœ`Žƒ9«Ã@!Fñ+Œ‘ñ­¤–‘ÎRr{&WtŒc·P§þYŒd…G2C,šr½n0~4ÍÙ‹Ü1#‚dÇåCˆB\“€Y‰ççTà>ÓÆ…YwuzV­Ü6¦ÙI·‰”ŠŒ@ÅP–æWb}¦ÁÛåÇûT’ÈïhNa4jÈM¯i–¿}³Q^ñ¾CΩëšDVò¢[1˜tê:ÖÆ¦»¥´àí}*®¶D÷ñÈ„þ ëYVƒ2¯´kÛkµµŠC(r6ûG*“÷®»a0·iåör6.¤c‘φ3[º´…uëg-¹cAŒ­rÝî²’¼`/w‚=y»ìRv¦)@žæ àû[«¹9ädü*î—«[O2„™•Ù¸ Àuè3Ò°µ y®6m?Š¡>—pb[©e)¸ŒVIz2à¢uÔÇ¢vcI‡I¾ºkÉ-ÌS—ˆwX8ÊsÃ×Ù#ÙëU{;Ú)ukëspÏuµV>ì W d¶p Éó9¯ÓáÖ¢‰ž×fÏ`Küœduòô¯Eû?“[ŒoÔÛMkhÑeÜFÀT’€{G=|+ŽLu´ôeÄú[ì>{©d“îír°†d¹ŽDc*H%I'kg^9žÀÖ¼³ìZúÚÛkªÙM§M" E㘠wdg'ÌxcÖ½AoìH¼·Àê{ÁŠï…ÔM% öÒ jõM.Æ]BÕvþ e®5].Þ3$ú…¬h²>ë·ûFíŠèó^[\G<Ð<…”ñ»ʹÙÃUÑ4ÎÊ]]jW© ö£vÒ°u#ÙÊŒãÏqø×ÊfÝF?³ÚŠ*UŠ;aÙŽs«@9ÇCý)W}™ÑhD§ÀQˆÖ¼ýªvŒÊhŸD€¹¢E|éqö“Úi¢îÅæÌ‚ /h ûJí@#\—Âã$óÒ¢Äý“æKÁôWÒ*+ç•ûLí;Äpx=*Ühzô§cÌÛ½øŸ²¬È÷ÀW¯‰ʼïí´Š’}£œäæ«´¾Òwœ\á@äuÍ/Èù—£è.(óóý§ëÛï8=9éJµ.РÚe ïŸ_‰û 22?l›ÀÚæ‹b¶ÆNL±¥{ÇÙµ¯ÜþÏ{=jG1é–á½ýÚçë_}¼ö–û´:õµÝÓÿa€1ŒgýþµìgÚF±m¦Áj$oàÆ±®Á@^UË.Lé<©EAð(†+Á$ûPÖJ¬àƒæ:|¨¿üN¿(Épcùø®¿örù‘ïYô®oí?L‹Zû<״ɧKdžÊAß9¡ ŸL^ZŸi·Ì™ynwŸüVnûu¬vKRÓ·LÂx ì3øðG¿§J’ÇJÛ4²¦Ò£ÃþÎ5]c²¥žÇK¼Óä–ìœ3¯Wdü|kÔu>Ëkº®šò_ö–ö>õ³ÝÃŒ™'ë^;o¡vÉ®bŸO°Ô­BÞOܼjŠIÝÇŸnµŸh#¯õûçó˜õóÆOé_72äí3èâ^Ö\ýœÚ.êÒ\Ës!#?:¥7d-¬-öˆ,Ö@3½a$ã=r+‘‘¯!wî5+Œ7h,ß2~µU…ÜÅýû·ø^W*=zÖcVÙZƒ¥Ø"ıÈÄDqj¤ÅÕË6éUz„dùäÖuµ´2ŒÈ·sð=—“‚}LmlÄÁšÊ(Ž=•VÎ>dšè›¾Œ¸Å.ɅΫy-¬®SÎÒ£0Ý3¼ÞY$žOy“ô ÚÂrÐÛÇÏãÚ¥©§Ôm#u݉3Ð V¶gE¸a•‹Þö‹´gj«¶ôÑAe<çꊈG!m3Š­«n¼ÌØ•Œš°u‹©"V‚Þä‚H,±õúqGhhš.Ï[¼X¼ïë?®qV!ìÖž¸2Ü_¸^p.~#šÎ‹QÖÆ+9ˆ>.Ê¿N·úèËMF¸Æé$–MGvUF€ìΑ+‰^ÞF rU®äy~5b÷JÒìlûÛmÎYä‘#âsœ/éY+{y ÄšÖ‘ἑðÛŠœê¶ѧ­O;)V+Q’sÆ 7ŸŽ+4Øfjû?¦A0¿ÕPÁÞ ‘Ç ‹Ó Œzšó¾×X,† 28˜M‡º~Á9>8"»Þß>¡¬i°EdodÛ&í×r(c@ôó¯8Öa›DµŽfiÉb8R>§­wÅáÙÇ)JÖÏ|J²´ËæªEXV}GxêªV7òïbaÝÓŽhÚæv'»…ÀÏøkÐq.Ú¿ü¥#ךœÉgt1¨ÿ61šË s!Üà:îlQ•mŠ=êrqõ .Iœbi}ò.ŒøìÔ1%ŸrD³ÊIþTP3ñªï ¶ÿ`HxËS°Ëox¹öI ×8æ€ß¶H @ªíAáæÔ1º®vD3Ó8«@·ëg ùÎxó£Yn&`!WqŸQC,‘åš÷í©Öè¶zT:j”îŸãùSÃÊ6⨬<@?Z’0î/´1’I8»’]„Òªã¦T²Œ7´äHP³'NxþÍXŠ6¶áì´Yy‚*ýêà ‡syóçð«6òn@‡•Ž'×9æ€Ò¸d¹µ…@$îÁϺ«êqíº·8௕hlßcfà‡¨õhÊËlHã ùŠˆõÛªÀ76øõ¢hš]Mür šŸR^÷Pµc×gÖŒ¡]Or’ ‘È=j]/RC4g²|êÔ.Zɦà"ù-m7ʤ/VÇÈU¨mZ+9?øX?Z ¯téÞ÷3&T"mö±ƒÝޏõçá].…„{žŽóƒ¸d‚|Èù×+}:ǨH3Ž2Bÿ¤r~u¡ܬHÍÔãÚ#¤pp|+Ç•»¦p–ÙÛØêR[NgpBÊJ!+Ôô#Ï»Ý[vÚÖ~¡û⎣qOo<œä“ÇZàôë™bºÝ…`’üð\þµØhŤK‰LŽœ† ì¶|qáî®ßÇ…ª8ÉÑØM°·-Bu&<œúÖ4sBçæ8Ç­hèéy¬ZZÿ2PO¸r~‚¾8¨·}¶‘½öŸrÚ_ÙµµŠ’'½eRVv¿sš‘žÚÒÚLç¼”¶Üqž•á§gÔµEI-µ4Eê þ-–ãó&€i·Fâk«–ñÊ@>•m4{¹7²j¹'£4Ewùž´é£_±Ú×Vìóm'?ZµC²ŒzL‚÷— Þ®?¦*gÒ4¸ÀÞI|äî°kV>Ï£_SNG„?Õ©Æ’ƒ êŒ29 Ÿ[)/LŠØHÖÖî¯ÊŽädŸ:– ³º‡`Q쀛@Ï…K‡eb÷÷,sà@ÇÃdè¶»7w®¾'¼)a¢6¼eTŒ[Ž:ß•UmBHçöÑmÔðqVŸBÑbÁ‘îÛwM×,?Z’ÛNÑ"B¢ÅeÏS)f?3š]“ë»6å#* ²ä“éž”/®#2ˆû1Ÿhcõ­§iœÇ¥Ú©ë–]ßI Z+ÐDqþÁ3v‘fOºJ„gË&±5ÝQ5Q¡…p‘ZR:޾êìe’8£’XXˆ”ùäŠÁ½7WÍÝ´k1BiÉÏÃÆ¢e£—ív§wq¦ÄñM<-á‡)ÔW)Ô· És‰ÀA¸¯ž…wº•¡~Ì‹‹˜Çáq7>z×9ñ®.iìåÓ®¡ŠÌ$Ê£käÚôcz8My³=ŒhKB±ã V¾ô¢1¿ñcšÍ¶…™ÛyuçmXû´AbXz±®Ôr,¼é&* ÿ1¥ml÷€X¨=UIü³Ek*B1U=z ?ÞWJ -Ä lb›ˆ4‹ƒÀ†P‡ùš<~u!Ó$†B%ƒðŽ Êª gÉ}vï¶Idoõh„SLIÜ ô¨]RØ<¤w—:|~C~@¢Ò-—3>§qÐ.Þ>µZÚÊ3“5ÐÏãó©cµµß“39ô9ãáQ襱mfîYOŽ×R3îÅ@¶6÷ätÈ®Cݤ*‘ÚÊçÀò~u'usÝøÝÔd…ãâj?@†(´×1¢ÛÊ3ÑžL•ˆmäU·µŠ@|HQùÒ1¸…VFµŒd|ªµÈt‹‹LƒÆÒ[#à*‹(êsÍ>°Œñ‚’¡@Æ2 X8ë€w üõ¬ûÆÍÔsHàÉ•# ѵ˜Šcžô0løT†Ý’†ÓbU?Ì<|*MP³-°‚Q˜qåýâ¡Ò¶™¿¼”døûªmHh”ø?õ¬—@ßûÝ´±¸lç'5+¡ûÜmísùÕ~#03 …=_ûÉ"*›FÁÀ=:Ð"®¯þé¹ù>\´‹‹)2E¿_EªÆÿz@ÍÆ@áþõ¡ox fœŸ ‚Œ6ÚþiK´iݨÈ^¤¨µ–?»ƒJKȆ„Ú:cúxb²µë©„[£lB‰‚˜ Y¶ pî2É#ôäç ò:·&y¥³®Ž[6x.d„«¹ÀÈÛƒïúxqS]’Rm£k†qåëãÖ±,nfº“ªûL-í^§5£§7Ýî6O@ÆI ÷Ö¸E}Ì5è×Ó®šEYŽX¬:f½'ì¢/½ê“ênI[Hö†ðËgôç^{h°á‘c*Àû@õæ½DUÐ>ËîoC%Ó»ƒãϲ£éŸzåJ4¼p+•ú9Y58/{]©jW:ÈåS<ázÈVEÜæ’D-¸¹+“áULа’ ȨmžWeemØ'9ò®øåKLÆGrlº,Ýý¡(løÒª²ÜÝE!H‚ºú7CåJ¯ÊÌ£¼ýÀl³6sŒøViïåwFÃ-Çjá•ÁÜ0¤ñɪ²ÜÊî#ÚÆA5ÆböCs,‹(@›v‰Åiì–Aí6ÙÀÀéQÅiC$«¾AÈ¡¼ßc¢Ã ÁøÖžú+-™{ˆ‘BÛG´}sÔQ%Ê“¹ †=[˜’eÆüí<`óš‚áÌw7az€*('£4mÍ$Ògc‚[ñ½&ÒHÈËu5Ž&=ÁPÛŠœòhåÕ²_ž•>7Ò*:+m«'x[ŸÃŽ*+ëG»s"ʱ¶0Ícýé™6«g<òzŠ»m|$ac©Æ IFQØvÊ·V0®â‚Ažœâ¢Ñ ‡WµE#sL `øî®.må`˜*B:ÔVvìºå¼É€.p<9ϾºG#ª‘bí¤ÈùŸ¶aãpJ%~ýk¨k{æxØ '¥rºÿø–y•²;¿k>YÿjÑÔ¯{Ä‘v¦ÀÁéš¶’F³neÖ¹ï\²°íÜËC\ƒÝĤn8éV¤¹[i¥w*¬¹Ø™àŒt÷³p›˜ŽHâ£a {'u±·?έ2; Â^Ä5Æ ÝŸ!Î>U¥#$Wòîê  uëãQÙÉÞ¸›\dwU‹ žÒð0Z–hî§ð-áxƒ`:G’0#ëTuI WÒ:¾íä‘ÓŠ—¿½`^+ íåX/€äœ]Ùç}—¬Ü>ÜDÀõ;N3Vn..!œH]”’Bî EˆÅ O/€Hò}~uçŽÒÚ)^Þ¤“£ã׃SÃb«’`V\îÿҷtígIÓìÒÖëEÓoW’Ò\DÃø||«É“ùzFá\–Ê„°Ðõ ­fî{­*V›º0Ù], ÐzùŒ5ÓÉÙíåpú¶½r ëûÉÏÅ ®__í5­Äm†º© ë„òŒg­SN×Þ¤†/¹®#¦<:VÓ>‚Ïfî£ØžÎ’Z)õÎy-6sïÀU;'¡A0#P¹'ÀßÖ²díV¨Û›îÈPt`ÜŸöªPv—Yœ{+ECüÆ\‘ðÅi;EY ÍûD@¹Ô™¼B1>j€ÒôtVXí/d ä³ÜÈqY×:ö¦²1’qœÛ!ÁÕûI¬$/qÂsÈ8#ô«ôʲų¥ýÍ¥1C÷[ÄI)8÷æ·tÍAˆ¬×:MŒ¨G*! ŽŸï^whµùs,vÑ6ïÂ7nÏÃzÓWí/s'~¨eTj¸×cšG \[h/vU4K! ¯¶F#ኳ¾†Œ¦7NOþJàð¯?KÍ|Àd[ËuTÿZ>çZ‹l²ÎáËuÙIüª6¨¼èõ;{`’=3Ng!¾æ¼|h5MÕíÁ:v"õÉ8>GŽ>uÄAq©&àúã.ÒØÐg§­Gg©v‚ç;näÀb¿…yùÖmv•N›ª²hšc¨Ëù%Ó´3Žtëì1± ^}:UXí¯ä·c6·0¡TŽ8#§ô¬ûˆõ(w÷7Œû2@˜ùRÑ 5‹}5áî[ADP8Â#â?¥qš–—¤³¼áÞ,¾Ùo<k´¼Ÿ¼Òç·KË™%tdS"®ÀHÇ@=zW7en­"’íõ=ÒÜ€3×á]1ëɉ§èä#–íå<ü*wŽwpK*ƒŒí÷Ôö÷k*9T,ʼnüëR .4Nòæ]¬Ø;7 ,ÿµzœÒìòÙ›k§¤ ïGÿ­ }b°­(Þ!&m#x6ÃéRÜE2íîbÉcœŽ|¸¬<›£V‘Mc(Æ5>•f!0oÀ@^¹¢2ÝŠ ÃSímÉõëBÛœ¹[€Æ8äÔç³.Jƾ{†…»µØ¹úü«xn\$§ ó¸ó[p£waÚBê¹9>}V–Þ×y•r0xÂg=|Oº¤rn‰ÏfLÊÒ°3”@9ÝS½œK… ;«åZض‰X.Åç#Ò¬Âè;q× ¿&è)# ;HÆÒ–ÓHsÀ#:[Í2¿w`‚ ö€Ï­m²G"È®'ðž @[(¬Hóñø *hʸ·¼ŽÅí¤ŽV\€Ú÷•fÚKÝÅ"ž ù†®Žðã1Éê¾¾ú΋L ü9˜äö¢Ê«cš-ée„²«`ÆÝO­\üvoθ&¨E°_†-ìoŽjìGm¤Ý2ØàyñZæ™T“|’ÂˆØØO§95wQÛoðA~uU£&ÕIÂûDŽzxÿ~ê—SÍÄI·6“ǯJÏȬ¼‘b5'P¶,x-ì!ŒÔÚ´˜×  D_j º‘`Ômƒà²¯N¼âªO4’ëi,ƒØøhŸÖµv[MœÅófþRÅ€ÝÀÅ]µ»X†@àpO¾¢»µ’MAÃ)ÚNAUÏ*Úl ¬Œ ŽI®9YÂTmÇ"M 4lxä€sEy»æ„ç/çñ¬­UFßp!H>­MNÖ4Z\¼ƒÚ,¹ÏÏ–MpäÓâú1äí¾ÉobÒöú(Pɰ©ÆÄ$À<•…®êFúíî‡y3™ƒ×5&—vý‘‘'žáG,¨\lWΨöF<þ«ºnšÊc3$Ä#Ý»º\û³ÏO•cvÎ’—$sQKÞÜ>Ò@ ï¢Äp8N}¾ 5Ý 2įDÿ _»,ºì!Zþì}7vpH0¸/!ž”«¾fŸù1üR«ýÅèÕ˜ Ù 9s™.‰óéDý‘Óïtßý+¥?ø‡çK#Û#À׃û9òf]œÙì~‘·˜î l(Çd´±œ œÿ¨WE¹:9òɦ/®âÌ}Ù5Ÿìåò`ÁNÉèãÿsNjԣ³VFmœûÜÕå˜-ø;ÔÆã íUÐÑóí)#¯=*|ù_–.Ñ“ÿÃÚXE_ºäx æ¥GÓãM«j@HkD8ç׊Qí$ÿ ž8ÊÔùgì”gþèÓøÅ©o,±4—HÓü-ÿ¨ÕÙ%Ž!´.[ÀqU^ülÈ ðrGùgìPK¥Ùcÿ–Ýž:+» a¥J‹@ò ;ÉÀ'â*•ƤኧQÓ“œPG|)Ây*y=?:ªrNÍÁñv€ìî• ®ža•#i Žü©äãéŠÐ’[T\,1ñž«ÐñáåXsß»ª•§>ʹǎ¿¯5ܦ0øË+ž¾üøâ’r{lÏ{7SµïNV,¯ˆ?«y~Ò•*¢8”cpü‡Â±eP@“|§’ãxÕ}FrÓ$LǦNÞœuçÏúVxÞ“%j·’`ò SÁLJ¥g}æVÝ29r©õ¨Nùš^ñ9ÛÁÏCœ>T*;»m’0›,ªsÐq^˜Á$i*Ì1åyŽ)®î£K¥HÐð1ïãùÓÚÚç|É#Ø<íóÉõÍ'UûÀ¸cžðá®qðó«ÿ"ÑgwI7<óáuZ”íPAÆGˆùyÔÈU–Iƒ~ÐŽz|ª­Ìð-ÆÆc¿¨ñŸ_ZŠM½2I`؇»Ág!gΛB¬`û qœjó2É·jíö¯…G,¬wŒÃ†è9¼sqì©Ó!Š «w°r 7€?ûUØžS‘a•¹ö‰'Æ¡„.?f32Ã8ǧÀTL ÔV(˜3>0äg¨ñ­ä“–™»mÕÍÈL´Ò#(Ãdññ«öÓÌ W §q\g øÕ¸Œ#ûD98äó×a ¬#An%z ñ\g7"JM“Ý3w 1˜†väg<úýjœWòZ©pËn3âOÉHmƒÄÛÕ°þÙåH'^µH¾eddÞ£ð)9ʤSJŒ¦Ñ¯&£:Iº;€d ŒcAÏÏåVnµMVå™­€LÙü_!Xö¬ÂÈ¿ÏǧN´®¦]ñ„@>æÁê§ÖºG3‹¦tŽVÕÖoR2·vî!ƒËŒþu…¬ß\Kö°È N…Xx{ýhK´ò8@ç1óÇŸ?*Y–í©Ü˜gßÎ ñ]GeùäÊzFš–ÖæW2²§´:œùxãçãZÜP¨ª¿ÈøøqG O-»4‘Â¥H# $õþχCœ×‹uY£$–ÜpCyÅ^|³Ù—Ä©Œ8fövŒgáDàÈ´¥O9$ŸmZÝ $^»GO<Z…¡3¯wµm§Ó59[´X¡‰XÉê0:ž¦¢Ù»{…þ"2…E"Y a–"±’K>?ÞiÙäc¹WöqãïùTL’nî\±!‚çßýý*Áí­¤bGâ§ä G$9ÈóÏÒŠi—-`@ö³Çº«¢Êñ£0åŽéááV.£Tf@ª¯´þú{ªù!^}­q¿z¡±Í?xøÀÜXäïÇúÔ®¦ÞÜ8mÁãëSZ@QUÙ6³ŒŒñÖœ©è¬ÅäyU^qÔÑ­Æð¡xüÿíF±*[ dÈyf>~”BÙÄc|+¸â?/) ˜7ޝ"»Üdn&žÌR4Œr9§?î)ö²Hñ„ rAÉëSJRU‰FWŽ˜ññª§ª/"âI†ÂñÇCŽ´ÒB;“×yäzÕ­›]YIaÁ#梈 ¦.Ç¡#ýøV9eh  *P6AÉâºÊÓQ¼WƯ4£{70O88ñDÄ6oÝP²®#»F;AÊíÈæ³&UW³Cµ³ß[ÝǦÜ÷7/`$x~p:zuÇŸJØìÄ ÷±°B»¹èr|ë/õÔRÊZMå7.1ýóÍuv¬¡{¤t^|ù¨³vÉv'ø9÷ m‡'*qåRwlFO u¤¨Fzuy¹ëf¶“éð¥V;ƳãJ¯7ìÕ¢ªw} Ôw68RqœUk"‰lŠÒ+¿˜èk?Q¹‘@]ÕÛ |ê¤ÞŒ¹šæ(Ð+ª™Nöx«&x»(À\q…ëî‚ò—´ŽB2›v± òr|zô©-n¥ŠÚI0,§fO•ce˜/mþøÑ¸’)C ¨<|xêzUátu¾NõêÑǭr·K4±ºòà†,\gØ­d¸î¢Øü°éŽ¢µ(ÒÑY¶×*%×8þ^£Ö±µZXî•"à ‘ =TÕ¹(à³ò­•ç Š«{"ÍpJ*¯™=N*F6M²hµ9å¾tYOv«€@Ɇê\*ËœŒ’ÇÁó?֪Dž˜$d‰#‘‘ëPJs+órG^µÙE‹fö^ã—WáGÇë[¶­ÚHƒ„nXãü#ûùVV§ƒ^ &Nç N=zÖ±¿³ u+#ɰƒµ1Œ| ª&è´ÁNWÅyòÎ?:¢–\Ë& Ø:zâ®iP,ÖýL8B2xðÊ’<¹5¦ãd¤‘–÷dVE 3`°ã¨éõ«òKOÉ6Ý¹Ûøp×úеƒG/v³oËxí'§çJe˜ÅtfŒcnS>óé[nÚ6’ðIº!›‰Þàû²Oêf“¸’Càê¥ÈÏ_©©Úhæf)£*¸Sœã·dŠ#º*P2¢Æ„õ “ñ­aÒèqðVb{&iT‡Çy91ÈÏAÐüx¨'¶ ÝGnL2¹Ç<¼xsVmÚdw`œ)9ëÓË­JÑÈñ«‹’ÖléÎ=ã‰i™‘JXŒrX–üLOO |êx‚Èí+ êN<¨drY"cжAê1ÓéUå•Cˆ²¤6Hê=>Už.Z3Ñ2β oñ™žEžH8ÈéT®nŠÉ°0až1ôú~tq]²Î#P /R<1“DšD'ž/â±ã aóíúUR»&)¿8=1ãS¥ò1€)èõ ۆʫ(m'Ÿjŵ¦hŒ‘’®9o ŒñFÖãÙUʦÝÜy”¤}Û{¬d0'ôâ®ZÈ7JY©]¹>Ò²ò{2,krÌAUã©Î5*CU(eÆqÔP¤{n&÷gä.:Ôü($Išh¢Yð p…Fì´O6ëi±c$ã¦jx5F‡2n\/cvh/f·…DnŽIᘯt¬ù"vT< ¨’}‘Ò7“\º”2‰ÀÞG²8òÕë}HƒíÊáOVÍrñÆé2Iåˆò¦‘e2û.vrXŸ/ :däÎÆÞpÈKÜî>>´«—n™Um£ÔUÍÂ^©—Vä @IÁÆ8éŸ_* ×XÑUH'ž@ç5“4°HÙcÁ Ïç’AÊ̼’Ct¯çHG¶b¼šv¥šÝᙑ²F9÷ô¥¹6ª¢‘†üJ9?Ò€:Dz!Ú|Î1@²3.Ðf•ÙdÂnï¿Ý¸ÏUñ—çqÊþ/+•&|»ÙÏ•V‘ðZ;[¦Us“ŠvKI·í  îsøh{¨Šfç%±Ž3SB‹³à‚ÄàdøUAíÜ2¨Âƒ‘ž¾u¨²“ÞÚ¡–R7“P<‘ìf09Qž0µ µ,bwÉÚø`G³¥ØEgS|ŠVÀç4ÖѬ³+¶ööˆe)⥽Š%x•pQ½’O—£{»‰cÔâ·Éx+üµ'ïüáìžç?+v¸ÂZP^«¿Œ¹ÏíÈNÖ)¸ìîèO_J”áìþ%-Óت¥Q¢vV’Ü}á6á[fN¯ŸÆ´£vF@U±ì’9Þj›Î±Ê²t޾5,s¬Î’ɆÚ~žUœ’o³VÙféû”üXž8/öD%FDI6î+ŽG=OÃÆ³ï®fomƒŒ®Æáýüꥴ³;!ñNO\¨?¥#‰ñ²×£~Àµ—›mÐ3a€ÜqŒ‘QÆV]ÐW‰‚…ÝTw¬WđХX†XáT ›Ÿi$çûÏJ¡,€VËKáÐyдâ&B̤·ûDVø¶’f³U^8ç~ìá$œc# ñŸˆþúÑ&D ¿#Ÿñdã†j·zc²$©Ç þ½j©¹Âí‰Ùƒž y?¥tŽ-›HÛ¸šâ+e²©*ã©ã‘ò£Úƒrîä$/ œ)Áù‰ªwwû÷;™Þ\gçý*y•ãKY’Ff1.Bã"sÓ…ZÚTuoÀ¤bOã>93ñx}>•£¨‹P“ Õ8 ç#©ʪž•æ—ÚIœ¶c¡]™‹1ˆCË/‰é~j¶i¢ûÂ+T>Ëu<ŽOάÁFbH%øãŽ(îÊ"”UU!@ÏŸ9Ǻºò®…“#­ÌÖ 7žì;nÜ¡[w–qâz|©G ÜÈâE]ꬼÀúšZ]»Ýjpå!ŒI-Ý®|<ù«˜[8Ê,ýá,ÄãËú ÄçÇFïF6«,“\°…E@ªäc­²)†KøïÇ÷ëR tZBŠ ÎAzH zhŸ*êY—ðÂÿ_*Û•%FõDQ¼,̱¨ ¼àséúÔ±„3«ž pÊÂ<>URt=ÜŒíÏ9 ø}}ÞúŠý®RCYîß m Gå\ÒÝÚ/µÙûÃIÆ01Ôð<Æ?*¯rýⱑUÜ䑜ÿ­Q•û‰L$1PAÛâqά(*]›£mç9ñúÕq¤¨6 ijwÒ¸^8ã΂åpX)’ràðsG"#¢`¯'©ãœ|êu -žUYÜdœàx­9y#aÛN’El²ñúq𬒔~ 1_`£ŸJYBÊàO\Ô‘Û i[vÅ€>'ž­ajÛ, m‹{Þ9PndnA8?>•]î ¦H¸aøŠò*ÚCnd^â\¹ ”ÛüÄsò55Ô(°™xG·ãÁÎ:ûëJI=„ÊÒ]Nõ·ºØW¦ Ê^6'~Ôc‘œgûÓÛÅ-¢NŠ ,¹Ï^O—À žÎ)–UÑ#â@G'#ŒzUµE^ˆ­d+¢³a° €çL¥åÈLj>>84ZsÌÐ…S“°8Àg?:šÔ‚…UY—iÜ\õ&£ö3RI;Þv€M@o#· :äû9qžxÏkP€¼j±“ /´sïÿzÁšty¹Œœt-‚Tt¯F8ò*Voµô0À•”{¹ó5êQH‡$nQžsð¬+ã$ŒªÿæðZŽÕט€,ÙöHþù­G«eP:X/Ôâe!xðñ«¶²´¬Ûb<‚yü«ÿ|ñ®D°ƒ•ÁPÃÙ>™â¬iS#ÝG–^™#Ë8'ûò®2Å{4±ìè`xãpS,áp]Ž3ÏûU{×fîOLdƒÉãšÎ¸œ«0BV58ëáMo*Í.àK8à|+ÆÔ¬Ä´Ë7d€m‘K ÏÒ¦GÄ9ÃFsÉãßîëU¦€¼}ò“¼Œ{áR$æÙ»ÆÚ"–#¦ Ït‚“i“½”µ1÷I‘eBG_CÓÊšÖw–ÓÙÜÃv~ŸO0ûôÁ¦ aOeÔîâ§»–8T4q®HŸLø{ÿ*ëËê“ìÞ¨ÏHG|’S¼È8^ü}h–y,n ЮðžéÇÈýj+û™ÚÞâ¸v*“œþ¸­}rÚ=£9Gßµ·<1_é]Þš³²Šì§¢¸Ó¾âˆçð“Üg¯¼f¨È¡îÛ½ ê8#qZµÄr*à“žX|:üGήÙiëLg2³+Éé•ÇÇ5ÎRã6N º1®²Ãta\†ägÃGÏëUÚ'šîHhؘ÷óÍi-®Åmç0r¹ö­]ÙŽâÚâÚ"g*ÒËaTÿxÖù(Ñ™C‰M¬.d™NÏẩàôÉÏÃëToY{õÆN ò~æHä‰ç%‰ä)?Ö¡´Ý\É;FAÚ9êzü¾u Úû3šÐoË*äS¹ñ"¦»*Zw[ž&ÚóÚq×ÝìÔwÝÑXž2B8<‘çÍ ì[tÑ$,dû¸PWãÉ>#çU;FÖÍ;IVKË[SΪç«p(­îÕfËÔÌ¹È ìb0}ÿdv~%Ö£™lºLA9à0?¯t,&ÿHûÔQ¦ôÂáT‚»í9ô8XšQ3ÇÉÎ;¶UÞÃ''ÃÏéM™\ð3 c9«n« EVocKæqò¨àI!—2…åƒínWÏÈô¢‘Š5»3ÔŽáÈw*HP2~g×5¯|a’éC`¡ÏVÈãxûë1eî'Ú÷o Gõ:ãWŒMjX²ìŠLHQznöƒcç^YËífïÁ…qjòNÑåU•¾-ÇãV¯‰‡³É„™#’G8òÜëŠ=zÛþ1cÀäTö‡ó6ÜîÎy«KŸJOh3Hû]±Œó“ú|«£È¢“{ÀëmD˜V ž¼d |ªô ca$qoËÿâ)#ôùÕ‹›4KéæÀ¬eÓ¦0¸qð1îŽxîGàwcð¨'?®JnH†~¯bçVdA•ÉêBàt? Ûi¬\,Qa"!y8Á§>¢µMÂ-€¹}›ÞE Xg+¸œýJ­Ú ¬\Iø6ÈWiÎd ã>žU¸¹]¼™7v†imç¤qŒ§9%W“¥ÎŒ²G>Éê9ð­>wmnÄïŽPßâÆPüHQS\[ÞVΟ„ÛÄG=\óñyHÕìÌ·ÑîšhŒ²(ÌÌ1ŒíÉÇÐ|ê„Ëfàm,^F>@€¼WFÎ µÑ1å–Û 9Ã*µ•¾ý&i€ÜÇ€IR óè9¬Ç+ke[Ts!÷i;¶ÝüËÏ^H>#š;ØŒÆ_aÉEù@ü¾´rÚΗ,²°}ÃJðÃ×>ú¿-„Vš‚§uEdž™l{CÞp~b½-¤¶f¨Z’ɤ=Ú.UT¨>È#ÇÌÐhêâ)-×ñ§#ÚnqÓËÚ5i!ûÌíí`DÛå=9Ê} Mr\]ÝÝHoÇ;”íäzãÙé\œÒѦb\[Þ ÞH yÛŸýêÕÝ»Ú["ª—i‚ÃqŽ:¸cxî-ض@„'^3¸šSy’8ü"8g?*s¶Œ™m!\¤Ë¼d‘¯÷ëAe§[K<æxûáeÖ B¹Î9^kN!%ȳ\ŸóáWtx#2°\·>¼qùVÖe£Pi­;?Ì 5µ¹<Ê^#ÈAŒû$õàv+mm¢{»‡…bŠ)'çÆ>5ÞéI¿Þ$—v'e‰¿U ?<Ö6«o ¶ßðìq;³HAÇð÷}MHævÓèéÊŒmJ ƈc+ SnVL`;/áôü"¨-¥êÁºL3ˆ÷¦s€|±‚>ЭºÏºÞ Œ…ÊçÙ *Oý¸øÓiÖko¶}βFüž3ԃﮋ=&ƒ›£žœ:ľ=ï†N*ÿgàw™„ŠëÆÈ#œïÝWã´\ƪ6q“œì Õ‚Æ86íU”º¸Ï2ãHåÙ’–ó5ôVár½árÞu­ †ÝÀÚ´_h'ʧ0<[wuQ¸ðzŸIp?ã;×`I#oŽ+„§l‰h­+ÇnꊄJ¨UÛÉ=MŸ²eW=܈p>=|ÇJ…ÞLÌŠ nñæ¥ÓÏÝ‹º£m%G¿ :Vãù7l¹5„v÷ÄeHÔ9Ú xR©ï,šiË÷ÐG•*¿$|³ÑÄçÙ`º– x®F'“åÒ§¶µ³rÒ]¶ÈÜ„^ìõ#Ïš‡½Y®€¾ÀÁãýô©m¡ÝǪDIfÏO_βäìàå³CYk$f‚ˆ *¹9̃ÃáY·‘ÙR«‡Nµ{S…^÷b.G² ÎFVÔŽùe}Ä!éϧ÷ó®)ñZ#fõ·w,2 ö$äå¿óý(¬´õ\4d–#ysÏ¿imûÕV`s•øøüêÐÛÜÊ `†ß×ûÅz£ž•„Ò‹hvŠª¾Ç$d{é4ï‘sĤU'>8<þu–²´}Ès¿¨ôô­´P²®ìÛ‚Ùäg?í^nI;1ÊÙ;W“¼ÝµU6…ñÇ_§åQ[£LOxÌ„áœ|*ΣÙ•ÏW8ã4M+ÝŒÏúf³kM•wf;@ña¤åŒER20 È<ŸŸÎ­Yɾظìqž€{³Vo,Ŷ¤²Ï&à"E8ä®:›KKä.ଈqýøÔ–[Z#ìå.„óN‘&‚î'<`;ø¦†÷îñ’‘Àq¸¨$ýM37ï@îı=ç?ÞkS´ ¾½#DŸøp€OCü4þ¦½Jn.]Ë(°û¬ªÛäbý@oï"•õ¡X0’œà`Ç»žOΩê3ÚGs,³JꀌÊ7_ˆ­dOh³ee€R=yÏÇ ‘§d¶]âÜBð…a:ÎÖžΦקß:v)HÝàpA1[bìµ¼A¡ØÊ…Ž žxëÐV>­j×7Ð÷cï0œœóñ¬ãÍÊVÿûÿ¨ë×d+¼Wñ3#0mä–c¡­Û\ÝZܤn0ªx=pA$|E^D…G R*œmèHÅ+žæàÈ《¤¨ãÄ)®ŠjrÚ=X§*ek”¶³’I„o4aŠ©VÁ#9}2kgMÒÍÄ3[®þåfØŸåIo~5‰r{É£„)páUçÍá]oï­4¨£HË˵™ÏŒS#^ iظ»=£qqª,÷ßv+ݪ‚ ¯‰ð¡ì½œv¶©g#+­ÈÛ!€#8#å劽»c—$ÈǼ’OwÁñÇbÎm»œ]®Šf,ÄY3€Ì[ŽqÓáî®2ÊçÑÑÆåIºÚi¯,Òxe Àœpp?¿}IsfÃOµº$³2~FÐÙÀ÷q­vZÄb©5˜Œ8.S¼ÜûÅeÍ}§¼ATÀÀ ¼ª¯¯…™¾Î<{LÇœí“fÑ­€3ÓåùÖŽ‡q,RÌ%‰ÂÈŠ‘ÇAÏ®)ZÄò4FRª$%Aò »ª³÷Ýá%Õ Ãùf¹ÉÔ¨Í7,n&YYÌlÿ6×?Qò©£hãÓì܈äžxý3L„Ƨ(UI-Ï$–Á÷^¹‰#··m»±/Aã;Iëô¤½ æúÊépÛ¤]ƒòË…\Õ¤$»œ€ c’9Qh^B‘´¹FV.xÉüa†?î5=ü`K"@U­B¯9Æqý~•…"=³™hSî¯ÜŽhéÃ>™ùš·¬Y™.ç¹m…ÙËÄû!·{^ú·÷xÚÔIµKE$rÏ×?J±4A®ï ÚÄ”áGCãùþuÓäw¢Õ4èå!£SËGì‚y$cøF)j{{+B=‡ €z+'áÅI™mî°YK°$õLÌ|ª#\2NOw‡20óãåDzNJ.B4eIJ¸E=0vîQŸJ8¤‹H½ˆ÷nªA¯NHϧ_•=»$šk^£í”•Aäãú çßW­³’eBU¶##Úçƒî'ëE:F—FæŸ$Љpý@#çœèjô–öÇñÀÀ*IÿY•h\Ûmm°FXïêG™üÎ*sm ĨVÎÖ1Î~|ÖžoAµvb[@qí,lí3H01ŸÏŸ&´®ñ$ŒñÊ©Œt^9ìŠ$FÄn¬ÀŒ”ñ#“ƒùUÝ×& ø I€§ÇÀ|À&°äØK“£šÊ¥}¦€R|Ÿ÷QvéWØXÙFó£=˜qo*¨V㑟N>Ÿ*}B_j¸ÈôéùŠŸ"{3FH´0Î&ˆ2F§iR<½ŸïßVm‚Ç=¼X!?ˆU³×Œ¨«IŒ±¬€!ƒƒã×ýªK›R‰j‚=’H<î­r#‹+3÷s–aì4¤çÔ€MW–Rñ#b±ö|FÖ´ÒÞ1t6$ ÀÉ¥2«Ý`a˜¶X©ÿJ’•ŠZ]±Šé$Ú¡B€qÁçœb£ïké"1†]¤*ã¦+U"(]X† ÌËŒrý3ô¨à°Î×~Ëf\m^»y9¬©–Œ‹˜Òà{lÄóÎ9nÜ;F£†B‘àçôÖˆQ´‚ÎÑ“b á‹Ôœýií£¹û¨PU¹e㎃åÅtr|L­öÎã¾göOþœ Ô‰ÿÈï‘ð\aN|OZ¶ŠB’ ª«“…ÏQŒ œØ÷ÚfhÀϵq„HÇ€›rÝ2´úQ– ý9Xïx^:gÏÆƒ^˜˜âĤ$*Á¹äàô«º1k™m$ʉV@o×{–¶œ”VÌϸÊ`]’È}³Áör?0~US]Xf¾»tgfÄjŒF2T`xt­[øZä’!º']‘Æ1ÁëåÈùÓCc$Z¡ºxV@®B¬œ¯\Žœ`×e$¾Å¤sé«Þî•„vNóŸý«nÖ쥶³1%Æ:{‰÷VΧaS*±.;µa’ =|1ÔÒ±ŠXX<꥕8ç¦qÆk3Ï)-™wb³·=ò…‹1(ôùçåUKK -íÈÀu@ë…8àžUhK*$r ’¬§#§©÷qùV£¬“Æë"÷¢ ù8ãß^^tí–'%oj÷2¬˜bX²ã;W©áZzu¬7Q\ći01ôÈñ8÷OÙË1½Èv"{œ…SÑn}r9¢ÓmR &–&þMª2X{°kÓ9úf¯e'·’ŽàÍm2{D`‘Ž=êMl먱Þ,âHÄØaXœúqJêØIky¼±<>ü§¯Ö¯é–¶¬Ž®$È‚±$–éõ©ó^ÙÕM˜ÑZ®É­Ø#ÃݶÖð·OýL*m?OHô»xÝámÁq¿Ùfö?ôû°kDÙA¶B #–ö²}œççŒÿJ=wl‘ϸÉP”tÇ#§õ¬G&Ì'³:[õæšeY S(¯°Ä}1ŠF®´Å‚ÞUíP77M§Ð€9ó­~ïîWÅÕŒ¢dgB|VªKlc¶–E'â=ùC© ººÜìyê3Ïæ+ {³ž»)¤ © AÆH$gô©Y$Cqs2•ˆ€€òFrˆäʵ¹yîeŠ\ýÙƒ«' ¶ ¯Æ°­ua¥°Ü\Č܀KnD W~.KDyºPÇ47R¾`yx!¹Ï\Ñ-»þïŸj€vpéáúŸ•eÜêV­‡C#;Éøpzzæ¯XjK(+y$‹ /&$‰ò ‘Çβ¯I ¦†Óm$ŽÒâ)#£ÆÇÇãÉ­û q,)nцm¾Øè­œ¯×èMsŽ.î/í°×t‘ˆE#B9#=OêjüæK—·´sšœåÓ“ŽFy¬NÕò7Q¥<]ÙhÊG1è@9úâ«Bí$m®½ácŸ üêåÈ™âŽyäV”ƒÛ[#z€ÓõÍQƒgñѲ âzùW)6¤èÜâÓ¤O@ÈÏÁ”O@|÷ãV4ż8þOídyÅ`ê—»-Î×Û#û*O#ÚÅ_즨e¿rìH<`ŒG#é]`ÛÙ¬M9+S¸»Tp%”€¾¥ª—H$žPÝàfÉ yQÍsH ì HÉÇ5 ÄäRlnö<Žzt?ZçöäŽw½É·´‘±¾Eß|FAúƒROû%Ì›÷HûsáÀÈýh nïE*a,а‘†ÁëÇ÷Ö¢q:ª4Ë(¶ViÞz…vW³³ŽïÚ(ê )Þ*~Õz¹3ñ nè›U¢‰÷m9~Ÿ­´Ó\Å”‰²[8 ù篆(5e•D’Q×i'çòyå–æKv&åQ£åU—‚ZˆýÚ¹’Eîºz.k7BܪFd7z`xÕòðÌmu4'fq†àÖ¼}™·a5عŠWïPíʾ089­8=¨Äãðœ`yäÖý¬QdÛ¤jW+sדW´™[1”"Ú rAøÖïë¢ÆLš'‰ {‚¡Ä€ygûâ´´€$» ÿŠÿI8ýk)mU¬®c¹Ä…†c ã?ÓwEž(b(q ô+š–Ž¸›åLí„Ð&6ÊØÏˆâ¬Œ¶èÅNQ@$ž¸éú…G«M'ÜÑ‚í~ûfâ3’?ÚŽ[°mÖÈnWm8àþUÕEݳÑñÓv¤Wï²3äÃOB3áJ£k€ê†|™ÇÏ«Œ¡+feÙŸ0‡!£€3œóÔš­so,wK# Rpà“뎢™^ÞY¦Ø@Ę O8¡2H·äK“œ ó·κ«èòÉ2â»>®Îœ€ªÁ±ä8ü…l¶¡ ÄK¥ÜgÆÜgXQÈÈýàUBäqާË3˲T;3»"™VB¸$žµžHšI÷)è%Ëcõë[âÞ‘®KÁ¹æå’qÔMfH¡É-o\ƒàO?,bªEys.±ÍÞ?‚ž"³ou[ØžI7.¡ãq¾=)7*Fy­YÑ\Ü÷0èv`’p<³@¦7!eRäìã<þÕBÃR’êÖNó» c 2¥G…åÜ9>É~5d³-Òwr* Ë63•ÅÍì¼’ÆŒ±£rÌ2|~µ9¾’Þˆb·ffy °f =œœ—'?QW®SîÖ}ú…w"ûC<OAÎû‹níóƒ ‰À­Z¸.T$“ ¥qæ?¥[~Je]ÌñÆÄ$œrrp8ÈòÎhX´¶±nbHÆãž¸éŸúQ\)v–I Ú’2 {‡ûÔ–°£E÷}§q=çN}Õ–÷³ùâYÑ#`ä¾ËÓë[ —tv“cíÛ=3OÐU%ˆ4*‘–9‘ôð«‰i䃀ÀmÇ™5‰;*º*Gm"jo"·³»8ä`|1ô©¬íâI&BI\{ øc•[á¾hðÀ†ò9þµ,q÷QÊ\œœóŸOô­ó´_$ÐÛBºŒ’9yº1íSŽ£8ÍI§…‰\cùµTÎa ¯‚H$ç¡ëú ”]Eà‚ýáÛÁ œcõãé\µBô5Û¤vÙTàygúý)íáõ8gIwÃ"åŸ]F<úTV»'›ce2sµ¼Á«ºL2$3+´>ôðxðÿj‘¿!G‘FbVúXá†Á*¾D~˜¯´2F{›˜ŽJS p`d3ÏÒšûMûÇñ;Ñ»nñg?!õ¤Y¢³Tj:‡w>ƒùVïVn e«ˆû²g>Ë*uHѲÅ<€¯w¸>'¯ä>U“te{%G”EöOO ~U¡¸,{dd=ß±‚pO‘ð󬯤tÇ6Õ0Þw–ý{²§»v ŸdŽGƬFDÉA'´|pqž¾™®oO‘’G.̲‚ê«»Ôjê¼Í:´žÐ‘û·pdbºJñF9m—ïoâmBh\’rüYÿŸžUîìf»ÚÀ篙¬AqtUL °€¬œ®0àkA®Þ}¢‰„R¬™éœ¶8òçš¶sK²´¥¼iºI¸qÓ,Jü<>UŸ«ë5ˆ•ÔäþH$yü+;÷~ ÷±E$<€‡0 É'#š Éö2íϵ¸ ü# úø|+´p#›Œ¨¯Õòß´Ñ$’žgSýô9õ®„K8)꘎aÝ«sä9ëÀ®xO ‘¥··XÁǃçÁ­ø‚\¥ýÄê´,L)ž2S©ãŸë[ɆЛ$·JûnUV'qÜ—ºŠæÝl®Ù „8•Ë"–᧩Ȩt³jÖ×âSq÷¨Ü£-ììÏ Œ~"¯Ç§Í©YÛ˜n@˜E™<¤ãÜqI.-&ÍqÕ28†âá· Q×1̽ ÉÆ~Nââk‡XlJ<‰—ÀmÈG\dãŒâ¶Æ‰÷Í&íáyEË22÷‘ãq“Œž¹ùÖ~—Ù+ù5$†-˜‘CHF ‘‘ϧO}1¸§ÞÐX߃Fêñ¥–ÖöT²GìÁ{*}98ÿqZ6:Μmß îφëÓ¥§£>g÷e¼oŽåš@68Îî¥YÓ´In4èâ‚!-Ó !Dq2}Ù®9arßgN¶ ¶« Ì‚›>‡ Ò¶¡¦«4žÌ‚†¼AϺ´°¦»:(·VÎRKÉóc‚ €+1êÀ`ÿ~†Š-}÷˜_‚€ppïÊ´/ä´[k«X¬¡Þî{©$s É<{ǾN–UÑ>ïÜÀw8%‚q‚‡'“óÏ…eÁ%VsQã«#´ŠâéfŽ"B§ãfáG_Cc¾ ñ ƒ… î÷üêÚÈöö¥ÚŽù,ñqÐóÖ˜,2çq–ÎF1\UÑš®‹SÜ “€paœŠ¯qró ³‰$`òÇÙ“òëõ qÑr[=<¨‚µÊà)ÁÀ]#˪;ói9X.nÖ¿=*¯|·‘ˆX¶×r<0\KÞ!¿<œçwËëOo§‹0cD‘°}–Ç"ºF-x0±ÏÑNÎ%…ãd¦G¿Š%”IÀÆöʹôð«réòw»ö>ÁÁU“Ï4â×¾„Ã)(3sšàŸ½1w™%{µ‘zç5°î,+µsÏ8­÷Òb•c?xÚ@Î6äV¦ÑÂÌNíÌda”ì×oŠÎñþ3èǺ‰¤]ÛxËø:c5PÛ]%—ÞÁ@Ñcûñ®÷tŽ[–un¾œñFš\Ìê²€1ï§õÚѹfUö ³Z+,£0r1 ^~ Õ)¦švÃ:wç„*\|×Sûž  nóÐ/uX¶±„>hÀ­z#Ž™ê’æ’}œl·øÚÚâF’‹Æ~t«³ŸH·y aÆ|¸¥]–8RÖÎ"he\\(LÎåÉÆ8¡¹i2° ¬I8ëéBÀ ùr>tKOl¤ä3€}GóÚ£áKEÇïBÆÂ$Ú둹¾´׌‘†ŽM…=ÜhûGìê‰ñåBŽ€V%ÄŽ’W`6ôÍ#=: º 7xRvWPBÆW©Fk8»"4jáŽN•¥!+cpËÁïÈ÷U svÄÂç§ ¯d^š'šDá–Ò3˜‚ìN|=Þêž9!¹Š8Ei0Ï“åçšÄJÒ͹Ë{~>úÒ ©{p`-¯œ ²IišHÐÓ/~ïðLÂüD#Žj…ÌÖSXHų6ìíôÉéPê_ñ„'³¹A'ÄœyÖ}¿6HÇ©-šCb­éš ï"p6©ÉÇ ÇuÒE$Ú•HÁÚ3a¸ç¹Ý-V]E#p ýåWœñ[è]¬h6¯´08à çý¨­SyfYÄjˆ#-™Œž:[ jÆ/4‰*VuÀêÈVU»¶çbÄœøñ[×>Í›àHùšòäoA$W†ÍžêØ…;”®8Ç?Þ)žÊâîOwí3ÁŽç¡­m=ÞæýZwi,sãV®B¶¥mo±FtBª  äqîœoäLE&sv¶í-¼\¹ÂûiþS“ŸïÖ Ó™"¸Üó•’3µWnC/Ÿ¥u½³†uhÄ0Å6à‘îaÐ{…dè6ÐK¯ZÇ$a–VU~z‚Gõ­NÔ«Éd«F:\Γ-º 1´…ÈÝŒ·Z¼òá"»l«£¯ã:›^†+[Ûè ]‰ƒ9Çγ§,mÃbyñÿUg%&eª²õ„ësnZhYrXc<UËÌ'1B­èUcGXZFW” s9Ï÷çPïcvŒO=î3éÍKmíß•ohw¾<õ<Ö¹]¤j„!y¯b–!–ÀŒŽF3ŒypE\°’5 IψëÍ6¥QÀò¤j®YFGúih®òÜÛ$ŒYc ÀÅoãäΕö¢xŠ£¬ö»•8Æ@ÏôÍVí ¼Ã„-&Ü–êÇâéçRjRHnbrÇwøÐÜ º±¾–à´ñ”%ñL0NѨ*d:•‹Û]µ³^ÂÏ݆R¤§Èü9¦Õ,íÿrw¡dœ€Ê$Ã+cdzãÕ7wi™Ø–R '9®‡J†)ífd C ޏ­Å¥Ò"I&ÑBîÃK;«V2›,òœ˜ø<ƒŒŒsôò¬ùbG†)mcµ‘÷—˜.Iƒàx榺E8ÇÈÔò{S6î}ŸÈŒVžN; éìmn-6+[h¤¾i™°ò¢ª®ÖÆž*{Em:Yfq ÈÝv—sñÏÒ²¤%µ @Þ×ü¾¼õ­ež[–œNýç r<0+m§ £o7E›;»KKµº³¸1_&B—UdoÄàúƒáãš“µWBÿKhÏußÊû¥AÎÎA#<õúVM’«›Wp 4`“ë×ó©ÕÚG%Îâ8©ó¸Æ’"Éôª0m´46¨‹#+¤¡ÑüsÎr=Ø­˜¢Ž)žÚ÷]Ç̰è3î©î"ŽÖX×hã »o MÈPÝŒ×))K¶sPð`Á`‰vd’5êÎSùäý*þ’­ÞºÉüä”êsZñÚÀËíFMLU}¤Ú6«kàäöαþ3¾Êl¥wn³(PWoëëþÕNIåܳF²3´…ã5«gmaš8Q PN9ÅHˆ¦P¥F7ZÔŠ¢û;/⥦Ì4ûÌêÈ tA•ÅY/Q‘V&ˆ/цG÷“[rÃzìcRBpO^‚ª€ñÇC:èñE2K L¡Ý1f” *z©õ¦û¹ö]ÈVqÔv+VÑ® 0Ü¥†A9ó« MtÆ…A8G˜þµVšñ•»MËn«{ü|óÅH,¬ˆ¥pCqŸδ¢·„ÍÊ/™«ÉoFªÑ‚<« eàéýxú9Ë«Ub©$LSv1Ï`Z§Alʾ¼Mo¤1 }ûíØ©Ê®Ú1Ò·*%ŽsÑi÷ AŠ$AžI^µuôü·± è+VSŸJ  ö­p£¬`‘–4ûÇ!@„¢ˆiÎbÃmVÏÕÝÇq4ïÇ#ü9øàÕà¬" == repr(resp) def test___repr__not_started(): resp = StreamResponse(reason=301) assert "" == repr(resp) @pytest.mark.run_loop def test_keep_alive_http10_default(): message = RawRequestMessage('GET', '/', HttpVersion10, CIMultiDict(), True, False) req = request_from_message(message) resp = StreamResponse() yield from resp.prepare(req) assert not resp.keep_alive @pytest.mark.run_loop def test_keep_alive_http10_switched_on(): headers = CIMultiDict(Connection='keep-alive') message = RawRequestMessage('GET', '/', HttpVersion10, headers, False, False) req = request_from_message(message) resp = StreamResponse() yield from resp.prepare(req) assert resp.keep_alive is True @pytest.mark.run_loop def test_keep_alive_http09(): headers = CIMultiDict(Connection='keep-alive') message = RawRequestMessage('GET', '/', HttpVersion(0, 9), headers, False, False) req = request_from_message(message) resp = StreamResponse() yield from resp.prepare(req) assert not resp.keep_alive def test_start_twice(warning): req = make_request('GET', '/') resp = StreamResponse() with warning(DeprecationWarning): impl1 = resp.start(req) impl2 = resp.start(req) assert impl1 is impl2 @pytest.mark.run_loop def test_prepare_calls_signal(): app = mock.Mock() req = make_request('GET', '/', app=app) resp = StreamResponse() sig = mock.Mock() app.on_response_prepare.append(sig) yield from resp.prepare(req) sig.assert_called_with(req, resp) def test_default_nodelay(): resp = StreamResponse() assert resp.tcp_nodelay def test_set_tcp_nodelay_before_start(): resp = StreamResponse() resp.set_tcp_nodelay(False) assert not resp.tcp_nodelay resp.set_tcp_nodelay(True) assert resp.tcp_nodelay @pytest.mark.run_loop def test_set_tcp_nodelay_on_start(): req = make_request('GET', '/') resp = StreamResponse() with mock.patch('aiohttp.web_reqrep.ResponseImpl'): resp_impl = yield from resp.prepare(req) resp_impl.transport.set_tcp_nodelay.assert_called_with(True) resp_impl.transport.set_tcp_cork.assert_called_with(False) @pytest.mark.run_loop def test_set_tcp_nodelay_after_start(): req = make_request('GET', '/') resp = StreamResponse() with mock.patch('aiohttp.web_reqrep.ResponseImpl'): resp_impl = yield from resp.prepare(req) resp_impl.transport.set_tcp_cork.assert_called_with(False) resp_impl.transport.set_tcp_nodelay.assert_called_with(True) resp.set_tcp_nodelay(False) assert not resp.tcp_nodelay resp_impl.transport.set_tcp_nodelay.assert_called_with(False) resp.set_tcp_nodelay(True) assert resp.tcp_nodelay resp_impl.transport.set_tcp_nodelay.assert_called_with(True) def test_default_cork(): resp = StreamResponse() assert not resp.tcp_cork def test_set_tcp_cork_before_start(): resp = StreamResponse() resp.set_tcp_cork(True) assert resp.tcp_cork resp.set_tcp_cork(False) assert not resp.tcp_cork @pytest.mark.run_loop def test_set_tcp_cork_on_start(): req = make_request('GET', '/') resp = StreamResponse() resp.set_tcp_cork(True) with mock.patch('aiohttp.web_reqrep.ResponseImpl'): resp_impl = yield from resp.prepare(req) resp_impl.transport.set_tcp_nodelay.assert_called_with(False) resp_impl.transport.set_tcp_cork.assert_called_with(True) @pytest.mark.run_loop def test_set_tcp_cork_after_start(): req = make_request('GET', '/') resp = StreamResponse() with mock.patch('aiohttp.web_reqrep.ResponseImpl'): resp_impl = yield from resp.prepare(req) resp_impl.transport.set_tcp_cork.assert_called_with(False) resp.set_tcp_cork(True) assert resp.tcp_cork resp_impl.transport.set_tcp_cork.assert_called_with(True) resp.set_tcp_cork(False) assert not resp.tcp_cork resp_impl.transport.set_tcp_cork.assert_called_with(False) # Response class def test_response_ctor(): resp = Response() assert 200 == resp.status assert 'OK' == resp.reason assert resp.body is None assert 0 == resp.content_length assert CIMultiDict([('CONTENT-LENGTH', '0')]) == resp.headers def test_ctor_with_headers_and_status(): resp = Response(body=b'body', status=201, headers={'Age': '12'}) assert 201 == resp.status assert b'body' == resp.body assert 4 == resp.content_length assert (CIMultiDict([('AGE', '12'), ('CONTENT-LENGTH', '4')]) == resp.headers) def test_ctor_content_type(): resp = Response(content_type='application/json') assert 200 == resp.status assert 'OK' == resp.reason assert (CIMultiDict([('CONTENT-TYPE', 'application/json'), ('CONTENT-LENGTH', '0')]) == resp.headers) def test_ctor_text_body_combined(): with pytest.raises(ValueError): Response(body=b'123', text='test text') def test_ctor_text(): resp = Response(text='test text') assert 200 == resp.status assert 'OK' == resp.reason assert (CIMultiDict( [('CONTENT-TYPE', 'text/plain; charset=utf-8'), ('CONTENT-LENGTH', '9')]) == resp.headers) assert resp.body == b'test text' assert resp.text == 'test text' def test_ctor_charset(): resp = Response(text='текÑÑ‚', charset='koi8-r') assert 'текÑÑ‚'.encode('koi8-r') == resp.body assert 'koi8-r' == resp.charset def test_ctor_charset_default_utf8(): resp = Response(text='test test', charset=None) assert 'utf-8' == resp.charset def test_ctor_charset_in_content_type(): with pytest.raises(ValueError): Response(text='test test', content_type='text/plain; charset=utf-8') def test_ctor_charset_without_text(): resp = Response(content_type='text/plain', charset='koi8-r') assert 'koi8-r' == resp.charset def test_ctor_both_content_type_param_and_header_with_text(): 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(): with pytest.raises(ValueError): Response(headers={'Content-Type': 'application/json'}, charset='koi8-r', text='text') def test_ctor_both_content_type_param_and_header(): with pytest.raises(ValueError): Response(headers={'Content-Type': 'application/json'}, content_type='text/html') def test_ctor_both_charset_param_and_header(): with pytest.raises(ValueError): Response(headers={'Content-Type': 'application/json'}, charset='koi8-r') def test_assign_nonbyteish_body(): resp = Response(body=b'data') with pytest.raises(TypeError): resp.body = 123 assert b'data' == resp.body assert 4 == resp.content_length def test_assign_nonstr_text(): resp = Response(text='test') with pytest.raises(TypeError): resp.text = b'123' assert b'test' == resp.body assert 4 == resp.content_length @pytest.mark.run_loop def test_send_headers_for_empty_body(): writer = mock.Mock() req = make_request('GET', '/', writer=writer) resp = Response() writer.drain.return_value = () buf = b'' def append(data): nonlocal buf buf += data writer.write.side_effect = append yield from resp.prepare(req) yield from resp.write_eof() txt = buf.decode('utf8') assert re.match('HTTP/1.1 200 OK\r\nCONTENT-LENGTH: 0\r\n' 'CONNECTION: keep-alive\r\n' 'DATE: .+\r\nSERVER: .+\r\n\r\n', txt) @pytest.mark.run_loop def test_render_with_body(): writer = mock.Mock() req = make_request('GET', '/', writer=writer) resp = Response(body=b'data') writer.drain.return_value = () buf = b'' def append(data): nonlocal buf buf += data writer.write.side_effect = append yield from resp.prepare(req) yield from resp.write_eof() txt = buf.decode('utf8') assert re.match('HTTP/1.1 200 OK\r\nCONTENT-LENGTH: 4\r\n' 'CONNECTION: keep-alive\r\n' 'DATE: .+\r\nSERVER: .+\r\n\r\ndata', txt) @pytest.mark.run_loop def test_send_set_cookie_header(): resp = Response() resp.cookies['name'] = 'value' writer = mock.Mock() req = make_request('GET', '/', writer=writer) writer.drain.return_value = () buf = b'' def append(data): nonlocal buf buf += data writer.write.side_effect = append yield from resp.prepare(req) yield from resp.write_eof() txt = buf.decode('utf8') assert re.match('HTTP/1.1 200 OK\r\nCONTENT-LENGTH: 0\r\n' 'SET-COOKIE: name=value\r\n' 'CONNECTION: keep-alive\r\n' 'DATE: .+\r\nSERVER: .+\r\n\r\n', txt) def test_set_text_with_content_type(): resp = Response() resp.content_type = "text/html" resp.text = "text" assert "text" == resp.text assert b"text" == resp.body assert "text/html" == resp.content_type def test_set_text_with_charset(): resp = Response() resp.content_type = 'text/plain' resp.charset = "KOI8-R" resp.text = "текÑÑ‚" assert "текÑÑ‚" == resp.text assert "текÑÑ‚".encode('koi8-r') == resp.body assert "koi8-r" == resp.charset def test_started_when_not_started(): resp = StreamResponse() assert not resp.prepared @pytest.mark.run_loop def test_started_when_started(): resp = StreamResponse() yield from resp.prepare(make_request('GET', '/')) assert resp.prepared @pytest.mark.run_loop def test_drain_before_start(): resp = StreamResponse() with pytest.raises(RuntimeError): yield from resp.drain() def test_nonstr_text_in_ctor(): with pytest.raises(TypeError): Response(text=b'data') def test_text_in_ctor_with_content_type(): 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(): resp = Response(text='текÑÑ‚', headers={'Content-Type': 'text/html; charset=koi8-r'}) assert 'текÑÑ‚'.encode('koi8-r') == resp.body assert 'text/html' == resp.content_type assert 'koi8-r' == resp.charset def test_text_with_empty_payload(): resp = Response(status=200) assert resp.body is None assert resp.text is None class TestJSONResponse: def test_content_type_is_application_json_by_default(self): resp = json_response('') assert 'application/json' == resp.content_type def test_passing_text_only(self): resp = json_response(text=json.dumps('jaysawn')) assert resp.text == json.dumps('jaysawn') def test_data_and_text_raises_value_error(self): with pytest.raises(ValueError) as excinfo: json_response(data='foo', text='bar') expected_message = ( 'only one of data, text, or body should be specified' ) assert expected_message == excinfo.value.args[0] def test_data_and_body_raises_value_error(self): with pytest.raises(ValueError) as excinfo: json_response(data='foo', body=b'bar') expected_message = ( 'only one of data, text, or body should be specified' ) assert expected_message == excinfo.value.args[0] def test_text_is_json_encoded(self): resp = json_response({'foo': 42}) assert json.dumps({'foo': 42}) == resp.text def test_content_type_is_overrideable(self): resp = json_response({'foo': 42}, content_type='application/vnd.json+api') assert 'application/vnd.json+api' == resp.content_type aiohttp-0.20.2/tests/data.unknown_mime_type0000664000175000017500000000001512552474754021606 0ustar andrewandrew00000000000000file content aiohttp-0.20.2/tests/test_multidict.py0000664000175000017500000006050512603601535020607 0ustar andrewandrew00000000000000import sys import unittest from aiohttp.multidict import (MultiDictProxy, MultiDict, CIMultiDictProxy, CIMultiDict, upstr, _MultiDictProxy, _MultiDict, _CIMultiDictProxy, _CIMultiDict, _upstr) import aiohttp class _Root: cls = None proxy_cls = None upstr_cls = None def test_exposed_names(self): name = self.cls.__name__ while name.startswith('_'): name = name[1:] self.assertIn(name, aiohttp.__all__) class _BaseTest(_Root): def test_instantiate__empty(self): d = self.make_dict() self.assertEqual(d, {}) self.assertEqual(len(d), 0) self.assertEqual(list(d.keys()), []) self.assertEqual(list(d.values()), []) self.assertEqual(list(d.values()), []) self.assertEqual(list(d.items()), []) self.assertEqual(list(d.items()), []) self.assertNotEqual(self.make_dict(), list()) with self.assertRaisesRegex(TypeError, "\(2 given\)"): self.make_dict(('key1', 'value1'), ('key2', 'value2')) def test_instantiate__from_arg0(self): d = self.make_dict([('key', 'value1')]) self.assertEqual(d, {'key': 'value1'}) self.assertEqual(len(d), 1) self.assertEqual(list(d.keys()), ['key']) self.assertEqual(list(d.values()), ['value1']) self.assertEqual(list(d.items()), [('key', 'value1')]) def test_instantiate__from_arg0_dict(self): d = self.make_dict({'key': 'value1'}) self.assertEqual(d, {'key': 'value1'}) self.assertEqual(len(d), 1) self.assertEqual(list(d.keys()), ['key']) self.assertEqual(list(d.values()), ['value1']) self.assertEqual(list(d.items()), [('key', 'value1')]) def test_instantiate__with_kwargs(self): d = self.make_dict([('key', 'value1')], key2='value2') self.assertEqual(d, {'key': 'value1', 'key2': 'value2'}) self.assertEqual(len(d), 2) self.assertEqual(sorted(d.keys()), ['key', 'key2']) self.assertEqual(sorted(d.values()), ['value1', 'value2']) self.assertEqual(sorted(d.items()), [('key', 'value1'), ('key2', 'value2')]) def test_getone(self): d = self.make_dict([('key', 'value1')], key='value2') self.assertEqual(d.getone('key'), 'value1') self.assertEqual(d.get('key'), 'value1') self.assertEqual(d['key'], 'value1') with self.assertRaises(KeyError): d['key2'] with self.assertRaises(KeyError): d.getone('key2') self.assertEqual('default', d.getone('key2', 'default')) def test__iter__(self): d = self.make_dict([('key', 'one'), ('key2', 'two'), ('key', 3)]) self.assertEqual(['key', 'key2', 'key'], list(d)) def test_keys__contains(self): d = self.make_dict([('key', 'one'), ('key2', 'two'), ('key', 3)]) self.assertEqual(list(d.keys()), ['key', 'key2', 'key']) self.assertIn('key', d.keys()) self.assertIn('key2', d.keys()) self.assertNotIn('foo', d.keys()) def test_values__contains(self): d = self.make_dict([('key', 'one'), ('key', 'two'), ('key', 3)]) self.assertEqual(list(d.values()), ['one', 'two', 3]) self.assertIn('one', d.values()) self.assertIn('two', d.values()) self.assertIn(3, d.values()) self.assertNotIn('foo', d.values()) def test_items__contains(self): d = self.make_dict([('key', 'one'), ('key', 'two'), ('key', 3)]) self.assertEqual(list(d.items()), [('key', 'one'), ('key', 'two'), ('key', 3)]) self.assertEqual(list(d.items()), [('key', 'one'), ('key', 'two'), ('key', 3)]) self.assertIn(('key', 'one'), d.items()) self.assertIn(('key', 'two'), d.items()) self.assertIn(('key', 3), d.items()) self.assertNotIn(('foo', 'bar'), d.items()) def test_cannot_create_from_unaccepted(self): with self.assertRaises(TypeError): self.make_dict([(1, 2, 3)]) def test_keys_is_set_less(self): d = self.make_dict([('key', 'value1')]) self.assertLess(d.keys(), {'key', 'key2'}) def test_keys_is_set_less_equal(self): d = self.make_dict([('key', 'value1')]) self.assertLessEqual(d.keys(), {'key'}) def test_keys_is_set_equal(self): d = self.make_dict([('key', 'value1')]) self.assertEqual(d.keys(), {'key'}) def test_keys_is_set_greater(self): d = self.make_dict([('key', 'value1')]) self.assertGreater({'key', 'key2'}, d.keys()) def test_keys_is_set_greater_equal(self): d = self.make_dict([('key', 'value1')]) self.assertGreaterEqual({'key'}, d.keys()) def test_keys_is_set_not_equal(self): d = self.make_dict([('key', 'value1')]) self.assertNotEqual(d.keys(), {'key2'}) def test_eq(self): d = self.make_dict([('key', 'value1')]) self.assertEqual({'key': 'value1'}, d) def test_ne(self): d = self.make_dict([('key', 'value1')]) self.assertNotEqual(d, {'key': 'another_value'}) def test_and(self): d = self.make_dict([('key', 'value1')]) self.assertEqual({'key'}, d.keys() & {'key', 'key2'}) def test_or(self): d = self.make_dict([('key', 'value1')]) self.assertEqual({'key', 'key2'}, d.keys() | {'key2'}) def test_sub(self): d = self.make_dict([('key', 'value1'), ('key2', 'value2')]) self.assertEqual({'key'}, d.keys() - {'key2'}) def test_xor(self): d = self.make_dict([('key', 'value1'), ('key2', 'value2')]) self.assertEqual({'key', 'key3'}, d.keys() ^ {'key2', 'key3'}) def test_isdisjoint(self): d = self.make_dict([('key', 'value1')]) self.assertTrue(d.keys().isdisjoint({'key2'})) def test_isdisjoint2(self): d = self.make_dict([('key', 'value1')]) self.assertFalse(d.keys().isdisjoint({'key'})) def test_repr_issue_410(self): d = self.make_dict() try: raise Exception self.fail("Sould never happen") # pragma: no cover except Exception as e: repr(d) self.assertIs(sys.exc_info()[1], e) def test_or_issue_410(self): d = self.make_dict([('key', 'value')]) try: raise Exception self.fail("Sould never happen") # pragma: no cover except Exception as e: d.keys() | {'other'} self.assertIs(sys.exc_info()[1], e) def test_and_issue_410(self): d = self.make_dict([('key', 'value')]) try: raise Exception self.fail("Sould never happen") # pragma: no cover except Exception as e: d.keys() & {'other'} self.assertIs(sys.exc_info()[1], e) def test_sub_issue_410(self): d = self.make_dict([('key', 'value')]) try: raise Exception self.fail("Sould never happen") # pragma: no cover except Exception as e: d.keys() - {'other'} self.assertIs(sys.exc_info()[1], e) def test_xor_issue_410(self): d = self.make_dict([('key', 'value')]) try: raise Exception self.fail("Sould never happen") # pragma: no cover except Exception as e: d.keys() ^ {'other'} self.assertIs(sys.exc_info()[1], e) class _MultiDictTests(_BaseTest): def test__repr__(self): d = self.make_dict() cls = self.proxy_cls if self.proxy_cls is not None else self.cls self.assertEqual(str(d), "<%s()>" % cls.__name__) d = self.make_dict([('key', 'one'), ('key', 'two')]) self.assertEqual( str(d), "<%s('key': 'one', 'key': 'two')>" % cls.__name__) def test_getall(self): d = self.make_dict([('key', 'value1')], key='value2') self.assertNotEqual(d, {'key': 'value1'}) self.assertEqual(len(d), 2) self.assertEqual(d.getall('key'), ['value1', 'value2']) with self.assertRaisesRegex(KeyError, "some_key"): d.getall('some_key') default = object() self.assertIs(d.getall('some_key', default), default) def test_preserve_stable_ordering(self): d = self.make_dict([('a', 1), ('b', '2'), ('a', 3)]) s = '&'.join('{}={}'.format(k, v) for k, v in d.items()) self.assertEqual('a=1&b=2&a=3', s) def test_get(self): d = self.make_dict([('a', 1), ('a', 2)]) self.assertEqual(1, d['a']) def test_items__repr__(self): d = self.make_dict([('key', 'value1')], key='value2') self.assertEqual(repr(d.items()), "_ItemsView('key': 'value1', 'key': 'value2')") def test_keys__repr__(self): d = self.make_dict([('key', 'value1')], key='value2') self.assertEqual(repr(d.keys()), "_KeysView('key', 'key')") def test_values__repr__(self): d = self.make_dict([('key', 'value1')], key='value2') self.assertEqual(repr(d.values()), "_ValuesView('value1', 'value2')") class _CIMultiDictTests(_Root): def test_basics(self): d = self.make_dict([('KEY', 'value1')], KEY='value2') self.assertEqual(d.getone('key'), 'value1') self.assertEqual(d.get('key'), 'value1') self.assertEqual(d.get('key2', 'val'), 'val') self.assertEqual(d['key'], 'value1') self.assertIn('key', d) with self.assertRaises(KeyError): d['key2'] with self.assertRaises(KeyError): d.getone('key2') def test_getall(self): d = self.make_dict([('KEY', 'value1')], KEY='value2') self.assertNotEqual(d, {'KEY': 'value1'}) self.assertEqual(len(d), 2) self.assertEqual(d.getall('key'), ['value1', 'value2']) with self.assertRaisesRegex(KeyError, "SOME_KEY"): d.getall('some_key') def test_get(self): d = self.make_dict([('A', 1), ('a', 2)]) self.assertEqual(1, d['a']) def test_items__repr__(self): d = self.make_dict([('KEY', 'value1')], key='value2') self.assertEqual(repr(d.items()), "_ItemsView('KEY': 'value1', 'KEY': 'value2')") def test_keys__repr__(self): d = self.make_dict([('KEY', 'value1')], key='value2') self.assertEqual(repr(d.keys()), "_KeysView('KEY', 'KEY')") def test_values__repr__(self): d = self.make_dict([('KEY', 'value1')], key='value2') self.assertEqual(repr(d.values()), "_ValuesView('value1', 'value2')") class _NonProxyCIMultiDict(_CIMultiDictTests): def test_extend_with_upstr(self): us = self.upstr_cls('a') d = self.make_dict() d.extend([(us, 'val')]) self.assertEqual([('A', 'val')], list(d.items())) class _TestProxy(_MultiDictTests): def make_dict(self, *args, **kwargs): dct = self.cls(*args, **kwargs) return self.proxy_cls(dct) def test_copy(self): d1 = self.cls(key='value', a='b') p1 = self.proxy_cls(d1) d2 = p1.copy() self.assertEqual(d1, d2) self.assertIsNot(d1, d2) class _TestCIProxy(_CIMultiDictTests): def make_dict(self, *args, **kwargs): dct = self.cls(*args, **kwargs) return self.proxy_cls(dct) def test_copy(self): d1 = self.cls(key='value', a='b') p1 = self.proxy_cls(d1) d2 = p1.copy() self.assertEqual(d1, d2) self.assertIsNot(d1, d2) class _BaseMutableMultiDictTests(_BaseTest): def test_copy(self): d1 = self.make_dict(key='value', a='b') d2 = d1.copy() self.assertEqual(d1, d2) self.assertIsNot(d1, d2) def make_dict(self, *args, **kwargs): return self.cls(*args, **kwargs) def test__repr__(self): d = self.make_dict() self.assertEqual(str(d), "<%s()>" % self.cls.__name__) d = self.make_dict([('key', 'one'), ('key', 'two')]) self.assertEqual( str(d), "<%s('key': 'one', 'key': 'two')>" % self.cls.__name__) def test_getall(self): d = self.make_dict([('key', 'value1')], key='value2') self.assertEqual(len(d), 2) self.assertEqual(d.getall('key'), ['value1', 'value2']) with self.assertRaisesRegex(KeyError, "some_key"): d.getall('some_key') default = object() self.assertIs(d.getall('some_key', default), default) def test_add(self): d = self.make_dict() self.assertEqual(d, {}) d['key'] = 'one' self.assertEqual(d, {'key': 'one'}) self.assertEqual(d.getall('key'), ['one']) d['key'] = 'two' self.assertEqual(d, {'key': 'two'}) self.assertEqual(d.getall('key'), ['two']) d.add('key', 'one') self.assertEqual(2, len(d)) self.assertEqual(d.getall('key'), ['two', 'one']) d.add('foo', 'bar') self.assertEqual(3, len(d)) self.assertEqual(d.getall('foo'), ['bar']) def test_extend(self): d = self.make_dict() self.assertEqual(d, {}) d.extend([('key', 'one'), ('key', 'two')], key=3, foo='bar') self.assertNotEqual(d, {'key': 'one', 'foo': 'bar'}) self.assertEqual(4, len(d)) itms = d.items() # we can't guarantee order of kwargs self.assertTrue(('key', 'one') in itms) self.assertTrue(('key', 'two') in itms) self.assertTrue(('key', 3) in itms) self.assertTrue(('foo', 'bar') in itms) other = self.make_dict(bar='baz') self.assertEqual(other, {'bar': 'baz'}) d.extend(other) self.assertIn(('bar', 'baz'), d.items()) d.extend({'foo': 'moo'}) self.assertIn(('foo', 'moo'), d.items()) d.extend() self.assertEqual(6, len(d)) with self.assertRaises(TypeError): d.extend('foo', 'bar') def test_extend_from_proxy(self): d = self.make_dict([('a', 'a'), ('b', 'b')]) proxy = self.proxy_cls(d) d2 = self.make_dict() d2.extend(proxy) self.assertEqual([('a', 'a'), ('b', 'b')], list(d2.items())) def test_clear(self): d = self.make_dict([('key', 'one')], key='two', foo='bar') d.clear() self.assertEqual(d, {}) self.assertEqual(list(d.items()), []) def test_del(self): d = self.make_dict([('key', 'one'), ('key', 'two')], foo='bar') del d['key'] self.assertEqual(d, {'foo': 'bar'}) self.assertEqual(list(d.items()), [('foo', 'bar')]) with self.assertRaises(KeyError): del d['key'] def test_set_default(self): d = self.make_dict([('key', 'one'), ('key', 'two')], foo='bar') self.assertEqual('one', d.setdefault('key', 'three')) self.assertEqual('three', d.setdefault('otherkey', 'three')) self.assertIn('otherkey', d) self.assertEqual('three', d['otherkey']) def test_popitem(self): d = self.make_dict() d.add('key', 'val1') d.add('key', 'val2') self.assertEqual(('key', 'val1'), d.popitem()) self.assertEqual([('key', 'val2')], list(d.items())) def test_popitem_empty_multidict(self): d = self.make_dict() with self.assertRaises(KeyError): d.popitem() def test_pop(self): d = self.make_dict() d.add('key', 'val1') d.add('key', 'val2') self.assertEqual('val1', d.pop('key')) self.assertFalse(d) def test_pop_default(self): d = self.make_dict(other='val') self.assertEqual('default', d.pop('key', 'default')) self.assertIn('other', d) def test_pop_raises(self): d = self.make_dict(other='val') with self.assertRaises(KeyError): d.pop('key') self.assertIn('other', d) def test_update(self): d = self.make_dict() d.add('key', 'val1') d.add('key', 'val2') d.add('key2', 'val3') d.update(key='val') self.assertEqual([('key2', 'val3'), ('key', 'val')], list(d.items())) class _CIMutableMultiDictTests(_Root): def make_dict(self, *args, **kwargs): return self.cls(*args, **kwargs) def test_getall(self): d = self.make_dict([('KEY', 'value1')], KEY='value2') self.assertNotEqual(d, {'KEY': 'value1'}) self.assertEqual(len(d), 2) self.assertEqual(d.getall('key'), ['value1', 'value2']) with self.assertRaisesRegex(KeyError, "SOME_KEY"): d.getall('some_key') def test_ctor(self): d = self.make_dict(k1='v1') self.assertEqual('v1', d['K1']) def test_setitem(self): d = self.make_dict() d['k1'] = 'v1' self.assertEqual('v1', d['K1']) def test_delitem(self): d = self.make_dict() d['k1'] = 'v1' self.assertIn('K1', d) del d['k1'] self.assertNotIn('K1', d) def test_copy(self): d1 = self.make_dict(key='KEY', a='b') d2 = d1.copy() self.assertEqual(d1, d2) self.assertIsNot(d1, d2) def test__repr__(self): d = self.make_dict() self.assertEqual(str(d), "<%s()>" % self.cls.__name__) d = self.make_dict([('KEY', 'one'), ('KEY', 'two')]) self.assertEqual( str(d), "<%s('KEY': 'one', 'KEY': 'two')>" % self.cls.__name__) def test_add(self): d = self.make_dict() self.assertEqual(d, {}) d['KEY'] = 'one' self.assertEqual(d, {'KEY': 'one'}) self.assertEqual(d.getall('key'), ['one']) d['KEY'] = 'two' self.assertEqual(d, {'KEY': 'two'}) self.assertEqual(d.getall('key'), ['two']) d.add('KEY', 'one') self.assertEqual(2, len(d)) self.assertEqual(d.getall('key'), ['two', 'one']) d.add('FOO', 'bar') self.assertEqual(3, len(d)) self.assertEqual(d.getall('foo'), ['bar']) def test_extend(self): d = self.make_dict() self.assertEqual(d, {}) d.extend([('KEY', 'one'), ('key', 'two')], key=3, foo='bar') self.assertNotEqual(d, {'KEY': 'one', 'FOO': 'bar'}) self.assertEqual(4, len(d)) itms = d.items() # we can't guarantee order of kwargs self.assertTrue(('KEY', 'one') in itms) self.assertTrue(('KEY', 'two') in itms) self.assertTrue(('KEY', 3) in itms) self.assertTrue(('FOO', 'bar') in itms) other = self.make_dict(bar='baz') self.assertEqual(other, {'BAR': 'baz'}) d.extend(other) self.assertIn(('BAR', 'baz'), d.items()) d.extend({'FOO': 'moo'}) self.assertIn(('FOO', 'moo'), d.items()) d.extend() self.assertEqual(6, len(d)) with self.assertRaises(TypeError): d.extend('foo', 'bar') def test_extend_from_proxy(self): d = self.make_dict([('a', 'a'), ('b', 'b')]) proxy = self.proxy_cls(d) d2 = self.make_dict() d2.extend(proxy) self.assertEqual([('A', 'a'), ('B', 'b')], list(d2.items())) def test_clear(self): d = self.make_dict([('KEY', 'one')], key='two', foo='bar') d.clear() self.assertEqual(d, {}) self.assertEqual(list(d.items()), []) def test_del(self): d = self.make_dict([('KEY', 'one'), ('key', 'two')], foo='bar') del d['key'] self.assertEqual(d, {'FOO': 'bar'}) self.assertEqual(list(d.items()), [('FOO', 'bar')]) with self.assertRaises(KeyError): del d['key'] def test_set_default(self): d = self.make_dict([('KEY', 'one'), ('key', 'two')], foo='bar') self.assertEqual('one', d.setdefault('key', 'three')) self.assertEqual('three', d.setdefault('otherkey', 'three')) self.assertIn('otherkey', d) self.assertEqual('three', d['OTHERKEY']) def test_popitem(self): d = self.make_dict() d.add('KEY', 'val1') d.add('key', 'val2') self.assertEqual(('KEY', 'val1'), d.popitem()) self.assertEqual([('KEY', 'val2')], list(d.items())) def test_popitem_empty_multidict(self): d = self.make_dict() with self.assertRaises(KeyError): d.popitem() def test_pop(self): d = self.make_dict() d.add('KEY', 'val1') d.add('key', 'val2') self.assertEqual('val1', d.pop('KEY')) self.assertFalse(d) def test_pop_default(self): d = self.make_dict(OTHER='val') self.assertEqual('default', d.pop('key', 'default')) self.assertIn('other', d) def test_pop_raises(self): d = self.make_dict(OTHER='val') with self.assertRaises(KeyError): d.pop('KEY') self.assertIn('other', d) def test_update(self): d = self.make_dict() d.add('KEY', 'val1') d.add('key', 'val2') d.add('key2', 'val3') d.update(key='val') self.assertEqual([('KEY2', 'val3'), ('KEY', 'val')], list(d.items())) class TestPyMultiDictProxy(_TestProxy, unittest.TestCase): cls = _MultiDict proxy_cls = _MultiDictProxy class TestPyCIMultiDictProxy(_TestCIProxy, unittest.TestCase): cls = _CIMultiDict proxy_cls = _CIMultiDictProxy class PyMutableMultiDictTests(_BaseMutableMultiDictTests, unittest.TestCase): cls = _MultiDict proxy_cls = _MultiDictProxy class PyCIMutableMultiDictTests(_CIMutableMultiDictTests, _NonProxyCIMultiDict, unittest.TestCase): cls = _CIMultiDict upstr_cls = _upstr proxy_cls = _CIMultiDictProxy class TestMultiDictProxy(_TestProxy, unittest.TestCase): cls = MultiDict proxy_cls = MultiDictProxy class TestCIMultiDictProxy(_TestCIProxy, unittest.TestCase): cls = CIMultiDict proxy_cls = CIMultiDictProxy class MutableMultiDictTests(_BaseMutableMultiDictTests, unittest.TestCase): cls = MultiDict proxy_cls = MultiDictProxy class CIMutableMultiDictTests(_CIMutableMultiDictTests, _NonProxyCIMultiDict, unittest.TestCase): cls = CIMultiDict upstr_cls = upstr proxy_cls = CIMultiDictProxy class _UpStrMixin: cls = None def test_ctor(self): s = self.cls() self.assertEqual('', s) def test_ctor_str(self): s = self.cls('a') self.assertEqual('A', s) def test_ctor_str_uppercase(self): s = self.cls('A') self.assertEqual('A', s) def test_ctor_buffer(self): s = self.cls(b'a') self.assertEqual('A', s) def test_ctor_repr(self): s = self.cls(None) self.assertEqual('NONE', s) def test_upper(self): s = self.cls('a') self.assertIs(s, s.upper()) class TestPyUpStr(_UpStrMixin, unittest.TestCase): cls = _upstr class TestUpStr(_UpStrMixin, unittest.TestCase): cls = upstr class TypesMixin: proxy = ciproxy = mdict = cimdict = None def test_proxies(self): self.assertTrue(issubclass(self.ciproxy, self.proxy)) def test_dicts(self): self.assertTrue(issubclass(self.cimdict, self.mdict)) def test_proxy_not_inherited_from_dict(self): self.assertFalse(issubclass(self.proxy, self.mdict)) def test_dict_not_inherited_from_proxy(self): self.assertFalse(issubclass(self.mdict, self.proxy)) def test_create_multidict_proxy_from_nonmultidict(self): with self.assertRaises(TypeError): self.proxy({}) def test_create_multidict_proxy_from_cimultidict(self): d = self.cimdict(key='val') p = self.proxy(d) self.assertEqual(p, d) def test_create_cimultidict_proxy_from_nonmultidict(self): with self.assertRaises(TypeError): self.ciproxy({}) def test_create_ci_multidict_proxy_from_multidict(self): d = self.mdict(key='val') with self.assertRaises(TypeError): self.ciproxy(d) class TestPyTypes(TypesMixin, unittest.TestCase): proxy = _MultiDictProxy ciproxy = _CIMultiDictProxy mdict = _MultiDict cimdict = _CIMultiDict class TestTypes(TypesMixin, unittest.TestCase): proxy = MultiDictProxy ciproxy = CIMultiDictProxy mdict = MultiDict cimdict = CIMultiDict aiohttp-0.20.2/tests/test_errors.py0000664000175000017500000000036012607257712020126 0ustar andrewandrew00000000000000"""Tests for errors.py""" import aiohttp def test_bad_status_line1(): err = aiohttp.BadStatusLine(b'') assert str(err) == "b''" def test_bad_status_line2(): err = aiohttp.BadStatusLine('Test') assert str(err) == 'Test' aiohttp-0.20.2/tests/test_stream_parser.py0000664000175000017500000002121512623705454021462 0ustar andrewandrew00000000000000"""Tests for parsers.py""" import pytest from unittest import mock from aiohttp import parsers DATA = b'line1\nline2\nline3\n' @pytest.fixture def lines_parser(): return parsers.LinesParser() def test_at_eof(loop): proto = parsers.StreamParser(loop=loop) assert not proto.at_eof() proto.feed_eof() assert proto.at_eof() def test_exception(loop): stream = parsers.StreamParser(loop=loop) assert stream.exception() is None exc = ValueError() stream.set_exception(exc) assert stream.exception() is exc def test_exception_connection_error(loop): stream = parsers.StreamParser(loop=loop) assert stream.exception() is None exc = ConnectionError() stream.set_exception(exc) assert stream.exception() is not exc assert isinstance(stream.exception(), RuntimeError) assert stream.exception().__cause__ is exc assert stream.exception().__context__ is exc def test_exception_waiter(loop, lines_parser): stream = parsers.StreamParser(loop=loop) stream._parser = lines_parser buf = stream._output = parsers.FlowControlDataQueue( stream, loop=loop) exc = ValueError() stream.set_exception(exc) assert buf.exception() is exc def test_feed_data(loop): stream = parsers.StreamParser(loop=loop) stream.feed_data(DATA) assert DATA == bytes(stream._buffer) def test_feed_none_data(loop): stream = parsers.StreamParser(loop=loop) stream.feed_data(None) assert b'' == bytes(stream._buffer) def test_set_parser_unset_prev(loop, lines_parser): stream = parsers.StreamParser(loop=loop) stream.set_parser(lines_parser) unset = stream.unset_parser = mock.Mock() stream.set_parser(lines_parser) assert unset.called def test_set_parser_exception(loop, lines_parser): stream = parsers.StreamParser(loop=loop) exc = ValueError() stream.set_exception(exc) s = stream.set_parser(lines_parser) assert s.exception() is exc def test_set_parser_feed_existing(loop, lines_parser): stream = parsers.StreamParser(loop=loop) stream.feed_data(b'line1') stream.feed_data(b'\r\nline2\r\ndata') s = stream.set_parser(lines_parser) assert ([(bytearray(b'line1\r\n'), 7), (bytearray(b'line2\r\n'), 7)] == list(s._buffer)) assert b'data' == bytes(stream._buffer) assert stream._parser is not None stream.unset_parser() assert stream._parser is None assert b'data' == bytes(stream._buffer) assert s._eof def test_set_parser_feed_existing_exc(loop): def p(out, buf): yield from buf.read(1) raise ValueError() stream = parsers.StreamParser(loop=loop) stream.feed_data(b'line1') s = stream.set_parser(p) assert isinstance(s.exception(), ValueError) def test_set_parser_feed_existing_eof(loop, lines_parser): stream = parsers.StreamParser(loop=loop) stream.feed_data(b'line1') stream.feed_data(b'\r\nline2\r\ndata') stream.feed_eof() s = stream.set_parser(lines_parser) assert ([(bytearray(b'line1\r\n'), 7), (bytearray(b'line2\r\n'), 7)] == list(s._buffer)) assert b'data' == bytes(stream._buffer) assert stream._parser is None def test_set_parser_feed_existing_eof_exc(loop): def p(out, buf): try: while True: yield # read chunk except parsers.EofStream: raise ValueError() stream = parsers.StreamParser(loop=loop) stream.feed_data(b'line1') stream.feed_eof() s = stream.set_parser(p) assert isinstance(s.exception(), ValueError) def test_set_parser_feed_existing_eof_unhandled_eof(loop): def p(out, buf): while True: yield # read chunk stream = parsers.StreamParser(loop=loop) stream.feed_data(b'line1') stream.feed_eof() s = stream.set_parser(p) assert not s.is_eof() assert isinstance(s.exception(), RuntimeError) def test_set_parser_unset(loop, lines_parser): stream = parsers.StreamParser(loop=loop) s = stream.set_parser(lines_parser) stream.feed_data(b'line1\r\nline2\r\n') assert ([(bytearray(b'line1\r\n'), 7), (bytearray(b'line2\r\n'), 7)] == list(s._buffer)) assert b'' == bytes(stream._buffer) stream.unset_parser() assert s._eof assert b'' == bytes(stream._buffer) def test_set_parser_feed_existing_stop(loop): def LinesParser(out, buf): try: chunk = yield from buf.readuntil(b'\n') out.feed_data(chunk, len(chunk)) chunk = yield from buf.readuntil(b'\n') out.feed_data(chunk, len(chunk)) finally: out.feed_eof() stream = parsers.StreamParser(loop=loop) stream.feed_data(b'line1') stream.feed_data(b'\r\nline2\r\ndata') s = stream.set_parser(LinesParser) assert b'line1\r\nline2\r\n' == b''.join(d for d, _ in s._buffer) assert b'data' == bytes(stream._buffer) assert stream._parser is None assert s._eof def test_feed_parser(loop, lines_parser): stream = parsers.StreamParser(loop=loop) s = stream.set_parser(lines_parser) stream.feed_data(b'line1') stream.feed_data(b'\r\nline2\r\ndata') assert b'data' == bytes(stream._buffer) stream.feed_eof() assert ([(bytearray(b'line1\r\n'), 7), (bytearray(b'line2\r\n'), 7)] == list(s._buffer)) assert b'data' == bytes(stream._buffer) assert s.is_eof() def test_feed_parser_exc(loop): def p(out, buf): yield # read chunk raise ValueError() stream = parsers.StreamParser(loop=loop) s = stream.set_parser(p) stream.feed_data(b'line1') assert isinstance(s.exception(), ValueError) assert b'' == bytes(stream._buffer) def test_feed_parser_stop(loop): def p(out, buf): yield # chunk stream = parsers.StreamParser(loop=loop) stream.set_parser(p) stream.feed_data(b'line1') assert stream._parser is None assert b'' == bytes(stream._buffer) def test_feed_eof_exc(loop): def p(out, buf): try: while True: yield # read chunk except parsers.EofStream: raise ValueError() stream = parsers.StreamParser(loop=loop) s = stream.set_parser(p) stream.feed_data(b'line1') assert s.exception() is None stream.feed_eof() assert isinstance(s.exception(), ValueError) def test_feed_eof_stop(loop): def p(out, buf): try: while True: yield # read chunk except parsers.EofStream: out.feed_eof() stream = parsers.StreamParser(loop=loop) s = stream.set_parser(p) stream.feed_data(b'line1') stream.feed_eof() assert s._eof def test_feed_eof_unhandled_eof(loop): def p(out, buf): while True: yield # read chunk stream = parsers.StreamParser(loop=loop) s = stream.set_parser(p) stream.feed_data(b'line1') stream.feed_eof() assert not s.is_eof() assert isinstance(s.exception(), RuntimeError) def test_feed_parser2(loop, lines_parser): stream = parsers.StreamParser(loop=loop) s = stream.set_parser(lines_parser) stream.feed_data(b'line1\r\nline2\r\n') stream.feed_eof() assert ([(bytearray(b'line1\r\n'), 7), (bytearray(b'line2\r\n'), 7)] == list(s._buffer)) assert b'' == bytes(stream._buffer) assert s._eof def test_unset_parser_eof_exc(loop): def p(out, buf): try: while True: yield # read chunk except parsers.EofStream: raise ValueError() stream = parsers.StreamParser(loop=loop) s = stream.set_parser(p) stream.feed_data(b'line1') stream.unset_parser() assert isinstance(s.exception(), ValueError) assert stream._parser is None def test_unset_parser_eof_unhandled_eof(loop): def p(out, buf): while True: yield # read chunk stream = parsers.StreamParser(loop=loop) s = stream.set_parser(p) stream.feed_data(b'line1') stream.unset_parser() assert isinstance(s.exception(), RuntimeError) assert not s.is_eof() def test_unset_parser_stop(loop): def p(out, buf): try: while True: yield # read chunk except parsers.EofStream: out.feed_eof() stream = parsers.StreamParser(loop=loop) s = stream.set_parser(p) stream.feed_data(b'line1') stream.unset_parser() assert s._eof def test_eof_exc(loop): def p(out, buf): while True: yield # read chunk class CustomEofErr(Exception): pass stream = parsers.StreamParser(eof_exc_class=CustomEofErr, loop=loop) s = stream.set_parser(p) stream.feed_eof() assert isinstance(s.exception(), CustomEofErr) aiohttp-0.20.2/LICENSE.txt0000664000175000017500000002610412642276035015664 0ustar andrewandrew00000000000000Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2013-2016 Nikolay Kim and Andrew Svetlov Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. aiohttp-0.20.2/examples/0000775000175000017500000000000012643555674015666 5ustar andrewandrew00000000000000aiohttp-0.20.2/examples/tcp_protocol_parser.py0000775000175000017500000001151112552474754022323 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """Protocol parser example.""" import argparse import aiohttp import collections import asyncio try: import signal except ImportError: signal = None MSG_TEXT = b'text:' MSG_PING = b'ping:' MSG_PONG = b'pong:' MSG_STOP = b'stop:' Message = collections.namedtuple('Message', ('tp', 'data')) def my_protocol_parser(out, buf): """Parser is used with StreamParser for incremental protocol parsing. Parser is a generator function, but it is not a coroutine. Usually parsers are implemented as a state machine. more details in asyncio/parsers.py existing parsers: * http protocol parsers asyncio/http/protocol.py * websocket parser asyncio/http/websocket.py """ while True: tp = yield from buf.read(5) if tp in (MSG_PING, MSG_PONG): # skip line yield from buf.skipuntil(b'\r\n') out.feed_data(Message(tp, None)) elif tp == MSG_STOP: out.feed_data(Message(tp, None)) elif tp == MSG_TEXT: # read text text = yield from buf.readuntil(b'\r\n') out.feed_data(Message(tp, text.strip().decode('utf-8'))) else: raise ValueError('Unknown protocol prefix.') class MyProtocolWriter: def __init__(self, transport): self.transport = transport def ping(self): self.transport.write(b'ping:\r\n') def pong(self): self.transport.write(b'pong:\r\n') def stop(self): self.transport.write(b'stop:\r\n') def send_text(self, text): self.transport.write( 'text:{}\r\n'.format(text.strip()).encode('utf-8')) class EchoServer(asyncio.Protocol): def connection_made(self, transport): print('Connection made') self.transport = transport self.stream = aiohttp.StreamParser() asyncio.Task(self.dispatch()) def data_received(self, data): self.stream.feed_data(data) def eof_received(self): self.stream.feed_eof() def connection_lost(self, exc): print('Connection lost') @asyncio.coroutine def dispatch(self): reader = self.stream.set_parser(my_protocol_parser) writer = MyProtocolWriter(self.transport) while True: try: msg = yield from reader.read() except aiohttp.ConnectionError: # client has been disconnected break print('Message received: {}'.format(msg)) if msg.tp == MSG_PING: writer.pong() elif msg.tp == MSG_TEXT: writer.send_text('Re: ' + msg.data) elif msg.tp == MSG_STOP: self.transport.close() break @asyncio.coroutine def start_client(loop, host, port): transport, stream = yield from loop.create_connection( aiohttp.StreamProtocol, host, port) reader = stream.reader.set_parser(my_protocol_parser) writer = MyProtocolWriter(transport) writer.ping() message = 'This is the message. It will be echoed.' while True: try: msg = yield from reader.read() except aiohttp.ConnectionError: print('Server has been disconnected.') break print('Message received: {}'.format(msg)) if msg.tp == MSG_PONG: writer.send_text(message) print('data sent:', message) elif msg.tp == MSG_TEXT: writer.stop() print('stop sent') break transport.close() def start_server(loop, host, port): f = loop.create_server(EchoServer, host, port) srv = loop.run_until_complete(f) x = srv.sockets[0] print('serving on', x.getsockname()) loop.run_forever() ARGS = argparse.ArgumentParser(description="Protocol parser example.") ARGS.add_argument( '--server', action="store_true", dest='server', default=False, help='Run tcp server') ARGS.add_argument( '--client', action="store_true", dest='client', default=False, help='Run tcp client') ARGS.add_argument( '--host', action="store", dest='host', default='127.0.0.1', help='Host name') ARGS.add_argument( '--port', action="store", dest='port', default=9999, type=int, help='Port number') if __name__ == '__main__': args = ARGS.parse_args() if ':' in args.host: args.host, port = args.host.split(':', 1) args.port = int(port) if (not (args.server or args.client)) or (args.server and args.client): print('Please specify --server or --client\n') ARGS.print_help() else: loop = asyncio.get_event_loop() if signal is not None: loop.add_signal_handler(signal.SIGINT, loop.stop) if args.server: start_server(loop, args.host, args.port) else: loop.run_until_complete(start_client(loop, args.host, args.port)) aiohttp-0.20.2/examples/web_classview1.py0000664000175000017500000000342512637063114021144 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """Example for aiohttp.web class based views """ import asyncio import functools import json from aiohttp.web import json_response, Application, Response, View class MyView(View): async def get(self): return json_response({ 'method': 'get', 'args': dict(self.request.GET), 'headers': dict(self.request.headers), }, dumps=functools.partial(json.dumps, indent=4)) async def post(self): data = await self.request.post() return json_response({ 'method': 'post', 'args': dict(self.request.GET), 'data': dict(data), 'headers': dict(self.request.headers), }, dumps=functools.partial(json.dumps, indent=4)) async def index(request): txt = """ Class based view example

Class based view example

  • / This page
  • /get Returns GET data.
  • /post Returns POST data.
""" return Response(text=txt, content_type='text/html') async def init(loop): app = Application(loop=loop) app.router.add_route('GET', '/', index) app.router.add_route('GET', '/get', MyView) app.router.add_route('POST', '/post', MyView) handler = app.make_handler() srv = await loop.create_server(handler, '127.0.0.1', 8080) print("Server started at http://127.0.0.1:8080") return srv, handler loop = asyncio.get_event_loop() srv, handler = loop.run_until_complete(init(loop)) try: loop.run_forever() except KeyboardInterrupt: loop.run_until_complete(handler.finish_connections()) aiohttp-0.20.2/examples/client_auth.py0000775000175000017500000000131612556410432020524 0ustar andrewandrew00000000000000import aiohttp import asyncio @asyncio.coroutine def go(session): print('Query http://httpbin.org/basic-auth/andrew/password') resp = yield from session.get( 'http://httpbin.org/basic-auth/andrew/password') print(resp.status) try: body = yield from resp.text() print(body) finally: yield from resp.release() loop = asyncio.get_event_loop() session = aiohttp.ClientSession(auth=aiohttp.BasicAuth('andrew', 'password'), loop=loop) loop.run_until_complete(go(session)) session.close() # run loop iteration for actual session closing loop.stop() loop.run_forever() loop.close() aiohttp-0.20.2/examples/web_cookies.py0000775000175000017500000000236712552474754020542 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """Example for aiohttp.web basic server with cookies. """ import asyncio from aiohttp import web tmpl = '''\ Login
Logout
{} ''' @asyncio.coroutine def root(request): resp = web.Response(content_type='text/html') resp.text = tmpl.format(request.cookies) return resp @asyncio.coroutine def login(request): resp = web.HTTPFound(location='/') resp.set_cookie('AUTH', 'secret') return resp @asyncio.coroutine def logout(request): resp = web.HTTPFound(location='/') resp.del_cookie('AUTH') return resp @asyncio.coroutine def init(loop): app = web.Application(loop=loop) app.router.add_route('GET', '/', root) app.router.add_route('GET', '/login', login) app.router.add_route('GET', '/logout', logout) handler = app.make_handler() srv = yield from loop.create_server(handler, '127.0.0.1', 8080) print("Server started at http://127.0.0.1:8080") return srv, handler loop = asyncio.get_event_loop() srv, handler = loop.run_until_complete(init(loop)) try: loop.run_forever() except KeyboardInterrupt: loop.run_until_complete(handler.finish_connections()) aiohttp-0.20.2/examples/web_srv.py0000775000175000017500000000325212634126367017705 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """Example for aiohttp.web basic server """ import asyncio import textwrap from aiohttp.web import Application, Response, StreamResponse def intro(request): txt = textwrap.dedent("""\ Type {url}/hello/John {url}/simple or {url}/change_body in browser url bar """).format(url='127.0.0.1:8080') binary = txt.encode('utf8') resp = StreamResponse() resp.content_length = len(binary) yield from resp.prepare(request) resp.write(binary) return resp def simple(request): return Response(body=b'Simple answer') def change_body(request): resp = Response() resp.body = b"Body changed" return resp @asyncio.coroutine def hello(request): resp = StreamResponse() name = request.match_info.get('name', 'Anonymous') answer = ('Hello, ' + name).encode('utf8') resp.content_length = len(answer) yield from resp.prepare(request) resp.write(answer) yield from resp.write_eof() return resp @asyncio.coroutine def init(loop): app = Application(loop=loop) app.router.add_route('GET', '/', intro) app.router.add_route('GET', '/simple', simple) app.router.add_route('GET', '/change_body', change_body) app.router.add_route('GET', '/hello/{name}', hello) app.router.add_route('GET', '/hello', hello) handler = app.make_handler() srv = yield from loop.create_server(handler, '127.0.0.1', 8080) print("Server started at http://127.0.0.1:8080") return srv, handler loop = asyncio.get_event_loop() srv, handler = loop.run_until_complete(init(loop)) try: loop.run_forever() except KeyboardInterrupt: loop.run_until_complete(handler.finish_connections()) aiohttp-0.20.2/examples/wssrv.py0000775000175000017500000002316712552474754017436 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """Multiprocess WebSocket http chat example.""" import argparse import os import socket import signal import time import asyncio import aiohttp import aiohttp.server from aiohttp import websocket ARGS = argparse.ArgumentParser(description="Run simple http server.") ARGS.add_argument( '--host', action="store", dest='host', default='127.0.0.1', help='Host name') ARGS.add_argument( '--port', action="store", dest='port', default=8080, type=int, help='Port number') ARGS.add_argument( '--workers', action="store", dest='workers', default=2, type=int, help='Number of workers.') WS_FILE = os.path.join(os.path.dirname(__file__), 'websocket.html') class HttpRequestHandler(aiohttp.server.ServerHttpProtocol): clients = None # list of all active connections parent = None # supervisor, we use it as broadcaster to all workers def __init__(self, *args, parent=None, clients=None, **kwargs): super().__init__(*args, **kwargs) self.parent = parent self.clients = clients @asyncio.coroutine def handle_request(self, message, payload): upgrade = 'websocket' in message.headers.get('UPGRADE', '').lower() if upgrade: # websocket handshake status, headers, parser, writer, protocol = websocket.do_handshake( message.method, message.headers, self.transport) resp = aiohttp.Response( self.writer, status, http_version=message.version) resp.add_headers(*headers) resp.send_headers() # install websocket parser dataqueue = self.reader.set_parser(parser) # notify everybody print('{}: Someone joined.'.format(os.getpid())) for wsc in self.clients: wsc.send(b'Someone joined.') self.clients.append(writer) self.parent.send(b'Someone joined.') # chat dispatcher while True: try: msg = yield from dataqueue.read() except: # client dropped connection break if msg.tp == websocket.MSG_PING: writer.pong() elif msg.tp == websocket.MSG_TEXT: data = msg.data.strip() print('{}: {}'.format(os.getpid(), data)) for wsc in self.clients: if wsc is not writer: wsc.send(data.encode()) self.parent.send(data) elif msg.tp == websocket.MSG_CLOSE: break # notify everybody print('{}: Someone disconnected.'.format(os.getpid())) self.parent.send(b'Someone disconnected.') self.clients.remove(writer) for wsc in self.clients: wsc.send(b'Someone disconnected.') else: # send html page with js chat response = aiohttp.Response( self.writer, 200, http_version=message.version) response.add_header('Transfer-Encoding', 'chunked') response.add_header('Content-type', 'text/html') response.send_headers() try: with open(WS_FILE, 'rb') as fp: chunk = fp.read(8192) while chunk: if not response.write(chunk): break chunk = fp.read(8192) except OSError: response.write(b'Cannot open') yield from response.write_eof() if response.keep_alive(): self.keep_alive(True) class ChildProcess: def __init__(self, up_read, down_write, args, sock): self.up_read = up_read self.down_write = down_write self.args = args self.sock = sock self.clients = [] def start(self): # start server self.loop = loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) def stop(): self.loop.stop() os._exit(0) loop.add_signal_handler(signal.SIGINT, stop) # heartbeat asyncio.Task(self.heartbeat()) asyncio.get_event_loop().run_forever() os._exit(0) @asyncio.coroutine def start_server(self, writer): socks = yield from self.loop.create_server( lambda: HttpRequestHandler( debug=True, keep_alive=75, parent=writer, clients=self.clients), sock=self.sock) print('Starting srv worker process {} on {}'.format( os.getpid(), socks.sockets[0].getsockname())) @asyncio.coroutine def heartbeat(self): # setup pipes read_transport, read_proto = yield from self.loop.connect_read_pipe( aiohttp.StreamProtocol, os.fdopen(self.up_read, 'rb')) write_transport, _ = yield from self.loop.connect_write_pipe( aiohttp.StreamProtocol, os.fdopen(self.down_write, 'wb')) reader = read_proto.reader.set_parser(websocket.WebSocketParser) writer = websocket.WebSocketWriter(write_transport) asyncio.Task(self.start_server(writer)) while True: try: msg = yield from reader.read() except: print('Supervisor is dead, {} stopping...'.format(os.getpid())) self.loop.stop() break if msg.tp == websocket.MSG_PING: writer.pong() elif msg.tp == websocket.MSG_CLOSE: break elif msg.tp == websocket.MSG_TEXT: # broadcast message for wsc in self.clients: wsc.send(msg.data.strip().encode()) read_transport.close() write_transport.close() class Worker: _started = False def __init__(self, sv, loop, args, sock): self.sv = sv self.loop = loop self.args = args self.sock = sock self.start() def start(self): assert not self._started self._started = True up_read, up_write = os.pipe() down_read, down_write = os.pipe() args, sock = self.args, self.sock pid = os.fork() if pid: # parent os.close(up_read) os.close(down_write) asyncio.async(self.connect(pid, up_write, down_read)) else: # child os.close(up_write) os.close(down_read) # cleanup after fork asyncio.set_event_loop(None) # setup process process = ChildProcess(up_read, down_write, args, sock) process.start() @asyncio.coroutine def heartbeat(self, writer): while True: yield from asyncio.sleep(15) if (time.monotonic() - self.ping) < 30: writer.ping() else: print('Restart unresponsive worker process: {}'.format( self.pid)) self.kill() self.start() return @asyncio.coroutine def chat(self, reader): while True: try: msg = yield from reader.read() except: print('Restart unresponsive worker process: {}'.format( self.pid)) self.kill() self.start() return if msg.tp == websocket.MSG_PONG: self.ping = time.monotonic() elif msg.tp == websocket.MSG_TEXT: # broadcast to all workers for worker in self.sv.workers: if self.pid != worker.pid: worker.writer.send(msg.data) @asyncio.coroutine def connect(self, pid, up_write, down_read): # setup pipes read_transport, proto = yield from self.loop.connect_read_pipe( aiohttp.StreamProtocol, os.fdopen(down_read, 'rb')) write_transport, _ = yield from self.loop.connect_write_pipe( aiohttp.StreamProtocol, os.fdopen(up_write, 'wb')) # websocket protocol reader = proto.reader.set_parser(websocket.WebSocketParser) writer = websocket.WebSocketWriter(write_transport) # store info self.pid = pid self.ping = time.monotonic() self.writer = writer self.rtransport = read_transport self.wtransport = write_transport self.chat_task = asyncio.async(self.chat(reader)) self.heartbeat_task = asyncio.async(self.heartbeat(writer)) def kill(self): self._started = False self.chat_task.cancel() self.heartbeat_task.cancel() self.rtransport.close() self.wtransport.close() os.kill(self.pid, signal.SIGTERM) class Supervisor: def __init__(self, args): self.loop = asyncio.get_event_loop() self.args = args self.workers = [] def start(self): # bind socket sock = self.sock = socket.socket() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((self.args.host, self.args.port)) sock.listen(1024) sock.setblocking(False) # start processes for idx in range(self.args.workers): self.workers.append(Worker(self, self.loop, self.args, sock)) self.loop.add_signal_handler(signal.SIGINT, lambda: self.loop.stop()) self.loop.run_forever() def main(): args = ARGS.parse_args() if ':' in args.host: args.host, port = args.host.split(':', 1) args.port = int(port) supervisor = Supervisor(args) supervisor.start() if __name__ == '__main__': main() aiohttp-0.20.2/examples/web_ws.py0000775000175000017500000000351612602466630017522 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """Example for aiohttp.web websocket server """ import asyncio import os from aiohttp.web import Application, Response, MsgType, WebSocketResponse WS_FILE = os.path.join(os.path.dirname(__file__), 'websocket.html') @asyncio.coroutine def wshandler(request): resp = WebSocketResponse() ok, protocol = resp.can_start(request) if not ok: with open(WS_FILE, 'rb') as fp: return Response(body=fp.read(), content_type='text/html') yield from resp.prepare(request) print('Someone joined.') for ws in request.app['sockets']: ws.send_str('Someone joined') request.app['sockets'].append(resp) while True: msg = yield from resp.receive() if msg.tp == MsgType.text: for ws in request.app['sockets']: if ws is not resp: ws.send_str(msg.data) else: break request.app['sockets'].remove(resp) print('Someone disconnected.') for ws in request.app['sockets']: ws.send_str('Someone disconnected.') return resp @asyncio.coroutine def init(loop): app = Application(loop=loop) app['sockets'] = [] app.router.add_route('GET', '/', wshandler) handler = app.make_handler() srv = yield from loop.create_server(handler, '127.0.0.1', 8080) print("Server started at http://127.0.0.1:8080") return app, srv, handler @asyncio.coroutine def finish(app, srv, handler): for ws in app['sockets']: ws.close() app['sockets'].clear() yield from asyncio.sleep(0.1) srv.close() yield from handler.finish_connections() yield from srv.wait_closed() loop = asyncio.get_event_loop() app, srv, handler = loop.run_until_complete(init(loop)) try: loop.run_forever() except KeyboardInterrupt: loop.run_until_complete(finish(app, srv, handler)) aiohttp-0.20.2/examples/curl.py0000775000175000017500000000110612552474754017204 0ustar andrewandrew00000000000000#!/usr/bin/env python3 import aiohttp import sys import asyncio def curl(url): response = yield from aiohttp.request('GET', url) print(repr(response)) chunk = yield from response.content.read() print('Downloaded: %s' % len(chunk)) response.close() if __name__ == '__main__': if '--iocp' in sys.argv: from asyncio import events, windows_events sys.argv.remove('--iocp') el = windows_events.ProactorEventLoop() events.set_event_loop(el) loop = asyncio.get_event_loop() loop.run_until_complete(curl(sys.argv[1])) aiohttp-0.20.2/examples/basic_srv.py0000775000175000017500000000276012552474754020221 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """Basic http server with minimal setup""" import aiohttp import aiohttp.server import asyncio from urllib.parse import urlparse, parse_qsl from aiohttp.multidict import MultiDict class HttpRequestHandler(aiohttp.server.ServerHttpProtocol): @asyncio.coroutine def handle_request(self, message, payload): response = aiohttp.Response( self.writer, 200, http_version=message.version) get_params = MultiDict(parse_qsl(urlparse(message.path).query)) if message.method == 'POST': post_params = yield from payload.read() else: post_params = None content = "

It Works!

" if get_params: content += "

Get params

" + str(get_params) + "

" if post_params: content += "

Post params

" + str(post_params) + "

" bcontent = content.encode('utf-8') response.add_header('Content-Type', 'text/html; charset=UTF-8') response.add_header('Content-Length', str(len(bcontent))) response.send_headers() response.write(bcontent) yield from response.write_eof() if __name__ == '__main__': loop = asyncio.get_event_loop() f = loop.create_server( lambda: HttpRequestHandler(debug=True, keep_alive=75), '0.0.0.0', '8080') srv = loop.run_until_complete(f) print('serving on', srv.sockets[0].getsockname()) try: loop.run_forever() except KeyboardInterrupt: pass aiohttp-0.20.2/examples/client_json.py0000664000175000017500000000103312602466630020530 0ustar andrewandrew00000000000000import aiohttp import asyncio @asyncio.coroutine def go(session): print('Query http://httpbin.org/get') resp = yield from session.get( 'http://httpbin.org/get') print(resp.status) try: data = yield from resp.json() print(data) finally: yield from resp.release() loop = asyncio.get_event_loop() session = aiohttp.ClientSession(loop=loop) loop.run_until_complete(go(session)) session.close() # run loop iteration for actual session closing loop.stop() loop.run_forever() loop.close() aiohttp-0.20.2/examples/crawl.py0000775000175000017500000000606512552474754017360 0ustar andrewandrew00000000000000#!/usr/bin/env python3 import logging import re import signal import sys import asyncio import urllib.parse import aiohttp class Crawler: def __init__(self, rooturl, loop, maxtasks=100): self.rooturl = rooturl self.loop = loop self.todo = set() self.busy = set() self.done = {} self.tasks = set() self.sem = asyncio.Semaphore(maxtasks) # connector stores cookies between requests and uses connection pool self.connector = aiohttp.TCPConnector(share_cookies=True, loop=loop) @asyncio.coroutine def run(self): asyncio.Task(self.addurls([(self.rooturl, '')])) # Set initial work. yield from asyncio.sleep(1) while self.busy: yield from asyncio.sleep(1) self.connector.close() self.loop.stop() @asyncio.coroutine def addurls(self, urls): for url, parenturl in urls: url = urllib.parse.urljoin(parenturl, url) url, frag = urllib.parse.urldefrag(url) if (url.startswith(self.rooturl) and url not in self.busy and url not in self.done and url not in self.todo): self.todo.add(url) yield from self.sem.acquire() task = asyncio.Task(self.process(url)) task.add_done_callback(lambda t: self.sem.release()) task.add_done_callback(self.tasks.remove) self.tasks.add(task) @asyncio.coroutine def process(self, url): print('processing:', url) self.todo.remove(url) self.busy.add(url) try: resp = yield from aiohttp.request( 'get', url, connector=self.connector) except Exception as exc: print('...', url, 'has error', repr(str(exc))) self.done[url] = False else: if (resp.status == 200 and ('text/html' in resp.headers.get('content-type'))): data = (yield from resp.read()).decode('utf-8', 'replace') urls = re.findall(r'(?i)href=["\']?([^\s"\'<>]+)', data) asyncio.Task(self.addurls([(u, url) for u in urls])) resp.close() self.done[url] = True self.busy.remove(url) print(len(self.done), 'completed tasks,', len(self.tasks), 'still pending, todo', len(self.todo)) def main(): loop = asyncio.get_event_loop() c = Crawler(sys.argv[1], loop) asyncio.Task(c.run()) try: loop.add_signal_handler(signal.SIGINT, loop.stop) except RuntimeError: pass loop.run_forever() print('todo:', len(c.todo)) print('busy:', len(c.busy)) print('done:', len(c.done), '; ok:', sum(c.done.values())) print('tasks:', len(c.tasks)) if __name__ == '__main__': if '--iocp' in sys.argv: from asyncio import events, windows_events sys.argv.remove('--iocp') logging.info('using iocp') el = windows_events.ProactorEventLoop() events.set_event_loop(el) main() aiohttp-0.20.2/examples/mpsrv.py0000775000175000017500000002163312552474754017415 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """Simple multiprocess http server written using an event loop.""" import argparse import os import socket import signal import time import asyncio import aiohttp import aiohttp.server from aiohttp import websocket ARGS = argparse.ArgumentParser(description="Run simple http server.") ARGS.add_argument( '--host', action="store", dest='host', default='127.0.0.1', help='Host name') ARGS.add_argument( '--port', action="store", dest='port', default=8080, type=int, help='Port number') ARGS.add_argument( '--workers', action="store", dest='workers', default=2, type=int, help='Number of workers.') class HttpRequestHandler(aiohttp.server.ServerHttpProtocol): @asyncio.coroutine def handle_request(self, message, payload): print('{}: method = {!r}; path = {!r}; version = {!r}'.format( os.getpid(), message.method, message.path, message.version)) path = message.path if (not (path.isprintable() and path.startswith('/')) or '/.' in path): path = None else: path = '.' + path if not os.path.exists(path): path = None else: isdir = os.path.isdir(path) if not path: raise aiohttp.HttpProcessingError(code=404) if isdir and not path.endswith('/'): path = path + '/' raise aiohttp.HttpProcessingError( code=302, headers=(('URI', path), ('Location', path))) response = aiohttp.Response( self.writer, 200, http_version=message.version) response.add_header('Transfer-Encoding', 'chunked') # content encoding accept_encoding = message.headers.get('accept-encoding', '').lower() if 'deflate' in accept_encoding: response.add_header('Content-Encoding', 'deflate') response.add_compression_filter('deflate') elif 'gzip' in accept_encoding: response.add_header('Content-Encoding', 'gzip') response.add_compression_filter('gzip') response.add_chunking_filter(1025) if isdir: response.add_header('Content-type', 'text/html') response.send_headers() response.write(b'
    \r\n') for name in sorted(os.listdir(path)): if name.isprintable() and not name.startswith('.'): try: bname = name.encode('ascii') except UnicodeError: pass else: if os.path.isdir(os.path.join(path, name)): response.write(b'
  • ' + bname + b'/
  • \r\n') else: response.write(b'
  • ' + bname + b'
  • \r\n') response.write(b'
') else: response.add_header('Content-type', 'text/plain') response.send_headers() try: with open(path, 'rb') as fp: chunk = fp.read(8192) while chunk: response.write(chunk) chunk = fp.read(8192) except OSError: response.write(b'Cannot open') yield from response.write_eof() if response.keep_alive(): self.keep_alive(True) class ChildProcess: def __init__(self, up_read, down_write, args, sock): self.up_read = up_read self.down_write = down_write self.args = args self.sock = sock def start(self): # start server self.loop = loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) def stop(): self.loop.stop() os._exit(0) loop.add_signal_handler(signal.SIGINT, stop) f = loop.create_server( lambda: HttpRequestHandler(debug=True, keep_alive=75), sock=self.sock) srv = loop.run_until_complete(f) x = srv.sockets[0] print('Starting srv worker process {} on {}'.format( os.getpid(), x.getsockname())) # heartbeat asyncio.async(self.heartbeat()) asyncio.get_event_loop().run_forever() os._exit(0) @asyncio.coroutine def heartbeat(self): # setup pipes read_transport, read_proto = yield from self.loop.connect_read_pipe( aiohttp.StreamProtocol, os.fdopen(self.up_read, 'rb')) write_transport, _ = yield from self.loop.connect_write_pipe( aiohttp.StreamProtocol, os.fdopen(self.down_write, 'wb')) reader = read_proto.reader.set_parser(websocket.WebSocketParser) writer = websocket.WebSocketWriter(write_transport) while True: try: msg = yield from reader.read() except: print('Supervisor is dead, {} stopping...'.format(os.getpid())) self.loop.stop() break if msg.tp == websocket.MSG_PING: writer.pong() elif msg.tp == websocket.MSG_CLOSE: break read_transport.close() write_transport.close() class Worker: _started = False def __init__(self, loop, args, sock): self.loop = loop self.args = args self.sock = sock self.start() def start(self): assert not self._started self._started = True up_read, up_write = os.pipe() down_read, down_write = os.pipe() args, sock = self.args, self.sock pid = os.fork() if pid: # parent os.close(up_read) os.close(down_write) asyncio.async(self.connect(pid, up_write, down_read)) else: # child os.close(up_write) os.close(down_read) # cleanup after fork asyncio.set_event_loop(None) # setup process process = ChildProcess(up_read, down_write, args, sock) process.start() @asyncio.coroutine def heartbeat(self, writer): while True: yield from asyncio.sleep(15) if (time.monotonic() - self.ping) < 30: writer.ping() else: print('Restart unresponsive worker process: {}'.format( self.pid)) self.kill() self.start() return @asyncio.coroutine def chat(self, reader): while True: try: msg = yield from reader.read() except: print('Restart unresponsive worker process: {}'.format( self.pid)) self.kill() self.start() return if msg.tp == websocket.MSG_PONG: self.ping = time.monotonic() @asyncio.coroutine def connect(self, pid, up_write, down_read): # setup pipes read_transport, proto = yield from self.loop.connect_read_pipe( aiohttp.StreamProtocol, os.fdopen(down_read, 'rb')) write_transport, _ = yield from self.loop.connect_write_pipe( aiohttp.StreamProtocol, os.fdopen(up_write, 'wb')) # websocket protocol reader = proto.reader.set_parser(websocket.WebSocketParser) writer = websocket.WebSocketWriter(write_transport) # store info self.pid = pid self.ping = time.monotonic() self.rtransport = read_transport self.wtransport = write_transport self.chat_task = asyncio.Task(self.chat(reader)) self.heartbeat_task = asyncio.Task(self.heartbeat(writer)) def kill(self): self._started = False self.chat_task.cancel() self.heartbeat_task.cancel() self.rtransport.close() self.wtransport.close() os.kill(self.pid, signal.SIGTERM) class Supervisor: def __init__(self, args): self.loop = asyncio.get_event_loop() self.args = args self.workers = [] def start(self): # bind socket sock = self.sock = socket.socket() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((self.args.host, self.args.port)) sock.listen(1024) sock.setblocking(False) # start processes for idx in range(self.args.workers): self.workers.append(Worker(self.loop, self.args, sock)) self.loop.add_signal_handler(signal.SIGINT, lambda: self.loop.stop()) self.loop.run_forever() def main(): if getattr(os, "fork", None) is None: print("os.fork isn't supported by your OS") return args = ARGS.parse_args() if ':' in args.host: args.host, port = args.host.split(':', 1) args.port = int(port) supervisor = Supervisor(args) supervisor.start() if __name__ == '__main__': main() aiohttp-0.20.2/examples/web_rewrite_headers_middleware.py0000775000175000017500000000230412552474754024446 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """ Example for rewriting response headers by middleware. """ import asyncio from aiohttp.web import Application, Response, HTTPException @asyncio.coroutine def handler(request): return Response(text="Everything is fine") @asyncio.coroutine def middleware_factory(app, next_handler): @asyncio.coroutine def middleware(request): try: response = yield from next_handler(request) except HTTPException as exc: response = exc if not response.started: response.headers['SERVER'] = "Secured Server Software" return response return middleware @asyncio.coroutine def init(loop): app = Application(loop=loop, middlewares=[middleware_factory]) app.router.add_route('GET', '/', handler) requests_handler = app.make_handler() srv = yield from loop.create_server(requests_handler, '127.0.0.1', 8080) print("Server started at http://127.0.0.1:8080") return srv, requests_handler loop = asyncio.get_event_loop() srv, requests_handler = loop.run_until_complete(init(loop)) try: loop.run_forever() except KeyboardInterrupt: loop.run_until_complete(requests_handler.finish_connections()) aiohttp-0.20.2/examples/srv.py0000775000175000017500000001240012603601535017032 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """Simple server written using an event loop.""" import argparse import logging import os import sys try: import ssl except ImportError: # pragma: no cover ssl = None import asyncio import aiohttp import aiohttp.server class HttpRequestHandler(aiohttp.server.ServerHttpProtocol): @asyncio.coroutine def handle_request(self, message, payload): print('method = {!r}; path = {!r}; version = {!r}'.format( message.method, message.path, message.version)) path = message.path if (not (path.isprintable() and path.startswith('/')) or '/.' in path): print('bad path', repr(path)) path = None else: path = '.' + path if not os.path.exists(path): print('no file', repr(path)) path = None else: isdir = os.path.isdir(path) if not path: raise aiohttp.HttpProcessingError(code=404) for hdr, val in message.headers.items(): print(hdr, val) if isdir and not path.endswith('/'): path = path + '/' raise aiohttp.HttpProcessingError( code=302, headers=(('URI', path), ('Location', path))) response = aiohttp.Response( self.writer, 200, http_version=message.version) response.add_header('Transfer-Encoding', 'chunked') # content encoding accept_encoding = message.headers.get('accept-encoding', '').lower() if 'deflate' in accept_encoding: response.add_header('Content-Encoding', 'deflate') response.add_compression_filter('deflate') elif 'gzip' in accept_encoding: response.add_header('Content-Encoding', 'gzip') response.add_compression_filter('gzip') response.add_chunking_filter(1025) if isdir: response.add_header('Content-type', 'text/html') response.send_headers() response.write(b'
    \r\n') for name in sorted(os.listdir(path)): if name.isprintable() and not name.startswith('.'): try: bname = name.encode('ascii') except UnicodeError: pass else: if os.path.isdir(os.path.join(path, name)): response.write(b'
  • ' + bname + b'/
  • \r\n') else: response.write(b'
  • ' + bname + b'
  • \r\n') response.write(b'
') else: response.add_header('Content-type', 'text/plain') response.send_headers() try: with open(path, 'rb') as fp: chunk = fp.read(8192) while chunk: response.write(chunk) chunk = fp.read(8192) except OSError: response.write(b'Cannot open') yield from response.write_eof() if response.keep_alive(): self.keep_alive(True) ARGS = argparse.ArgumentParser(description="Run simple http server.") ARGS.add_argument( '--host', action="store", dest='host', default='127.0.0.1', help='Host name') ARGS.add_argument( '--port', action="store", dest='port', default=8080, type=int, help='Port number') # make iocp and ssl mutually exclusive because ProactorEventLoop is # incompatible with SSL group = ARGS.add_mutually_exclusive_group() group.add_argument( '--iocp', action="store_true", dest='iocp', help='Windows IOCP event loop') group.add_argument( '--ssl', action="store_true", dest='ssl', help='Run ssl mode.') ARGS.add_argument( '--sslcert', action="store", dest='certfile', help='SSL cert file.') ARGS.add_argument( '--sslkey', action="store", dest='keyfile', help='SSL key file.') def main(): args = ARGS.parse_args() if ':' in args.host: args.host, port = args.host.split(':', 1) args.port = int(port) if args.iocp: from asyncio import windows_events sys.argv.remove('--iocp') logging.info('using iocp') el = windows_events.ProactorEventLoop() asyncio.set_event_loop(el) if args.ssl: here = os.path.join(os.path.dirname(__file__), 'tests') if args.certfile: certfile = args.certfile or os.path.join(here, 'sample.crt') keyfile = args.keyfile or os.path.join(here, 'sample.key') else: certfile = os.path.join(here, 'sample.crt') keyfile = os.path.join(here, 'sample.key') sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslcontext.load_cert_chain(certfile, keyfile) else: sslcontext = None loop = asyncio.get_event_loop() f = loop.create_server( lambda: HttpRequestHandler(debug=True, keep_alive=75), args.host, args.port, ssl=sslcontext) svr = loop.run_until_complete(f) socks = svr.sockets print('serving on', socks[0].getsockname()) try: loop.run_forever() except KeyboardInterrupt: pass if __name__ == '__main__': main() aiohttp-0.20.2/examples/websocket.html0000664000175000017500000000452112552474754020542 0ustar andrewandrew00000000000000

Chat!

 | Status: disconnected
aiohttp-0.20.2/examples/wsclient.py0000775000175000017500000000430112552474754020067 0ustar andrewandrew00000000000000#!/usr/bin/env python3 """websocket cmd client for wssrv.py example.""" import argparse import signal import sys import asyncio try: import selectors except ImportError: from asyncio import selectors import aiohttp def start_client(loop, url): name = input('Please enter your name: ') # send request ws = yield from aiohttp.ws_connect(url, autoclose=False, autoping=False) # input reader def stdin_callback(): line = sys.stdin.buffer.readline().decode('utf-8') if not line: loop.stop() else: ws.send_str(name + ': ' + line) loop.add_reader(sys.stdin.fileno(), stdin_callback) @asyncio.coroutine def dispatch(): while True: msg = yield from ws.receive() if msg.tp == aiohttp.MsgType.text: print('Text: ', msg.data.strip()) elif msg.tp == aiohttp.MsgType.binary: print('Binary: ', msg.data) elif msg.tp == aiohttp.MsgType.ping: ws.pong() elif msg.tp == aiohttp.MsgType.pong: print('Pong received') else: if msg.tp == aiohttp.MsgType.close: yield from ws.close() elif msg.tp == aiohttp.MsgType.error: print('Error during receive %s' % ws.exception()) elif msg.tp == aiohttp.MsgType.closed: pass break yield from dispatch() ARGS = argparse.ArgumentParser( description="websocket console client for wssrv.py example.") ARGS.add_argument( '--host', action="store", dest='host', default='127.0.0.1', help='Host name') ARGS.add_argument( '--port', action="store", dest='port', default=8080, type=int, help='Port number') if __name__ == '__main__': args = ARGS.parse_args() if ':' in args.host: args.host, port = args.host.split(':', 1) args.port = int(port) url = 'http://{}:{}'.format(args.host, args.port) loop = asyncio.SelectorEventLoop(selectors.SelectSelector()) asyncio.set_event_loop(loop) loop.add_signal_handler(signal.SIGINT, loop.stop) asyncio.Task(start_client(loop, url)) loop.run_forever() aiohttp-0.20.2/PKG-INFO0000664000175000017500000001344212643555674015151 0ustar andrewandrew00000000000000Metadata-Version: 1.1 Name: aiohttp Version: 0.20.2 Summary: http client/server for asyncio Home-page: https://github.com/KeepSafe/aiohttp/ Author: Andrew Svetlov Author-email: andrew.svetlov@gmail.com License: Apache 2 Description: http client/server for asyncio ============================== .. image:: https://raw.github.com/KeepSafe/aiohttp/master/docs/_static/aiohttp-icon-128x128.png :height: 64px :width: 64px :alt: aiohttp logo .. image:: https://travis-ci.org/KeepSafe/aiohttp.svg?branch=master :target: https://travis-ci.org/KeepSafe/aiohttp :align: right .. image:: https://coveralls.io/repos/KeepSafe/aiohttp/badge.svg?branch=master&service=github :target: https://coveralls.io/github/KeepSafe/aiohttp?branch=master :align: right .. image:: https://badge.fury.io/py/aiohttp.svg :target: https://badge.fury.io/py/aiohttp Features -------- - Supports both client and server side of HTTP protocol. - Supports both client and server Web-Sockets out-of-the-box. - Web-server has middlewares and pluggable routing. Getting started --------------- Client ^^^^^^ To retrieve something from the web: .. code-block:: python import aiohttp import asyncio async def get_body(client, url): async with client.get(url) as response: return await response.read() if __name__ == '__main__': loop = asyncio.get_event_loop() client = aiohttp.ClientSession(loop=loop) raw_html = loop.run_until_complete(get_body(client, 'http://python.org')) print(raw_html) client.close() If you want to use timeouts for aiohttp client please use standard asyncio approach: .. code-block:: python yield from asyncio.wait_for(client.get(url), 10) Server ^^^^^^ This is simple usage example: .. code-block:: python import asyncio from aiohttp import web async def handle(request): name = request.match_info.get('name', "Anonymous") text = "Hello, " + name return web.Response(body=text.encode('utf-8')) async def wshandler(request): ws = web.WebSocketResponse() await ws.prepare(request) async for msg in ws: if msg.tp == web.MsgType.text: ws.send_str("Hello, {}".format(msg.data)) elif msg.tp == web.MsgType.binary: ws.send_bytes(msg.data) elif msg.tp == web.MsgType.close: break return ws async def init(loop): app = web.Application(loop=loop) app.router.add_route('GET', '/echo', wshandler) app.router.add_route('GET', '/{name}', handle) srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8080) print("Server started at http://127.0.0.1:8080") return srv loop = asyncio.get_event_loop() loop.run_until_complete(init(loop)) loop.run_forever() Note: examples are written for Python 3.5+ and utilize PEP-492 aka async/await. If you are using Python 3.4 please replace ``await`` with ``yield from`` and ``async def`` with ``@coroutine`` e.g.:: async def coro(...): ret = await f() shoud be replaced by:: @asyncio.coroutine def coro(...): ret = yield from f() Documentation ------------- http://aiohttp.readthedocs.org/ Discussion list --------------- *aio-libs* google group: https://groups.google.com/forum/#!forum/aio-libs Requirements ------------ - Python >= 3.4.1 - chardet https://pypi.python.org/pypi/chardet Optionally you may install cChardet library: https://pypi.python.org/pypi/cchardet/1.0.0 License ------- ``aiohttp`` is offered under the Apache 2 license. Source code ------------ The latest developer version is available in a github repository: https://github.com/KeepSafe/aiohttp Benchmarks ---------- If you are interested in by efficiency, AsyncIO community maintains a list of benchmarks on the official wiki: https://github.com/python/asyncio/wiki/Benchmarks CHANGES ======= 0.20.2 (01-07-2015) -------------------- - Enable use of `await` for a class based view #717 - Check address family to fill wsgi env properly #718 - Fix memory leak in headers processing (thanks to Marco Paolini) #723 Platform: UNKNOWN Classifier: License :: OSI Approved :: Apache Software License Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Topic :: Internet :: WWW/HTTP aiohttp-0.20.2/MANIFEST.in0000664000175000017500000000070012552474754015601 0ustar andrewandrew00000000000000include LICENSE.txt include CHANGES.txt include README.rst include CONTRIBUTORS.txt include Makefile graft aiohttp graft docs graft examples graft tests global-exclude *.pyc exclude aiohttp/_multidict.html exclude aiohttp/_multidict.*.so exclude aiohttp/_multidict.pyd exclude aiohttp/_multidict.*.pyd exclude aiohttp/_websocket.html exclude aiohttp/_websocket.*.so exclude aiohttp/_websocket.pyd exclude aiohttp/_websocket.*.pyd prune docs/_build aiohttp-0.20.2/CHANGES.txt0000664000175000017500000000035612643555267015663 0ustar andrewandrew00000000000000CHANGES ======= 0.20.2 (01-07-2015) -------------------- - Enable use of `await` for a class based view #717 - Check address family to fill wsgi env properly #718 - Fix memory leak in headers processing (thanks to Marco Paolini) #723 aiohttp-0.20.2/setup.py0000664000175000017500000000642512637063114015553 0ustar andrewandrew00000000000000import codecs import os import re import sys from setuptools import setup, Extension from distutils.errors import (CCompilerError, DistutilsExecError, DistutilsPlatformError) from distutils.command.build_ext import build_ext from setuptools.command.test import test as TestCommand try: from Cython.Build import cythonize USE_CYTHON = True except ImportError: USE_CYTHON = False ext = '.pyx' if USE_CYTHON else '.c' extensions = [Extension('aiohttp._multidict', ['aiohttp/_multidict' + ext]), Extension('aiohttp._websocket', ['aiohttp/_websocket' + ext])] if USE_CYTHON: extensions = cythonize(extensions) class BuildFailed(Exception): pass class ve_build_ext(build_ext): # This class allows C extension building to fail. def run(self): try: build_ext.run(self) except (DistutilsPlatformError, FileNotFoundError): raise BuildFailed() def build_extension(self, ext): try: build_ext.build_extension(self, ext) except (CCompilerError, DistutilsExecError, DistutilsPlatformError, ValueError): raise BuildFailed() with codecs.open(os.path.join(os.path.abspath(os.path.dirname( __file__)), 'aiohttp', '__init__.py'), 'r', 'latin1') as fp: try: version = re.findall(r"^__version__ = '([^']+)'\r?$", fp.read(), re.M)[0] except IndexError: raise RuntimeError('Unable to determine version.') install_requires = ['chardet'] if sys.version_info < (3, 4, 1): raise RuntimeError("aiohttp requires Python 3.4.1+") def read(f): return open(os.path.join(os.path.dirname(__file__), f)).read().strip() class PyTest(TestCommand): user_options = [] def run(self): import subprocess import sys errno = subprocess.call([sys.executable, '-m', 'pytest', 'tests']) raise SystemExit(errno) tests_require = install_requires + ['pytest', 'gunicorn'] args = dict( name='aiohttp', version=version, description=('http client/server for asyncio'), long_description='\n\n'.join((read('README.rst'), read('CHANGES.txt'))), classifiers=[ 'License :: OSI Approved :: Apache Software License', 'Intended Audience :: Developers', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Topic :: Internet :: WWW/HTTP'], author='Nikolay Kim', author_email='fafhrd91@gmail.com', maintainer='Andrew Svetlov', maintainer_email='andrew.svetlov@gmail.com', url='https://github.com/KeepSafe/aiohttp/', license='Apache 2', packages=['aiohttp'], install_requires=install_requires, tests_require=tests_require, include_package_data=True, ext_modules=extensions, cmdclass=dict(build_ext=ve_build_ext, test=PyTest)) try: setup(**args) except BuildFailed: print("************************************************************") print("Cannot compile C accelerator module, use pure python version") print("************************************************************") del args['ext_modules'] del args['cmdclass'] setup(**args)