You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.3 KiB

4 years ago
  1. # coding: utf-8
  2. #
  3. # Copyright © 2010—2014 Andrey Mikhaylenko and contributors
  4. #
  5. # This file is part of Argh.
  6. #
  7. # Argh is free software under terms of the GNU Lesser
  8. # General Public License version 3 (LGPLv3) as published by the Free
  9. # Software Foundation. See the file README.rst for copying conditions.
  10. #
  11. """
  12. Interaction
  13. ~~~~~~~~~~~
  14. """
  15. from argh.compat import text_type
  16. from argh.io import safe_input
  17. __all__ = ['confirm', 'safe_input']
  18. def confirm(action, default=None, skip=False):
  19. """
  20. A shortcut for typical confirmation prompt.
  21. :param action:
  22. a string describing the action, e.g. "Apply changes". A question mark
  23. will be appended.
  24. :param default:
  25. `bool` or `None`. Determines what happens when user hits :kbd:`Enter`
  26. without typing in a choice. If `True`, default choice is "yes". If
  27. `False`, it is "no". If `None` the prompt keeps reappearing until user
  28. types in a choice (not necessarily acceptable) or until the number of
  29. iteration reaches the limit. Default is `None`.
  30. :param skip:
  31. `bool`; if `True`, no interactive prompt is used and default choice is
  32. returned (useful for batch mode). Default is `False`.
  33. Usage::
  34. def delete(key, silent=False):
  35. item = db.get(Item, args.key)
  36. if confirm('Delete '+item.title, default=True, skip=silent):
  37. item.delete()
  38. print('Item deleted.')
  39. else:
  40. print('Operation cancelled.')
  41. Returns `None` on `KeyboardInterrupt` event.
  42. """
  43. MAX_ITERATIONS = 3
  44. if skip:
  45. return default
  46. else:
  47. defaults = {
  48. None: ('y','n'),
  49. True: ('Y','n'),
  50. False: ('y','N'),
  51. }
  52. y, n = defaults[default]
  53. prompt = text_type('{action}? ({y}/{n})').format(**locals())
  54. choice = None
  55. try:
  56. if default is None:
  57. cnt = 1
  58. while not choice and cnt < MAX_ITERATIONS:
  59. choice = safe_input(prompt)
  60. cnt += 1
  61. else:
  62. choice = safe_input(prompt)
  63. except KeyboardInterrupt:
  64. return None
  65. if choice in ('yes', 'y', 'Y'):
  66. return True
  67. if choice in ('no', 'n', 'N'):
  68. return False
  69. if default is not None:
  70. return default
  71. return None