diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..cf368171 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,39 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: 'v4.1.0' + hooks: + - id: check-merge-conflict + exclude: "rst$" +- repo: https://github.com/asottile/yesqa + rev: v1.3.0 + hooks: + - id: yesqa +- repo: https://github.com/Zac-HD/shed + rev: 0.6.0 # 0.7 does not support Python 3.7 + hooks: + - id: shed + args: + - --refactor + - --py37-plus + types_or: + - python + - markdown + - rst +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.1.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: fix-encoding-pragma + args: [--remove] + - id: check-yaml + - id: debug-statements +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.9.2 + hooks: + - id: flake8 + language_version: python3 +- repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.9.0 + hooks: + - id: python-use-type-annotations diff --git a/LICENSE b/LICENSE index e06d2081..5c304d1a 100644 --- a/LICENSE +++ b/LICENSE @@ -199,4 +199,3 @@ Apache License 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/Makefile b/Makefile index 8cf88841..fa6d6c0d 100644 --- a/Makefile +++ b/Makefile @@ -20,9 +20,17 @@ clean-test: ## remove test and coverage artifacts rm -f .coverage rm -fr htmlcov/ -lint: ## check style with flake8 - flake8 pytest_asyncio tests - black --check --verbose pytest_asyncio tests +lint: +# CI env-var is set by GitHub actions +ifdef CI + pre-commit run --all-files --show-diff-on-failure +else + pre-commit run --all-files +endif test: pytest tests + +install: + pip install -U pre-commit + pre-commit install diff --git a/README.rst b/README.rst index acaa99b5..2e36df3a 100644 --- a/README.rst +++ b/README.rst @@ -25,7 +25,7 @@ provides useful fixtures and markers to make testing easier. @pytest.mark.asyncio async def test_some_asyncio_code(): res = await library.do_something() - assert b'expected result' == res + assert b"expected result" == res pytest-asyncio has been strongly influenced by pytest-tornado_. @@ -139,9 +139,9 @@ Use ``pytest.mark.asyncio`` for this purpose. .. code-block:: python def test_http_client(event_loop): - url = 'http://httpbin.org/get' + url = "http://httpbin.org/get" resp = event_loop.run_until_complete(http_client(url)) - assert b'HTTP/1.1 200 OK' in resp + assert b"HTTP/1.1 200 OK" in resp This fixture can be easily overridden in any of the standard pytest locations (e.g. directly in the test file, or in ``conftest.py``) to use a non-default @@ -189,12 +189,14 @@ Asynchronous fixtures are defined just like ordinary pytest fixtures, except the import pytest_asyncio + @pytest_asyncio.fixture async def async_gen_fixture(): await asyncio.sleep(0.1) - yield 'a value' + yield "a value" + - @pytest_asyncio.fixture(scope='module') + @pytest_asyncio.fixture(scope="module") async def async_fixture(): return await asyncio.sleep(0.1) @@ -227,11 +229,13 @@ Only test coroutines will be affected (by default, coroutines prefixed by .. code-block:: python import asyncio + import pytest # All test coroutines will be treated as marked. pytestmark = pytest.mark.asyncio + async def test_example(event_loop): """No marker!""" await asyncio.sleep(0, loop=event_loop) diff --git a/pytest_asyncio/__init__.py b/pytest_asyncio/__init__.py index 0da62156..2a50727f 100644 --- a/pytest_asyncio/__init__.py +++ b/pytest_asyncio/__init__.py @@ -3,5 +3,4 @@ from .plugin import fixture - __all__ = ("fixture",) diff --git a/pytest_asyncio/plugin.py b/pytest_asyncio/plugin.py index 44165602..06b2af19 100644 --- a/pytest_asyncio/plugin.py +++ b/pytest_asyncio/plugin.py @@ -174,7 +174,8 @@ def pytest_fixture_post_finalizer(fixturedef, request): """Called after fixture teardown""" if fixturedef.argname == "event_loop": policy = asyncio.get_event_loop_policy() - policy.get_event_loop().close() # Clean up existing loop to avoid ResourceWarnings + # Clean up existing loop to avoid ResourceWarnings + policy.get_event_loop().close() new_loop = policy.new_event_loop() # Replace existing event loop # Ensure subsequent calls to get_event_loop() succeed policy.set_event_loop(new_loop) @@ -297,7 +298,8 @@ def pytest_pyfunc_call(pyfuncitem): """ 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. + Wraps marked tests in a synchronous function + where the wrapped test coroutine is executed in an event loop. """ if "asyncio" in pyfuncitem.keywords: if getattr(pyfuncitem.obj, "is_hypothesis_test", False): diff --git a/setup.cfg b/setup.cfg index fc18e3d9..e2804822 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,4 +15,4 @@ filterwarnings = error license_file = LICENSE [flake8] -ignore = E203, E501, W503 +max-line-length = 88 diff --git a/setup.py b/setup.py index 1cd1415c..4b331753 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ import re from pathlib import Path -from setuptools import setup, find_packages +from setuptools import find_packages, setup def find_version(): diff --git a/tests/async_fixtures/test_async_fixtures_with_finalizer.py b/tests/async_fixtures/test_async_fixtures_with_finalizer.py index c90a0124..2e72d5de 100644 --- a/tests/async_fixtures/test_async_fixtures_with_finalizer.py +++ b/tests/async_fixtures/test_async_fixtures_with_finalizer.py @@ -46,7 +46,8 @@ def port_finalizer(finalizer): async def port_afinalizer(): # await task using current loop retrieved from the event loop policy # RuntimeError is raised if task is created on a different loop. - # This can happen when pytest_fixture_setup does not set up the loop correctly, + # This can happen when pytest_fixture_setup + # does not set up the loop correctly, # for example when policy.set_event_loop() is called with a wrong argument await finalizer diff --git a/tests/hypothesis/test_base.py b/tests/hypothesis/test_base.py index 39cb6075..e9273d0e 100644 --- a/tests/hypothesis/test_base.py +++ b/tests/hypothesis/test_base.py @@ -4,7 +4,6 @@ import asyncio import pytest - from hypothesis import given, strategies as st diff --git a/tests/hypothesis/test_inherited_test.py b/tests/hypothesis/test_inherited_test.py index 86e92efd..a7762264 100644 --- a/tests/hypothesis/test_inherited_test.py +++ b/tests/hypothesis/test_inherited_test.py @@ -1,22 +1,20 @@ import hypothesis.strategies as st -from hypothesis import given import pytest +from hypothesis import given class BaseClass: @pytest.mark.asyncio @given(value=st.integers()) async def test_hypothesis(self, value: int) -> None: - assert True + pass class TestOne(BaseClass): - """During the first execution the Hypothesis test is wrapped in a synchronous function.""" - - pass + """During the first execution the Hypothesis test + is wrapped in a synchronous function.""" class TestTwo(BaseClass): - """Execute the test a second time to ensure that the test receives a fresh event loop.""" - - pass + """Execute the test a second time to ensure that + the test receives a fresh event loop.""" diff --git a/tests/multiloop/conftest.py b/tests/multiloop/conftest.py index 9c74a509..ebcb627a 100644 --- a/tests/multiloop/conftest.py +++ b/tests/multiloop/conftest.py @@ -6,8 +6,6 @@ class CustomSelectorLoop(asyncio.SelectorEventLoop): """A subclass with no overrides, just to test for presence.""" - pass - @pytest.fixture def event_loop(): diff --git a/tests/respect_event_loop_policy/test_respects_event_loop_policy.py b/tests/respect_event_loop_policy/test_respects_event_loop_policy.py index 2537ca24..610b3388 100644 --- a/tests/respect_event_loop_policy/test_respects_event_loop_policy.py +++ b/tests/respect_event_loop_policy/test_respects_event_loop_policy.py @@ -6,7 +6,8 @@ @pytest.mark.asyncio async def test_uses_loop_provided_by_custom_policy(): - """Asserts that test cases use the event loop provided by the custom event loop policy""" + """Asserts that test cases use the event loop + provided by the custom event loop policy""" assert type(asyncio.get_event_loop()).__name__ == "TestEventLoop" diff --git a/tests/sessionloop/conftest.py b/tests/sessionloop/conftest.py index 6c657688..bb6c1d6c 100644 --- a/tests/sessionloop/conftest.py +++ b/tests/sessionloop/conftest.py @@ -6,8 +6,6 @@ class CustomSelectorLoopSession(asyncio.SelectorEventLoop): """A subclass with no overrides, just to test for presence.""" - pass - loop = CustomSelectorLoopSession() diff --git a/tests/test_asyncio_fixture.py b/tests/test_asyncio_fixture.py index 824956d8..cfe10479 100644 --- a/tests/test_asyncio_fixture.py +++ b/tests/test_asyncio_fixture.py @@ -1,7 +1,9 @@ import asyncio -import pytest_asyncio + import pytest +import pytest_asyncio + @pytest_asyncio.fixture async def fixture_bare(): diff --git a/tests/test_dependent_fixtures.py b/tests/test_dependent_fixtures.py index 2876255b..dc70fe9c 100644 --- a/tests/test_dependent_fixtures.py +++ b/tests/test_dependent_fixtures.py @@ -1,4 +1,5 @@ import asyncio + import pytest diff --git a/tests/test_simple.py b/tests/test_simple.py index 42151852..31204b6c 100644 --- a/tests/test_simple.py +++ b/tests/test_simple.py @@ -2,6 +2,7 @@ import asyncio import pytest + import pytest_asyncio.plugin @@ -26,7 +27,7 @@ async def test_asyncio_marker(): @pytest.mark.xfail(reason="need a failure", strict=True) @pytest.mark.asyncio def test_asyncio_marker_fail(): - assert False + raise AssertionError @pytest.mark.asyncio @@ -196,13 +197,15 @@ class TestMarkerInClassBasedTests: @pytest.mark.asyncio async def test_asyncio_marker_with_explicit_loop_fixture(self, event_loop): - """Test the "asyncio" marker works on a method in a class-based test with explicit loop fixture.""" + """Test the "asyncio" marker works on a method in + a class-based test with explicit loop fixture.""" ret = await async_coro() assert ret == "ok" @pytest.mark.asyncio async def test_asyncio_marker_with_implicit_loop_fixture(self): - """Test the "asyncio" marker works on a method in a class-based test with implicit loop fixture.""" + """Test the "asyncio" marker works on a method in + a class-based test with implicit loop fixture.""" ret = await async_coro() assert ret == "ok" diff --git a/tests/test_subprocess.py b/tests/test_subprocess.py index 88ea29ab..311d67d5 100644 --- a/tests/test_subprocess.py +++ b/tests/test_subprocess.py @@ -1,5 +1,4 @@ """Tests for using subprocesses in tests.""" -import asyncio import asyncio.subprocess import sys diff --git a/tox.ini b/tox.ini index edae7dec..7d551eca 100644 --- a/tox.ini +++ b/tox.ini @@ -12,8 +12,7 @@ skip_install = true basepython = python3.9 extras = tests deps = - flake8 - black + pre-commit commands = make lint