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

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. 

33 

34.. hint:: See :ref:`high-level help <COMMON/Platform>` for explanations and usage examples. 

35""" 

36from enum import Flag, auto 

37 

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.*'!") 

45 

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 

54 

55 

56__all__ = ["CurrentPlatform"] 

57 

58 

59@export 

60class PlatformException(ToolingException): 

61 """Base-exception of all exceptions raised by :mod:`pyTooling.Platform`.""" 

62 

63 

64@export 

65class UnknownPlatformException(PlatformException): 

66 """ 

67 The exception is raised by pyTooling.Platform when the platform can't be determined. 

68 

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 """ 

72 

73 def __init__(self, *args) -> None: 

74 """ 

75 Initialize a new :class:`UnknownPlatformException` instance and add notes with further debugging information. 

76 

77 :param args: Forward positional parameters. 

78 """ 

79 super().__init__(*args) 

80 

81 import sys 

82 import os 

83 import platform 

84 import sysconfig 

85 

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()}") 

92 

93 

94@export 

95class UnknownOperatingSystemException(PlatformException): 

96 """The exception is raised by pyTooling.Platform when the operating system is unknown.""" 

97 

98 

99@export 

100class PythonImplementation(Flag): 

101 Unknown = 0 

102 

103 CPython = 1 

104 PyPy = 2 

105 

106 

107@export 

108class Platforms(Flag): 

109 Unknown = 0 

110 

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. 

115 

116 OperatingSystem = OS_FreeBSD | OS_Linux | OS_MacOS | OS_Windows #: Mask: Any operating system. 

117 

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). 

120 

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`. 

125 

126 Environment = ENV_Native | ENV_WSL | ENV_MSYS2 | ENV_Cygwin #: Mask: Any environment. 

127 

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). 

131 

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. 

135 

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. 

140 

141 MacOS_Intel = MacOS | ARCH_x86_64 #: Group: native macOS on x86-64. 

142 MacOS_ARM = MacOS | ARCH_AArch64 #: Group: native macOS on aarch64. 

143 

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. 

150 

151 MSYS2_Runtime = MSYS | MinGW32 | MinGW64 | UCRT64 | Clang32 | Clang64 #: Mask: Any MSYS2 runtime environment. 

152 

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 

159 

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 

162 

163 

164@export 

165class Platform(metaclass=ExtendedType, singleton=True, slots=True): 

166 """An instance of this class contains all gathered information available from various sources. 

167 

168 .. seealso:: 

169 

170 StackOverflow question: `Python: What OS am I running on? <https://stackoverflow.com/a/54837707/3719459>`__ 

171 """ 

172 

173 _platform: Platforms 

174 _pythonImplementation: PythonImplementation 

175 _pythonVersion: PythonVersion 

176 

177 def __init__(self) -> None: 

178 import sys 

179 import os 

180 import platform 

181 import sysconfig 

182 

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 

191 

192 # Discover the Python version 

193 self._pythonVersion = PythonVersion.FromSysVersionInfo() 

194 

195 # Discover the platform 

196 self._platform = Platforms.Unknown 

197 

198 machine = platform.machine() 

199 sys_platform = sys.platform 

200 sysconfig_platform = sysconfig.get_platform() 

201 

202 if os.name == "nt": 

203 self._platform |= Platforms.OS_Windows 

204 

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.") 

214 

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.") 

235 

236 elif os.name == "posix": 

237 if sys_platform == "linux": 

238 self._platform |= Platforms.OS_Linux | Platforms.ENV_Native 

239 

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.") 

246 

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 

249 

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.") 

256 

257 elif sys_platform == "msys": 

258 self._platform |= Platforms.OS_Windows | Platforms.ENV_MSYS2 | Platforms.MSYS 

259 

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.") 

266 

267 elif sys_platform == "cygwin": 

268 self._platform |= Platforms.OS_Windows 

269 

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.") 

276 

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}'.") 

286 

287 @readonly 

288 def PythonImplementation(self) -> PythonImplementation: 

289 return self._pythonImplementation 

290 

291 @readonly 

292 def IsCPython(self) -> bool: 

293 """Returns true, if the Python implementation is a :term:`CPython`. 

