Coverage for pyTooling/Platform/__init__.py: 78%

313 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-22 21:29 +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. 

33 

34.. hint:: 

35 

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

37 

38.. seealso:: 

39 

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 

46 

47from pyTooling.Decorators import export, readonly 

48from pyTooling.Exceptions import ToolingException 

49from pyTooling.MetaClasses import ExtendedType 

50from pyTooling.Versioning import PythonVersion 

51 

52 

53__all__ = ["CurrentPlatform"] 

54 

55 

56@export 

57class PlatformException(ToolingException): 

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

59 

60 

61@export 

62class UnknownPlatformException(PlatformException): 

63 """ 

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

65 

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

69 

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

71 """ 

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

73 

74 :param args: Forward positional parameters. 

75 """ 

76 super().__init__(*args) 

77 

78 import sys 

79 import os 

80 import platform 

81 import sysconfig 

82 

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

89 

90 

91@export 

92class UnknownOperatingSystemException(PlatformException): 

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

94 

95 

96@export 

97class PythonImplementation(Enum): 

98 """An enumeration describing the Python implementation (CPython, PyPy, ...).""" 

99 Unknown = 0 #: Unknown Python implementation 

100 

101 CPython = 1 #: CPython (reference implementation) 

102 PyPy = 2 #: PyPy 

103 

104 

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 

109 

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. 

114 

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

116 

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

119 

120 ENV_Native = auto() #: Environment: :term:`native`. 

121 ENV_WSL = auto() #: Environment: :term:`Windows System for Linux <WSL>`. 

122 ENV_MSYS2 = auto() #: Environment: :term:`MSYS2`. 

123 ENV_Cygwin = auto() #: Environment: :term:`Cygwin`. 

124 

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

126 

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 

132 

133 ContinuousIntegration = CI_None | CI_AppVeyor | CI_GitHubActions | CI_GitLabCI | CI_TravisCI #: Mask: Any CI environment. 

134 

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

138 

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. 

142 

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. 

147 

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. 

154 

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. 

161 

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

163 

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 

170 

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 

173 

174 

175@export 

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

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

178 

179 .. seealso:: 

180 

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

182 """ 

183 

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. 

187 

188 def __init__(self) -> None: 

189 """ 

190 Initializes a platform by accessing multiple APIs of Python to gather all necessary information. 

191 

192 :raises UnknownPlatformException: 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 

198 

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 

207 

208 # Discover the Python version 

209 self._pythonVersion = PythonVersion.FromSysVersionInfo() 

210 

211 # Discover the platform 

212 self._platform = Platforms.Unknown 

213 

214 machine = platform.machine() 

215 sys_platform = sys.platform 

216 sysconfig_platform = sysconfig.get_platform() 

217 

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 

228 

229 if os.name == "nt": 

230 self._platform |= Platforms.OS_Windows 

231 

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 UnknownPlatformException(f"Unknown architecture '{machine}' for Windows.") 

243 

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 UnknownPlatformException(f"Unknown MSYS2 architecture '{sysconfig_platform}'.") 

262 else: # pragma: no cover 

263 raise UnknownPlatformException(f"Unknown platform '{sysconfig_platform}' running on Windows.") 

264 

265 elif os.name == "posix": 

266 if sys_platform == "linux": 

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

268 

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 UnknownPlatformException(f"Unknown architecture '{sysconfig_platform}' for a native Linux.") 

275 

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 

278 

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 UnknownPlatformException(f"Unknown architecture '{machine}' for a native macOS.") 

285 

286 elif sys_platform == "msys": 

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

288 

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 UnknownPlatformException(f"Unknown architecture '{machine}' for MSYS2-MSYS on Windows.") 

295 

296 elif sys_platform == "cygwin": 

297 self._platform |= Platforms.OS_Windows 

298 

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 UnknownPlatformException(f"Unknown architecture '{machine}' for Cygwin on Windows.") 

305 

306 elif sys_platform.startswith("freebsd"): 

307 if machine == "amd64": 

308 self._platform = Platforms.FreeBSD 

309 else: # pragma: no cover 

310 raise UnknownPlatformException(f"Unknown architecture '{machine}' for FreeBSD.") 

311 else: # pragma: no cover 

312 raise UnknownPlatformException(f"Unknown POSIX platform '{sys_platform}'.") 

313 else: # pragma: no cover 

314 raise UnknownPlatformException(f"Unknown operating system '{os.name}'.") 

315 

316 @readonly 

317 def PythonImplementation(self) -> PythonImplementation: 

318 """ 

