Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuples as list choices can't be hashed when containing a dict #525

Closed
Zereges opened this issue Feb 3, 2024 · 2 comments · Fixed by #526
Closed

Tuples as list choices can't be hashed when containing a dict #525

Zereges opened this issue Feb 3, 2024 · 2 comments · Fixed by #526

Comments

@Zereges
Copy link

Zereges commented Feb 3, 2024

In 3.2.1, the following worked:

>>> import inquirer
>>> test = [('aa', {'a': 1}), ('bb', {'b':2})]
>>> inquirer.list_input('Which?', carousel=True, choices=test)
[?] Which?: bb
   aa
 > bb

{'b': 2}

Whereas in 3.2.2 (and 3.2.3) this doesn't:

>>> import inquirer
>>> test = [('aa', {'a': 1}), ('bb', {'b':2})]
>>> inquirer.list_input('Which?', carousel=True, choices=test)
[?] Which?:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "App/.venv/lib/python3.11/site-packages/inquirer/shortcuts.py", line 32, in list_input
    return render.render(question)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "App/.venv/lib/python3.11/site-packages/inquirer/render/console/__init__.py", line 38, in render
    return self._event_loop(render)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "App/.venv/lib/python3.11/site-packages/inquirer/render/console/__init__.py", line 49, in _event_loop
    self._print_hint(render)
  File "App/.venv/lib/python3.11/site-packages/inquirer/render/console/__init__.py", line 96, in _print_hint
    hint = render.get_hint()
           ^^^^^^^^^^^^^^^^^
  File "App/.venv/lib/python3.11/site-packages/inquirer/render/console/_list.py", line 23, in get_hint
    hint = self.question.hints[choice]
           ~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "App/.venv/lib/python3.11/site-packages/inquirer/questions.py", line 37, in __hash__
    return hash(self.tuple)
           ^^^^^^^^^^^^^^^^
TypeError: unhashable type: 'dict'

The reason is that TaggedValue's hash function tries to hash whole tuple passed. Would it be enough to hash just the string representation (i.e. hash(self.tag)), instead of the whole tuple? I'd say the list of choices should provide unique string descriptions for every item (although it might technically not be necessary when passing hints= as well?)

@Cube707 Cube707 changed the title Tuples with dictionary as list choices no longer works as expected with v3.2.2 - regression from v3.2.1 Tuples as list choices can't be hashed when containing a dict Feb 3, 2024
@Cube707
Copy link
Collaborator

Cube707 commented Feb 3, 2024

Hm, this is a though one. The TaggedValue needs to hash to the same hash-value as the tuple it represents, so that they can be used interchangeably as dict-keys. This is need by the feature introduced in #433 to make tuple-pair and hint compatible.

I agree that it technically shouldn'd need to be hashed if no hints are provided, so I will check that if I find some time.

But as tuples in general repersend immutable data it can usually be assumed that they are hashable and this is not really a regression, instead your usecase only happend to work before due to pythons loose enforcment of such things

@Cube707
Copy link
Collaborator

Cube707 commented Feb 3, 2024

as you suggested, it is easy enough to just skip the whole hints part if its not needed, avoiding the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants