updated for version 7.4a.027
Problem:    When Python adds lines to another buffer the cursor position is
            wrong, it might be below the last line causing ml_get errors.
            (Vlad Irnov)
Solution:   Temporarily change the current window, so that marks are corrected
            properly.
diff --git a/src/if_py_both.h b/src/if_py_both.h
index 48b7be7..4ac2ebf 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -3997,30 +3997,43 @@
     static int
 InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
 {
+    buf_T	*save_curbuf = NULL;
+    win_T	*wp;
+    win_T	*save_curwin = NULL;
+    tabpage_T	*tp;
+    tabpage_T	*save_curtab = NULL;
+
     /* First of all, we check the type of the supplied Python object.
      * It must be a string or a list, or the call is in error.
      */
     if (PyBytes_Check(lines) || PyUnicode_Check(lines))
     {
-	char	*str = StringToLine(lines);
-	buf_T	*savebuf;
+	char		*str = StringToLine(lines);
 
 	if (str == NULL)
 	    return FAIL;
 
 	PyErr_Clear();
 	VimTryStart();
-	switch_buffer(&savebuf, buf);
+	if (find_win_for_buf(buf, &wp, &tp) == FAIL
+		|| switch_win(&save_curwin, &save_curtab, wp, tp, TRUE)
+								      == FAIL)
+	    switch_buffer(&save_curbuf, buf);
 
-	if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
+	if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
 	    RAISE_UNDO_FAIL;
 	else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
 	    RAISE_INSERT_LINE_FAIL;
-	else
+	else if (save_curbuf == NULL)
+	    /* Only adjust marks if we managed to switch to a window that
+	     * holds the buffer, otherwise line numbers will be invalid. */
 	    appended_lines_mark((linenr_T)n, 1L);
 
 	vim_free(str);
-	restore_buffer(savebuf);
+	if (save_curbuf == NULL)
+	    restore_win(save_curwin, save_curtab, TRUE);
+	else
+	    restore_buffer(save_curbuf);
 	update_screen(VALID);
 
 	if (VimTryEnd())
@@ -4036,7 +4049,6 @@
 	PyInt	i;
 	PyInt	size = PyList_Size(lines);
 	char	**array;
-	buf_T	*savebuf;
 
 	array = PyMem_New(char *, size);
 	if (array == NULL)
@@ -4061,7 +4073,10 @@
 
 	PyErr_Clear();
 	VimTryStart();
-	switch_buffer(&savebuf, buf);
+	if (find_win_for_buf(buf, &wp, &tp) == FAIL
+		|| switch_win(&save_curwin, &save_curtab, wp, tp, TRUE)
+								      == FAIL)
+	    switch_buffer(&save_curbuf, buf);
 
 	if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
 	    RAISE_UNDO_FAIL;
@@ -4087,11 +4102,13 @@
 	}
 
 	/* Free the array of lines. All of its contents have now
-	 * been freed.
-	 */
+	 * been freed. */
 	PyMem_Free(array);
 
-	restore_buffer(savebuf);
+	if (save_curbuf == NULL)
+	    restore_win(save_curwin, save_curtab, TRUE);
+	else
+	    restore_buffer(save_curbuf);
 	update_screen(VALID);
 
 	if (VimTryEnd())
diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro
index ad205c0..9e97f67 100644
--- a/src/proto/buffer.pro
+++ b/src/proto/buffer.pro
@@ -52,6 +52,7 @@
 int read_viminfo_bufferlist __ARGS((vir_T *virp, int writing));
 void write_viminfo_bufferlist __ARGS((FILE *fp));
 char_u *buf_spname __ARGS((buf_T *buf));
+int find_win_for_buf __ARGS((buf_T *buf, win_T **wp, tabpage_T **tp));
 void buf_addsign __ARGS((buf_T *buf, int id, linenr_T lnum, int typenr));
 linenr_T buf_change_sign_type __ARGS((buf_T *buf, int markId, int typenr));
 int buf_getsigntype __ARGS((buf_T *buf, linenr_T lnum, int type));
diff --git a/src/version.c b/src/version.c
index eb48ddd..64325c2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -728,6 +728,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    27,
+/**/
     26,
 /**/
     25,
diff --git a/src/window.c b/src/window.c
index 2435952..28bb125 100644
--- a/src/window.c
+++ b/src/window.c
@@ -6577,7 +6577,8 @@
 
 #endif
 
-#if defined(FEAT_EVAL) || defined(PROTO)
+#if defined(FEAT_EVAL) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \
+	|| defined(PROTO)
 /*
  * Set "win" to be the curwin and "tp" to be the current tab page.
  * restore_win() MUST be called to undo.