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

317 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-05 23:48 +0000

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

38from enum import Flag, auto, Enum 

39 

40try: 

41 from pyTooling.Decorators import export, readonly 

42 from pyTooling.Exceptions import ToolingException 

43 from pyTooling.MetaClasses import ExtendedType 

44 from pyTooling.Versioning import PythonVersion 

45except (ImportError, ModuleNotFoundError): # pragma: no cover 

46 print("[pyTooling.Platform] Could not import from 'pyTooling.*'!") 

47 

48 try: 

49 from Decorators import export, readonly 

50 from Exceptions import ToolingException 

51 from MetaClasses import ExtendedType 

52 from Versioning import PythonVersion 

53 except (ImportError, ModuleNotFoundError) as ex: # pragma: no cover 

54 print("[pyTooling.Platform] Could not import directly!") 

55 raise ex 

56 

57 

58__all__ = ["CurrentPlatform"] 

59 

60 

61@export 

62class PlatformException(ToolingException): 

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

64 

65 

66@export 

67class UnknownPlatformException(PlatformException): 

68 """ 

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

70 

71 For debugging purposes, a list of system properties from various APIs is added as notes to this exception to ease 

72 debugging unknown or new platforms. 

73 """ 

74 

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

76 """ 

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

78 

79 :param args: Forward positional parameters. 

80 """ 

81 super().__init__(*args) 

82 

83 import sys 

84 import os 

85 import platform 

86 import sysconfig 

87 

88 self.add_note(f"os.name: {os.name}") 

89 self.add_note(f"platform.system: {platform.system()}") 

90 self.add_note(f"platform.machine: {platform.machine()}") 

91 self.add_note(f"platform.architecture: {platform.architecture()}") 

92 self.add_note(f"sys.platform: {sys.platform}") 

93 self.add_note(f"sysconfig.get_platform: {sysconfig.get_platform()}") 

94 

95 

96@export 

97class UnknownOperatingSystemException(PlatformException): 

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

99 

100 

101@export 

102class PythonImplementation(Enum): 

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

104 Unknown = 0 #: Unknown Python implementation 

105 

106 CPython = 1 #: CPython (reference implementation) 

107 PyPy = 2 #: PyPy 

108 

109 

110@export 

111class Platforms(Flag): 

112 """A flag describing on which platform Python is running on and/or in which environment it's running in.""" 

113 Unknown = 0 

114 

115 OS_FreeBSD = auto() #: Operating System: BSD (Unix). 

116 OS_Linux = auto() #: Operating System: Linux. 

117 OS_MacOS = auto() #: Operating System: macOS. 

118 OS_Windows = auto() #: Operating System: Windows. 

119 

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

121 

122 SEP_WindowsPath = auto() #: Seperator: Path element seperator (e.g. for directories). 

123 SEP_WindowsValue = auto() #: Seperator: Value seperator in variables (e.g. for paths in PATH). 

124 

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

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

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

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

129 

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

131 

132 CI_None = auto() #: CI: No CI environment detected. Running on host. 

133 CI_AppVeyor = auto() #: CI: AppVayor 

134 CI_GitHubActions = auto() #: CI: GitHub Actions 

135 CI_GitLabCI = auto() #: CI: GitLab CI 

136 CI_TravisCI = auto() #: CI: Travis CI 

137 

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

139 

140 ARCH_x86_32 = auto() #: Architecture: x86-32 (IA32). 

141 ARCH_x86_64 = auto() #: Architecture: x86-64 (AMD64). 

142 ARCH_AArch64 = auto() #: Architecture: AArch64 (arm64). 

143 

144 Arch_x86 = ARCH_x86_32 | ARCH_x86_64 #: Mask: Any x86 architecture. 

145 Arch_Arm = ARCH_AArch64 #: Mask: Any Arm architecture. 

146 Architecture = Arch_x86 | Arch_Arm #: Mask: Any architecture. 

147 

148 FreeBSD = OS_FreeBSD | ENV_Native #: Group: native FreeBSD on x86-64. 

149 Linux = OS_Linux | ENV_Native #: Group: native Linux on x86-64. 

150 MacOS = OS_MacOS | ENV_Native #: Group: native macOS. 

151 Windows = OS_Windows | ENV_Native | SEP_WindowsPath | SEP_WindowsValue #: Group: native Windows on x86-64. 

152 

153 Linux_x86_64 = Linux | ARCH_x86_64 #: Group: native Linux on x86-64. 

154 Linux_AArch64 = Linux | ARCH_AArch64 #: Group: native Linux on aarch64. 

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

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

