From 52ed2b645e1dd8c9a874cfd21c4c9f2500032626 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Fri, 9 Aug 2024 13:41:18 -0400 Subject: [PATCH] Refs #35060 -- Adjusted deprecation warning stacklevel in Model.save()/asave(). --- django/db/models/base.py | 2 +- docs/releases/5.1.1.txt | 4 ++++ tests/basic/tests.py | 6 ++++-- tests/update_only_fields/tests.py | 6 ++++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/django/db/models/base.py b/django/db/models/base.py index a89ceafbef..4a051f8215 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -788,7 +788,7 @@ class Model(AltersData, metaclass=ModelBase): warnings.warn( f"Passing positional arguments to {method_name}() is deprecated", RemovedInDjango60Warning, - stacklevel=2, + stacklevel=3, ) total_len_args = len(args) + 1 # include self max_len_args = len(defaults) + 1 diff --git a/docs/releases/5.1.1.txt b/docs/releases/5.1.1.txt index b8c2993933..84a61efec5 100644 --- a/docs/releases/5.1.1.txt +++ b/docs/releases/5.1.1.txt @@ -19,3 +19,7 @@ Bugfixes children). A new :class:`~django.contrib.auth.forms.AdminUserCreationForm` including this field was added, isolating the feature to the admin where it was intended (:ticket:`35678`). + +* Adjusted the deprecation warning ``stacklevel`` in :meth:`.Model.save` and + :meth:`.Model.asave` to correctly point to the offending call site + (:ticket:`35060`). diff --git a/tests/basic/tests.py b/tests/basic/tests.py index 6fb67f7e6e..6d34a95805 100644 --- a/tests/basic/tests.py +++ b/tests/basic/tests.py @@ -206,9 +206,10 @@ class ModelInstanceCreationTests(TestCase): def test_save_deprecation(self): a = Article(headline="original", pub_date=datetime(2014, 5, 16)) msg = "Passing positional arguments to save() is deprecated" - with self.assertWarnsMessage(RemovedInDjango60Warning, msg): + with self.assertWarnsMessage(RemovedInDjango60Warning, msg) as ctx: a.save(False, False, None, None) self.assertEqual(Article.objects.count(), 1) + self.assertEqual(ctx.filename, __file__) def test_save_deprecation_positional_arguments_used(self): a = Article() @@ -259,9 +260,10 @@ class ModelInstanceCreationTests(TestCase): async def test_asave_deprecation(self): a = Article(headline="original", pub_date=datetime(2014, 5, 16)) msg = "Passing positional arguments to asave() is deprecated" - with self.assertWarnsMessage(RemovedInDjango60Warning, msg): + with self.assertWarnsMessage(RemovedInDjango60Warning, msg) as ctx: await a.asave(False, False, None, None) self.assertEqual(await Article.objects.acount(), 1) + self.assertEqual(ctx.filename, __file__) async def test_asave_deprecation_positional_arguments_used(self): a = Article() diff --git a/tests/update_only_fields/tests.py b/tests/update_only_fields/tests.py index 816112bc33..a6a5b7cb8e 100644 --- a/tests/update_only_fields/tests.py +++ b/tests/update_only_fields/tests.py @@ -262,10 +262,11 @@ class UpdateOnlyFieldsTests(TestCase): msg = "Passing positional arguments to save() is deprecated" with ( - self.assertWarnsMessage(RemovedInDjango60Warning, msg), + self.assertWarnsMessage(RemovedInDjango60Warning, msg) as ctx, self.assertNumQueries(0), ): s.save(False, False, None, []) + self.assertEqual(ctx.filename, __file__) async def test_empty_update_fields_positional_asave(self): s = await Person.objects.acreate(name="Sara", gender="F") @@ -273,8 +274,9 @@ class UpdateOnlyFieldsTests(TestCase): s.name = "Other" msg = "Passing positional arguments to asave() is deprecated" - with self.assertWarnsMessage(RemovedInDjango60Warning, msg): + with self.assertWarnsMessage(RemovedInDjango60Warning, msg) as ctx: await s.asave(False, False, None, []) + self.assertEqual(ctx.filename, __file__) # No save occurred for an empty update_fields. await s.arefresh_from_db()