-
Notifications
You must be signed in to change notification settings - Fork 365
Exposes the underlining TestCase instance to avoid using "asserts" module #1191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c56c818
c551601
f4d6ea9
0a6ef42
8b26d9b
3962bd5
3520685
0c796b9
c2d9f72
14ce12a
567fa23
d42d733
e705113
4917b34
90d40b2
636771b
60578dc
8ee49d0
5da273a
ccbead4
a91d2ce
1130721
91c867b
c8fccc0
b75db55
3b2e45f
26e6ebc
48b0320
8f36bd8
8f086dc
4efe1a4
48a658e
371ecfb
81aaf82
bb38422
8d627f8
9be61ec
d08d16c
c257569
49829b5
634faad
ae89ed3
b7d23e4
6855d08
1952bf9
58eddcf
6307f9a
90c8e04
abf6b31
9b36a8a
5d3452a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -44,6 +44,8 @@ | |||||||||||||||||||||||||
| "django_db_reset_sequences", | ||||||||||||||||||||||||||
| "django_db_serialized_rollback", | ||||||||||||||||||||||||||
| "django_db_setup", | ||||||||||||||||||||||||||
| "django_testcase", | ||||||||||||||||||||||||||
| "django_testcase_class", | ||||||||||||||||||||||||||
| "django_user_model", | ||||||||||||||||||||||||||
| "django_username_field", | ||||||||||||||||||||||||||
| "live_server", | ||||||||||||||||||||||||||
|
|
@@ -204,15 +206,17 @@ def django_db_setup( # noqa: PLR0917 | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| @pytest.fixture | ||||||||||||||||||||||||||
| def _django_db_helper( | ||||||||||||||||||||||||||
| def django_testcase_class( | ||||||||||||||||||||||||||
| request: pytest.FixtureRequest, | ||||||||||||||||||||||||||
| django_db_setup: None, # noqa: ARG001 | ||||||||||||||||||||||||||
| django_db_blocker: DjangoDbBlocker, | ||||||||||||||||||||||||||
| ) -> Generator[None]: | ||||||||||||||||||||||||||
| if is_django_unittest(request): | ||||||||||||||||||||||||||
| yield | ||||||||||||||||||||||||||
| yield None | ||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| import django.test | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| marker = request.node.get_closest_marker("django_db") | ||||||||||||||||||||||||||
| if marker: | ||||||||||||||||||||||||||
| ( | ||||||||||||||||||||||||||
|
|
@@ -241,9 +245,63 @@ def _django_db_helper( | |||||||||||||||||||||||||
| "django_db_serialized_rollback" in request.fixturenames | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if transactional: | ||||||||||||||||||||||||||
| test_case_class = django.test.TransactionTestCase | ||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||
| test_case_class = django.test.TestCase | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| _reset_sequences = reset_sequences | ||||||||||||||||||||||||||
| _serialized_rollback = serialized_rollback | ||||||||||||||||||||||||||
| _databases = databases | ||||||||||||||||||||||||||
| _available_apps = available_apps | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| class PytestDjangoTestCase(test_case_class): # type: ignore[misc,valid-type] | ||||||||||||||||||||||||||
| reset_sequences = _reset_sequences | ||||||||||||||||||||||||||
| serialized_rollback = _serialized_rollback | ||||||||||||||||||||||||||
| if _databases is not None: | ||||||||||||||||||||||||||
| databases = _databases | ||||||||||||||||||||||||||
| if _available_apps is not None: | ||||||||||||||||||||||||||
| available_apps = _available_apps | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # For non-transactional tests, skip executing `django.test.TestCase`'s | ||||||||||||||||||||||||||
| # `setUpClass`/`tearDownClass`, only execute the super class ones. | ||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||
| # `TestCase`'s class setup manages the `setUpTestData`/class-level | ||||||||||||||||||||||||||
| # transaction functionality. We don't use it; instead we (will) offer | ||||||||||||||||||||||||||
| # our own alternatives. So it only adds overhead, and does some things | ||||||||||||||||||||||||||
| # which conflict with our (planned) functionality, particularly, it | ||||||||||||||||||||||||||
| # closes all database connections in `tearDownClass` which inhibits | ||||||||||||||||||||||||||
| # wrapping tests in higher-scoped transactions. | ||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||
| # It's possible a new version of Django will add some unrelated | ||||||||||||||||||||||||||
| # functionality to these methods, in which case skipping them completely | ||||||||||||||||||||||||||
| # would not be desirable. Let's cross that bridge when we get there... | ||||||||||||||||||||||||||
| if not transactional: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| @classmethod | ||||||||||||||||||||||||||
| def setUpClass(cls) -> None: | ||||||||||||||||||||||||||
| super(django.test.TestCase, cls).setUpClass() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| @classmethod | ||||||||||||||||||||||||||
| def tearDownClass(cls) -> None: | ||||||||||||||||||||||||||
| super(django.test.TestCase, cls).tearDownClass() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| yield PytestDjangoTestCase | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| @pytest.fixture | ||||||||||||||||||||||||||
| def _django_db_helper( | ||||||||||||||||||||||||||
| request: pytest.FixtureRequest, | ||||||||||||||||||||||||||
| django_db_setup: None, # noqa: ARG001 | ||||||||||||||||||||||||||
| django_db_blocker: DjangoDbBlocker, | ||||||||||||||||||||||||||
| django_testcase_class: type[django.test.TestCase], | ||||||||||||||||||||||||||
| ) -> Generator[None, None, None]: | ||||||||||||||||||||||||||
| if is_django_unittest(request): | ||||||||||||||||||||||||||
| yield | ||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
Comment on lines
+297
to
+302
|
||||||||||||||||||||||||||
| django_testcase_class: type[django.test.TestCase], | |
| ) -> Generator[None, None, None]: | |
| if is_django_unittest(request): | |
| yield | |
| return | |
| django_testcase_class: type[django.test.TestCase] | None, | |
| ) -> Generator[None, None, None]: | |
| if is_django_unittest(request): | |
| yield | |
| return | |
| assert django_testcase_class is not None |
Copilot
AI
Feb 19, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_django_db_helper is annotated as Generator[None, None, None] but it now yields test_case (a TestCase/TransactionTestCase instance). Update the generator yield type (and any dependent fixture parameter annotations) so the typing matches the runtime behavior.
Copilot
AI
Feb 19, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
db (and similar fixtures) annotate _django_db_helper as None, but _django_db_helper now yields a TestCase instance. Even if unused, this annotation is now incorrect and will confuse type checkers; update it to the actual yielded type (or a common base/Protocol) for consistency.
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,8 +8,11 @@ | |||||||||||||
| from collections.abc import Sequence | ||||||||||||||
| from typing import cast | ||||||||||||||
|
|
||||||||||||||
| import django.test | ||||||||||||||
| import pytest | ||||||||||||||
|
|
||||||||||||||
| from .helpers import DjangoPytester | ||||||||||||||
|
|
||||||||||||||
| import pytest_django | ||||||||||||||
| from pytest_django.asserts import __all__ as asserts_all | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -73,3 +76,61 @@ def test_sanity() -> None: | |||||||||||||
| pass | ||||||||||||||
|
|
||||||||||||||
| assert assertContains.__doc__ | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| def test_fixture_assert(djt: django.test.TestCase) -> None: | ||||||||||||||
| djt.assertEqual("a", "a") # noqa: PT009 | ||||||||||||||
|
|
||||||||||||||
| with pytest.raises(AssertionError): | ||||||||||||||
| djt.assertXMLEqual("a" * 10_000, "a") | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
|
Comment on lines
+84
to
+87
|
||||||||||||||
| with pytest.raises(AssertionError): | |
| djt.assertXMLEqual("a" * 10_000, "a") | |
| djt.maxDiff = None | |
| with pytest.raises(AssertionError) as excinfo: | |
| djt.assertXMLEqual("a" * 10_000, "a") | |
| assert "a" * 10_000 in str(excinfo.value) |
Uh oh!
There was an error while loading. Please reload this page.