From 17d215dfa332009a3987d93cfbddaf316f09f057 Mon Sep 17 00:00:00 2001 From: Rafik Lekouara Date: Mon, 27 Jan 2025 09:20:39 +0100 Subject: [PATCH 1/3] Add a date/time input --- scripts/tests.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 scripts/tests.py diff --git a/scripts/tests.py b/scripts/tests.py new file mode 100644 index 00000000..0a5a4905 --- /dev/null +++ b/scripts/tests.py @@ -0,0 +1,25 @@ +import questionary + +questionary.date( + "Which date do you want?", + format="%Y-%m-%d", +).ask() +questionary.text("What's your first name").ask() +questionary.password("What's your secret?").ask() +questionary.confirm("Are you amazed?").ask() + +questionary.select( + "What do you want to do?", + choices=["Order a pizza", "Make a reservation", "Ask for opening hours"], +).ask() + +questionary.rawselect( + "What do you want to do?", + choices=["Order a pizza", "Make a reservation", "Ask for opening hours"], +).ask() + +questionary.checkbox( + "Select toppings", choices=["foo", "bar", "bazz"] +).ask() + +questionary.path("Path to the projects version file").ask() \ No newline at end of file From 0a6402bd6eb97982cdf578897a7cf680080633da Mon Sep 17 00:00:00 2001 From: Rafik Lekouara Date: Mon, 27 Jan 2025 09:21:07 +0100 Subject: [PATCH 2/3] Add a date/time input --- questionary/__init__.py | 2 + questionary/prompts/__init__.py | 2 + questionary/prompts/date.py | 98 +++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 questionary/prompts/date.py diff --git a/questionary/__init__.py b/questionary/__init__.py index 8d9ddedc..60b434bf 100644 --- a/questionary/__init__.py +++ b/questionary/__init__.py @@ -23,6 +23,7 @@ from questionary.prompts.rawselect import rawselect from questionary.prompts.select import select from questionary.prompts.text import text +from questionary.prompts.date import date from questionary.question import Question __version__ = questionary.version.__version__ @@ -39,6 +40,7 @@ "rawselect", "select", "text", + "date", # utility methods "print", "form", diff --git a/questionary/prompts/__init__.py b/questionary/prompts/__init__.py index d728e985..09bcea12 100644 --- a/questionary/prompts/__init__.py +++ b/questionary/prompts/__init__.py @@ -7,11 +7,13 @@ from questionary.prompts import rawselect from questionary.prompts import select from questionary.prompts import text +from questionary.prompts import date AVAILABLE_PROMPTS = { "autocomplete": autocomplete.autocomplete, "confirm": confirm.confirm, "text": text.text, + "date": date.date, "select": select.select, "rawselect": rawselect.rawselect, "password": password.password, diff --git a/questionary/prompts/date.py b/questionary/prompts/date.py new file mode 100644 index 00000000..4c3296d0 --- /dev/null +++ b/questionary/prompts/date.py @@ -0,0 +1,98 @@ +from typing import Any, Optional +from datetime import datetime + +from questionary import Style +from questionary.constants import DEFAULT_QUESTION_PREFIX +from questionary.prompts import text +from questionary.question import Question + + +def date( + message: str, + default: Optional[str] = None, + validate: Any = None, + qmark: str = DEFAULT_QUESTION_PREFIX, + style: Optional[Style] = None, + format: str = "%Y-%m-%d", + min_date: Optional[str] = None, + max_date: Optional[str] = None, + **kwargs: Any, +) -> Question: + """ + Prompt the user to enter a date. + + This question type can be used to prompt the user for a date input, + with optional validation, formatting, and range restrictions. + + Example: + >>> import questionary + >>> questionary.date("Enter your birthdate (YYYY-MM-DD):").ask() + ? Enter your birthdate (YYYY-MM-DD): 1990-01-01 + '1990-01-01' + + Args: + message: Question text. + + default: Default date value in the given format. Defaults to None. + + validate: Custom validation function for the date input. + This can either be a function accepting the input and + returning a boolean, or a class reference to a + subclass of the prompt toolkit Validator class. + + qmark: Question prefix displayed in front of the question. + By default this is a ``?``. + + style: A custom color and style for the question parts. You can + configure colors as well as font types for different elements. + + format: The expected date format (e.g., "%Y-%m-%d"). Defaults to "%Y-%m-%d". + + min_date: The minimum allowed date in the given format. Defaults to None. + + max_date: The maximum allowed date in the given format. Defaults to None. + + kwargs: Additional arguments, they will be passed to prompt toolkit. + + Returns: + :class:`Question`: Question instance, ready to be prompted (using ``.ask()``). + """ + + def date_validator(input_date: str) -> bool: + """Validate the entered date based on format and range.""" + try: + parsed_date = datetime.strptime(input_date, format) + + # Validate minimum date + if min_date: + min_date_obj = datetime.strptime(min_date, format) + if parsed_date < min_date_obj: + raise ValueError( + f"Date must not be earlier than {min_date}." + ) + + # Validate maximum date + if max_date: + max_date_obj = datetime.strptime(max_date, format) + if parsed_date > max_date_obj: + raise ValueError( + f"Date must not be later than {max_date}." + ) + + return True + except ValueError as e: + raise ValueError(str(e)) + + # Use the provided validator or the built-in date_validator + final_validator = validate or date_validator + + return text.text( + message=message, + default=default, + validate=final_validator, + qmark=qmark, + style=style, + **kwargs, + ) + + From 06360245936d670592a0dbbde984fa49cfe5ffaf Mon Sep 17 00:00:00 2001 From: Rafik Lekouara Date: Mon, 27 Jan 2025 14:55:19 +0100 Subject: [PATCH 3/3] Add date/time input test for default value --- tests/prompts/test_date.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/prompts/test_date.py diff --git a/tests/prompts/test_date.py b/tests/prompts/test_date.py new file mode 100644 index 00000000..ba4bb504 --- /dev/null +++ b/tests/prompts/test_date.py @@ -0,0 +1,17 @@ +import pytest +from prompt_toolkit.input.defaults import create_pipe_input +from prompt_toolkit.output import DummyOutput +from questionary.prompts.date import date + + +def test_date_prompt_with_default(): + """Test de saisie avec une valeur par défaut.""" + with create_pipe_input() as pipe_input: + pipe_input.send_text("\n") # L'utilisateur appuie simplement sur Entrée + result = date( + "Enter a date (default is 2023-01-01):", + default="2023-01-01", # Définit une valeur par défaut valide + input=pipe_input, + output=DummyOutput() + ).ask() + assert result == "2023-01-01" \ No newline at end of file