diff --git a/APIDOC.md b/APIDOC.md index 1e8b85e..57e4acf 100644 --- a/APIDOC.md +++ b/APIDOC.md @@ -51,7 +51,7 @@ Creates a spinner which can be used to provide some user feedback during long pr - `refresh_per_second` _float, optional_ - Number of refreshes the spinner will do a second, this will affect the fluidity of the "animation". Defaults to 10. - `transient` _bool, optional_ - If the spinner will disappear after it's done, otherwise not. Defaults to True. - + **Raises**: @@ -146,14 +146,14 @@ Function that prompts the user for written input the error will be reported onto the console. Defaults to True. - `raise_type_conversion_fail` _bool, optional_ - If True, invalid inputs will raise `rich.internals.ConversionError`, else the error will be reported onto the console. Defaults to True. - + **Raises**: - `ValidationError` - Raised if validation with provided validator fails - `ConversionError` - Raised if the value cannot be converted to provided type - `KeyboardInterrupt` - Raised when keyboard interrupt is encountered and Config.raise_on_interrupt is True - + **Returns**: @@ -188,13 +188,13 @@ A prompt that allows selecting one option from a list of options - `return_index` _bool, optional_ - If `True`, `select` will return the index of selected element in options. Defaults to `False`. - `strict` _bool, optional_ - If empty `options` is provided and strict is `False`, None will be returned, if it's `True`, `ValueError` will be thrown. Defaults to False. - + **Raises**: -- `ValueError` - Thrown if no `options` are povided and strict is `True` +- `ValueError` - Thrown if no `options` are provided and strict is `True` - `KeyboardInterrupt` - Raised when keyboard interrupt is encountered and Config.raise_on_interrupt is True - + **Returns**: @@ -238,12 +238,12 @@ A prompt that allows selecting multiple options from a list of options of ticked elements in options. Defaults to `False`. - `strict` _bool, optional_ - If empty `options` is provided and strict is `False`, None will be returned, if it's `True`, `ValueError` will be thrown. Defaults to False. - + **Raises**: - `KeyboardInterrupt` - Raised when keyboard interrupt is encountered and Config.raise_on_interrupt is True - + **Returns**: @@ -278,14 +278,13 @@ A prompt that asks a question and offers two responses - `cursor` _str, optional_ - What character(s) to use as a cursor. Defaults to '> '. - `cursor_style` _str, optional_ - Rich friendly style for the cursor. Defaults to 'pink1'. - `char_prompt` _bool, optional_ - Print [Y/n] after the question. Defaults to True. - + **Raises**: - `KeyboardInterrupt` - Raised when keyboard interrupt is encountered and Config.raise_on_interrupt is True - + **Returns**: Optional[bool] - diff --git a/README.md b/README.md index b7e2660..a963e43 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,8 @@ if confirm("Will you take the ring to Mordor?"): # Choose one item from a list name = select(names, cursor="💧", cursor_style="cyan") console.print(f"AlΓ‘menΓ«, {name}") - - + + item_options = [ "The One Ring", "Dagger", @@ -66,44 +66,44 @@ if confirm("Will you take the ring to Mordor?"): console.print("What do you bring with you?") # Choose multiple options from a list items = select_multiple(item_options, tick_character='πŸŽ’', ticked_indices=[0], maximal_count=3) - + potato_count = 0 if "Po-tae-toes" in items: # Prompt with type conversion and validation potato_count = prompt('How many potatoes?', target_type=int, validator=lambda count: count > 0) - + # Spinner to show while doing some work spinner = Spinner(DOTS, "Packing things...") spinner.start() - + time.sleep(2) - + spinner.stop() # Get input without showing it being typed if "friend" == prompt("Speak, [blue bold underline]friend[/blue bold underline], and enter", secure=True).lower(): - + # Custom spinner animation spinner_animation = ['β–‰β–‰', 'β–Œβ–', ' ', 'β–Œβ–', 'β–‰β–‰'] spinner = Spinner(spinner_animation, "Opening the Door of Durin...") spinner.start() - + time.sleep(2) - + spinner.stop() else: spinner_animation = ['πŸ™πŸŒŠ βš”οΈ ', 'πŸ™ 🌊 βš”οΈ ', 'πŸ™ 🌊 βš”οΈ ', 'πŸ™ 🌊 βš”οΈ ', 'πŸ™ πŸŒŠβš”οΈ '] spinner = Spinner(spinner_animation, "Getting attacked by an octopus...") spinner.start() - + time.sleep(2) - + spinner.stop() if 'The One Ring' in items: console.print("[green]You throw The One Ring to a lava from an eagle![/green]") else: console.print("[red]You forgot the ring and brought Middle-Earth to its knees![/red]") - console.print(f"And you brought {potato_count} taters!") + console.print(f"And you brought {potato_count} taters!") ``` For more information refer to [more examples](https://petereon.github.io/beaupy/examples/) or definitive, but much less exciting [API documentation](https://petereon.github.io/beaupy/api/) diff --git a/beaupy/_beaupy.py b/beaupy/_beaupy.py index 7c1f888..50e259f 100755 --- a/beaupy/_beaupy.py +++ b/beaupy/_beaupy.py @@ -206,7 +206,7 @@ def prompt( renderer=renderer, ) - with element.diplayed(): + with element.displayed(): while True: key = get_key() new_state = element.state @@ -270,7 +270,7 @@ def select( page_size (int, optional): Number of options to show on a single page if pagination is enabled. Defaults to 5. Raises: - ValueError: Thrown if no `options` are povided and strict is `True` + ValueError: Thrown if no `options` are provided and strict is `True` KeyboardInterrupt: Raised when keyboard interrupt is encountered and Config.raise_on_interrupt is True Returns: @@ -298,7 +298,7 @@ def select( renderer=renderer, ) - with element.diplayed(): + with element.displayed(): while True: keypress = get_key() @@ -391,7 +391,7 @@ def select_multiple( renderer=renderer, ) - with element.diplayed(): + with element.displayed(): while True: keypress = get_key() new_state = element.state diff --git a/docs/content/examples.md b/docs/content/examples.md index 185e8e8..0181365 100644 --- a/docs/content/examples.md +++ b/docs/content/examples.md @@ -9,7 +9,7 @@ Selective elements default to return the selected item (in case of `select`) or list of items (in case of `select_multiple`). This behavior can be modified by `return_index` parameter (or `return_indices` in case of the latter), see example, ```python -result_index = select(options=['I\'ll be returned as 0', 'I\'ll be returned as 1'], +result_index = select(options=['I\'ll be returned as 0', 'I\'ll be returned as 1'], return_index=True) ``` @@ -49,15 +49,15 @@ pizza_toppings = select_multiple(['pineapple', 'olives', 'anchovies', 'mozzarell #### Style as text ```python -stylish = select(options = ["red", "on", "white"], - cursor = "x", +stylish = select(options = ["red", "on", "white"], + cursor = "x", cursor_style= "red on white") ``` #### Style as hex ```python -selections = select_multiple(options = ["s", "h", "e", "", "b", "e", "l", "i", "e", "v", "e", "d"], +selections = select_multiple(options = ["s", "h", "e", "", "b", "e", "l", "i", "e", "v", "e", "d"], tick_style="#af00ff", ticked_indices=[1,2,6,7,8,11]) ``` @@ -70,14 +70,14 @@ selections = select_multiple(options = ["s", "h", "e", "", "b", "e", "l", "i", " Some emojis can appear as one character instead of two! ```python -result = select(options = ["here", "comes", "the", "sun"], +result = select(options = ["here", "comes", "the", "sun"], cursor = "🌞") ``` #### Non-ascii as a cursor ```python -result = select(options = ["hardcore", "unicode"], +result = select(options = ["hardcore", "unicode"], cursor = "⇉") ``` @@ -87,7 +87,7 @@ result = select(options = ["hardcore", "unicode"], You can use multiple characters as a cursor ```python -correct_abba_lyric = select_multiple(options = ["queen", "bean"], +correct_abba_lyric = select_multiple(options = ["queen", "bean"], tick_character = "dancing") ``` @@ -149,7 +149,7 @@ from os import listdir from pathlib import Path # ugly hacky path completion callable: -def path_completion(str_path: str = ""): +def path_completion(str_path: str = ""): if not str_path: return [] try: @@ -214,4 +214,4 @@ Animation speed can be set using `refresh_per_second` parameter: from beaupy.spinners import Spinner, LOADING spinner = Spinner(LOADING, "something", refresh_per_second=4) spinner.start() -``` \ No newline at end of file +``` diff --git a/poetry.lock b/poetry.lock index 8bfc03d..e38eb77 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "astor" @@ -127,13 +127,13 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2023.7.22" +version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, + {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, + {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, ] [[package]] @@ -766,13 +766,13 @@ test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre [[package]] name = "idna" -version = "3.4" +version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] [[package]] @@ -1221,17 +1221,18 @@ files = [ [[package]] name = "pygments" -version = "2.16.1" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, - {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, ] [package.extras] plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pylint" @@ -1349,13 +1350,13 @@ files = [ [[package]] name = "questo" -version = "0.1.2" +version = "0.2.0" description = "A library of extensible and modular CLI prompt elements" optional = false python-versions = ">=3.7.8,<4.0.0" files = [ - {file = "questo-0.1.2-py3-none-any.whl", hash = "sha256:0f40961dfaeeb722001a6e8c81af2973d3d9e3c1c1f67d7f04abb4c34b8f0ecf"}, - {file = "questo-0.1.2.tar.gz", hash = "sha256:cfd0d53bd950b0659059646f36feca7a96f2301575d31630a99bac6d2f99579b"}, + {file = "questo-0.2.0-py3-none-any.whl", hash = "sha256:f453ca311e546fba508f57275ca9d6ed5d0908e21e9d7b5cfe1ee95c4809c298"}, + {file = "questo-0.2.0.tar.gz", hash = "sha256:1d47272559c6de73852628ed96efc991ec55f06d9948721e3f15b2c94214e4d2"}, ] [package.dependencies] @@ -1522,13 +1523,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.12.2" +version = "0.12.3" description = "Style preserving TOML library" optional = false python-versions = ">=3.7" files = [ - {file = "tomlkit-0.12.2-py3-none-any.whl", hash = "sha256:eeea7ac7563faeab0a1ed8fe12c2e5a51c61f933f2502f7e9db0241a65163ad0"}, - {file = "tomlkit-0.12.2.tar.gz", hash = "sha256:df32fab589a81f0d7dc525a4267b6d7a64ee99619cbd1eeb0fae32c1dd426977"}, + {file = "tomlkit-0.12.3-py3-none-any.whl", hash = "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba"}, + {file = "tomlkit-0.12.3.tar.gz", hash = "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4"}, ] [[package]] @@ -1843,4 +1844,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.7.8" -content-hash = "eb4816bb3b1608445022a976c72f809cae066ad3aa6218f51835a2b84b23812b" +content-hash = "10c6b551610b1793e4cdf4be98ed089428256cbccd7575aaa770d2a265538eb6" diff --git a/pyproject.toml b/pyproject.toml index 562c0a8..6c3e47b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = 'beaupy' -version = '3.7.0' +version = '3.7.1' description = 'A library of elements for interactive TUIs in Python' authors = ['Peter Vyboch '] license = 'MIT' @@ -42,7 +42,7 @@ python = '^3.7.8' rich = "^12.2.0" emoji = "^2.0.0" python-yakh = "0.3.2" -questo = "^0.1.2" +questo = "^0.2.0" [tool.mypy] diff --git a/test/beaupy_internals_test.py b/test/beaupy_internals_test.py index 9f3ec2d..6ebd3d9 100644 --- a/test/beaupy_internals_test.py +++ b/test/beaupy_internals_test.py @@ -13,7 +13,7 @@ def _(): @test("Test that prompt is rendered with error") def _(): - + result = _render_prompt(False, qprompt.PromptState(value='ab', title='Test prompt', error='Test Error', cursor_position=1)) assert ( result == "Test prompt\n> a[black on white]b[/black on white] \n\n(Confirm with [bold]enter[/bold])\n[red]Error:[/red] Test Error" diff --git a/test/beaupy_select_test.py b/test/beaupy_select_test.py index 7e8b502..1e43d42 100644 --- a/test/beaupy_select_test.py +++ b/test/beaupy_select_test.py @@ -6,7 +6,6 @@ from beaupy._internals import Abort from beaupy._beaupy import Config, Live, select, warnings -import beaupy def raise_keyboard_interrupt(): @@ -24,7 +23,7 @@ def set_raise_on_escape(): def _(): b.get_key = lambda: Keys.ENTER res = select(options=[]) - assert res == None + assert res is None @test("`select` with no options strict") @@ -220,7 +219,7 @@ def _(): mock.call(renderable=" test1\n[green]x[/green] test2\n test3\n test4\n\n(Confirm with [bold]enter[/bold])") ] assert Live.update.call_count == 1 - assert res == None + assert res is None @test( @@ -312,7 +311,7 @@ def _(): mock.call(renderable=" test1\n[green]x[/green] test2\n test3\n test4\n\n(Confirm with [bold]enter[/bold])"), ] assert Live.update.call_count == 1 - assert res == None + assert res is None @test("`select` raises Abort when ESC is pressed and raise_on_escape is True")