From 53c3f1fec868fb50541ecbca2cbb1fce7c2a2ef5 Mon Sep 17 00:00:00 2001 From: Sam Mirazi Date: Fri, 30 May 2025 23:05:11 -0700 Subject: [PATCH] phase 3 complete --- .../__init__.cpython-312-pytest-8.3.5.pyc | Bin 0 -> 212 bytes .../_asyncio.cpython-312-pytest-8.3.5.pyc | Bin 0 -> 137081 bytes .../pytest_asyncio-1.0.0.dist-info/INSTALLER | 1 + .../pytest_asyncio-1.0.0.dist-info/METADATA | 89 ++ .../pytest_asyncio-1.0.0.dist-info/RECORD | 15 + .../pytest_asyncio-1.0.0.dist-info/REQUESTED | 0 .../pytest_asyncio-1.0.0.dist-info/WHEEL | 5 + .../entry_points.txt | 2 + .../licenses/LICENSE | 201 ++++ .../top_level.txt | 1 + .../site-packages/pytest_asyncio/__init__.py | 8 + .../__init__.cpython-312-pytest-8.3.5.pyc | Bin 0 -> 582 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 468 bytes .../_version.cpython-312-pytest-8.3.5.pyc | Bin 0 -> 782 bytes .../__pycache__/_version.cpython-312.pyc | Bin 0 -> 672 bytes .../plugin.cpython-312-pytest-8.3.5.pyc | Bin 0 -> 44924 bytes .../__pycache__/plugin.cpython-312.pyc | Bin 0 -> 40519 bytes .../site-packages/pytest_asyncio/_version.py | 21 + .../site-packages/pytest_asyncio/plugin.py | 948 ++++++++++++++++++ .../Lib/site-packages/pytest_asyncio/py.typed | 0 app_flask/flask_application.py | 4 +- ...fastapi_route.cpython-312-pytest-8.3.5.pyc | Bin 0 -> 4287 bytes ...t_flask_route.cpython-312-pytest-8.3.5.pyc | Bin 3040 -> 4556 bytes tests/test_fastapi_route.py | 41 + tests/test_flask_route.py | 47 +- 25 files changed, 1369 insertions(+), 14 deletions(-) create mode 100644 .venv/Lib/site-packages/anyio/_backends/__pycache__/__init__.cpython-312-pytest-8.3.5.pyc create mode 100644 .venv/Lib/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-312-pytest-8.3.5.pyc create mode 100644 .venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/REQUESTED create mode 100644 .venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/entry_points.txt create mode 100644 .venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/licenses/LICENSE create mode 100644 .venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/top_level.txt create mode 100644 .venv/Lib/site-packages/pytest_asyncio/__init__.py create mode 100644 .venv/Lib/site-packages/pytest_asyncio/__pycache__/__init__.cpython-312-pytest-8.3.5.pyc create mode 100644 .venv/Lib/site-packages/pytest_asyncio/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pytest_asyncio/__pycache__/_version.cpython-312-pytest-8.3.5.pyc create mode 100644 .venv/Lib/site-packages/pytest_asyncio/__pycache__/_version.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pytest_asyncio/__pycache__/plugin.cpython-312-pytest-8.3.5.pyc create mode 100644 .venv/Lib/site-packages/pytest_asyncio/__pycache__/plugin.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pytest_asyncio/_version.py create mode 100644 .venv/Lib/site-packages/pytest_asyncio/plugin.py create mode 100644 .venv/Lib/site-packages/pytest_asyncio/py.typed create mode 100644 tests/__pycache__/test_fastapi_route.cpython-312-pytest-8.3.5.pyc create mode 100644 tests/test_fastapi_route.py diff --git a/.venv/Lib/site-packages/anyio/_backends/__pycache__/__init__.cpython-312-pytest-8.3.5.pyc b/.venv/Lib/site-packages/anyio/_backends/__pycache__/__init__.cpython-312-pytest-8.3.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9d6137625db5bce13d19b7c2061f9f2f39c2c07 GIT binary patch literal 212 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" +License-Expression: Apache-2.0 +Project-URL: Bug Tracker, https://github.com/pytest-dev/pytest-asyncio/issues +Project-URL: Changelog, https://pytest-asyncio.readthedocs.io/en/latest/reference/changelog.html +Project-URL: Documentation, https://pytest-asyncio.readthedocs.io +Project-URL: Homepage, https://github.com/pytest-dev/pytest-asyncio +Project-URL: Source Code, https://github.com/pytest-dev/pytest-asyncio +Classifier: Development Status :: 4 - Beta +Classifier: Framework :: AsyncIO +Classifier: Framework :: Pytest +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Topic :: Software Development :: Testing +Classifier: Typing :: Typed +Requires-Python: >=3.9 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: pytest<9,>=8.2 +Requires-Dist: typing-extensions>=4.12; python_version < "3.10" +Provides-Extra: docs +Requires-Dist: sphinx>=5.3; extra == "docs" +Requires-Dist: sphinx-rtd-theme>=1; extra == "docs" +Provides-Extra: testing +Requires-Dist: coverage>=6.2; extra == "testing" +Requires-Dist: hypothesis>=5.7.1; extra == "testing" +Dynamic: license-file + +pytest-asyncio +============== + +.. image:: https://img.shields.io/pypi/v/pytest-asyncio.svg + :target: https://pypi.python.org/pypi/pytest-asyncio +.. image:: https://github.com/pytest-dev/pytest-asyncio/workflows/CI/badge.svg + :target: https://github.com/pytest-dev/pytest-asyncio/actions?workflow=CI +.. image:: https://codecov.io/gh/pytest-dev/pytest-asyncio/branch/main/graph/badge.svg + :target: https://codecov.io/gh/pytest-dev/pytest-asyncio +.. image:: https://img.shields.io/pypi/pyversions/pytest-asyncio.svg + :target: https://github.com/pytest-dev/pytest-asyncio + :alt: Supported Python versions +.. image:: https://img.shields.io/badge/Matrix-%23pytest--asyncio-brightgreen + :alt: Matrix chat room: #pytest-asyncio + :target: https://matrix.to/#/#pytest-asyncio:matrix.org + +`pytest-asyncio `_ is a `pytest `_ plugin. It facilitates testing of code that uses the `asyncio `_ library. + +Specifically, pytest-asyncio provides support for coroutines as test functions. This allows users to *await* code inside their tests. For example, the following code is executed as a test item by pytest: + +.. code-block:: python + + @pytest.mark.asyncio + async def test_some_asyncio_code(): + res = await library.do_something() + assert b"expected result" == res + +More details can be found in the `documentation `_. + +Note that test classes subclassing the standard `unittest `__ library are not supported. Users +are advised to use `unittest.IsolatedAsyncioTestCase `__ +or an async framework such as `asynctest `__. + + +pytest-asyncio is available under the `Apache License 2.0 `_. + + +Installation +------------ + +To install pytest-asyncio, simply: + +.. code-block:: bash + + $ pip install pytest-asyncio + +This is enough for pytest to pick up pytest-asyncio. + + +Contributing +------------ +Contributions are very welcome. Tests can be run with ``tox``, please ensure +the coverage at least stays the same before you submit a pull request. diff --git a/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/RECORD b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/RECORD new file mode 100644 index 0000000..ff8b08c --- /dev/null +++ b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/RECORD @@ -0,0 +1,15 @@ +pytest_asyncio-1.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pytest_asyncio-1.0.0.dist-info/METADATA,sha256=COXTlvAPs6WJu76Pi1olsFlvFIhY7gHlEnhIi5tZKxM,3956 +pytest_asyncio-1.0.0.dist-info/RECORD,, +pytest_asyncio-1.0.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pytest_asyncio-1.0.0.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91 +pytest_asyncio-1.0.0.dist-info/entry_points.txt,sha256=_5TsciE-7mIopUy1NrPCEjHVTDIwhNbyXvP-su1-O7w,43 +pytest_asyncio-1.0.0.dist-info/licenses/LICENSE,sha256=qK0xscP0DcpahBGTUbj6jdyGjt13-tio6_bY8tFvpK4,11324 +pytest_asyncio-1.0.0.dist-info/top_level.txt,sha256=J4BTi9IZbfghCsiVybot1y0AaLUgxp3NMaNpH9fghNI,15 +pytest_asyncio/__init__.py,sha256=EWf0KLgnvHEAZXcbCJ3BxAGeH1OLzMhyh-oCU0Idwew,236 +pytest_asyncio/__pycache__/__init__.cpython-312.pyc,, +pytest_asyncio/__pycache__/_version.cpython-312.pyc,, +pytest_asyncio/__pycache__/plugin.cpython-312.pyc,, +pytest_asyncio/_version.py,sha256=fo5PXsZuloQZu3LdpIFTUAXvJmY2L9N5sNGe2tvdU98,511 +pytest_asyncio/plugin.py,sha256=iQBFi9d2REjOarR7EfvLogAdq6VvJ_aUL5CrUAYawrg,32098 +pytest_asyncio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/REQUESTED b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/WHEEL b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/WHEEL new file mode 100644 index 0000000..870aa26 --- /dev/null +++ b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (80.8.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/entry_points.txt b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/entry_points.txt new file mode 100644 index 0000000..88db714 --- /dev/null +++ b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[pytest11] +asyncio = pytest_asyncio.plugin diff --git a/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/licenses/LICENSE b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000..5c304d1 --- /dev/null +++ b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/licenses/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/top_level.txt b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/top_level.txt new file mode 100644 index 0000000..08d05d1 --- /dev/null +++ b/.venv/Lib/site-packages/pytest_asyncio-1.0.0.dist-info/top_level.txt @@ -0,0 +1 @@ +pytest_asyncio diff --git a/.venv/Lib/site-packages/pytest_asyncio/__init__.py b/.venv/Lib/site-packages/pytest_asyncio/__init__.py new file mode 100644 index 0000000..c25c1bf --- /dev/null +++ b/.venv/Lib/site-packages/pytest_asyncio/__init__.py @@ -0,0 +1,8 @@ +"""The main point for importing pytest-asyncio items.""" + +from __future__ import annotations + +from ._version import version as __version__ # noqa: F401 +from .plugin import fixture, is_async_test + +__all__ = ("fixture", "is_async_test") diff --git a/.venv/Lib/site-packages/pytest_asyncio/__pycache__/__init__.cpython-312-pytest-8.3.5.pyc b/.venv/Lib/site-packages/pytest_asyncio/__pycache__/__init__.cpython-312-pytest-8.3.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..871a29a24b226b42b35c4257b6b0fa9c4d38b081 GIT binary patch literal 582 zcmX|7L2DE-6wd5)XSTDQ+KY&I89WFpb`GATh$xn#Af-^f41q^Flij8}Nroh|b-W4w z2M_)N|B9YHn2Uml6g&vMdGgJ!+jmIb_kGFxKHldvO$gSf4|}J-@&3_+bq!WcaCwN$ zds2~tR6#YU134%LLEndUSZplsp^Qr8WL%6;*{Fu~rc8?QvXAO5nHH(sF18Uz#kDS+ z#Bc7uJmr~WLS>B>%4Jh+G9epnoKUl@=^VFim)TC0LTAEpY4eLd&?N9NJ%;OE{8nDHa{AIS`RhcT=%`bSOO&V(`%Dkkn_ zjK=C3;3K(2NdB6qd-N4rT6)YR-RE}hbVH9t#j_)$&v@x9Jz&;7IeMNgY<5sHJEzZB zIp-$Z*JqmM3$7OQg*c%W)9yAXu^G2?9dNZ;3Lunl0D05-(L<@Lw&st_4UEt)*51P7 gPZ$KjSMuN|x&4cfcjODX_l?~Bp4@pGo9n3m0|~~s(*OVf literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pytest_asyncio/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/pytest_asyncio/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cdd90ac58a07244bcf9e853ef33d8c37e215f441 GIT binary patch literal 468 zcmXv~%Sr<=6iueKQ!7Q>xDGCaimf0nq=+CEQ4lGpn;~$CowTN%Btw!G$DLo{!Y}Yw z^b4Ggg19KS5Zt*kW9?le=iGBS_wih>*N~5=hxYZS|KAHTk6;Gy_l^hmC`J*AaU3LA z22p@fT#6Txl3a+&f4H1fWEh3A8dW_nM~hjd5#DZJTyr9sP$bntInvjL2$^c*gc^`E zbKJTnvzh7%O@!mpwx&hf2F{n5Qra;mw6aq?%Y_qetWPw8JnV}bH#R)43k!b^P?()H zYIz6{>mEQ}1L%*7A^=nJ4tW*+4NSS9OEBlYxRNI0fl#L66%!V+_hCr_@QA)WML*`S zO)ssVfSxl+JKT<(PU*RbIq4cbYC=!N z6}5iXX6hw2;FiwrFxx`tEdZf}18AjLUfq*A9w&U?toRX%GuT!Ce3dZ9FKG7zt$m=) PSG4g~TfYmA#|vYA$g=2zcsE=t1zJZ__3Y!+YQR_3e9a_KRWY2+rqs%a8tIgnq`x z_$1H3$$J2=Q60I+#Xhp|NGIA#BY{ynX{9h~A~*2?TWMFZRI0KfWF&p9ov|`Fu1W#c zEgd78p*qdd+`~i>INkKAwu~S_&she|(J5D5fyfAHBV>RtGeLTc-0Tx<<*jKq2l~7< z)5T@u82o6boRnEYI+SrQ3<#0a{|#{v`4n90SyUS1v{7WejAd#!&WS-ifO?aqfRib) zh&Y0jl7`A)cErn2&s61kO~(} z8uu&rYMXa=$Zoy5Rgvj%Z=W`VoC2yK2!#_jzzI2>Yc%0xxKHQ=xX>TAx@^~>S8msw zw!KDqON5bK^ITf0vM{FO_PWEx&FW^U!%OSF!&~--(`ZpvS_}6>+w9PwV{dtTHit16 zA_zH6%I)!Fyc;yU&>p{(8Fi($(hl7NpI&E|poMt3yb0o$f-(NBA&g(3Z~ElzA!M_4aAWN`>6p5)@rEVMC%=TQv2v`3f zf>Ylia3x-4LwQ-Y$W+ci5*2V5Z$*U>X}chz(&(Es76BJQ9NV+GjXc(sBKqI;Jv{5!n`{mL>wf-O!f}wA_T`ES!5Hly>``b?T6NbR8^2qhQAX=N!iPTtfH&|42R@iSx|*NdC!Xe(`x& z^K9<@?J+lQj-?O9&vz#q>i2B%Wo@3_7}e&9^sDqt&P-8ewx&#xGF!<{QGR}NbAmQU TsW;u(t*r@ywfeS3*PzuujmEn1 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pytest_asyncio/__pycache__/plugin.cpython-312-pytest-8.3.5.pyc b/.venv/Lib/site-packages/pytest_asyncio/__pycache__/plugin.cpython-312-pytest-8.3.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fae8c58a54c049fe5f76cc25f71e2e0defcf91e8 GIT binary patch literal 44924 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pytest_asyncio/_version.py b/.venv/Lib/site-packages/pytest_asyncio/_version.py new file mode 100644 index 0000000..93f235a --- /dev/null +++ b/.venv/Lib/site-packages/pytest_asyncio/_version.py @@ -0,0 +1,21 @@ +# file generated by setuptools-scm +# don't change, don't track in version control + +__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"] + +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple + from typing import Union + + VERSION_TUPLE = Tuple[Union[int, str], ...] +else: + VERSION_TUPLE = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE + +__version__ = version = '1.0.0' +__version_tuple__ = version_tuple = (1, 0, 0) diff --git a/.venv/Lib/site-packages/pytest_asyncio/plugin.py b/.venv/Lib/site-packages/pytest_asyncio/plugin.py new file mode 100644 index 0000000..aecf6e9 --- /dev/null +++ b/.venv/Lib/site-packages/pytest_asyncio/plugin.py @@ -0,0 +1,948 @@ +"""pytest-asyncio implementation.""" + +from __future__ import annotations + +import asyncio +import contextlib +import contextvars +import enum +import functools +import inspect +import socket +import sys +import warnings +from asyncio import AbstractEventLoop, AbstractEventLoopPolicy +from collections.abc import ( + AsyncIterator, + Awaitable, + Coroutine as AbstractCoroutine, + Generator, + Iterable, + Iterator, + Sequence, +) +from typing import ( + Any, + Callable, + Literal, + TypeVar, + Union, + cast, + overload, +) + +import pluggy +import pytest +from _pytest.scope import Scope +from pytest import ( + Collector, + Config, + FixtureDef, + FixtureRequest, + Function, + Item, + Mark, + Metafunc, + Parser, + PytestCollectionWarning, + PytestDeprecationWarning, + PytestPluginManager, +) + +if sys.version_info >= (3, 10): + from typing import ParamSpec +else: + from typing_extensions import ParamSpec + + +_ScopeName = Literal["session", "package", "module", "class", "function"] +_T = TypeVar("_T") +_R = TypeVar("_R", bound=Union[Awaitable[Any], AsyncIterator[Any]]) +_P = ParamSpec("_P") +FixtureFunction = Callable[_P, _R] + + +class PytestAsyncioError(Exception): + """Base class for exceptions raised by pytest-asyncio""" + + +class Mode(str, enum.Enum): + AUTO = "auto" + STRICT = "strict" + + +ASYNCIO_MODE_HELP = """\ +'auto' - for automatically handling all async functions by the plugin +'strict' - for autoprocessing disabling (useful if different async frameworks \ +should be tested together, e.g. \ +both pytest-asyncio and pytest-trio are used in the same project) +""" + + +def pytest_addoption(parser: Parser, pluginmanager: PytestPluginManager) -> None: + group = parser.getgroup("asyncio") + group.addoption( + "--asyncio-mode", + dest="asyncio_mode", + default=None, + metavar="MODE", + help=ASYNCIO_MODE_HELP, + ) + parser.addini( + "asyncio_mode", + help="default value for --asyncio-mode", + default="strict", + ) + parser.addini( + "asyncio_default_fixture_loop_scope", + type="string", + help="default scope of the asyncio event loop used to execute async fixtures", + default=None, + ) + parser.addini( + "asyncio_default_test_loop_scope", + type="string", + help="default scope of the asyncio event loop used to execute tests", + default="function", + ) + + +@overload +def fixture( + fixture_function: FixtureFunction[_P, _R], + *, + scope: _ScopeName | Callable[[str, Config], _ScopeName] = ..., + loop_scope: _ScopeName | None = ..., + params: Iterable[object] | None = ..., + autouse: bool = ..., + ids: ( + Iterable[str | float | int | bool | None] + | Callable[[Any], object | None] + | None + ) = ..., + name: str | None = ..., +) -> FixtureFunction[_P, _R]: ... + + +@overload +def fixture( + fixture_function: None = ..., + *, + scope: _ScopeName | Callable[[str, Config], _ScopeName] = ..., + loop_scope: _ScopeName | None = ..., + params: Iterable[object] | None = ..., + autouse: bool = ..., + ids: ( + Iterable[str | float | int | bool | None] + | Callable[[Any], object | None] + | None + ) = ..., + name: str | None = None, +) -> Callable[[FixtureFunction[_P, _R]], FixtureFunction[_P, _R]]: ... + + +def fixture( + fixture_function: FixtureFunction[_P, _R] | None = None, + loop_scope: _ScopeName | None = None, + **kwargs: Any, +) -> ( + FixtureFunction[_P, _R] + | Callable[[FixtureFunction[_P, _R]], FixtureFunction[_P, _R]] +): + if fixture_function is not None: + _make_asyncio_fixture_function(fixture_function, loop_scope) + return pytest.fixture(fixture_function, **kwargs) + + else: + + @functools.wraps(fixture) + def inner(fixture_function: FixtureFunction[_P, _R]) -> FixtureFunction[_P, _R]: + return fixture(fixture_function, loop_scope=loop_scope, **kwargs) + + return inner + + +def _is_asyncio_fixture_function(obj: Any) -> bool: + obj = getattr(obj, "__func__", obj) # instance method maybe? + return getattr(obj, "_force_asyncio_fixture", False) + + +def _make_asyncio_fixture_function(obj: Any, loop_scope: _ScopeName | None) -> None: + if hasattr(obj, "__func__"): + # instance method, check the function object + obj = obj.__func__ + obj._force_asyncio_fixture = True + obj._loop_scope = loop_scope + + +def _is_coroutine_or_asyncgen(obj: Any) -> bool: + return inspect.iscoroutinefunction(obj) or inspect.isasyncgenfunction(obj) + + +def _get_asyncio_mode(config: Config) -> Mode: + val = config.getoption("asyncio_mode") + if val is None: + val = config.getini("asyncio_mode") + try: + return Mode(val) + except ValueError as e: + modes = ", ".join(m.value for m in Mode) + raise pytest.UsageError( + f"{val!r} is not a valid asyncio_mode. Valid modes: {modes}." + ) from e + + +_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET = """\ +The configuration option "asyncio_default_fixture_loop_scope" is unset. +The event loop scope for asynchronous fixtures will default to the fixture caching \ +scope. Future versions of pytest-asyncio will default the loop scope for asynchronous \ +fixtures to function scope. Set the default fixture loop scope explicitly in order to \ +avoid unexpected behavior in the future. Valid fixture loop scopes are: \ +"function", "class", "module", "package", "session" +""" + + +def pytest_configure(config: Config) -> None: + default_loop_scope = config.getini("asyncio_default_fixture_loop_scope") + if not default_loop_scope: + warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET)) + config.addinivalue_line( + "markers", + "asyncio: " + "mark the test as a coroutine, it will be " + "run using an asyncio event loop", + ) + + +@pytest.hookimpl(tryfirst=True) +def pytest_report_header(config: Config) -> list[str]: + """Add asyncio config to pytest header.""" + mode = _get_asyncio_mode(config) + default_fixture_loop_scope = config.getini("asyncio_default_fixture_loop_scope") + default_test_loop_scope = _get_default_test_loop_scope(config) + header = [ + f"mode={mode}", + f"asyncio_default_fixture_loop_scope={default_fixture_loop_scope}", + f"asyncio_default_test_loop_scope={default_test_loop_scope}", + ] + return [ + "asyncio: " + ", ".join(header), + ] + + +def _preprocess_async_fixtures( + collector: Collector, + processed_fixturedefs: set[FixtureDef], +) -> None: + config = collector.config + default_loop_scope = config.getini("asyncio_default_fixture_loop_scope") + asyncio_mode = _get_asyncio_mode(config) + fixturemanager = config.pluginmanager.get_plugin("funcmanage") + assert fixturemanager is not None + for fixtures in fixturemanager._arg2fixturedefs.values(): + for fixturedef in fixtures: + func = fixturedef.func + if fixturedef in processed_fixturedefs or not _is_coroutine_or_asyncgen( + func + ): + continue + if asyncio_mode == Mode.STRICT and not _is_asyncio_fixture_function(func): + # Ignore async fixtures without explicit asyncio mark in strict mode + # This applies to pytest_trio fixtures, for example + continue + loop_scope = ( + getattr(func, "_loop_scope", None) + or default_loop_scope + or fixturedef.scope + ) + _make_asyncio_fixture_function(func, loop_scope) + if "request" not in fixturedef.argnames: + fixturedef.argnames += ("request",) + _synchronize_async_fixture(fixturedef) + assert _is_asyncio_fixture_function(fixturedef.func) + processed_fixturedefs.add(fixturedef) + + +def _synchronize_async_fixture(fixturedef: FixtureDef) -> None: + """Wraps the fixture function of an async fixture in a synchronous function.""" + if inspect.isasyncgenfunction(fixturedef.func): + _wrap_asyncgen_fixture(fixturedef) + elif inspect.iscoroutinefunction(fixturedef.func): + _wrap_async_fixture(fixturedef) + + +def _add_kwargs( + func: Callable[..., Any], + kwargs: dict[str, Any], + request: FixtureRequest, +) -> dict[str, Any]: + sig = inspect.signature(func) + ret = kwargs.copy() + if "request" in sig.parameters: + ret["request"] = request + return ret + + +def _perhaps_rebind_fixture_func(func: _T, instance: Any | None) -> _T: + if instance is not None: + # The fixture needs to be bound to the actual request.instance + # so it is bound to the same object as the test method. + unbound, cls = func, None + try: + unbound, cls = func.__func__, type(func.__self__) # type: ignore + except AttributeError: + pass + # Only if the fixture was bound before to an instance of + # the same type. + if cls is not None and isinstance(instance, cls): + func = unbound.__get__(instance) # type: ignore + return func + + +def _wrap_asyncgen_fixture(fixturedef: FixtureDef) -> None: + fixture = fixturedef.func + + @functools.wraps(fixture) + def _asyncgen_fixture_wrapper(request: FixtureRequest, **kwargs: Any): + func = _perhaps_rebind_fixture_func(fixture, request.instance) + event_loop_fixture_id = _get_event_loop_fixture_id_for_async_fixture( + request, func + ) + event_loop = request.getfixturevalue(event_loop_fixture_id) + kwargs.pop(event_loop_fixture_id, None) + gen_obj = func(**_add_kwargs(func, kwargs, request)) + + async def setup(): + res = await gen_obj.__anext__() # type: ignore[union-attr] + return res + + context = contextvars.copy_context() + setup_task = _create_task_in_context(event_loop, setup(), context) + result = event_loop.run_until_complete(setup_task) + + reset_contextvars = _apply_contextvar_changes(context) + + def finalizer() -> None: + """Yield again, to finalize.""" + + async def async_finalizer() -> None: + try: + await gen_obj.__anext__() # type: ignore[union-attr] + except StopAsyncIteration: + pass + else: + msg = "Async generator fixture didn't stop." + msg += "Yield only once." + raise ValueError(msg) + + task = _create_task_in_context(event_loop, async_finalizer(), context) + event_loop.run_until_complete(task) + if reset_contextvars is not None: + reset_contextvars() + + request.addfinalizer(finalizer) + return result + + fixturedef.func = _asyncgen_fixture_wrapper # type: ignore[misc] + + +def _wrap_async_fixture(fixturedef: FixtureDef) -> None: + fixture = fixturedef.func + + @functools.wraps(fixture) + def _async_fixture_wrapper(request: FixtureRequest, **kwargs: Any): + func = _perhaps_rebind_fixture_func(fixture, request.instance) + event_loop_fixture_id = _get_event_loop_fixture_id_for_async_fixture( + request, func + ) + event_loop = request.getfixturevalue(event_loop_fixture_id) + kwargs.pop(event_loop_fixture_id, None) + + async def setup(): + res = await func(**_add_kwargs(func, kwargs, request)) + return res + + context = contextvars.copy_context() + setup_task = _create_task_in_context(event_loop, setup(), context) + result = event_loop.run_until_complete(setup_task) + + # Copy the context vars modified by the setup task into the current + # context, and (if needed) add a finalizer to reset them. + # + # Note that this is slightly different from the behavior of a non-async + # fixture, which would rely on the fixture author to add a finalizer + # to reset the variables. In this case, the author of the fixture can't + # write such a finalizer because they have no way to capture the Context + # in which the setup function was run, so we need to do it for them. + reset_contextvars = _apply_contextvar_changes(context) + if reset_contextvars is not None: + request.addfinalizer(reset_contextvars) + + return result + + fixturedef.func = _async_fixture_wrapper # type: ignore[misc] + + +def _get_event_loop_fixture_id_for_async_fixture( + request: FixtureRequest, func: Any +) -> str: + default_loop_scope = cast( + _ScopeName, request.config.getini("asyncio_default_fixture_loop_scope") + ) + loop_scope = ( + getattr(func, "_loop_scope", None) or default_loop_scope or request.scope + ) + return f"_{loop_scope}_event_loop" + + +def _create_task_in_context( + loop: asyncio.AbstractEventLoop, + coro: AbstractCoroutine[Any, Any, _T], + context: contextvars.Context, +) -> asyncio.Task[_T]: + """ + Return an asyncio task that runs the coro in the specified context, + if possible. + + This allows fixture setup and teardown to be run as separate asyncio tasks, + while still being able to use context-manager idioms to maintain context + variables and make those variables visible to test functions. + + This is only fully supported on Python 3.11 and newer, as it requires + the API added for https://github.com/python/cpython/issues/91150. + On earlier versions, the returned task will use the default context instead. + """ + try: + return loop.create_task(coro, context=context) + except TypeError: + return loop.create_task(coro) + + +def _apply_contextvar_changes( + context: contextvars.Context, +) -> Callable[[], None] | None: + """ + Copy contextvar changes from the given context to the current context. + + If any contextvars were modified by the fixture, return a finalizer that + will restore them. + """ + context_tokens = [] + for var in context: + try: + if var.get() is context.get(var): + # This variable is not modified, so leave it as-is. + continue + except LookupError: + # This variable isn't yet set in the current context at all. + pass + token = var.set(context.get(var)) + context_tokens.append((var, token)) + + if not context_tokens: + return None + + def restore_contextvars(): + while context_tokens: + (var, token) = context_tokens.pop() + var.reset(token) + + return restore_contextvars + + +class PytestAsyncioFunction(Function): + """Base class for all test functions managed by pytest-asyncio.""" + + @classmethod + def item_subclass_for(cls, item: Function, /) -> type[PytestAsyncioFunction] | None: + """ + Returns a subclass of PytestAsyncioFunction if there is a specialized subclass + for the specified function item. + + Return None if no specialized subclass exists for the specified item. + """ + for subclass in cls.__subclasses__(): + if subclass._can_substitute(item): + return subclass + return None + + @classmethod + def _from_function(cls, function: Function, /) -> Function: + """ + Instantiates this specific PytestAsyncioFunction type from the specified + Function item. + """ + assert function.get_closest_marker("asyncio") + subclass_instance = cls.from_parent( + function.parent, + name=function.name, + callspec=getattr(function, "callspec", None), + callobj=function.obj, + fixtureinfo=function._fixtureinfo, + keywords=function.keywords, + originalname=function.originalname, + ) + subclass_instance.own_markers = function.own_markers + assert subclass_instance.own_markers == function.own_markers + return subclass_instance + + @staticmethod + def _can_substitute(item: Function) -> bool: + """Returns whether the specified function can be replaced by this class""" + raise NotImplementedError() + + +class Coroutine(PytestAsyncioFunction): + """Pytest item created by a coroutine""" + + @staticmethod + def _can_substitute(item: Function) -> bool: + func = item.obj + return inspect.iscoroutinefunction(func) + + def runtest(self) -> None: + self.obj = wrap_in_sync( + # https://github.com/pytest-dev/pytest-asyncio/issues/596 + self.obj, # type: ignore[has-type] + ) + super().runtest() + + +class AsyncGenerator(PytestAsyncioFunction): + """Pytest item created by an asynchronous generator""" + + @staticmethod + def _can_substitute(item: Function) -> bool: + func = item.obj + return inspect.isasyncgenfunction(func) + + @classmethod + def _from_function(cls, function: Function, /) -> Function: + async_gen_item = super()._from_function(function) + unsupported_item_type_message = ( + f"Tests based on asynchronous generators are not supported. " + f"{function.name} will be ignored." + ) + async_gen_item.warn(PytestCollectionWarning(unsupported_item_type_message)) + async_gen_item.add_marker( + pytest.mark.xfail(run=False, reason=unsupported_item_type_message) + ) + return async_gen_item + + +class AsyncStaticMethod(PytestAsyncioFunction): + """ + Pytest item that is a coroutine or an asynchronous generator + decorated with staticmethod + """ + + @staticmethod + def _can_substitute(item: Function) -> bool: + func = item.obj + return isinstance(func, staticmethod) and _is_coroutine_or_asyncgen( + func.__func__ + ) + + def runtest(self) -> None: + self.obj = wrap_in_sync( + # https://github.com/pytest-dev/pytest-asyncio/issues/596 + self.obj, # type: ignore[has-type] + ) + super().runtest() + + +class AsyncHypothesisTest(PytestAsyncioFunction): + """ + Pytest item that is coroutine or an asynchronous generator decorated by + @hypothesis.given. + """ + + @staticmethod + def _can_substitute(item: Function) -> bool: + func = item.obj + return ( + getattr(func, "is_hypothesis_test", False) # type: ignore[return-value] + and getattr(func, "hypothesis", None) + and inspect.iscoroutinefunction(func.hypothesis.inner_test) + ) + + def runtest(self) -> None: + self.obj.hypothesis.inner_test = wrap_in_sync( + self.obj.hypothesis.inner_test, + ) + super().runtest() + + +_HOLDER: set[FixtureDef] = set() + + +# The function name needs to start with "pytest_" +# see https://github.com/pytest-dev/pytest/issues/11307 +@pytest.hookimpl(specname="pytest_pycollect_makeitem", tryfirst=True) +def pytest_pycollect_makeitem_preprocess_async_fixtures( + collector: pytest.Module | pytest.Class, name: str, obj: object +) -> pytest.Item | pytest.Collector | list[pytest.Item | pytest.Collector] | None: + """A pytest hook to collect asyncio coroutines.""" + if not collector.funcnamefilter(name): + return None + _preprocess_async_fixtures(collector, _HOLDER) + return None + + +# The function name needs to start with "pytest_" +# see https://github.com/pytest-dev/pytest/issues/11307 +@pytest.hookimpl(specname="pytest_pycollect_makeitem", hookwrapper=True) +def pytest_pycollect_makeitem_convert_async_functions_to_subclass( + collector: pytest.Module | pytest.Class, name: str, obj: object +) -> Generator[None, pluggy.Result, None]: + """ + Converts coroutines and async generators collected as pytest.Functions + to AsyncFunction items. + """ + hook_result = yield + try: + node_or_list_of_nodes: ( + pytest.Item | pytest.Collector | list[pytest.Item | pytest.Collector] | None + ) = hook_result.get_result() + except BaseException as e: + hook_result.force_exception(e) + return + if not node_or_list_of_nodes: + return + if isinstance(node_or_list_of_nodes, Sequence): + node_iterator = iter(node_or_list_of_nodes) + else: + # Treat single node as a single-element iterable + node_iterator = iter((node_or_list_of_nodes,)) + updated_node_collection = [] + for node in node_iterator: + updated_item = node + if isinstance(node, Function): + specialized_item_class = PytestAsyncioFunction.item_subclass_for(node) + if specialized_item_class: + if _get_asyncio_mode( + node.config + ) == Mode.AUTO and not node.get_closest_marker("asyncio"): + node.add_marker("asyncio") + if node.get_closest_marker("asyncio"): + updated_item = specialized_item_class._from_function(node) + updated_node_collection.append(updated_item) + hook_result.force_result(updated_node_collection) + + +@contextlib.contextmanager +def _temporary_event_loop_policy(policy: AbstractEventLoopPolicy) -> Iterator[None]: + old_loop_policy = _get_event_loop_policy() + try: + old_loop = _get_event_loop_no_warn() + except RuntimeError: + old_loop = None + _set_event_loop_policy(policy) + try: + yield + finally: + _set_event_loop_policy(old_loop_policy) + _set_event_loop(old_loop) + + +@pytest.hookimpl(tryfirst=True) +def pytest_generate_tests(metafunc: Metafunc) -> None: + marker = metafunc.definition.get_closest_marker("asyncio") + if not marker: + return + default_loop_scope = _get_default_test_loop_scope(metafunc.config) + loop_scope = _get_marked_loop_scope(marker, default_loop_scope) + event_loop_fixture_id = f"_{loop_scope}_event_loop" + # This specific fixture name may already be in metafunc.argnames, if this + # test indirectly depends on the fixture. For example, this is the case + # when the test depends on an async fixture, both of which share the same + # event loop fixture mark. + if event_loop_fixture_id in metafunc.fixturenames: + return + fixturemanager = metafunc.config.pluginmanager.get_plugin("funcmanage") + assert fixturemanager is not None + # Add the scoped event loop fixture to Metafunc's list of fixture names and + # fixturedefs and leave the actual parametrization to pytest + # The fixture needs to be appended to avoid messing up the fixture evaluation + # order + metafunc.fixturenames.append(event_loop_fixture_id) + metafunc._arg2fixturedefs[event_loop_fixture_id] = fixturemanager._arg2fixturedefs[ + event_loop_fixture_id + ] + + +def _get_event_loop_policy() -> AbstractEventLoopPolicy: + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + return asyncio.get_event_loop_policy() + + +def _set_event_loop_policy(policy: AbstractEventLoopPolicy) -> None: + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + asyncio.set_event_loop_policy(policy) + + +def _get_event_loop_no_warn( + policy: AbstractEventLoopPolicy | None = None, +) -> asyncio.AbstractEventLoop: + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + if policy is not None: + return policy.get_event_loop() + else: + return asyncio.get_event_loop() + + +def _set_event_loop(loop: AbstractEventLoop | None) -> None: + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + asyncio.set_event_loop(loop) + + +@pytest.hookimpl(tryfirst=True, hookwrapper=True) +def pytest_pyfunc_call(pyfuncitem: Function) -> object | None: + """ + Pytest hook called before a test case is run. + + Wraps marked tests in a synchronous function + where the wrapped test coroutine is executed in an event loop. + """ + if pyfuncitem.get_closest_marker("asyncio") is not None: + if isinstance(pyfuncitem, PytestAsyncioFunction): + asyncio_mode = _get_asyncio_mode(pyfuncitem.config) + for fixname, fixtures in pyfuncitem._fixtureinfo.name2fixturedefs.items(): + # name2fixturedefs is a dict between fixture name and a list of matching + # fixturedefs. The last entry in the list is closest and the one used. + func = fixtures[-1].func + if ( + asyncio_mode == Mode.STRICT + and _is_coroutine_or_asyncgen(func) + and not _is_asyncio_fixture_function(func) + ): + warnings.warn( + PytestDeprecationWarning( + f"asyncio test {pyfuncitem.name!r} requested async " + "@pytest.fixture " + f"{fixname!r} in strict mode. " + "You might want to use @pytest_asyncio.fixture or switch " + "to auto mode. " + "This will become an error in future versions of " + "flake8-asyncio." + ), + stacklevel=1, + ) + # no stacklevel points at the users code, so we set stacklevel=1 + # so it at least indicates that it's the plugin complaining. + # Pytest gives the test file & name in the warnings summary at least + + else: + pyfuncitem.warn( + pytest.PytestWarning( + f"The test {pyfuncitem} is marked with '@pytest.mark.asyncio' " + "but it is not an async function. " + "Please remove the asyncio mark. " + "If the test is not marked explicitly, " + "check for global marks applied via 'pytestmark'." + ) + ) + yield + return None + + +def wrap_in_sync( + func: Callable[..., Awaitable[Any]], +): + """ + Return a sync wrapper around an async function executing it in the + current event loop. + """ + # if the function is already wrapped, we rewrap using the original one + # not using __wrapped__ because the original function may already be + # a wrapped one + raw_func = getattr(func, "_raw_test_func", None) + if raw_func is not None: + func = raw_func + + @functools.wraps(func) + def inner(*args, **kwargs): + coro = func(*args, **kwargs) + _loop = _get_event_loop_no_warn() + task = asyncio.ensure_future(coro, loop=_loop) + try: + _loop.run_until_complete(task) + except BaseException: + # run_until_complete doesn't get the result from exceptions + # that are not subclasses of `Exception`. Consume all + # exceptions to prevent asyncio's warning from logging. + if task.done() and not task.cancelled(): + task.exception() + raise + + inner._raw_test_func = func # type: ignore[attr-defined] + return inner + + +def pytest_runtest_setup(item: pytest.Item) -> None: + marker = item.get_closest_marker("asyncio") + if marker is None: + return + default_loop_scope = _get_default_test_loop_scope(item.config) + loop_scope = _get_marked_loop_scope(marker, default_loop_scope) + event_loop_fixture_id = f"_{loop_scope}_event_loop" + fixturenames = item.fixturenames # type: ignore[attr-defined] + if event_loop_fixture_id not in fixturenames: + fixturenames.append(event_loop_fixture_id) + obj = getattr(item, "obj", None) + if not getattr(obj, "hypothesis", False) and getattr( + obj, "is_hypothesis_test", False + ): + pytest.fail( + f"test function `{item!r}` is using Hypothesis, but pytest-asyncio " + "only works with Hypothesis 3.64.0 or later." + ) + + +_DUPLICATE_LOOP_SCOPE_DEFINITION_ERROR = """\ +An asyncio pytest marker defines both "scope" and "loop_scope", \ +but it should only use "loop_scope". +""" + +_MARKER_SCOPE_KWARG_DEPRECATION_WARNING = """\ +The "scope" keyword argument to the asyncio marker has been deprecated. \ +Please use the "loop_scope" argument instead. +""" + + +def _get_marked_loop_scope( + asyncio_marker: Mark, default_loop_scope: _ScopeName +) -> _ScopeName: + assert asyncio_marker.name == "asyncio" + if asyncio_marker.args or ( + asyncio_marker.kwargs and set(asyncio_marker.kwargs) - {"loop_scope", "scope"} + ): + raise ValueError("mark.asyncio accepts only a keyword argument 'loop_scope'.") + if "scope" in asyncio_marker.kwargs: + if "loop_scope" in asyncio_marker.kwargs: + raise pytest.UsageError(_DUPLICATE_LOOP_SCOPE_DEFINITION_ERROR) + warnings.warn(PytestDeprecationWarning(_MARKER_SCOPE_KWARG_DEPRECATION_WARNING)) + scope = asyncio_marker.kwargs.get("loop_scope") or asyncio_marker.kwargs.get( + "scope" + ) + if scope is None: + scope = default_loop_scope + assert scope in {"function", "class", "module", "package", "session"} + return scope + + +def _get_default_test_loop_scope(config: Config) -> _ScopeName: + return config.getini("asyncio_default_test_loop_scope") + + +def _create_scoped_event_loop_fixture(scope: _ScopeName) -> Callable: + @pytest.fixture( + scope=scope, + name=f"_{scope}_event_loop", + ) + def _scoped_event_loop( + *args, # Function needs to accept "cls" when collected by pytest.Class + event_loop_policy, + ) -> Iterator[asyncio.AbstractEventLoop]: + new_loop_policy = event_loop_policy + with ( + _temporary_event_loop_policy(new_loop_policy), + _provide_event_loop() as loop, + ): + _set_event_loop(loop) + yield loop + + return _scoped_event_loop + + +for scope in Scope: + globals()[f"_{scope.value}_event_loop"] = _create_scoped_event_loop_fixture( + scope.value + ) + + +@contextlib.contextmanager +def _provide_event_loop() -> Iterator[asyncio.AbstractEventLoop]: + policy = _get_event_loop_policy() + loop = policy.new_event_loop() + try: + yield loop + finally: + # cleanup the event loop if it hasn't been cleaned up already + if not loop.is_closed(): + try: + loop.run_until_complete(loop.shutdown_asyncgens()) + except Exception as e: + warnings.warn(f"Error cleaning up asyncio loop: {e}", RuntimeWarning) + finally: + loop.close() + + +@pytest.fixture(scope="session", autouse=True) +def event_loop_policy() -> AbstractEventLoopPolicy: + """Return an instance of the policy used to create asyncio event loops.""" + return _get_event_loop_policy() + + +def is_async_test(item: Item) -> bool: + """Returns whether a test item is a pytest-asyncio test""" + return isinstance(item, PytestAsyncioFunction) + + +def _unused_port(socket_type: int) -> int: + """Find an unused localhost port from 1024-65535 and return it.""" + with contextlib.closing(socket.socket(type=socket_type)) as sock: + sock.bind(("127.0.0.1", 0)) + return sock.getsockname()[1] + + +@pytest.fixture +def unused_tcp_port() -> int: + return _unused_port(socket.SOCK_STREAM) + + +@pytest.fixture +def unused_udp_port() -> int: + return _unused_port(socket.SOCK_DGRAM) + + +@pytest.fixture(scope="session") +def unused_tcp_port_factory() -> Callable[[], int]: + """A factory function, producing different unused TCP ports.""" + produced = set() + + def factory(): + """Return an unused port.""" + port = _unused_port(socket.SOCK_STREAM) + + while port in produced: + port = _unused_port(socket.SOCK_STREAM) + + produced.add(port) + + return port + + return factory + + +@pytest.fixture(scope="session") +def unused_udp_port_factory() -> Callable[[], int]: + """A factory function, producing different unused UDP ports.""" + produced = set() + + def factory(): + """Return an unused port.""" + port = _unused_port(socket.SOCK_DGRAM) + + while port in produced: + port = _unused_port(socket.SOCK_DGRAM) + + produced.add(port) + + return port + + return factory diff --git a/.venv/Lib/site-packages/pytest_asyncio/py.typed b/.venv/Lib/site-packages/pytest_asyncio/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/app_flask/flask_application.py b/app_flask/flask_application.py index bd4f688..ca23d35 100644 --- a/app_flask/flask_application.py +++ b/app_flask/flask_application.py @@ -7,7 +7,7 @@ app = Flask(__name__) @app.route("/") def home(): time.sleep(3) # simulate slow work - html = "Hello from Flask :)" + html = "

