Coverage for pyTooling/Platform/__init__.py: 78%
316 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-03 23:02 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-03 23:02 +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.
38.. seealso::
40 :mod:`pyTooling.Process`
41 |rarr| Information about the running process, independent of the platform.
42 :mod:`pyTooling.Filesystem`
43 |rarr| Filesystem statistics, whose path style depends on the platform.
44"""
45from enum import Flag, auto, Enum
47from pyTooling.Decorators import export, readonly
48from pyTooling.Exceptions import ToolingException
49from pyTooling.MetaClasses import ExtendedType
50from pyTooling.Versioning import PythonVersion
53__all__ = ["CurrentPlatform"]
56@export
57class PlatformError(ToolingException):
58 """Base-exception of all exceptions raised by :mod:`pyTooling.Platform`."""
61@export
62class UnknownPlatformError(PlatformError):
63 """
64 The exception is raised by pyTooling.Platform when the platform can't be determined.
66 For debugging purposes, a list of system properties from various APIs is added as notes to this exception to ease
67 debugging unknown or new platforms.
68 """
70 def __init__(self, *args) -> None:
71 """
72 Initialize a new :class:`UnknownPlatformError` instance and add notes with further debugging information.
74 :param args: Forward positional parameters.
75 """
76 super().__init__(*args)
78 import sys
79 import os
80 import platform
81 import sysconfig
83 self.add_note(f"os.name: {os.name}")
84 self.add_note(f"platform.system: {platform.system()}")
85 self.add_note(f"platform.machine: {platform.machine()}")
86 self.add_note(f"platform.architecture: {platform.architecture()}")
87 self.add_note(f"sys.platform: {sys.platform}")
88 self.add_note(f"sysconfig.get_platform: {sysconfig.get_platform()}")
91@export
92class UnknownOperatingSystemError(PlatformError):
93 """The exception is raised by pyTooling.Platform when the operating system is unknown."""
96@export
97class PythonImplementation(Enum):
98 """An enumeration describing the Python implementation (CPython, PyPy, ...)."""
99 Unknown = 0 #: Unknown Python implementation
101 CPython = 1 #: CPython (reference implementation)
102 PyPy = 2 #: PyPy
105@export
106class Platforms(Flag):
107 """A flag describing on which platform Python is running on and/or in which environment it's running in."""
108 Unknown = 0
110 OS_FreeBSD = auto() #: Operating System: BSD (Unix).
111 OS_Linux = auto() #: Operating System: Linux.
112 OS_MacOS = auto() #: Operating System: macOS.
113 OS_Windows = auto() #: Operating System: Windows.
115 OperatingSystem = OS_FreeBSD | OS_Linux | OS_MacOS | OS_Windows #: Mask: Any operating system.
117 SEP_WindowsPath = auto() #: Seperator: Path element seperator (e.g. for directories).
118 SEP_WindowsValue = auto() #: Seperator: Value seperator in variables (e.g. for paths in PATH).
120 ENV_Native = auto() #: Environment: :term:`native`.
121 ENV_WSL = auto() #: Environment: :term:`Windows Subsystem for Linux <WSL>`.
122 ENV_MSYS2 = auto() #: Environment: :term:`MSYS2`.
123 ENV_Cygwin = auto() #: Environment: :term:`Cygwin`.
125 Environment = ENV_Native | ENV_WSL | ENV_MSYS2 | ENV_Cygwin #: Mask: Any environment.
127 CI_None = auto() #: CI: No CI environment detected. Running on host.
128 CI_AppVeyor = auto() #: CI: AppVayor
129 CI_GitHubActions = auto() #: CI: GitHub Actions
130 CI_GitLabCI = auto() #: CI: GitLab CI
131 CI_TravisCI = auto() #: CI: Travis CI
133 ContinuousIntegration = CI_None | CI_AppVeyor | CI_GitHubActions | CI_GitLabCI | CI_TravisCI #: Mask: Any CI environment.
135 ARCH_x86_32 = auto() #: Architecture: x86-32 (IA32).
136 ARCH_x86_64 = auto() #: Architecture: x86-64 (AMD64).
137 ARCH_AArch64 = auto() #: Architecture: AArch64 (arm64).
139 Arch_x86 = ARCH_x86_32 | ARCH_x86_64 #: Mask: Any x86 architecture.
140 Arch_Arm = ARCH_AArch64 #: Mask: Any Arm architecture.
141 Architecture = Arch_x86 | Arch_Arm #: Mask: Any architecture.
143 FreeBSD = OS_FreeBSD | ENV_Native #: Group: native FreeBSD on x86-64.
144 Linux = OS_Linux | ENV_Native #: Group: native Linux on x86-64.
145 MacOS = OS_MacOS | ENV_Native #: Group: native macOS.
146 Windows = OS_Windows | ENV_Native | SEP_WindowsPath | SEP_WindowsValue #: Group: native Windows on x86-64.
148 Linux_x86_64 = Linux | ARCH_x86_64 #: Group: native Linux on x86-64.
149 Linux_AArch64 = Linux | ARCH_AArch64 #: Group: native Linux on aarch64.
150 MacOS_Intel = MacOS | ARCH_x86_64 #: Group: native macOS on x86-64.
151 MacOS_ARM = MacOS | ARCH_AArch64 #: Group: native macOS on aarch64.
152 Windows_x86_64 = Windows | ARCH_x86_64 #: Group: native Windows on x86-64.
153 Windows_AArch64 = Windows | ARCH_AArch64 #: Group: native Windows on aarch64.
155 MSYS = auto() #: MSYS2 Runtime: MSYS.
156 MinGW32 = auto() #: MSYS2 Runtime: :term:`MinGW32 <MinGW>`.
157 MinGW64 = auto() #: MSYS2 Runtime: :term:`MinGW64 <MinGW>`.
158 UCRT64 = auto() #: MSYS2 Runtime: :term:`UCRT64 <UCRT>`.
159 Clang32 = auto() #: MSYS2 Runtime: Clang32.
160 Clang64 = auto() #: MSYS2 Runtime: Clang64.
162 MSYS2_Runtime = MSYS | MinGW32 | MinGW64 | UCRT64 | Clang32 | Clang64 #: Mask: Any MSYS2 runtime environment.
164 Windows_MSYS2_MSYS = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MSYS #: Group: MSYS runtime running on Windows x86-64
165 Windows_MSYS2_MinGW32 = OS_Windows | ENV_MSYS2 | ARCH_x86_32 | MinGW32 #: Group: MinGW32 runtime running on Windows x86-64
166 Windows_MSYS2_MinGW64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MinGW64 #: Group: MinGW64 runtime running on Windows x86-64
167 Windows_MSYS2_UCRT64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | UCRT64 #: Group: UCRT64 runtime running on Windows x86-64
168 Windows_MSYS2_Clang32 = OS_Windows | ENV_MSYS2 | ARCH_x86_32 | Clang32 #: Group: Clang32 runtime running on Windows x86-64
169 Windows_MSYS2_Clang64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | Clang64 #: Group: Clang64 runtime running on Windows x86-64
171 Windows_Cygwin32 = OS_Windows | ENV_Cygwin | ARCH_x86_32 #: Group: 32-bit Cygwin runtime on Windows x86-64
172 Windows_Cygwin64 = OS_Windows | ENV_Cygwin | ARCH_x86_64 #: Group: 64-bit Cygwin runtime on Windows x86-64
175@export
176class Platform(metaclass=ExtendedType, singleton=True, slots=True):
177 """An instance of this class contains all gathered information available from various sources.
179 .. seealso::
181 StackOverflow question: `Python: What OS am I running on? <https://stackoverflow.com/a/54837707/3719459>`__
182 """
184 _platform: Platforms #: Operating system, processor architecture and environment, as flags.
185 _pythonImplementation: PythonImplementation #: The Python implementation running this program (CPython, PyPy).
186 _pythonVersion: PythonVersion #: Version of the Python interpreter running this program.
188 def __init__(self) -> None:
189 """
190 Initializes a platform by accessing multiple APIs of Python to gather all necessary information.
192 :raises UnknownPlatformError: If the operating system or the Python implementation isn't known to pyTooling.
193 """
194 import sys
195 import os
196 import platform
197 import sysconfig
199 # Discover the Python implementation
200 pythonImplementation = platform.python_implementation()
201 if pythonImplementation == "CPython":
202 self._pythonImplementation = PythonImplementation.CPython
203 elif pythonImplementation == "PyPy":
204 self._pythonImplementation = PythonImplementation.PyPy
205 else: # pragma: no cover
206 self._pythonImplementation = PythonImplementation.Unknown
208 # Discover the Python version
209 self._pythonVersion = PythonVersion.FromSysVersionInfo()
211 # Discover the platform
212 self._platform = Platforms.Unknown
214 machine = platform.machine()
215 sys_platform = sys.platform
216 sysconfig_platform = sysconfig.get_platform()
218 if "APPVEYOR" in os.environ: 218 ↛ 219line 218 didn't jump to line 219 because the condition on line 218 was never true
219 self._platform |= Platforms.CI_AppVeyor
220 elif "GITHUB_ACTIONS" in os.environ: 220 ↛ 222line 220 didn't jump to line 222 because the condition on line 220 was always true
221 self._platform |= Platforms.CI_GitHubActions
222 elif "GITLAB_CI" in os.environ:
223 self._platform |= Platforms.CI_GitLabCI
224 elif "TRAVIS" in os.environ:
225 self._platform |= Platforms.CI_TravisCI
226 else:
227 self._platform |= Platforms.CI_None
229 if os.name == "nt":
230 self._platform |= Platforms.OS_Windows
232 if sysconfig_platform == "win32": 232 ↛ 233line 232 didn't jump to line 233 because the condition on line 232 was never true
233 self._platform |= Platforms.ENV_Native | Platforms.ARCH_x86_32 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
234 elif sysconfig_platform == "win-amd64":
235 self._platform |= Platforms.ENV_Native | Platforms.ARCH_x86_64 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
236 elif sysconfig_platform == "win-arm64":
237 self._platform |= Platforms.ENV_Native | Platforms.ARCH_AArch64 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue
238 elif sysconfig_platform.startswith("mingw"):
239 if machine == "AMD64":
240 self._platform |= Platforms.ARCH_x86_64
241 else: # pragma: no cover
242 raise UnknownPlatformError(f"Unknown architecture '{machine}' for Windows.")
244 if sysconfig_platform == "mingw_i686_msvcrt_gnu": 244 ↛ 245line 244 didn't jump to line 245 because the condition on line 244 was never true
245 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW32
246 elif sysconfig_platform == "mingw_x86_64_msvcrt_gnu":
247 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW64
248 elif sysconfig_platform == "mingw_x86_64_ucrt_gnu":
249 self._platform |= Platforms.ENV_MSYS2 | Platforms.UCRT64
250 elif sysconfig_platform == "mingw_x86_64_ucrt_llvm":
251 self._platform |= Platforms.ENV_MSYS2 | Platforms.Clang64
252 elif sysconfig_platform == "mingw_i686": # pragma: no cover
253 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW32
254 elif sysconfig_platform == "mingw_x86_64": # pragma: no cover
255 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW64
256 elif sysconfig_platform == "mingw_x86_64_ucrt": # pragma: no cover
257 self._platform |= Platforms.ENV_MSYS2 | Platforms.UCRT64
258 elif sysconfig_platform == "mingw_x86_64_clang": # pragma: no cover
259 self._platform |= Platforms.ENV_MSYS2 | Platforms.Clang64
260 else: # pragma: no cover
261 raise UnknownPlatformError(f"Unknown MSYS2 architecture '{sysconfig_platform}'.")
262 else: # pragma: no cover
263 raise UnknownPlatformError(f"Unknown platform '{sysconfig_platform}' running on Windows.")
265 elif os.name == "posix":
266 if sys_platform == "linux":
267 self._platform |= Platforms.OS_Linux | Platforms.ENV_Native
269 if sysconfig_platform == "linux-x86_64": # native Linux x86_64; Windows 64 + WSL 269 ↛ 271line 269 didn't jump to line 271 because the condition on line 269 was always true
270 self._platform |= Platforms.ARCH_x86_64
271 elif sysconfig_platform == "linux-aarch64": # native Linux Aarch64
272 self._platform |= Platforms.ARCH_AArch64
273 else: # pragma: no cover
274 raise UnknownPlatformError(f"Unknown architecture '{sysconfig_platform}' for a native Linux.")
276 elif sys_platform == "darwin": 276 ↛ 286line 276 didn't jump to line 286 because the condition on line 276 was always true
277 self._platform |= Platforms.OS_MacOS | Platforms.ENV_Native
279 if machine == "x86_64":
280 self._platform |= Platforms.ARCH_x86_64
281 elif machine == "arm64":
282 self._platform |= Platforms.ARCH_AArch64
283 else: # pragma: no cover
284 raise UnknownPlatformError(f"Unknown architecture '{machine}' for a native macOS.")
286 elif sys_platform == "msys":
287 self._platform |= Platforms.OS_Windows | Platforms.ENV_MSYS2 | Platforms.MSYS
289 if machine == "i686":
290 self._platform |= Platforms.ARCH_x86_32
291 elif machine == "x86_64":
292 self._platform |= Platforms.ARCH_x86_64
293 else: # pragma: no cover
294 raise UnknownPlatformError(f"Unknown architecture '{machine}' for MSYS2-MSYS on Windows.")
296 elif sys_platform == "cygwin":
297 self._platform |= Platforms.OS_Windows
299 if machine == "i686":
300 self._platform |= Platforms.ARCH_x86_32
301 elif machine == "x86_64":
302 self._platform |= Platforms.ARCH_x86_64
303 else: # pragma: no cover
304 raise UnknownPlatformError(f"Unknown architecture '{machine}' for Cygwin on Windows.")
306 elif sys_platform.startswith("freebsd"):
307 self._platform = Platforms.OS_FreeBSD | Platforms.ENV_Native
308 if machine == "amd64":
309 self._platform |= Platforms.ARCH_x86_64
310 elif machine in ("aarch64", "arm64"):
311 self._platform |= Platforms.ARCH_AArch64
312 else: # pragma: no cover
313 raise UnknownPlatformError(f"Unknown architecture '{machine}' for FreeBSD.")
314 else: # pragma: no cover
315 raise UnknownPlatformError(f"Unknown POSIX platform '{sys_platform}'.")
316 else: # pragma: no cover
317 raise UnknownPlatformError(f"Unknown operating system '{os.name}'.")
319 @readonly
320 def PythonImplementation(self) -> PythonImplementation:
321 """
322 Read-only property to access 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 access 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 """
356 Read-only property to return the host's operating system.
358 :returns: The operating system portion of the platform flags.
359 """
360 return self._platform & Platforms.OperatingSystem
362 @readonly
363 def IsNativePlatform(self) -> bool:
364 """Returns true, if the platform is a :term:`native` platform.
366 :returns: ``True``, if the platform is a native platform.
367 """
368 return Platforms.ENV_Native in self._platform
370 @readonly
371 def IsNativeFreeBSD(self) -> bool:
372 """Returns true, if the platform is a :term:`native` FreeBSD platform.
374 :returns: ``True``, if the platform is a native FreeBSD platform.
375 """
376 return (Platforms.OS_FreeBSD in self._platform) and (Platforms.ENV_Native in self._platform)
378 @readonly
379 def IsNativeMacOS(self) -> bool:
380 """Returns true, if the platform is a :term:`native` macOS x86-64 platform.
382 :returns: ``True``, if the platform is a native macOS x86-64 platform.
383 """
384 return Platforms.MacOS in self._platform
386 @readonly
387 def IsNativeLinux(self) -> bool:
388 """Returns true, if the platform is a :term:`native` Linux x86-64 platform.
390 :returns: ``True``, if the platform is a native Linux x86-64 platform.
391 """
392 return Platforms.Linux in self._platform
394 @readonly
395 def IsNativeWindows(self) -> bool:
396 """Returns true, if the platform is a :term:`native` Windows x86-64 platform.
398 :returns: ``True``, if the platform is a native Windows x86-64 platform.
399 """
400 return Platforms.Windows in self._platform
402 @readonly
403 def IsMSYS2Environment(self) -> bool:
404 """Returns true, if the platform is a :term:`MSYS2` environment on Windows.
406 :returns: ``True``, if the platform is a MSYS2 environment on Windows.
407 """
408 return Platforms.ENV_MSYS2 in self._platform
410 @readonly
411 def IsMSYSOnWindows(self) -> bool:
412 """Returns true, if the platform is a MSYS runtime on Windows.
414 :returns: ``True``, if the platform is a MSYS runtime on Windows.
415 """
416 return Platforms.Windows_MSYS2_MSYS in self._platform
418 @readonly
419 def IsMinGW32OnWindows(self) -> bool:
420 """Returns true, if the platform is a :term:`MinGW32 <MinGW>` runtime on Windows.
422 :returns: ``True``, if the platform is a MINGW32 runtime on Windows.
423 """
424 return Platforms.Windows_MSYS2_MinGW32 in self._platform
426 @readonly
427 def IsMinGW64OnWindows(self) -> bool:
428 """Returns true, if the platform is a :term:`MinGW64 <MinGW>` runtime on Windows.
430 :returns: ``True``, if the platform is a MINGW64 runtime on Windows.
431 """
432 return Platforms.Windows_MSYS2_MinGW64 in self._platform
434 @readonly
435 def IsUCRT64OnWindows(self) -> bool:
436 """Returns true, if the platform is a :term:`UCRT64 <UCRT>` runtime on Windows.
438 :returns: ``True``, if the platform is a UCRT64 runtime on Windows.
439 """
440 return Platforms.Windows_MSYS2_UCRT64 in self._platform
442 @readonly
443 def IsClang32OnWindows(self) -> bool:
444 """Returns true, if the platform is a Clang32 runtime on Windows.
446 :returns: ``True``, if the platform is a Clang32 runtime on Windows.
447 """
448 return Platforms.Windows_MSYS2_Clang32 in self._platform
450 @readonly
451 def IsClang64OnWindows(self) -> bool:
452 """Returns true, if the platform is a Clang64 runtime on Windows.
454 :returns: ``True``, if the platform is a Clang64 runtime on Windows.
455 """
456 return Platforms.Windows_MSYS2_Clang64 in self._platform
458 @readonly
459 def IsCygwin32OnWindows(self) -> bool:
460 """Returns true, if the platform is a 32-bit Cygwin runtime on Windows.
462 :returns: ``True``, if the platform is a 32-bit Cygwin runtime on Windows.
463 """
464 return Platforms.Windows_Cygwin32 in self._platform
466 @readonly
467 def IsCygwin64OnWindows(self) -> bool:
468 """Returns true, if the platform is a 64-bit Cygwin runtime on Windows.
470 :returns: ``True``, if the platform is a 64-bit Cygwin runtime on Windows.
471 """
472 return Platforms.Windows_Cygwin64 in self._platform
474 @readonly
475 def IsPOSIX(self) -> bool:
476 """
477 Returns true, if the platform is POSIX or POSIX-like.
479 :returns: ``True``, if POSIX or POSIX-like.
480 """
481 return Platforms.SEP_WindowsPath not in self._platform
483 @readonly
484 def IsCI(self) -> bool:
485 """
486 Returns true, if the platform is a CI environment.
488 :returns: ``True``, if on CI runner.
489 """
490 return Platforms.CI_None not in self._platform
492 @readonly
493 def IsAppVeyor(self) -> bool:
494 """
495 Returns true, if the platform is on AppVeyor.
497 :returns: ``True``, if on AppVeyor.
498 """
499 return Platforms.CI_AppVeyor in self._platform
501 @readonly
502 def IsGitHub(self) -> bool:
503 """
504 Returns true, if the platform is on GitHub.
506 :returns: ``True``, if on GitHub.
507 """
508 return Platforms.CI_GitHubActions in self._platform
510 @readonly
511 def IsGitLab(self) -> bool:
512 """
513 Returns true, if the platform is on GitLab CI.
515 :returns: ``True``, if on GitLab CI.
516 """
517 return Platforms.CI_GitLabCI in self._platform
519 @readonly
520 def IsTravisCI(self) -> bool:
521 """
522 Returns true, if the platform is on Travis CI.
524 :returns: ``True``, if on Travis CI.
525 """
526 return Platforms.CI_TravisCI in self._platform
528 @readonly
529 def PathSeperator(self) -> str:
530 """
531 Returns the path element separation character (e.g. for directories).
533 * POSIX-like: ``/``
534 * Windows: ``\\``
536 :returns: Path separation character.
537 """
538 if Platforms.SEP_WindowsPath in self._platform:
539 return "\\"
540 else:
541 return "/"
543 @readonly
544 def ValueSeperator(self) -> str:
545 """
546 Returns the value separation character (e.g. for paths in PATH).
548 * POSIX-like: ``:``
549 * Windows: ``;``
551 :returns: Value separation character.
552 """
553 if Platforms.SEP_WindowsValue in self._platform:
554 return ";"
555 else:
556 return ":"
558 @readonly
559 def ExecutableExtension(self) -> str:
560 """
561 Returns the file extension for an executable.
563 * FreeBSD: ``""`` (empty string)
564 * Linux: ``""`` (empty string)
565 * macOS: ``""`` (empty string)
566 * Windows: ``"exe"``
568 :returns: File extension of an executable.
569 :raises UnknownOperatingSystemError: If the operating system is unknown.
570 """
572 if Platforms.OS_FreeBSD in self._platform: 572 ↛ 573line 572 didn't jump to line 573 because the condition on line 572 was never true
573 return ""
574 elif Platforms.OS_Linux in self._platform:
575 return ""
576 elif Platforms.OS_MacOS in self._platform:
577 return ""
578 elif Platforms.OS_Windows in self._platform:
579 return "exe"
580 else: # pragma: no cover
581 raise UnknownOperatingSystemError("Unknown operating system.")
583 @readonly
584 def StaticLibraryExtension(self) -> str:
585 """
586 Returns the file extension for a static library.
588 * FreeBSD: ``"a"``
589 * Linux: ``"a"``
590 * macOS: ``"lib"``
591 * Windows: ``"lib"``
593 :returns: File extension of a static library.
594 :raises UnknownOperatingSystemError: If the operating system is unknown.
595 """
596 if Platforms.OS_FreeBSD in self._platform: 596 ↛ 597line 596 didn't jump to line 597 because the condition on line 596 was never true
597 return "a"
598 elif Platforms.OS_Linux in self._platform:
599 return "a"
600 elif Platforms.OS_MacOS in self._platform:
601 return "a"
602 elif Platforms.OS_Windows in self._platform:
603 return "lib"
604 else: # pragma: no cover
605 raise UnknownOperatingSystemError("Unknown operating system.")
607 @readonly
608 def DynamicLibraryExtension(self) -> str:
609 """
610 Returns the file extension for a dynamic/shared library.
612 * FreeBSD: ``"so"``
613 * Linux: ``"so"``
614 * macOS: ``"dylib"``
615 * Windows: ``"dll"``
617 :returns: File extension of a dynamic library.
618 :raises UnknownOperatingSystemError: If the operating system is unknown.
619 """
620 if Platforms.OS_FreeBSD in self._platform: 620 ↛ 621line 620 didn't jump to line 621 because the condition on line 620 was never true
621 return "so"
622 elif Platforms.OS_Linux in self._platform:
623 return "so"
624 elif Platforms.OS_MacOS in self._platform:
625 return "dylib"
626 elif Platforms.OS_Windows in self._platform:
627 return "dll"
628 else: # pragma: no cover
629 raise UnknownOperatingSystemError("Unknown operating system.")
631 def __repr__(self) -> str:
632 """
633 Returns the platform's string representation.
635 :returns: The string representation of the current platform.
636 """
637 return str(self._platform)
639 def __str__(self) -> str:
640 """
641 Returns the platform's string equivalent.
643 :returns: The string equivalent of the platform.
644 """
645 runtime = ""
647 if Platforms.OS_FreeBSD in self._platform: 647 ↛ 648line 647 didn't jump to line 648 because the condition on line 647 was never true
648 platform = "FreeBSD"
649 elif Platforms.OS_MacOS in self._platform:
650 platform = "macOS"
651 elif Platforms.OS_Linux in self._platform:
652 platform = "Linux"
653 elif Platforms.OS_Windows in self._platform: 653 ↛ 656line 653 didn't jump to line 656 because the condition on line 653 was always true
654 platform = "Windows"
655 else:
656 platform = "plat:dec-err"
658 if Platforms.ENV_Native in self._platform:
659 environment = ""
660 elif Platforms.ENV_WSL in self._platform: 660 ↛ 661line 660 didn't jump to line 661 because the condition on line 660 was never true
661 environment = "+WSL"
662 elif Platforms.ENV_MSYS2 in self._platform: 662 ↛ 680line 662 didn't jump to line 680 because the condition on line 662 was always true
663 environment = "+MSYS2"
665 if Platforms.MSYS in self._platform: 665 ↛ 666line 665 didn't jump to line 666 because the condition on line 665 was never true
666 runtime = " - MSYS"
667 elif Platforms.MinGW32 in self._platform: 667 ↛ 668line 667 didn't jump to line 668 because the condition on line 667 was never true
668 runtime = " - MinGW32"
669 elif Platforms.MinGW64 in self._platform:
670 runtime = " - MinGW64"
671 elif Platforms.UCRT64 in self._platform:
672 runtime = " - UCRT64"
673 elif Platforms.Clang32 in self._platform: 673 ↛ 674line 673 didn't jump to line 674 because the condition on line 673 was never true
674 runtime = " - Clang32"
675 elif Platforms.Clang64 in self._platform: 675 ↛ 678line 675 didn't jump to line 678 because the condition on line 675 was always true
676 runtime = " - Clang64"
677 else:
678 runtime = "rt:dec-err"
680 elif Platforms.ENV_Cygwin in self._platform:
681 environment = "+Cygwin"
682 else:
683 environment = "env:dec-err"
685 if Platforms.ARCH_x86_32 in self._platform: 685 ↛ 686line 685 didn't jump to line 686 because the condition on line 685 was never true
686 architecture = "x86-32"
687 elif Platforms.ARCH_x86_64 in self._platform:
688 architecture = "x86-64"
689 elif Platforms.ARCH_AArch64 in self._platform: 689 ↛ 692line 689 didn't jump to line 692 because the condition on line 689 was always true
690 architecture = "aarch64"
691 else:
692 architecture = "arch:dec-err"
694 return f"{platform}{environment} ({architecture}){runtime}"
697CurrentPlatform = Platform() #: Gathered information for the current platform.