summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lisp/comint.el6
-rw-r--r--lisp/progmodes/python.el98
2 files changed, 57 insertions, 47 deletions
diff --git a/lisp/comint.el b/lisp/comint.el
index e058e6b8cf1..c2e528a5d53 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -479,6 +479,12 @@ executed once, when the buffer is created."
:group 'comint
:version "26.1")
+(defconst comint-max-line-length
+ (pcase system-type
+ ('gnu/linux 4096)
+ (_ 1024))
+ "Maximum line length, in bytes, accepted by the inferior process.")
+
(defvar comint-mode-map
(let ((map (make-sparse-keymap)))
;; Keys:
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index db7008df244..8f7bb7a8b60 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -2811,6 +2811,44 @@ eventually provide a shell."
:type 'hook
:group 'python)
+(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.")
+
+(defconst python-shell-eval-file-setup-code
+ "\
+def __PYTHON_EL_eval_file(filename, tempname, encoding, delete):
+ import codecs, os
+ with codecs.open(tempname or filename, encoding=encoding) as file:
+ source = file.read().encode(encoding)
+ if delete and tempname:
+ os.remove(tempname)
+ return __PYTHON_EL_eval(source, filename)"
+ "Code used to evaluate files in inferior Python processes.")
+
(defun python-shell-comint-watch-for-first-prompt-output-filter (output)
"Run `python-shell-first-prompt-hook' when first prompt is found in OUTPUT."
(when (not python-shell--first-prompt-received)
@@ -2826,6 +2864,15 @@ eventually provide a shell."
(setq python-shell--first-prompt-received-output-buffer nil)
(setq-local python-shell--first-prompt-received t)
(setq python-shell--first-prompt-received-output-buffer nil)
+ (cl-letf (((symbol-function 'python-shell-send-string)
+ (lambda (string process)
+ (comint-send-string
+ process
+ (format "exec(%s)\n" (python-shell--encode-string string))))))
+ ;; Bootstrap: the normal definition of `python-shell-send-string'
+ ;; depends on the Python code sent here.
+ (python-shell-send-string-no-output python-shell-eval-setup-code)
+ (python-shell-send-string-no-output python-shell-eval-file-setup-code))
(with-current-buffer (current-buffer)
(let ((inhibit-quit nil))
(run-hooks 'python-shell-first-prompt-hook))))))
@@ -3081,33 +3128,6 @@ there for compatibility with CEDET.")
(delete-trailing-whitespace))
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))
@@ -3128,12 +3148,11 @@ t when called interactively."
(interactive
(list (read-string "Python command: ") nil t))
(let ((process (or process (python-shell-get-process-or-error msg)))
- (code (format "exec(%s);__PYTHON_EL_eval(%s, %s)\n"
- (python-shell--encode-string python-shell-eval-setup-code)
+ (code (format "__PYTHON_EL_eval(%s, %s)\n"
(python-shell--encode-string string)
(python-shell--encode-string (or (buffer-file-name)
"<string>")))))
- (if (<= (string-bytes code) 4096)
+ (if (<= (string-bytes code) comint-max-line-length)
(comint-send-string process code)
(let* ((temp-file-name (with-current-buffer (process-buffer process)
(python-shell--save-temp-file string)))
@@ -3180,8 +3199,7 @@ Return the output."
(inhibit-quit t))
(or
(with-local-quit
- (comint-send-string
- process (format "exec(%s)\n" (python-shell--encode-string string)))
+ (python-shell-send-string string process)
(while python-shell-output-filter-in-progress
;; `python-shell-output-filter' takes care of setting
;; `python-shell-output-filter-in-progress' to NIL after it
@@ -3378,18 +3396,6 @@ t when called interactively."
nil ;; noop
msg))))
-
-(defconst python-shell-eval-file-setup-code
- "\
-def __PYTHON_EL_eval_file(filename, tempname, encoding, delete):
- import codecs, os
- with codecs.open(tempname or filename, encoding=encoding) as file:
- source = file.read().encode(encoding)
- if delete and tempname:
- os.remove(tempname)
- return __PYTHON_EL_eval(source, filename)"
- "Code used to evaluate files in inferior Python processes.")
-
(defun python-shell-send-file (file-name &optional process temp-file-name
delete msg)
"Send FILE-NAME to inferior Python PROCESS.
@@ -3419,9 +3425,7 @@ t when called interactively."
(comint-send-string
process
(format
- "exec(%s);exec(%s);__PYTHON_EL_eval_file(%s, %s, %s, %s)\n"
- (python-shell--encode-string python-shell-eval-setup-code)
- (python-shell--encode-string python-shell-eval-file-setup-code)
+ "__PYTHON_EL_eval_file(%s, %s, %s, %s)\n"
(python-shell--encode-string file-name)
(python-shell--encode-string (or temp-file-name ""))
(python-shell--encode-string (symbol-name encoding))