diff options
| author | Stefan Monnier | 2010-12-10 19:13:08 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2010-12-10 19:13:08 -0500 |
| commit | 2c302df3a13236bfbf8ea1b771d13618fcda8d71 (patch) | |
| tree | f26dc9f22861dc37610de319d05255de058c221b /lisp/org/ob-python.el | |
| parent | 0c747cb143fa227e78f350ac353d703f489209df (diff) | |
| parent | 175069efeb080517afefdd44a06f7a779ea8c25c (diff) | |
| download | emacs-2c302df3a13236bfbf8ea1b771d13618fcda8d71.tar.gz emacs-2c302df3a13236bfbf8ea1b771d13618fcda8d71.zip | |
Merge from trunk
Diffstat (limited to 'lisp/org/ob-python.el')
| -rw-r--r-- | lisp/org/ob-python.el | 213 |
1 files changed, 113 insertions, 100 deletions
diff --git a/lisp/org/ob-python.el b/lisp/org/ob-python.el index c082188bea7..22cb5337d7a 100644 --- a/lisp/org/ob-python.el +++ b/lisp/org/ob-python.el | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | ;;; ob-python.el --- org-babel functions for python evaluation | 1 | ;;; ob-python.el --- org-babel functions for python evaluation |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2009, 2010 Free Software Foundation | 3 | ;; Copyright (C) 2009, 2010 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Eric Schulte, Dan Davison | 5 | ;; Author: Eric Schulte |
| 6 | ;; Dan Davison | ||
| 6 | ;; Keywords: literate programming, reproducible research | 7 | ;; Keywords: literate programming, reproducible research |
| 7 | ;; Homepage: http://orgmode.org | 8 | ;; Homepage: http://orgmode.org |
| 8 | ;; Version: 7.01 | 9 | ;; Version: 7.3 |
| 9 | 10 | ||
| 10 | ;; This file is part of GNU Emacs. | 11 | ;; This file is part of GNU Emacs. |
| 11 | 12 | ||
| @@ -47,46 +48,34 @@ | |||
| 47 | (defvar org-babel-python-mode (if (featurep 'xemacs) 'python-mode 'python) | 48 | (defvar org-babel-python-mode (if (featurep 'xemacs) 'python-mode 'python) |
| 48 | "Preferred python mode for use in running python interactively.") | 49 | "Preferred python mode for use in running python interactively.") |
| 49 | 50 | ||
| 50 | (defun org-babel-expand-body:python (body params &optional processed-params) | 51 | (defvar org-src-preserve-indentation) |
| 51 | "Expand BODY according to PARAMS, return the expanded body." | ||
| 52 | (concat | ||
| 53 | (mapconcat ;; define any variables | ||
| 54 | (lambda (pair) | ||
| 55 | (format "%s=%s" | ||
| 56 | (car pair) | ||
| 57 | (org-babel-python-var-to-python (cdr pair)))) | ||
| 58 | (nth 1 (or processed-params (org-babel-process-params params))) "\n") | ||
| 59 | "\n" (org-babel-trim body) "\n")) | ||
| 60 | 52 | ||
| 61 | (defun org-babel-execute:python (body params) | 53 | (defun org-babel-execute:python (body params) |
| 62 | "Execute a block of Python code with Babel. | 54 | "Execute a block of Python code with Babel. |
| 63 | This function is called by `org-babel-execute-src-block'." | 55 | This function is called by `org-babel-execute-src-block'." |
| 64 | (let* ((processed-params (org-babel-process-params params)) | 56 | (let* ((session (org-babel-python-initiate-session |
| 65 | (session (org-babel-python-initiate-session (first processed-params))) | 57 | (cdr (assoc :session params)))) |
| 66 | (result-params (nth 2 processed-params)) | 58 | (result-params (cdr (assoc :result-params params))) |
| 67 | (result-type (nth 3 processed-params)) | 59 | (result-type (cdr (assoc :result-type params))) |
| 68 | (full-body (org-babel-expand-body:python | 60 | (full-body |
| 69 | body params processed-params)) | 61 | (org-babel-expand-body:generic |
| 62 | body params (org-babel-variable-assignments:python params))) | ||
| 70 | (result (org-babel-python-evaluate | 63 | (result (org-babel-python-evaluate |
| 71 | session full-body result-type result-params))) | 64 | session full-body result-type result-params))) |
| 72 | (or (cdr (assoc :file params)) | 65 | (or (cdr (assoc :file params)) |
| 73 | (org-babel-reassemble-table | 66 | (org-babel-reassemble-table |
| 74 | result | 67 | result |
| 75 | (org-babel-pick-name (nth 4 processed-params) | 68 | (org-babel-pick-name (cdr (assoc :colname-names params)) |
| 76 | (cdr (assoc :colnames params))) | 69 | (cdr (assoc :colnames params))) |
| 77 | (org-babel-pick-name (nth 5 processed-params) | 70 | (org-babel-pick-name (cdr (assoc :rowname-names params)) |
| 78 | (cdr (assoc :rownames params))))))) | 71 | (cdr (assoc :rownames params))))))) |
| 79 | 72 | ||
| 80 | (defun org-babel-prep-session:python (session params) | 73 | (defun org-babel-prep-session:python (session params) |
| 81 | "Prepare SESSION according to the header arguments in PARAMS." | 74 | "Prepare SESSION according to the header arguments in PARAMS. |
| 75 | VARS contains resolved variable references" | ||
| 82 | (let* ((session (org-babel-python-initiate-session session)) | 76 | (let* ((session (org-babel-python-initiate-session session)) |
| 83 | (vars (org-babel-ref-variables params)) | 77 | (var-lines |
| 84 | (var-lines (mapcar ;; define any variables | 78 | (org-babel-variable-assignments:python params))) |
| 85 | (lambda (pair) | ||
| 86 | (format "%s=%s" | ||
| 87 | (car pair) | ||
| 88 | (org-babel-python-var-to-python (cdr pair)))) | ||
| 89 | vars))) | ||
| 90 | (org-babel-comint-in-buffer session | 79 | (org-babel-comint-in-buffer session |
| 91 | (mapc (lambda (var) | 80 | (mapc (lambda (var) |
| 92 | (end-of-line 1) (insert var) (comint-send-input) | 81 | (end-of-line 1) (insert var) (comint-send-input) |
| @@ -104,6 +93,15 @@ This function is called by `org-babel-execute-src-block'." | |||
| 104 | 93 | ||
| 105 | ;; helper functions | 94 | ;; helper functions |
| 106 | 95 | ||
| 96 | (defun org-babel-variable-assignments:python (params) | ||
| 97 | "Return list of python statements assigning the block's variables" | ||
| 98 | (mapcar | ||
| 99 | (lambda (pair) | ||
| 100 | (format "%s=%s" | ||
| 101 | (car pair) | ||
| 102 | (org-babel-python-var-to-python (cdr pair)))) | ||
| 103 | (mapcar #'cdr (org-babel-get-header params :var)))) | ||
| 104 | |||
| 107 | (defun org-babel-python-var-to-python (var) | 105 | (defun org-babel-python-var-to-python (var) |
| 108 | "Convert an elisp value to a python variable. | 106 | "Convert an elisp value to a python variable. |
| 109 | Convert an elisp value, VAR, into a string of python source code | 107 | Convert an elisp value, VAR, into a string of python source code |
| @@ -125,8 +123,7 @@ Emacs-lisp table, otherwise return the results as a string." | |||
| 125 | (mapcar (lambda (el) (if (equal el 'None) 'hline el)) res) | 123 | (mapcar (lambda (el) (if (equal el 'None) 'hline el)) res) |
| 126 | res)) | 124 | res)) |
| 127 | (org-babel-read | 125 | (org-babel-read |
| 128 | (if (or (string-match "^\\[.+\\]$" results) | 126 | (if (and (stringp results) (string-match "^[([].+[])]$" results)) |
| 129 | (string-match "^(.+)$" results)) | ||
| 130 | (org-babel-read | 127 | (org-babel-read |
| 131 | (concat "'" | 128 | (concat "'" |
| 132 | (replace-regexp-in-string | 129 | (replace-regexp-in-string |
| @@ -151,10 +148,10 @@ then create. Return the initialized session." | |||
| 151 | (let* ((session (if session (intern session) :default)) | 148 | (let* ((session (if session (intern session) :default)) |
| 152 | (python-buffer (org-babel-python-session-buffer session))) | 149 | (python-buffer (org-babel-python-session-buffer session))) |
| 153 | (cond | 150 | (cond |
| 154 | ((and (equal 'python org-babel-python-mode) | 151 | ((and (eq 'python org-babel-python-mode) |
| 155 | (fboundp 'run-python)) ; python.el | 152 | (fboundp 'run-python)) ; python.el |
| 156 | (run-python)) | 153 | (run-python)) |
| 157 | ((and (equal 'python-mode org-babel-python-mode) | 154 | ((and (eq 'python-mode org-babel-python-mode) |
| 158 | (fboundp 'py-shell)) ; python-mode.el | 155 | (fboundp 'py-shell)) ; python-mode.el |
| 159 | ;; `py-shell' creates a buffer whose name is the value of | 156 | ;; `py-shell' creates a buffer whose name is the value of |
| 160 | ;; `py-which-bufname' with '*'s at the beginning and end | 157 | ;; `py-which-bufname' with '*'s at the beginning and end |
| @@ -195,73 +192,89 @@ def main(): | |||
| 195 | open('%s', 'w').write( pprint.pformat(main()) )") | 192 | open('%s', 'w').write( pprint.pformat(main()) )") |
| 196 | 193 | ||
| 197 | (defun org-babel-python-evaluate | 194 | (defun org-babel-python-evaluate |
| 198 | (buffer body &optional result-type result-params) | 195 | (session body &optional result-type result-params) |
| 199 | "Pass BODY to the Python process in BUFFER. | 196 | "Evaluate BODY as python code." |
| 200 | If RESULT-TYPE equals 'output then return a list of the outputs | 197 | (if session |
| 201 | of the statements in BODY, if RESULT-TYPE equals 'value then | 198 | (org-babel-python-evaluate-session |
| 202 | return the value of the last statement in BODY, as elisp." | 199 | session body result-type result-params) |
| 203 | (if (not buffer) | 200 | (org-babel-python-evaluate-external-process |
| 204 | ;; external process evaluation | 201 | body result-type result-params))) |
| 205 | (case result-type | 202 | |
| 206 | (output (org-babel-eval org-babel-python-command body)) | 203 | (defun org-babel-python-evaluate-external-process |
| 207 | (value (let ((tmp-file (make-temp-file "org-babel-python-results-"))) | 204 | (body &optional result-type result-params) |
| 208 | (org-babel-eval org-babel-python-command | 205 | "Evaluate BODY in external python process. |
| 209 | (format | 206 | If RESULT-TYPE equals 'output then return standard output as a |
| 210 | (if (member "pp" result-params) | 207 | string. If RESULT-TYPE equals 'value then return the value of the |
| 211 | org-babel-python-pp-wrapper-method | 208 | last statement in BODY, as elisp." |
| 212 | org-babel-python-wrapper-method) | 209 | (case result-type |
| 213 | (mapconcat | 210 | (output (org-babel-eval org-babel-python-command body)) |
| 214 | (lambda (line) (format "\t%s" line)) | 211 | (value (let ((tmp-file (org-babel-temp-file "python-"))) |
| 215 | (split-string | 212 | (org-babel-eval org-babel-python-command |
| 216 | (org-remove-indentation | 213 | (format |
| 217 | (org-babel-trim body)) | 214 | (if (member "pp" result-params) |
| 218 | "[\r\n]") "\n") | 215 | org-babel-python-pp-wrapper-method |
| 219 | tmp-file)) | 216 | org-babel-python-wrapper-method) |
| 220 | ((lambda (raw) | 217 | (mapconcat |
| 221 | (if (or (member "code" result-params) | 218 | (lambda (line) (format "\t%s" line)) |
| 222 | (member "pp" result-params)) | 219 | (split-string |
| 223 | raw | 220 | (org-remove-indentation |
| 224 | (org-babel-python-table-or-string raw))) | 221 | (org-babel-trim body)) |
| 225 | (org-babel-eval-read-file tmp-file))))) | 222 | "[\r\n]") "\n") |
| 226 | ;; comint session evaluation | 223 | (org-babel-process-file-name tmp-file 'noquote))) |
| 227 | (flet ((dump-last-value (tmp-file pp) | 224 | ((lambda (raw) |
| 228 | (mapc | 225 | (if (or (member "code" result-params) |
| 229 | (lambda (statement) (insert statement) (comint-send-input)) | 226 | (member "pp" result-params)) |
| 230 | (if pp | 227 | raw |
| 231 | (list | 228 | (org-babel-python-table-or-string raw))) |
| 232 | "import pp" | 229 | (org-babel-eval-read-file tmp-file)))))) |
| 233 | (format "open('%s', 'w').write(pprint.pformat(_))" tmp-file)) | 230 | |
| 234 | (list (format "open('%s', 'w').write(str(_))" tmp-file))))) | 231 | (defun org-babel-python-evaluate-session |
| 235 | (input-body (body) | 232 | (session body &optional result-type result-params) |
| 236 | (mapc (lambda (statement) (insert statement) (comint-send-input)) | 233 | "Pass BODY to the Python process in SESSION. |
| 237 | (split-string (org-babel-trim body) "[\r\n]+")) | 234 | If RESULT-TYPE equals 'output then return standard output as a |
| 238 | (comint-send-input) (comint-send-input))) | 235 | string. If RESULT-TYPE equals 'value then return the value of the |
| 239 | (case result-type | 236 | last statement in BODY, as elisp." |
| 240 | (output | 237 | (flet ((dump-last-value |
| 241 | (mapconcat | 238 | (tmp-file pp) |
| 242 | #'org-babel-trim | 239 | (mapc |
| 243 | (butlast | 240 | (lambda (statement) (insert statement) (comint-send-input)) |
| 244 | (org-babel-comint-with-output | 241 | (if pp |
| 245 | (buffer org-babel-python-eoe-indicator t body) | 242 | (list |
| 246 | (let ((comint-process-echoes nil)) | 243 | "import pp" |
| 247 | (input-body body) | 244 | (format "open('%s', 'w').write(pprint.pformat(_))" |
| 248 | (insert org-babel-python-eoe-indicator) | 245 | (org-babel-process-file-name tmp-file 'noquote))) |
| 249 | (comint-send-input))) 2) "\n")) | 246 | (list (format "open('%s', 'w').write(str(_))" |
| 250 | (value | 247 | (org-babel-process-file-name tmp-file 'noquote)))))) |
| 251 | ((lambda (results) | 248 | (input-body (body) |
| 252 | (if (or (member "code" result-params) (member "pp" result-params)) | 249 | (mapc (lambda (statement) (insert statement) (comint-send-input)) |
| 253 | results | 250 | (split-string (org-babel-trim body) "[\r\n]+")) |
| 254 | (org-babel-python-table-or-string results))) | 251 | (comint-send-input) (comint-send-input))) |
| 255 | (let ((tmp-file (make-temp-file "org-babel-python-results-"))) | 252 | (case result-type |
| 256 | (org-babel-comint-with-output | 253 | (output |
| 257 | (buffer org-babel-python-eoe-indicator t body) | 254 | (mapconcat |
| 258 | (let ((comint-process-echoes nil)) | 255 | #'org-babel-trim |
| 259 | (input-body body) | 256 | (butlast |
| 260 | (dump-last-value tmp-file (member "pp" result-params)) | 257 | (org-babel-comint-with-output |
| 261 | (comint-send-input) (comint-send-input) | 258 | (session org-babel-python-eoe-indicator t body) |
| 262 | (insert org-babel-python-eoe-indicator) | 259 | (let ((comint-process-echoes nil)) |
| 263 | (comint-send-input))) | 260 | (input-body body) |
| 264 | (org-babel-eval-read-file tmp-file)))))))) | 261 | (insert org-babel-python-eoe-indicator) |
| 262 | (comint-send-input))) 2) "\n")) | ||
| 263 | (value | ||
| 264 | ((lambda (results) | ||
| 265 | (if (or (member "code" result-params) (member "pp" result-params)) | ||
| 266 | results | ||
| 267 | (org-babel-python-table-or-string results))) | ||
| 268 | (let ((tmp-file (org-babel-temp-file "python-"))) | ||
| 269 | (org-babel-comint-with-output | ||
| 270 | (session org-babel-python-eoe-indicator t body) | ||
| 271 | (let ((comint-process-echoes nil)) | ||
| 272 | (input-body body) | ||
| 273 | (dump-last-value tmp-file (member "pp" result-params)) | ||
| 274 | (comint-send-input) (comint-send-input) | ||
| 275 | (insert org-babel-python-eoe-indicator) | ||
| 276 | (comint-send-input))) | ||
| 277 | (org-babel-eval-read-file tmp-file))))))) | ||
| 265 | 278 | ||
| 266 | (defun org-babel-python-read-string (string) | 279 | (defun org-babel-python-read-string (string) |
| 267 | "Strip 's from around python string" | 280 | "Strip 's from around python string" |