Fix Python completion failure under certain conditions

* lisp/progmodes/python.el (python-shell-send-string-no-output):
Save and restore `comint-last-prompt-overlay' or `comint-last-prompt'.
* test/lisp/progmodes/python-tests.el (python-tests-shell-wait-for-prompt):
New helper function.
(python-tests-with-temp-buffer-with-shell): New helper macro.
(python-shell-completion-1, python-shell-completion-native-1)
(python-shell-completion-native-with-ffap-1)
(python-shell-completion-native-with-eldoc-1): New tests (bug#58389).
This commit is contained in:
kobarity
2022-10-10 22:24:17 +09:00
committed by Lars Ingebrigtsen
parent 36ab164496
commit b0585441a3
2 changed files with 111 additions and 8 deletions

View File

@@ -43,6 +43,37 @@ always located at the beginning of buffer."
(goto-char (point-min))
,@body)))
(defun python-tests-shell-wait-for-prompt ()
"Wait for the prompt in the shell buffer."
(python-shell-with-shell-buffer
(while (not (if-let ((prompt (python-util-comint-last-prompt)))
(python-shell-comint-end-of-output-p
(buffer-substring-no-properties
(car prompt) (cdr prompt)))))
(sit-for 0.1))))
(defmacro python-tests-with-temp-buffer-with-shell (contents &rest body)
"Create a `python-mode' enabled temp buffer with CONTENTS and `run-python'.
BODY is code to be executed within the temp buffer. Point is
always located at the beginning of buffer. Native completion is
turned off. Shell buffer will be killed on exit."
(declare (indent 1) (debug t))
`(with-temp-buffer
(let ((python-indent-guess-indent-offset nil)
(python-shell-completion-native-enable nil))
(python-mode)
(unwind-protect
(progn
(run-python nil t)
(insert ,contents)
(goto-char (point-min))
(python-tests-shell-wait-for-prompt)
,@body)
(when (python-shell-get-buffer)
(python-shell-with-shell-buffer
(let (kill-buffer-hook kill-buffer-query-functions)
(kill-buffer))))))))
(defmacro python-tests-with-temp-file (contents &rest body)
"Create a `python-mode' enabled file with CONTENTS.
BODY is code to be executed within the temp buffer. Point is
@@ -4365,6 +4396,68 @@ def foo():
(python-shell-interpreter "/some/path/to/bin/pypy"))
(should (python-shell-completion-native-interpreter-disabled-p))))
(ert-deftest python-shell-completion-1 ()
(skip-unless (executable-find python-tests-shell-interpreter))
(python-tests-with-temp-buffer-with-shell
"
import abc
"
(let ((inhibit-message t))
(python-shell-send-buffer)
(python-tests-shell-wait-for-prompt)
(goto-char (point-max))
(insert "abc.")
(should (completion-at-point))
(insert "A")
(should (completion-at-point)))))
(ert-deftest python-shell-completion-native-1 ()
(skip-unless (executable-find python-tests-shell-interpreter))
(python-tests-with-temp-buffer-with-shell
"
import abc
"
(let ((inhibit-message t))
(python-shell-completion-native-turn-on)
(python-shell-send-buffer)
(python-tests-shell-wait-for-prompt)
(goto-char (point-max))
(insert "abc.")
(should (completion-at-point))
(insert "A")
(should (completion-at-point)))))
(ert-deftest python-shell-completion-native-with-ffap-1 ()
(skip-unless (executable-find python-tests-shell-interpreter))
(python-tests-with-temp-buffer-with-shell
"
import abc
"
(let ((inhibit-message t))
(python-shell-completion-native-turn-on)
(python-shell-send-buffer)
(python-tests-shell-wait-for-prompt)
(goto-char (point-max))
(insert "abc.")
;; This is called when FFAP is enabled and a find-file function is called.
(python-ffap-module-path "abc.")
(should (completion-at-point)))))
(ert-deftest python-shell-completion-native-with-eldoc-1 ()
(skip-unless (executable-find python-tests-shell-interpreter))
(python-tests-with-temp-buffer-with-shell
"
import abc
"
(let ((inhibit-message t))
(python-shell-completion-native-turn-on)
(python-shell-send-buffer)
(python-tests-shell-wait-for-prompt)
(goto-char (point-max))
(insert "abc.")
;; This is called by idle-timer when ElDoc is enabled.
(python-eldoc-function)
(should (completion-at-point)))))