]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
simplify CodeType rewriting 1536/head
authorDavid Lord <davidism@gmail.com>
Tue, 9 Nov 2021 15:10:53 +0000 (07:10 -0800)
committerDavid Lord <davidism@gmail.com>
Tue, 9 Nov 2021 15:10:53 +0000 (07:10 -0800)
CHANGES.rst
src/jinja2/debug.py

index 0ce916df497fd2605dd3ceef81839c07a2c19e02..de9bd455819bdde20672eb3e5dd879a6f67182a9 100644 (file)
@@ -1,5 +1,14 @@
 .. currentmodule:: jinja2
 
+Version 3.0.3
+-------------
+
+Unreleased
+
+-   Fix traceback rewriting internals for Python 3.10 and 3.11.
+    :issue:`1535`
+
+
 Version 3.0.2
 -------------
 
index 02de4ee71b36035c8c4055b00ff36ad6dd2e43d5..805866bd6f9b04dcde0c36a7e72739f5b3759dd0 100644 (file)
@@ -102,62 +102,42 @@ def fake_traceback(  # type: ignore
         "__jinja_exception__": exc_value,
     }
     # Raise an exception at the correct line number.
-    code = compile("\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec")
+    code: CodeType = compile(
+        "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec"
+    )
 
     # Build a new code object that points to the template file and
     # replaces the location with a block name.
-    try:
-        location = "template"
-
-        if tb is not None:
-            function = tb.tb_frame.f_code.co_name
-
-            if function == "root":
-                location = "top-level template code"
-            elif function.startswith("block_"):
-                location = f"block {function[6:]!r}"
-
-        # Collect arguments for the new code object. CodeType only
-        # accepts positional arguments, and arguments were inserted in
-        # new Python versions.
-        code_args = []
-
-        for attr in (
-            "argcount",
-            "posonlyargcount",  # Python 3.8
-            "kwonlyargcount",
-            "nlocals",
-            "stacksize",
-            "flags",
-            "code",  # codestring
-            "consts",  # constants
-            "names",
-            "varnames",
-            ("filename", filename),
-            ("name", location),
-            "firstlineno",
-            "lnotab",
-            "freevars",
-            "cellvars",
-            "linetable",  # Python 3.10
-        ):
-            if isinstance(attr, tuple):
-                # Replace with given value.
-                code_args.append(attr[1])
-                continue
-
-            try:
-                # Copy original value if it exists.
-                code_args.append(getattr(code, "co_" + t.cast(str, attr)))
-            except AttributeError:
-                # Some arguments were added later.
-                continue
-
-        code = CodeType(*code_args)
-    except Exception:
-        # Some environments such as Google App Engine don't support
-        # modifying code objects.
-        pass
+    location = "template"
+
+    if tb is not None:
+        function = tb.tb_frame.f_code.co_name
+
+        if function == "root":
+            location = "top-level template code"
+        elif function.startswith("block_"):
+            location = f"block {function[6:]!r}"
+
+    if sys.version_info >= (3, 8):
+        code = code.replace(co_name=location)
+    else:
+        code = CodeType(
+            code.co_argcount,
+            code.co_kwonlyargcount,
+            code.co_nlocals,
+            code.co_stacksize,
+            code.co_flags,
+            code.co_code,
+            code.co_consts,
+            code.co_names,
+            code.co_varnames,
+            code.co_filename,
+            location,
+            code.co_firstlineno,
+            code.co_lnotab,
+            code.co_freevars,
+            code.co_cellvars,
+        )
 
     # Execute the new code, which is guaranteed to raise, and return
     # the new traceback without this frame.