Python bindings for GNU parted library providing disk partition management capabilities
—
Utility functions in pyparted provide helper functionality for unit conversion, version information, system compatibility, and other common operations.
Functions for converting between different size units and sector counts.
def formatBytes(bytes_: int, unit: str) -> float:
"""
Convert bytes to specified unit using SI or IEC prefixes.
Args:
bytes_ (int): Number of bytes to convert
unit (str): Target unit ('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'
or 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB')
Returns:
float: Value in specified unit
Raises:
SyntaxError: If unit is not a valid SI or IEC byte unit
"""
def sizeToSectors(bytes_: int, unit: str, sector_size: int) -> int:
"""
Convert size in specified unit to number of sectors.
Args:
bytes_ (int): Size value in the specified unit
unit (str): Unit of the size value ('B', 'kB', 'MB', etc.)
sector_size (int): Device sector size in bytes
Returns:
int: Number of sectors (rounded up)
Raises:
SyntaxError: If unit is not a valid SI or IEC byte unit
"""Function for retrieving version information about pyparted and libparted.
def version() -> dict[str, str]:
"""
Get version information for pyparted and libparted.
Returns:
dict: Dictionary with 'pyparted' and 'libparted' version strings
"""Function for determining supported disk label types for different architectures.
def getLabels(arch: str = None) -> set[str]:
"""
Get set of disk label types compatible with specified architecture.
Args:
arch (str, optional): Architecture name. If None, uses current system architecture.
Returns:
set[str]: Set of compatible disk label type names
"""import parted
# Convert bytes to different units
size_bytes = 1024 * 1024 * 1024 # 1GB in bytes
# SI units (decimal, base 1000)
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'kB'):.1f} kB")
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'MB'):.1f} MB")
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'GB'):.1f} GB")
# IEC units (binary, base 1024)
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'KiB'):.1f} KiB")
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'MiB'):.1f} MiB")
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'GiB'):.1f} GiB")
# Large units
large_bytes = 2 * 1024**4 # 2 TiB in bytes
print(f"{large_bytes} bytes = {parted.formatBytes(large_bytes, 'TiB'):.1f} TiB")
print(f"{large_bytes} bytes = {parted.formatBytes(large_bytes, 'TB'):.1f} TB")import parted
device = parted.getDevice('/dev/sda')
sector_size = device.sectorSize
# Convert various sizes to sector counts
sizes_to_convert = [
(1, 'GiB'), # 1 GiB
(500, 'MB'), # 500 MB
(2, 'TB'), # 2 TB
(4096, 'B') # 4096 bytes
]
print(f"Device sector size: {sector_size} bytes")
print("\nSize conversions to sectors:")
for size_value, unit in sizes_to_convert:
sectors = parted.sizeToSectors(size_value, unit, sector_size)
actual_bytes = sectors * sector_size
print(f"{size_value} {unit} = {sectors:,} sectors ({actual_bytes:,} bytes)")import parted
def calculate_partition_sizes(device_path):
"""Calculate and display partition sizes in multiple units."""
device = parted.getDevice(device_path)
disk = parted.newDisk(device)
print(f"Device: {device.model} ({device.path})")
print(f"Sector size: {device.sectorSize} bytes")
print(f"Total sectors: {device.length:,}")
total_bytes = device.length * device.sectorSize
print(f"Total size: {parted.formatBytes(total_bytes, 'GB'):.1f} GB ({parted.formatBytes(total_bytes, 'GiB'):.1f} GiB)")
print("\nPartition sizes:")
for partition in disk.partitions:
part_bytes = partition.geometry.length * device.sectorSize
print(f"Partition {partition.number}:")
print(f" Sectors: {partition.geometry.length:,}")
print(f" MB: {parted.formatBytes(part_bytes, 'MB'):.1f}")
print(f" MiB: {parted.formatBytes(part_bytes, 'MiB'):.1f}")
print(f" GB: {parted.formatBytes(part_bytes, 'GB'):.2f}")
print(f" GiB: {parted.formatBytes(part_bytes, 'GiB'):.2f}")
# Example usage
calculate_partition_sizes('/dev/sda')import parted
# Get version information
versions = parted.version()
print(f"pyparted version: {versions['pyparted']}")
print(f"libparted version: {versions['libparted']}")
# Use version info for compatibility checks
def check_version_compatibility():
"""Check if versions meet minimum requirements."""
versions = parted.version()
# Example minimum version requirements
min_pyparted = "3.12.0"
min_libparted = "3.4"
print(f"Current versions: pyparted {versions['pyparted']}, libparted {versions['libparted']}")
print(f"Required minimum: pyparted {min_pyparted}, libparted {min_libparted}")
# Note: Simple string comparison for demonstration
# Real code should use proper version parsing
pyparted_ok = versions['pyparted'] >= min_pyparted
libparted_ok = versions['libparted'] >= min_libparted
if pyparted_ok and libparted_ok:
print("✓ Version requirements met")
else:
print("✗ Version requirements not met")
check_version_compatibility()import parted
import platform
# Get supported disk labels for current architecture
current_arch = platform.machine()
supported_labels = parted.getLabels()
print(f"Current architecture: {current_arch}")
print(f"Supported disk label types: {sorted(supported_labels)}")
# Check support for specific architectures
architectures = ['x86_64', 'aarch64', 'ppc64', 's390', 'sparc']
print("\nDisk label support by architecture:")
for arch in architectures:
labels = parted.getLabels(arch)
print(f"{arch:8}: {sorted(labels)}")
# Check if specific label type is supported
def is_label_supported(label_type, arch=None):
"""Check if disk label type is supported on architecture."""
supported = parted.getLabels(arch)
return label_type in supported
# Test label support
label_tests = [
('gpt', None), # Current architecture
('msdos', 'x86_64'),
('mac', 'ppc64'),
('sun', 'sparc'),
('dasd', 's390')
]
print("\nLabel type support tests:")
for label, arch in label_tests:
arch_str = arch or current_arch
supported = is_label_supported(label, arch)
status = "✓" if supported else "✗"
print(f"{status} {label} on {arch_str}")import parted
def safe_format_bytes(bytes_value, unit):
"""Safely format bytes with error handling."""
try:
result = parted.formatBytes(bytes_value, unit)
return f"{result:.2f} {unit}"
except SyntaxError as e:
return f"Error: {e}"
def safe_size_to_sectors(size_value, unit, sector_size):
"""Safely convert size to sectors with error handling."""
try:
sectors = parted.sizeToSectors(size_value, unit, sector_size)
return sectors
except SyntaxError as e:
return f"Error: {e}"
# Test valid and invalid units
test_cases = [
(1024**3, 'GB'), # Valid SI unit
(1024**3, 'GiB'), # Valid IEC unit
(1024**3, 'gb'), # Invalid (lowercase)
(1024**3, 'XXX'), # Invalid unit
(1024**3, 'GByte') # Invalid format
]
print("Unit validation tests:")
for bytes_val, unit in test_cases:
result = safe_format_bytes(bytes_val, unit)
print(f"{bytes_val} bytes as {unit}: {result}")import parted
def partition_size_calculator(device_path, percentage):
"""Calculate partition size as percentage of device."""
device = parted.getDevice(device_path)
# Calculate partition size
total_sectors = device.length
partition_sectors = int(total_sectors * percentage / 100)
partition_bytes = partition_sectors * device.sectorSize
print(f"Device: {device.path}")
print(f"Total size: {parted.formatBytes(device.length * device.sectorSize, 'GiB'):.1f} GiB")
print(f"Partition ({percentage}%): {parted.formatBytes(partition_bytes, 'GiB'):.1f} GiB")
print(f"Partition sectors: {partition_sectors:,}")
return partition_sectors
def optimal_partition_sizes(device_path, partition_sizes):
"""Calculate optimal partition sizes in sectors."""
device = parted.getDevice(device_path)
sector_size = device.sectorSize
print(f"Device: {device.path} (sector size: {sector_size} bytes)")
print("\nPartition size calculations:")
total_sectors_needed = 0
for i, (size_value, unit) in enumerate(partition_sizes, 1):
sectors = parted.sizeToSectors(size_value, unit, sector_size)
actual_bytes = sectors * sector_size
total_sectors_needed += sectors
print(f"Partition {i}: {size_value} {unit}")
print(f" Sectors needed: {sectors:,}")
print(f" Actual size: {parted.formatBytes(actual_bytes, 'GiB'):.2f} GiB")
available_sectors = device.length - 2048 # Reserve space for partition table
if total_sectors_needed <= available_sectors:
print(f"\n✓ All partitions fit ({total_sectors_needed:,} <= {available_sectors:,} sectors)")
else:
print(f"\n✗ Partitions too large ({total_sectors_needed:,} > {available_sectors:,} sectors)")
# Example usage
partition_plans = [
(512, 'MiB'), # Boot partition
(4, 'GiB'), # Swap
(50, 'GiB'), # Root filesystem
(100, 'GiB') # Home partition
]
optimal_partition_sizes('/dev/sda', partition_plans)Install with Tessl CLI
npx tessl i tessl/pypi-pyparted