319 Read-only property to access the :class:`PythonImplementation` of the current interpreter. 

320 

321 :returns: Python implementation of the current interpreter. 

322 """ 

323 return self._pythonImplementation 

324 

325 @readonly 

326 def IsCPython(self) -> bool: 

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

328 

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

330 """ 

331 return self._pythonImplementation is PythonImplementation.CPython 

332 

333 @readonly 

334 def IsPyPy(self) -> bool: 

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

336 

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

338 """ 

339 return self._pythonImplementation is PythonImplementation.PyPy 

340 

341 @readonly 

342 def PythonVersion(self) -> PythonVersion: 

343 """ 

344 Read-only property to access the :class:`pyTooling.Versioning.PythonVersion` of the current interpreter. 

345 

346 :returns: Python version of the current interpreter. 

347 """ 

348 return self._pythonVersion 

349 

350 @readonly 

351 def HostOperatingSystem(self) -> Platforms: 

352 """ 

353 Read-only property to return the host's operating system. 

354 

355 :returns: The operating system portion of the platform flags. 

356 """ 

357 return self._platform & Platforms.OperatingSystem 

358 

359 @readonly 

360 def IsNativePlatform(self) -> bool: 

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

362 

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

364 """ 

365 return Platforms.ENV_Native in self._platform 

366 

367 @readonly 

368 def IsNativeFreeBSD(self) -> bool: 

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

370 

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

372 """ 

373 return Platforms.FreeBSD in self._platform 

374 

375 @readonly 

376 def IsNativeMacOS(self) -> bool: 

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

378 

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

380 """ 

381 return Platforms.MacOS in self._platform 

382 

383 @readonly 

384 def IsNativeLinux(self) -> bool: 

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

386 

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

388 """ 

389 return Platforms.Linux in self._platform 

390 

391 @readonly 

392 def IsNativeWindows(self) -> bool: 

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

394 

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

396 """ 

397 return Platforms.Windows in self._platform 

398 

399 @readonly 

400 def IsMSYS2Environment(self) -> bool: 

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

402 

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

404 """ 

405 return Platforms.ENV_MSYS2 in self._platform 

406 

407 @readonly 

408 def IsMSYSOnWindows(self) -> bool: 

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

410 

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

412 """ 

413 return Platforms.Windows_MSYS2_MSYS in self._platform 

414 

415 @readonly 

416 def IsMinGW32OnWindows(self) -> bool: 

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

418 

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

420 """ 

421 return Platforms.Windows_MSYS2_MinGW32 in self._platform 

422 

423 @readonly 

424 def IsMinGW64OnWindows(self) -> bool: 

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

426 

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

428 """ 

429 return Platforms.Windows_MSYS2_MinGW64 in self._platform 

430 

431 @readonly 

432 def IsUCRT64OnWindows(self) -> bool: 

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

434 

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

436 """ 

437 return Platforms.Windows_MSYS2_UCRT64 in self._platform 

438 

439 @readonly 

440 def IsClang32OnWindows(self) -> bool: 

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

442 

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

444 """ 

445 return Platforms.Windows_MSYS2_Clang32 in self._platform 

446 

447 @readonly 

448 def IsClang64OnWindows(self) -> bool: 

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

450 

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

452 """ 

453 return Platforms.Windows_MSYS2_Clang64 in self._platform 

454 

455 @readonly 

456 def IsCygwin32OnWindows(self) -> bool: 

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

458 

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

460 """ 

461 return Platforms.Windows_Cygwin32 in self._platform 

462 

463 @readonly 

464 def IsCygwin64OnWindows(self) -> bool: 

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

