Subject: bug#30822: 25.3; python-shell-send-defun sends only one line

From: Nitish <[email-masked]>
Date: Thu, 05 Apr 2018 23:22:19 -0400

As Noam Postavsky mentioned, there was an unconditional (forward-line 1) expression.

The issue manifests itself in a different way too. In the example that David Liu gave, add a decorator to the function on the first line. Then `python-shell-send-defun` enters an infinite loop.

The attached patch fixes both these issues. `(forward-line 1)` should be called only when `(forward-line -1)` moves Point and `(looking-at..` returns false.
From 17b43cf36c58bb396bf269762fb081af1e08f736 Mon Sep 17 00:00:00 2001
From: nitishch <[email-masked]>
Date: Fri, 6 Apr 2018 08:01:14 +0530
Subject: [PATCH] 30822: Fixed infinite loop and also removed an extra call to
 forward-line

---
 lisp/progmodes/python.el | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index afafd1b42c..3043428413 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -3163,9 +3163,13 @@ python-shell-send-defun
                        (beginning-of-line 1))
                    (> (current-indentation) 0)))
        (when (not arg)
-         (while (and (forward-line -1)
-                     (looking-at (python-rx decorator))))
-         (forward-line 1))
+         (while (and
+                 ;; Make sure forward-line actually moves Point
+                 (eq (forward-line -1) 0)
+                 ;; If Point is at a decorator, loop.
+                 ;; else, move one line down and exit the loop.
+                 (or (looking-at (python-rx decorator))
+                     (and (forward-line 1) nil)))))
        (point-marker))
      (progn
        (or (python-nav-end-of-defun)
-- 
2.16.2