157 Windows_x86_64 = Windows | ARCH_x86_64 #: Group: native Windows on x86-64. 

158 Windows_AArch64 = Windows | ARCH_AArch64 #: Group: native Windows on aarch64. 

159 

160 MSYS = auto() #: MSYS2 Runtime: MSYS. 

161 MinGW32 = auto() #: MSYS2 Runtime: :term:`MinGW32 <MinGW>`. 

162 MinGW64 = auto() #: MSYS2 Runtime: :term:`MinGW64 <MinGW>`. 

163 UCRT64 = auto() #: MSYS2 Runtime: :term:`UCRT64 <UCRT>`. 

164 Clang32 = auto() #: MSYS2 Runtime: Clang32. 

165 Clang64 = auto() #: MSYS2 Runtime: Clang64. 

166 

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

168 

169 Windows_MSYS2_MSYS = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MSYS #: Group: MSYS runtime running on Windows x86-64 

170 Windows_MSYS2_MinGW32 = OS_Windows | ENV_MSYS2 | ARCH_x86_32 | MinGW32 #: Group: MinGW32 runtime running on Windows x86-64 

171 Windows_MSYS2_MinGW64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | MinGW64 #: Group: MinGW64 runtime running on Windows x86-64 

172 Windows_MSYS2_UCRT64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | UCRT64 #: Group: UCRT64 runtime running on Windows x86-64 

173 Windows_MSYS2_Clang32 = OS_Windows | ENV_MSYS2 | ARCH_x86_32 | Clang32 #: Group: Clang32 runtime running on Windows x86-64 

174 Windows_MSYS2_Clang64 = OS_Windows | ENV_MSYS2 | ARCH_x86_64 | Clang64 #: Group: Clang64 runtime running on Windows x86-64 

175 

176 Windows_Cygwin32 = OS_Windows | ENV_Cygwin | ARCH_x86_32 #: Group: 32-bit Cygwin runtime on Windows x86-64 

177 Windows_Cygwin64 = OS_Windows | ENV_Cygwin | ARCH_x86_64 #: Group: 64-bit Cygwin runtime on Windows x86-64 

178 

179 

180@export 

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

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

183 

184 .. seealso:: 

185 

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

187 """ 

188 

189 _platform: Platforms 

190 _pythonImplementation: PythonImplementation 

191 _pythonVersion: PythonVersion 

192 

193 def __init__(self) -> None: 

194 """ 

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

