summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Kamm <jackkamm@gmail.com>2023-12-29 07:39:59 -0800
committerJack Kamm <jackkamm@gmail.com>2023-12-29 07:46:49 -0800
commitd0d838b02e44a40adca14d6eae39fd4c364730da (patch)
treeea49e94b56465630b8f83cccc24375d2acf4ef23
parent996441fd564c8d5612668694f6d5baec354652ba (diff)
downloadorg-mode-d0d838b02e44a40adca14d6eae39fd4c364730da.tar.gz
ob-python: Test and improve robustness for externally started python
* lisp/ob-python.el (org-babel-python-initiate-session-by-key): Wait for first prompt for pre-existing python processes. Document behavior for pre-existing python processes. (org-babel-python-initiate-session): Document behavior for pre-existing python processes. * testing/lisp/test-ob-python.el (test-ob-python/session-with-existing-inferior-python): New test for working with existing python processes.
-rw-r--r--lisp/ob-python.el19
-rw-r--r--testing/lisp/test-ob-python.el19
2 files changed, 35 insertions, 3 deletions
diff --git a/lisp/ob-python.el b/lisp/ob-python.el
index 6002a28..8963d2f 100644
--- a/lisp/ob-python.el
+++ b/lisp/ob-python.el
@@ -248,8 +248,12 @@ unless the Python session was created outside Org."
(setq-local org-babel-python--initialized t))
(defun org-babel-python-initiate-session-by-key (&optional session)
"Initiate a python session.
-If there is not a current inferior-process-buffer in SESSION
-then create. Return the initialized session."
+If there is not a current inferior-process-buffer matching
+SESSION then create it. If inferior process already
+exists (e.g. if it was manually started with `run-python'), make
+sure it's configured to work with ob-python. If session has
+already been configured as such, do nothing. Return the
+initialized session."
(save-window-excursion
(let* ((session (if session (intern session) :default))
(py-buffer (or (org-babel-python-session-buffer session)
@@ -266,6 +270,10 @@ then create. Return the initialized session."
;; Session was created outside Org. Assume first prompt
;; already happened; run session setup code directly
(unless org-babel-python--initialized
+ ;; Ensure first prompt. Based on python-tests.el
+ ;; (`python-tests-shell-wait-for-prompt')
+ (while (not (python-util-comint-end-of-output-p))
+ (sit-for 0.1))
(org-babel-python--setup-session))
;; Adding to `python-shell-first-prompt-hook' immediately
;; after `run-python' should be safe from race conditions,
@@ -288,7 +296,12 @@ then create. Return the initialized session."
session)))
(defun org-babel-python-initiate-session (&optional session _params)
- "Create a session named SESSION according to PARAMS."
+ "Initiate Python session named SESSION according to PARAMS.
+If there is not a current inferior-process-buffer matching
+SESSION then create it. If inferior process already
+exists (e.g. if it was manually started with `run-python'), make
+sure it's configured to work with ob-python. If session has
+already been configured as such, do nothing."
(unless (string= session "none")
(org-babel-python-session-buffer
(org-babel-python-initiate-session-by-key session))))
diff --git a/testing/lisp/test-ob-python.el b/testing/lisp/test-ob-python.el
index 1886144..e3c6a40 100644
--- a/testing/lisp/test-ob-python.el
+++ b/testing/lisp/test-ob-python.el
@@ -329,6 +329,25 @@ print('success')
#+end_src"
(org-babel-execute-src-block))))))
+(ert-deftest test-ob-python/session-with-existing-inferior-python ()
+ ;; Disable the test on older Emacs as built-in python.el sometimes
+ ;; fail to initialize session.
+ (skip-unless (version<= "28" emacs-version))
+ (let ((session-name
+ "test-ob-python/session-with-existing-inferior-python"))
+ (let ((python-shell-buffer-name session-name))
+ (run-python))
+ (unwind-protect
+ (should (equal "success"
+ (org-test-with-temp-text
+ (format "#+begin_src python :session %s :results value
+'success'
+#+end_src"
+ session-name)
+ (org-babel-execute-src-block))))
+ (let (kill-buffer-hook kill-buffer-query-functions)
+ (kill-buffer (format "*%s*" session-name))))))
+
(provide 'test-ob-python)
;;; test-ob-python.el ends here