From 4f2ae0644de34791b84b7beb11a966ce4bc48fb6 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Sun, 24 Sep 2023 19:02:50 +1000 Subject: [PATCH] Fixed #34849 -- Avoided raising RuntimeWarning about import-time queries when apps are reinitialized with test tools. Regression in fbd16438f46bc2128926958ad24331da5d1b406f. --- django/db/backends/utils.py | 12 +++++++++--- tests/apps/tests.py | 8 ++++---- tests/postgres_tests/test_apps.py | 12 +++++++++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/django/db/backends/utils.py b/django/db/backends/utils.py index 0aa94cc30b..f363253ca3 100644 --- a/django/db/backends/utils.py +++ b/django/db/backends/utils.py @@ -61,7 +61,9 @@ class CursorWrapper: "Keyword parameters for callproc are not supported on this " "database backend." ) - if not apps.ready: + # Raise a warning during app initialization (stored_app_configs is only + # ever set during testing). + if not apps.ready and not apps.stored_app_configs: warnings.warn(self.APPS_NOT_READY_WARNING_MSG, category=RuntimeWarning) self.db.validate_no_broken_transaction() with self.db.wrap_database_errors: @@ -90,7 +92,9 @@ class CursorWrapper: return executor(sql, params, many, context) def _execute(self, sql, params, *ignored_wrapper_args): - if not apps.ready: + # Raise a warning during app initialization (stored_app_configs is only + # ever set during testing). + if not apps.ready and not apps.stored_app_configs: warnings.warn(self.APPS_NOT_READY_WARNING_MSG, category=RuntimeWarning) self.db.validate_no_broken_transaction() with self.db.wrap_database_errors: @@ -101,7 +105,9 @@ class CursorWrapper: return self.cursor.execute(sql, params) def _executemany(self, sql, param_list, *ignored_wrapper_args): - if not apps.ready: + # Raise a warning during app initialization (stored_app_configs is only + # ever set during testing). + if not apps.ready and not apps.stored_app_configs: warnings.warn(self.APPS_NOT_READY_WARNING_MSG, category=RuntimeWarning) self.db.validate_no_broken_transaction() with self.db.wrap_database_errors: diff --git a/tests/apps/tests.py b/tests/apps/tests.py index e443e37dc5..fba9c43a34 100644 --- a/tests/apps/tests.py +++ b/tests/apps/tests.py @@ -607,10 +607,9 @@ class QueryPerformingAppTests(TransactionTestCase): custom_settings = override_settings( INSTALLED_APPS=[f"apps.query_performing_app.apps.{app_config_name}"] ) - # Ignore the RuntimeWarning, as override_settings.enable() calls - # AppConfig.ready() which will trigger the warning. - with self.assertWarnsMessage(RuntimeWarning, self.expected_msg): - custom_settings.enable() + custom_settings.enable() + old_stored_app_configs = apps.stored_app_configs + apps.stored_app_configs = [] try: with patch.multiple(apps, ready=False, loading=False, app_configs={}): with self.assertWarnsMessage(RuntimeWarning, self.expected_msg): @@ -619,4 +618,5 @@ class QueryPerformingAppTests(TransactionTestCase): app_config = apps.get_app_config("query_performing_app") return app_config.query_results finally: + setattr(apps, "stored_app_configs", old_stored_app_configs) custom_settings.disable() diff --git a/tests/postgres_tests/test_apps.py b/tests/postgres_tests/test_apps.py index 3fdd7c3faf..ea2a28d7a8 100644 --- a/tests/postgres_tests/test_apps.py +++ b/tests/postgres_tests/test_apps.py @@ -5,7 +5,7 @@ from django.db import connection from django.db.backends.signals import connection_created from django.db.migrations.writer import MigrationWriter from django.test import TestCase -from django.test.utils import modify_settings +from django.test.utils import CaptureQueriesContext, modify_settings, override_settings try: from django.contrib.postgres.fields import ( @@ -14,6 +14,7 @@ try: DecimalRangeField, IntegerRangeField, ) + from django.contrib.postgres.signals import get_hstore_oids from django.db.backends.postgresql.psycopg_any import ( DateRange, DateTimeRange, @@ -27,6 +28,15 @@ except ImportError: @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific tests") class PostgresConfigTests(TestCase): + def test_install_app_no_warning(self): + # Clear cache to force queries when (re)initializing the + # "django.contrib.postgres" app. + get_hstore_oids.cache_clear() + with CaptureQueriesContext(connection) as captured_queries: + with override_settings(INSTALLED_APPS=["django.contrib.postgres"]): + pass + self.assertGreaterEqual(len(captured_queries), 1) + def test_register_type_handlers_connection(self): from django.contrib.postgres.signals import register_type_handlers