: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)
(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))))))
(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))
(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)))
(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
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.
(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))