Source code for diskinfo.disk

#
#    Module `disk`: implements `Disk` class.
#    Peter Sulyok (C) 2022-2026.
#
import os
import re
from typing import List, Tuple, Union
import pySMART
from pyudev import Context, Device, Devices, DeviceNotFoundAtPathError
from diskinfo.utils import _read_file, size_in_hrf, _pyudev_getenc
from diskinfo.disktype import DiskType
from diskinfo.filesystem import FileSystem
from diskinfo.partition import Partition
from diskinfo.disksmart import DiskSmartData, SmartAttribute, NvmeAttributes


[docs] class Disk: """The Disk class contains all disk related information. The class can be initialized with specifying one of the five unique identifiers of the disk: * a disk name (e.g. `sda` or `nvme0n1`) located in `/dev/` directory. * a disk serial number (e.g. `"92837A469FF876"`) * a disk `wwn identifier <https://en.wikipedia.org/wiki/World_Wide_Name>`_ (e.g. `"0x5002638c807270be"`) * a `by-id` name of the disk (e.g. `"ata-Samsung_SSD_850_PRO_1TB_92837A469FF876"`) located in `/dev/disk/by-id/` directory * a `by-path` name of the disk (e.g. `"pci-0000:00:17.0-ata-3"`) located in `/dev/disk/by-path/` directory Based on the specified input parameter the disk will be identified and its attributes will be collected and stored. A :py:obj:`ValueError` exception will be raised in case of missing or invalid disk identifier. Operators (``<``, ``>`` and ``==``) are also implemented for this class to compare different class instances, they use the disk name for comparison. .. note:: During the class initialization the disk will not be physically accessed. Args: disk_name (str): the disk name serial_number (str): serial number of the disk wwn (str): wwn identifier of the disk byid_name (str): by-id name of the disk bypath_name (str): by-path name of the disk _device (pyudev.Device): pyudev.Device() class (internal use) Raises: ValueError: in case of missing or invalid parameters RuntimeError: in case of any system error Example: This example shows how to create a :class:`~diskinfo.Disk` class then how to get its path and serial number:: >>> from diskinfo import Disk >>> d = Disk("sda") >>> d.get_path() "/dev/sda" >>> d.get_serial_number() "S3D2NY0J819210S" and here are additional ways how the :class:`~diskinfo.Disk` class can be initialized:: >>> d = Disk(serial_number="92837A469FF876") >>> d.get_name() "sdc" >>> d = Disk(wwn="0x5002539c417223be") >>> d.get_name() "sdc" >>> d = Disk(byid_name="ata-Samsung_SSD_850_PRO_1TB_92837A469FF876") >>> d.get_name() "sdc" >>> d = Disk(bypath_name="pci-0000:00:17.0-ata-3") >>> d.get_name() "sdc" """ # Disk attributes: __name: str # Disk name (e.g. sda) __path: str # Disk path (e.g. /dev/sda) __byid_path: List[str] # Disk by-id paths (e.g. /dev/disk/by-id/ata-WDC_WD80FLAX...) __bypath_path: List[str] # Disk by-path paths (e.g. /dev/disk/by-path/pci-0000:00:17.0-ata-1) __wwn: str # Disk WWN __model: str # Disk model __serial_number: str # Disk serial number __firmware: str # Disk firmware __type: int # Disk type (HDD, SSD, NVME or LOOP) __size: int # Disk size (number of 512-byte blocks) __device_id: str # Disk device id (e.g. 8:0) __physical_block_size: int # Disk physical block size __logical_block_size: int # Disk logical block size __part_table_type: str # Disk partition table type __part_table_uuid: str # Disk partition table UUID __hwmon_path: str # Path for the /sys/HWMON temperature file __partitions: List[Partition] # List of partitions on the disk __filesystem: Union[FileSystem, None] # Raw filesystem (no partition table) def __init__(self, disk_name: str = None, serial_number: str = None, wwn: str = None, byid_name: str = None, bypath_name: str = None, _device: Device = None) -> None: """See class definition docstring above.""" pyudev_context: Context pyudev_device: Union[Device, None] # Create pyudev context. pyudev_context = Context() pyudev_device = None # Initialization 1: disk name. if disk_name: try: pyudev_device = Devices.from_name(pyudev_context, "block", disk_name) except DeviceNotFoundAtPathError as exc: raise ValueError(f"ERROR: Disk name not found: {disk_name}.") from exc # Initialization 2: disk serial number. elif serial_number: for dev in pyudev_context.list_devices(subsystem="block", DEVTYPE="disk"): if dev.get("ID_SERIAL_SHORT") == serial_number: pyudev_device = dev break if pyudev_device is None: raise ValueError(f"ERROR: Serial number not found: {serial_number}.") # Initialization 3: disk WWN name. elif wwn: for dev in pyudev_context.list_devices(subsystem="block", DEVTYPE="disk"): if dev.get("ID_WWN") == wwn: pyudev_device = dev break if pyudev_device is None: raise ValueError(f"ERROR: WWN number not found: {wwn}.") # Initialization 4: disk `by-id` name. elif byid_name: try: name = os.readlink("/dev/disk/by-id/" + byid_name) except (OSError, FileNotFoundError) as exc: raise ValueError(f"ERROR: /dev/disk/by-id/ name not found: {byid_name}.") from exc try: pyudev_device = Devices.from_name(pyudev_context, "block", os.path.basename(name)) except DeviceNotFoundAtPathError as exc: raise ValueError(f"ERROR: /dev/disk/by-id/ name not found: {byid_name}.") from exc # Initialization 5: disk `by-path` name. elif bypath_name: try: name = os.readlink("/dev/disk/by-path/" + bypath_name) except (OSError, FileNotFoundError) as exc: raise ValueError(f"ERROR: /dev/disk/by-path/ name not found: {bypath_name}.") from exc try: pyudev_device = Devices.from_name(pyudev_context, "block", os.path.basename(name)) except DeviceNotFoundAtPathError as exc: raise ValueError(f"ERROR: /dev/disk/by-path/ name not found: {bypath_name}.") from exc # Initialization 6: pyudev device. elif _device: pyudev_device = _device # Initialization error (none of them was specified). else: raise ValueError("ERROR: Missing disk identifier, Disk() class cannot be initialized.") # Read disk attributes. self.__name = pyudev_device.sys_name self.__path = pyudev_device.device_node self.__size = pyudev_device.attributes.asint("size") self.__device_id = pyudev_device.attributes.asstring("dev") self.__physical_block_size = pyudev_device.attributes.asint("queue/physical_block_size") self.__logical_block_size = pyudev_device.attributes.asint("queue/logical_block_size") # Determination of the disk type (HDD, SSD, NVME or LOOP) # Type: LOOP if re.match(r"^7:", self.__device_id): self.__type = DiskType.LOOP # Type: NVME elif "nvme" in self.__name: self.__type = DiskType.NVME # Type: SSD or HDD else: rotational = pyudev_device.attributes.asstring("queue/rotational") if rotational == "1": self.__type = DiskType.HDD elif rotational == "0": self.__type = DiskType.SSD else: raise RuntimeError(f"Disk type cannot be determined: disk={pyudev_device.sys_name}, queue/rotational={rotational}.") # Read further disk attributes. self.__serial_number = pyudev_device.get("ID_SERIAL_SHORT") self.__firmware = pyudev_device.get("ID_REVISION") self.__wwn = pyudev_device.get("ID_WWN") self.__part_table_type = pyudev_device.get("ID_PART_TABLE_TYPE") self.__part_table_uuid = pyudev_device.get("ID_PART_TABLE_UUID") self.__model = _pyudev_getenc(pyudev_device, "ID_MODEL") # Read `/dev/disk/by-byid/` and `/dev/disk/by-path/` path elements. self.__byid_path = [] self.__bypath_path = [] for link in pyudev_device.device_links: if link.startswith("/dev/disk/by-id"): self.__byid_path.append(link) continue if link.startswith("/dev/disk/by-path"): self.__bypath_path.append(link) continue # Find HWMON path. self.__hwmon_path = "" try: c = Context() [hwmon_dev] = c.list_devices(subsystem="hwmon", parent=pyudev_device.parent) self.__hwmon_path = os.path.join(hwmon_dev.sys_path, "temp1_input") except ValueError: pass # Iterate on the partitions of this disk. self.__partitions = [] for children in pyudev_device.children: if children.device_type == "partition": self.__partitions.append(Partition(children)) # Detect raw filesystem (no partition table, no partitions). self.__filesystem = None if not self.__partitions and not self.__part_table_type: fs_type = pyudev_device.get("ID_FS_TYPE") if fs_type: self.__filesystem = FileSystem(pyudev_device)
[docs] def get_name(self) -> str: """Returns the disk name. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk(serial_number="92837A469FF876") >>> d.get_name() "sdc" """ return self.__name
[docs] def get_path(self) -> str: """Returns the disk path. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk(serial_number="92837A469FF876") >>> d.get_path() "/dev/sdc" .. note:: Please note this path is not persistent (i.e. it may refer different physical disk after a reboot). """ return self.__path
[docs] def get_byid_path(self) -> List[str]: """Returns disk path in a persistent ``/dev/disk/by-id/...`` form. The result could be one or more path elements in a list. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_byid_path() ["/dev/disk/by-id/ata-Samsung_SSD_850_PRO_1TB_92837A469FF876", "/dev/disk/by-id/wwn-0x5002539c417223be"] """ return self.__byid_path
[docs] def get_bypath_path(self) -> List[str]: """Returns disk path in a persistent ``/dev/disk/by-path/...`` form. The result could be one or more path elements in a list. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_bypath_path() ["/dev/disk/by-path/pci-0000:00:17.0-ata-3", "/dev/disk/by-path/pci-0000:00:17.0-ata-3.0"] """ return self.__bypath_path
[docs] def get_wwn(self) -> str: """Returns the world-wide name (WWN) of the disk. Read more about `WWN here <https://en.wikipedia.org/wiki/World_Wide_Name>`_. .. note:: This is a unique and persistent identifier of a disk. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_wwn() "0x5002539c417223be" """ return self.__wwn
[docs] def get_model(self) -> str: """Returns the disk model string. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_model() "Samsung SSD 850 PRO 1TB" """ return self.__model
[docs] def get_serial_number(self) -> str: """Returns the disk serial number. .. note:: This is a unique and persistent identifier of the disk. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_serial_number() "92837A469FF876" """ return self.__serial_number
[docs] def get_firmware(self) -> str: """Returns the disk firmware string. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_firmware() "EXM04B6Q" """ return self.__firmware
[docs] def get_type(self) -> int: """Returns the type of the disk. One of the constants in :class:`~diskinfo.DiskType` class: - ``DiskType.HDD`` for hard disks (with spinning platters) - ``DiskType.SSD`` for SDDs on SATA or USB interface - ``DiskType.NVME`` for NVME disks - ``DiskType.LOOP`` for LOOP disks Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_type() 2 """ return self.__type
[docs] def is_ssd(self) -> bool: """Returns `True` if the disk type is SSD, otherwise `False`. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.is_ssd() True """ return bool(self.__type == DiskType.SSD)
[docs] def is_nvme(self) -> bool: """Returns `True` if the disk type is NVME, otherwise `False`. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.is_nvme() False """ return bool(self.__type == DiskType.NVME)
[docs] def is_hdd(self) -> bool: """Returns `True` if the disk type is HDD, otherwise `False`. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.is_hdd() False """ return bool(self.__type == DiskType.HDD)
[docs] def is_loop(self) -> bool: """Returns `True` if the disk type is LOOP, otherwise `False`. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("loop0") >>> d.is_loop() True """ return bool(self.__type == DiskType.LOOP)
[docs] def get_type_str(self) -> str: """Returns the name of the disk type. See the return values in :class:`~diskinfo.DiskType` class: - ``DiskType.HDD_STR`` for hard disks (with spinning platters) - ``DiskType.SSD_STR`` for SDDs on SATA or USB interface - ``DiskType.NVME_STR`` for NVME disks - ``DiskType.LOOP_STR`` for LOOP disks Raises: RuntimeError: in case of unknown disk type. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_type_str() "SSD" """ if self.is_nvme(): return DiskType.NVME_STR if self.is_ssd(): return DiskType.SSD_STR if self.is_hdd(): return DiskType.HDD_STR if self.is_loop(): return DiskType.LOOP_STR raise RuntimeError(f"Unknown disk type (type={self.__type})")
[docs] def get_size(self) -> int: """Returns the size of the disk in 512-byte units. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> s = d.get_size() >>> print(f"Disk size: { s * 512 } bytes.") Disk size: 1024209543168 bytes. """ return self.__size
[docs] def get_size_in_hrf(self, units: int = 0) -> Tuple[float, str]: """Returns the size of the disk in a human-readable form. Args: units (int): unit system will be used in result: - 0 metric units (default) - 1 IEC units - 2 legacy units Read more about `units here <https://en.wikipedia.org/wiki/Byte>`_. Returns: Tuple[float, str]: size of the disk, proper unit Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> s,u = d.get_size_in_hrf() >>> print(f"{s:.1f} {u}") 1.0 TB """ return size_in_hrf(self.__size * 512, units)
[docs] def get_device_id(self) -> str: """Returns the disk device id in `"major:minor"` form. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_device_id() "8:32" """ return self.__device_id
[docs] def get_physical_block_size(self) -> int: """Returns the physical block size of the disk in bytes. Typical value is 512 bytes for SSDs/NVMEs, and 4096 bytes for HDDs. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_physical_block_size() 512 """ return self.__physical_block_size
[docs] def get_logical_block_size(self) -> int: """Returns the logical block size of the disk in bytes. Typical value is 512 bytes. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_logical_block_size() 512 """ return self.__logical_block_size
[docs] def get_partition_table_type(self) -> str: """Returns the type of the partition table on the disk (e.g. `mbr` or `gpt`). Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_partition_table_type() "gpt" """ return self.__part_table_type
[docs] def get_partition_table_uuid(self) -> str: """Returns the UUID of the partition table on the disk. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_partition_table_uuid() "d3f932e0-7107-455e-a569-9acd5b60d204" """ return self.__part_table_uuid
[docs] def get_temperature(self, sudo: bool = False, smartctl_path: str = "/usr/sbin/smartctl") -> Union[float, None]: """Returns the current disk temperature. The method will try to read disk temperature from the Linux kernel HWMON interface first then will try to execute the `smartctl` command. The method has the following requirements: .. list-table:: :header-rows: 1 * - Disk type - Requirement * - SATA HDD/SSD - `drivetemp` kernel module (Linux kernel version `5.6+`) has to be loaded * - SCSI/ATA HDD - `smartmontools` has to be installed * - NVME - none .. note:: Please note that reading disk temperature from HWMON kernel interface will not access the disk and will not change its power state (e.g. HDD can be in STANDBY state) but reading disk temperature with `smartctl` will do. Args: sudo (bool): ``sudo`` command should be used for ``smartctl``, default value is ``False`` smartctl_path (str): Path for ``smartctl`` command, default value is ``/usr/sbin/smartctl`` Returns: float: disk temperature in degrees Celsius or None if the temperature cannot be determined Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdc") >>> d.get_temperature(sudo=True) 28.5 """ temp: float sd: pySMART.Device # Read disk temperature from HWMON system of the Linux kernel. if hasattr(self, "_Disk__hwmon_path") and \ self.__hwmon_path and \ os.path.exists(self.__hwmon_path): try: return float(_read_file(self.__hwmon_path)) / 1000.0 except ValueError: pass # Read disk temperature from `smartctl` command. pySMART.SMARTCTL.options = [] pySMART.SMARTCTL.smartctl_path = smartctl_path if sudo: pySMART.SMARTCTL.sudo = True else: pySMART.SMARTCTL.sudo = False sd = pySMART.Device(self.__path) temp = sd.temperature if not temp: return None return float(temp)
[docs] def get_smart_data(self, nocheck: bool = False, sudo: bool = False, smartctl_path: str = "/usr/sbin/smartctl") \ -> Union[DiskSmartData, None]: """Returns SMART data of the disk. This function will execute the ``smartctl`` command from the `smartmontools <https://www.smartmontools.org/>`_ package. It needs to be installed. .. note:: ``smartctl`` command needs root privilege for reading device SMART attributes. This function has to be used as `root` user or called with ``sudo=True`` parameter. In case of HDDs, the ``smartctl`` command will access the disk directly and the HDD could be woken up. If the ``nocheck=True`` parameter is used then the current power state of the disk will be preserved. Args: nocheck (bool): No check should be applied for a HDDs (``"-n standby"`` argument will be used) sudo (bool): ``sudo`` command should be used, default value is ``False`` smartctl_path (str): Path for ``smartctl`` command, default value is ``/usr/sbin/smartctl`` Returns: DiskSmartData: SMART information of the disk (see more details at :class:`~diskinfo.DiskSmartData` class) or None if `smartctl` cannot be executed Example: The following example shows the use of the function:: >>> from diskinfo import Disk, DiskSmartData >>> d = Disk("sda") >>> d = d.get_smart_data() In case of SSDs and HDDs the traditional SMART attributes can be accessed via :attr:`~diskinfo.DiskSmartData.smart_attributes` list:: >>> for item in d.smart_attributes: ... print(f"{item.id:>3d} {item.attribute_name}: {item.raw_value}") ... 5 Reallocated_Sector_Ct: 0 9 Power_On_Hours: 6356 12 Power_Cycle_Count: 2308 177 Wear_Leveling_Count: 2 179 Used_Rsvd_Blk_Cnt_Tot: 0 181 Program_Fail_Cnt_Total: 0 182 Erase_Fail_Count_Total: 0 183 Runtime_Bad_Block: 0 187 Uncorrectable_Error_Cnt: 0 190 Airflow_Temperature_Cel: 28 195 ECC_Error_Rate: 0 199 CRC_Error_Count: 0 235 POR_Recovery_Count: 67 241 Total_LBAs_Written: 9869978356 In case of NVME disks they have their own SMART data in :attr:`~diskinfo.DiskSmartData.nvme_attributes` field:: >>> if d.is_nvme(): ... print(f"Power on hours: {d.nvme_attributes.power_on_hours} h") ... Power on hours: 1565 h """ sd: pySMART.Device # Device class created by pySMART rv: DiskSmartData # return value # Ignore loop disks. if self.is_loop(): return None rv = DiskSmartData() rv.standby_mode = False pySMART.SMARTCTL.options = [] pySMART.SMARTCTL.smartctl_path = smartctl_path # If sudo command should be used if sudo: pySMART.SMARTCTL.sudo = True else: pySMART.SMARTCTL.sudo = False # If no check should be applied in standby power mode of an HDD if nocheck: pySMART.SMARTCTL.add_options(["-n", "standby"]) # Check if `smartctl` can be executed. output = pySMART.SMARTCTL.info(self.__path) if not output: return None # Check if the disk is in STANDBY mode if "Device is in STANDBY mode" in output[3]: rv.standby_mode = True return rv # Get SMART data from pySMART. sd = pySMART.Device(self.__path) # Check if the device interface was not identified (i.e. unknown device). if not sd.interface: return None # Save SMART flags. rv.smart_enabled = sd.smart_enabled rv.smart_capable = sd.smart_capable # Find overall-health status if sd.assessment == "PASS": rv.healthy = True else: rv.healthy = False # Read and store of NVME attributes if self.is_nvme(): if hasattr(sd, "if_attributes"): rv.nvme_attributes = NvmeAttributes( sd.if_attributes.criticalWarning if hasattr(sd.if_attributes, "criticalWarning") else None, sd.if_attributes._temperature if hasattr(sd.if_attributes, "_temperature") else None, sd.if_attributes.availableSpare if hasattr(sd.if_attributes, "availableSpare") else None, sd.if_attributes.availableSpareThreshold if hasattr(sd.if_attributes, "availableSpareThreshold") else None, sd.if_attributes.percentageUsed if hasattr(sd.if_attributes, "percentageUsed") else None, sd.if_attributes.dataUnitsRead if hasattr(sd.if_attributes, "dataUnitsRead") else None, sd.if_attributes.dataUnitsWritten if hasattr(sd.if_attributes, "dataUnitsWritten") else None, sd.if_attributes.hostReadCommands if hasattr(sd.if_attributes, "hostReadCommands") else None, sd.if_attributes.hostWriteCommands if hasattr(sd.if_attributes, "hostWriteCommands") else None, sd.if_attributes.controllerBusyTime if hasattr(sd.if_attributes, "controllerBusyTime") else None, sd.if_attributes.powerCycles if hasattr(sd.if_attributes, "powerCycles") else None, sd.if_attributes.powerOnHours if hasattr(sd.if_attributes, "powerOnHours") else None, sd.if_attributes.unsafeShutdowns if hasattr(sd.if_attributes, "unsafeShutdowns") else None, sd.if_attributes.integrityErrors if hasattr(sd.if_attributes, "integrityErrors") else None, sd.if_attributes.errorEntries if hasattr(sd.if_attributes, "errorEntries") else None, sd.if_attributes.warningTemperatureTime if hasattr(sd.if_attributes, "warningTemperatureTime") else None, sd.if_attributes.criticalTemperatureTime if hasattr(sd.if_attributes, "criticalTemperatureTime") else None ) # Read and save SATA attributes else: if hasattr(sd, "if_attributes") and hasattr(sd.if_attributes, "legacyAttributes"): rv.smart_attributes = [] for i in sd.if_attributes.legacyAttributes: if i: rv.smart_attributes.append(SmartAttribute(i.num, i.name, i.flags, i.value_int, i.worst, i.thresh, i.type, i.updated, i.when_failed, i.raw_int) ) return rv
[docs] def get_filesystem(self) -> Union[FileSystem, None]: """Returns the :class:`~diskinfo.FileSystem` object if the disk has a raw filesystem (i.e. a filesystem created directly on the block device without a partition table). Returns ``None`` if no raw filesystem is detected. Returns: Union[FileSystem, None]: filesystem information or None Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdb") >>> fs = d.get_filesystem() >>> if fs: ... print(fs.get_fs_type()) ... ext4 """ return self.__filesystem
[docs] def has_filesystem(self) -> bool: """Returns ``True`` if the disk has a raw filesystem (i.e. a filesystem created directly on the block device without a partition table), otherwise ``False``. Example: An example about the use of this function:: >>> from diskinfo import Disk >>> d = Disk("sdb") >>> d.has_filesystem() True """ return self.__filesystem is not None
[docs] def get_partition_list(self) -> List[Partition]: """Returns the list of partitions on the disk. See :class:`~diskinfo.Partition` class for more details about a partition entry. Returns: List[Partition]: list of partitions Example: >>> from diskinfo import * >>> disk=Disk("nvme0n1") >>> plist=disk.get_partition_list() >>> for item in plist: ... print(item.get_name()) ... nvme0n1p1 nvme0n1p2 nvme0n1p3 nvme0n1p4 nvme0n1p5 nvme0n1p6 """ return self.__partitions
def __gt__(self, other) -> bool: """Implementation of ">" operator for Disk class.""" return bool(self.__name > other.__name) def __lt__(self, other) -> bool: """Implementation of "<" operator for Disk class.""" return bool(self.__name < other.__name) def __eq__(self, other) -> bool: """Implementation of "==" operator for Disk class.""" return bool(self.__name == other.__name) def __repr__(self): """String representation of the Disk class.""" return (f"Disk(name={self.__name}, " f"path={self.__path}, " f"byid_path={self.__byid_path}, " f"by_path={self.__bypath_path}, " f"wwn={self.__wwn}, " f"model={self.__model}, " f"serial={self.__serial_number}, " f"firmware={self.__firmware}, " f"type={self.get_type_str()}, " f"size={self.__size}, " f"device_id={self.__device_id}, " f"physical_block_size={self.__physical_block_size}, " f"logical_block_size={self.__logical_block_size}, " f"partition_table_type={self.__part_table_type}, " f"partition_table_uuid={self.__part_table_uuid}, " f"filesystem={self.__filesystem})")
# End.