ob-python: Fix hanging on emacs-26.3 by adding indicator token

* lisp/ob-python.el (org-babel-python-eoe-indicator): Add back
variable for end-of-expression indicator.
(org-babel-python--shift-right): New function to indent source body.
(org-babel-python-evaluate-external-process): Call new function org-babel-python--shift-right.
(org-babel-python--send-string): Wrap body in try-except-finally,
print indicator token, and find end of output via the token.

cf https://orgmode.org/list/871rjcan53.fsf@kyleam.com/
This commit is contained in:
Jack Kamm 2020-09-09 06:24:07 -07:00
parent 771c66f791
commit 939cf16bc7
1 changed files with 29 additions and 16 deletions

View File

@ -223,6 +223,9 @@ then create. Return the initialized session."
(org-babel-python-session-buffer
(org-babel-python-initiate-session-by-key session))))
(defvar org-babel-python-eoe-indicator "org_babel_python_eoe"
"A string to indicate that evaluation has completed.")
(defconst org-babel-python-wrapper-method
"
def main():
@ -280,6 +283,19 @@ else:
(org-babel-python-evaluate-external-process
body result-type result-params preamble)))
(defun org-babel-python--shift-right (body &optional count)
(with-temp-buffer
(python-mode)
(insert body)
(goto-char (point-min))
(while (not (eobp))
(unless (python-syntax-context 'string)
(python-indent-shift-right (line-beginning-position)
(line-end-position)
count))
(forward-line 1))
(buffer-string)))
(defun org-babel-python-evaluate-external-process
(body &optional result-type result-params preamble)
"Evaluate BODY in external python process.
@ -300,16 +316,7 @@ last statement in BODY, as elisp."
(if (member "pp" result-params)
org-babel-python-pp-wrapper-method
org-babel-python-wrapper-method)
(with-temp-buffer
(python-mode)
(insert body)
(goto-char (point-min))
(while (not (eobp))
(unless (python-syntax-context 'string)
(python-indent-shift-right (line-beginning-position)
(line-end-position)))
(forward-line 1))
(buffer-string))
(org-babel-python--shift-right body)
(org-babel-process-file-name tmp-file 'noquote))))
(org-babel-eval-read-file tmp-file))))))
(org-babel-result-cond result-params
@ -324,7 +331,16 @@ Return output."
(comint-output-filter-functions
(cons (lambda (text) (setq string-buffer
(concat string-buffer text)))
comint-output-filter-functions)))
comint-output-filter-functions))
(body (format "\
try:
%s
except:
raise
finally:
print('%s')"
(org-babel-python--shift-right body 4)
org-babel-python-eoe-indicator)))
(if (not (eq 'python-mode org-babel-python-mode))
(let ((python-shell-buffer-name
(org-babel-python-without-earmuffs session)))
@ -333,13 +349,10 @@ Return output."
(py-shell-send-string body (get-buffer-process session)))
;; same as `python-shell-comint-end-of-output-p' in emacs-25.1+
(while (not (string-match
(concat "\r?\n?"
(replace-regexp-in-string
(rx string-start ?^) "" comint-prompt-regexp)
(rx eos))
org-babel-python-eoe-indicator
string-buffer))
(accept-process-output (get-buffer-process (current-buffer))))
(substring string-buffer 0 (match-beginning 0)))))
(org-babel-chomp (substring string-buffer 0 (match-beginning 0))))))
(defun org-babel-python-evaluate-session
(session body &optional result-type result-params)