mirror of
https://github.com/masscollaborationlabs/emacs.git
synced 2025-07-08 13:19:36 +00:00
Change Python eval to send directly instead of using temporary files
* lisp/progmodes/python.el (python-shell-eval-setup-code): New const for setting up eval (bug#49822). (python-shell--encode-string): New function. (python-shell-send-string): Use it to send commands directly instead of writing to a temporary file. (python-shell-send-string-no-output): Adjust sending. (python-shell-send-file): Ditto.
This commit is contained in:
parent
34550b4492
commit
e32c7d2a8d
1 changed files with 50 additions and 14 deletions
|
@ -3081,6 +3081,45 @@ there for compatibility with CEDET.")
|
||||||
(delete-trailing-whitespace))
|
(delete-trailing-whitespace))
|
||||||
temp-file-name))
|
temp-file-name))
|
||||||
|
|
||||||
|
(defconst python-shell-eval-setup-code
|
||||||
|
"\
|
||||||
|
def __PYTHON_EL_eval(source, filename):
|
||||||
|
import ast, sys
|
||||||
|
if sys.version_info[0] == 2:
|
||||||
|
from __builtin__ import compile, eval, globals
|
||||||
|
else:
|
||||||
|
from builtins import compile, eval, globals
|
||||||
|
sys.stdout.write('\\n')
|
||||||
|
try:
|
||||||
|
p, e = ast.parse(source, filename), None
|
||||||
|
except SyntaxError:
|
||||||
|
t, v, tb = sys.exc_info()
|
||||||
|
sys.excepthook(t, v, tb.tb_next)
|
||||||
|
return
|
||||||
|
if p.body and isinstance(p.body[-1], ast.Expr):
|
||||||
|
e = p.body.pop()
|
||||||
|
try:
|
||||||
|
g = globals()
|
||||||
|
exec(compile(p, filename, 'exec'), g, g)
|
||||||
|
if e:
|
||||||
|
return eval(compile(ast.Expression(e.value), filename, 'eval'), g, g)
|
||||||
|
except Exception:
|
||||||
|
t, v, tb = sys.exc_info()
|
||||||
|
sys.excepthook(t, v, tb.tb_next)"
|
||||||
|
"Code used to evaluate statements in inferior Python processes.")
|
||||||
|
|
||||||
|
(defalias 'python-shell--encode-string
|
||||||
|
(let ((fun (if (and (fboundp 'json-serialize)
|
||||||
|
(>= emacs-major-version 28))
|
||||||
|
'json-serialize
|
||||||
|
(require 'json)
|
||||||
|
'json-encode-string)))
|
||||||
|
(lambda (text)
|
||||||
|
(if (stringp text)
|
||||||
|
(funcall fun text)
|
||||||
|
(signal 'wrong-type-argument (list 'stringp text)))))
|
||||||
|
"Encode TEXT as a valid Python string.")
|
||||||
|
|
||||||
(defun python-shell-send-string (string &optional process msg)
|
(defun python-shell-send-string (string &optional process msg)
|
||||||
"Send STRING to inferior Python PROCESS.
|
"Send STRING to inferior Python PROCESS.
|
||||||
When optional argument MSG is non-nil, forces display of a
|
When optional argument MSG is non-nil, forces display of a
|
||||||
|
@ -3088,16 +3127,12 @@ user-friendly message if there's no process running; defaults to
|
||||||
t when called interactively."
|
t when called interactively."
|
||||||
(interactive
|
(interactive
|
||||||
(list (read-string "Python command: ") nil t))
|
(list (read-string "Python command: ") nil t))
|
||||||
(let ((process (or process (python-shell-get-process-or-error msg))))
|
(comint-send-string
|
||||||
(if (string-match ".\n+." string) ;Multiline.
|
(or process (python-shell-get-process-or-error msg))
|
||||||
(let* ((temp-file-name (with-current-buffer (process-buffer process)
|
(format "exec(%s);__PYTHON_EL_eval(%s, %s)\n"
|
||||||
(python-shell--save-temp-file string)))
|
(python-shell--encode-string python-shell-eval-setup-code)
|
||||||
(file-name (or (buffer-file-name) temp-file-name)))
|
(python-shell--encode-string string)
|
||||||
(python-shell-send-file file-name process temp-file-name t))
|
(python-shell--encode-string (or (buffer-file-name) "<string>")))))
|
||||||
(comint-send-string process string)
|
|
||||||
(when (or (not (string-match "\n\\'" string))
|
|
||||||
(string-match "\n[ \t].*\n?\\'" string))
|
|
||||||
(comint-send-string process "\n")))))
|
|
||||||
|
|
||||||
(defvar python-shell-output-filter-in-progress nil)
|
(defvar python-shell-output-filter-in-progress nil)
|
||||||
(defvar python-shell-output-filter-buffer nil)
|
(defvar python-shell-output-filter-buffer nil)
|
||||||
|
@ -3139,7 +3174,8 @@ Return the output."
|
||||||
(inhibit-quit t))
|
(inhibit-quit t))
|
||||||
(or
|
(or
|
||||||
(with-local-quit
|
(with-local-quit
|
||||||
(python-shell-send-string string process)
|
(comint-send-string
|
||||||
|
process (format "exec(%s)\n" (python-shell--encode-string string)))
|
||||||
(while python-shell-output-filter-in-progress
|
(while python-shell-output-filter-in-progress
|
||||||
;; `python-shell-output-filter' takes care of setting
|
;; `python-shell-output-filter' takes care of setting
|
||||||
;; `python-shell-output-filter-in-progress' to NIL after it
|
;; `python-shell-output-filter-in-progress' to NIL after it
|
||||||
|
@ -3362,7 +3398,8 @@ t when called interactively."
|
||||||
(temp-file-name (when temp-file-name
|
(temp-file-name (when temp-file-name
|
||||||
(file-local-name (expand-file-name
|
(file-local-name (expand-file-name
|
||||||
temp-file-name)))))
|
temp-file-name)))))
|
||||||
(python-shell-send-string
|
(comint-send-string
|
||||||
|
process
|
||||||
(format
|
(format
|
||||||
(concat
|
(concat
|
||||||
"import codecs, os;"
|
"import codecs, os;"
|
||||||
|
@ -3372,8 +3409,7 @@ t when called interactively."
|
||||||
(when (and delete temp-file-name)
|
(when (and delete temp-file-name)
|
||||||
(format "os.remove('''%s''');" temp-file-name))
|
(format "os.remove('''%s''');" temp-file-name))
|
||||||
"exec(compile(__code, '''%s''', 'exec'));")
|
"exec(compile(__code, '''%s''', 'exec'));")
|
||||||
(or temp-file-name file-name) encoding encoding file-name)
|
(or temp-file-name file-name) encoding encoding file-name))))
|
||||||
process)))
|
|
||||||
|
|
||||||
(defun python-shell-switch-to-shell (&optional msg)
|
(defun python-shell-switch-to-shell (&optional msg)
|
||||||
"Switch to inferior Python process buffer.
|
"Switch to inferior Python process buffer.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue