Skip to content

Commit 63a1d57

Browse files
committed
made some fixtures yield, and restructured django_db_blocker fixture
1 parent debecc8 commit 63a1d57

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

Diff for: pytest_django/fixtures.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def django_db_createdb(request):
8484
def django_db_setup(
8585
request,
8686
django_test_environment,
87-
django_db_blocker,
87+
_django_db_blocker,
8888
django_db_use_migrations,
8989
django_db_keepdb,
9090
django_db_createdb,
@@ -101,15 +101,16 @@ def django_db_setup(
101101
if django_db_keepdb and not django_db_createdb:
102102
setup_databases_args["keepdb"] = True
103103

104-
with django_db_blocker.unblock():
104+
with _django_db_blocker.unblock():
105105
db_cfg = setup_databases(
106106
verbosity=request.config.option.verbose,
107107
interactive=False,
108108
**setup_databases_args
109109
)
110110

111-
def teardown_database():
112-
with django_db_blocker.unblock():
111+
yield
112+
if not django_db_keepdb:
113+
with _django_db_blocker.unblock():
113114
try:
114115
teardown_databases(db_cfg, verbosity=request.config.option.verbose)
115116
except Exception as exc:
@@ -119,9 +120,6 @@ def teardown_database():
119120
)
120121
)
121122

122-
if not django_db_keepdb:
123-
request.addfinalizer(teardown_database)
124-
125123

126124
def _django_db_fixture_helper(
127125
request, django_db_blocker, transactional=False, reset_sequences=False
@@ -191,7 +189,7 @@ def _set_suffix_to_test_databases(suffix):
191189

192190

193191
@pytest.fixture(scope="function")
194-
def db(request, django_db_setup, django_db_blocker):
192+
def db(request, django_db_blocker):
195193
"""Require a django test database.
196194
197195
This database will be setup with the default fixtures and will have
@@ -429,13 +427,15 @@ def _live_server_helper(request):
429427
It will also override settings only for the duration of the test.
430428
"""
431429
if "live_server" not in request.fixturenames:
430+
yield
432431
return
433432

434433
request.getfixturevalue("transactional_db")
435434

436435
live_server = request.getfixturevalue("live_server")
437436
live_server._live_server_modified_settings.enable()
438-
request.addfinalizer(live_server._live_server_modified_settings.disable)
437+
yield
438+
live_server._live_server_modified_settings.disable()
439439

440440

441441
@contextmanager

Diff for: pytest_django/plugin.py

+26-4
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ def django_test_environment(request):
462462

463463

464464
@pytest.fixture(scope="session")
465-
def django_db_blocker():
465+
def _django_db_blocker():
466466
"""Wrapper around Django's database access.
467467
468468
This object can be used to re-enable database access. This fixture is used
@@ -481,6 +481,28 @@ def django_db_blocker():
481481
return _blocking_manager
482482

483483

484+
@pytest.fixture(scope="session")
485+
def django_db_blocker(django_db_setup, _django_db_blocker):
486+
"""Wrapper around _django_db_blocker to serve as convenience reference.
487+
488+
The ``_django_db_blocker`` fixture must be available for the ``django_db_setup``
489+
fixture, so ``django_db_setup`` must request the ``_django_db_blocker`` fixture. But
490+
in order for ``_django_db_blocker`` to be used, ``django_db_setup`` must also have
491+
been executed, suggesting that ``_django_db_blocker`` should request
492+
``django_db_setup``, especially since it is possible for ``_django_db_blocker`` to
493+
be needed when ``django_db_setup`` wouldn't normally have been run (e.g. if a test
494+
isn't marked with ``pytest.mark.django_db``).
495+
496+
This would normally cause a catch-22, but to circumvent this, the
497+
`_django_db_blocker`` fixture is used behind the scenes, while ``django_db_blocker``
498+
serves as the fixture used by everything that would normally need the blocker (aside
499+
from ``django_db_setup``). This fixture helps coordinate between both
500+
``django_db_setup`` and ``_django_db_blocker``, so that whenever
501+
``django_db_blocker`` gets used, it ensures ``django_db_setup`` is run first.
502+
"""
503+
return _django_db_blocker
504+
505+
484506
@pytest.fixture(autouse=True)
485507
def _django_db_marker(request):
486508
"""Implement the django_db marker, internal to pytest-django.
@@ -500,7 +522,7 @@ def _django_db_marker(request):
500522

501523

502524
@pytest.fixture(autouse=True, scope="class")
503-
def _django_setup_unittest(request, django_db_blocker):
525+
def _django_setup_unittest(request, _django_db_blocker):
504526
"""Setup a django unittest, internal to pytest-django."""
505527
if not django_settings_is_configured() or not is_django_unittest(request):
506528
yield
@@ -525,7 +547,7 @@ def non_debugging_runtest(self):
525547

526548
cls = request.node.cls
527549

528-
with django_db_blocker.unblock():
550+
with _django_db_blocker.unblock():
529551
if _handle_unittest_methods:
530552
_restore_class_methods(cls)
531553
cls.setUpClass()
@@ -736,7 +758,7 @@ def __exit__(self, exc_type, exc_value, traceback):
736758
class _DatabaseBlocker(object):
737759
"""Manager for django.db.backends.base.base.BaseDatabaseWrapper.
738760
739-
This is the object returned by django_db_blocker.
761+
This is the object returned by _django_db_blocker and django_db_blocker.
740762
"""
741763

742764
def __init__(self):

Diff for: tests/test_db_access_in_repr.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ def test_db_access_with_repr_in_report(django_testdir):
55
66
from .app.models import Item
77
8-
def test_via_db_blocker(django_db_setup, django_db_blocker):
8+
def test_via_db_blocker(django_db_blocker):
99
with django_db_blocker.unblock():
1010
Item.objects.get(name='This one is not there')
1111

Diff for: tests/test_fixtures.py

-2
Original file line numberDiff line numberDiff line change
@@ -617,15 +617,13 @@ def test_block_with_block(self, django_db_blocker):
617617
with pytest.raises(RuntimeError):
618618
Item.objects.exists()
619619

620-
@pytest.mark.django_db
621620
def test_unblock_manually(self, django_db_blocker):
622621
try:
623622
django_db_blocker.unblock()
624623
Item.objects.exists()
625624
finally:
626625
django_db_blocker.restore()
627626

628-
@pytest.mark.django_db
629627
def test_unblock_with_block(self, django_db_blocker):
630628
with django_db_blocker.unblock():
631629
Item.objects.exists()

0 commit comments

Comments
 (0)