242 lines
6.3 KiB
Python
242 lines
6.3 KiB
Python
"""
|
|
Platform detection and information module.
|
|
|
|
This module provides utilities for detecting the current platform
|
|
and getting platform-specific information.
|
|
"""
|
|
|
|
import platform
|
|
import sys
|
|
from typing import Optional, Tuple
|
|
|
|
|
|
class Platform:
|
|
"""Platform information and detection."""
|
|
|
|
# Supported platforms
|
|
LINUX = "linux"
|
|
WINDOWS = "windows"
|
|
MACOS = "macos"
|
|
RP2040 = "rp2040"
|
|
|
|
# Platform aliases
|
|
ALIASES = {
|
|
"darwin": MACOS,
|
|
"win32": WINDOWS,
|
|
"cygwin": WINDOWS,
|
|
"msys": WINDOWS,
|
|
"pico": RP2040,
|
|
}
|
|
|
|
def __init__(self):
|
|
"""Initialize platform detection."""
|
|
self._system = None
|
|
self._machine = None
|
|
self._detected = None
|
|
|
|
@property
|
|
def system(self) -> str:
|
|
"""Get the system name (Linux, Windows, Darwin, etc.)."""
|
|
if self._system is None:
|
|
self._system = platform.system()
|
|
return self._system
|
|
|
|
@property
|
|
def machine(self) -> str:
|
|
"""Get the machine architecture (x86_64, arm, etc.)."""
|
|
if self._machine is None:
|
|
self._machine = platform.machine()
|
|
return self._machine
|
|
|
|
def detect(self) -> str:
|
|
"""
|
|
Detect the current platform.
|
|
|
|
Returns:
|
|
Platform string ('linux', 'windows', 'macos')
|
|
"""
|
|
if self._detected is not None:
|
|
return self._detected
|
|
|
|
system = self.system.lower()
|
|
|
|
# Check aliases
|
|
for alias, platform_name in self.ALIASES.items():
|
|
if alias in system:
|
|
self._detected = platform_name
|
|
return self._detected
|
|
|
|
# Direct mapping
|
|
if system == "linux":
|
|
self._detected = self.LINUX
|
|
elif system == "darwin":
|
|
self._detected = self.MACOS
|
|
elif system == "windows":
|
|
self._detected = self.WINDOWS
|
|
else:
|
|
# Unknown platform, default to linux
|
|
self._detected = self.LINUX
|
|
|
|
return self._detected
|
|
|
|
def is_linux(self) -> bool:
|
|
"""Check if current platform is Linux."""
|
|
return self.detect() == self.LINUX
|
|
|
|
def is_windows(self) -> bool:
|
|
"""Check if current platform is Windows."""
|
|
return self.detect() == self.WINDOWS
|
|
|
|
def is_macos(self) -> bool:
|
|
"""Check if current platform is macOS."""
|
|
return self.detect() == self.MACOS
|
|
|
|
def is_64bit(self) -> bool:
|
|
"""Check if running on 64-bit architecture."""
|
|
return sys.maxsize > 2**32
|
|
|
|
def get_cpu_count(self) -> int:
|
|
"""Get number of CPU cores."""
|
|
import os
|
|
return os.cpu_count() or 1
|
|
|
|
def get_exe_extension(self) -> str:
|
|
"""
|
|
Get the executable file extension for this platform.
|
|
|
|
Returns:
|
|
'.exe' on Windows, '' on Unix-like systems
|
|
"""
|
|
return ".exe" if self.is_windows() else ""
|
|
|
|
def get_shared_lib_extension(self) -> str:
|
|
"""
|
|
Get the shared library extension for this platform.
|
|
|
|
Returns:
|
|
'.dll' on Windows, '.dylib' on macOS, '.so' on Linux
|
|
"""
|
|
if self.is_windows():
|
|
return ".dll"
|
|
elif self.is_macos():
|
|
return ".dylib"
|
|
else:
|
|
return ".so"
|
|
|
|
def normalize_platform_name(self, name: str) -> str:
|
|
"""
|
|
Normalize a platform name to canonical form.
|
|
|
|
Args:
|
|
name: Platform name (possibly an alias)
|
|
|
|
Returns:
|
|
Canonical platform name
|
|
"""
|
|
name = name.lower()
|
|
|
|
# Check if it's already canonical
|
|
if name in [self.LINUX, self.WINDOWS, self.MACOS, self.RP2040]:
|
|
return name
|
|
|
|
# Check aliases
|
|
for alias, platform_name in self.ALIASES.items():
|
|
if alias in name:
|
|
return platform_name
|
|
|
|
# Return as-is if unknown
|
|
return name
|
|
|
|
def get_platform_info(self) -> dict:
|
|
"""
|
|
Get detailed platform information.
|
|
|
|
Returns:
|
|
Dictionary with platform details
|
|
"""
|
|
return {
|
|
'platform': self.detect(),
|
|
'system': self.system,
|
|
'machine': self.machine,
|
|
'architecture': platform.architecture()[0],
|
|
'python_version': platform.python_version(),
|
|
'is_64bit': self.is_64bit(),
|
|
'cpu_count': self.get_cpu_count(),
|
|
}
|
|
|
|
def __str__(self) -> str:
|
|
"""String representation of platform."""
|
|
return self.detect()
|
|
|
|
def __repr__(self) -> str:
|
|
"""Detailed representation."""
|
|
return f"Platform(system='{self.system}', detected='{self.detect()}')"
|
|
|
|
|
|
# Global platform instance
|
|
_platform = Platform()
|
|
|
|
|
|
def detect_platform() -> str:
|
|
"""
|
|
Detect the current platform.
|
|
|
|
Returns:
|
|
Platform string ('linux', 'windows', 'macos')
|
|
"""
|
|
return _platform.detect()
|
|
|
|
|
|
def get_platform() -> Platform:
|
|
"""
|
|
Get the global Platform instance.
|
|
|
|
Returns:
|
|
Platform instance
|
|
"""
|
|
return _platform
|
|
|
|
|
|
def is_linux() -> bool:
|
|
"""Check if current platform is Linux."""
|
|
return _platform.is_linux()
|
|
|
|
|
|
def is_windows() -> bool:
|
|
"""Check if current platform is Windows."""
|
|
return _platform.is_windows()
|
|
|
|
|
|
def is_macos() -> bool:
|
|
"""Check if current platform is macOS."""
|
|
return _platform.is_macos()
|
|
|
|
|
|
def normalize_target(target: Optional[str]) -> str:
|
|
"""
|
|
Normalize a target platform name.
|
|
|
|
Args:
|
|
target: Target name or 'self' for current platform
|
|
|
|
Returns:
|
|
Normalized platform name
|
|
"""
|
|
if target is None or target.lower() == "self":
|
|
return detect_platform()
|
|
|
|
return _platform.normalize_platform_name(target)
|
|
|
|
|
|
def print_platform_info():
|
|
"""Print detailed platform information."""
|
|
info = _platform.get_platform_info()
|
|
print("Platform Information:")
|
|
print(f" Platform: {info['platform']}")
|
|
print(f" System: {info['system']}")
|
|
print(f" Machine: {info['machine']}")
|
|
print(f" Architecture: {info['architecture']}")
|
|
print(f" Python: {info['python_version']}")
|
|
print(f" 64-bit: {info['is_64bit']}")
|
|
print(f" CPU Cores: {info['cpu_count']}")
|