196 """ 

197 import sys 

198 import os 

199 import platform 

200 import sysconfig 

201 

202 # Discover the Python implementation 

203 pythonImplementation = platform.python_implementation() 

204 if pythonImplementation == "CPython": 

205 self._pythonImplementation = PythonImplementation.CPython 

206 elif pythonImplementation == "PyPy": 

207 self._pythonImplementation = PythonImplementation.PyPy 

208 else: # pragma: no cover 

209 self._pythonImplementation = PythonImplementation.Unknown 

210 

211 # Discover the Python version 

212 self._pythonVersion = PythonVersion.FromSysVersionInfo() 

213 

214 # Discover the platform 

215 self._platform = Platforms.Unknown 

216 

217 machine = platform.machine() 

218 sys_platform = sys.platform 

219 sysconfig_platform = sysconfig.get_platform() 

220 

221 if "APPVEYOR" in os.environ: 221 ↛ 222line 221 didn't jump to line 222 because the condition on line 221 was never true

222 self._platform |= Platforms.CI_AppVeyor 

223 elif "GITHUB_ACTIONS" in os.environ: 223 ↛ 225line 223 didn't jump to line 225 because the condition on line 223 was always true

224 self._platform |= Platforms.CI_GitHubActions 

225 elif "GITLAB_CI" in os.environ: 

226 self._platform |= Platforms.CI_GitLabCI 

227 elif "TRAVIS" in os.environ: 

228 self._platform |= Platforms.CI_TravisCI 

229 else: 

230 self._platform |= Platforms.CI_None 

231 

232 if os.name == "nt": 

233 self._platform |= Platforms.OS_Windows 

234 

235 if sysconfig_platform == "win32": 235 ↛ 236line 235 didn't jump to line 236 because the condition on line 235 was never true

236 self._platform |= Platforms.ENV_Native | Platforms.ARCH_x86_32 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue 

237 elif sysconfig_platform == "win-amd64": 

238 self._platform |= Platforms.ENV_Native | Platforms.ARCH_x86_64 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue 

239 elif sysconfig_platform == "win-arm64": 

240 self._platform |= Platforms.ENV_Native | Platforms.ARCH_AArch64 | Platforms.SEP_WindowsPath | Platforms.SEP_WindowsValue 

241 elif sysconfig_platform.startswith("mingw"): 

242 if machine == "AMD64": 

243 self._platform |= Platforms.ARCH_x86_64 

244 else: # pragma: no cover 

245 raise UnknownPlatformException(f"Unknown architecture '{machine}' for Windows.") 

246 

247 if sysconfig_platform == "mingw_i686_msvcrt_gnu": 247 ↛ 248line 247 didn't jump to line 248 because the condition on line 247 was never true

248 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW32 

249 elif sysconfig_platform == "mingw_x86_64_msvcrt_gnu": 

250 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW64 

251 elif sysconfig_platform == "mingw_x86_64_ucrt_gnu": 

252 self._platform |= Platforms.ENV_MSYS2 | Platforms.UCRT64 

253 elif sysconfig_platform == "mingw_x86_64_ucrt_llvm": 

254 self._platform |= Platforms.ENV_MSYS2 | Platforms.Clang64 

255 elif sysconfig_platform == "mingw_i686": # pragma: no cover 

256 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW32 

257 elif sysconfig_platform == "mingw_x86_64": # pragma: no cover 

258 self._platform |= Platforms.ENV_MSYS2 | Platforms.MinGW64 

259 elif sysconfig_platform == "mingw_x86_64_ucrt": # pragma: no cover 

260 self._platform |= Platforms.ENV_MSYS2 | Platforms.UCRT64 

261 elif sysconfig_platform == "mingw_x86_64_clang": # pragma: no cover 

262 self._platform |= Platforms.ENV_MSYS2 | Platforms.Clang64 

263 else: # pragma: no cover 

264 raise UnknownPlatformException(f"Unknown MSYS2 architecture '{sysconfig_platform}'.") 

265 else: # pragma: no cover 

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

267 

268 elif os.name == "posix": 

269 if sys_platform == "linux": 

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

271 

272 if sysconfig_platform == "linux-x86_64": # native Linux x86_64; Windows 64 + WSL 272 ↛ 274line 272 didn't jump to line 274 because the condition on line 272 was always true

273 self._platform |= Platforms.ARCH_x86_64 

274 elif sysconfig_platform == "linux-aarch64": # native Linux Aarch64 

275 self._platform |= Platforms.ARCH_AArch64 

276 else: # pragma: no cover 

277 raise UnknownPlatformException(f"Unknown architecture '{sysconfig_platform}' for a native Linux.") 

278 

279 elif sys_platform == "darwin": 279 ↛ 289line 279 didn't jump to line 289 because the condition on line 279 was always true

280 self._platform |= Platforms.OS_MacOS | Platforms.ENV_Native 

281 

282 if machine == "x86_64": 

283 self._platform |= Platforms.ARCH_x86_64 

284 elif machine == "arm64": 

285 self._platform |= Platforms.ARCH_AArch64 

286 else: # pragma: no cover 

287 raise UnknownPlatformException(f"Unknown architecture '{machine}' for a native macOS.") 

288 

289 elif sys_platform == "msys": 

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

291 

292 if machine == "i686": 

293 self._platform |= Platforms.ARCH_x86_32 

294 elif machine == "x86_64": 

295 self._platform |= Platforms.ARCH_x86_64 

296 else: # pragma: no cover 

297 raise UnknownPlatformException(f"Unknown architecture '{machine}' for MSYS2-MSYS on Windows.") 

298 

299 elif sys_platform == "cygwin": 

300 self._platform |= Platforms.OS_Windows 

301 

302 if machine == "i686": 

303 self._platform |= Platforms.ARCH_x86_32 

304 elif machine == "x86_64": 

305 self._platform |= Platforms.ARCH_x86_64 

306 else: # pragma: no cover 

307 raise UnknownPlatformException(f"Unknown architecture '{machine}' for Cygwin on Windows.") 

308 

309 elif sys_platform.startswith("freebsd"): 

310 if machine == "amd64": 

311 self._platform = Platforms.FreeBSD 

312 else: # pragma: no cover 

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

314 else: # pragma: no cover 

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

316 else: # pragma: no cover 

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

318 

319 @readonly 

320 def PythonImplementation(self) -> PythonImplementation: 

321 """ 

322 Read-only property to return the :class:`PythonImplementation` of the current interpreter. 

323 

324 :returns: Python implementation of the current interpreter. 