Slow Flask Demo

" # TDD Phase 2 content return Response(html, mimetype="text/html") if __name__ == "__main__": @@ -18,4 +18,4 @@ if __name__ == "__main__": # Open the URL in a new browser tab webbrowser.open_new_tab(url) - app.run(host=host, port=port) \ No newline at end of file + app.run(host="0.0.0.0", port=3000) \ No newline at end of file diff --git a/tests/__pycache__/test_fastapi_route.cpython-312-pytest-8.3.5.pyc b/tests/__pycache__/test_fastapi_route.cpython-312-pytest-8.3.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb357836760e7f8e53d6b9875610e219458fce22 GIT binary patch literal 4287 zcmd59ZD<_Fb!K<(_C8i$KAn59B>UnI$=B#xj$|v6U0Je`s$f){6nqsN>)VyIr@Px@ zc26IdyGFH48-s`~C|05Qk%U58oV0c+82T@v)JhCRsvJ&i4GlDq`cF}9L;dlieY1Oe zcTq&$LQ6Zkoq6xgd-FbK-n`N6iV6>c_Uj+_PCa!Z^e2kgjVS;Reh9z{l8}VsD2&aK zNw84{qXZXrU~9%1cA7JMm^VjP*kz9Hu-hCxVUIa_!(MX~!h*zHMBxfqh}GLFOJl6M z1ly3rUPRXlNVsYqhq!wbI}^1T=*Yvj2;YMYMragauw18fv&C$mYyyliM;TH8pCLhY zY-`VuaBpJ=R5v3}>DRzg+9Z6fV4qFNp-Ch$@8TTRD=Z$cx6+16V-{zTF4*`^vHRz< z@3Yr9OFGBszT!HyHdGoV&bDn4_Wd;$p{vXa`+bK4BAsQUni@Z=NOEw@64k~}gR=u;Bf%Lhcsed>)8oTpbXq3C zAvLCs>$0Y6W^V@tbftB3px}ou2pl-s$@lbCbWp->kY(^&8hl`^f5%jRRvFzHcqOeBX(@ui%Bj&%OS< zw{G2Ax9Re33W2*-&s~1~((8rcq1z!i7ls}R$h+%u%cYhdu^XQHJXgQQ)o*&M7Dl&N z) z?ePNa;vCMg@Hujv+I<3U7PG13p&6sgL#!StlbrkBQ&C*Vh@M7N>R{5dp_W|3{je=;t!=zr_i zY|$^vJF~i1pULc=()CntTU$qGk6F4qdTGUOySEC#3E?M9e}4#Px(*#q&3A@0&uaxB z*dL@&dq``A8mFhVNK}<%PcGPRO}rS=3`}U<2PWEe((c7frKmwQ)J@?Y-~nP!W>4Q# z$MLgqbv9^M+95fi_O$^ugbhYXf(6Y~T}Ma@DoIlq6j;UpP%x$ojM3#e-IKHQcF@(k z2tBv==;IL9;&mkLAsxESuDcZRpjJwj`nQTd7$np1Nrg~*cO zND&2G;i$g`H!CW7NFci@r!#7LN$7Lm@KVdIP33@50-Pe>C=)mU(x8Lw>O3A%OjUYmPQM}o1U_a#XaKQPY z>$DG$TXkNb-)h9eb=<8cj>0cggW#<`|8OT-tziIO^<$u~1~Bli)|qgFbGVIPJ%EQB zh1G*Rg#=ckH1~d0DOBd zrtm(N!uu(IsM>JZHv?&==l;2fb(geSX$Se;O5|Ch=(6E1k_^5;BVPv@(nvd+=Y&2= z3H?77{tHtklOiNHy%Y_nwWxKeaS4%36PiFjLl2-wR>ryd5~`Gr%g4#fK%E=0Bi{`_4*Sy%j`^>j!n;tIOlsbzJ*brUnNdu!!-S5E%ve Fe*hs(oeBT| literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_flask_route.cpython-312-pytest-8.3.5.pyc b/tests/__pycache__/test_flask_route.cpython-312-pytest-8.3.5.pyc index c1722ee5ccde3ef84ffba700013ff44010e3b294..25cc9664466b4d68d8f47d78e8bd164467b7b4ee 100644 GIT binary patch literal 4556 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 diff --git a/tests/test_fastapi_route.py b/tests/test_fastapi_route.py new file mode 100644 index 0000000..f873426 --- /dev/null +++ b/tests/test_fastapi_route.py @@ -0,0 +1,41 @@ +# tests/test_fastapi_route.py +import httpx +import subprocess, asyncio, os, signal, time # signal and time may not be needed if Popen is handled well +import pytest # For @pytest.mark.asyncio + +# Adjusted to be an async function and use uvicorn +async def start_server_fastapi(): + # Ensure CWD is project root + project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + # Command to run FastAPI app with uvicorn + # Assuming app_fastapi/app.py and app instance is named 'app' + cmd = ["uvicorn", "app_fastapi.app:app", "--host", "0.0.0.0", "--port", "8000"] + + proc = subprocess.Popen( + cmd, + cwd=project_root, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + await asyncio.sleep(1.5) # Allow uvicorn to start + return proc + +@pytest.mark.asyncio +async def test_home_returns_html_fastapi(): + proc = await start_server_fastapi() + try: + async with httpx.AsyncClient() as client: + r = await client.get("http://127.0.0.1:8000/") # Default FastAPI port + assert r.status_code == 200 + assert "

