]> git.eshelyaron.com Git - emacs.git/commitdiff
Specify Python 3 in some ERTs on Mac
authorkobarity <kobarity@gmail.com>
Tue, 4 Jun 2024 12:51:32 +0000 (21:51 +0900)
committerEshel Yaron <me@eshelyaron.com>
Mon, 10 Jun 2024 07:26:22 +0000 (09:26 +0200)
* 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)

(cherry picked from commit bfb4c69e7f1b86e358e827f757b73161952aae3c)

test/lisp/progmodes/python-tests.el

index a48c6152f962a09b9dd6fe6cf1070d13cf5adc5d..3a04550f071d7eedc203a7ab343e9a9627096c24 100644 (file)
@@ -59,8 +59,7 @@ turned off.  Shell buffer will be killed on exit."
   (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
@@ -3726,21 +3725,67 @@ if x:
 \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'."
@@ -4002,48 +4047,46 @@ If env string EMACS_PYTHON_INTERPRETER exists, use it as preferred one."
 
 (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.
@@ -4075,58 +4118,56 @@ and `python-shell-interpreter-args' in the new shell buffer."
 
 (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
@@ -4150,131 +4191,134 @@ and `python-shell-interpreter-args' in the new shell buffer."
             ;; 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."
@@ -4420,32 +4464,32 @@ and `python-shell-interpreter-args' in the new shell buffer."
 
 (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."
@@ -4804,8 +4848,8 @@ def foo():
     (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)
@@ -4818,8 +4862,8 @@ def foo():
      (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
@@ -4904,25 +4948,25 @@ def foo():
 
 (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
@@ -4949,8 +4993,8 @@ def foo():
 ;;; 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
 "
@@ -4967,8 +5011,8 @@ import abc
 
 (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
 "
@@ -4985,8 +5029,8 @@ import abc
 
 (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
 
@@ -5004,8 +5048,8 @@ print('Hello')
 
 (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
 
@@ -5020,8 +5064,8 @@ time.sleep(3)
      (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
 "
@@ -5039,8 +5083,8 @@ import abc
 
 (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
 "
@@ -5057,8 +5101,8 @@ import abc
      (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
 "
@@ -5075,8 +5119,8 @@ import abc
      (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
 "
@@ -5102,8 +5146,8 @@ import abc
 ;;; 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
 "
@@ -5114,8 +5158,8 @@ import abc
 
 (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
@@ -5190,8 +5234,8 @@ some_symbol   some_other_symbol
                     "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
 "
@@ -5203,8 +5247,8 @@ import time
 
 (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
 
@@ -7439,18 +7483,18 @@ buffer with overlapping strings."
 ;; 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
@@ -7511,31 +7555,31 @@ buffer with overlapping strings."
                        "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