Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
version: ${{ steps.version.outputs.version }}
prerelease: ${{ steps.version.outputs.prerelease }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
persist-credentials: false
Expand Down Expand Up @@ -51,7 +51,7 @@ jobs:
name: Run linters
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
persist-credentials: false
Expand All @@ -77,7 +77,7 @@ jobs:
required: [true]

steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548
Expand Down Expand Up @@ -116,7 +116,7 @@ jobs:
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
with:
jobs: ${{ toJSON(needs) }}
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548
Expand Down Expand Up @@ -151,7 +151,7 @@ jobs:
contents: write
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
persist-credentials: false
Expand Down
2 changes: 1 addition & 1 deletion pytest_asyncio/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ def _apply_contextvar_changes(

def restore_contextvars():
while context_tokens:
(var, token) = context_tokens.pop()
var, token = context_tokens.pop()
var.reset(token)

return restore_contextvars
Expand Down
85 changes: 20 additions & 65 deletions tests/async_fixtures/test_async_fixtures_contextvars.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
import pytest
from pytest import Pytester

_prelude = dedent(
"""
_prelude = dedent("""
import pytest
import pytest_asyncio
from contextlib import contextmanager
Expand All @@ -27,16 +26,12 @@ def context_var_manager(value):
yield
finally:
_context_var.reset(token)
"""
)
""")


def test_var_from_sync_generator_propagates_to_async(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
_prelude
+ dedent(
"""
pytester.makepyfile(_prelude + dedent("""
@pytest.fixture
def var_fixture():
with context_var_manager("value"):
Expand All @@ -49,19 +44,14 @@ async def check_var_fixture(var_fixture):
@pytest.mark.asyncio
async def test(check_var_fixture):
assert _context_var.get() == "value"
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=1)


def test_var_from_async_generator_propagates_to_sync(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
_prelude
+ dedent(
"""
pytester.makepyfile(_prelude + dedent("""
@pytest_asyncio.fixture
async def var_fixture():
with context_var_manager("value"):
Expand All @@ -74,19 +64,14 @@ def check_var_fixture(var_fixture):
@pytest.mark.asyncio
async def test(check_var_fixture):
assert _context_var.get() == "value"
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=1)


def test_var_from_async_fixture_propagates_to_sync(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
_prelude
+ dedent(
"""
pytester.makepyfile(_prelude + dedent("""
@pytest_asyncio.fixture
async def var_fixture():
_context_var.set("value")
Expand All @@ -98,19 +83,14 @@ def check_var_fixture(var_fixture):

def test(check_var_fixture):
assert _context_var.get() == "value"
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=1)


def test_var_from_generator_reset_before_previous_fixture_cleanup(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
_prelude
+ dedent(
"""
pytester.makepyfile(_prelude + dedent("""
@pytest_asyncio.fixture
async def no_var_fixture():
with pytest.raises(LookupError):
Expand All @@ -127,19 +107,14 @@ async def var_fixture(no_var_fixture):
@pytest.mark.asyncio
async def test(var_fixture):
assert _context_var.get() == "value"
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=1)


def test_var_from_fixture_reset_before_previous_fixture_cleanup(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
_prelude
+ dedent(
"""
pytester.makepyfile(_prelude + dedent("""
@pytest_asyncio.fixture
async def no_var_fixture():
with pytest.raises(LookupError):
Expand All @@ -156,19 +131,14 @@ async def var_fixture(no_var_fixture):
@pytest.mark.asyncio
async def test(var_fixture):
assert _context_var.get() == "value"
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=1)


def test_var_previous_value_restored_after_fixture(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
_prelude
+ dedent(
"""
pytester.makepyfile(_prelude + dedent("""
@pytest_asyncio.fixture
async def var_fixture_1():
with context_var_manager("value1"):
Expand All @@ -184,19 +154,14 @@ async def var_fixture_2(var_fixture_1):
@pytest.mark.asyncio
async def test(var_fixture_2):
assert _context_var.get() == "value2"
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=1)


def test_var_set_to_existing_value_ok(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
_prelude
+ dedent(
"""
pytester.makepyfile(_prelude + dedent("""
@pytest_asyncio.fixture
async def var_fixture():
with context_var_manager("value"):
Expand All @@ -210,18 +175,14 @@ async def same_var_fixture(var_fixture):
@pytest.mark.asyncio
async def test(same_var_fixture):
assert _context_var.get() == "value"
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=1)


def test_no_isolation_against_context_changes_in_sync_tests(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
"""
pytester.makepyfile(dedent("""
import pytest
import pytest_asyncio
from contextvars import ContextVar
Expand All @@ -234,9 +195,7 @@ def test_sync():
@pytest.mark.asyncio
async def test_async():
assert _context_var.get() == "new_value"
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=2)

Expand All @@ -246,9 +205,7 @@ def test_isolation_against_context_changes_in_async_tests(
pytester: Pytester, loop_scope: Literal["function", "module"]
):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
f"""
pytester.makepyfile(dedent(f"""
import pytest
import pytest_asyncio
from contextvars import ContextVar
Expand All @@ -263,8 +220,6 @@ async def test_async_first():
async def test_async_second():
with pytest.raises(LookupError):
_context_var.get()
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=2)
18 changes: 6 additions & 12 deletions tests/async_fixtures/test_shared_module_fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,24 @@ def test_asyncio_mark_provides_package_scoped_loop_strict_mode(pytester: Pyteste
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
__init__="",
conftest=dedent(
"""\
conftest=dedent("""\
import pytest_asyncio
@pytest_asyncio.fixture(loop_scope="module", scope="module")
async def async_shared_module_fixture():
return True
"""
),
test_module_one=dedent(
"""\
"""),
test_module_one=dedent("""\
import pytest
@pytest.mark.asyncio
async def test_shared_module_fixture_use_a(async_shared_module_fixture):
assert async_shared_module_fixture is True
"""
),
test_module_two=dedent(
"""\
"""),
test_module_two=dedent("""\
import pytest
@pytest.mark.asyncio
async def test_shared_module_fixture_use_b(async_shared_module_fixture):
assert async_shared_module_fixture is True
"""
),
"""),
)
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(passed=2)
24 changes: 6 additions & 18 deletions tests/hypothesis/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,15 @@

def test_hypothesis_given_decorator_before_asyncio_mark(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
"""\
pytester.makepyfile(dedent("""\
import pytest
from hypothesis import given, strategies as st

@given(st.integers())
@pytest.mark.asyncio
async def test_mark_inner(n):
assert isinstance(n, int)
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=strict", "-W default")
result.assert_outcomes(passed=1)

Expand All @@ -47,9 +43,7 @@ async def test_mark_and_parametrize(x, y):

def test_async_auto_marked(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
"""\
pytester.makepyfile(dedent("""\
import asyncio
import pytest
from hypothesis import given
Expand All @@ -60,19 +54,15 @@ def test_async_auto_marked(pytester: Pytester):
@given(n=st.integers())
async def test_hypothesis(n: int):
assert isinstance(n, int)
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=auto")
result.assert_outcomes(passed=1)


def test_sync_not_auto_marked(pytester: Pytester):
"""Assert that synchronous Hypothesis functions are not marked with asyncio"""
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent(
"""\
pytester.makepyfile(dedent("""\
import asyncio
import pytest
from hypothesis import given
Expand All @@ -85,8 +75,6 @@ def test_hypothesis(request, n: int):
markers = [marker.name for marker in request.node.own_markers]
assert "asyncio" not in markers
assert isinstance(n, int)
"""
)
)
"""))
result = pytester.runpytest("--asyncio-mode=auto")
result.assert_outcomes(passed=1)
Loading
Loading