325 """ 

326 return self._pythonImplementation 

327 

328 @readonly 

329 def IsCPython(self) -> bool: 

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

331 

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

333 """ 

334 return self._pythonImplementation is PythonImplementation.CPython 

335 

336 @readonly 

337 def IsPyPy(self) -> bool: 

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

339 

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

341 """ 

342 return self._pythonImplementation is PythonImplementation.PyPy 

343 

344 @readonly 

345 def PythonVersion(self) -> PythonVersion: 

346 """ 

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

348 

349 :returns: Python version of the current interpreter. 

350 """ 

351 return self._pythonVersion 

352 

353 @readonly 

354 def HostOperatingSystem(self) -> Platforms: 

355 return self._platform & Platforms.OperatingSystem 

356 

357 @readonly 

358 def IsNativePlatform(self) -> bool: 

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

360 

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

362 """ 

363 return Platforms.ENV_Native in self._platform 

364 

365 @readonly 

366 def IsNativeFreeBSD(self) -> bool: 

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

368 

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

370 """ 

371 return Platforms.FreeBSD in self._platform 

372 

373 @readonly 

374 def IsNativeMacOS(self) -> bool: 

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

376 

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

378 """ 

379 return Platforms.MacOS in self._platform 

380 

381 @readonly 

382 def IsNativeLinux(self) -> bool: 

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

384 

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

386 """ 

387 return Platforms.Linux in self._platform 

388 

389 @readonly 

390 def IsNativeWindows(self) -> bool: 

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

392 

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

394 """ 

395 return Platforms.Windows in self._platform 

396 

397 @readonly 

398 def IsMSYS2Environment(self) -> bool: 

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

400 

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

402 """ 

403 return Platforms.ENV_MSYS2 in self._platform 

404 

405 @readonly 

406 def IsMSYSOnWindows(self) -> bool: 

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

408 

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

410 """ 

411 return Platforms.Windows_MSYS2_MSYS in self._platform 

412 

413 @readonly 

414 def IsMinGW32OnWindows(self) -> bool: 

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

416 

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

418 """ 

419 return Platforms.Windows_MSYS2_MinGW32 in self._platform 

420 

421 @readonly 

422 def IsMinGW64OnWindows(self) -> bool: 

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

424 

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

426 """ 

427 return Platforms.Windows_MSYS2_MinGW64 in self._platform 

428 

429 @readonly 

430 def IsUCRT64OnWindows(self) -> bool: 

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

432 

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

434 """ 

435 return Platforms.Windows_MSYS2_UCRT64 in self._platform 

436 

437 @readonly 

438 def IsClang32OnWindows(self) -> bool: 

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

440 

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

442 """ 

443 return Platforms.Windows_MSYS2_Clang32 in self._platform 

444 

445 @readonly 

446 def IsClang64OnWindows(self) -> bool: 

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

448 

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

450 """ 

451 return Platforms.Windows_MSYS2_Clang64 in self._platform 

452 

453 @readonly 

454 def IsCygwin32OnWindows(self) -> bool: 

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

456 

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

458 """ 

459 return Platforms.Windows_Cygwin32 in self._platform 

460 

461 @readonly 

462 def IsCygwin64OnWindows(self) -> bool: 

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

464 

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

466 """ 

467 return Platforms.Windows_Cygwin64 in self._platform 

468 

469 @readonly 

470 def IsPOSIX(self) -> bool: 

471 """ 

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

473 

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

475 """ 

476 return Platforms.SEP_WindowsPath not in self._platform 

477 

478 @readonly 

479 def IsCI(self) -> bool: 

480 """ 

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

482 

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

484 """ 

485 return Platforms.CI_None not in self._platform 

486 

487 @readonly 

488 def IsAppVeyor(self) -> bool: 

489 """ 

490 Returns true, if the platform is on AppVeyor. 

491 

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

493 """ 

494 return Platforms.CI_AppVeyor in self._platform 

495 

496 @readonly 

497 def IsGitHub(self) -> bool: 

498 """ 

499 Returns true, if the platform is on GitHub. 

500 

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

502 """ 

503 return Platforms.CI_GitHubActions in self._platform 

504 

505 @readonly 

506 def IsGitLab(self) -> bool: 

507 """ 

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

509 

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

511 """ 

512 return Platforms.CI_GitLabCI in self._platform 

513 

514 @readonly 

515 def IsTravisCI(self) -> bool: 

516 """ 

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

518 

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

520 """ 

521 return Platforms.CI_TravisCI in self._platform 

522 

523 @readonly 

524 def PathSeperator(self) -> str: 

525 """ 

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

