()
| 225 | |
| 226 | # Check whether a gui is actually available |
| 227 | def _is_gui_available(): |
| 228 | if hasattr(_is_gui_available, 'result'): |
| 229 | return _is_gui_available.result |
| 230 | import platform |
| 231 | reason = None |
| 232 | if sys.platform.startswith('win') and platform.win32_is_iot(): |
| 233 | reason = "gui is not available on Windows IoT Core" |
| 234 | elif sys.platform.startswith('win'): |
| 235 | # if Python is running as a service (such as the buildbot service), |
| 236 | # gui interaction may be disallowed |
| 237 | import ctypes |
| 238 | import ctypes.wintypes |
| 239 | UOI_FLAGS = 1 |
| 240 | WSF_VISIBLE = 0x0001 |
| 241 | class USEROBJECTFLAGS(ctypes.Structure): |
| 242 | _fields_ = [("fInherit", ctypes.wintypes.BOOL), |
| 243 | ("fReserved", ctypes.wintypes.BOOL), |
| 244 | ("dwFlags", ctypes.wintypes.DWORD)] |
| 245 | dll = ctypes.windll.user32 |
| 246 | h = dll.GetProcessWindowStation() |
| 247 | if not h: |
| 248 | raise ctypes.WinError() |
| 249 | uof = USEROBJECTFLAGS() |
| 250 | needed = ctypes.wintypes.DWORD() |
| 251 | res = dll.GetUserObjectInformationW(h, |
| 252 | UOI_FLAGS, |
| 253 | ctypes.byref(uof), |
| 254 | ctypes.sizeof(uof), |
| 255 | ctypes.byref(needed)) |
| 256 | if not res: |
| 257 | raise ctypes.WinError() |
| 258 | if not bool(uof.dwFlags & WSF_VISIBLE): |
| 259 | reason = "gui not available (WSF_VISIBLE flag not set)" |
| 260 | elif sys.platform == 'darwin': |
| 261 | # The Aqua Tk implementations on OS X can abort the process if |
| 262 | # being called in an environment where a window server connection |
| 263 | # cannot be made, for instance when invoked by a buildbot or ssh |
| 264 | # process not running under the same user id as the current console |
| 265 | # user. To avoid that, raise an exception if the window manager |
| 266 | # connection is not available. |
| 267 | import subprocess |
| 268 | try: |
| 269 | rc = subprocess.run(["launchctl", "managername"], |
| 270 | capture_output=True, check=True) |
| 271 | managername = rc.stdout.decode("utf-8").strip() |
| 272 | except subprocess.CalledProcessError: |
| 273 | reason = "unable to detect macOS launchd job manager" |
| 274 | else: |
| 275 | if managername != "Aqua": |
| 276 | reason = f"{managername=} -- can only run in a macOS GUI session" |
| 277 | |
| 278 | # check on every platform whether tkinter can actually do anything |
| 279 | if not reason: |
| 280 | try: |
| 281 | from tkinter import Tk |
| 282 | root = Tk() |
| 283 | root.withdraw() |
| 284 | root.update() |
no test coverage detected
searching dependent graphs…