tmbo / questionary

Python library to build pretty command line user prompts ✨Easy to use multi-select lists, confirmations, free text prompts ...
MIT License
1.53k stars 87 forks source link

Add print question type to dictionary style prompt #207

Closed PhML closed 2 years ago

PhML commented 2 years ago

Describe the problem

With version 1.10.0 when I want to use both prompt with dictionary and print question type, I need to call several prompts and to merge answers:

from pprint import pprint
from questionary import Separator, prompt
from questionary import print as qprint

def ask_dictstyle(**kwargs):
    questions = [
        {
            "type": "text",
            "name": "first",
            "message": "Your first message:",
        },
        {
            "type": "text",
            "name": "second",
            "message": "Your second message",
        },
    ]

    answers = prompt(questions)
    qprint("Oh! I need to give somme fancy explanations about what’s next!🦄", style="bold italic fg:darkred")
    questions = [
        {
            "type": "select",
            "name": "third",
            "message": "Select item",
            "choices": ["item1", "item2", Separator(), "other"],
        },
    ]
    answers.update(prompt(questions))
    return answers

if __name__ == "__main__":
    pprint(ask_dictstyle())

Describe the solution

Adding print type to prompt dictionary would resolve the issue:

from pprint import pprint
from questionary import Separator, prompt

def ask_dictstyle(**kwargs):
    questions = [
        {
            "type": "text",
            "name": "first",
            "message": "Your first message:",
        },
        {
            "type": "text",
            "name": "second",
            "message": "Your second message",
        },
        {
            "type": "print",
            "name": "help", #  Do I need a name?
            "message": "Oh! I need to give somme fancy explanations about what’s next!🦄",
            "style": "bold italic fg:darkred",
        },
        {
            "type": "select",
            "name": "third",
            "message": "Select item",
            "choices": ["item1", "item2", Separator(), "other"],
        },
    ]
    return prompt(questions)

if __name__ == "__main__":
    pprint(ask_dictstyle())

Alternatives considered

No response

tmbo commented 2 years ago

Oh that is a really good point - @PhML I'd love to merge this as a contribution, any chance you can take a stab at it? Happy to provide pointers and help out

RhetTbull commented 2 years ago

Anyone working a PR for this? I'm willing to take a stab at it if no one is.

RhetTbull commented 2 years ago

I've got a basic implementation working. Question for those interested in this feature: should it work with the qmark value or not? I think it makes sense that if you're just printing a message, you don't want/need to the qmark value (that is, print type would just print message with style style and ignore qmark) but open to feedback.

Python 3.10.5 (main, Jun 23 2022, 17:18:49) [Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from questionary import prompt
>>> prompt([{"name": "name", "type": "text", "message": "What is your name"},{"name": "printme", "type": "print", "message": "Hello Rhet 🦄", "style": "bold italic fg:darkred", "qmark": True, "when": lambda x: x["name"] == "Rhet"}])
? What is your name Rhet
Hello Rhet 🦄
{'name': 'Rhet'}
>>>

(I tried to do an asciinema recording per the contributor's guide but couldn't figure out how to make it work with my python virtual environment to load the right python)

Screen Shot 2022-07-31 at 6 38 13 PM
kiancross commented 2 years ago

I think it makes sense that if you're just printing a message, you don't want/need to the qmark value (that is, print type would just print message with style style and ignore qmark)

I agree with this.

Thanks for working on a PR :)

tmbo commented 2 years ago

Nice work 🎉 , do you mind opening a PR?

RhetTbull commented 2 years ago

Yes, I'm working on a PR but I'm reworking the implementation because I feel it's a bit too "hacky" at the moment. I initially wanted to avoid modifying prompt() so I added a new prompt type that subclasses Question which just prints without asking so that when prompt calls Question.ask_unsafe(), everything 'just works'. This is not super intuitive though so I think it would be cleaner to just have prompt() handle the print. As soon as I get a chance to fix this I'll push a PR!

RhetTbull commented 2 years ago

PR submitted (#244)