Present a menu to the user. Modeled after the bash shell's SELECT. Returns the item chosen. Argument ``opts`` can be: | a single string -> will be split into one-word options | a list of strings -> will be offered as options | a list of tuples -> int
(self, opts: str | Iterable[str] | Iterable[tuple[Any, str | None]], prompt: str = "Your choice? ")
| 4539 | return True |
| 4540 | |
| 4541 | def select(self, opts: str | Iterable[str] | Iterable[tuple[Any, str | None]], prompt: str = "Your choice? ") -> Any: |
| 4542 | """Present a menu to the user. |
| 4543 | |
| 4544 | Modeled after the bash shell's SELECT. Returns the item chosen. |
| 4545 | |
| 4546 | Argument ``opts`` can be: |
| 4547 | |
| 4548 | | a single string -> will be split into one-word options |
| 4549 | | a list of strings -> will be offered as options |
| 4550 | | a list of tuples -> interpreted as (value, text), so |
| 4551 | that the return value can differ from |
| 4552 | the text advertised to the user |
| 4553 | """ |
| 4554 | local_opts: Iterable[str] | Iterable[tuple[Any, str | None]] |
| 4555 | if isinstance(opts, str): |
| 4556 | local_opts = cast(list[tuple[Any, str | None]], list(zip(opts.split(), opts.split(), strict=False))) |
| 4557 | else: |
| 4558 | local_opts = opts |
| 4559 | fulloptions: list[tuple[Any, str]] = [] |
| 4560 | for opt in local_opts: |
| 4561 | if isinstance(opt, str): |
| 4562 | fulloptions.append((opt, opt)) |
| 4563 | else: |
| 4564 | try: |
| 4565 | val = opt[0] |
| 4566 | text = str(opt[1]) if len(opt) > 1 and opt[1] is not None else str(val) |
| 4567 | fulloptions.append((val, text)) |
| 4568 | except (IndexError, TypeError): |
| 4569 | fulloptions.append((opt[0], str(opt[0]))) |
| 4570 | |
| 4571 | if self._is_tty_session(self.main_session): |
| 4572 | try: |
| 4573 | while True: |
| 4574 | with create_app_session(input=self.main_session.input, output=self.main_session.output): |
| 4575 | result = choice(message=prompt, options=fulloptions) |
| 4576 | if result is not None: |
| 4577 | return result |
| 4578 | except KeyboardInterrupt: |
| 4579 | self.poutput("^C") |
| 4580 | raise |
| 4581 | |
| 4582 | # Non-interactive fallback |
| 4583 | for idx, (_, text) in enumerate(fulloptions): |
| 4584 | self.poutput(" %2d. %s" % (idx + 1, text)) # noqa: UP031 |
| 4585 | |
| 4586 | while True: |
| 4587 | try: |
| 4588 | response = self.read_input(prompt) |
| 4589 | except EOFError: |
| 4590 | response = "" |
| 4591 | self.poutput() |
| 4592 | except KeyboardInterrupt: |
| 4593 | self.poutput("^C") |
| 4594 | raise |
| 4595 | |
| 4596 | if not response: |
| 4597 | continue |
| 4598 |