527 

528 * POSIX-like: ``/`` 

529 * Windows: ``\\`` 

530 

531 :returns: Path separation character. 

532 """ 

533 if Platforms.SEP_WindowsPath in self._platform: 

534 return "\\" 

535 else: 

536 return "/" 

537 

538 @readonly 

539 def ValueSeperator(self) -> str: 

540 """ 

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

542 

543 * POSIX-like: ``:`` 

544 * Windows: ``;`` 

545 

546 :returns: Value separation character. 

547 """ 

548 if Platforms.SEP_WindowsValue in self._platform: 

549 return ";" 

550 else: 

551 return ":" 

552 

553 @readonly 

554 def ExecutableExtension(self) -> str: 

555 """ 

556 Returns the file extension for an executable. 

557 

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

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

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

561 * Windows: ``"exe"`` 

562 

563 :returns: File extension of an executable. 

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

565 """ 

566 

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

568 return "" 

569 elif Platforms.OS_Linux in self._platform: 

570 return "" 

571 elif Platforms.OS_MacOS in self._platform: 

572 return "" 

573 elif Platforms.OS_Windows in self._platform: 

574 return "exe" 

575 else: # pragma: no cover 

576 raise UnknownOperatingSystemException("Unknown operating system.") 

577 

578 @readonly 

579 def StaticLibraryExtension(self) -> str: 

580 """ 

581 Returns the file extension for a static library. 

582 

583 * FreeBSD: ``"a"`` 

584 * Linux: ``"a"`` 

585 * macOS: ``"lib"`` 

586 * Windows: ``"lib"`` 

587 

588 :returns: File extension of a static library. 

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

590 """ 

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

592 return "a" 

593 elif Platforms.OS_Linux in self._platform: 

594 return "a" 

595 elif Platforms.OS_MacOS in self._platform: 

596 return "a" 

597 elif Platforms.OS_Windows in self._platform: 

598 return "lib" 

599 else: # pragma: no cover 

600 raise UnknownOperatingSystemException("Unknown operating system.") 

601 

602 @readonly 

603 def DynamicLibraryExtension(self) -> str: 

604 """ 

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

606 

607 * FreeBSD: ``"so"`` 

608 * Linux: ``"so"`` 

609 * macOS: ``"dylib"`` 

610 * Windows: ``"dll"`` 

611 

612 :returns: File extension of a dynamic library. 

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

614 """ 

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

616 return "so" 

617 elif Platforms.OS_Linux in self._platform: 

618 return "so" 

619 elif Platforms.OS_MacOS in self._platform: 

620 return "dylib" 

621 elif Platforms.OS_Windows in self._platform: 

622 return "dll" 

623 else: # pragma: no cover 

624 raise UnknownOperatingSystemException("Unknown operating system.") 

625 

626 def __repr__(self) -> str: 

627 """ 

628 Returns the platform's string representation. 

629 

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

631 """ 

632 return str(self._platform) 

633 

634 def __str__(self) -> str: 

635 """ 

636 Returns the platform's string equivalent. 

637 

638 :returns: The string equivalent of the platform. 

639 """ 

640 runtime = "" 

641 

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

643 platform = "FreeBSD" 

644 elif Platforms.OS_MacOS in self._platform: 

645 platform = "macOS" 

646 elif Platforms.OS_Linux in self._platform: 

647 platform = "Linux" 

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

649 platform = "Windows" 

650 else: 

651 platform = "plat:dec-err" 

652 

653 if Platforms.ENV_Native in self._platform: 

654 environment = "" 

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

656 environment = "+WSL" 

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

658 environment = "+MSYS2" 

659 

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

661 runtime = " - MSYS" 

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

663 runtime = " - MinGW32" 

664 elif Platforms.MinGW64 in self._platform: 

665 runtime = " - MinGW64" 

666 elif Platforms.UCRT64 in self._platform: 

667 runtime = " - UCRT64" 

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

669 runtime = " - Clang32" 

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

671 runtime = " - Clang64" 

672 else: 

673 runtime = "rt:dec-err" 

674 

675 elif Platforms.ENV_Cygwin in self._platform: 

676 environment = "+Cygwin" 

677 else: 

678 environment = "env:dec-err" 

679 

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

681 architecture = "x86-32" 

682 elif Platforms.ARCH_x86_64 in self._platform: 

683 architecture = "x86-64" 

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

685 architecture = "aarch64" 

686 else: 

687 architecture = "arch:dec-err" 

688 

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

690 

691 

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