466 

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

468 """ 

469 return Platforms.Windows_Cygwin64 in self._platform 

470 

471 @readonly 

472 def IsPOSIX(self) -> bool: 

473 """ 

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

475 

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

477 """ 

478 return Platforms.SEP_WindowsPath not in self._platform 

479 

480 @readonly 

481 def IsCI(self) -> bool: 

482 """ 

483 Returns true, if the platform is a CI environment. 

484 

485 :returns: ``True``, if on CI runner. 

486 """ 

487 return Platforms.CI_None not in self._platform 

488 

489 @readonly 

490 def IsAppVeyor(self) -> bool: 

491 """ 

492 Returns true, if the platform is on AppVeyor. 

493 

494 :returns: ``True``, if on AppVeyor. 

495 """ 

496 return Platforms.CI_AppVeyor in self._platform 

497 

498 @readonly 

499 def IsGitHub(self) -> bool: 

500 """ 

501 Returns true, if the platform is on GitHub. 

502 

503 :returns: ``True``, if on GitHub. 

504 """ 

505 return Platforms.CI_GitHubActions in self._platform 

506 

507 @readonly 

508 def IsGitLab(self) -> bool: 

509 """ 

510 Returns true, if the platform is on GitLab CI. 

511 

512 :returns: ``True``, if on GitLab CI. 

513 """ 

514 return Platforms.CI_GitLabCI in self._platform 

515 

516 @readonly 

517 def IsTravisCI(self) -> bool: 

518 """ 

519 Returns true, if the platform is on Travis CI. 

520 

521 :returns: ``True``, if on Travis CI. 

522 """ 

523 return Platforms.CI_TravisCI in self._platform 

524 

525 @readonly 

526 def PathSeperator(self) -> str: 

527 """ 

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

529 

530 * POSIX-like: ``/`` 

531 * Windows: ``\\`` 

532 

533 :returns: Path separation character. 

534 """ 

535 if Platforms.SEP_WindowsPath in self._platform: 

536 return "\\" 

537 else: 

538 return "/" 

539 

540 @readonly 

541 def ValueSeperator(self) -> str: 

542 """ 

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

544 

545 * POSIX-like: ``:`` 

546 * Windows: ``;`` 

547 

548 :returns: Value separation character. 

549 """ 

550 if Platforms.SEP_WindowsValue in self._platform: 

551 return ";" 

552 else: 

553 return ":" 

554 

555 @readonly 

556 def ExecutableExtension(self) -> str: 

557 """ 

558 Returns the file extension for an executable. 

559 

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

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

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

563 * Windows: ``"exe"`` 

564 

565 :returns: File extension of an executable. 

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

567 """ 

568 

569 if Platforms.OS_FreeBSD in self._platform: 569 ↛ 570line 569 didn't jump to line 570 because the condition on line 569 was never true

570 return "" 

571 elif Platforms.OS_Linux in self._platform: 

572 return "" 

573 elif Platforms.OS_MacOS in self._platform: 

574 return "" 

575 elif Platforms.OS_Windows in self._platform: 

576 return "exe" 

577 else: # pragma: no cover 

578 raise UnknownOperatingSystemException("Unknown operating system.") 

579 

580 @readonly 

581 def StaticLibraryExtension(self) -> str: 

582 """ 

583 Returns the file extension for a static library. 

584 

585 * FreeBSD: ``"a"`` 

586 * Linux: ``"a"`` 

587 * macOS: ``"lib"`` 

588 * Windows: ``"lib"`` 

589 

590 :returns: File extension of a static library. 

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

592 """ 

593 if Platforms.OS_FreeBSD in self._platform: 593 ↛ 594line 593 didn't jump to line 594 because the condition on line 593 was never true

594 return "a" 

595 elif Platforms.OS_Linux in self._platform: 

596 return "a" 

597 elif Platforms.OS_MacOS in self._platform: 

598 return "a" 

599 elif Platforms.OS_Windows in self._platform: 

600 return "lib" 

601 else: # pragma: no cover 

602 raise UnknownOperatingSystemException("Unknown operating system.") 

603 

604 @readonly 

605 def DynamicLibraryExtension(self) -> str: 

606 """ 

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

