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

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 PlatformError(ToolingException): 

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

59 

60 

61@export 

62class UnknownPlatformError(PlatformError): 

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:`UnknownPlatformError` 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 UnknownOperatingSystemError(PlatformError): 

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

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

262 else: # pragma: no cover 

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

305 

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

318 

319 @readonly 

320 def PythonImplementation(self) -> PythonImplementation: 

321 """ 

322 Read-only property to access 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 access 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 """ 

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

357 

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

359 """ 

360 return self._platform & Platforms.OperatingSystem 

361 

362 @readonly 

363 def IsNativePlatform(self) -> bool: 

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

365 

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

367 """ 

368 return Platforms.ENV_Native in self._platform 

369 

370 @readonly 

371 def IsNativeFreeBSD(self) -> bool: 

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

373 

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) 

377 

378 @readonly 

379 def IsNativeMacOS(self) -> bool: 

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

381 

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

383 """ 

384 return Platforms.MacOS in self._platform 

385 

386 @readonly 

387 def IsNativeLinux(self) -> bool: 

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

389 

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

391 """ 

392 return Platforms.Linux in self._platform 

393 

394 @readonly 

395 def IsNativeWindows(self) -> bool: 

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

397 

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

399 """ 

400 return Platforms.Windows in self._platform 

401 

402 @readonly 

403 def IsMSYS2Environment(self) -> bool: 

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

405 

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

407 """ 

408 return Platforms.ENV_MSYS2 in self._platform 

409 

410 @readonly 

411 def IsMSYSOnWindows(self) -> bool: 

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

413 

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

415 """ 

416 return Platforms.Windows_MSYS2_MSYS in self._platform 

417 

418 @readonly 

419 def IsMinGW32OnWindows(self) -> bool: 

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

421 

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

423 """ 

424 return Platforms.Windows_MSYS2_MinGW32 in self._platform 

425 

426 @readonly 

427 def IsMinGW64OnWindows(self) -> bool: 

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

429 

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

431 """ 

432 return Platforms.Windows_MSYS2_MinGW64 in self._platform 

433 

434 @readonly 

435 def IsUCRT64OnWindows(self) -> bool: 

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

437 

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

439 """ 

440 return Platforms.Windows_MSYS2_UCRT64 in self._platform 

441 

442 @readonly 

443 def IsClang32OnWindows(self) -> bool: 

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

445 

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

447 """ 

448 return Platforms.Windows_MSYS2_Clang32 in self._platform 

449 

450 @readonly 

451 def IsClang64OnWindows(self) -> bool: 

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

453 

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

455 """ 

456 return Platforms.Windows_MSYS2_Clang64 in self._platform 

457 

458 @readonly 

459 def IsCygwin32OnWindows(self) -> bool: 

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

461 

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

463 """ 

464 return Platforms.Windows_Cygwin32 in self._platform 

465 

466 @readonly 

467 def IsCygwin64OnWindows(self) -> bool: 

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

469 

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

471 """ 

472 return Platforms.Windows_Cygwin64 in self._platform 

473 

474 @readonly 

475 def IsPOSIX(self) -> bool: 

476 """ 

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

478 

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

480 """ 

481 return Platforms.SEP_WindowsPath not in self._platform 

482 

483 @readonly 

484 def IsCI(self) -> bool: 

485 """ 

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

487 

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

489 """ 

490 return Platforms.CI_None not in self._platform 

491 

492 @readonly 

493 def IsAppVeyor(self) -> bool: 

494 """ 

495 Returns true, if the platform is on AppVeyor. 

496 

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

498 """ 

499 return Platforms.CI_AppVeyor in self._platform 

500 

501 @readonly 

502 def IsGitHub(self) -> bool: 

503 """ 

504 Returns true, if the platform is on GitHub. 

505 

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

507 """ 

508 return Platforms.CI_GitHubActions in self._platform 

509 

510 @readonly 

511 def IsGitLab(self) -> bool: 

512 """ 

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

514 

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

516 """ 

517 return Platforms.CI_GitLabCI in self._platform 

518 

519 @readonly 

520 def IsTravisCI(self) -> bool: 

521 """ 

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

523 

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

525 """ 

526 return Platforms.CI_TravisCI in self._platform 

527 

528 @readonly 

529 def PathSeperator(self) -> str: 

530 """ 

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

532 

533 * POSIX-like: ``/`` 

534 * Windows: ``\\`` 

535 

536 :returns: Path separation character. 

537 """ 

538 if Platforms.SEP_WindowsPath in self._platform: 

539 return "\\" 

540 else: 

541 return "/" 

542 

543 @readonly 

544 def ValueSeperator(self) -> str: 

545 """ 

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

547 

548 * POSIX-like: ``:`` 

549 * Windows: ``;`` 

550 

551 :returns: Value separation character. 

552 """ 

553 if Platforms.SEP_WindowsValue in self._platform: 

554 return ";" 

555 else: 

556 return ":" 

557 

558 @readonly 

559 def ExecutableExtension(self) -> str: 

560 """ 

561 Returns the file extension for an executable. 

562 

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

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

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

566 * Windows: ``"exe"`` 

567 

568 :returns: File extension of an executable. 

569 :raises UnknownOperatingSystemError: If the operating system is unknown. 

570 """ 

571 

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

582 

583 @readonly 

584 def StaticLibraryExtension(self) -> str: 

585 """ 

586 Returns the file extension for a static library. 

587 

588 * FreeBSD: ``"a"`` 

589 * Linux: ``"a"`` 

590 * macOS: ``"lib"`` 

591 * Windows: ``"lib"`` 

592 

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

606 

607 @readonly 

608 def DynamicLibraryExtension(self) -> str: 

609 """ 

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

611 

612 * FreeBSD: ``"so"`` 

613 * Linux: ``"so"`` 

614 * macOS: ``"dylib"`` 

615 * Windows: ``"dll"`` 

616 

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

630 

631 def __repr__(self) -> str: 

632 """ 

633 Returns the platform's string representation. 

634 

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

636 """ 

637 return str(self._platform) 

638 

639 def __str__(self) -> str: 

640 """ 

641 Returns the platform's string equivalent. 

642 

643 :returns: The string equivalent of the platform. 

644 """ 

645 runtime = "" 

646 

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" 

657 

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" 

664 

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" 

679 

680 elif Platforms.ENV_Cygwin in self._platform: 

681 environment = "+Cygwin" 

682 else: 

683 environment = "env:dec-err" 

684 

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" 

693 

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

695 

696 

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