[Bf-blender-cvs] [1466f480c4e] master: Python: select the start-end range of syntax errors

Campbell Barton noreply at git.blender.org
Mon Mar 28 08:08:15 CEST 2022


Commit: 1466f480c4ea894c2f0b23663fcdba644cceb3f8
Author: Campbell Barton
Date:   Mon Mar 28 17:04:19 2022 +1100
Branches: master
https://developer.blender.org/rB1466f480c4ea894c2f0b23663fcdba644cceb3f8

Python: select the start-end range of syntax errors

Python 3.10's syntax errors can specify a range.
Use this for text editor error selection.

===================================================================

M	source/blender/python/intern/bpy_interface_run.c
M	source/blender/python/intern/bpy_traceback.c
M	source/blender/python/intern/bpy_traceback.h

===================================================================

diff --git a/source/blender/python/intern/bpy_interface_run.c b/source/blender/python/intern/bpy_interface_run.c
index 14d03bf7e2b..8f7437ac1da 100644
--- a/source/blender/python/intern/bpy_interface_run.c
+++ b/source/blender/python/intern/bpy_interface_run.c
@@ -37,12 +37,14 @@
 
 static void python_script_error_jump_text(Text *text, const char *filepath)
 {
-  int lineno;
-  int offset;
-  python_script_error_jump(filepath, &lineno, &offset);
+  int lineno, lineno_end;
+  int offset, offset_end;
+  python_script_error_jump(filepath, &lineno, &offset, &lineno_end, &offset_end);
   if (lineno != -1) {
-    /* select the line with the error */
-    txt_move_to(text, lineno - 1, INT_MAX, false);
+    /* Start at the end so cursor motion that looses the selection,
+     * leaves the cursor from the most useful place.
+     * Also, the end can't always be set, so don't give it priority. */
+    txt_move_to(text, lineno_end - 1, offset_end, false);
     txt_move_to(text, lineno - 1, offset, true);
   }
 }
diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c
index 87e6375c7d1..6813496be83 100644
--- a/source/blender/python/intern/bpy_traceback.c
+++ b/source/blender/python/intern/bpy_traceback.c
@@ -24,7 +24,7 @@ static const char *traceback_filepath(PyTracebackObject *tb, PyObject **coerce)
   return PyBytes_AS_STRING(*coerce);
 }
 
