all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: kobarity <kobarity@gmail.com>
To: "Mattias Engdegård" <mattias.engdegard@gmail.com>,
	"Lin Sun" <sunlin7.mail@gmail.com>
Cc: Eli Zaretskii <eliz@gnu.org>,
	Stefan Kangas <stefankangas@gmail.com>,
	70815@debbugs.gnu.org
Subject: bug#70815: [PATCH] ; Enahnce python-tests.el to adapt different python interpreters
Date: Tue, 04 Jun 2024 23:29:52 +0900	[thread overview]
Message-ID: <eke7h6e8aihr.wl-kobarity@gmail.com> (raw)
In-Reply-To: <eke7ikyq9eq0.wl-kobarity@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 3635 bytes --]

kobarity wrote:
> 
> kobarity wrote:
> > Mattias Engdegård wrote:
> > > > 2. Revert 9c7de10079 and run ERTs.  The expectation is that the 7 ERTs
> > > >   that previously failed will succeed.
> > > 
> > > No, they still fail:
> > > 
> > > 7 unexpected results:
> > >    FAILED  python-completion-at-point-1
> > >    FAILED  python-completion-at-point-2
> > >    FAILED  python-completion-at-point-native-1
> > >    FAILED  python-completion-at-point-native-2
> > >    FAILED  python-completion-at-point-native-with-eldoc-1
> > >    FAILED  python-completion-at-point-native-with-ffap-1
> > >    FAILED  python-shell-completion-at-point-1
> > > 
> > > 2 skipped results:
> > >   SKIPPED  python-shell-completion-at-point-ipython
> > >   SKIPPED  python-shell-completion-at-point-jedi-completer
> > 
> > Maybe I did not make the right request.  What I wanted you to try was
> > to make the following changes after applying my patch in the previous
> > email.
> > 
> > diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
> > index 970ec32bc0c..77b30f8bdbc 100644
> > --- a/test/lisp/progmodes/python-tests.el
> > +++ b/test/lisp/progmodes/python-tests.el
> > @@ -3770,7 +3770,7 @@ python-tests-get-shell-interpreter
> >              ;; Use the same order as for the default value of
> >              ;; `python-shell-interpreter'.
> >              (delq nil (mapcar #'python-tests--get-interpreter-info
> > -                              '("python3" "python" "python2"))))))
> > +                              '("python" "python3" "python2"))))))
> >    (cl-some (or pred #'car) python-tests-shell-interpreters))
> > 
> >  (defun python-tests--get-interpreter-info (name)
> > 
> > If you have tried it this way, could you tell me what the value of
> > `python-tests-shell-interpreters' is?
> 
> Sorry, I realized my mistake.  I will revise my patch within a few
> days.

The attached is the revised patch.  In order to bind
`python-shell-interpreter' consistently, new macros
`python-tests-with-shell-interpreter' and
`python-tests-with-temp-buffer-with-shell-interpreter' were
introduced.  The patch is larger because some of the indentations have
been changed by using new macros.  I have fixed
`python-shell-interpreter' was not bound correctly in some ERTs, so
you might find new ERTs that fail with Python 2 on Mac.

Same as before, it would be helpful if you could try each of the
following on Mac.

1. Set EMACS_PYTHON_INTERPRETER environment variable to "python" and
   run ERTs.  The expectation is that the 7 ERTs that previously
   resulted in errors will be skipped.
2. Change the order of the interpreters in
   `python-tests-get-shell-interpreter' to  "python" "python3"
   "python2" and run ERTs.  The expectation is that the 7 ERTs that
   previously failed will succeed.

Another change is the behavior when the interpreter specified in
EMACS_PYTHON_INTERPRETER is not found.  In the current master, ERTs
are skipped if the interpreter specified by EMACS_PYTHON_INTERPRETER
is not found.  This is because although
`python-tests-get-shell-interpreter' raises an error, `skip-unless'
ignores it.