608 

609 * FreeBSD: ``"so"`` 

610 * Linux: ``"so"`` 

611 * macOS: ``"dylib"`` 

612 * Windows: ``"dll"`` 

613 

614 :returns: File extension of a dynamic library. 

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

616 """ 

617 if Platforms.OS_FreeBSD in self._platform: 617 ↛ 618line 617 didn't jump to line 618 because the condition on line 617 was never true

618 return "so" 

619 elif Platforms.OS_Linux in self._platform: 

620 return "so" 

621 elif Platforms.OS_MacOS in self._platform: 

622 return "dylib" 

623 elif Platforms.OS_Windows in self._platform: 

624 return "dll" 

625 else: # pragma: no cover 

626 raise UnknownOperatingSystemException("Unknown operating system.") 

627 

628 def __repr__(self) -> str: 

629 """ 

630 Returns the platform's string representation. 

631 

632 :returns: The string representation of the current platform. 

633 """ 

634 return str(self._platform) 

635 

636 def __str__(self) -> str: 

637 """ 

638 Returns the platform's string equivalent. 

639 

640 :returns: The string equivalent of the platform. 

641 """ 

642 runtime = "" 

643 

644 if Platforms.OS_FreeBSD in self._platform: 644 ↛ 645line 644 didn't jump to line 645 because the condition on line 644 was never true

645 platform = "FreeBSD" 

646 elif Platforms.OS_MacOS in self._platform: 

647 platform = "macOS" 

648 elif Platforms.OS_Linux in self._platform: 

649 platform = "Linux" 

650 elif Platforms.OS_Windows in self._platform: 650 ↛ 653line 650 didn't jump to line 653 because the condition on line 650 was always true

651 platform = "Windows" 

652 else: 

653 platform = "plat:dec-err" 

654 

655 if Platforms.ENV_Native in self._platform: 

656 environment = "" 

657 elif Platforms.ENV_WSL in self._platform: 657 ↛ 658line 657 didn't jump to line 658 because the condition on line 657 was never true

658 environment = "+WSL" 

659 elif Platforms.ENV_MSYS2 in self._platform: 659 ↛ 677line 659 didn't jump to line 677 because the condition on line 659 was always true

660 environment = "+MSYS2" 

661 

662 if Platforms.MSYS in self._platform: 662 ↛ 663line 662 didn't jump to line 663 because the condition on line 662 was never true

663 runtime = " - MSYS" 

664 elif Platforms.MinGW32 in self._platform: 664 ↛ 665line 664 didn't jump to line 665 because the condition on line 664 was never true

665 runtime = " - MinGW32" 

666 elif Platforms.MinGW64 in self._platform: 

667 runtime = " - MinGW64" 

668 elif Platforms.UCRT64 in self._platform: 

669 runtime = " - UCRT64" 

670 elif Platforms.Clang32 in self._platform: 670 ↛ 671line 670 didn't jump to line 671 because the condition on line 670 was never true

671 runtime = " - Clang32" 

672 elif Platforms.Clang64 in self._platform: 672 ↛ 675line 672 didn't jump to line 675 because the condition on line 672 was always true

673 runtime = " - Clang64" 

674 else: 

675 runtime = "rt:dec-err" 

676 

677 elif Platforms.ENV_Cygwin in self._platform: 

678 environment = "+Cygwin" 

679 else: 

680 environment = "env:dec-err" 

681 

682 if Platforms.ARCH_x86_32 in self._platform: 682 ↛ 683line 682 didn't jump to line 683 because the condition on line 682 was never true

683 architecture = "x86-32" 

684 elif Platforms.ARCH_x86_64 in self._platform: 

685 architecture = "x86-64" 

686 elif Platforms.ARCH_AArch64 in self._platform: 686 ↛ 689line 686 didn't jump to line 689 because the condition on line 686 was always true

687 architecture = "aarch64" 

688 else: 

689 architecture = "arch:dec-err" 

690 

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

692 

693 

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