294 

295 :returns: ``True``, if the Python implementation is CPython. 

296 """ 

297 return self._pythonImplementation is PythonImplementation.CPython 

298 

299 @readonly 

300 def IsPyPy(self) -> bool: 

301 """Returns true, if the Python implementation is a :term:`PyPy`. 

302 

303 :returns: ``True``, if the Python implementation is PyPY. 

304 """ 

305 return self._pythonImplementation is PythonImplementation.PyPy 

306 

307 @readonly 

308 def PythonVersion(self) -> PythonVersion: 

309 return self._pythonVersion 

310 

311 @readonly 

312 def HostOperatingSystem(self) -> Platforms: 

313 return self._platform & Platforms.OperatingSystem 

314 

315 @readonly 

316 def IsNativePlatform(self) -> bool: 

317 """Returns true, if the platform is a :term:`native` platform. 

318 

319 :returns: ``True``, if the platform is a native platform. 

320 """ 

321 return Platforms.ENV_Native in self._platform 

322 

323 @readonly 

324 def IsNativeFreeBSD(self) -> bool: 

325 """Returns true, if the platform is a :term:`native` FreeBSD x86-64 platform. 

326 

327 :returns: ``True``, if the platform is a native FreeBSD x86-64 platform. 

328 """ 

329 return Platforms.FreeBSD in self._platform 

330 

331 @readonly 

332 def IsNativeMacOS(self) -> bool: 

333 """Returns true, if the platform is a :term:`native` macOS x86-64 platform. 

334 

335 :returns: ``True``, if the platform is a native macOS x86-64 platform. 

336 """ 

337 return Platforms.MacOS in self._platform 

338 

339 @readonly 

340 def IsNativeLinux(self) -> bool: 

341 """Returns true, if the platform is a :term:`native` Linux x86-64 platform. 

342 

343 :returns: ``True``, if the platform is a native Linux x86-64 platform. 

344 """ 

345 return Platforms.Linux in self._platform 

346 

347 @readonly 

348 def IsNativeWindows(self) -> bool: 

349 """Returns true, if the platform is a :term:`native` Windows x86-64 platform. 

350 

351 :returns: ``True``, if the platform is a native Windows x86-64 platform. 

352 """ 

353 return Platforms.Windows in self._platform 

354 

355 @readonly 

356 def IsMSYS2Environment(self) -> bool: 

357 """Returns true, if the platform is a :term:`MSYS2` environment on Windows. 

358 

359 :returns: ``True``, if the platform is a MSYS2 environment on Windows. 

360 """ 

361 return Platforms.ENV_MSYS2 in self._platform 

362 

363 @readonly 

364 def IsMSYSOnWindows(self) -> bool: 

365 """Returns true, if the platform is a MSYS runtime on Windows. 

366 

367 :returns: ``True``, if the platform is a MSYS runtime on Windows. 

368 """ 

369 return Platforms.Windows_MSYS2_MSYS in self._platform 

370 

371 @readonly 

372 def IsMinGW32OnWindows(self) -> bool: 

373 """Returns true, if the platform is a :term:`MinGW32 <MinGW>` runtime on Windows. 

374 

375 :returns: ``True``, if the platform is a MINGW32 runtime on Windows. 

376 """ 

377 return Platforms.Windows_MSYS2_MinGW32 in self._platform 

378 

379 @readonly 

380 def IsMinGW64OnWindows(self) -> bool: 

381 """Returns true, if the platform is a :term:`MinGW64 <MinGW>` runtime on Windows. 

382 

383 :returns: ``True``, if the platform is a MINGW64 runtime on Windows. 

384 """ 

385 return Platforms.Windows_MSYS2_MinGW64 in self._platform 

386 

387 @readonly 

388 def IsUCRT64OnWindows(self) -> bool: 

389 """Returns true, if the platform is a :term:`UCRT64 <UCRT>` runtime on Windows. 

390 

391 :returns: ``True``, if the platform is a UCRT64 runtime on Windows. 

392 """ 

393 return Platforms.Windows_MSYS2_UCRT64 in self._platform 

394 

395 @readonly 

396 def IsClang32OnWindows(self) -> bool: 

397 """Returns true, if the platform is a Clang32 runtime on Windows. 