However, if the interpreter specified by EMACS_PYTHON_INTERPRETER is
not found, it is likely that EMACS_PYTHON_INTERPRETER is incorrectly
configured, and I would prefer to let it fail rather than let it be
skipped.  If it is better to be skipped, it would be better to have
`python-tests-get-shell-interpreter' return nil without raising an
error.  I would like to hear Lin's and others opinions on this matter.

[-- Attachment #2: 0001-Specify-Python-3-in-some-ERTs-on-Mac.patch --]
[-- Type: application/octet-stream, Size: 41276 bytes --]

From 8721e1e08543f0328f8bf822e64bfea6742d8abf Mon Sep 17 00:00:00 2001
From: kobarity <kobarity@gmail.com>
Date: Tue, 4 Jun 2024 21:51:32 +0900
Subject: [PATCH] Specify Python 3 in some ERTs on Mac

* test/lisp/progmodes/python-tests.el
(python-tests-with-temp-buffer-with-shell): Remove setting
'python-shell-interpreter'.
(python-tests-shell-interpreter): Removed.
(python-tests-shell-interpreters): New variable.
(python-tests-with-shell-interpreter)
(python-tests-with-temp-buffer-with-shell-interpreter): New macros.
(python-tests-get-shell-interpreter): Add an optional PRED
argument to allow ERts to specify Python interpreter version.
(python-tests--get-interpreter-info): New function.
(python-tests-interpreter-3-p): New function to be used as the
PRED argument of 'python-tests-get-shell-interpreter'.
(python-shell-make-comint-1)
(python-shell-make-comint-2)
(python-shell-make-comint-4)
(python-shell-get-process-1)
(python-shell-internal-get-or-create-process-1)
(python-shell-prompt-detect-1)
(python-shell-prompt-detect-2)
(python-shell-prompt-detect-3)
(python-shell-prompt-detect-4)
(python-shell-prompt-detect-5)
(python-shell-prompt-detect-6)
(python-shell-prompt-set-calculated-regexps-6)
(python-shell-completion-at-point-jedi-completer)
(python-completion-at-point-pdb-1)
(python-completion-at-point-while-running-1)
(python-ffap-module-path-1)
(python-ffap-module-path-while-running-1)
(python-eldoc--get-doc-at-point-1)
(python-eldoc--get-doc-at-point-while-running-1)
(python-tests--run-python-selects-window)
(python-test--shell-send-block): Use the new macro.
(python-shell-completion-at-point-ipython): Remove setting
'python-tests-shell-interpreter'.
(python-shell-completion-at-point-1)
(python-completion-at-point-1)
(python-completion-at-point-2)
(python-completion-at-point-native-1)
(python-completion-at-point-native-2)
(python-completion-at-point-native-with-ffap-1)
(python-completion-at-point-native-with-eldoc-1): Use the new
macro and specify Python 3 on Mac to avoid errors.  (Bug#70815)
---
 test/lisp/progmodes/python-tests.el | 660 +++++++++++++++-------------
 1 file changed, 352 insertions(+), 308 deletions(-)

diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index b06547b10ff..5fc773026e7 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -59,8 +59,7 @@ python-tests-with-temp-buffer-with-shell
   (let ((dir (make-symbol "dir")))
     `(with-temp-buffer
        (let ((python-indent-guess-indent-offset nil)
-             (python-shell-completion-native-enable nil)
-             (python-shell-interpreter (python-tests-get-shell-interpreter)))
+             (python-shell-completion-native-enable nil))
          (python-mode)
          (unwind-protect
              ;; Prevent test failures when Jedi is used as a completion
@@ -3750,21 +3749,67 @@ python-bob-infloop-avoid
 \f
 ;;; Shell integration
 
-(defvar python-tests-shell-interpreter nil)
-
-(defun python-tests-get-shell-interpreter ()
+(defvar python-tests-shell-interpreters nil
+  "List of Python interpreter information.
+Set this variable to nil to rescan interpreters.")
+
+(defmacro python-tests-with-shell-interpreter (pred &rest body)
+  "Bind `python-shell-interpreter' and execute BODY.
+`python-shell-interpreter' is bound to the result of calling
+`python-tests-get-shell-interpreter' with PRED argument.  The calling
+ERT is skipped if `python-tests-get-shell-interpreter' returned nil."
+  `(let ((python-shell-interpreter
+          (python-tests-get-shell-interpreter ,pred)))
+     (skip-unless python-shell-interpreter)
+     ,@body))
+
+(defmacro python-tests-with-temp-buffer-with-shell-interpreter
+    (pred contents &rest body)
+  "Variant of `python-tests-with-temp-buffer-with-shell'.
+It binds `python-shell-interpreter' to the result of calling
+`python-tests-get-shell-interpreter' with PRED argument, and calls
+`python-tests-with-temp-buffer-with-shell' with CONTENTS and BODY."
+  `(python-tests-with-shell-interpreter
+    ,pred
+    (python-tests-with-temp-buffer-with-shell ,contents ,@body)))
+
+(defun python-tests-get-shell-interpreter (&optional pred)
   "Get the shell interpreter.
-If env string EMACS_PYTHON_INTERPRETER exists, use it as preferred one."
-  (if python-tests-shell-interpreter
-      python-tests-shell-interpreter
-    (setq python-tests-shell-interpreter
-          (or (when-let ((interpreter (getenv "EMACS_PYTHON_INTERPRETER")))
-                (or (executable-find interpreter)
-                    (error "Couldn't find EMACS_PYTHON_INTERPRETER(%s) in path"
-                           interpreter)))
-              ;; Use the same order as for the default value of
-              ;; `python-shell-interpreter'.
-              (cl-some #'executable-find '("python3" "python" "python2"))))))
+If an optional PRED is specified, an interpreter is selected that
+matches the predicate.  PRED must return the absolute file name if the
+condition is met.  If env string EMACS_PYTHON_INTERPRETER exists, use it
+as preferred one."
+  (unless python-tests-shell-interpreters
+    (setq python-tests-shell-interpreters
+          (if-let ((interpreter (getenv "EMACS_PYTHON_INTERPRETER")))
+              (if-let ((info (python-tests--get-interpreter-info interpreter)))
+                  (list info)
+                (error "Couldn't find EMACS_PYTHON_INTERPRETER(%s) in path"
+                       interpreter))
+            ;; Use the same order as for the default value of
+            ;; `python-shell-interpreter'.
+            (delq nil (mapcar #'python-tests--get-interpreter-info
+                              '("python3" "python" "python2"))))))
+  (cl-some (or pred #'car) python-tests-shell-interpreters))
+
+(defun python-tests--get-interpreter-info (name)
+  "Get Python interpreter information specified by NAME.
+The information returned is a cons cell consisting of the file path and
+the version string."
+  (when-let ((interpreter (executable-find name)))
+    (with-temp-buffer
+      (and (equal (call-process interpreter nil t nil "--version") 0)
+           (goto-char (point-min))
+           (looking-at
+            (rx (seq "Python" (+ space) (group (+ (any digit ?.))))))
+           (cons interpreter (match-string-no-properties 1))))))
+
+(defun python-tests-interpreter-3-p (info)
+  "Return the absolute file name if the interpreter major version in INFO is 3.
+This function is intended to be used as the PRED argument of
+`python-tests-get-shell-interpreter'."
+  (when (string= (car (split-string (cdr info) "\\.")) "3")
+    (car info)))
 
 (ert-deftest python-shell-get-process-name-1 ()
   "Check process name calculation sans `buffer-file-name'."
@@ -4026,48 +4071,46 @@ python-shell-with-environment-3
 
 (ert-deftest python-shell-make-comint-1 ()
   "Check comint creation for global shell buffer."
-  (skip-unless (python-tests-get-shell-interpreter))
   ;; The interpreter can get killed too quickly to allow it to clean
   ;; up the tempfiles that the default python-shell-setup-codes create,
   ;; so it leaves tempfiles behind, which is a minor irritation.
-  (let* ((python-shell-setup-codes nil)
-         (python-shell-interpreter
-          (python-tests-get-shell-interpreter))
-         (proc-name (python-shell-get-process-name nil))
-         (shell-buffer
-          (python-tests-with-temp-buffer
-           "" (python-shell-make-comint
-               (python-shell-calculate-command) proc-name)))
-         (process (get-buffer-process shell-buffer)))
-    (unwind-protect
-        (progn
-          (set-process-query-on-exit-flag process nil)
-          (should (process-live-p process))
-          (with-current-buffer shell-buffer
-            (should (eq major-mode 'inferior-python-mode))
-            (should (string= (buffer-name) (format "*%s*" proc-name)))))
-      (kill-buffer shell-buffer))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let* ((python-shell-setup-codes nil)
+          (proc-name (python-shell-get-process-name nil))
+          (shell-buffer
+           (python-tests-with-temp-buffer
+            "" (python-shell-make-comint
+                (python-shell-calculate-command) proc-name)))
+          (process (get-buffer-process shell-buffer)))
+     (unwind-protect
+         (progn
+           (set-process-query-on-exit-flag process nil)
+           (should (process-live-p process))
+           (with-current-buffer shell-buffer
+             (should (eq major-mode 'inferior-python-mode))
+             (should (string= (buffer-name) (format "*%s*" proc-name)))))
+       (kill-buffer shell-buffer)))))
 
 (ert-deftest python-shell-make-comint-2 ()
   "Check comint creation for internal shell buffer."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (let* ((python-shell-setup-codes nil)
-         (python-shell-interpreter
-          (python-tests-get-shell-interpreter))
-         (proc-name (python-shell-internal-get-process-name))
-         (shell-buffer
-          (python-tests-with-temp-buffer
-           "" (python-shell-make-comint
-               (python-shell-calculate-command) proc-name nil t)))
-         (process (get-buffer-process shell-buffer)))
-    (unwind-protect
-        (progn
-          (set-process-query-on-exit-flag process nil)
-          (should (process-live-p process))
-          (with-current-buffer shell-buffer
-            (should (eq major-mode 'inferior-python-mode))
-            (should (string= (buffer-name) (format " *%s*" proc-name)))))
-      (kill-buffer shell-buffer))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let* ((python-shell-setup-codes nil)
+          (proc-name (python-shell-internal-get-process-name))
+          (shell-buffer
+           (python-tests-with-temp-buffer
+            "" (python-shell-make-comint
+                (python-shell-calculate-command) proc-name nil t)))
+          (process (get-buffer-process shell-buffer)))
+     (unwind-protect
+         (progn
+           (set-process-query-on-exit-flag process nil)
+           (should (process-live-p process))
+           (with-current-buffer shell-buffer
+             (should (eq major-mode 'inferior-python-mode))
+             (should (string= (buffer-name) (format " *%s*" proc-name)))))
+       (kill-buffer shell-buffer)))))
 
 (ert-deftest python-shell-make-comint-3 ()
   "Check comint creation with overridden python interpreter and args.
@@ -4099,58 +4142,56 @@ python-shell-make-comint-3
 
 (ert-deftest python-shell-make-comint-4 ()
   "Check shell calculated prompts regexps are set."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (let* ((process-environment process-environment)
-         (python-shell-setup-codes nil)
-         (python-shell-interpreter
-          (python-tests-get-shell-interpreter))
-         (python-shell-interpreter-args "-i")
-         (python-shell--prompt-calculated-input-regexp nil)
-         (python-shell--prompt-calculated-output-regexp nil)
-         (python-shell-prompt-detect-enabled t)
-         (python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
-         (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
-         (python-shell-prompt-regexp "in")
-         (python-shell-prompt-block-regexp "block")
-         (python-shell-prompt-pdb-regexp "pdf")
-         (python-shell-prompt-output-regexp "output")
-         (startup-code (concat "import sys\n"
-                               "sys.ps1 = 'py> '\n"
-                               "sys.ps2 = '..> '\n"
-                               "sys.ps3 = 'out '\n"))
-         (startup-file (python-shell--save-temp-file startup-code))
-         (proc-name (python-shell-get-process-name nil))
-         (shell-buffer
-          (progn
-            (setenv "PYTHONSTARTUP" startup-file)
-            (python-tests-with-temp-buffer
-             "" (python-shell-make-comint
-                 (python-shell-calculate-command) proc-name nil))))
-         (process (get-buffer-process shell-buffer)))
-    (unwind-protect
-        (progn
-          (set-process-query-on-exit-flag process nil)
-          (should (process-live-p process))
-          (with-current-buffer shell-buffer
-            (should (eq major-mode 'inferior-python-mode))
-            (should (string=
-                     python-shell--prompt-calculated-input-regexp
-                     (concat "^\\(extralargeinputprompt\\|\\.\\.> \\|"
-                             "block\\|py> \\|pdf\\|sml\\|in\\)")))
-            (should (string=
-                     python-shell--prompt-calculated-output-regexp
-                     "^\\(extralargeoutputprompt\\|output\\|out \\|sml\\)"))))
-      (delete-file startup-file)
-      (kill-buffer shell-buffer))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let* ((process-environment process-environment)
+          (python-shell-setup-codes nil)
+          (python-shell-interpreter-args "-i")
+          (python-shell--prompt-calculated-input-regexp nil)
+          (python-shell--prompt-calculated-output-regexp nil)
+          (python-shell-prompt-detect-enabled t)
+          (python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
+          (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
+          (python-shell-prompt-regexp "in")
+          (python-shell-prompt-block-regexp "block")
+          (python-shell-prompt-pdb-regexp "pdf")
+          (python-shell-prompt-output-regexp "output")
+          (startup-code (concat "import sys\n"
+                                "sys.ps1 = 'py> '\n"
+                                "sys.ps2 = '..> '\n"
+                                "sys.ps3 = 'out '\n"))
+          (startup-file (python-shell--save-temp-file startup-code))
+          (proc-name (python-shell-get-process-name nil))
+          (shell-buffer
+           (progn
+             (setenv "PYTHONSTARTUP" startup-file)
+             (python-tests-with-temp-buffer
+              "" (python-shell-make-comint
+                  (python-shell-calculate-command) proc-name nil))))
+          (process (get-buffer-process shell-buffer)))
+     (unwind-protect
+         (progn
+           (set-process-query-on-exit-flag process nil)
+           (should (process-live-p process))
+           (with-current-buffer shell-buffer
+             (should (eq major-mode 'inferior-python-mode))
+             (should (string=
+                      python-shell--prompt-calculated-input-regexp
+                      (concat "^\\(extralargeinputprompt\\|\\.\\.> \\|"
+                              "block\\|py> \\|pdf\\|sml\\|in\\)")))
+             (should (string=
+                      python-shell--prompt-calculated-output-regexp
+                      "^\\(extralargeoutputprompt\\|output\\|out \\|sml\\)"))))
+       (delete-file startup-file)
+       (kill-buffer shell-buffer)))))
 
 (ert-deftest python-shell-get-process-1 ()
   "Check dedicated shell process preference over global."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-file
-      ""
+  (python-tests-with-shell-interpreter
+   nil
+   (python-tests-with-temp-file
+    ""
     (let* ((python-shell-setup-codes nil)
-           (python-shell-interpreter
-            (python-tests-get-shell-interpreter))
            (global-proc-name (python-shell-get-process-name nil))
            (dedicated-proc-name (python-shell-get-process-name t))
            (global-shell-buffer
@@ -4174,131 +4215,134 @@ python-shell-get-process-1
             ;; No buffer available.
             (should (not (python-shell-get-process))))
         (ignore-errors (kill-buffer global-shell-buffer))
-        (ignore-errors (kill-buffer dedicated-shell-buffer))))))
+        (ignore-errors (kill-buffer dedicated-shell-buffer)))))))
 
 (ert-deftest python-shell-internal-get-or-create-process-1 ()
   "Check internal shell process creation fallback."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-file
-   ""
-   (should (not (process-live-p (python-shell-internal-get-process-name))))
-   (let* ((python-shell-interpreter
-           (python-tests-get-shell-interpreter))
-          (internal-process-name (python-shell-internal-get-process-name))
-          (internal-process (python-shell-internal-get-or-create-process))
-          (internal-shell-buffer (process-buffer internal-process)))
-     (unwind-protect
-         (progn
-           (set-process-query-on-exit-flag internal-process nil)
-           (should (equal (process-name internal-process)
-                          internal-process-name))
-           (should (equal internal-process
-                          (python-shell-internal-get-or-create-process)))
-           ;; Assert the internal process is not a user process
-           (should (not (python-shell-get-process)))
-           (kill-buffer internal-shell-buffer))
-       (ignore-errors (kill-buffer internal-shell-buffer))))))
+  (python-tests-with-shell-interpreter
+   nil
+   (python-tests-with-temp-file
+    ""
+    (should (not (process-live-p (python-shell-internal-get-process-name))))
+    (let* ((internal-process-name (python-shell-internal-get-process-name))
+           (internal-process (python-shell-internal-get-or-create-process))
+           (internal-shell-buffer (process-buffer internal-process)))
+      (unwind-protect
+          (progn
+            (set-process-query-on-exit-flag internal-process nil)
+            (should (equal (process-name internal-process)
+                           internal-process-name))
+            (should (equal internal-process
+                           (python-shell-internal-get-or-create-process)))
+            ;; Assert the internal process is not a user process
+            (should (not (python-shell-get-process)))
+            (kill-buffer internal-shell-buffer))
+        (ignore-errors (kill-buffer internal-shell-buffer)))))))
 
 (ert-deftest python-shell-prompt-detect-1 ()
   "Check prompt autodetection."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (let ((process-environment process-environment)
-        (python-shell-interpreter (python-tests-get-shell-interpreter)))
-    ;; Ensure no startup file is enabled
-    (setenv "PYTHONSTARTUP" "")
-    (should python-shell-prompt-detect-enabled)
-    (should (equal (python-shell-prompt-detect) '(">>> " "... " "")))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let ((process-environment process-environment))
+     ;; Ensure no startup file is enabled
+     (setenv "PYTHONSTARTUP" "")
+     (should python-shell-prompt-detect-enabled)
+     (should (equal (python-shell-prompt-detect) '(">>> " "... " ""))))))
 
 (ert-deftest python-shell-prompt-detect-2 ()
   "Check prompt autodetection with startup file.  Bug#17370."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (let* ((process-environment process-environment)
-         (python-shell-interpreter (python-tests-get-shell-interpreter))
-         (startup-code (concat "import sys\n"
-                               "sys.ps1 = 'py> '\n"
-                               "sys.ps2 = '..> '\n"
-                               "sys.ps3 = 'out '\n"))
-         (startup-file (python-shell--save-temp-file startup-code)))
-    (unwind-protect
-        (progn
-          ;; Ensure startup file is enabled
-          (setenv "PYTHONSTARTUP" startup-file)
-          (should python-shell-prompt-detect-enabled)
-          (should (equal (python-shell-prompt-detect) '("py> " "..> " "out "))))
-      (ignore-errors (delete-file startup-file)))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let* ((process-environment process-environment)
+          (startup-code (concat "import sys\n"
+                                "sys.ps1 = 'py> '\n"
+                                "sys.ps2 = '..> '\n"
+                                "sys.ps3 = 'out '\n"))
+          (startup-file (python-shell--save-temp-file startup-code)))
+     (unwind-protect
+         (progn
+           ;; Ensure startup file is enabled
+           (setenv "PYTHONSTARTUP" startup-file)
+           (should python-shell-prompt-detect-enabled)
+           (should (equal (python-shell-prompt-detect) '("py> " "..> " "out "))))
+       (ignore-errors (delete-file startup-file))))))
 
 (ert-deftest python-shell-prompt-detect-3 ()
   "Check prompts are not autodetected when feature is disabled."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (let ((process-environment process-environment)
-        (python-shell-prompt-detect-enabled nil))
-    ;; Ensure no startup file is enabled
-    (should (not python-shell-prompt-detect-enabled))
-    (should (not (python-shell-prompt-detect)))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let ((process-environment process-environment)
+         (python-shell-prompt-detect-enabled nil))
+     ;; Ensure no startup file is enabled
+     (should (not python-shell-prompt-detect-enabled))
+     (should (not (python-shell-prompt-detect))))))
 
 (ert-deftest python-shell-prompt-detect-4 ()
   "Check warning is shown when detection fails."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (let* ((process-environment process-environment)
-         ;; Trigger failure by removing prompts in the startup file
-         (startup-code (concat "import sys\n"
-                               "sys.ps1 = ''\n"
-                               "sys.ps2 = ''\n"
-                               "sys.ps3 = ''\n"))
-         (startup-file (python-shell--save-temp-file startup-code)))
-    (unwind-protect
-        (progn
-          (kill-buffer (get-buffer-create "*Warnings*"))
-          (should (not (get-buffer "*Warnings*")))
-          (setenv "PYTHONSTARTUP" startup-file)
-          (should python-shell-prompt-detect-failure-warning)
-          (should python-shell-prompt-detect-enabled)
-          (should (not (python-shell-prompt-detect)))
-          (should (get-buffer "*Warnings*")))
-      (ignore-errors (delete-file startup-file)))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let* ((process-environment process-environment)
+          ;; Trigger failure by removing prompts in the startup file
+          (startup-code (concat "import sys\n"
+                                "sys.ps1 = ''\n"
+                                "sys.ps2 = ''\n"
+                                "sys.ps3 = ''\n"))
+          (startup-file (python-shell--save-temp-file startup-code)))
+     (unwind-protect
+         (progn
+           (kill-buffer (get-buffer-create "*Warnings*"))
+           (should (not (get-buffer "*Warnings*")))
+           (setenv "PYTHONSTARTUP" startup-file)
+           (should python-shell-prompt-detect-failure-warning)
+           (should python-shell-prompt-detect-enabled)
+           (should (not (python-shell-prompt-detect)))
+           (should (get-buffer "*Warnings*")))
+       (ignore-errors (delete-file startup-file))))))
 
 (ert-deftest python-shell-prompt-detect-5 ()
   "Check disabled warnings are not shown when detection fails."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (let* ((process-environment process-environment)
-         (startup-code (concat "import sys\n"
-                               "sys.ps1 = ''\n"
-                               "sys.ps2 = ''\n"
-                               "sys.ps3 = ''\n"))
-         (startup-file (python-shell--save-temp-file startup-code))
-         (python-shell-prompt-detect-failure-warning nil))
-    (unwind-protect
-        (progn
-          (kill-buffer (get-buffer-create "*Warnings*"))
-          (should (not (get-buffer "*Warnings*")))
-          (setenv "PYTHONSTARTUP" startup-file)
-          (should (not python-shell-prompt-detect-failure-warning))
-          (should python-shell-prompt-detect-enabled)
-          (should (not (python-shell-prompt-detect)))
-          (should (not (get-buffer "*Warnings*"))))
-      (ignore-errors (delete-file startup-file)))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let* ((process-environment process-environment)
+          (startup-code (concat "import sys\n"
+                                "sys.ps1 = ''\n"
+                                "sys.ps2 = ''\n"
+                                "sys.ps3 = ''\n"))
+          (startup-file (python-shell--save-temp-file startup-code))
+          (python-shell-prompt-detect-failure-warning nil))
+     (unwind-protect
+         (progn
+           (kill-buffer (get-buffer-create "*Warnings*"))
+           (should (not (get-buffer "*Warnings*")))
+           (setenv "PYTHONSTARTUP" startup-file)
+           (should (not python-shell-prompt-detect-failure-warning))
+           (should python-shell-prompt-detect-enabled)
+           (should (not (python-shell-prompt-detect)))
+           (should (not (get-buffer "*Warnings*"))))
+       (ignore-errors (delete-file startup-file))))))
 
 (ert-deftest python-shell-prompt-detect-6 ()
   "Warnings are not shown when detection is disabled."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (let* ((process-environment process-environment)
-         (startup-code (concat "import sys\n"
-                               "sys.ps1 = ''\n"
-                               "sys.ps2 = ''\n"
-                               "sys.ps3 = ''\n"))
-         (startup-file (python-shell--save-temp-file startup-code))
-         (python-shell-prompt-detect-failure-warning t)
-         (python-shell-prompt-detect-enabled nil))
-    (unwind-protect
-        (progn
-          (kill-buffer (get-buffer-create "*Warnings*"))
-          (should (not (get-buffer "*Warnings*")))
-          (setenv "PYTHONSTARTUP" startup-file)
-          (should python-shell-prompt-detect-failure-warning)
-          (should (not python-shell-prompt-detect-enabled))
-          (should (not (python-shell-prompt-detect)))
-          (should (not (get-buffer "*Warnings*"))))
-      (ignore-errors (delete-file startup-file)))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let* ((process-environment process-environment)
+          (startup-code (concat "import sys\n"
+                                "sys.ps1 = ''\n"
+                                "sys.ps2 = ''\n"
+                                "sys.ps3 = ''\n"))
+          (startup-file (python-shell--save-temp-file startup-code))
+          (python-shell-prompt-detect-failure-warning t)
+          (python-shell-prompt-detect-enabled nil))
+     (unwind-protect
+         (progn
+           (kill-buffer (get-buffer-create "*Warnings*"))
+           (should (not (get-buffer "*Warnings*")))
+           (setenv "PYTHONSTARTUP" startup-file)
+           (should python-shell-prompt-detect-failure-warning)
+           (should (not python-shell-prompt-detect-enabled))
+           (should (not (python-shell-prompt-detect)))
+           (should (not (get-buffer "*Warnings*"))))
+       (ignore-errors (delete-file startup-file))))))
 
 (ert-deftest python-shell-prompt-validate-regexps-1 ()
   "Check `python-shell-prompt-input-regexps' are validated."
@@ -4444,32 +4488,32 @@ python-shell-prompt-set-calculated-regexps-5
 
 (ert-deftest python-shell-prompt-set-calculated-regexps-6 ()
   "Check detected prompts are included `regexp-quote'd."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (let* ((python-shell-prompt-input-regexps '(""))
-         (python-shell-prompt-output-regexps '(""))
-         (python-shell-prompt-regexp "")
-         (python-shell-prompt-block-regexp "")
-         (python-shell-prompt-pdb-regexp "")
-         (python-shell-prompt-output-regexp "")
-         (python-shell--prompt-calculated-input-regexp nil)
-         (python-shell--prompt-calculated-output-regexp nil)
-         (python-shell-prompt-detect-enabled t)
-         (python-shell-interpreter (python-tests-get-shell-interpreter))
-         (process-environment process-environment)
-         (startup-code (concat "import sys\n"
-                               "sys.ps1 = 'p.> '\n"
-                               "sys.ps2 = '..> '\n"
-                               "sys.ps3 = 'o.t '\n"))
-         (startup-file (python-shell--save-temp-file startup-code)))
-    (unwind-protect
-        (progn
-          (setenv "PYTHONSTARTUP" startup-file)
-          (python-shell-prompt-set-calculated-regexps)
-          (should (string= python-shell--prompt-calculated-input-regexp
-                           "^\\(\\.\\.> \\|p\\.> \\|\\)"))
-          (should (string= python-shell--prompt-calculated-output-regexp
-                           "^\\(o\\.t \\|\\)")))
-      (ignore-errors (delete-file startup-file)))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let* ((python-shell-prompt-input-regexps '(""))
+          (python-shell-prompt-output-regexps '(""))
+          (python-shell-prompt-regexp "")
+          (python-shell-prompt-block-regexp "")
+          (python-shell-prompt-pdb-regexp "")
+          (python-shell-prompt-output-regexp "")
+          (python-shell--prompt-calculated-input-regexp nil)
+          (python-shell--prompt-calculated-output-regexp nil)
+          (python-shell-prompt-detect-enabled t)
+          (process-environment process-environment)
+          (startup-code (concat "import sys\n"
+                                "sys.ps1 = 'p.> '\n"
+                                "sys.ps2 = '..> '\n"
+                                "sys.ps3 = 'o.t '\n"))
+          (startup-file (python-shell--save-temp-file startup-code)))
+     (unwind-protect
+         (progn
+           (setenv "PYTHONSTARTUP" startup-file)
+           (python-shell-prompt-set-calculated-regexps)
+           (should (string= python-shell--prompt-calculated-input-regexp
+                            "^\\(\\.\\.> \\|p\\.> \\|\\)"))
+           (should (string= python-shell--prompt-calculated-output-regexp
+                            "^\\(o\\.t \\|\\)")))
+       (ignore-errors (delete-file startup-file))))))
 
 (ert-deftest python-shell-buffer-substring-1 ()
   "Selecting a substring of the whole buffer must match its contents."
@@ -4828,8 +4872,8 @@ python-shell-completion-native-interpreter-disabled-p-1
     (should (python-shell-completion-native-interpreter-disabled-p))))
 
 (ert-deftest python-shell-completion-at-point-1 ()
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)
    ""
    (python-shell-with-shell-buffer
      (skip-unless python-shell-readline-completer-delims)
@@ -4842,8 +4886,8 @@ python-shell-completion-at-point-1
      (should-not (nth 2 (python-shell-completion-at-point))))))
 
 (ert-deftest python-shell-completion-at-point-native-1 ()
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   nil
    ""
    (python-shell-completion-native-turn-on)
    (python-shell-with-shell-buffer
@@ -4928,25 +4972,25 @@ python-tests--pythonstartup-file
 
 (ert-deftest python-shell-completion-at-point-jedi-completer ()
   "Check if Python shell completion works when Jedi completer is used."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (with-environment-variables
-      (("PYTHONSTARTUP" (python-tests--pythonstartup-file)))
-    (python-tests-with-temp-buffer-with-shell
-     ""
-     (python-shell-with-shell-buffer
-       (skip-unless (string= python-shell-readline-completer-delims ""))
-       (python-shell-completion-native-turn-off)
-       (python-tests--completion-module)
-       (python-tests--completion-parameters)
-       (python-shell-completion-native-turn-on)
-       (python-tests--completion-module)
-       (python-tests--completion-parameters)
-       (python-tests--completion-extra-context)))))
+  (python-tests-with-shell-interpreter
+   nil
+   (with-environment-variables
+       (("PYTHONSTARTUP" (python-tests--pythonstartup-file)))
+     (python-tests-with-temp-buffer-with-shell
+      ""
+      (python-shell-with-shell-buffer
+        (skip-unless (string= python-shell-readline-completer-delims ""))
+        (python-shell-completion-native-turn-off)
+        (python-tests--completion-module)
+        (python-tests--completion-parameters)
+        (python-shell-completion-native-turn-on)
+        (python-tests--completion-module)
+        (python-tests--completion-parameters)
+        (python-tests--completion-extra-context))))))
 
 (ert-deftest python-shell-completion-at-point-ipython ()
   "Check if Python shell completion works for IPython."
-  (let ((python-tests-shell-interpreter "ipython")
-        (python-shell-interpreter "ipython")
+  (let ((python-shell-interpreter "ipython")
         (python-shell-interpreter-args "-i --simple-prompt"))
     (skip-unless
      (and
@@ -4973,8 +5017,8 @@ python-shell-completion-at-point-ipython
 ;;; Symbol completion
 
 (ert-deftest python-completion-at-point-1 ()
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)
    "
 import abc
 "
@@ -4991,8 +5035,8 @@ python-completion-at-point-1
 
 (ert-deftest python-completion-at-point-2 ()
   "Should work regardless of the point in the Shell buffer."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)
    "
 import abc
 "
@@ -5009,8 +5053,8 @@ python-completion-at-point-2
 
 (ert-deftest python-completion-at-point-pdb-1 ()
   "Should not complete PDB commands in Python buffer."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   nil
    "
 import pdb
 
@@ -5028,8 +5072,8 @@ python-completion-at-point-pdb-1
 
 (ert-deftest python-completion-at-point-while-running-1 ()
   "Should not try to complete when a program is running in the Shell buffer."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   nil
    "
 import time
 
@@ -5044,8 +5088,8 @@ python-completion-at-point-while-running-1
      (should-not (with-timeout (1 t) (completion-at-point))))))
 
 (ert-deftest python-completion-at-point-native-1 ()
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)
    "
 import abc
 "
@@ -5063,8 +5107,8 @@ python-completion-at-point-native-1
 
 (ert-deftest python-completion-at-point-native-2 ()
   "Should work regardless of the point in the Shell buffer."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)
    "
 import abc
 "
@@ -5081,8 +5125,8 @@ python-completion-at-point-native-2
      (should (completion-at-point)))))
 
 (ert-deftest python-completion-at-point-native-with-ffap-1 ()
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)
    "
 import abc
 "
@@ -5099,8 +5143,8 @@ python-completion-at-point-native-with-ffap-1
      (should (completion-at-point)))))
 
 (ert-deftest python-completion-at-point-native-with-eldoc-1 ()
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)
    "
 import abc
 "
@@ -5126,8 +5170,8 @@ python-completion-at-point-native-with-eldoc-1
 ;;; FFAP
 
 (ert-deftest python-ffap-module-path-1 ()
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   nil
    "
 import abc
 "
@@ -5138,8 +5182,8 @@ python-ffap-module-path-1
 
 (ert-deftest python-ffap-module-path-while-running-1 ()
   "Should not get module path when a program is running in the Shell buffer."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   nil
    "
 import abc
 import time
@@ -5214,8 +5258,8 @@ python-eldoc--get-symbol-at-point-4
                     "some_symbol"))))
 
 (ert-deftest python-eldoc--get-doc-at-point-1 ()
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   nil
    "
 import time
 "
@@ -5227,8 +5271,8 @@ python-eldoc--get-doc-at-point-1
 
 (ert-deftest python-eldoc--get-doc-at-point-while-running-1 ()
   "Should not get documentation when a program is running in the Shell buffer."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   nil
    "
 import time
 
@@ -7445,18 +7489,18 @@ python-tests--python-nav-end-of-statement--infloop
 ;; interpreter.
 (ert-deftest python-tests--run-python-selects-window ()
   "Test for bug#31398.  See also bug#44421 and bug#52380."
-  (skip-unless (python-tests-get-shell-interpreter))
-  (let* ((python-shell-interpreter (python-tests-get-shell-interpreter))
-         (buffer (process-buffer (run-python nil nil 'show)))
-         (window (get-buffer-window buffer)))
-    ;; We look at `selected-window' rather than `current-buffer'
-    ;; because as `(elisp)Current buffer' says, the latter will only
-    ;; be synchronized with the former when returning to the "command
-    ;; loop"; until then, `current-buffer' can change arbitrarily.
-    (should (eq window (selected-window)))
-    (pop-to-buffer (other-buffer))
-    (run-python nil nil 'show)
-    (should (eq window (selected-window)))))
+  (python-tests-with-shell-interpreter
+   nil
+   (let* ((buffer (process-buffer (run-python nil nil 'show)))
+          (window (get-buffer-window buffer)))
+     ;; We look at `selected-window' rather than `current-buffer'
+     ;; because as `(elisp)Current buffer' says, the latter will only
+     ;; be synchronized with the former when returning to the "command
+     ;; loop"; until then, `current-buffer' can change arbitrarily.
+     (should (eq window (selected-window)))
+     (pop-to-buffer (other-buffer))
+     (run-python nil nil 'show)
+     (should (eq window (selected-window))))))
 
 (ert-deftest python-tests--fill-long-first-line ()
   (should
@@ -7517,31 +7561,31 @@ python-tests--flymake-command-output-pattern
                        "W0611: Unused import a.b.c (unused-import)"))))))
 
 (ert-deftest python-test--shell-send-block ()
-  (skip-unless (python-tests-get-shell-interpreter))
-  (python-tests-with-temp-buffer-with-shell
-    "print('current 0')
+  (python-tests-with-temp-buffer-with-shell-interpreter
+   nil
+   "print('current 0')
 for x in range(1,3):
     print('current %s' % x)
 print('current 3')"
-    (goto-char (point-min))
-    (should-error (python-shell-send-block) :type 'user-error)
-    (forward-line)
-    (python-shell-send-block t) ;; send block with header
-    (python-tests-shell-wait-for-prompt)
-    (python-shell-with-shell-buffer
-      (goto-char (point-min))
-      (should-not (re-search-forward "current 0" nil t))
-      (should (re-search-forward "current 1" nil t))
-      (should (re-search-forward "current 2" nil t))
-      (should-not (re-search-forward "current 3" nil t)))
-    (forward-line)
-    (python-shell-send-block) ;; send block body only
-    (python-tests-shell-wait-for-prompt)
-    (python-shell-with-shell-buffer
-      ;; should only 1 line output from the block body
-      (should (re-search-forward "current"))
-      (should (looking-at " 2"))
-      (should-not (re-search-forward "current" nil t)))))
+   (goto-char (point-min))
+   (should-error (python-shell-send-block) :type 'user-error)
+   (forward-line)
+   (python-shell-send-block t) ;; send block with header
+   (python-tests-shell-wait-for-prompt)
+   (python-shell-with-shell-buffer
+     (goto-char (point-min))
+     (should-not (re-search-forward "current 0" nil t))
+     (should (re-search-forward "current 1" nil t))
+     (should (re-search-forward "current 2" nil t))
+     (should-not (re-search-forward "current 3" nil t)))
+   (forward-line)
+   (python-shell-send-block) ;; send block body only
+   (python-tests-shell-wait-for-prompt)
+   (python-shell-with-shell-buffer
+     ;; should only 1 line output from the block body
+     (should (re-search-forward "current"))
+     (should (looking-at " 2"))
+     (should-not (re-search-forward "current" nil t)))))
 
 ;;; python-ts-mode font-lock tests
 
-- 
2.34.1


  reply	other threads:[~2024-06-04 14:29 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-07  6:53 bug#70815: [PATCH] ; Enahnce python-tests.el to adapt different python interpreters Lin Sun
2024-05-11  9:05 ` Eli Zaretskii
2024-05-11 13:37   ` kobarity
2024-05-11 14:27     ` Lin Sun
2024-05-12  2:06       ` kobarity
2024-05-18 22:20 ` Stefan Kangas
2024-05-19  5:54   ` Eli Zaretskii
2024-05-20  0:08     ` Lin Sun
2024-05-20 15:52       ` kobarity
2024-05-20 17:51         ` Lin Sun
2024-05-21 14:04           ` kobarity
2024-05-21 15:34             ` Lin Sun
2024-05-22 14:38               ` kobarity
2024-05-23 13:09                 ` Eli Zaretskii
2024-05-26 10:52 ` Mattias Engdegård
2024-05-26 12:05   ` kobarity
2024-05-26 12:21     ` Mattias Engdegård
2024-05-26 12:36       ` kobarity
2024-05-26 13:23         ` Mattias Engdegård
2024-05-26 14:15           ` kobarity
2024-05-26 15:00             ` kobarity
2024-05-26 15:24               ` Mattias Engdegård
2024-05-27 12:33                 ` kobarity
2024-05-27 12:45                   ` Eli Zaretskii
2024-05-28 12:30                   ` Mattias Engdegård
2024-05-28 15:17                     ` kobarity
2024-05-28 16:09                       ` Mattias Engdegård
2024-05-29 14:56                         ` kobarity
2024-05-30 10:09                           ` Mattias Engdegård
2024-06-02 13:20                             ` kobarity
2024-06-03 14:02                               ` Mattias Engdegård
2024-06-03 14:34                                 ` kobarity
2024-06-03 16:24                                   ` kobarity
2024-06-04 14:29                                     ` kobarity [this message]
2024-06-05 10:25                                       ` Mattias Engdegård
2024-06-05 11:52                                         ` kobarity
2024-06-08 15:34                                           ` kobarity
2024-06-09 13:58                                             ` Mattias Engdegård
2024-06-10 14:57                                               ` kobarity
2024-06-10 15:44                                                 ` Mattias Engdegård
2024-05-26 15:56             ` Eli Zaretskii
2024-05-26 23:06               ` Stefan Kangas
2024-05-27 11:18                 ` Eli Zaretskii
2024-05-27 12:20                   ` Mattias Engdegård
2024-05-27 12:43                     ` Eli Zaretskii
2024-05-26 15:52           ` Eli Zaretskii
2024-05-27 10:24             ` Mattias Engdegård
2024-05-27 11:19               ` Lin Sun
2024-05-26 15:36   ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=eke7h6e8aihr.wl-kobarity@gmail.com \
    --to=kobarity@gmail.com \
    --cc=70815@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=mattias.engdegard@gmail.com \
    --cc=stefankangas@gmail.com \
    --cc=sunlin7.mail@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.