Fix point moving when calling python-shell-send-region

* lisp/progmodes/python.el (python-shell-buffer-substring): Add
`save-excursion' to prevent the point from moving.
* test/lisp/progmodes/python-tests.el (python-tests-should-not-move):
New helper function to assert that point does not move while calling a
function.
(python-shell-buffer-substring-*): Use
`python-tests-should-not-move'. (Bug#61463)
This commit is contained in:
kobarity 2023-02-14 00:30:15 +09:00 committed by Eli Zaretskii
parent 6c0d821017
commit 5190ea6259
2 changed files with 58 additions and 30 deletions

View file

@ -3759,14 +3759,15 @@ the python shell:
whitespaces will be removed. Otherwise, wraps indented whitespaces will be removed. Otherwise, wraps indented
regions under an \"if True:\" block so the interpreter regions under an \"if True:\" block so the interpreter
evaluates them correctly." evaluates them correctly."
(let* ((single-p (save-restriction (let* ((single-p (save-excursion
(narrow-to-region start end) (save-restriction
(= (progn (narrow-to-region start end)
(goto-char start) (= (progn
(python-nav-beginning-of-statement)) (goto-char start)
(progn (python-nav-beginning-of-statement))
(goto-char end) (progn
(python-nav-beginning-of-statement))))) (goto-char end)
(python-nav-beginning-of-statement))))))
(start (save-excursion (start (save-excursion
;; If we're at the start of the expression, and if ;; If we're at the start of the expression, and if
;; the region consists of a single statement, then ;; the region consists of a single statement, then
@ -3785,10 +3786,11 @@ the python shell:
(line-beginning-position) (line-beginning-position)
start)))) start))))
(substring (buffer-substring-no-properties start end)) (substring (buffer-substring-no-properties start end))
(starts-at-first-line-p (save-restriction (starts-at-first-line-p (save-excursion
(widen) (save-restriction
(goto-char start) (widen)
(= (line-number-at-pos) 1))) (goto-char start)
(= (line-number-at-pos) 1))))
(encoding (python-info-encoding)) (encoding (python-info-encoding))
(toplevel-p (zerop (save-excursion (toplevel-p (zerop (save-excursion
(goto-char start) (goto-char start)

View file

@ -189,6 +189,14 @@ default to `point-min' and `point-max' respectively."
(overlay-end overlay)))) (overlay-end overlay))))
(buffer-substring-no-properties (point-min) (point-max))))) (buffer-substring-no-properties (point-min) (point-max)))))
(defun python-tests-should-not-move (func &rest args)
"Assert that point does not move while calling FUNC with ARGS.
Returns the value returned by FUNC."
(let ((pos (point))
(ret (apply func args)))
(should (= pos (point)))
ret))
(defun python-virt-bin (&optional virt-root) (defun python-virt-bin (&optional virt-root)
"Return the virtualenv bin dir, starting from VIRT-ROOT. "Return the virtualenv bin dir, starting from VIRT-ROOT.
If nil, VIRT-ROOT defaults to `python-shell-virtualenv-root'. If nil, VIRT-ROOT defaults to `python-shell-virtualenv-root'.
@ -4213,7 +4221,8 @@ class Bar(models.Model):
pass pass
" "
(should (string= (buffer-string) (should (string= (buffer-string)
(python-shell-buffer-substring (point-min) (point-max)))))) (python-tests-should-not-move
#'python-shell-buffer-substring (point-min) (point-max))))))
(ert-deftest python-shell-buffer-substring-2 () (ert-deftest python-shell-buffer-substring-2 ()
"Main block should be removed if NOMAIN is non-nil." "Main block should be removed if NOMAIN is non-nil."
@ -4229,7 +4238,8 @@ if __name__ == \"__main__\":
foo = Foo() foo = Foo()
print (foo) print (foo)
" "
(should (string= (python-shell-buffer-substring (point-min) (point-max) t) (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring (point-min) (point-max) t)
" "
class Foo(models.Model): class Foo(models.Model):
pass pass
@ -4256,7 +4266,8 @@ if __name__ == \"__main__\":
class Bar(models.Model): class Bar(models.Model):
pass pass
" "
(should (string= (python-shell-buffer-substring (point-min) (point-max) t) (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring (point-min) (point-max) t)
" "
class Foo(models.Model): class Foo(models.Model):
pass pass
@ -4284,7 +4295,8 @@ if __name__ == \"__main__\":
class Bar(models.Model): class Bar(models.Model):
pass pass
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "class Foo(models.Model):") (python-tests-look-at "class Foo(models.Model):")
(progn (python-nav-forward-sexp) (point))) (progn (python-nav-forward-sexp) (point)))
"# -*- coding: latin-1 -*- "# -*- coding: latin-1 -*-
@ -4307,7 +4319,8 @@ if __name__ == \"__main__\":
class Bar(models.Model): class Bar(models.Model):
pass pass
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "class Bar(models.Model):") (python-tests-look-at "class Bar(models.Model):")
(progn (python-nav-forward-sexp) (point))) (progn (python-nav-forward-sexp) (point)))
"# -*- coding: latin-1 -*- "# -*- coding: latin-1 -*-
@ -4338,7 +4351,8 @@ if __name__ == \"__main__\":
class Bar(models.Model): class Bar(models.Model):
pass pass
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "# coding: latin-1") (python-tests-look-at "# coding: latin-1")
(python-tests-look-at "if __name__ == \"__main__\":")) (python-tests-look-at "if __name__ == \"__main__\":"))
"# -*- coding: latin-1 -*- "# -*- coding: latin-1 -*-
@ -4365,7 +4379,8 @@ if __name__ == \"__main__\":
class Bar(models.Model): class Bar(models.Model):
pass pass
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "# coding: latin-1") (python-tests-look-at "# coding: latin-1")
(python-tests-look-at "if __name__ == \"__main__\":")) (python-tests-look-at "if __name__ == \"__main__\":"))
"# -*- coding: utf-8 -*- "# -*- coding: utf-8 -*-
@ -4385,7 +4400,8 @@ class Foo(models.Model):
class Foo(models.Model): class Foo(models.Model):
pass pass
" "
(should (string= (python-shell-buffer-substring (point-min) (point-max)) (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring (point-min) (point-max))
"# coding: utf-8 "# coding: utf-8
@ -4404,7 +4420,8 @@ class Foo(models.Model):
class Bar(models.Model): class Bar(models.Model):
pass pass
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(point-min) (point-min)
(python-tests-look-at "class Bar(models.Model):")) (python-tests-look-at "class Bar(models.Model):"))
"# coding: utf-8 "# coding: utf-8
@ -4421,7 +4438,8 @@ class Foo(models.Model):
def foo(): def foo():
print ('a') print ('a')
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "print ('a')") (python-tests-look-at "print ('a')")
(point-max)) (point-max))
"# -*- coding: utf-8 -*-\nif True:\n print ('a')\n\n")))) "# -*- coding: utf-8 -*-\nif True:\n print ('a')\n\n"))))
@ -4433,7 +4451,8 @@ def foo():
def foo(): def foo():
print ('a') print ('a')
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(progn (progn
(python-tests-look-at "print ('a')") (python-tests-look-at "print ('a')")
(backward-char 1) (backward-char 1)
@ -4451,7 +4470,8 @@ def foo():
print ('a') print ('a')
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "# Whitespace") (python-tests-look-at "# Whitespace")
(point-max)) (point-max))
"# -*- coding: utf-8 -*-\n\nif True:\n # Whitespace\n\n print ('a')\n\n")))) "# -*- coding: utf-8 -*-\n\nif True:\n # Whitespace\n\n print ('a')\n\n"))))
@ -4463,7 +4483,8 @@ def foo():
def foo(): def foo():
a = 1 a = 1
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "a = 1") (python-tests-look-at "a = 1")
(pos-eol)) (pos-eol))
"# -*- coding: utf-8 -*-\n\na = 1")))) "# -*- coding: utf-8 -*-\n\na = 1"))))
@ -4476,7 +4497,8 @@ def foo():
a = \"\"\"Some a = \"\"\"Some
string\"\"\" string\"\"\"
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "a = \"\"\"Some") (python-tests-look-at "a = \"\"\"Some")
(pos-eol 2)) (pos-eol 2))
"# -*- coding: utf-8 -*-\n\na = \"\"\"Some\n string\"\"\"")))) "# -*- coding: utf-8 -*-\n\na = \"\"\"Some\n string\"\"\""))))
@ -4488,7 +4510,8 @@ def foo():
def foo(): def foo():
a = 1 a = 1
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at " a = 1") (python-tests-look-at " a = 1")
(python-tests-look-at " = 1")) (python-tests-look-at " = 1"))
"# -*- coding: utf-8 -*-\n\na")))) "# -*- coding: utf-8 -*-\n\na"))))
@ -4500,7 +4523,8 @@ def foo():
def foo(): def foo():
a = 1 a = 1
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "1") (python-tests-look-at "1")
(1+ (point))) (1+ (point)))
"# -*- coding: utf-8 -*-\n\n1")))) "# -*- coding: utf-8 -*-\n\n1"))))
@ -4515,7 +4539,8 @@ def foo():
b = 2 b = 2
\"\"\" \"\"\"
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "a = 1") (python-tests-look-at "a = 1")
(python-tests-look-at "\"\"\"")) (python-tests-look-at "\"\"\""))
"# -*- coding: utf-8 -*-\n\nif True:\n a = 1\n b = 2\n\n")))) "# -*- coding: utf-8 -*-\n\nif True:\n a = 1\n b = 2\n\n"))))
@ -4525,7 +4550,8 @@ def foo():
(python-tests-with-temp-buffer (python-tests-with-temp-buffer
"s = 'test' "s = 'test'
" "
(should (string= (python-shell-buffer-substring (should (string= (python-tests-should-not-move
#'python-shell-buffer-substring
(python-tests-look-at "'test'") (python-tests-look-at "'test'")
(pos-eol)) (pos-eol))
"'test'")))) "'test'"))))