From 939cf16bc7363c3fbeccc5ab478e86258e8cd11c Mon Sep 17 00:00:00 2001 From: Jack Kamm Date: Wed, 9 Sep 2020 06:24:07 -0700 Subject: [PATCH] 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/ --- lisp/ob-python.el | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/lisp/ob-python.el b/lisp/ob-python.el index 1cded4515..00a7c1a2d 100644 --- a/lisp/ob-python.el +++ b/lisp/ob-python.el @@ -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)