]> granicus.if.org Git - python/commitdiff
Issue #8716: Instead of relying on Aqua Tk exceptions to detect lack of
authorNed Deily <nad@acm.org>
Wed, 6 Jul 2011 02:08:38 +0000 (19:08 -0700)
committerNed Deily <nad@acm.org>
Wed, 6 Jul 2011 02:08:38 +0000 (19:08 -0700)
OS X window manager connection in tk tests, use OS X Application Services
API calls instead.

Lib/lib-tk/test/runtktests.py

index 19769adac72a72c99c9a978c06b5f616721c3099..95e1728861938980fdd816ac1075ecdd25aba949 100644 (file)
@@ -10,41 +10,51 @@ import os
 import sys
 import unittest
 import importlib
-import subprocess
 import test.test_support
 
 this_dir_path = os.path.abspath(os.path.dirname(__file__))
 
-_tk_available = None
+_tk_unavailable = None
 
 def check_tk_availability():
     """Check that Tk is installed and available."""
-    global _tk_available
-
-    if _tk_available is not None:
-        return
-
-    if sys.platform == 'darwin':
-        # The Aqua Tk implementations on OS X can abort the process if
-        # being called in an environment where a window server connection
-        # cannot be made, for instance when invoked by a buildbot or ssh
-        # process not running under the same user id as the current console
-        # user.  Instead, try to initialize Tk under a subprocess.
-        p = subprocess.Popen(
-                [sys.executable, '-c', 'import Tkinter; Tkinter.Button()'],
-                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        stderr = test.test_support.strip_python_stderr(p.communicate()[1])
-        if stderr or p.returncode:
-            raise unittest.SkipTest("tk cannot be initialized: %s" % stderr)
-    else:
-        import Tkinter
-        try:
-            Tkinter.Button()
-        except Tkinter.TclError as msg:
-            # assuming tk is not available
-            raise unittest.SkipTest("tk not available: %s" % msg)
-
-    _tk_available = True
+    global _tk_unavailable
+
+    if _tk_unavailable is None:
+        _tk_unavailable = False
+        if sys.platform == 'darwin':
+            # The Aqua Tk implementations on OS X can abort the process if
+            # being called in an environment where a window server connection
+            # cannot be made, for instance when invoked by a buildbot or ssh
+            # process not running under the same user id as the current console
+            # user.  To avoid that, raise an exception if the window manager
+            # connection is not available.
+            from ctypes import cdll, c_int, pointer, Structure
+            from ctypes.util import find_library
+
+            app_services = cdll.LoadLibrary(find_library("ApplicationServices"))
+
+            if app_services.CGMainDisplayID() == 0:
+                _tk_unavailable = "cannot run without OS X window manager"
+            else:
+                class ProcessSerialNumber(Structure):
+                    _fields_ = [("highLongOfPSN", c_int),
+                                ("lowLongOfPSN", c_int)]
+                psn = ProcessSerialNumber()
+                psn_p = pointer(psn)
+                if (  (app_services.GetCurrentProcess(psn_p) < 0) or
+                      (app_services.SetFrontProcess(psn_p) < 0) ):
+                    _tk_unavailable = "cannot run without OS X gui process"
+        else:   # not OS X
+            import Tkinter
+            try:
+                Tkinter.Button()
+            except Tkinter.TclError as msg:
+                # assuming tk is not available
+                _tk_unavailable = "tk not available: %s" % msg
+
+    if _tk_unavailable:
+        raise unittest.SkipTest(_tk_unavailable)
     return
 
 def is_package(path):