mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-15 09:47:20 +00:00
Better treatment of line length limits for the Python inferior
* lisp/comint.el (comint-max-line-length): New constant reflecting a
safe maximum line size that can be sent to an inferior process.
* lisp/progmodes/python.el
(python-shell-comint-watch-for-first-prompt-output-filter): Send setup
code to the inferior process only once and at this stage.
(python-shell-eval-setup-code, python-shell-eval-file-setup-code):
Move, unchanged, to an earlier point to avoid byte-compiler warnings.
(python-shell-send-string-no-output): Revert changes of e32c7d2a8d
(python-shell-send-string): Use 'comint-max-line-length' to decide
when to resort to temp files.
(python-shell-send-string, python-shell-send-file): Don't send setup
code each time (bug#49822).
This commit is contained in:
parent
2be75990a7
commit
e27385ec37
@ -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:
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user