-/* copied from pythonrun.c, 3.4.0 */
+/* copied from pythonrun.c, 3.10.0 */
 _Py_static_string(PyId_string, "<string>");
 
 static int parse_syntax_error(PyObject *err,
@@ -32,14 +32,18 @@ static int parse_syntax_error(PyObject *err,
                               PyObject **filename,
                               int *lineno,
                               int *offset,
+                              int *end_lineno,
+                              int *end_offset,
                               PyObject **text)
 {
-  long hold;
+  Py_ssize_t hold;
   PyObject *v;
   _Py_IDENTIFIER(msg);
   _Py_IDENTIFIER(filename);
   _Py_IDENTIFIER(lineno);
   _Py_IDENTIFIER(offset);
+  _Py_IDENTIFIER(end_lineno);
+  _Py_IDENTIFIER(end_offset);
   _Py_IDENTIFIER(text);
 
   *message = NULL;
@@ -71,7 +75,7 @@ static int parse_syntax_error(PyObject *err,
   if (!v) {
     goto finally;
   }
-  hold = PyLong_AsLong(v);
+  hold = PyLong_AsSsize_t(v);
   Py_DECREF(v);
   if (hold < 0 && PyErr_Occurred()) {
     goto finally;
@@ -87,7 +91,7 @@ static int parse_syntax_error(PyObject *err,
     Py_DECREF(v);
   }
   else {
-    hold = PyLong_AsLong(v);
+    hold = PyLong_AsSsize_t(v);
     Py_DECREF(v);
     if (hold < 0 && PyErr_Occurred()) {
       goto finally;
@@ -95,6 +99,49 @@ static int parse_syntax_error(PyObject *err,
     *offset = (int)hold;
   }
 
+  if (Py_TYPE(err) == (PyTypeObject *)PyExc_SyntaxError) {
+    v = _PyObject_GetAttrId(err, &PyId_end_lineno);
+    if (!v) {
+      PyErr_Clear();
+      *end_lineno = *lineno;
+    }
+    else if (v == Py_None) {
+      *end_lineno = *lineno;
+      Py_DECREF(v);
+    }
+    else {
+      hold = PyLong_AsSsize_t(v);
+      Py_DECREF(v);
+      if (hold < 0 && PyErr_Occurred()) {
+        goto finally;
+      }
+      *end_lineno = hold;
+    }
+
+    v = _PyObject_GetAttrId(err, &PyId_end_offset);
+    if (!v) {
+      PyErr_Clear();
+      *end_offset = -1;
+    }
+    else if (v == Py_None) {
+      *end_offset = -1;
+      Py_DECREF(v);
+    }
+    else {
+      hold = PyLong_AsSsize_t(v);
+      Py_DECREF(v);
+      if (hold < 0 && PyErr_Occurred()) {
+        goto finally;
+      }
+      *end_offset = hold;
+    }
+  }
+  else {
+    /* `SyntaxError` subclasses. */
+    *end_lineno = *lineno;
+    *end_offset = -1;
+  }
+
   v = _PyObject_GetAttrId(err, &PyId_text);
   if (!v) {
     goto finally;
@@ -115,7 +162,8 @@ finally:
 }
 /* end copied function! */
 
-void python_script_error_jump(const char *filepath, int *r_lineno, int *r_offset)
+void python_script_error_jump(
+    const char *filepath, int *r_lineno, int *r_offset, int *r_lineno_end, int *r_offset_end)
 {
   PyObject *exception, *value;
   PyTracebackObject *tb;
@@ -123,6 +171,9 @@ void python_script_error_jump(const char *filepath, int *r_lineno, int *r_offset
   *r_lineno = -1;
   *r_offset = 0;
 
+  *r_lineno_end = -1;
+  *r_offset_end = 0;
+
   PyErr_Fetch(&exception, &value, (PyObject **)&tb);
   if (exception == NULL) {
     return;
@@ -137,7 +188,14 @@ void python_script_error_jump(const char *filepath, int *r_lineno, int *r_offset
       PyObject *message;
       PyObject *filepath_exc_py, *text_py;
 
-      if (parse_syntax_error(value, &message, &filepath_exc_py, r_lineno, r_offset, &text_py)) {
+      if (parse_syntax_error(value,
+                             &message,
+                             &filepath_exc_py,
+                             r_lineno,
+                             r_offset,
+                             r_lineno_end,
+                             r_offset_end,
+                             &text_py)) {
         const char *filepath_exc = PyUnicode_AsUTF8(filepath_exc_py);
         /* python adds a '/', prefix, so check for both */
         if ((BLI_path_cmp(filepath_exc, filepath) == 0) ||
@@ -170,7 +228,7 @@ void python_script_error_jump(const char *filepath, int *r_lineno, int *r_offset
       Py_DECREF(coerce);
 
       if (match) {
-        *r_lineno = tb->tb_lineno;
+        *r_lineno = *r_lineno_end = tb->tb_lineno;
         /* used to break here, but better find the inner most line */
       }
     }
diff --git a/source/blender/python/intern/bpy_traceback.h b/source/blender/python/intern/bpy_traceback.h
index c96f8751989..2ebdab527e8 100644
--- a/source/blender/python/intern/bpy_traceback.h
+++ b/source/blender/python/intern/bpy_traceback.h
@@ -10,7 +10,8 @@
 extern "C" {
 #endif
 
-void python_script_error_jump(const char *filepath, int *r_lineno, int *r_offset);
+void python_script_error_jump(
+    const char *filepath, int *r_lineno, int *r_offset, int *r_lineno_end, int *r_offset_end);
 
 #ifdef __cplusplus
 }



More information about the Bf-blender-cvs mailing list