* [PATCH] python.el: Returning inferior Python output without inhibiting it
@ 2023-10-01 16:05 Jack Kamm
2023-10-01 17:00 ` Eli Zaretskii
0 siblings, 1 reply; 7+ messages in thread
From: Jack Kamm @ 2023-10-01 16:05 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1005 bytes --]
Hello, maintainer of ob-python.el in Org-mode here.
It would be very useful to ob-python, if python.el had a function that
evaluated Python code and returned output, without inhibiting the
output.
So, this patch modifies `python-shell-send-string-no-output', adding
an argument to show the output. I also rename it to
`python-shell-send-string-return-output' since that is a more accurate
name for the new behavior.
The motivation is that ob-python already implements this in
`org-babel-python-send-string', but we have noticed occasional issues
with leaky prompts in our CI [1], and suspect that the
`python-shell-send-string-no-output' implementation may be more
robust. Also, in Org-mode we have a long term goal to be more modular
and integrate better with the rest of Emacs [2]; and replacing custom
ob-python code with python.el functionality would help with that.
[1] https://list.orgmode.org/873506j7ky.fsf@localhost/
[2] https://list.orgmode.org/orgmode/E1kIPh1-0001Lu-Rg@fencepost.gnu.org/
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-python.el-Function-to-return-output-without-necessar.patch --]
[-- Type: text/x-patch, Size: 9283 bytes --]
From ffdbf2961c9d159b2c1d586667469cf7020240c2 Mon Sep 17 00:00:00 2001
From: Jack Kamm <jackkamm@gmail.com>
Date: Sat, 30 Sep 2023 21:04:12 -0700
Subject: [PATCH] python.el: Function to return output without necessarily
inhibiting
Rename `python-shell-send-string-no-output' to
`python-shell-send-string-return-output', and add option to not
inhibit the output.
*
lisp/progmodes/python.el (python-shell-output-filter-inhibit-output):
Variable to determine whether output currently inhibited.
(python-shell-comint-watch-for-first-prompt-output-filter,
python-shell-internal-send-string,
python-shell-completion-native-setup,
python-shell-completion-get-completions, python-ffap-module-path,
python-eldoc--get-doc-at-point): Replace
`python-shell-send-string-no-output' with
`python-shell-send-string-return-output'.
(python-shell-send-string): Check
`python-shell-output-filter-inhibit-output' instead of
`python-shell-output-filter-in-progress' to determine whether output
is inhibited.
(python-shell-output-filter): Set
`python-shell-output-filter-inhibit-output' to nil after reaching end
of output.
(python-shell-send-string-no-output): Obsolete function alias for
`python-shell-send-string-return-output'.
(python-shell-send-string-return-output): Rename from
`python-shell-send-string-no-output'. Add function argument on
whether output should be inhibited, and set
`python-shell-output-filter-inhibit-output' accordingly. If not
inhibited, then the original filter function is run in addition to
`python-shell-output-filter', and `comint-last-prompt' is not reset
after evaluation (since the original output filter will set it
approriately).
---
lisp/progmodes/python.el | 52 ++++++++++++++++++++++++----------------
1 file changed, 32 insertions(+), 20 deletions(-)
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index d3cb5a77e22..67a79192372 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -2736,6 +2736,7 @@ python-shell-dedicated
(defvar python-shell-output-filter-in-progress nil)
(defvar python-shell-output-filter-buffer nil)
+(defvar python-shell-output-filter-inhibit-output nil)
(defmacro python-shell--add-to-path-with-priority (pathvar paths)
"Modify PATHVAR and ensure PATHS are added only once at beginning."
@@ -3445,8 +3446,8 @@ python-shell-comint-watch-for-first-prompt-output-filter
(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))
+ (python-shell-send-string-return-output python-shell-eval-setup-code)
+ (python-shell-send-string-return-output python-shell-eval-file-setup-code))
(with-current-buffer (current-buffer)
(let ((inhibit-quit nil))
(run-hooks 'python-shell-first-prompt-hook))))))
@@ -3750,7 +3751,7 @@ python-shell-send-string
(python-shell--encode-string string)
(python-shell--encode-string (or (buffer-file-name)
"<string>")))))
- (unless python-shell-output-filter-in-progress
+ (unless python-shell-output-filter-inhibit-output
(with-current-buffer (process-buffer process)
(save-excursion
(goto-char (process-mark process))
@@ -3766,7 +3767,7 @@ python-shell-send-string
(python-shell-send-file file-name process temp-file-name t)))))
(defun python-shell-output-filter (string)
- "Filter used in `python-shell-send-string-no-output' to grab output.
+ "Filter used in `python-shell-send-string-return-output' to grab output.
STRING is the output received to this point from the process.
This filter saves received output from the process in
`python-shell-output-filter-buffer' and stops receiving it after
@@ -3780,6 +3781,7 @@ python-shell-output-filter
;; Output ends when `python-shell-output-filter-buffer' contains
;; the prompt attached at the end of it.
(setq python-shell-output-filter-in-progress nil
+ python-shell-output-filter-inhibit-output nil
python-shell-output-filter-buffer
(substring python-shell-output-filter-buffer
0 (match-beginning 0)))
@@ -3792,15 +3794,23 @@ python-shell-output-filter
(substring python-shell-output-filter-buffer (match-end 0)))))
"")
-(defun python-shell-send-string-no-output (string &optional process)
- "Send STRING to PROCESS and inhibit output.
-Return the output."
+(define-obsolete-function-alias
+ 'python-shell-send-string-no-output
+ #'python-shell-send-string-return-output "30.1")
+
+(defun python-shell-send-string-return-output (string &optional process show-output)
+ "Send STRING to PROCESS and return the output.
+Inhibit printing the output unless SHOW-OUTPUT is non-nil."
(or process (setq process (python-shell-get-process-or-error)))
- (cl-letf* (((process-filter process)
+ (cl-letf* ((original-filter-fn (process-filter process))
+ ((process-filter process)
(lambda (_proc str)
(with-current-buffer (process-buffer process)
- (python-shell-output-filter str))))
+ (python-shell-output-filter str))
+ (when show-output
+ (funcall original-filter-fn process str))))
(python-shell-output-filter-in-progress t)
+ (python-shell-output-filter-inhibit-output (not show-output))
(inhibit-quit t)
(buffer (process-buffer process))
(last-prompt (cond ((boundp 'comint-last-prompt-overlay)
@@ -3812,13 +3822,15 @@ python-shell-send-string-no-output
(with-local-quit
(unwind-protect
(python-shell-send-string string process)
- (when (not (null last-prompt))
- (with-current-buffer buffer
- (set last-prompt last-prompt-value))))
+ (unless show-output
+ (when (not (null last-prompt))
+ (with-current-buffer buffer
+ (set last-prompt last-prompt-value)))))
(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
- ;; detects end of output.
+ ;; `python-shell-output-filter-in-progress' and
+ ;; `python-shell-output-filter-inhibit-output' to NIL after
+ ;; it detects end of output.
(accept-process-output process))
(prog1
python-shell-output-filter-buffer
@@ -3828,11 +3840,11 @@ python-shell-send-string-no-output
(defun python-shell-internal-send-string (string)
"Send STRING to the Internal Python interpreter.
-Returns the output. See `python-shell-send-string-no-output'."
+Returns the output. See `python-shell-send-string-return-output'."
;; XXX Remove `python-shell-internal-last-output' once CEDET is
;; updated to support this new mode.
(setq python-shell-internal-last-output
- (python-shell-send-string-no-output
+ (python-shell-send-string-return-output
;; Makes this function compatible with the old
;; python-send-receive. (At least for CEDET).
(replace-regexp-in-string "_emacs_out +" "" string)
@@ -4217,7 +4229,7 @@ python-shell-completion-native-try
(defun python-shell-completion-native-setup ()
"Try to setup native completion, return non-nil on success."
(let* ((process (python-shell-get-process))
- (output (python-shell-send-string-no-output "
+ (output (python-shell-send-string-return-output "
def __PYTHON_EL_native_completion_setup():
try:
import readline
@@ -4454,7 +4466,7 @@ python-shell-completion-get-completions
(with-current-buffer (process-buffer process)
(let ((completions
(python-util-strip-string
- (python-shell-send-string-no-output
+ (python-shell-send-string-return-output
(format
"%s\nprint(';'.join(__PYTHON_EL_get_completions(%s)))"
python-shell-completion-setup-code
@@ -5198,7 +5210,7 @@ python-ffap-module-path
(ready (python-shell-with-shell-buffer
(python-util-comint-end-of-output-p)))
(module-file
- (python-shell-send-string-no-output
+ (python-shell-send-string-return-output
(format "%s\nprint(__FFAP_get_module_path(%s))"
python-ffap-setup-code
(python-shell--encode-string module)))))
@@ -5327,7 +5339,7 @@ python-eldoc--get-doc-at-point
;; Prevent resizing the echo area when iPython is
;; enabled. Bug#18794.
(python-util-strip-string
- (python-shell-send-string-no-output
+ (python-shell-send-string-return-output
(format
"%s\nprint(__PYDOC_get_help(%s))"
python-eldoc-setup-code
--
2.42.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] python.el: Returning inferior Python output without inhibiting it
2023-10-01 16:05 [PATCH] python.el: Returning inferior Python output without inhibiting it Jack Kamm
@ 2023-10-01 17:00 ` Eli Zaretskii
2023-10-01 20:23 ` Jack Kamm
0 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2023-10-01 17:00 UTC (permalink / raw)
To: Jack Kamm; +Cc: emacs-devel
> From: Jack Kamm <jackkamm@gmail.com>
> Date: Sun, 01 Oct 2023 09:05:23 -0700
>
> It would be very useful to ob-python, if python.el had a function that
> evaluated Python code and returned output, without inhibiting the
> output.
>
> So, this patch modifies `python-shell-send-string-no-output', adding
> an argument to show the output. I also rename it to
> `python-shell-send-string-return-output' since that is a more accurate
> name for the new behavior.
I think instead of renaming (which then requires us to add an obsolete
alias), it would be better to leave python-shell-send-string-no-output
available, but just make it a thin wrapper around
python-shell-send-string-return-output (which I would suggest to name
python-shell-send-string-maybe-output instead). This way, we don't
annoy Lisp programs that use python-shell-send-string-no-output with
obsolescence warnings.
Thanks.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] python.el: Returning inferior Python output without inhibiting it
2023-10-01 17:00 ` Eli Zaretskii
@ 2023-10-01 20:23 ` Jack Kamm
2023-10-02 5:54 ` Eli Zaretskii
0 siblings, 1 reply; 7+ messages in thread
From: Jack Kamm @ 2023-10-01 20:23 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 550 bytes --]
Eli Zaretskii <eliz@gnu.org> writes:
> I think instead of renaming (which then requires us to add an obsolete
> alias), it would be better to leave python-shell-send-string-no-output
> available, but just make it a thin wrapper around
> python-shell-send-string-return-output (which I would suggest to name
> python-shell-send-string-maybe-output instead). This way, we don't
> annoy Lisp programs that use python-shell-send-string-no-output with
> obsolescence warnings.
Thanks for the feedback -- I've updated the patch accordingly (attached).
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-python.el-Function-to-return-output-without-necessar.patch --]
[-- Type: text/x-patch, Size: 4948 bytes --]
From c071d5a531a6f17e229b0f4a9239f0f054321bc9 Mon Sep 17 00:00:00 2001
From: Jack Kamm <jackkamm@gmail.com>
Date: Sat, 30 Sep 2023 21:04:12 -0700
Subject: [PATCH] python.el: Function to return output without necessarily
inhibiting
*
lisp/progmodes/python.el (python-shell-output-filter-inhibit-output):
Variable to determine whether output currently inhibited.
(python-shell-send-string): Check
`python-shell-output-filter-inhibit-output' instead of
`python-shell-output-filter-in-progress' to determine whether output
is inhibited.
(python-shell-output-filter): Set
`python-shell-output-filter-inhibit-output' to nil after reaching end
of output.
(python-shell-send-string-no-output): Turned into a thin wrapper
around `python-shell-send-string-maybe-output'.
(python-shell-send-string-maybe-output): Adapted from
`python-shell-send-string-no-output'. Add function argument on
whether output should be inhibited, and set
`python-shell-output-filter-inhibit-output' accordingly. If not
inhibited, then the original filter function is run in addition to
`python-shell-output-filter', and `comint-last-prompt' is not reset
after evaluation (since the original output filter will set it
approriately).
---
lisp/progmodes/python.el | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index d3cb5a77e22..30d0416d035 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -2736,6 +2736,7 @@ python-shell-dedicated
(defvar python-shell-output-filter-in-progress nil)
(defvar python-shell-output-filter-buffer nil)
+(defvar python-shell-output-filter-inhibit-output nil)
(defmacro python-shell--add-to-path-with-priority (pathvar paths)
"Modify PATHVAR and ensure PATHS are added only once at beginning."
@@ -3750,7 +3751,7 @@ python-shell-send-string
(python-shell--encode-string string)
(python-shell--encode-string (or (buffer-file-name)
"<string>")))))
- (unless python-shell-output-filter-in-progress
+ (unless python-shell-output-filter-inhibit-output
(with-current-buffer (process-buffer process)
(save-excursion
(goto-char (process-mark process))
@@ -3780,6 +3781,7 @@ python-shell-output-filter
;; Output ends when `python-shell-output-filter-buffer' contains
;; the prompt attached at the end of it.
(setq python-shell-output-filter-in-progress nil
+ python-shell-output-filter-inhibit-output nil
python-shell-output-filter-buffer
(substring python-shell-output-filter-buffer
0 (match-beginning 0)))
@@ -3795,12 +3797,21 @@ python-shell-output-filter
(defun python-shell-send-string-no-output (string &optional process)
"Send STRING to PROCESS and inhibit output.
Return the output."
+ (python-shell-send-string-maybe-output string process))
+
+(defun python-shell-send-string-maybe-output (string &optional process show-output)
+ "Send STRING to PROCESS and return the output.
+Inhibit printing the output unless SHOW-OUTPUT is non-nil."
(or process (setq process (python-shell-get-process-or-error)))
- (cl-letf* (((process-filter process)
+ (cl-letf* ((original-filter-fn (process-filter process))
+ ((process-filter process)
(lambda (_proc str)
(with-current-buffer (process-buffer process)
- (python-shell-output-filter str))))
+ (python-shell-output-filter str))
+ (when show-output
+ (funcall original-filter-fn process str))))
(python-shell-output-filter-in-progress t)
+ (python-shell-output-filter-inhibit-output (not show-output))
(inhibit-quit t)
(buffer (process-buffer process))
(last-prompt (cond ((boundp 'comint-last-prompt-overlay)
@@ -3812,13 +3823,15 @@ python-shell-send-string-no-output
(with-local-quit
(unwind-protect
(python-shell-send-string string process)
- (when (not (null last-prompt))
- (with-current-buffer buffer
- (set last-prompt last-prompt-value))))
+ (unless show-output
+ (when (not (null last-prompt))
+ (with-current-buffer buffer
+ (set last-prompt last-prompt-value)))))
(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
- ;; detects end of output.
+ ;; `python-shell-output-filter-in-progress' and
+ ;; `python-shell-output-filter-inhibit-output' to NIL after
+ ;; it detects end of output.
(accept-process-output process))
(prog1
python-shell-output-filter-buffer
--
2.42.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] python.el: Returning inferior Python output without inhibiting it
2023-10-01 20:23 ` Jack Kamm
@ 2023-10-02 5:54 ` Eli Zaretskii
2023-10-02 12:42 ` kobarity
0 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2023-10-02 5:54 UTC (permalink / raw)
To: Jack Kamm, kobarity; +Cc: emacs-devel
> From: Jack Kamm <jackkamm@gmail.com>
> Cc: emacs-devel@gnu.org
> Date: Sun, 01 Oct 2023 13:23:29 -0700
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
> > I think instead of renaming (which then requires us to add an obsolete
> > alias), it would be better to leave python-shell-send-string-no-output
> > available, but just make it a thin wrapper around
> > python-shell-send-string-return-output (which I would suggest to name
> > python-shell-send-string-maybe-output instead). This way, we don't
> > annoy Lisp programs that use python-shell-send-string-no-output with
> > obsolescence warnings.
>
> Thanks for the feedback -- I've updated the patch accordingly (attached).
Thanks. kobarity, any comments or suggestions?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] python.el: Returning inferior Python output without inhibiting it
2023-10-02 5:54 ` Eli Zaretskii
@ 2023-10-02 12:42 ` kobarity
2023-10-02 16:10 ` Eli Zaretskii
0 siblings, 1 reply; 7+ messages in thread
From: kobarity @ 2023-10-02 12:42 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Jack Kamm, emacs-devel
Eli Zaretskii wrote:
>
> > From: Jack Kamm <jackkamm@gmail.com>
> > Cc: emacs-devel@gnu.org
> > Date: Sun, 01 Oct 2023 13:23:29 -0700
> >
> > Eli Zaretskii <eliz@gnu.org> writes:
> >
> > > I think instead of renaming (which then requires us to add an obsolete
> > > alias), it would be better to leave python-shell-send-string-no-output
> > > available, but just make it a thin wrapper around
> > > python-shell-send-string-return-output (which I would suggest to name
> > > python-shell-send-string-maybe-output instead). This way, we don't
> > > annoy Lisp programs that use python-shell-send-string-no-output with
> > > obsolescence warnings.
> >
> > Thanks for the feedback -- I've updated the patch accordingly (attached).
>
> Thanks. kobarity, any comments or suggestions?
I agree with leaving `python-shell-send-string-no-output' as it is.
The updated patch looks good to me.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] python.el: Returning inferior Python output without inhibiting it
2023-10-02 12:42 ` kobarity
@ 2023-10-02 16:10 ` Eli Zaretskii
2023-10-16 0:27 ` Jack Kamm
0 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2023-10-02 16:10 UTC (permalink / raw)
To: kobarity; +Cc: jackkamm, emacs-devel
> Date: Mon, 02 Oct 2023 21:42:43 +0900
> From: kobarity <kobarity@gmail.com>
> Cc: Jack Kamm <jackkamm@gmail.com>,
> emacs-devel@gnu.org
>
>
> Eli Zaretskii wrote:
> >
> > > From: Jack Kamm <jackkamm@gmail.com>
> > > Cc: emacs-devel@gnu.org
> > > Date: Sun, 01 Oct 2023 13:23:29 -0700
> > >
> > > Eli Zaretskii <eliz@gnu.org> writes:
> > >
> > > > I think instead of renaming (which then requires us to add an obsolete
> > > > alias), it would be better to leave python-shell-send-string-no-output
> > > > available, but just make it a thin wrapper around
> > > > python-shell-send-string-return-output (which I would suggest to name
> > > > python-shell-send-string-maybe-output instead). This way, we don't
> > > > annoy Lisp programs that use python-shell-send-string-no-output with
> > > > obsolescence warnings.
> > >
> > > Thanks for the feedback -- I've updated the patch accordingly (attached).
> >
> > Thanks. kobarity, any comments or suggestions?
>
> I agree with leaving `python-shell-send-string-no-output' as it is.
> The updated patch looks good to me.
Thanks. I will wait for a few days to give others a chance to chime
in and post comments or suggestions, and will install this after that,
barring any objections.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] python.el: Returning inferior Python output without inhibiting it
2023-10-02 16:10 ` Eli Zaretskii
@ 2023-10-16 0:27 ` Jack Kamm
0 siblings, 0 replies; 7+ messages in thread
From: Jack Kamm @ 2023-10-16 0:27 UTC (permalink / raw)
To: Eli Zaretskii, kobarity; +Cc: emacs-devel
Eli Zaretskii <eliz@gnu.org> writes:
> Thanks. I will wait for a few days to give others a chance to chime
> in and post comments or suggestions, and will install this after that,
> barring any objections.
Since submitting this patch, I started to have doubts that
`python-shell-send-string-maybe-output' is suitable for ob-python.
So, I suggest not to merge this after all, since ob-python was the main
motivating use case.
The reason is that `python-shell-send-string-no-output' can end
prematurely if the output contains a substring that looks like a prompt,
and ob-python should remain robust to this edge case -- it's not too
far-fetched that some user code executed by ob-python would produce a
substring like ">>>".
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-10-16 0:27 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-01 16:05 [PATCH] python.el: Returning inferior Python output without inhibiting it Jack Kamm
2023-10-01 17:00 ` Eli Zaretskii
2023-10-01 20:23 ` Jack Kamm
2023-10-02 5:54 ` Eli Zaretskii
2023-10-02 12:42 ` kobarity
2023-10-02 16:10 ` Eli Zaretskii
2023-10-16 0:27 ` Jack Kamm
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).