Repository: archlinux/archinstall

Issue:
`select_disk` throw an error because BlockDevice does not contain label
Running this line from a python script causes an error: 

`archinstall.select_disk(archinstall.all_blockdevices())`


```
Traceback (most recent call last):
  File "/root/test.py", line 3, in <module>
    hdd = archinstall.select_disk(archinstall.all_blockdevices())
  File "/usr/lib/python3.10/site-packages/archinstall/lib/user_interaction/disk_conf.py", line 68, in select_disk
    f"{index}: {drive} ({dict_o_disks[drive]['size'], dict_o_disks[drive].device, dict_o_disks[drive]['label']})"
  File "/usr/lib/python3.10/site-packages/archinstall/lib/disk/blockdevice.py", line 45, in __getitem__
    raise KeyError(f'{self} does not contain information: "{key}"')
KeyError: 'BlockDevice(/dev/sr0, size=0.8GB, free_space=, bus_type=sata) does not contain information: "label"'
```


Discussion:
I was trying to reproduce this but actually got a different one myself 
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "archinstall/archinstall/lib/user_interaction/disk_conf.py", line 68, in select_disk
    f"{index}: {drive} ({dict_o_disks[drive]['size'], dict_o_disks[drive].device, dict_o_disks[drive]['label']})"
TypeError: 'DMCryptDev' object is not subscriptable
```

I'll have a look, my feeling is that the Blockdevice class is a bit fragile and might need saver data structures 
Yea i want to make these more reliable and convert dicts to data structures overall. the mixing causes issues :) my bad!
I saw that some info is coming from `blkid` I wonder if they would return at known set of key-value pairs overall or if it will return exotic stuff for strange things. If it's a known set we can easily throw it into a dataclass 
Some are mandatory things that will always be there.
But most of the fields are totally optional, but we can handle that with `Optional[X]` I guess.
Sounds good :)
I started working on this, will add some dataclasses and rework the block device code a bit :)
Sounds awesome, I've taken some inspiration from discord where each object should be responsible for it's own actions :) 

Resolving patch:
diff --git a/archinstall/lib/user_interaction/disk_conf.py b/archinstall/lib/user_interaction/disk_conf.py
--- a/archinstall/lib/user_interaction/disk_conf.py
+++ b/archinstall/lib/user_interaction/disk_conf.py
@@ -7,7 +7,6 @@
 from ..exceptions import DiskError
 from ..menu import Menu
 from ..menu.menu import MenuSelectionType
-from ..output import log
 
 if TYPE_CHECKING:
 	_: Any
@@ -60,7 +59,7 @@ def select_disk_layout(preset: Optional[Dict[str, Any]], block_devices: list, ad
 				return select_individual_blockdevice_usage(block_devices)
 
 
-def select_disk(dict_o_disks: Dict[str, BlockDevice]) -> BlockDevice:
+def select_disk(dict_o_disks: Dict[str, BlockDevice]) -> Optional[BlockDevice]:
 	"""
 	Asks the user to select a harddrive from the `dict_o_disks` selection.
 	Usually this is combined with :ref:`archinstall.list_drives`.
@@ -73,19 +72,15 @@ def select_disk(dict_o_disks: Dict[str, BlockDevice]) -> BlockDevice:
 	"""
 	drives = sorted(list(dict_o_disks.keys()))
 	if len(drives) >= 1:
-		for index, drive in enumerate(drives):
-			print(
-				f"{index}: {drive} ({dict_o_disks[drive]['size'], dict_o_disks[drive].device, dict_o_disks[drive]['label']})"
-			)
+		title = str(_('You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)')) + '\n'
+		title += str(_('Select one of the disks or skip and use /mnt as default'))
 
-		log("You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)",
-			fg="yellow")
+		choice = Menu(title, drives).run()
 
-		drive = Menu('Select one of the disks or skip and use "/mnt" as default"', drives).run()
-		if not drive:
-			return drive
+		if choice.type_ == MenuSelectionType.Esc:
+			return None
 
-		drive = dict_o_disks[drive]
+		drive = dict_o_disks[choice.value]
 		return drive
 
 	raise DiskError('select_disk() requires a non-empty dictionary of disks to select from.')


Test patch: