Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f6cbdc2

Browse files
committed
Issue #8716: Instead of relying on Aqua Tk exceptions to detect lack of
OS X window manager connection in tk tests, use OS X Application Services API calls instead.
1 parent 1848db8 commit f6cbdc2

1 file changed

Lines changed: 35 additions & 25 deletions

File tree

Lib/tkinter/test/support.py

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,48 @@
1-
import subprocess
21
import sys
3-
from test import support
42
import tkinter
53
import unittest
64

7-
_tk_available = None
5+
_tk_unavailable = None
86

97
def check_tk_availability():
108
"""Check that Tk is installed and available."""
11-
global _tk_available
9+
global _tk_unavailable
1210

13-
if _tk_available is not None:
14-
return
11+
if _tk_unavailable is None:
12+
_tk_unavailable = False
13+
if sys.platform == 'darwin':
14+
# The Aqua Tk implementations on OS X can abort the process if
15+
# being called in an environment where a window server connection
16+
# cannot be made, for instance when invoked by a buildbot or ssh
17+
# process not running under the same user id as the current console
18+
# user. To avoid that, raise an exception if the window manager
19+
# connection is not available.
20+
from ctypes import cdll, c_int, pointer, Structure
21+
from ctypes.util import find_library
1522

16-
if sys.platform == 'darwin':
17-
# The Aqua Tk implementations on OS X can abort the process if
18-
# being called in an environment where a window server connection
19-
# cannot be made, for instance when invoked by a buildbot or ssh
20-
# process not running under the same user id as the current console
21-
# user. Instead, try to initialize Tk under a subprocess.
22-
p = subprocess.Popen(
23-
[sys.executable, '-c', 'import tkinter; tkinter.Button()'],
24-
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
25-
stderr = support.strip_python_stderr(p.communicate()[1])
26-
if stderr or p.returncode:
27-
raise unittest.SkipTest("tk cannot be initialized: %s" % stderr)
28-
else:
29-
try:
30-
tkinter.Button()
31-
except tkinter.TclError as msg:
32-
# assuming tk is not available
33-
raise unittest.SkipTest("tk not available: %s" % msg)
23+
app_services = cdll.LoadLibrary(find_library("ApplicationServices"))
3424

35-
_tk_available = True
25+
if app_services.CGMainDisplayID() == 0:
26+
_tk_unavailable = "cannot run without OS X window manager"
27+
else:
28+
class ProcessSerialNumber(Structure):
29+
_fields_ = [("highLongOfPSN", c_int),
30+
("lowLongOfPSN", c_int)]
31+
psn = ProcessSerialNumber()
32+
psn_p = pointer(psn)
33+
if ( (app_services.GetCurrentProcess(psn_p) < 0) or
34+
(app_services.SetFrontProcess(psn_p) < 0) ):
35+
_tk_unavailable = "cannot run without OS X gui process"
36+
else: # not OS X
37+
import tkinter
38+
try:
39+
tkinter.Button()
40+
except tkinter.TclError as msg:
41+
# assuming tk is not available
42+
_tk_unavailable = "tk not available: %s" % msg
43+
44+
if _tk_unavailable:
45+
raise unittest.SkipTest(_tk_unavailable)
3646
return
3747

3848
def get_tk_root():

0 commit comments

Comments
 (0)