Przeglądaj źródła

adding support for python with :session none

Eric Schulte 16 lat temu
rodzic
commit
f2aaba8ca6
2 zmienionych plików z 54 dodań i 19 usunięć
  1. 48 16
      lisp/langs/org-babel-python.el
  2. 6 3
      org-babel.org

+ 48 - 16
lisp/langs/org-babel-python.el

@@ -116,33 +116,65 @@ then create.  Return the initialized session."
       session)))
 
 (defun org-babel-python-initiate-session (&optional session)
-  (org-babel-python-session-buffer (org-babel-python-initiate-session-by-key session)))
+  (unless (string= session "none")
+    (org-babel-python-session-buffer (org-babel-python-initiate-session-by-key session))))
 
 (defvar org-babel-python-last-value-eval "_"
   "When evaluated by Python this returns the return value of the last statement.")
 (defvar org-babel-python-eoe-indicator "'org_babel_python_eoe'"
   "Used to indicate that evaluation is has completed.")
+(defvar org-babel-python-wrapper-method
+  "
+def main():
+%s
+
+open('%s', 'w').write( str(main()) )")
 
 (defun org-babel-python-evaluate (buffer body &optional result-type)
   "Pass BODY to the Python process in BUFFER.  If RESULT-TYPE equals
 'output then return a list of the outputs of the statements in
 BODY, if RESULT-TYPE equals 'value then return the value of the
 last statement in BODY."
-  (org-babel-comint-in-buffer buffer
-    (let* ((full-body (mapconcat #'org-babel-trim
-                                 (list body org-babel-python-last-value-eval org-babel-python-eoe-indicator) "\n"))
-           (raw (org-babel-comint-with-output buffer org-babel-python-eoe-indicator t
-                  ;; for some reason python is fussy, and likes enters after every input
-                  (mapc (lambda (statement) (insert statement) (comint-send-input nil t))
-                        (split-string full-body "[\r\n]+"))))
-           (results (delete org-babel-python-eoe-indicator
-                            (cdr (member org-babel-python-eoe-indicator
-                                         (reverse (mapcar #'org-babel-trim raw)))))))
-      (setq results (mapcar #'org-babel-python-read-string results))
-      (org-babel-trim (case result-type
-                        (output (mapconcat #'identity (reverse (cdr results)) "\n"))
-                        (value (car results))
-                        (t (reverse results)))))))
+  (if (not session)
+      ;; external process evaluation
+      (save-window-excursion
+        (case result-type
+          (output
+           (with-temp-buffer
+             (insert body)
+             ;; (message "buffer=%s" (buffer-string)) ;; debugging
+             (shell-command-on-region (point-min) (point-max) "python" 'replace)
+             (buffer-string)))
+          (value
+           (let ((tmp-file (make-temp-file "python-functional-results")))
+             (with-temp-buffer
+               (insert (format org-babel-python-wrapper-method
+                               (let ((lines (split-string (org-remove-indentation (org-babel-trim body)) "[\r\n]")))
+                                 (concat
+                                  (mapconcat
+                                   (lambda (line) (format "\t%s" line))
+                                   (butlast lines) "\n")
+                                  (format "\n\treturn %s" (last lines))))
+                               tmp-file))
+               (message "buffer=%s" (buffer-string)) ;; debugging
+               (shell-command-on-region (point-min) (point-max) "python"))
+             (with-temp-buffer (insert-file-contents tmp-file) (buffer-string))))))
+    ;; comint session evaluation
+    (org-babel-comint-in-buffer buffer
+      (let* ((full-body (mapconcat #'org-babel-trim
+                                   (list body org-babel-python-last-value-eval org-babel-python-eoe-indicator) "\n"))
+             (raw (org-babel-comint-with-output buffer org-babel-python-eoe-indicator t
+                    ;; for some reason python is fussy, and likes enters after every input
+                    (mapc (lambda (statement) (insert statement) (comint-send-input nil t))
+                          (split-string full-body "[\r\n]+"))))
+             (results (delete org-babel-python-eoe-indicator
+                              (cdr (member org-babel-python-eoe-indicator
+                                           (reverse (mapcar #'org-babel-trim raw)))))))
+        (setq results (mapcar #'org-babel-python-read-string results))
+        (org-babel-trim (case result-type
+                          (output (mapconcat #'identity (reverse (cdr results)) "\n"))
+                          (value (car results))
+                          (t (reverse results))))))))
 
 (defun org-babel-python-read-string (string)
   "Strip 's from around ruby string"

+ 6 - 3
org-babel.org

@@ -497,7 +497,7 @@ tabel
 
 Another example is in the [[*operations%20in%20on%20tables][grades example]].
 
-** PROPOSED add =:none= session argument (for purely functional execution) [1/4]
+** PROPOSED add =:none= session argument (for purely functional execution) [2/4]
 This would allow source blocks to be run in their own new process
 
 - These blocks could then also be run in the background (since we can
@@ -531,15 +531,18 @@ puts :schulte
 #+resname: ruby-task-no-session
 | "eric"    |
 | "schulte" |
-*** TODO python
+*** DONE python
 
 #+srcname: task-python-none-session
-#+begin_src python :results replace
+#+begin_src python :session none :results replace value
 print 'something'
 print 'output'
 [1, 2, 3]
 #+end_src
 
+#+resname: task-python-none-session
+| 1 | 2 | 3 |
+
 *** TODO sh
 
 *** TODO R