398 

399 :returns: ``True``, if the platform is a Clang32 runtime on Windows. 

400 """ 

401 return Platforms.Windows_MSYS2_Clang32 in self._platform 

402 

403 @readonly 

404 def IsClang64OnWindows(self) -> bool: 

405 """Returns true, if the platform is a Clang64 runtime on Windows. 

406 

407 :returns: ``True``, if the platform is a Clang64 runtime on Windows. 

408 """ 

409 return Platforms.Windows_MSYS2_Clang64 in self._platform 

410 

411 @readonly 

412 def IsCygwin32OnWindows(self) -> bool: 

413 """Returns true, if the platform is a 32-bit Cygwin runtime on Windows. 

414 

415 :returns: ``True``, if the platform is a 32-bit Cygwin runtime on Windows. 

416 """ 

417 return Platforms.Windows_Cygwin32 in self._platform 

418 

419 @readonly 

420 def IsCygwin64OnWindows(self) -> bool: 

421 """Returns true, if the platform is a 64-bit Cygwin runtime on Windows. 

422 

423 :returns: ``True``, if the platform is a 64-bit Cygwin runtime on Windows. 

424 """ 

425 return Platforms.Windows_Cygwin64 in self._platform 

426 

427 @readonly 

428 def IsPOSIX(self) -> bool: 

429 """ 

430 Returns true, if the platform is POSIX or POSIX-like. 

431 

432 :returns: ``True``, if POSIX or POSIX-like. 

433 """ 

434 return Platforms.SEP_WindowsPath not in self._platform 

435 

436 @readonly 

437 def PathSeperator(self) -> str: 

438 """ 

439 Returns the path element separation character (e.g. for directories). 

440 

441 * POSIX-like: ``/`` 

442 * Windows: ``\\`` 

443 

444 :returns: Path separation character. 

445 """ 

446 if Platforms.SEP_WindowsPath in self._platform: 

447 return "\\" 

448 else: 

449 return "/" 

450 

451 @readonly 

452 def ValueSeperator(self) -> str: 

453 """ 

454 Returns the value separation character (e.g. for paths in PATH). 

455 

456 * POSIX-like: ``:`` 

457 * Windows: ``;`` 

458 

459 :returns: Value separation character. 

460 """ 

461 if Platforms.SEP_WindowsValue in self._platform: 

462 return ";" 

463 else: 

464 return ":" 

465 

466 @readonly 

467 def ExecutableExtension(self) -> str: 

468 """ 

469 Returns the file extension for an executable. 

470 

471 * FreeBSD: ``""`` (empty string) 

472 * Linux: ``""`` (empty string) 

473 * macOS: ``""`` (empty string) 

474 * Windows: ``"exe"`` 

475 

476 :returns: File extension of an executable. 

477 :raises UnknownOperatingSystemException: If the operating system is unknown. 

478 """ 

479 

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.") 

490 

491 @readonly 

492 def StaticLibraryExtension(self) -> str: 

493 """ 

494 Returns the file extension for a static library. 

495 

496 * FreeBSD: ``"a"`` 

497 * Linux: ``"a"`` 

498 * macOS: ``"lib"`` 

499 * Windows: ``"lib"`` 

500 

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.") 

514 

515 @readonly 

516 def DynamicLibraryExtension(self) -> str: 

517 """ 

518 Returns the file extension for a dynamic/shared library. 

519 

520 * FreeBSD: ``"so"`` 

521 * Linux: ``"so"`` 

522 * macOS: ``"dylib"`` 

523 * Windows: ``"dll"`` 

524 

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.") 

538 

539 def __repr__(self) -> str: 

540 return str(self._platform) 

541 

542 def __str__(self) -> str: 

543 runtime = "" 

544 

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" 

555 

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" 

562 

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" 

577 

578 elif Platforms.ENV_Cygwin in self._platform: 

579 environment = "+Cygwin" 

580 else: 

581 environment = "env:dec-err" 

582 

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" 

591 

592 return f"{platform}{environment} ({architecture}){runtime}" 

593 

594 

595CurrentPlatform = Platform() #: Gathered information for the current platform.