From 681a9c7e6498f19c0d9bc74fd478c7b610fa74b1 Mon Sep 17 00:00:00 2001 From: Grant Ramsay Date: Tue, 25 Jul 2023 21:09:30 +0100 Subject: [PATCH] subclass the Rich prompt locally this means we dont need to import from my repo fork of Rich, so the app should now be able to be uploaded to PyPi Signed-off-by: Grant Ramsay --- poetry.lock | 16 +++++------ py_maker/prompt.py | 65 +++++++++++++++++++++++++++++++++++++++++++++ py_maker/pymaker.py | 3 +-- pyproject.toml | 2 +- 4 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 py_maker/prompt.py diff --git a/poetry.lock b/poetry.lock index c63a6ce0..e547df89 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1285,22 +1285,18 @@ version = "13.4.2" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" -files = [] -develop = false +files = [ + {file = "rich-13.4.2-py3-none-any.whl", hash = "sha256:8f87bc7ee54675732fa66a05ebfe489e27264caeeff3728c945d25971b6485ec"}, + {file = "rich-13.4.2.tar.gz", hash = "sha256:d653d6bccede5844304c605d5aac802c7cf9621efd700b46c7ec2b51ea914898"}, +] [package.dependencies] markdown-it-py = ">=2.2.0" -pygments = "^2.13.0" +pygments = ">=2.13.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] -[package.source] -type = "git" -url = "https://github.com/seapagan/rich.git" -reference = "case-insensitive-prompt-choices" -resolved_reference = "10705a43b26ecf0eb9c7ed3a687bc797b3e1b4d5" - [[package]] name = "setuptools" version = "68.0.0" @@ -1596,4 +1592,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = ">=3.9,<4.0" -content-hash = "d72ab5271aaf28ee9f8b1a28b9368c9829957f91b1418170259258bbae833ea9" +content-hash = "52358e72de74d186b5b3ee74f02760f5e059e07dea419770e68a84d896f39f4e" diff --git a/py_maker/prompt.py b/py_maker/prompt.py new file mode 100644 index 00000000..635d8900 --- /dev/null +++ b/py_maker/prompt.py @@ -0,0 +1,65 @@ +"""Subclass the Prompt class from Rich to add a few features. + +Currently only makes the choices case-insensitive. +""" +from rich.prompt import Confirm as RichConfirm +from rich.prompt import InvalidResponse +from rich.prompt import Prompt as RichPrompt +from rich.prompt import PromptType + + +class Confirm(RichConfirm): + """Just so we can import it from the same place as IPrompt. + + Saves importing from the Rich library. + """ + + +class Prompt(RichPrompt): + """Override the Prompt class to make choices case-insensitive.""" + + def check_choice(self, value: str) -> bool: + """Check value is in the list of valid choices. + + Args: + value (str): Value entered by user. + + Returns: + bool: True if choice was valid, otherwise False. + """ + assert self.choices is not None # nosec + return value.strip().lower() in [ + choice.lower() for choice in self.choices + ] + + def process_response(self, value: str) -> PromptType: # type: ignore + """Process response from user, convert to prompt type. + + Args: + value (str): String typed by user. + + Raises: + InvalidResponse: If ``value`` is invalid. + + Returns: + PromptType: The value to be returned from ask method. + """ + value = value.strip() + try: + return_value: PromptType = self.response_type(value) # type: ignore + except ValueError as exc: + raise InvalidResponse(self.validate_error_message) from exc + + if self.choices is not None: + if not self.check_choice(value): + raise InvalidResponse(self.illegal_choice_message) + + # return the original choice, not the lower case version + return_value = self.response_type( # type: ignore + self.choices[ + [choice.lower() for choice in self.choices].index( + value.lower() + ) + ] + ) + return return_value diff --git a/py_maker/pymaker.py b/py_maker/pymaker.py index ab82aae3..d0dc105e 100644 --- a/py_maker/pymaker.py +++ b/py_maker/pymaker.py @@ -14,10 +14,10 @@ from git.repo import Repo from jinja2 import Environment, FileSystemLoader from rich import print # pylint: disable=W0622 -from rich.prompt import Confirm, Prompt from py_maker import template from py_maker.constants import ExitErrors, license_names +from py_maker.prompt import Confirm, Prompt from py_maker.schema import ProjectValues @@ -277,7 +277,6 @@ def run(self) -> None: "Application License?", choices=license_names, default="MIT", - case_insensitive=True, ) if not self.confirm_values(): diff --git a/pyproject.toml b/pyproject.toml index 155cf6e0..908cf3c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,11 +18,11 @@ pymaker = "py_maker.main:app" [tool.poetry.dependencies] python = ">=3.9,<4.0" typer = {extras = ["all"], version = "^0.9.0"} -rich = {git = "https://github.com/seapagan/rich.git", rev = "case-insensitive-prompt-choices"} jinja2 = "^3.1.2" gitpython = "^3.1.32" tomli = "^2.0.1" pydantic = "^2.0" +rich = "^13.4.2" [build-system] requires = ["poetry-core"]