From 19605d71d9b0345e659f854d3fbacf55a314bbdf Mon Sep 17 00:00:00 2001 From: Xavier Fernandez Date: Mon, 2 Sep 2024 13:22:06 +0200 Subject: [PATCH] fail-on-template-vars: modernize stack inspection code (#1129) inspect.stack() returns a list of namedtuple (or retrocompatible objects) since Python 3.5+: let's use the named attribute. cf https://docs.python.org/3/library/inspect.html#inspect.stack And once we have access to a FrameInfo object/namedtuple, access to its frame object and its f_locals member should not need to iterate on all its members: https://docs.python.org/3/reference/datamodel.html#frame-objects --- pytest_django/plugin.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index 814e530c..81455dca 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -670,13 +670,11 @@ def _get_origin() -> str | None: # Try to use topmost `self.origin` first (Django 1.9+, and with # TEMPLATE_DEBUG).. - for f in stack[2:]: - func = f[3] - if func == "render": - frame = f[0] + for frame_info in stack[2:]: + if frame_info.function == "render": origin: str | None try: - origin = frame.f_locals["self"].origin + origin = frame_info.frame.f_locals["self"].origin except (AttributeError, KeyError): origin = None if origin is not None: @@ -686,16 +684,10 @@ def _get_origin() -> str | None: # finding the ``render`` needle in the stack frameinfo = reduce( - lambda x, y: y[3] == "render" and "base.py" in y[1] and y or x, stack + lambda x, y: y if y.function == "render" and "base.py" in y.filename else x, stack ) - # assert 0, stack - frame = frameinfo[0] - # finding only the frame locals in all frame members - f_locals = reduce( - lambda x, y: y[0] == "f_locals" and y or x, inspect.getmembers(frame) - )[1] # ``django.template.base.Template`` - template = f_locals["self"] + template = frameinfo.frame.f_locals["self"] if isinstance(template, Template): name: str = template.name return name