Coverage for pyTooling / Platform / __init__.py: 79%
316 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-07 17:18 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-07 17:18 +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
40from pyTooling.Decorators import export, readonly
41from pyTooling.Exceptions import ToolingException
42from pyTooling.MetaClasses import ExtendedType
43from pyTooling.Versioning import PythonVersion
46__all__ = ["CurrentPlatform"]
49@export
50class PlatformException(ToolingException):
51 """Base-exception of all exceptions raised by :mod:`pyTooling.Platform`."""
54@export
55class UnknownPlatformException(PlatformException):
56 """
57 The exception is raised by pyTooling.Platform when the platform can't be determined.
59 For debugging purposes, a list of system properties from various APIs is added as notes to this exception to ease
60 debugging unknown or new platforms.
61 """
63 def __init__(self, *args) -> None:
64 """
65 Initialize a new :class:`UnknownPlatformException` instance and add notes with further debugging information.
67 :param args: Forward positional parameters.
68 """
69 super().__init__(*args)
71 import sys
72 import os
73 import platform
74 import sysconfig
76 self.add_note(f"os.name: {os.name}")
77 self.add_note(f"platform.system: {platform.system()}")
78 self.add_note(f"platform.machine: {platform.machine()}")
79 self.add_note(f"platform.architecture: {platform.architecture()}")
80 self.add_note(f"sys.platform: {sys.platform}")
81 self.add_note(f"sysconfig.get_platform: {sysconfig.get_platform()}")
84@export
85class UnknownOperatingSystemException(PlatformException):
86 """The exception is raised by pyTooling.Platform when the operating system is unknown."""
89@export
90class PythonImplementation(Enum):
91 """An enumeration describing the Python implementation (CPython, PyPy, ...)."""
92 Unknown = 0 #: Unknown Python implementation
94 CPython = 1 #: CPython (reference implementation)
95 PyPy = 2 #: PyPy
98@export
99class Platforms(Flag):
100 """A flag describing on which platform Python is running on and/or in which environment it's running in."""
101 Unknown = 0
103 OS_FreeBSD = auto() #: Operating System: BSD (Unix).
104 OS_Linux = auto() #: Operating System: Linux.
105 OS_MacOS = auto() #: Operating System: macOS.
106 OS_Windows = auto() #: Operating System: Windows.
108 OperatingSystem = OS_FreeBSD | OS_Linux | OS_MacOS | OS_Windows #: Mask: Any operating system.
110 SEP_WindowsPath = auto() #: Seperator: Path element seperator (e.g. for directories).
111 SEP_WindowsValue = auto() #: Seperator: Value seperator in variables (e.g. for paths in PATH).
113 ENV_Native = auto() #: Environment: :term:`native`.
114 ENV_WSL = auto() #: Environment: :term:`Windows System for Linux <WSL>`.
115 ENV_MSYS2 = auto() #: Environment: :term:`MSYS2`.
116 ENV_Cygwin = auto() #: Environment: :term:`Cygwin`.
118 Environment = ENV_Native | ENV_WSL | ENV_MSYS2 | ENV_Cygwin #: Mask: Any environment.
120 CI_None = auto() #: CI: No CI environment detected. Running on host.
121 CI_AppVeyor = auto() #: CI: AppVayor
122 CI_GitHubActions = auto() #: CI: GitHub Actions
123 CI_GitLabCI = auto() #: CI: GitLab CI
124 CI_TravisCI = auto() #: CI: Travis CI
126 ContinuousIntegration = CI_None | CI_AppVeyor | CI_GitHubActions | CI_GitLabCI | CI_TravisCI #: Mask: Any CI 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 #: Group: native FreeBSD on x86-64.
137 Linux = OS_Linux | ENV_Native #: Group: native Linux on x86-64.
138 MacOS = OS_MacOS | ENV_Native #: Group: native macOS.
139 Windows = OS_Windows | ENV_Native | SEP_WindowsPath | SEP_WindowsValue #: Group: native Windows on x86-64.
141 Linux_x86_64 = Linux | ARCH_x86_64 #: Group: native Linux on x86-64.
142 Linux_AArch64 = Linux | ARCH_AArch64 #: Group: native Linux on aarch64.
143 MacOS_Intel = MacOS | ARCH_x86_64 #: Group: native macOS on x86-64.
144 MacOS_ARM = MacOS | ARCH_AArch64 #: Group: native macOS on aarch64.
145 Windows_x86_64 = Windows | ARCH_x86_64 #: Group: native Windows on x86-64.
146 Windows_AArch64 = Windows | ARCH_AArch64 #: Group: native Windows on aarch64.
148 MSYS = auto() #: MSYS2 Runtime: MSYS.
149 MinGW32 = auto() #: MSYS2 Runtime: :term:`MinGW32 <MinGW>`.
150 MinGW64 = auto() #: MSYS2 Runtime: :term:`MinGW64 <MinGW>`.
151 UCRT64 = auto() #: MSYS2 Runtime: :term:`UCRT64 <UCRT>`.
152 Clang32 = auto() #: MSYS2 Runtime: Clang32.
153 Clang64 = auto() #: MSYS2 Runtime: Clang64.
155 MSYS2_Runtime = MSYS | MinGW32 | MinGW64 | UCRT64 | Clang32 | Clang64 #: Mask: Any MSYS2 runtime environment.
157 Windows_MSYS2_MSYS = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MSYS #: Group: MSYS runtime running on Windows x86-64
158 Windows_MSYS2_MinGW32 = OS_Windows | ENV_MSYS2 | ARCH_x86_32 | MinGW32 #: Group: MinGW32 runtime running on Windows x86-64
159 Windows_MSYS2_MinGW64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MinGW64 #: Group: MinGW64 runtime running on Windows x86-64
160 Windows_MSYS2_UCRT64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | UCRT64 #: Group: UCRT64 runtime running on Windows x86-64
161 Windows_MSYS2_Clang32 = OS_Windows | ENV_MSYS2 | ARCH_x86_32 | Clang32 #: Group: Clang32 runtime running on Windows x86-64
162 Windows_MSYS2_Clang64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | Clang64 #: Group: Clang64 runtime running on Windows x86-64
164 Windows_Cygwin32 = OS_Windows | ENV_Cygwin | ARCH_x86_32 #: Group: 32-bit Cygwin runtime on Windows x86-64
165 Windows_Cygwin64 = OS_Windows | ENV_Cygwin | ARCH_x86_64 #: Group: 64-bit Cygwin runtime on Windows x86-64
168@export
169class Platform(metaclass=ExtendedType, singleton=True, slots=True):
170 """An instance of this class contains all gathered information available from various sources.
172 .. seealso::
174 StackOverflow question: `Python: What OS am I running on? <https://stackoverflow.com/a/54837707/3719459>`__
175 """
177 _platform: Platforms
178 _pythonImplementation: PythonImplementation
179 _pythonVersion: PythonVersion
181 def __init__(self) -> None:
182 """
183 Initializes a platform by accessing multiple APIs of Python to gather all necessary information.
184 """
185 import sys
186 import os
187 import platform
188 import sysconfig
190 # Discover the Python implementation
191 pythonImplementation = platform.python_implementation()
192 if pythonImplementation == "CPython":
193 self._pythonImplementation = PythonImplementation.CPython
194 elif pythonImplementation == "PyPy":
195 self._pythonImplementation = PythonImplementation.PyPy
196 else: # pragma: no cover
197 self._pythonImplementation = PythonImplementation.Unknown
199 # Discover the Python version
200 self._pythonVersion = PythonVersion.FromSysVersionInfo()
202 # Discover the platform
203 self._platform = Platforms.Unknown
205 machine = platform.machine()
206 sys_platform = sys.platform
207 sysconfig_platform = sysconfig.get_platform()
209 if "APPVEYOR" in os.environ: 209 ↛ 210line 209 didn't jump to line 210 because the condition on line 209 was never true
210 self._platform |= Platforms.CI_AppVeyor
211 elif "GITHUB_ACTIONS" in os.environ: 211 ↛ 213line 211 didn't jump to line 213 because the condition on line 211 was always true
212 self._platform |= Platforms.CI_GitHubActions
213 elif "GITLAB_CI" in os.environ:
214 self._platform |= Platforms.CI_GitLabCI
215 elif "TRAVIS" in os.environ:
216 self._platform |= Platforms.CI_TravisCI
217 else:
218 self._platform |= Platforms.CI_None
220 if os.name == "nt":
221 self._platform |= Platforms.OS_Windows
223 if sysconfig_platform == "win32": 223 ↛ 224line 223 didn't jump to line 224 because the condition on line 223 was never true
224 self._platform |= Platforms.ENV_Native | Platforms.ARCH_x86_32 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
225 elif sysconfig_platform == "win-amd64":
226 self._platform |= Platforms.ENV_Native | Platforms.ARCH_x86_64 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
227 elif sysconfig_platform == "win-arm64":
228 self._platform |= Platforms.ENV_Native | Platforms.ARCH_AArch64 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
229 elif sysconfig_platform.startswith("mingw"):
230 if machine == "AMD64":
231 self._platform |= Platforms.ARCH_x86_64
232 else: # pragma: no cover
233 raise UnknownPlatformException(f"Unknown architecture '{machine}' for Windows.")
235 if sysconfig_platform == "mingw_i686_msvcrt_gnu": 235 ↛ 236line 235 didn't jump to line 236 because the condition on line 235 was never true
236 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW32
237 elif sysconfig_platform == "mingw_x86_64_msvcrt_gnu":
238 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW64
239 elif sysconfig_platform == "mingw_x86_64_ucrt_gnu":
240 self._platform |= Platforms.ENV_MSYS2 | Platforms.UCRT64
241 elif sysconfig_platform == "mingw_x86_64_ucrt_llvm":
242 self._platform |= Platforms.ENV_MSYS2 | Platforms.Clang64
243 elif sysconfig_platform == "mingw_i686": # pragma: no cover
244 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW32
245 elif sysconfig_platform == "mingw_x86_64": # pragma: no cover
246 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW64
247 elif sysconfig_platform == "mingw_x86_64_ucrt": # pragma: no cover
248 self._platform |= Platforms.ENV_MSYS2 | Platforms.UCRT64
249 elif sysconfig_platform == "mingw_x86_64_clang": # pragma: no cover
250 self._platform |= Platforms.ENV_MSYS2 | Platforms.Clang64
251 else: # pragma: no cover
252 raise UnknownPlatformException(f"Unknown MSYS2 architecture '{sysconfig_platform}'.")
253 else: # pragma: no cover
254 raise UnknownPlatformException(f"Unknown platform '{sysconfig_platform}' running on Windows.")
256 elif os.name == "posix":
257 if sys_platform == "linux":
258 self._platform |= Platforms.OS_Linux | Platforms.ENV_Native
260 if sysconfig_platform == "linux-x86_64": # native Linux x86_64; Windows 64 + WSL 260 ↛ 262line 260 didn't jump to line 262 because the condition on line 260 was always true
261 self._platform |= Platforms.ARCH_x86_64
262 elif sysconfig_platform == "linux-aarch64": # native Linux Aarch64
263 self._platform |= Platforms.ARCH_AArch64
264 else: # pragma: no cover
265 raise UnknownPlatformException(f"Unknown architecture '{sysconfig_platform}' for a native Linux.")
267 elif sys_platform == "darwin": 267 ↛ 277line 267 didn't jump to line 277 because the condition on line 267 was always true
268 self._platform |= Platforms.OS_MacOS | Platforms.ENV_Native
270 if machine == "x86_64":
271 self._platform |= Platforms.ARCH_x86_64
272 elif machine == "arm64":
273 self._platform |= Platforms.ARCH_AArch64
274 else: # pragma: no cover
275 raise UnknownPlatformException(f"Unknown architecture '{machine}' for a native macOS.")
277 elif sys_platform == "msys":
278 self._platform |= Platforms.OS_Windows | Platforms.ENV_MSYS2 | Platforms.MSYS
280 if machine == "i686":
281 self._platform |= Platforms.ARCH_x86_32
282 elif machine == "x86_64":
283 self._platform |= Platforms.ARCH_x86_64
284 else: # pragma: no cover
285 raise UnknownPlatformException(f"Unknown architecture '{machine}' for MSYS2-MSYS on Windows.")
287 elif sys_platform == "cygwin":
288 self._platform |= Platforms.OS_Windows
290 if machine == "i686":
291 self._platform |= Platforms.ARCH_x86_32
292 elif machine == "x86_64":
293 self._platform |= Platforms.ARCH_x86_64
294 else: # pragma: no cover
295 raise UnknownPlatformException(f"Unknown architecture '{machine}' for Cygwin on Windows.")
297 elif sys_platform.startswith("freebsd"):
298 if machine == "amd64":
299 self._platform = Platforms.FreeBSD
300 else: # pragma: no cover
301 raise UnknownPlatformException(f"Unknown architecture '{machine}' for FreeBSD.")
302 else: # pragma: no cover
303 raise UnknownPlatformException(f"Unknown POSIX platform '{sys_platform}'.")
304 else: # pragma: no cover
305 raise UnknownPlatformException(f"Unknown operating system '{os.name}'.")
307 @readonly
308 def PythonImplementation(self) -> PythonImplementation:
309 """
310 Read-only property to return the :class:`PythonImplementation` of the current interpreter.
312 :returns: Python implementation of the current interpreter.
313 """
314 return self._pythonImplementation
316 @readonly
317 def IsCPython(self) -> bool:
318 """Returns true, if the Python implementation is a :term:`CPython`.
320 :returns: ``True``, if the Python implementation is CPython.
321 """
322 return self._pythonImplementation is PythonImplementation.CPython
324 @readonly
325 def IsPyPy(self) -> bool:
326 """Returns true, if the Python implementation is a :term:`PyPy`.
328 :returns: ``True``, if the Python implementation is PyPY.
329 """
330 return self._pythonImplementation is PythonImplementation.PyPy
332 @readonly
333 def PythonVersion(self) -> PythonVersion:
334 """
335 Read-only property to return the :class:`pyTooling.Versioning.PythonVersion` of the current interpreter.
337 :returns: Python version of the current interpreter.
338 """
339 return self._pythonVersion
341 @readonly
342 def HostOperatingSystem(self) -> Platforms:
343 return self._platform & Platforms.OperatingSystem
345 @readonly
346 def IsNativePlatform(self) -> bool:
347 """Returns true, if the platform is a :term:`native` platform.
349 :returns: ``True``, if the platform is a native platform.
350 """
351 return Platforms.ENV_Native in self._platform
353 @readonly
354 def IsNativeFreeBSD(self) -> bool:
355 """Returns true, if the platform is a :term:`native` FreeBSD x86-64 platform.
357 :returns: ``True``, if the platform is a native FreeBSD x86-64 platform.
358 """
359 return Platforms.FreeBSD in self._platform
361 @readonly
362 def IsNativeMacOS(self) -> bool:
363 """Returns true, if the platform is a :term:`native` macOS x86-64 platform.
365 :returns: ``True``, if the platform is a native macOS x86-64 platform.
366 """
367 return Platforms.MacOS in self._platform
369 @readonly
370 def IsNativeLinux(self) -> bool:
371 """Returns true, if the platform is a :term:`native` Linux x86-64 platform.
373 :returns: ``True``, if the platform is a native Linux x86-64 platform.
374 """
375 return Platforms.Linux in self._platform
377 @readonly
378 def IsNativeWindows(self) -> bool:
379 """Returns true, if the platform is a :term:`native` Windows x86-64 platform.
381 :returns: ``True``, if the platform is a native Windows x86-64 platform.
382 """
383 return Platforms.Windows in self._platform
385 @readonly
386 def IsMSYS2Environment(self) -> bool:
387 """Returns true, if the platform is a :term:`MSYS2` environment on Windows.
389 :returns: ``True``, if the platform is a MSYS2 environment on Windows.
390 """
391 return Platforms.ENV_MSYS2 in self._platform
393 @readonly
394 def IsMSYSOnWindows(self) -> bool:
395 """Returns true, if the platform is a MSYS runtime on Windows.
397 :returns: ``True``, if the platform is a MSYS runtime on Windows.
398 """
399 return Platforms.Windows_MSYS2_MSYS in self._platform
401 @readonly
402 def IsMinGW32OnWindows(self) -> bool:
403 """Returns true, if the platform is a :term:`MinGW32 <MinGW>` runtime on Windows.
405 :returns: ``True``, if the platform is a MINGW32 runtime on Windows.
406 """
407 return Platforms.Windows_MSYS2_MinGW32 in self._platform
409 @readonly
410 def IsMinGW64OnWindows(self) -> bool:
411 """Returns true, if the platform is a :term:`MinGW64 <MinGW>` runtime on Windows.
413 :returns: ``True``, if the platform is a MINGW64 runtime on Windows.
414 """
415 return Platforms.Windows_MSYS2_MinGW64 in self._platform
417 @readonly
418 def IsUCRT64OnWindows(self) -> bool:
419 """Returns true, if the platform is a :term:`UCRT64 <UCRT>` runtime on Windows.
421 :returns: ``True``, if the platform is a UCRT64 runtime on Windows.
422 """
423 return Platforms.Windows_MSYS2_UCRT64 in self._platform
425 @readonly
426 def IsClang32OnWindows(self) -> bool:
427 """Returns true, if the platform is a Clang32 runtime on Windows.
429 :returns: ``True``, if the platform is a Clang32 runtime on Windows.
430 """
431 return Platforms.Windows_MSYS2_Clang32 in self._platform
433 @readonly
434 def IsClang64OnWindows(self) -> bool:
435 """Returns true, if the platform is a Clang64 runtime on Windows.
437 :returns: ``True``, if the platform is a Clang64 runtime on Windows.
438 """
439 return Platforms.Windows_MSYS2_Clang64 in self._platform
441 @readonly
442 def IsCygwin32OnWindows(self) -> bool:
443 """Returns true, if the platform is a 32-bit Cygwin runtime on Windows.
445 :returns: ``True``, if the platform is a 32-bit Cygwin runtime on Windows.
446 """
447 return Platforms.Windows_Cygwin32 in self._platform
449 @readonly
450 def IsCygwin64OnWindows(self) -> bool:
451 """Returns true, if the platform is a 64-bit Cygwin runtime on Windows.
453 :returns: ``True``, if the platform is a 64-bit Cygwin runtime on Windows.
454 """
455 return Platforms.Windows_Cygwin64 in self._platform
457 @readonly
458 def IsPOSIX(self) -> bool:
459 """
460 Returns true, if the platform is POSIX or POSIX-like.
462 :returns: ``True``, if POSIX or POSIX-like.
463 """
464 return Platforms.SEP_WindowsPath not in self._platform
466 @readonly
467 def IsCI(self) -> bool:
468 """
469 Returns true, if the platform is a CI environment.
471 :returns: ``True``, if on CI runner.
472 """
473 return Platforms.CI_None not in self._platform
475 @readonly
476 def IsAppVeyor(self) -> bool:
477 """
478 Returns true, if the platform is on AppVeyor.
480 :returns: ``True``, if on AppVeyor.
481 """
482 return Platforms.CI_AppVeyor in self._platform
484 @readonly
485 def IsGitHub(self) -> bool:
486 """
487 Returns true, if the platform is on GitHub.
489 :returns: ``True``, if on GitHub.
490 """
491 return Platforms.CI_GitHubActions in self._platform
493 @readonly
494 def IsGitLab(self) -> bool:
495 """
496 Returns true, if the platform is on GitLab CI.
498 :returns: ``True``, if on GitLab CI.
499 """
500 return Platforms.CI_GitLabCI in self._platform
502 @readonly
503 def IsTravisCI(self) -> bool:
504 """
505 Returns true, if the platform is on Travis CI.
507 :returns: ``True``, if on Travis CI.
508 """
509 return Platforms.CI_TravisCI in self._platform
511 @readonly
512 def PathSeperator(self) -> str:
513 """
514 Returns the path element separation character (e.g. for directories).
516 * POSIX-like: ``/``
517 * Windows: ``\\``
519 :returns: Path separation character.
520 """
521 if Platforms.SEP_WindowsPath in self._platform:
522 return "\\"
523 else:
524 return "/"
526 @readonly
527 def ValueSeperator(self) -> str:
528 """
529 Returns the value separation character (e.g. for paths in PATH).
531 * POSIX-like: ``:``
532 * Windows: ``;``
534 :returns: Value separation character.
535 """
536 if Platforms.SEP_WindowsValue in self._platform:
537 return ";"
538 else:
539 return ":"
541 @readonly
542 def ExecutableExtension(self) -> str:
543 """
544 Returns the file extension for an executable.
546 * FreeBSD: ``""`` (empty string)
547 * Linux: ``""`` (empty string)
548 * macOS: ``""`` (empty string)
549 * Windows: ``"exe"``
551 :returns: File extension of an executable.
552 :raises UnknownOperatingSystemException: If the operating system is unknown.
553 """
555 if Platforms.OS_FreeBSD in self._platform: 555 ↛ 556line 555 didn't jump to line 556 because the condition on line 555 was never true
556 return ""
557 elif Platforms.OS_Linux in self._platform:
558 return ""
559 elif Platforms.OS_MacOS in self._platform:
560 return ""
561 elif Platforms.OS_Windows in self._platform:
562 return "exe"
563 else: # pragma: no cover
564 raise UnknownOperatingSystemException("Unknown operating system.")
566 @readonly
567 def StaticLibraryExtension(self) -> str:
568 """
569 Returns the file extension for a static library.
571 * FreeBSD: ``"a"``
572 * Linux: ``"a"``
573 * macOS: ``"lib"``
574 * Windows: ``"lib"``
576 :returns: File extension of a static library.
577 :raises UnknownOperatingSystemException: If the operating system is unknown.
578 """
579 if Platforms.OS_FreeBSD in self._platform: 579 ↛ 580line 579 didn't jump to line 580 because the condition on line 579 was never true
580 return "a"
581 elif Platforms.OS_Linux in self._platform:
582 return "a"
583 elif Platforms.OS_MacOS in self._platform:
584 return "a"
585 elif Platforms.OS_Windows in self._platform:
586 return "lib"
587 else: # pragma: no cover
588 raise UnknownOperatingSystemException("Unknown operating system.")
590 @readonly
591 def DynamicLibraryExtension(self) -> str:
592 """
593 Returns the file extension for a dynamic/shared library.
595 * FreeBSD: ``"so"``
596 * Linux: ``"so"``
597 * macOS: ``"dylib"``
598 * Windows: ``"dll"``
600 :returns: File extension of a dynamic library.
601 :raises UnknownOperatingSystemException: If the operating system is unknown.
602 """
603 if Platforms.OS_FreeBSD in self._platform: 603 ↛ 604line 603 didn't jump to line 604 because the condition on line 603 was never true
604 return "so"
605 elif Platforms.OS_Linux in self._platform:
606 return "so"
607 elif Platforms.OS_MacOS in self._platform:
608 return "dylib"
609 elif Platforms.OS_Windows in self._platform:
610 return "dll"
611 else: # pragma: no cover
612 raise UnknownOperatingSystemException("Unknown operating system.")
614 def __repr__(self) -> str:
615 """
616 Returns the platform's string representation.
618 :returns: The string representation of the current platform.
619 """
620 return str(self._platform)
622 def __str__(self) -> str:
623 """
624 Returns the platform's string equivalent.
626 :returns: The string equivalent of the platform.
627 """
628 runtime = ""
630 if Platforms.OS_FreeBSD in self._platform: 630 ↛ 631line 630 didn't jump to line 631 because the condition on line 630 was never true
631 platform = "FreeBSD"
632 elif Platforms.OS_MacOS in self._platform:
633 platform = "macOS"
634 elif Platforms.OS_Linux in self._platform:
635 platform = "Linux"
636 elif Platforms.OS_Windows in self._platform: 636 ↛ 639line 636 didn't jump to line 639 because the condition on line 636 was always true
637 platform = "Windows"
638 else:
639 platform = "plat:dec-err"
641 if Platforms.ENV_Native in self._platform:
642 environment = ""
643 elif Platforms.ENV_WSL in self._platform: 643 ↛ 644line 643 didn't jump to line 644 because the condition on line 643 was never true
644 environment = "+WSL"
645 elif Platforms.ENV_MSYS2 in self._platform: 645 ↛ 663line 645 didn't jump to line 663 because the condition on line 645 was always true
646 environment = "+MSYS2"
648 if Platforms.MSYS in self._platform: 648 ↛ 649line 648 didn't jump to line 649 because the condition on line 648 was never true
649 runtime = " - MSYS"
650 elif Platforms.MinGW32 in self._platform: 650 ↛ 651line 650 didn't jump to line 651 because the condition on line 650 was never true
651 runtime = " - MinGW32"
652 elif Platforms.MinGW64 in self._platform:
653 runtime = " - MinGW64"
654 elif Platforms.UCRT64 in self._platform:
655 runtime = " - UCRT64"
656 elif Platforms.Clang32 in self._platform: 656 ↛ 657line 656 didn't jump to line 657 because the condition on line 656 was never true
657 runtime = " - Clang32"
658 elif Platforms.Clang64 in self._platform: 658 ↛ 661line 658 didn't jump to line 661 because the condition on line 658 was always true
659 runtime = " - Clang64"
660 else:
661 runtime = "rt:dec-err"
663 elif Platforms.ENV_Cygwin in self._platform:
664 environment = "+Cygwin"
665 else:
666 environment = "env:dec-err"
668 if Platforms.ARCH_x86_32 in self._platform: 668 ↛ 669line 668 didn't jump to line 669 because the condition on line 668 was never true
669 architecture = "x86-32"
670 elif Platforms.ARCH_x86_64 in self._platform:
671 architecture = "x86-64"
672 elif Platforms.ARCH_AArch64 in self._platform: 672 ↛ 675line 672 didn't jump to line 675 because the condition on line 672 was always true
673 architecture = "aarch64"
674 else:
675 architecture = "arch:dec-err"
677 return f"{platform}{environment} ({architecture}){runtime}"
680CurrentPlatform = Platform() #: Gathered information for the current platform.