Coverage for pyTooling/Platform/__init__.py: 79%
281 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-06 22:21 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-06 22:21 +0000
1# ==================================================================================================================== #
2# _____ _ _ ____ _ _ __ #
3# _ __ _ |_ _|__ ___ | (_)_ __ __ _ | _ \| | __ _| |_ / _| ___ _ __ _ __ ___ #
4# | '_ \| | | || |/ _ \ / _ \| | | '_ \ / _` | | |_) | |/ _` | __| |_ / _ \| '__| '_ ` _ \ #
5# | |_) | |_| || | (_) | (_) | | | | | | (_| |_| __/| | (_| | |_| _| (_) | | | | | | | | #
6# | .__/ \__, ||_|\___/ \___/|_|_|_| |_|\__, (_)_| |_|\__,_|\__|_| \___/|_| |_| |_| |_| #
7# |_| |___/ |___/ #
8# ==================================================================================================================== #
9# Authors: #
10# Patrick Lehmann #
11# #
12# License: #
13# ==================================================================================================================== #
14# Copyright 2017-2025 Patrick Lehmann - Bötzingen, Germany #
15# #
16# Licensed under the Apache License, Version 2.0 (the "License"); #
17# you may not use this file except in compliance with the License. #
18# You may obtain a copy of the License at #
19# #
20# http://www.apache.org/licenses/LICENSE-2.0 #
21# #
22# Unless required by applicable law or agreed to in writing, software #
23# distributed under the License is distributed on an "AS IS" BASIS, #
24# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
25# See the License for the specific language governing permissions and #
26# limitations under the License. #
27# #
28# SPDX-License-Identifier: Apache-2.0 #
29# ==================================================================================================================== #
30#
31"""
32Common platform information gathered from various sources.
34.. hint:: See :ref:`high-level help <COMMON/Platform>` for explanations and usage examples.
35"""
36from enum import Flag, auto
38try:
39 from pyTooling.Decorators import export, readonly
40 from pyTooling.Exceptions import ToolingException
41 from pyTooling.MetaClasses import ExtendedType
42 from pyTooling.Versioning import PythonVersion
43except (ImportError, ModuleNotFoundError): # pragma: no cover
44 print("[pyTooling.Platform] Could not import from 'pyTooling.*'!")
46 try:
47 from Decorators import export, readonly
48 from Exceptions import ToolingException
49 from MetaClasses import ExtendedType
50 from Versioning import PythonVersion
51 except (ImportError, ModuleNotFoundError) as ex: # pragma: no cover
52 print("[pyTooling.Platform] Could not import directly!")
53 raise ex
56__all__ = ["CurrentPlatform"]
59@export
60class PlatformException(ToolingException):
61 """Base-exception of all exceptions raised by :mod:`pyTooling.Platform`."""
64@export
65class UnknownPlatformException(PlatformException):
66 """
67 The exception is raised by pyTooling.Platform when the platform can't be determined.
69 For debugging purposes, a list of system properties from various APIs is added as notes to this exception to ease
70 debugging unknown or new platforms.
71 """
73 def __init__(self, *args) -> None:
74 """
75 Initialize a new :class:`UnknownPlatformException` instance and add notes with further debugging information.
77 :param args: Forward positional parameters.
78 """
79 super().__init__(*args)
81 import sys
82 import os
83 import platform
84 import sysconfig
86 self.add_note(f"os.name: {os.name}")
87 self.add_note(f"platform.system: {platform.system()}")
88 self.add_note(f"platform.machine: {platform.machine()}")
89 self.add_note(f"platform.architecture: {platform.architecture()}")
90 self.add_note(f"sys.platform: {sys.platform}")
91 self.add_note(f"sysconfig.get_platform: {sysconfig.get_platform()}")
94@export
95class UnknownOperatingSystemException(PlatformException):
96 """The exception is raised by pyTooling.Platform when the operating system is unknown."""
99@export
100class PythonImplementation(Flag):
101 Unknown = 0
103 CPython = 1
104 PyPy = 2
107@export
108class Platforms(Flag):
109 Unknown = 0
111 OS_FreeBSD = auto() #: Operating System: BSD (Unix).
112 OS_Linux = auto() #: Operating System: Linux.
113 OS_MacOS = auto() #: Operating System: macOS.
114 OS_Windows = auto() #: Operating System: Windows.
116 OperatingSystem = OS_FreeBSD | OS_Linux | OS_MacOS | OS_Windows #: Mask: Any operating system.
118 SEP_WindowsPath = auto() #: Seperator: Path element seperator (e.g. for directories).
119 SEP_WindowsValue = auto() #: Seperator: Value seperator in variables (e.g. for paths in PATH).
121 ENV_Native = auto() #: Environment: :term:`native`.
122 ENV_WSL = auto() #: Environment: :term:`Windows System for Linux <WSL>`.
123 ENV_MSYS2 = auto() #: Environment: :term:`MSYS2`.
124 ENV_Cygwin = auto() #: Environment: :term:`Cygwin`.
126 Environment = ENV_Native | ENV_WSL | ENV_MSYS2 | ENV_Cygwin #: Mask: Any environment.
128 ARCH_x86_32 = auto() #: Architecture: x86-32 (IA32).
129 ARCH_x86_64 = auto() #: Architecture: x86-64 (AMD64).
130 ARCH_AArch64 = auto() #: Architecture: AArch64 (arm64).
132 Arch_x86 = ARCH_x86_32 | ARCH_x86_64 #: Mask: Any x86 architecture.
133 Arch_Arm = ARCH_AArch64 #: Mask: Any Arm architecture.
134 Architecture = Arch_x86 | Arch_Arm #: Mask: Any architecture.
136 FreeBSD = OS_FreeBSD | ENV_Native | ARCH_x86_64 #: Group: native FreeBSD on x86-64.
137 Linux = OS_Linux | ENV_Native | ARCH_x86_64 #: Group: native Linux on x86-64.
138 MacOS = OS_MacOS | ENV_Native #: Group: native macOS.
139 Windows = OS_Windows | ENV_Native | ARCH_x86_64 | SEP_WindowsPath | SEP_WindowsValue #: Group: native Windows on x86-64.
141 MacOS_Intel = MacOS | ARCH_x86_64 #: Group: native macOS on x86-64.
142 MacOS_ARM = MacOS | ARCH_AArch64 #: Group: native macOS on aarch64.
144 MSYS = auto() #: MSYS2 Runtime: MSYS.
145 MinGW32 = auto() #: MSYS2 Runtime: :term:`MinGW32 <MinGW>`.
146 MinGW64 = auto() #: MSYS2 Runtime: :term:`MinGW64 <MinGW>`.
147 UCRT64 = auto() #: MSYS2 Runtime: :term:`UCRT64 <UCRT>`.
148 Clang32 = auto() #: MSYS2 Runtime: Clang32.
149 Clang64 = auto() #: MSYS2 Runtime: Clang64.
151 MSYS2_Runtime = MSYS | MinGW32 | MinGW64 | UCRT64 | Clang32 | Clang64 #: Mask: Any MSYS2 runtime environment.
153 Windows_MSYS2_MSYS = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MSYS #: Group: MSYS runtime running on Windows x86-64
154 Windows_MSYS2_MinGW32 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MinGW32 #: Group: MinGW32 runtime running on Windows x86-64
155 Windows_MSYS2_MinGW64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MinGW64 #: Group: MinGW64 runtime running on Windows x86-64
156 Windows_MSYS2_UCRT64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | UCRT64 #: Group: UCRT64 runtime running on Windows x86-64
157 Windows_MSYS2_Clang32 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | Clang32 #: Group: Clang32 runtime running on Windows x86-64
158 Windows_MSYS2_Clang64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | Clang64 #: Group: Clang64 runtime running on Windows x86-64
160 Windows_Cygwin32 = OS_Windows | ENV_Cygwin | ARCH_x86_32 #: Group: 32-bit Cygwin runtime on Windows x86-64
161 Windows_Cygwin64 = OS_Windows | ENV_Cygwin | ARCH_x86_64 #: Group: 64-bit Cygwin runtime on Windows x86-64
164@export
165class Platform(metaclass=ExtendedType, singleton=True, slots=True):
166 """An instance of this class contains all gathered information available from various sources.
168 .. seealso::
170 StackOverflow question: `Python: What OS am I running on? <https://stackoverflow.com/a/54837707/3719459>`__
171 """
173 _platform: Platforms
174 _pythonImplementation: PythonImplementation
175 _pythonVersion: PythonVersion
177 def __init__(self) -> None:
178 import sys
179 import os
180 import platform
181 import sysconfig
183 # Discover the Python implementation
184 pythonImplementation = platform.python_implementation()
185 if pythonImplementation == "CPython":
186 self._pythonImplementation = PythonImplementation.CPython
187 elif pythonImplementation == "PyPy":
188 self._pythonImplementation = PythonImplementation.PyPy
189 else: # pragma: no cover
190 self._pythonImplementation = PythonImplementation.Unknown
192 # Discover the Python version
193 self._pythonVersion = PythonVersion.FromSysVersionInfo()
195 # Discover the platform
196 self._platform = Platforms.Unknown
198 machine = platform.machine()
199 sys_platform = sys.platform
200 sysconfig_platform = sysconfig.get_platform()
202 if os.name == "nt":
203 self._platform |= Platforms.OS_Windows
205 if sysconfig_platform == "win32": 205 ↛ 206line 205 didn't jump to line 206 because the condition on line 205 was never true
206 self._platform |= Platforms.ENV_Native | Platforms.ARCH_x86_32 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
207 elif sysconfig_platform == "win-amd64":
208 self._platform |= Platforms.ENV_Native | Platforms.ARCH_x86_64 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
209 elif sysconfig_platform.startswith("mingw"):
210 if machine == "AMD64":
211 self._platform |= Platforms.ARCH_x86_64
212 else: # pragma: no cover
213 raise UnknownPlatformException(f"Unknown architecture '{machine}' for Windows.")
215 if sysconfig_platform == "mingw_i686_msvcrt_gnu": 215 ↛ 216line 215 didn't jump to line 216 because the condition on line 215 was never true
216 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW32
217 elif sysconfig_platform == "mingw_x86_64_msvcrt_gnu":
218 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW64
219 elif sysconfig_platform == "mingw_x86_64_ucrt_gnu":
220 self._platform |= Platforms.ENV_MSYS2 | Platforms.UCRT64
221 elif sysconfig_platform == "mingw_x86_64_ucrt_llvm":
222 self._platform |= Platforms.ENV_MSYS2 | Platforms.Clang64
223 elif sysconfig_platform == "mingw_i686": # pragma: no cover
224 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW32
225 elif sysconfig_platform == "mingw_x86_64": # pragma: no cover
226 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW64
227 elif sysconfig_platform == "mingw_x86_64_ucrt": # pragma: no cover
228 self._platform |= Platforms.ENV_MSYS2 | Platforms.UCRT64
229 elif sysconfig_platform == "mingw_x86_64_clang": # pragma: no cover
230 self._platform |= Platforms.ENV_MSYS2 | Platforms.Clang64
231 else: # pragma: no cover
232 raise UnknownPlatformException(f"Unknown MSYS2 architecture '{sysconfig_platform}'.")
233 else: # pragma: no cover
234 raise UnknownPlatformException(f"Unknown platform '{sysconfig_platform}' running on Windows.")
236 elif os.name == "posix":
237 if sys_platform == "linux":
238 self._platform |= Platforms.OS_Linux | Platforms.ENV_Native
240 if sysconfig_platform == "linux-x86_64": # native Linux x86_64; Windows 64 + WSL 240 ↛ 242line 240 didn't jump to line 242 because the condition on line 240 was always true
241 self._platform |= Platforms.ARCH_x86_64
242 elif sysconfig_platform == "linux-aarch64": # native Linux Aarch64
243 self._platform |= Platforms.ARCH_AArch64
244 else: # pragma: no cover
245 raise UnknownPlatformException(f"Unknown architecture '{sysconfig_platform}' for a native Linux.")
247 elif sys_platform == "darwin": 247 ↛ 257line 247 didn't jump to line 257 because the condition on line 247 was always true
248 self._platform |= Platforms.OS_MacOS | Platforms.ENV_Native
250 if machine == "x86_64":
251 self._platform |= Platforms.ARCH_x86_64
252 elif machine == "arm64":
253 self._platform |= Platforms.ARCH_AArch64
254 else: # pragma: no cover
255 raise UnknownPlatformException(f"Unknown architecture '{machine}' for a native macOS.")
257 elif sys_platform == "msys":
258 self._platform |= Platforms.OS_Windows | Platforms.ENV_MSYS2 | Platforms.MSYS
260 if machine == "i686":
261 self._platform |= Platforms.ARCH_x86_32
262 elif machine == "x86_64":
263 self._platform |= Platforms.ARCH_x86_64
264 else: # pragma: no cover
265 raise UnknownPlatformException(f"Unknown architecture '{machine}' for MSYS2-MSYS on Windows.")
267 elif sys_platform == "cygwin":
268 self._platform |= Platforms.OS_Windows
270 if machine == "i686":
271 self._platform |= Platforms.ARCH_x86_32
272 elif machine == "x86_64":
273 self._platform |= Platforms.ARCH_x86_64
274 else: # pragma: no cover
275 raise UnknownPlatformException(f"Unknown architecture '{machine}' for Cygwin on Windows.")
277 elif sys_platform.startswith("freebsd"):
278 if machine == "amd64":
279 self._platform = Platforms.FreeBSD
280 else: # pragma: no cover
281 raise UnknownPlatformException(f"Unknown architecture '{machine}' for FreeBSD.")
282 else: # pragma: no cover
283 raise UnknownPlatformException(f"Unknown POSIX platform '{sys_platform}'.")
284 else: # pragma: no cover
285 raise UnknownPlatformException(f"Unknown operating system '{os.name}'.")
287 @readonly
288 def PythonImplementation(self) -> PythonImplementation:
289 return self._pythonImplementation
291 @readonly
292 def IsCPython(self) -> bool:
293 """Returns true, if the Python implementation is a :term:`CPython`.
295 :returns: ``True``, if the Python implementation is CPython.
296 """
297 return self._pythonImplementation is PythonImplementation.CPython
299 @readonly
300 def IsPyPy(self) -> bool:
301 """Returns true, if the Python implementation is a :term:`PyPy`.
303 :returns: ``True``, if the Python implementation is PyPY.
304 """
305 return self._pythonImplementation is PythonImplementation.PyPy
307 @readonly
308 def PythonVersion(self) -> PythonVersion:
309 return self._pythonVersion
311 @readonly
312 def HostOperatingSystem(self) -> Platforms:
313 return self._platform & Platforms.OperatingSystem
315 @readonly
316 def IsNativePlatform(self) -> bool:
317 """Returns true, if the platform is a :term:`native` platform.
319 :returns: ``True``, if the platform is a native platform.
320 """
321 return Platforms.ENV_Native in self._platform
323 @readonly
324 def IsNativeFreeBSD(self) -> bool:
325 """Returns true, if the platform is a :term:`native` FreeBSD x86-64 platform.
327 :returns: ``True``, if the platform is a native FreeBSD x86-64 platform.
328 """
329 return Platforms.FreeBSD in self._platform
331 @readonly
332 def IsNativeMacOS(self) -> bool:
333 """Returns true, if the platform is a :term:`native` macOS x86-64 platform.
335 :returns: ``True``, if the platform is a native macOS x86-64 platform.
336 """
337 return Platforms.MacOS in self._platform
339 @readonly
340 def IsNativeLinux(self) -> bool:
341 """Returns true, if the platform is a :term:`native` Linux x86-64 platform.
343 :returns: ``True``, if the platform is a native Linux x86-64 platform.
344 """
345 return Platforms.Linux in self._platform
347 @readonly
348 def IsNativeWindows(self) -> bool:
349 """Returns true, if the platform is a :term:`native` Windows x86-64 platform.
351 :returns: ``True``, if the platform is a native Windows x86-64 platform.
352 """
353 return Platforms.Windows in self._platform
355 @readonly
356 def IsMSYS2Environment(self) -> bool:
357 """Returns true, if the platform is a :term:`MSYS2` environment on Windows.
359 :returns: ``True``, if the platform is a MSYS2 environment on Windows.
360 """
361 return Platforms.ENV_MSYS2 in self._platform
363 @readonly
364 def IsMSYSOnWindows(self) -> bool:
365 """Returns true, if the platform is a MSYS runtime on Windows.
367 :returns: ``True``, if the platform is a MSYS runtime on Windows.
368 """
369 return Platforms.Windows_MSYS2_MSYS in self._platform
371 @readonly
372 def IsMinGW32OnWindows(self) -> bool:
373 """Returns true, if the platform is a :term:`MinGW32 <MinGW>` runtime on Windows.
375 :returns: ``True``, if the platform is a MINGW32 runtime on Windows.
376 """
377 return Platforms.Windows_MSYS2_MinGW32 in self._platform
379 @readonly
380 def IsMinGW64OnWindows(self) -> bool:
381 """Returns true, if the platform is a :term:`MinGW64 <MinGW>` runtime on Windows.
383 :returns: ``True``, if the platform is a MINGW64 runtime on Windows.
384 """
385 return Platforms.Windows_MSYS2_MinGW64 in self._platform
387 @readonly
388 def IsUCRT64OnWindows(self) -> bool:
389 """Returns true, if the platform is a :term:`UCRT64 <UCRT>` runtime on Windows.
391 :returns: ``True``, if the platform is a UCRT64 runtime on Windows.
392 """
393 return Platforms.Windows_MSYS2_UCRT64 in self._platform
395 @readonly
396 def IsClang32OnWindows(self) -> bool:
397 """Returns true, if the platform is a Clang32 runtime on Windows.
399 :returns: ``True``, if the platform is a Clang32 runtime on Windows.
400 """
401 return Platforms.Windows_MSYS2_Clang32 in self._platform
403 @readonly
404 def IsClang64OnWindows(self) -> bool:
405 """Returns true, if the platform is a Clang64 runtime on Windows.
407 :returns: ``True``, if the platform is a Clang64 runtime on Windows.
408 """
409 return Platforms.Windows_MSYS2_Clang64 in self._platform
411 @readonly
412 def IsCygwin32OnWindows(self) -> bool:
413 """Returns true, if the platform is a 32-bit Cygwin runtime on Windows.
415 :returns: ``True``, if the platform is a 32-bit Cygwin runtime on Windows.
416 """
417 return Platforms.Windows_Cygwin32 in self._platform
419 @readonly
420 def IsCygwin64OnWindows(self) -> bool:
421 """Returns true, if the platform is a 64-bit Cygwin runtime on Windows.
423 :returns: ``True``, if the platform is a 64-bit Cygwin runtime on Windows.
424 """
425 return Platforms.Windows_Cygwin64 in self._platform
427 @readonly
428 def IsPOSIX(self) -> bool:
429 """
430 Returns true, if the platform is POSIX or POSIX-like.
432 :returns: ``True``, if POSIX or POSIX-like.
433 """
434 return Platforms.SEP_WindowsPath not in self._platform
436 @readonly
437 def PathSeperator(self) -> str:
438 """
439 Returns the path element separation character (e.g. for directories).
441 * POSIX-like: ``/``
442 * Windows: ``\\``
444 :returns: Path separation character.
445 """
446 if Platforms.SEP_WindowsPath in self._platform:
447 return "\\"
448 else:
449 return "/"
451 @readonly
452 def ValueSeperator(self) -> str:
453 """
454 Returns the value separation character (e.g. for paths in PATH).
456 * POSIX-like: ``:``
457 * Windows: ``;``
459 :returns: Value separation character.
460 """
461 if Platforms.SEP_WindowsValue in self._platform:
462 return ";"
463 else:
464 return ":"
466 @readonly
467 def ExecutableExtension(self) -> str:
468 """
469 Returns the file extension for an executable.
471 * FreeBSD: ``""`` (empty string)
472 * Linux: ``""`` (empty string)
473 * macOS: ``""`` (empty string)
474 * Windows: ``"exe"``
476 :returns: File extension of an executable.
477 :raises UnknownOperatingSystemException: If the operating system is unknown.
478 """
480 if Platforms.OS_FreeBSD in self._platform: 480 ↛ 481line 480 didn't jump to line 481 because the condition on line 480 was never true
481 return ""
482 elif Platforms.OS_Linux in self._platform:
483 return ""
484 elif Platforms.OS_MacOS in self._platform:
485 return ""
486 elif Platforms.OS_Windows in self._platform:
487 return "exe"
488 else: # pragma: no cover
489 raise UnknownOperatingSystemException("Unknown operating system.")
491 @readonly
492 def StaticLibraryExtension(self) -> str:
493 """
494 Returns the file extension for a static library.
496 * FreeBSD: ``"a"``
497 * Linux: ``"a"``
498 * macOS: ``"lib"``
499 * Windows: ``"lib"``
501 :returns: File extension of a static library.
502 :raises UnknownOperatingSystemException: If the operating system is unknown.
503 """
504 if Platforms.OS_FreeBSD in self._platform: 504 ↛ 505line 504 didn't jump to line 505 because the condition on line 504 was never true
505 return "a"
506 elif Platforms.OS_Linux in self._platform:
507 return "a"
508 elif Platforms.OS_MacOS in self._platform:
509 return "a"
510 elif Platforms.OS_Windows in self._platform:
511 return "lib"
512 else: # pragma: no cover
513 raise UnknownOperatingSystemException("Unknown operating system.")
515 @readonly
516 def DynamicLibraryExtension(self) -> str:
517 """
518 Returns the file extension for a dynamic/shared library.
520 * FreeBSD: ``"so"``
521 * Linux: ``"so"``
522 * macOS: ``"dylib"``
523 * Windows: ``"dll"``
525 :returns: File extension of a dynamic library.
526 :raises UnknownOperatingSystemException: If the operating system is unknown.
527 """
528 if Platforms.OS_FreeBSD in self._platform: 528 ↛ 529line 528 didn't jump to line 529 because the condition on line 528 was never true
529 return "so"
530 elif Platforms.OS_Linux in self._platform:
531 return "so"
532 elif Platforms.OS_MacOS in self._platform:
533 return "dylib"
534 elif Platforms.OS_Windows in self._platform:
535 return "dll"
536 else: # pragma: no cover
537 raise UnknownOperatingSystemException("Unknown operating system.")
539 def __repr__(self) -> str:
540 return str(self._platform)
542 def __str__(self) -> str:
543 runtime = ""
545 if Platforms.OS_FreeBSD in self._platform: 545 ↛ 546line 545 didn't jump to line 546 because the condition on line 545 was never true
546 platform = "FreeBSD"
547 elif Platforms.OS_MacOS in self._platform:
548 platform = "macOS"
549 elif Platforms.OS_Linux in self._platform:
550 platform = "Linux"
551 elif Platforms.OS_Windows in self._platform: 551 ↛ 554line 551 didn't jump to line 554 because the condition on line 551 was always true
552 platform = "Windows"
553 else:
554 platform = "plat:dec-err"
556 if Platforms.ENV_Native in self._platform:
557 environment = ""
558 elif Platforms.ENV_WSL in self._platform: 558 ↛ 559line 558 didn't jump to line 559 because the condition on line 558 was never true
559 environment = "+WSL"
560 elif Platforms.ENV_MSYS2 in self._platform: 560 ↛ 578line 560 didn't jump to line 578 because the condition on line 560 was always true
561 environment = "+MSYS2"
563 if Platforms.MSYS in self._platform: 563 ↛ 564line 563 didn't jump to line 564 because the condition on line 563 was never true
564 runtime = " - MSYS"
565 elif Platforms.MinGW32 in self._platform: 565 ↛ 566line 565 didn't jump to line 566 because the condition on line 565 was never true
566 runtime = " - MinGW32"
567 elif Platforms.MinGW64 in self._platform:
568 runtime = " - MinGW64"
569 elif Platforms.UCRT64 in self._platform:
570 runtime = " - UCRT64"
571 elif Platforms.Clang32 in self._platform: 571 ↛ 572line 571 didn't jump to line 572 because the condition on line 571 was never true
572 runtime = " - Clang32"
573 elif Platforms.Clang64 in self._platform: 573 ↛ 576line 573 didn't jump to line 576 because the condition on line 573 was always true
574 runtime = " - Clang64"
575 else:
576 runtime = "rt:dec-err"
578 elif Platforms.ENV_Cygwin in self._platform:
579 environment = "+Cygwin"
580 else:
581 environment = "env:dec-err"
583 if Platforms.ARCH_x86_32 in self._platform: 583 ↛ 584line 583 didn't jump to line 584 because the condition on line 583 was never true
584 architecture = "x86-32"
585 elif Platforms.ARCH_x86_64 in self._platform:
586 architecture = "x86-64"
587 elif Platforms.ARCH_AArch64 in self._platform: 587 ↛ 590line 587 didn't jump to line 590 because the condition on line 587 was always true
588 architecture = "aarch64"
589 else:
590 architecture = "arch:dec-err"
592 return f"{platform}{environment} ({architecture}){runtime}"
595CurrentPlatform = Platform() #: Gathered information for the current platform.