Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-03-28 09:04:19 +0300
committerCampbell Barton <campbell@blender.org>2022-03-28 09:06:38 +0300
commit1466f480c4ea894c2f0b23663fcdba644cceb3f8 (patch)
treed50be1db2281f9f8655b21e67b75b8b80219ee49 /source/blender/python/intern
parent0ce6ed47533f715a72b139cb47a4f2dfb5a0bb39 (diff)
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.
Diffstat (limited to 'source/blender/python/intern')
-rw-r--r--source/blender/python/intern/bpy_interface_run.c12
-rw-r--r--source/blender/python/intern/bpy_traceback.c72
-rw-r--r--source/blender/python/intern/bpy_traceback.h3
3 files changed, 74 insertions, 13 deletions
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
}