1
0
mirror of https://github.com/django/django.git synced 2024-12-22 09:05:43 +00:00

Fixed #35667 -- Improved deprecation warning handling by replacing stacklevel with skip_file_prefixes.

Signed-off-by: saJaeHyukc <wogur981208@gmail.com>
This commit is contained in:
saJaeHyukc 2024-10-16 20:06:59 +09:00
parent 9ca1f6eff6
commit b698b0de37
3 changed files with 70 additions and 3 deletions

View File

@ -1,8 +1,12 @@
import inspect
import os
import warnings
from asgiref.sync import iscoroutinefunction, markcoroutinefunction, sync_to_async
import django
from django.utils.version import PY312
class RemovedInDjango60Warning(DeprecationWarning):
pass
@ -140,3 +144,25 @@ class MiddlewareMixin:
thread_sensitive=True,
)(request, response)
return response
def adjust_stacklevel_for_warning(skip_file_prefixes):
def _get_non_django_stacklevel():
django_path = os.path.dirname(django.__file__)
stacklevel = 1
# Exclude current and nested function frames with [2:].
for frame_info in inspect.stack()[2:]:
filename = os.path.abspath(frame_info.filename)
if not filename.startswith(django_path):
return stacklevel
stacklevel += 1
return 1
if PY312:
return {
"skip_file_prefixes": (
os.path.normpath(os.path.dirname(skip_file_prefixes)),
)
}
else:
return {"stacklevel": _get_non_django_stacklevel()}

View File

@ -114,7 +114,7 @@ requirements:
feature, the change should also contain documentation.
When you think your work is ready to be reviewed, send :doc:`a GitHub pull
request <working-with-git>`.
request <working-with-git>`.
If you can't send a pull request for some reason, you can also use patches in
Trac. When using this style, follow these guidelines.
@ -221,7 +221,10 @@ previous behavior, or standalone items that are unnecessary or unused when the
deprecation ends. For example::
import warnings
from django.utils.deprecation import RemovedInDjangoXXWarning
from django.utils.deprecation import (
RemovedInDjangoXXWarning,
adjust_stacklevel_for_warning,
)
# RemovedInDjangoXXWarning.
@ -234,7 +237,7 @@ deprecation ends. For example::
warnings.warn(
"foo() is deprecated.",
category=RemovedInDjangoXXWarning,
stacklevel=2,
**adjust_stacklevel_for_warning(__file__),
)
old_private_helper()
...

View File

@ -1,5 +1,9 @@
import importlib.util
import os
import warnings
from pathlib import Path
import django
from django.test import SimpleTestCase
from django.utils.deprecation import RemovedAfterNextVersionWarning, RenameMethodsBase
@ -178,3 +182,37 @@ class RenameMethodsTests(SimpleTestCase):
self.assertTrue(
issubclass(RemovedAfterNextVersionWarning, PendingDeprecationWarning)
)
class AdjustStacklevelForWarningTests(SimpleTestCase):
def test_warning_in_django_code(self):
self.django_path = Path(os.path.dirname(django.__file__))
self.temp_file_path = self.django_path / "temp_adjust_stacklevel_for_warning.py"
file_content = """
import warnings
from django.utils.deprecation import adjust_stacklevel_for_warning
def django_function():
warnings.warn(
"This is a test warning from Django code.",
DeprecationWarning,
**adjust_stacklevel_for_warning(__file__),
)
"""
self.temp_file_path.write_text(file_content)
module_name = "temp_adjust_stacklevel_for_warning"
spec = importlib.util.spec_from_file_location(
module_name, str(self.temp_file_path)
)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
msg = "This is a test warning from Django code."
with self.assertWarnsMessage(DeprecationWarning, msg) as ctx:
module.django_function()
self.assertEqual(ctx.filename, __file__)
self.temp_file_path.unlink()