Coverage for pyTooling / Platform / __init__.py: 79%
317 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-05 23:48 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-05 23:48 +0000
1# ==================================================================================================================== #
2# _____ _ _ ____ _ _ __ #
3# _ __ _ |_ _|__ ___ | (_)_ __ __ _ | _ \| | __ _| |_ / _| ___ _ __ _ __ ___ #
4# | '_ \| | | || |/ _ \ / _ \| | | '_ \ / _` | | |_) | |/ _` | __| |_ / _ \| '__| '_ ` _ \ #
5# | |_) | |_| || | (_) | (_) | | | | | | (_| |_| __/| | (_| | |_| _| (_) | | | | | | | | #
6# | .__/ \__, ||_|\___/ \___/|_|_|_| |_|\__, (_)_| |_|\__,_|\__|_| \___/|_| |_| |_| |_| #
7# |_| |___/ |___/ #
8# ==================================================================================================================== #
9# Authors: #
10# Patrick Lehmann #
11# #
12# License: #
13# ==================================================================================================================== #
14# Copyright 2017-2026 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::
36 See :ref:`high-level help <COMMON/Platform>` for explanations and usage examples.
37"""
38from enum import Flag, auto, Enum
40try:
41 from pyTooling.Decorators import export, readonly
42 from pyTooling.Exceptions import ToolingException
43 from pyTooling.MetaClasses import ExtendedType
44 from pyTooling.Versioning import PythonVersion
45except (ImportError, ModuleNotFoundError): # pragma: no cover
46 print("[pyTooling.Platform] Could not import from 'pyTooling.*'!")
48 try:
49 from Decorators import export, readonly
50 from Exceptions import ToolingException
51 from MetaClasses import ExtendedType
52 from Versioning import PythonVersion
53 except (ImportError, ModuleNotFoundError) as ex: # pragma: no cover
54 print("[pyTooling.Platform] Could not import directly!")
55 raise ex
58__all__ = ["CurrentPlatform"]
61@export
62class PlatformException(ToolingException):
63 """Base-exception of all exceptions raised by :mod:`pyTooling.Platform`."""
66@export
67class UnknownPlatformException(PlatformException):
68 """
69 The exception is raised by pyTooling.Platform when the platform can't be determined.
71 For debugging purposes, a list of system properties from various APIs is added as notes to this exception to ease
72 debugging unknown or new platforms.
73 """
75 def __init__(self, *args) -> None:
76 """
77 Initialize a new :class:`UnknownPlatformException` instance and add notes with further debugging information.
79 :param args: Forward positional parameters.
80 """
81 super().__init__(*args)
83 import sys
84 import os
85 import platform
86 import sysconfig
88 self.add_note(f"os.name: {os.name}")
89 self.add_note(f"platform.system: {platform.system()}")
90 self.add_note(f"platform.machine: {platform.machine()}")
91 self.add_note(f"platform.architecture: {platform.architecture()}")
92 self.add_note(f"sys.platform: {sys.platform}")
93 self.add_note(f"sysconfig.get_platform: {sysconfig.get_platform()}")
96@export
97class UnknownOperatingSystemException(PlatformException):
98 """The exception is raised by pyTooling.Platform when the operating system is unknown."""
101@export
102class PythonImplementation(Enum):
103 """An enumeration describing the Python implementation (CPython, PyPy, ...)."""
104 Unknown = 0 #: Unknown Python implementation
106 CPython = 1 #: CPython (reference implementation)
107 PyPy = 2 #: PyPy
110@export
111class Platforms(Flag):
112 """A flag describing on which platform Python is running on and/or in which environment it's running in."""
113 Unknown = 0
115 OS_FreeBSD = auto() #: Operating System: BSD (Unix).
116 OS_Linux = auto() #: Operating System: Linux.
117 OS_MacOS = auto() #: Operating System: macOS.
118 OS_Windows = auto() #: Operating System: Windows.
120 OperatingSystem = OS_FreeBSD | OS_Linux | OS_MacOS | OS_Windows #: Mask: Any operating system.
122 SEP_WindowsPath = auto() #: Seperator: Path element seperator (e.g. for directories).
123 SEP_WindowsValue = auto() #: Seperator: Value seperator in variables (e.g. for paths in PATH).
125 ENV_Native = auto() #: Environment: :term:`native`.
126 ENV_WSL = auto() #: Environment: :term:`Windows System for Linux <WSL>`.
127 ENV_MSYS2 = auto() #: Environment: :term:`MSYS2`.
128 ENV_Cygwin = auto() #: Environment: :term:`Cygwin`.
130 Environment = ENV_Native | ENV_WSL | ENV_MSYS2 | ENV_Cygwin #: Mask: Any environment.
132 CI_None = auto() #: CI: No CI environment detected. Running on host.
133 CI_AppVeyor = auto() #: CI: AppVayor
134 CI_GitHubActions = auto() #: CI: GitHub Actions
135 CI_GitLabCI = auto() #: CI: GitLab CI
136 CI_TravisCI = auto() #: CI: Travis CI
138 ContinuousIntegration = CI_None | CI_AppVeyor | CI_GitHubActions | CI_GitLabCI | CI_TravisCI #: Mask: Any CI environment.
140 ARCH_x86_32 = auto() #: Architecture: x86-32 (IA32).
141 ARCH_x86_64 = auto() #: Architecture: x86-64 (AMD64).
142 ARCH_AArch64 = auto() #: Architecture: AArch64 (arm64).
144 Arch_x86 = ARCH_x86_32 | ARCH_x86_64 #: Mask: Any x86 architecture.
145 Arch_Arm = ARCH_AArch64 #: Mask: Any Arm architecture.
146 Architecture = Arch_x86 | Arch_Arm #: Mask: Any architecture.
148 FreeBSD = OS_FreeBSD | ENV_Native #: Group: native FreeBSD on x86-64.
149 Linux = OS_Linux | ENV_Native #: Group: native Linux on x86-64.
150 MacOS = OS_MacOS | ENV_Native #: Group: native macOS.
151 Windows = OS_Windows | ENV_Native | SEP_WindowsPath | SEP_WindowsValue #: Group: native Windows on x86-64.
153 Linux_x86_64 = Linux | ARCH_x86_64 #: Group: native Linux on x86-64.
154 Linux_AArch64 = Linux | ARCH_AArch64 #: Group: native Linux on aarch64.
155 MacOS_Intel = MacOS | ARCH_x86_64 #: Group: native macOS on x86-64.
156 MacOS_ARM = MacOS | ARCH_AArch64 #: Group: native macOS on aarch64.
157 Windows_x86_64 = Windows | ARCH_x86_64 #: Group: native Windows on x86-64.
158 Windows_AArch64 = Windows | ARCH_AArch64 #: Group: native Windows on aarch64.
160 MSYS = auto() #: MSYS2 Runtime: MSYS.
161 MinGW32 = auto() #: MSYS2 Runtime: :term:`MinGW32 <MinGW>`.
162 MinGW64 = auto() #: MSYS2 Runtime: :term:`MinGW64 <MinGW>`.
163 UCRT64 = auto() #: MSYS2 Runtime: :term:`UCRT64 <UCRT>`.
164 Clang32 = auto() #: MSYS2 Runtime: Clang32.
165 Clang64 = auto() #: MSYS2 Runtime: Clang64.
167 MSYS2_Runtime = MSYS | MinGW32 | MinGW64 | UCRT64 | Clang32 | Clang64 #: Mask: Any MSYS2 runtime environment.
169 Windows_MSYS2_MSYS = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MSYS #: Group: MSYS runtime running on Windows x86-64
170 Windows_MSYS2_MinGW32 = OS_Windows | ENV_MSYS2 | ARCH_x86_32 | MinGW32 #: Group: MinGW32 runtime running on Windows x86-64
171 Windows_MSYS2_MinGW64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MinGW64 #: Group: MinGW64 runtime running on Windows x86-64
172 Windows_MSYS2_UCRT64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | UCRT64 #: Group: UCRT64 runtime running on Windows x86-64
173 Windows_MSYS2_Clang32 = OS_Windows | ENV_MSYS2 | ARCH_x86_32 | Clang32 #: Group: Clang32 runtime running on Windows x86-64
174 Windows_MSYS2_Clang64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | Clang64 #: Group: Clang64 runtime running on Windows x86-64
176 Windows_Cygwin32 = OS_Windows | ENV_Cygwin | ARCH_x86_32 #: Group: 32-bit Cygwin runtime on Windows x86-64
177 Windows_Cygwin64 = OS_Windows | ENV_Cygwin | ARCH_x86_64 #: Group: 64-bit Cygwin runtime on Windows x86-64
180@export
181class Platform(metaclass=ExtendedType, singleton=True, slots=True):
182 """An instance of this class contains all gathered information available from various sources.
184 .. seealso::
186 StackOverflow question: `Python: What OS am I running on? <https://stackoverflow.com/a/54837707/3719459>`__
187 """
189 _platform: Platforms
190 _pythonImplementation: PythonImplementation
191 _pythonVersion: PythonVersion
193 def __init__(self) -> None:
194 """
195 Initializes a platform by accessing multiple APIs of Python to gather all necessary information.
196 """
197 import sys
198 import os
199 import platform
200 import sysconfig
202 # Discover the Python implementation
203 pythonImplementation = platform.python_implementation()
204 if pythonImplementation == "CPython":
205 self._pythonImplementation = PythonImplementation.CPython
206 elif pythonImplementation == "PyPy":
207 self._pythonImplementation = PythonImplementation.PyPy
208 else: # pragma: no cover
209 self._pythonImplementation = PythonImplementation.Unknown
211 # Discover the Python version
212 self._pythonVersion = PythonVersion.FromSysVersionInfo()
214 # Discover the platform
215 self._platform = Platforms.Unknown
217 machine = platform.machine()
218 sys_platform = sys.platform
219 sysconfig_platform = sysconfig.get_platform()
221 if "APPVEYOR" in os.environ: 221 ↛ 222line 221 didn't jump to line 222 because the condition on line 221 was never true
222 self._platform |= Platforms.CI_AppVeyor
223 elif "GITHUB_ACTIONS" in os.environ: 223 ↛ 225line 223 didn't jump to line 225 because the condition on line 223 was always true
224 self._platform |= Platforms.CI_GitHubActions
225 elif "GITLAB_CI" in os.environ:
226 self._platform |= Platforms.CI_GitLabCI
227 elif "TRAVIS" in os.environ:
228 self._platform |= Platforms.CI_TravisCI
229 else:
230 self._platform |= Platforms.CI_None
232 if os.name == "nt":
233 self._platform |= Platforms.OS_Windows
235 if sysconfig_platform == "win32": 235 ↛ 236line 235 didn't jump to line 236 because the condition on line 235 was never true
236 self._platform |= Platforms.ENV_Native | Platforms.ARCH_x86_32 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
237 elif sysconfig_platform == "win-amd64":
238 self._platform |= Platforms.ENV_Native | Platforms.ARCH_x86_64 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
239 elif sysconfig_platform == "win-arm64":
240 self._platform |= Platforms.ENV_Native | Platforms.ARCH_AArch64 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
241 elif sysconfig_platform.startswith("mingw"):
242 if machine == "AMD64":
243 self._platform |= Platforms.ARCH_x86_64
244 else: # pragma: no cover
245 raise UnknownPlatformException(f"Unknown architecture '{machine}' for Windows.")
247 if sysconfig_platform == "mingw_i686_msvcrt_gnu": 247 ↛ 248line 247 didn't jump to line 248 because the condition on line 247 was never true
248 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW32
249 elif sysconfig_platform == "mingw_x86_64_msvcrt_gnu":
250 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW64
251 elif sysconfig_platform == "mingw_x86_64_ucrt_gnu":
252 self._platform |= Platforms.ENV_MSYS2 | Platforms.UCRT64
253 elif sysconfig_platform == "mingw_x86_64_ucrt_llvm":
254 self._platform |= Platforms.ENV_MSYS2 | Platforms.Clang64
255 elif sysconfig_platform == "mingw_i686": # pragma: no cover
256 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW32
257 elif sysconfig_platform == "mingw_x86_64": # pragma: no cover
258 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW64
259 elif sysconfig_platform == "mingw_x86_64_ucrt": # pragma: no cover
260 self._platform |= Platforms.ENV_MSYS2 | Platforms.UCRT64
261 elif sysconfig_platform == "mingw_x86_64_clang": # pragma: no cover
262 self._platform |= Platforms.ENV_MSYS2 | Platforms.Clang64
263 else: # pragma: no cover
264 raise UnknownPlatformException(f"Unknown MSYS2 architecture '{sysconfig_platform}'.")
265 else: # pragma: no cover
266 raise UnknownPlatformException(f"Unknown platform '{sysconfig_platform}' running on Windows.")
268 elif os.name == "posix":
269 if sys_platform == "linux":
270 self._platform |= Platforms.OS_Linux | Platforms.ENV_Native
272 if sysconfig_platform == "linux-x86_64": # native Linux x86_64; Windows 64 + WSL 272 ↛ 274line 272 didn't jump to line 274 because the condition on line 272 was always true
273 self._platform |= Platforms.ARCH_x86_64
274 elif sysconfig_platform == "linux-aarch64": # native Linux Aarch64
275 self._platform |= Platforms.ARCH_AArch64
276 else: # pragma: no cover
277 raise UnknownPlatformException(f"Unknown architecture '{sysconfig_platform}' for a native Linux.")
279 elif sys_platform == "darwin": 279 ↛ 289line 279 didn't jump to line 289 because the condition on line 279 was always true
280 self._platform |= Platforms.OS_MacOS | Platforms.ENV_Native
282 if machine == "x86_64":
283 self._platform |= Platforms.ARCH_x86_64
284 elif machine == "arm64":
285 self._platform |= Platforms.ARCH_AArch64
286 else: # pragma: no cover
287 raise UnknownPlatformException(f"Unknown architecture '{machine}' for a native macOS.")
289 elif sys_platform == "msys":
290 self._platform |= Platforms.OS_Windows | Platforms.ENV_MSYS2 | Platforms.MSYS
292 if machine == "i686":
293 self._platform |= Platforms.ARCH_x86_32
294 elif machine == "x86_64":
295 self._platform |= Platforms.ARCH_x86_64
296 else: # pragma: no cover
297 raise UnknownPlatformException(f"Unknown architecture '{machine}' for MSYS2-MSYS on Windows.")
299 elif sys_platform == "cygwin":
300 self._platform |= Platforms.OS_Windows
302 if machine == "i686":
303 self._platform |= Platforms.ARCH_x86_32
304 elif machine == "x86_64":
305 self._platform |= Platforms.ARCH_x86_64
306 else: # pragma: no cover
307 raise UnknownPlatformException(f"Unknown architecture '{machine}' for Cygwin on Windows.")
309 elif sys_platform.startswith("freebsd"):
310 if machine == "amd64":
311 self._platform = Platforms.FreeBSD
312 else: # pragma: no cover
313 raise UnknownPlatformException(f"Unknown architecture '{machine}' for FreeBSD.")
314 else: # pragma: no cover
315 raise UnknownPlatformException(f"Unknown POSIX platform '{sys_platform}'.")
316 else: # pragma: no cover
317 raise UnknownPlatformException(f"Unknown operating system '{os.name}'.")
319 @readonly
320 def PythonImplementation(self) -> PythonImplementation:
321 """
322 Read-only property to return the :class:`PythonImplementation` of the current interpreter.
324 :returns: Python implementation of the current interpreter.
325 """
326 return self._pythonImplementation
328 @readonly
329 def IsCPython(self) -> bool:
330 """Returns true, if the Python implementation is a :term:`CPython`.
332 :returns: ``True``, if the Python implementation is CPython.
333 """
334 return self._pythonImplementation is PythonImplementation.CPython
336 @readonly
337 def IsPyPy(self) -> bool:
338 """Returns true, if the Python implementation is a :term:`PyPy`.
340 :returns: ``True``, if the Python implementation is PyPY.
341 """
342 return self._pythonImplementation is PythonImplementation.PyPy
344 @readonly
345 def PythonVersion(self) -> PythonVersion:
346 """
347 Read-only property to return the :class:`pyTooling.Versioning.PythonVersion` of the current interpreter.
349 :returns: Python version of the current interpreter.
350 """
351 return self._pythonVersion
353 @readonly
354 def HostOperatingSystem(self) -> Platforms:
355 return self._platform & Platforms.OperatingSystem
357 @readonly
358 def IsNativePlatform(self) -> bool:
359 """Returns true, if the platform is a :term:`native` platform.
361 :returns: ``True``, if the platform is a native platform.
362 """
363 return Platforms.ENV_Native in self._platform
365 @readonly
366 def IsNativeFreeBSD(self) -> bool:
367 """Returns true, if the platform is a :term:`native` FreeBSD x86-64 platform.
369 :returns: ``True``, if the platform is a native FreeBSD x86-64 platform.
370 """
371 return Platforms.FreeBSD in self._platform
373 @readonly
374 def IsNativeMacOS(self) -> bool:
375 """Returns true, if the platform is a :term:`native` macOS x86-64 platform.
377 :returns: ``True``, if the platform is a native macOS x86-64 platform.
378 """
379 return Platforms.MacOS in self._platform
381 @readonly
382 def IsNativeLinux(self) -> bool:
383 """Returns true, if the platform is a :term:`native` Linux x86-64 platform.
385 :returns: ``True``, if the platform is a native Linux x86-64 platform.
386 """
387 return Platforms.Linux in self._platform
389 @readonly
390 def IsNativeWindows(self) -> bool:
391 """Returns true, if the platform is a :term:`native` Windows x86-64 platform.
393 :returns: ``True``, if the platform is a native Windows x86-64 platform.
394 """
395 return Platforms.Windows in self._platform
397 @readonly
398 def IsMSYS2Environment(self) -> bool:
399 """Returns true, if the platform is a :term:`MSYS2` environment on Windows.
401 :returns: ``True``, if the platform is a MSYS2 environment on Windows.
402 """
403 return Platforms.ENV_MSYS2 in self._platform
405 @readonly
406 def IsMSYSOnWindows(self) -> bool:
407 """Returns true, if the platform is a MSYS runtime on Windows.
409 :returns: ``True``, if the platform is a MSYS runtime on Windows.
410 """
411 return Platforms.Windows_MSYS2_MSYS in self._platform
413 @readonly
414 def IsMinGW32OnWindows(self) -> bool:
415 """Returns true, if the platform is a :term:`MinGW32 <MinGW>` runtime on Windows.
417 :returns: ``True``, if the platform is a MINGW32 runtime on Windows.
418 """
419 return Platforms.Windows_MSYS2_MinGW32 in self._platform
421 @readonly
422 def IsMinGW64OnWindows(self) -> bool:
423 """Returns true, if the platform is a :term:`MinGW64 <MinGW>` runtime on Windows.
425 :returns: ``True``, if the platform is a MINGW64 runtime on Windows.
426 """
427 return Platforms.Windows_MSYS2_MinGW64 in self._platform
429 @readonly
430 def IsUCRT64OnWindows(self) -> bool:
431 """Returns true, if the platform is a :term:`UCRT64 <UCRT>` runtime on Windows.
433 :returns: ``True``, if the platform is a UCRT64 runtime on Windows.
434 """
435 return Platforms.Windows_MSYS2_UCRT64 in self._platform
437 @readonly
438 def IsClang32OnWindows(self) -> bool:
439 """Returns true, if the platform is a Clang32 runtime on Windows.
441 :returns: ``True``, if the platform is a Clang32 runtime on Windows.
442 """
443 return Platforms.Windows_MSYS2_Clang32 in self._platform
445 @readonly
446 def IsClang64OnWindows(self) -> bool:
447 """Returns true, if the platform is a Clang64 runtime on Windows.
449 :returns: ``True``, if the platform is a Clang64 runtime on Windows.
450 """
451 return Platforms.Windows_MSYS2_Clang64 in self._platform
453 @readonly
454 def IsCygwin32OnWindows(self) -> bool:
455 """Returns true, if the platform is a 32-bit Cygwin runtime on Windows.
457 :returns: ``True``, if the platform is a 32-bit Cygwin runtime on Windows.
458 """
459 return Platforms.Windows_Cygwin32 in self._platform
461 @readonly
462 def IsCygwin64OnWindows(self) -> bool:
463 """Returns true, if the platform is a 64-bit Cygwin runtime on Windows.
465 :returns: ``True``, if the platform is a 64-bit Cygwin runtime on Windows.
466 """
467 return Platforms.Windows_Cygwin64 in self._platform
469 @readonly
470 def IsPOSIX(self) -> bool:
471 """
472 Returns true, if the platform is POSIX or POSIX-like.
474 :returns: ``True``, if POSIX or POSIX-like.
475 """
476 return Platforms.SEP_WindowsPath not in self._platform
478 @readonly
479 def IsCI(self) -> bool:
480 """
481 Returns true, if the platform is a CI environment.
483 :returns: ``True``, if on CI runner.
484 """
485 return Platforms.CI_None not in self._platform
487 @readonly
488 def IsAppVeyor(self) -> bool:
489 """
490 Returns true, if the platform is on AppVeyor.
492 :returns: ``True``, if on AppVeyor.
493 """
494 return Platforms.CI_AppVeyor in self._platform
496 @readonly
497 def IsGitHub(self) -> bool:
498 """
499 Returns true, if the platform is on GitHub.
501 :returns: ``True``, if on GitHub.
502 """
503 return Platforms.CI_GitHubActions in self._platform
505 @readonly
506 def IsGitLab(self) -> bool:
507 """
508 Returns true, if the platform is on GitLab CI.
510 :returns: ``True``, if on GitLab CI.
511 """
512 return Platforms.CI_GitLabCI in self._platform
514 @readonly
515 def IsTravisCI(self) -> bool:
516 """
517 Returns true, if the platform is on Travis CI.
519 :returns: ``True``, if on Travis CI.
520 """
521 return Platforms.CI_TravisCI in self._platform
523 @readonly
524 def PathSeperator(self) -> str:
525 """
526 Returns the path element separation character (e.g. for directories).
528 * POSIX-like: ``/``
529 * Windows: ``\\``
531 :returns: Path separation character.
532 """
533 if Platforms.SEP_WindowsPath in self._platform:
534 return "\\"
535 else:
536 return "/"
538 @readonly
539 def ValueSeperator(self) -> str:
540 """
541 Returns the value separation character (e.g. for paths in PATH).
543 * POSIX-like: ``:``
544 * Windows: ``;``
546 :returns: Value separation character.
547 """
548 if Platforms.SEP_WindowsValue in self._platform:
549 return ";"
550 else:
551 return ":"
553 @readonly
554 def ExecutableExtension(self) -> str:
555 """
556 Returns the file extension for an executable.
558 * FreeBSD: ``""`` (empty string)
559 * Linux: ``""`` (empty string)
560 * macOS: ``""`` (empty string)
561 * Windows: ``"exe"``
563 :returns: File extension of an executable.
564 :raises UnknownOperatingSystemException: If the operating system is unknown.
565 """
567 if Platforms.OS_FreeBSD in self._platform: 567 ↛ 568line 567 didn't jump to line 568 because the condition on line 567 was never true
568 return ""
569 elif Platforms.OS_Linux in self._platform:
570 return ""
571 elif Platforms.OS_MacOS in self._platform:
572 return ""
573 elif Platforms.OS_Windows in self._platform:
574 return "exe"
575 else: # pragma: no cover
576 raise UnknownOperatingSystemException("Unknown operating system.")
578 @readonly
579 def StaticLibraryExtension(self) -> str:
580 """
581 Returns the file extension for a static library.
583 * FreeBSD: ``"a"``
584 * Linux: ``"a"``
585 * macOS: ``"lib"``
586 * Windows: ``"lib"``
588 :returns: File extension of a static library.
589 :raises UnknownOperatingSystemException: If the operating system is unknown.
590 """
591 if Platforms.OS_FreeBSD in self._platform: 591 ↛ 592line 591 didn't jump to line 592 because the condition on line 591 was never true
592 return "a"
593 elif Platforms.OS_Linux in self._platform:
594 return "a"
595 elif Platforms.OS_MacOS in self._platform:
596 return "a"
597 elif Platforms.OS_Windows in self._platform:
598 return "lib"
599 else: # pragma: no cover
600 raise UnknownOperatingSystemException("Unknown operating system.")
602 @readonly
603 def DynamicLibraryExtension(self) -> str:
604 """
605 Returns the file extension for a dynamic/shared library.
607 * FreeBSD: ``"so"``
608 * Linux: ``"so"``
609 * macOS: ``"dylib"``
610 * Windows: ``"dll"``
612 :returns: File extension of a dynamic library.
613 :raises UnknownOperatingSystemException: If the operating system is unknown.
614 """
615 if Platforms.OS_FreeBSD in self._platform: 615 ↛ 616line 615 didn't jump to line 616 because the condition on line 615 was never true
616 return "so"
617 elif Platforms.OS_Linux in self._platform:
618 return "so"
619 elif Platforms.OS_MacOS in self._platform:
620 return "dylib"
621 elif Platforms.OS_Windows in self._platform:
622 return "dll"
623 else: # pragma: no cover
624 raise UnknownOperatingSystemException("Unknown operating system.")
626 def __repr__(self) -> str:
627 """
628 Returns the platform's string representation.
630 :returns: The string representation of the current platform.
631 """
632 return str(self._platform)
634 def __str__(self) -> str:
635 """
636 Returns the platform's string equivalent.
638 :returns: The string equivalent of the platform.
639 """
640 runtime = ""
642 if Platforms.OS_FreeBSD in self._platform: 642 ↛ 643line 642 didn't jump to line 643 because the condition on line 642 was never true
643 platform = "FreeBSD"
644 elif Platforms.OS_MacOS in self._platform:
645 platform = "macOS"
646 elif Platforms.OS_Linux in self._platform:
647 platform = "Linux"
648 elif Platforms.OS_Windows in self._platform: 648 ↛ 651line 648 didn't jump to line 651 because the condition on line 648 was always true
649 platform = "Windows"
650 else:
651 platform = "plat:dec-err"
653 if Platforms.ENV_Native in self._platform:
654 environment = ""
655 elif Platforms.ENV_WSL in self._platform: 655 ↛ 656line 655 didn't jump to line 656 because the condition on line 655 was never true
656 environment = "+WSL"
657 elif Platforms.ENV_MSYS2 in self._platform: 657 ↛ 675line 657 didn't jump to line 675 because the condition on line 657 was always true
658 environment = "+MSYS2"
660 if Platforms.MSYS in self._platform: 660 ↛ 661line 660 didn't jump to line 661 because the condition on line 660 was never true
661 runtime = " - MSYS"
662 elif Platforms.MinGW32 in self._platform: 662 ↛ 663line 662 didn't jump to line 663 because the condition on line 662 was never true
663 runtime = " - MinGW32"
664 elif Platforms.MinGW64 in self._platform:
665 runtime = " - MinGW64"
666 elif Platforms.UCRT64 in self._platform:
667 runtime = " - UCRT64"
668 elif Platforms.Clang32 in self._platform: 668 ↛ 669line 668 didn't jump to line 669 because the condition on line 668 was never true
669 runtime = " - Clang32"
670 elif Platforms.Clang64 in self._platform: 670 ↛ 673line 670 didn't jump to line 673 because the condition on line 670 was always true
671 runtime = " - Clang64"
672 else:
673 runtime = "rt:dec-err"
675 elif Platforms.ENV_Cygwin in self._platform:
676 environment = "+Cygwin"
677 else:
678 environment = "env:dec-err"
680 if Platforms.ARCH_x86_32 in self._platform: 680 ↛ 681line 680 didn't jump to line 681 because the condition on line 680 was never true
681 architecture = "x86-32"
682 elif Platforms.ARCH_x86_64 in self._platform:
683 architecture = "x86-64"
684 elif Platforms.ARCH_AArch64 in self._platform: 684 ↛ 687line 684 didn't jump to line 687 because the condition on line 684 was always true
685 architecture = "aarch64"
686 else:
687 architecture = "arch:dec-err"
689 return f"{platform}{environment} ({architecture}){runtime}"
692CurrentPlatform = Platform() #: Gathered information for the current platform.