From e7e40853ea7f310aab50f223ecf17fe7cbf123e8 Mon Sep 17 00:00:00 2001
From: kobarity <kobarity@gmail.com>
Date: Sun, 2 Jun 2024 22:14:07 +0900
Subject: [PATCH] Specify Python 3 in some ERTs on Mac

* test/lisp/progmodes/python-tests.el (cl-extra): Remove
require.
(python-tests-shell-interpreter): Removed.
(python-tests-shell-interpreters): New variable.
(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-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): Specify
Python 3 on Mac to avoid errors.  (Bug#70815)
---
 test/lisp/progmodes/python-tests.el | 76 ++++++++++++++++++++---------
 1 file changed, 54 insertions(+), 22 deletions(-)

diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index b06547b10ff..970ec32bc0c 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -3750,21 +3750,47 @@ python-bob-infloop-avoid
 
 ;;; Shell integration
 
-(defvar python-tests-shell-interpreter nil)
+(defvar python-tests-shell-interpreters nil
+  "List of Python interpreter information.
+Set this variable to nil to rescan interpreters.")
 
-(defun python-tests-get-shell-interpreter ()
+(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'."
@@ -4828,7 +4854,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))
+  (skip-unless (python-tests-get-shell-interpreter
+                (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)))
   (python-tests-with-temp-buffer-with-shell
    ""
    (python-shell-with-shell-buffer
@@ -4945,8 +4972,7 @@ python-shell-completion-at-point-jedi-completer
 
 (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,7 +4999,8 @@ python-shell-completion-at-point-ipython
 ;;; Symbol completion
 
 (ert-deftest python-completion-at-point-1 ()
-  (skip-unless (python-tests-get-shell-interpreter))
+  (skip-unless (python-tests-get-shell-interpreter
+                (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)))
   (python-tests-with-temp-buffer-with-shell
    "
 import abc
@@ -4991,7 +5018,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))
+  (skip-unless (python-tests-get-shell-interpreter
+                (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)))
   (python-tests-with-temp-buffer-with-shell
    "
 import abc
@@ -5044,7 +5072,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))
+  (skip-unless (python-tests-get-shell-interpreter
+                (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)))
   (python-tests-with-temp-buffer-with-shell
    "
 import abc
@@ -5063,7 +5092,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))
+  (skip-unless (python-tests-get-shell-interpreter
+                (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)))
   (python-tests-with-temp-buffer-with-shell
    "
 import abc
@@ -5081,7 +5111,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))
+  (skip-unless (python-tests-get-shell-interpreter
+                (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)))
   (python-tests-with-temp-buffer-with-shell
    "
 import abc
@@ -5099,7 +5130,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))
+  (skip-unless (python-tests-get-shell-interpreter
+                (when (eq system-type 'darwin) #'python-tests-interpreter-3-p)))
   (python-tests-with-temp-buffer-with-shell
    "
 import abc
-- 
2.34.1

