0
# Utility Functions
1
2
Utility functions in pyparted provide helper functionality for unit conversion, version information, system compatibility, and other common operations.
3
4
## Capabilities
5
6
### Unit Conversion Functions
7
8
Functions for converting between different size units and sector counts.
9
10
```python { .api }
11
def formatBytes(bytes_: int, unit: str) -> float:
12
"""
13
Convert bytes to specified unit using SI or IEC prefixes.
14
15
Args:
16
bytes_ (int): Number of bytes to convert
17
unit (str): Target unit ('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'
18
or 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB')
19
20
Returns:
21
float: Value in specified unit
22
23
Raises:
24
SyntaxError: If unit is not a valid SI or IEC byte unit
25
"""
26
27
def sizeToSectors(bytes_: int, unit: str, sector_size: int) -> int:
28
"""
29
Convert size in specified unit to number of sectors.
30
31
Args:
32
bytes_ (int): Size value in the specified unit
33
unit (str): Unit of the size value ('B', 'kB', 'MB', etc.)
34
sector_size (int): Device sector size in bytes
35
36
Returns:
37
int: Number of sectors (rounded up)
38
39
Raises:
40
SyntaxError: If unit is not a valid SI or IEC byte unit
41
"""
42
```
43
44
### Version Information
45
46
Function for retrieving version information about pyparted and libparted.
47
48
```python { .api }
49
def version() -> dict[str, str]:
50
"""
51
Get version information for pyparted and libparted.
52
53
Returns:
54
dict: Dictionary with 'pyparted' and 'libparted' version strings
55
"""
56
```
57
58
### System Compatibility
59
60
Function for determining supported disk label types for different architectures.
61
62
```python { .api }
63
def getLabels(arch: str = None) -> set[str]:
64
"""
65
Get set of disk label types compatible with specified architecture.
66
67
Args:
68
arch (str, optional): Architecture name. If None, uses current system architecture.
69
70
Returns:
71
set[str]: Set of compatible disk label type names
72
"""
73
```
74
75
## Usage Examples
76
77
### Unit Conversion Operations
78
79
```python
80
import parted
81
82
# Convert bytes to different units
83
size_bytes = 1024 * 1024 * 1024 # 1GB in bytes
84
85
# SI units (decimal, base 1000)
86
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'kB'):.1f} kB")
87
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'MB'):.1f} MB")
88
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'GB'):.1f} GB")
89
90
# IEC units (binary, base 1024)
91
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'KiB'):.1f} KiB")
92
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'MiB'):.1f} MiB")
93
print(f"{size_bytes} bytes = {parted.formatBytes(size_bytes, 'GiB'):.1f} GiB")
94
95
# Large units
96
large_bytes = 2 * 1024**4 # 2 TiB in bytes
97
print(f"{large_bytes} bytes = {parted.formatBytes(large_bytes, 'TiB'):.1f} TiB")
98
print(f"{large_bytes} bytes = {parted.formatBytes(large_bytes, 'TB'):.1f} TB")
99
```
100
101
### Sector Calculations
102
103
```python
104
import parted
105
106
device = parted.getDevice('/dev/sda')
107
sector_size = device.sectorSize
108
109
# Convert various sizes to sector counts
110
sizes_to_convert = [
111
(1, 'GiB'), # 1 GiB
112
(500, 'MB'), # 500 MB
113
(2, 'TB'), # 2 TB
114
(4096, 'B') # 4096 bytes
115
]
116
117
print(f"Device sector size: {sector_size} bytes")
118
print("\nSize conversions to sectors:")
119
120
for size_value, unit in sizes_to_convert:
121
sectors = parted.sizeToSectors(size_value, unit, sector_size)
122
actual_bytes = sectors * sector_size
123
print(f"{size_value} {unit} = {sectors:,} sectors ({actual_bytes:,} bytes)")
124
```
125
126
### Partition Size Calculations
127
128
```python
129
import parted
130
131
def calculate_partition_sizes(device_path):
132
"""Calculate and display partition sizes in multiple units."""
133
device = parted.getDevice(device_path)
134
disk = parted.newDisk(device)
135
136
print(f"Device: {device.model} ({device.path})")
137
print(f"Sector size: {device.sectorSize} bytes")
138
print(f"Total sectors: {device.length:,}")
139
140
total_bytes = device.length * device.sectorSize
141
print(f"Total size: {parted.formatBytes(total_bytes, 'GB'):.1f} GB ({parted.formatBytes(total_bytes, 'GiB'):.1f} GiB)")
142
143
print("\nPartition sizes:")
144
for partition in disk.partitions:
145
part_bytes = partition.geometry.length * device.sectorSize
146
147
print(f"Partition {partition.number}:")
148
print(f" Sectors: {partition.geometry.length:,}")
149
print(f" MB: {parted.formatBytes(part_bytes, 'MB'):.1f}")
150
print(f" MiB: {parted.formatBytes(part_bytes, 'MiB'):.1f}")
151
print(f" GB: {parted.formatBytes(part_bytes, 'GB'):.2f}")
152
print(f" GiB: {parted.formatBytes(part_bytes, 'GiB'):.2f}")
153
154
# Example usage
155
calculate_partition_sizes('/dev/sda')
156
```
157
158
### Version Information
159
160
```python
161
import parted
162
163
# Get version information
164
versions = parted.version()
165
print(f"pyparted version: {versions['pyparted']}")
166
print(f"libparted version: {versions['libparted']}")
167
168
# Use version info for compatibility checks
169
def check_version_compatibility():
170
"""Check if versions meet minimum requirements."""
171
versions = parted.version()
172
173
# Example minimum version requirements
174
min_pyparted = "3.12.0"
175
min_libparted = "3.4"
176
177
print(f"Current versions: pyparted {versions['pyparted']}, libparted {versions['libparted']}")
178
print(f"Required minimum: pyparted {min_pyparted}, libparted {min_libparted}")
179
180
# Note: Simple string comparison for demonstration
181
# Real code should use proper version parsing
182
pyparted_ok = versions['pyparted'] >= min_pyparted
183
libparted_ok = versions['libparted'] >= min_libparted
184
185
if pyparted_ok and libparted_ok:
186
print("✓ Version requirements met")
187
else:
188
print("✗ Version requirements not met")
189
190
check_version_compatibility()
191
```
192
193
### Architecture Compatibility
194
195
```python
196
import parted
197
import platform
198
199
# Get supported disk labels for current architecture
200
current_arch = platform.machine()
201
supported_labels = parted.getLabels()
202
203
print(f"Current architecture: {current_arch}")
204
print(f"Supported disk label types: {sorted(supported_labels)}")
205
206
# Check support for specific architectures
207
architectures = ['x86_64', 'aarch64', 'ppc64', 's390', 'sparc']
208
209
print("\nDisk label support by architecture:")
210
for arch in architectures:
211
labels = parted.getLabels(arch)
212
print(f"{arch:8}: {sorted(labels)}")
213
214
# Check if specific label type is supported
215
def is_label_supported(label_type, arch=None):
216
"""Check if disk label type is supported on architecture."""
217
supported = parted.getLabels(arch)
218
return label_type in supported
219
220
# Test label support
221
label_tests = [
222
('gpt', None), # Current architecture
223
('msdos', 'x86_64'),
224
('mac', 'ppc64'),
225
('sun', 'sparc'),
226
('dasd', 's390')
227
]
228
229
print("\nLabel type support tests:")
230
for label, arch in label_tests:
231
arch_str = arch or current_arch
232
supported = is_label_supported(label, arch)
233
status = "✓" if supported else "✗"
234
print(f"{status} {label} on {arch_str}")
235
```
236
237
### Unit Validation and Error Handling
238
239
```python
240
import parted
241
242
def safe_format_bytes(bytes_value, unit):
243
"""Safely format bytes with error handling."""
244
try:
245
result = parted.formatBytes(bytes_value, unit)
246
return f"{result:.2f} {unit}"
247
except SyntaxError as e:
248
return f"Error: {e}"
249
250
def safe_size_to_sectors(size_value, unit, sector_size):
251
"""Safely convert size to sectors with error handling."""
252
try:
253
sectors = parted.sizeToSectors(size_value, unit, sector_size)
254
return sectors
255
except SyntaxError as e:
256
return f"Error: {e}"
257
258
# Test valid and invalid units
259
test_cases = [
260
(1024**3, 'GB'), # Valid SI unit
261
(1024**3, 'GiB'), # Valid IEC unit
262
(1024**3, 'gb'), # Invalid (lowercase)
263
(1024**3, 'XXX'), # Invalid unit
264
(1024**3, 'GByte') # Invalid format
265
]
266
267
print("Unit validation tests:")
268
for bytes_val, unit in test_cases:
269
result = safe_format_bytes(bytes_val, unit)
270
print(f"{bytes_val} bytes as {unit}: {result}")
271
```
272
273
### Practical Size Calculations
274
275
```python
276
import parted
277
278
def partition_size_calculator(device_path, percentage):
279
"""Calculate partition size as percentage of device."""
280
device = parted.getDevice(device_path)
281
282
# Calculate partition size
283
total_sectors = device.length
284
partition_sectors = int(total_sectors * percentage / 100)
285
partition_bytes = partition_sectors * device.sectorSize
286
287
print(f"Device: {device.path}")
288
print(f"Total size: {parted.formatBytes(device.length * device.sectorSize, 'GiB'):.1f} GiB")
289
print(f"Partition ({percentage}%): {parted.formatBytes(partition_bytes, 'GiB'):.1f} GiB")
290
print(f"Partition sectors: {partition_sectors:,}")
291
292
return partition_sectors
293
294
def optimal_partition_sizes(device_path, partition_sizes):
295
"""Calculate optimal partition sizes in sectors."""
296
device = parted.getDevice(device_path)
297
sector_size = device.sectorSize
298
299
print(f"Device: {device.path} (sector size: {sector_size} bytes)")
300
print("\nPartition size calculations:")
301
302
total_sectors_needed = 0
303
for i, (size_value, unit) in enumerate(partition_sizes, 1):
304
sectors = parted.sizeToSectors(size_value, unit, sector_size)
305
actual_bytes = sectors * sector_size
306
total_sectors_needed += sectors
307
308
print(f"Partition {i}: {size_value} {unit}")
309
print(f" Sectors needed: {sectors:,}")
310
print(f" Actual size: {parted.formatBytes(actual_bytes, 'GiB'):.2f} GiB")
311
312
available_sectors = device.length - 2048 # Reserve space for partition table
313
if total_sectors_needed <= available_sectors:
314
print(f"\n✓ All partitions fit ({total_sectors_needed:,} <= {available_sectors:,} sectors)")
315
else:
316
print(f"\n✗ Partitions too large ({total_sectors_needed:,} > {available_sectors:,} sectors)")
317
318
# Example usage
319
partition_plans = [
320
(512, 'MiB'), # Boot partition
321
(4, 'GiB'), # Swap
322
(50, 'GiB'), # Root filesystem
323
(100, 'GiB') # Home partition
324
]
325
326
optimal_partition_sizes('/dev/sda', partition_plans)
327
```
328
329
## Unit Systems
330
331
### SI Units (Decimal, Base 1000)
332
- **B**: Bytes (1)
333
- **kB**: Kilobytes (1,000)
334
- **MB**: Megabytes (1,000,000)
335
- **GB**: Gigabytes (1,000,000,000)
336
- **TB**: Terabytes (1,000,000,000,000)
337
- **PB, EB, ZB, YB**: Larger SI units
338
339
### IEC Units (Binary, Base 1024)
340
- **KiB**: Kibibytes (1,024)
341
- **MiB**: Mebibytes (1,048,576)
342
- **GiB**: Gibibytes (1,073,741,824)
343
- **TiB**: Tebibytes (1,099,511,627,776)
344
- **PiB, EiB, ZiB, YiB**: Larger IEC units
345
346
### Best Practices
347
348
1. **Use IEC Units for Binary**: Use GiB, MiB for actual storage calculations
349
2. **Use SI Units for Marketing**: Use GB, MB when matching manufacturer specifications
350
3. **Be Consistent**: Don't mix unit systems in the same calculation
351
4. **Validate Units**: Always handle potential SyntaxError from invalid units
352
5. **Round Up for Sectors**: sizeToSectors() automatically rounds up to whole sectors