Slow FastAPI Demo

" in r.text # Expected content + finally: + proc.terminate() + try: + # Use communicate to get output and ensure process is reaped + stdout, stderr = proc.communicate(timeout=5) + # print(f"FastAPI stdout:\n{stdout.decode(errors='replace')}") # Optional: for debugging + # print(f"FastAPI stderr:\n{stderr.decode(errors='replace')}") # Optional: for debugging + except subprocess.TimeoutExpired: + print("FastAPI server did not terminate/communicate gracefully, killing.") + proc.kill() + proc.wait() # Ensure kill completes \ No newline at end of file diff --git a/tests/test_flask_route.py b/tests/test_flask_route.py index 0ab89a3..d9a7e61 100644 --- a/tests/test_flask_route.py +++ b/tests/test_flask_route.py @@ -2,25 +2,48 @@ import httpx import subprocess, time, os, signal def start_server(): - # Ensure the Python interpreter can find the app_flask module. - # This might require adjusting PYTHONPATH or running pytest from the project root. - proc = subprocess.Popen(["python", "-m", "app_flask.flask_application"]) # Updated module name - time.sleep(1) # Increased sleep to allow server startup, especially on slower systems + current_env = os.environ.copy() + project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + script_path = os.path.join(project_root, "app_flask", "flask_application.py") + proc = subprocess.Popen( + ["python", script_path], + env=current_env, + cwd=project_root, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + time.sleep(1.5) return proc def test_home_returns_html(): proc = start_server() + server_stdout_data = b"" + server_stderr_data = b"" try: - r = httpx.get("http://127.0.0.1:3000/", timeout=10) + headers = { + "Cache-Control": "no-cache, no-store, must-revalidate", + "Pragma": "no-cache", + "Expires": "0" + } + r = httpx.get("http://127.0.0.1:3000/", timeout=10, headers=headers) assert r.status_code == 200 - assert "Hello from Flask :)" in r.text # Corrected assertion + assert "

Slow Flask Demo

" in r.text finally: - # It's important to ensure the server process is terminated. - # os.kill might not be cross-platform for SIGINT. - # proc.terminate() followed by proc.wait() is generally safer. proc.terminate() try: - proc.wait(timeout=5) # Wait for the process to terminate + stdout_bytes, stderr_bytes = proc.communicate(timeout=5) + server_stdout_data = stdout_bytes + server_stderr_data = stderr_bytes except subprocess.TimeoutExpired: - proc.kill() # Force kill if terminate doesn't work - proc.wait() # Wait for the kill to complete \ No newline at end of file + print("Server did not terminate/communicate gracefully, killing.") + proc.kill() + try: + stdout_bytes, stderr_bytes = proc.communicate(timeout=1) + server_stdout_data = stdout_bytes + server_stderr_data = stderr_bytes + except subprocess.TimeoutExpired: + print("Could not get output even after kill.") + + # Keep these for CI logs or if needed later, but they will be empty if flask app is quiet. + # print(f"Server stdout captured:\n{server_stdout_data.decode(errors='replace')}") + # print(f"Server stderr captured:\n{server_stderr_data.decode(errors='replace')}") \ No newline at end of file -- 2.25.1