Repository: archlinux/archinstall

Issue:
AttributeError: 'dict' object has no attribute 'index'
I got this error when typing "gnome" when asked for what profile to install. It is thrown on this line:

https://github.com/archlinux/archinstall/blob/1a09ad7bff5d799180b926df4a3611c8f7a6ea29/archinstall/lib/user_interaction.py#L254

Would a `selected_profile = options[list(options).index(selected_profile)]` solve this one?

~can't copy text from this VM~ just remembered screenshots exist

![Screenshot from 2021-04-06 12-19-58](https://user-images.githubusercontent.com/1429672/113766663-88f52d80-96d2-11eb-9cd7-154f98a487f8.png)



Discussion:
Instead of typing gnome you should have hit '2'. That said, looking up the index by value on an error might work to recover from a situation where a user inputs the value instead of number. 
> Instead of typing gnome you should have hit '2'. That said, looking up the index by value on an error might work to recover from a situation where a user inputs the value instead of number.

Agreed, this option was *meant* to be a number-input, but it should also support by name, so this is a mistake on my end :)
It looks like the line that threw the error already tries to account for this, in the way you said. I think the `list` conversion in my OP might fix :smiley: 

I was using numbers up until that point, but what threw me off was the installer asking for "Enter a pre-programmed profile **name**". Anyway, it's a cool installer, thanks for writing it!
We, and by we I mean me, should really start using [generic_select()](https://github.com/archlinux/archinstall/blob/a8da159f176b6867ccf147780c63ee7c7ba3045b/archinstall/lib/user_interaction.py#L164) which supports both numbers and text-input.
FYI, this seems to be resolved in master and can probably be closed:

![VirtualBox_arch_11_04_2021_20_41_29](https://user-images.githubusercontent.com/277927/114327264-59955500-9b06-11eb-85b2-690a92c6d988.png)

Note that this issue persists for the graphics driver selection, and I would rework it in master, but there are substantial changes to this GPU driver selection logic being made in 2.2.0, so it'll probably get fixed in that version :)

Resolving patch:
diff --git a/archinstall/lib/gfx_drivers.py b/archinstall/lib/gfx_drivers.py
deleted file mode 100644
--- a/archinstall/lib/gfx_drivers.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import archinstall
-
-AVAILABLE_DRIVERS = {
-	# Sub-dicts are layer-2 options to be selected
-	# and lists are a list of packages to be installed
-	'AMD / ATI' : {
-		'amd' : ['xf86-video-amdgpu'],
-		'ati' : ['xf86-video-ati']
-	},
-	'intel' : ['xf86-video-intel'],
-	'nvidia' : {
-		'open source' : ['xf86-video-nouveau'],
-		'proprietary' : ['nvidia']
-	},
-	'mesa' : ['mesa'],
-	'fbdev' : ['xf86-video-fbdev'],
-	'vesa' : ['xf86-video-vesa'],
-	'vmware' : ['xf86-video-vmware']
-}
-
-def select_driver(options=AVAILABLE_DRIVERS):
-	"""
-	Some what convoluted function, which's job is simple.
-	Select a graphics driver from a pre-defined set of popular options.
-
-	(The template xorg is for beginner users, not advanced, and should
-	there for appeal to the general public first and edge cases later)
-	"""
-	drivers = sorted(list(options))
-
-	if len(drivers) >= 1:
-		for index, driver in enumerate(drivers):
-			print(f"{index}: {driver}")
-
-		print(' -- The above list are supported graphic card drivers. --')
-		print(' -- You need to select (and read about) which one you need. --')
-
-		lspci = archinstall.sys_command(f'/usr/bin/lspci')
-		for line in lspci.trace_log.split(b'\r\n'):
-			if b' vga ' in line.lower():
-				if b'nvidia' in line.lower():
-					print(' ** nvidia card detected, suggested driver: nvidia **')
-				elif b'amd' in line.lower():
-					print(' ** AMD card detected, suggested driver: AMD / ATI **')
-
-		selected_driver = input('Select your graphics card driver: ')
-		initial_option = selected_driver
-
-		# Disabled search for now, only a few profiles exist anyway
-		#
-		#print(' -- You can enter ? or help to search for more drivers --')
-		#if selected_driver.lower() in ('?', 'help'):
-		#	filter_string = input('Search for layout containing (example: "sv-"): ')
-		#	new_options = search_keyboard_layout(filter_string)
-		#	return select_language(new_options)
-		if selected_driver.isdigit() and (pos := int(selected_driver)) <= len(drivers)-1:
-			selected_driver = options[drivers[pos]]
-		elif selected_driver in options:
-			selected_driver = options[options.index(selected_driver)]
-		elif len(selected_driver) == 0:
-			raise archinstall.RequirementError("At least one graphics driver is needed to support a graphical environment. Please restart the installer and try again.")
-		else:
-			raise archinstall.RequirementError("Selected driver does not exist.")
-
-		if type(selected_driver) == dict:
-			driver_options = sorted(list(selected_driver))
-			for index, driver_package_group in enumerate(driver_options):
-				print(f"{index}: {driver_package_group}")
-
-			selected_driver_package_group = input(f'Which driver-type do you want for {initial_option}: ')
-			if selected_driver_package_group.isdigit() and (pos := int(selected_driver_package_group)) <= len(driver_options)-1:
-				selected_driver_package_group = selected_driver[driver_options[pos]]
-			elif selected_driver_package_group in selected_driver:
-				selected_driver_package_group = selected_driver[selected_driver.index(selected_driver_package_group)]
-			elif len(selected_driver_package_group) == 0:
-				raise archinstall.RequirementError(f"At least one driver package is required for a graphical environment using {selected_driver}. Please restart the installer and try again.")
-			else:
-				raise archinstall.RequirementError(f"Selected driver-type does not exist for {initial_option}.")
-
-			return selected_driver_package_group
-
-		return selected_driver
-
-	raise archinstall.RequirementError("Selecting drivers require a least one profile to be given as an option.")
\ No newline at end of file
diff --git a/archinstall/lib/hardware.py b/archinstall/lib/hardware.py
--- a/archinstall/lib/hardware.py
+++ b/archinstall/lib/hardware.py
@@ -12,7 +12,7 @@
 	},
 	'intel' : ['xf86-video-intel'],
 	'nvidia' : {
-		'open source' : ['xf86-video-nouveau'],
+		'open-source' : ['xf86-video-nouveau'],
 		'proprietary' : ['nvidia']
 	},
 	'mesa' : ['mesa'],
diff --git a/archinstall/lib/user_interaction.py b/archinstall/lib/user_interaction.py
--- a/archinstall/lib/user_interaction.py
+++ b/archinstall/lib/user_interaction.py
@@ -412,15 +412,7 @@ def select_driver(options=AVAILABLE_GFX_DRIVERS):
 	(The template xorg is for beginner users, not advanced, and should
 	there for appeal to the general public first and edge cases later)
 	"""
-	drivers = sorted(list(options))
-
-	if len(drivers) >= 1:
-		for index, driver in enumerate(drivers):
-			print(f"{index}: {driver}")
-
-		print(' -- The above list are supported graphic card drivers. --')
-		print(' -- You need to select (and read about) which one you need. --')
-
+	if len(options) >= 1:
 		lspci = sys_command(f'/usr/bin/lspci')
 		for line in lspci.trace_log.split(b'\r\n'):
 			if b' vga ' in line.lower():
@@ -429,37 +421,16 @@ def select_driver(options=AVAILABLE_GFX_DRIVERS):
 				elif b'amd' in line.lower():
 					print(' ** AMD card detected, suggested driver: AMD / ATI **')
 
-		selected_driver = input('Select your graphics card driver: ')
+		selected_driver = generic_select(options, input_text="Select your graphics card driver: ", sort=True)
 		initial_option = selected_driver
 
-		# Disabled search for now, only a few profiles exist anyway
-		#
-		#print(' -- You can enter ? or help to search for more drivers --')
-		#if selected_driver.lower() in ('?', 'help'):
-		#	filter_string = input('Search for layout containing (example: "sv-"): ')
-		#	new_options = search_keyboard_layout(filter_string)
-		#	return select_language(new_options)
-		if selected_driver.isdigit() and (pos := int(selected_driver)) <= len(drivers)-1:
-			selected_driver = options[drivers[pos]]
-		elif selected_driver in options:
-			selected_driver = options[options.index(selected_driver)]
-		elif len(selected_driver) == 0:
-			raise RequirementError("At least one graphics driver is needed to support a graphical environment. Please restart the installer and try again.")
-		else:
-			raise RequirementError("Selected driver does not exist.")
-
-		if type(selected_driver) == dict:
-			driver_options = sorted(list(selected_driver))
-			for index, driver_package_group in enumerate(driver_options):
-				print(f"{index}: {driver_package_group}")
-
-			selected_driver_package_group = input(f'Which driver-type do you want for {initial_option}: ')
-			if selected_driver_package_group.isdigit() and (pos := int(selected_driver_package_group)) <= len(driver_options)-1:
-				selected_driver_package_group = selected_driver[driver_options[pos]]
-			elif selected_driver_package_group in selected_driver:
-				selected_driver_package_group = selected_driver[selected_driver.index(selected_driver_package_group)]
-			elif len(selected_driver_package_group) == 0:
-				raise RequirementError(f"At least one driver package is required for a graphical environment using {selected_driver}. Please restart the installer and try again.")
+		if type(options[initial_option]) == dict:
+			driver_options = sorted(options[initial_option].keys())
+
+			selected_driver_package_group = generic_select(driver_options, input_text=f"Which driver-type do you want for {initial_option}: ")
+			if selected_driver_package_group in options[initial_option].keys():
+				print(options[initial_option][selected_driver_package_group])
+				selected_driver = options[initial_option][selected_driver_package_group]
 			else:
 				raise RequirementError(f"Selected driver-type does not exist for {initial_option}.")
 
@@ -467,4 +438,4 @@ def select_driver(options=AVAILABLE_GFX_DRIVERS):
 
 		return selected_driver
 
-	raise RequirementError("Selecting drivers require a least one profile to be given as an option.")
\ No newline at end of file
+	raise RequirementError("Selecting drivers require a least one profile to be given as an option.")


Test patch: