Fix python-shell-buffer-substring when retrieving a single statement

* lisp/progmodes/python.el (python-shell-buffer-substring): Do not add
"if True:" line when retrieving a single statement.
(python-shell-send-region): Add a reference to
`python-shell-buffer-substring' in docstring.
* test/lisp/progmodes/python-tests.el (python-shell-buffer-substring-13)
(python-shell-buffer-substring-14, python-shell-buffer-substring-15)
(python-shell-buffer-substring-16, python-shell-buffer-substring-17):
New tests. (Bug#60142)
This commit is contained in:
kobarity 2022-12-22 23:08:40 +09:00 committed by Eli Zaretskii
parent bfdad6c4e5
commit eee2aeca25
2 changed files with 95 additions and 14 deletions

View file

@ -3736,19 +3736,35 @@ the python shell:
appending extra empty lines so tracebacks are correct. appending extra empty lines so tracebacks are correct.
3. When the region sent is a substring of the current buffer, a 3. When the region sent is a substring of the current buffer, a
coding cookie is added. coding cookie is added.
4. Wraps indented regions under an \"if True:\" block so the 4. When the region consists of a single statement, leading
interpreter evaluates them correctly." whitespaces will be removed. Otherwise, wraps indented
(let* ((start (save-excursion regions under an \"if True:\" block so the interpreter
;; If we're at the start of the expression, and evaluates them correctly."
;; there's just blank space ahead of it, then expand (let* ((single-p (save-restriction
;; the region to include the start of the line. (narrow-to-region start end)
;; This makes things work better with the rest of (= (progn
;; the data we're sending over.
(goto-char start) (goto-char start)
(python-nav-beginning-of-statement))
(progn
(goto-char end)
(python-nav-beginning-of-statement)))))
(start (save-excursion
;; If we're at the start of the expression, and if
;; the region consists of a single statement, then
;; remove leading whitespaces, else if there's just
;; blank space ahead of it, then expand the region
;; to include the start of the line. This makes
;; things work better with the rest of the data
;; we're sending over.
(goto-char start)
(if single-p
(progn
(skip-chars-forward "[:space:]" end)
(point))
(if (string-blank-p (if (string-blank-p
(buffer-substring (line-beginning-position) start)) (buffer-substring (line-beginning-position) start))
(line-beginning-position) (line-beginning-position)
start))) start))))
(substring (buffer-substring-no-properties start end)) (substring (buffer-substring-no-properties start end))
(starts-at-point-min-p (save-restriction (starts-at-point-min-p (save-restriction
(widen) (widen)
@ -3772,7 +3788,7 @@ the python shell:
(python-mode) (python-mode)
(when fillstr (when fillstr
(insert fillstr)) (insert fillstr))
(when (not toplevel-p) (when (and (not single-p) (not toplevel-p))
(forward-line -1) (forward-line -1)
(insert "if True:\n") (insert "if True:\n")
(delete-region (point) (line-end-position))) (delete-region (point) (line-end-position)))
@ -3816,7 +3832,8 @@ code inside blocks delimited by \"if __name__== \\='__main__\\=':\".
When called interactively SEND-MAIN defaults to nil, unless it's When called interactively SEND-MAIN defaults to nil, unless it's
called with prefix argument. When optional argument MSG is called with prefix argument. When optional argument MSG is
non-nil, forces display of a user-friendly message if there's no non-nil, forces display of a user-friendly message if there's no
process running; defaults to t when called interactively." process running; defaults to t when called interactively. The
substring to be sent is retrieved using `python-shell-buffer-substring'."
(interactive (interactive
(list (region-beginning) (region-end) current-prefix-arg t)) (list (region-beginning) (region-end) current-prefix-arg t))
(let* ((string (python-shell-buffer-substring start end (not send-main) (let* ((string (python-shell-buffer-substring start end (not send-main)

View file

@ -4456,6 +4456,70 @@ def foo():
(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"))))
(ert-deftest python-shell-buffer-substring-13 ()
"Check substring from indented single statement."
(python-tests-with-temp-buffer
"
def foo():
a = 1
"
(should (string= (python-shell-buffer-substring
(python-tests-look-at "a = 1")
(pos-eol))
"# -*- coding: utf-8 -*-\n\na = 1"))))
(ert-deftest python-shell-buffer-substring-14 ()
"Check substring from indented single statement spanning multiple lines."
(python-tests-with-temp-buffer
"
def foo():
a = \"\"\"Some
string\"\"\"
"
(should (string= (python-shell-buffer-substring
(python-tests-look-at "a = \"\"\"Some")
(pos-eol 2))
"# -*- coding: utf-8 -*-\n\na = \"\"\"Some\n string\"\"\""))))
(ert-deftest python-shell-buffer-substring-15 ()
"Check substring from partial statement."
(python-tests-with-temp-buffer
"
def foo():
a = 1
"
(should (string= (python-shell-buffer-substring
(python-tests-look-at " a = 1")
(python-tests-look-at " = 1"))
"# -*- coding: utf-8 -*-\n\na"))))
(ert-deftest python-shell-buffer-substring-16 ()
"Check substring from partial statement."
(python-tests-with-temp-buffer
"
def foo():
a = 1
"
(should (string= (python-shell-buffer-substring
(python-tests-look-at "1")
(1+ (point)))
"# -*- coding: utf-8 -*-\n\n1"))))
(ert-deftest python-shell-buffer-substring-17 ()
"Check substring from multiline string."
(python-tests-with-temp-buffer
"
def foo():
s = \"\"\"
a = 1
b = 2
\"\"\"
"
(should (string= (python-shell-buffer-substring
(python-tests-look-at "a = 1")
(python-tests-look-at "\"\"\""))
"# -*- coding: utf-8 -*-\n\nif True:\n a = 1\n b = 2\n\n"))))
;;; Shell completion ;;; Shell completion