From 6dc655898df34ad424dfc467a8b276fdf31bd791 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 5 Jun 2024 06:45:15 +0200 Subject: Merging upstream version 3.0.46. Signed-off-by: Daniel Baumann --- src/prompt_toolkit/__init__.py | 3 +- src/prompt_toolkit/application/application.py | 3 +- src/prompt_toolkit/application/current.py | 12 +++-- src/prompt_toolkit/application/run_in_terminal.py | 1 + src/prompt_toolkit/auto_suggest.py | 3 +- src/prompt_toolkit/buffer.py | 29 ++++++------ src/prompt_toolkit/clipboard/base.py | 1 + src/prompt_toolkit/completion/base.py | 23 +++------- src/prompt_toolkit/completion/nested.py | 1 + .../contrib/regular_languages/__init__.py | 1 + .../contrib/regular_languages/compiler.py | 15 ++++--- .../contrib/regular_languages/completion.py | 24 ++++++---- .../contrib/regular_languages/lexer.py | 1 + .../contrib/regular_languages/regex_parser.py | 9 ++-- .../contrib/regular_languages/validation.py | 1 + src/prompt_toolkit/contrib/ssh/server.py | 1 + src/prompt_toolkit/contrib/telnet/log.py | 1 + src/prompt_toolkit/contrib/telnet/protocol.py | 1 + src/prompt_toolkit/contrib/telnet/server.py | 5 ++- src/prompt_toolkit/document.py | 1 + src/prompt_toolkit/eventloop/async_generator.py | 1 + src/prompt_toolkit/eventloop/inputhook.py | 1 + src/prompt_toolkit/filters/__init__.py | 1 + src/prompt_toolkit/filters/app.py | 1 + src/prompt_toolkit/filters/base.py | 14 ++++-- src/prompt_toolkit/filters/cli.py | 1 + src/prompt_toolkit/filters/utils.py | 2 +- src/prompt_toolkit/formatted_text/__init__.py | 1 + src/prompt_toolkit/formatted_text/ansi.py | 6 +-- src/prompt_toolkit/formatted_text/base.py | 5 +-- src/prompt_toolkit/formatted_text/utils.py | 1 + src/prompt_toolkit/history.py | 12 +++-- src/prompt_toolkit/input/ansi_escape_sequences.py | 1 + src/prompt_toolkit/input/base.py | 3 +- src/prompt_toolkit/input/typeahead.py | 1 + src/prompt_toolkit/input/vt100_parser.py | 1 + src/prompt_toolkit/input/win32.py | 4 +- .../key_binding/bindings/auto_suggest.py | 1 + src/prompt_toolkit/key_binding/bindings/basic.py | 18 ++++---- .../key_binding/bindings/completion.py | 1 + src/prompt_toolkit/key_binding/bindings/emacs.py | 16 ++++--- .../key_binding/bindings/named_commands.py | 3 +- .../key_binding/bindings/open_in_editor.py | 1 + .../key_binding/bindings/page_navigation.py | 1 + src/prompt_toolkit/key_binding/bindings/scroll.py | 1 + src/prompt_toolkit/key_binding/bindings/search.py | 1 + src/prompt_toolkit/key_binding/bindings/vi.py | 51 +++++++++++++--------- src/prompt_toolkit/key_binding/defaults.py | 1 + src/prompt_toolkit/key_binding/digraphs.py | 1 + src/prompt_toolkit/key_binding/key_bindings.py | 13 +++--- src/prompt_toolkit/key_binding/key_processor.py | 7 +-- src/prompt_toolkit/layout/__init__.py | 1 + src/prompt_toolkit/layout/containers.py | 33 ++++++-------- src/prompt_toolkit/layout/controls.py | 1 + src/prompt_toolkit/layout/dimension.py | 11 ++--- src/prompt_toolkit/layout/dummy.py | 1 + src/prompt_toolkit/layout/layout.py | 1 + src/prompt_toolkit/layout/margins.py | 3 +- src/prompt_toolkit/layout/menus.py | 5 +-- src/prompt_toolkit/layout/mouse_handlers.py | 6 +-- src/prompt_toolkit/layout/processors.py | 13 +++--- src/prompt_toolkit/layout/screen.py | 8 +--- src/prompt_toolkit/layout/utils.py | 6 +-- src/prompt_toolkit/lexers/__init__.py | 1 + src/prompt_toolkit/lexers/base.py | 1 + src/prompt_toolkit/lexers/pygments.py | 1 + src/prompt_toolkit/log.py | 1 + src/prompt_toolkit/mouse_events.py | 8 +--- src/prompt_toolkit/output/base.py | 1 + src/prompt_toolkit/output/vt100.py | 3 +- src/prompt_toolkit/output/win32.py | 12 ++--- src/prompt_toolkit/patch_stdout.py | 1 + src/prompt_toolkit/renderer.py | 1 + src/prompt_toolkit/search.py | 8 +--- src/prompt_toolkit/selection.py | 7 +-- src/prompt_toolkit/shortcuts/progress_bar/base.py | 1 + .../shortcuts/progress_bar/formatters.py | 34 ++++++++------- src/prompt_toolkit/shortcuts/prompt.py | 1 + src/prompt_toolkit/styles/__init__.py | 1 + src/prompt_toolkit/styles/base.py | 1 + src/prompt_toolkit/styles/defaults.py | 1 + src/prompt_toolkit/styles/named_colors.py | 1 + src/prompt_toolkit/styles/pygments.py | 1 + src/prompt_toolkit/styles/style.py | 3 +- src/prompt_toolkit/styles/style_transformation.py | 1 + src/prompt_toolkit/token.py | 3 +- src/prompt_toolkit/validation.py | 7 +-- src/prompt_toolkit/widgets/__init__.py | 1 + src/prompt_toolkit/widgets/base.py | 1 + src/prompt_toolkit/widgets/dialogs.py | 1 + src/prompt_toolkit/widgets/toolbars.py | 6 +-- 91 files changed, 275 insertions(+), 231 deletions(-) (limited to 'src') diff --git a/src/prompt_toolkit/__init__.py b/src/prompt_toolkit/__init__.py index 82324cb..9f194f1 100644 --- a/src/prompt_toolkit/__init__.py +++ b/src/prompt_toolkit/__init__.py @@ -13,6 +13,7 @@ See the examples directory to learn about the usage. Probably, to get started, you might also want to have a look at `prompt_toolkit.shortcuts.prompt`. """ + from __future__ import annotations import re @@ -27,7 +28,7 @@ from .formatted_text import ANSI, HTML from .shortcuts import PromptSession, print_formatted_text, prompt # Don't forget to update in `docs/conf.py`! -__version__ = "3.0.43" +__version__ = "3.0.46" assert pep440.match(__version__) diff --git a/src/prompt_toolkit/application/application.py b/src/prompt_toolkit/application/application.py index d463781..d93c243 100644 --- a/src/prompt_toolkit/application/application.py +++ b/src/prompt_toolkit/application/application.py @@ -1621,5 +1621,6 @@ def _restore_sigint_from_ctypes() -> Generator[None, None, None]: try: yield finally: - signal.signal(signal.SIGINT, sigint) + if sigint is not None: + signal.signal(signal.SIGINT, sigint) pythonapi.PyOS_setsig(signal.SIGINT, sigint_os) diff --git a/src/prompt_toolkit/application/current.py b/src/prompt_toolkit/application/current.py index 908141a..7e2cf48 100644 --- a/src/prompt_toolkit/application/current.py +++ b/src/prompt_toolkit/application/current.py @@ -147,11 +147,17 @@ def create_app_session( Like in the case of an Telnet/SSH server. """ # If no input/output is specified, fall back to the current input/output, - # whatever that is. + # if there was one that was set/created for the current session. + # (Note that we check `_input`/`_output` and not `input`/`output`. This is + # because we don't want to accidently create a new input/output objects + # here and store it in the "parent" `AppSession`. Especially, when + # combining pytest's `capsys` fixture and `create_app_session`, sys.stdin + # and sys.stderr are patched for every test, so we don't want to leak + # those outputs object across `AppSession`s.) if input is None: - input = get_app_session().input + input = get_app_session()._input if output is None: - output = get_app_session().output + output = get_app_session()._output # Create new `AppSession` and activate. session = AppSession(input=input, output=output) diff --git a/src/prompt_toolkit/application/run_in_terminal.py b/src/prompt_toolkit/application/run_in_terminal.py index 1e4da2d..18a3dad 100644 --- a/src/prompt_toolkit/application/run_in_terminal.py +++ b/src/prompt_toolkit/application/run_in_terminal.py @@ -1,6 +1,7 @@ """ Tools for running functions on the terminal above the current application or prompt. """ + from __future__ import annotations from asyncio import Future, ensure_future diff --git a/src/prompt_toolkit/auto_suggest.py b/src/prompt_toolkit/auto_suggest.py index 98cb4dd..73213ba 100644 --- a/src/prompt_toolkit/auto_suggest.py +++ b/src/prompt_toolkit/auto_suggest.py @@ -11,6 +11,7 @@ because they take too much time, and could potentially block the event loop, then wrap the :class:`.AutoSuggest` instance into a :class:`.ThreadedAutoSuggest`. """ + from __future__ import annotations from abc import ABCMeta, abstractmethod @@ -46,7 +47,7 @@ class Suggestion: self.text = text def __repr__(self) -> str: - return "Suggestion(%s)" % self.text + return f"Suggestion({self.text})" class AutoSuggest(metaclass=ABCMeta): diff --git a/src/prompt_toolkit/buffer.py b/src/prompt_toolkit/buffer.py index 100ca78..f5847d4 100644 --- a/src/prompt_toolkit/buffer.py +++ b/src/prompt_toolkit/buffer.py @@ -2,6 +2,7 @@ Data structures for the Buffer. It holds the text, cursor position, history, etc... """ + from __future__ import annotations import asyncio @@ -85,12 +86,7 @@ class CompletionState: self.complete_index = complete_index # Position in the `_completions` array. def __repr__(self) -> str: - return "{}({!r}, <{!r}> completions, index={!r})".format( - self.__class__.__name__, - self.original_document, - len(self.completions), - self.complete_index, - ) + return f"{self.__class__.__name__}({self.original_document!r}, <{len(self.completions)!r}> completions, index={self.complete_index!r})" def go_to_index(self, index: int | None) -> None: """ @@ -149,12 +145,7 @@ class YankNthArgState: self.n = n def __repr__(self) -> str: - return "{}(history_position={!r}, n={!r}, previous_inserted_word={!r})".format( - self.__class__.__name__, - self.history_position, - self.n, - self.previous_inserted_word, - ) + return f"{self.__class__.__name__}(history_position={self.history_position!r}, n={self.n!r}, previous_inserted_word={self.previous_inserted_word!r})" BufferEventHandler = Callable[["Buffer"], None] @@ -188,6 +179,9 @@ class Buffer: In case of a `PromptSession` for instance, we want to keep the text, because we will exit the application, and only reset it during the next run. + :param max_number_of_completions: Never display more than this number of + completions, even when the completer can produce more (limited by + default to 10k for performance). Events: @@ -234,12 +228,13 @@ class Buffer: accept_handler: BufferAcceptHandler | None = None, read_only: FilterOrBool = False, multiline: FilterOrBool = True, + max_number_of_completions: int = 10000, on_text_changed: BufferEventHandler | None = None, on_text_insert: BufferEventHandler | None = None, on_cursor_position_changed: BufferEventHandler | None = None, on_completions_changed: BufferEventHandler | None = None, on_suggestion_set: BufferEventHandler | None = None, - ): + ) -> None: # Accept both filters and booleans as input. enable_history_search = to_filter(enable_history_search) complete_while_typing = to_filter(complete_while_typing) @@ -261,6 +256,7 @@ class Buffer: self.enable_history_search = enable_history_search self.read_only = read_only self.multiline = multiline + self.max_number_of_completions = max_number_of_completions # Text width. (For wrapping, used by the Vi 'gq' operator.) self.text_width = 0 @@ -1748,6 +1744,13 @@ class Buffer: # If the input text changes, abort. if not proceed(): break + + # Always stop at 10k completions. + if ( + len(complete_state.completions) + >= self.max_number_of_completions + ): + break finally: refresh_task.cancel() diff --git a/src/prompt_toolkit/clipboard/base.py b/src/prompt_toolkit/clipboard/base.py index b05275b..28cfdcd 100644 --- a/src/prompt_toolkit/clipboard/base.py +++ b/src/prompt_toolkit/clipboard/base.py @@ -1,6 +1,7 @@ """ Clipboard for command line interface. """ + from __future__ import annotations from abc import ABCMeta, abstractmethod diff --git a/src/prompt_toolkit/completion/base.py b/src/prompt_toolkit/completion/base.py index 04a712d..3846ef7 100644 --- a/src/prompt_toolkit/completion/base.py +++ b/src/prompt_toolkit/completion/base.py @@ -1,5 +1,5 @@ -""" -""" +""" """ + from __future__ import annotations from abc import ABCMeta, abstractmethod @@ -66,18 +66,9 @@ class Completion: def __repr__(self) -> str: if isinstance(self.display, str) and self.display == self.text: - return "{}(text={!r}, start_position={!r})".format( - self.__class__.__name__, - self.text, - self.start_position, - ) + return f"{self.__class__.__name__}(text={self.text!r}, start_position={self.start_position!r})" else: - return "{}(text={!r}, start_position={!r}, display={!r})".format( - self.__class__.__name__, - self.text, - self.start_position, - self.display, - ) + return f"{self.__class__.__name__}(text={self.text!r}, start_position={self.start_position!r}, display={self.display!r})" def __eq__(self, other: object) -> bool: if not isinstance(other, Completion): @@ -156,11 +147,7 @@ class CompleteEvent: self.completion_requested = completion_requested def __repr__(self) -> str: - return "{}(text_inserted={!r}, completion_requested={!r})".format( - self.__class__.__name__, - self.text_inserted, - self.completion_requested, - ) + return f"{self.__class__.__name__}(text_inserted={self.text_inserted!r}, completion_requested={self.completion_requested!r})" class Completer(metaclass=ABCMeta): diff --git a/src/prompt_toolkit/completion/nested.py b/src/prompt_toolkit/completion/nested.py index a1d211a..8569bd2 100644 --- a/src/prompt_toolkit/completion/nested.py +++ b/src/prompt_toolkit/completion/nested.py @@ -1,6 +1,7 @@ """ Nestedcompleter for completion of hierarchical data structures. """ + from __future__ import annotations from typing import Any, Iterable, Mapping, Set, Union diff --git a/src/prompt_toolkit/contrib/regular_languages/__init__.py b/src/prompt_toolkit/contrib/regular_languages/__init__.py index c947fd5..38b027c 100644 --- a/src/prompt_toolkit/contrib/regular_languages/__init__.py +++ b/src/prompt_toolkit/contrib/regular_languages/__init__.py @@ -72,6 +72,7 @@ TODO: some examples of: - How to create an autocompleter from this grammar. - How to create a parser from this grammar. """ + from __future__ import annotations from .compiler import compile diff --git a/src/prompt_toolkit/contrib/regular_languages/compiler.py b/src/prompt_toolkit/contrib/regular_languages/compiler.py index 474f6cf..dd558a6 100644 --- a/src/prompt_toolkit/contrib/regular_languages/compiler.py +++ b/src/prompt_toolkit/contrib/regular_languages/compiler.py @@ -38,6 +38,7 @@ Partial matches are possible:: m.variables().get('operator2') # Returns "add" """ + from __future__ import annotations import re @@ -96,13 +97,13 @@ class _CompiledGrammar: counter = [0] def create_group_func(node: Variable) -> str: - name = "n%s" % counter[0] + name = f"n{counter[0]}" self._group_names_to_nodes[name] = node.varname counter[0] += 1 return name # Compile regex strings. - self._re_pattern = "^%s$" % self._transform(root_node, create_group_func) + self._re_pattern = f"^{self._transform(root_node, create_group_func)}$" self._re_prefix_patterns = list( self._transform_prefix(root_node, create_group_func) ) @@ -153,7 +154,7 @@ class _CompiledGrammar: def transform(node: Node) -> str: # Turn `AnyNode` into an OR. if isinstance(node, AnyNode): - return "(?:%s)" % "|".join(transform(c) for c in node.children) + return "(?:{})".format("|".join(transform(c) for c in node.children)) # Concatenate a `NodeSequence` elif isinstance(node, NodeSequence): @@ -311,11 +312,11 @@ class _CompiledGrammar: yield "".join(result) elif isinstance(node, Regex): - yield "(?:%s)?" % node.regex + yield f"(?:{node.regex})?" elif isinstance(node, Lookahead): if node.negative: - yield "(?!%s)" % cls._transform(node.childnode, create_group_func) + yield f"(?!{cls._transform(node.childnode, create_group_func)})" else: # Not sure what the correct semantics are in this case. # (Probably it's not worth implementing this.) @@ -349,10 +350,10 @@ class _CompiledGrammar: ) else: - raise TypeError("Got %r" % node) + raise TypeError(f"Got {node!r}") for r in transform(root_node): - yield "^(?:%s)$" % r + yield f"^(?:{r})$" def match(self, string: str) -> Match | None: """ diff --git a/src/prompt_toolkit/contrib/regular_languages/completion.py b/src/prompt_toolkit/contrib/regular_languages/completion.py index 2e353e8..19ebaad 100644 --- a/src/prompt_toolkit/contrib/regular_languages/completion.py +++ b/src/prompt_toolkit/contrib/regular_languages/completion.py @@ -1,6 +1,7 @@ """ Completer for a regular grammar. """ + from __future__ import annotations from typing import Iterable @@ -37,12 +38,10 @@ class GrammarCompleter(Completer): m = self.compiled_grammar.match_prefix(document.text_before_cursor) if m: - completions = self._remove_duplicates( + yield from self._remove_duplicates( self._get_completions_for_match(m, complete_event) ) - yield from completions - def _get_completions_for_match( self, match: Match, complete_event: CompleteEvent ) -> Iterable[Completion]: @@ -81,14 +80,21 @@ class GrammarCompleter(Completer): display_meta=completion.display_meta, ) - def _remove_duplicates(self, items: Iterable[Completion]) -> list[Completion]: + def _remove_duplicates(self, items: Iterable[Completion]) -> Iterable[Completion]: """ Remove duplicates, while keeping the order. (Sometimes we have duplicates, because the there several matches of the same grammar, each yielding similar completions.) """ - result: list[Completion] = [] - for i in items: - if i not in result: - result.append(i) - return result + + def hash_completion(completion: Completion) -> tuple[str, int]: + return completion.text, completion.start_position + + yielded_so_far: set[tuple[str, int]] = set() + + for completion in items: + hash_value = hash_completion(completion) + + if hash_value not in yielded_so_far: + yielded_so_far.add(hash_value) + yield completion diff --git a/src/prompt_toolkit/contrib/regular_languages/lexer.py b/src/prompt_toolkit/contrib/regular_languages/lexer.py index b0a4deb..c5434cf 100644 --- a/src/prompt_toolkit/contrib/regular_languages/lexer.py +++ b/src/prompt_toolkit/contrib/regular_languages/lexer.py @@ -2,6 +2,7 @@ `GrammarLexer` is compatible with other lexers and can be used to highlight the input using a regular grammar with annotations. """ + from __future__ import annotations from typing import Callable diff --git a/src/prompt_toolkit/contrib/regular_languages/regex_parser.py b/src/prompt_toolkit/contrib/regular_languages/regex_parser.py index a365ba8..353e54f 100644 --- a/src/prompt_toolkit/contrib/regular_languages/regex_parser.py +++ b/src/prompt_toolkit/contrib/regular_languages/regex_parser.py @@ -14,6 +14,7 @@ Remarks: Limitations: - Lookahead is not supported. """ + from __future__ import annotations import re @@ -115,11 +116,7 @@ class Variable(Node): self.varname = varname def __repr__(self) -> str: - return "{}(childnode={!r}, varname={!r})".format( - self.__class__.__name__, - self.childnode, - self.varname, - ) + return f"{self.__class__.__name__}(childnode={self.childnode!r}, varname={self.varname!r})" class Repeat(Node): @@ -265,7 +262,7 @@ def parse_regex(regex_tokens: list[str]) -> Node: raise Exception(f"{t}-style repetition not yet supported") elif t.startswith("(?"): - raise Exception("%r not supported" % t) + raise Exception(f"{t!r} not supported") elif t.isspace(): pass diff --git a/src/prompt_toolkit/contrib/regular_languages/validation.py b/src/prompt_toolkit/contrib/regular_languages/validation.py index 8e56e05..e6cfd74 100644 --- a/src/prompt_toolkit/contrib/regular_languages/validation.py +++ b/src/prompt_toolkit/contrib/regular_languages/validation.py @@ -1,6 +1,7 @@ """ Validator for a regular language. """ + from __future__ import annotations from prompt_toolkit.document import Document diff --git a/src/prompt_toolkit/contrib/ssh/server.py b/src/prompt_toolkit/contrib/ssh/server.py index 9a5d402..4badc6c 100644 --- a/src/prompt_toolkit/contrib/ssh/server.py +++ b/src/prompt_toolkit/contrib/ssh/server.py @@ -1,6 +1,7 @@ """ Utility for running a prompt_toolkit application in an asyncssh server. """ + from __future__ import annotations import asyncio diff --git a/src/prompt_toolkit/contrib/telnet/log.py b/src/prompt_toolkit/contrib/telnet/log.py index 0fe8433..476dffc 100644 --- a/src/prompt_toolkit/contrib/telnet/log.py +++ b/src/prompt_toolkit/contrib/telnet/log.py @@ -1,6 +1,7 @@ """ Python logger for the telnet server. """ + from __future__ import annotations import logging diff --git a/src/prompt_toolkit/contrib/telnet/protocol.py b/src/prompt_toolkit/contrib/telnet/protocol.py index 4b90e98..58286e2 100644 --- a/src/prompt_toolkit/contrib/telnet/protocol.py +++ b/src/prompt_toolkit/contrib/telnet/protocol.py @@ -4,6 +4,7 @@ specification, but sufficient for a command line interface.) Inspired by `Twisted.conch.telnet`. """ + from __future__ import annotations import struct diff --git a/src/prompt_toolkit/contrib/telnet/server.py b/src/prompt_toolkit/contrib/telnet/server.py index 9ebe66c..69e9a88 100644 --- a/src/prompt_toolkit/contrib/telnet/server.py +++ b/src/prompt_toolkit/contrib/telnet/server.py @@ -1,6 +1,7 @@ """ Telnet server. """ + from __future__ import annotations import asyncio @@ -99,7 +100,7 @@ class _ConnectionStdout: if not self._closed: self._connection.send(b"".join(self._buffer)) except OSError as e: - logger.warning("Couldn't send data over socket: %s" % e) + logger.warning(f"Couldn't send data over socket: {e}") self._buffer = [] @@ -416,7 +417,7 @@ class TelnetServer: # Unhandled control-c propagated by a prompt. logger.info("Unhandled KeyboardInterrupt in telnet application.") except BaseException as e: - print("Got %s" % type(e).__name__, e) + print(f"Got {type(e).__name__}", e) import traceback traceback.print_exc() diff --git a/src/prompt_toolkit/document.py b/src/prompt_toolkit/document.py index 74f4c13..df5293e 100644 --- a/src/prompt_toolkit/document.py +++ b/src/prompt_toolkit/document.py @@ -1,6 +1,7 @@ """ The `Document` that implements all the text operations/querying. """ + from __future__ import annotations import bisect diff --git a/src/prompt_toolkit/eventloop/async_generator.py b/src/prompt_toolkit/eventloop/async_generator.py index 5aee50a..32e5f88 100644 --- a/src/prompt_toolkit/eventloop/async_generator.py +++ b/src/prompt_toolkit/eventloop/async_generator.py @@ -1,6 +1,7 @@ """ Implementation for async generators. """ + from __future__ import annotations from asyncio import get_running_loop diff --git a/src/prompt_toolkit/eventloop/inputhook.py b/src/prompt_toolkit/eventloop/inputhook.py index a4c0eee..40016e8 100644 --- a/src/prompt_toolkit/eventloop/inputhook.py +++ b/src/prompt_toolkit/eventloop/inputhook.py @@ -22,6 +22,7 @@ stuff to do. There are two ways to detect when to return: asynchronous autocompletion. When the completion for instance is ready, we also want prompt-toolkit to gain control again in order to display that. """ + from __future__ import annotations import asyncio diff --git a/src/prompt_toolkit/filters/__init__.py b/src/prompt_toolkit/filters/__init__.py index 277f428..556ed88 100644 --- a/src/prompt_toolkit/filters/__init__.py +++ b/src/prompt_toolkit/filters/__init__.py @@ -16,6 +16,7 @@ Filters can be chained using ``&`` and ``|`` operations, and inverted using the filter = has_focus('default') & ~ has_selection """ + from __future__ import annotations from .app import * diff --git a/src/prompt_toolkit/filters/app.py b/src/prompt_toolkit/filters/app.py index aacb228..b1b7c1b 100644 --- a/src/prompt_toolkit/filters/app.py +++ b/src/prompt_toolkit/filters/app.py @@ -1,6 +1,7 @@ """ Filters that accept a `Application` as argument. """ + from __future__ import annotations from typing import TYPE_CHECKING, cast diff --git a/src/prompt_toolkit/filters/base.py b/src/prompt_toolkit/filters/base.py index afce6dc..410749d 100644 --- a/src/prompt_toolkit/filters/base.py +++ b/src/prompt_toolkit/filters/base.py @@ -30,7 +30,7 @@ class Filter(metaclass=ABCMeta): """ Chaining of filters using the & operator. """ - assert isinstance(other, Filter), "Expecting filter, got %r" % other + assert isinstance(other, Filter), f"Expecting filter, got {other!r}" if isinstance(other, Always): return self @@ -48,7 +48,7 @@ class Filter(metaclass=ABCMeta): """ Chaining of filters using the | operator. """ - assert isinstance(other, Filter), "Expecting filter, got %r" % other + assert isinstance(other, Filter), f"Expecting filter, got {other!r}" if isinstance(other, Always): return other @@ -193,7 +193,7 @@ class _Invert(Filter): return not self.filter() def __repr__(self) -> str: - return "~%r" % self.filter + return f"~{self.filter!r}" class Always(Filter): @@ -207,6 +207,9 @@ class Always(Filter): def __or__(self, other: Filter) -> Filter: return self + def __and__(self, other: Filter) -> Filter: + return other + def __invert__(self) -> Never: return Never() @@ -222,6 +225,9 @@ class Never(Filter): def __and__(self, other: Filter) -> Filter: return self + def __or__(self, other: Filter) -> Filter: + return other + def __invert__(self) -> Always: return Always() @@ -248,7 +254,7 @@ class Condition(Filter): return self.func() def __repr__(self) -> str: - return "Condition(%r)" % self.func + return f"Condition({self.func!r})" # Often used as type annotation. diff --git a/src/prompt_toolkit/filters/cli.py b/src/prompt_toolkit/filters/cli.py index c95080a..902fbaa 100644 --- a/src/prompt_toolkit/filters/cli.py +++ b/src/prompt_toolkit/filters/cli.py @@ -2,6 +2,7 @@ For backwards-compatibility. keep this file. (Many people are going to have key bindings that rely on this file.) """ + from __future__ import annotations from .app import * diff --git a/src/prompt_toolkit/filters/utils.py b/src/prompt_toolkit/filters/utils.py index bac85ba..20e00ee 100644 --- a/src/prompt_toolkit/filters/utils.py +++ b/src/prompt_toolkit/filters/utils.py @@ -29,7 +29,7 @@ def to_filter(bool_or_filter: FilterOrBool) -> Filter: if isinstance(bool_or_filter, Filter): return bool_or_filter - raise TypeError("Expecting a bool or a Filter instance. Got %r" % bool_or_filter) + raise TypeError(f"Expecting a bool or a Filter instance. Got {bool_or_filter!r}") def is_true(value: FilterOrBool) -> bool: diff --git a/src/prompt_toolkit/formatted_text/__init__.py b/src/prompt_toolkit/formatted_text/__init__.py index db44ab9..0590c81 100644 --- a/src/prompt_toolkit/formatted_text/__init__.py +++ b/src/prompt_toolkit/formatted_text/__init__.py @@ -10,6 +10,7 @@ an :class:`.HTML` object, an :class:`.ANSI` object or a sequence of `(style_string, text)` tuples. The :func:`.to_formatted_text` conversion function takes any of these and turns all of them into such a tuple sequence. """ + from __future__ import annotations from .ansi import ANSI diff --git a/src/prompt_toolkit/formatted_text/ansi.py b/src/prompt_toolkit/formatted_text/ansi.py index 08ec0b3..4761982 100644 --- a/src/prompt_toolkit/formatted_text/ansi.py +++ b/src/prompt_toolkit/formatted_text/ansi.py @@ -210,10 +210,8 @@ class ANSI: # True colors. if n == 2 and len(attrs) >= 3: try: - color_str = "#{:02x}{:02x}{:02x}".format( - attrs.pop(), - attrs.pop(), - attrs.pop(), + color_str = ( + f"#{attrs.pop():02x}{attrs.pop():02x}{attrs.pop():02x}" ) except IndexError: pass diff --git a/src/prompt_toolkit/formatted_text/base.py b/src/prompt_toolkit/formatted_text/base.py index 92de353..5fee1f8 100644 --- a/src/prompt_toolkit/formatted_text/base.py +++ b/src/prompt_toolkit/formatted_text/base.py @@ -38,8 +38,7 @@ if TYPE_CHECKING: text. """ - def __pt_formatted_text__(self) -> StyleAndTextTuples: - ... + def __pt_formatted_text__(self) -> StyleAndTextTuples: ... AnyFormattedText = Union[ @@ -132,7 +131,7 @@ class FormattedText(StyleAndTextTuples): return self def __repr__(self) -> str: - return "FormattedText(%s)" % super().__repr__() + return f"FormattedText({super().__repr__()})" class Template: diff --git a/src/prompt_toolkit/formatted_text/utils.py b/src/prompt_toolkit/formatted_text/utils.py index c8c37e0..43228c3 100644 --- a/src/prompt_toolkit/formatted_text/utils.py +++ b/src/prompt_toolkit/formatted_text/utils.py @@ -4,6 +4,7 @@ Utilities for manipulating formatted text. When ``to_formatted_text`` has been called, we get a list of ``(style, text)`` tuples. This file contains functions for manipulating such a list. """ + from __future__ import annotations from typing import Iterable, cast diff --git a/src/prompt_toolkit/history.py b/src/prompt_toolkit/history.py index 553918e..2d497a0 100644 --- a/src/prompt_toolkit/history.py +++ b/src/prompt_toolkit/history.py @@ -7,6 +7,7 @@ NOTE: There is no `DynamicHistory`: loading can be done asynchronously and making the history swappable would probably break this. """ + from __future__ import annotations import datetime @@ -14,7 +15,7 @@ import os import threading from abc import ABCMeta, abstractmethod from asyncio import get_running_loop -from typing import AsyncGenerator, Iterable, Sequence +from typing import AsyncGenerator, Iterable, Sequence, Union __all__ = [ "History", @@ -254,12 +255,15 @@ class DummyHistory(History): pass +_StrOrBytesPath = Union[str, bytes, "os.PathLike[str]", "os.PathLike[bytes]"] + + class FileHistory(History): """ :class:`.History` class that stores all strings in a file. """ - def __init__(self, filename: str) -> None: + def __init__(self, filename: _StrOrBytesPath) -> None: self.filename = filename super().__init__() @@ -297,6 +301,6 @@ class FileHistory(History): def write(t: str) -> None: f.write(t.encode("utf-8")) - write("\n# %s\n" % datetime.datetime.now()) + write(f"\n# {datetime.datetime.now()}\n") for line in string.split("\n"): - write("+%s\n" % line) + write(f"+{line}\n") diff --git a/src/prompt_toolkit/input/ansi_escape_sequences.py b/src/prompt_toolkit/input/ansi_escape_sequences.py index 5648c66..1fba418 100644 --- a/src/prompt_toolkit/input/ansi_escape_sequences.py +++ b/src/prompt_toolkit/input/ansi_escape_sequences.py @@ -10,6 +10,7 @@ mostly Xterm compatible. Some useful docs: - Mintty: https://github.com/mintty/mintty/blob/master/wiki/Keycodes.md """ + from __future__ import annotations from ..keys import Keys diff --git a/src/prompt_toolkit/input/base.py b/src/prompt_toolkit/input/base.py index fd1429d..3dcb994 100644 --- a/src/prompt_toolkit/input/base.py +++ b/src/prompt_toolkit/input/base.py @@ -1,6 +1,7 @@ """ Abstraction of CLI Input. """ + from __future__ import annotations from abc import ABCMeta, abstractmethod, abstractproperty @@ -116,7 +117,7 @@ class DummyInput(Input): raise NotImplementedError def typeahead_hash(self) -> str: - return "dummy-%s" % id(self) + return f"dummy-{id(self)}" def read_keys(self) -> list[KeyPress]: return [] diff --git a/src/prompt_toolkit/input/typeahead.py b/src/prompt_toolkit/input/typeahead.py index a45e7cf..f8faa93 100644 --- a/src/prompt_toolkit/input/typeahead.py +++ b/src/prompt_toolkit/input/typeahead.py @@ -31,6 +31,7 @@ To support type ahead, this module will store all the key strokes that were read too early, so that they can be feed into to the next `prompt()` call or to the next prompt_toolkit `Application`. """ + from __future__ import annotations from collections import defaultdict diff --git a/src/prompt_toolkit/input/vt100_parser.py b/src/prompt_toolkit/input/vt100_parser.py index 99e2d99..73dbce3 100644 --- a/src/prompt_toolkit/input/vt100_parser.py +++ b/src/prompt_toolkit/input/vt100_parser.py @@ -1,6 +1,7 @@ """ Parser for VT100 input stream. """ + from __future__ import annotations import re diff --git a/src/prompt_toolkit/input/win32.py b/src/prompt_toolkit/input/win32.py index 35e8948..322d7c0 100644 --- a/src/prompt_toolkit/input/win32.py +++ b/src/prompt_toolkit/input/win32.py @@ -329,8 +329,8 @@ class ConsoleInputReader: buffered_high_surrogate = None for key in key_presses: is_text = not isinstance(key.key, Keys) - is_high_surrogate = is_text and "\uD800" <= key.key <= "\uDBFF" - is_low_surrogate = is_text and "\uDC00" <= key.key <= "\uDFFF" + is_high_surrogate = is_text and "\ud800" <= key.key <= "\udbff" + is_low_surrogate = is_text and "\udc00" <= key.key <= "\udfff" if buffered_high_surrogate: if is_low_surrogate: diff --git a/src/prompt_toolkit/key_binding/bindings/auto_suggest.py b/src/prompt_toolkit/key_binding/bindings/auto_suggest.py index 3d8a843..b487f14 100644 --- a/src/prompt_toolkit/key_binding/bindings/auto_suggest.py +++ b/src/prompt_toolkit/key_binding/bindings/auto_suggest.py @@ -1,6 +1,7 @@ """ Key bindings for auto suggestion (for fish-style auto suggestion). """ + from __future__ import annotations import re diff --git a/src/prompt_toolkit/key_binding/bindings/basic.py b/src/prompt_toolkit/key_binding/bindings/basic.py index 084548d..ad18df9 100644 --- a/src/prompt_toolkit/key_binding/bindings/basic.py +++ b/src/prompt_toolkit/key_binding/bindings/basic.py @@ -29,6 +29,16 @@ def if_no_repeat(event: E) -> bool: return not event.is_repeat +@Condition +def has_text_before_cursor() -> bool: + return bool(get_app().current_buffer.text) + + +@Condition +def in_quoted_insert() -> bool: + return get_app().quoted_insert + + def load_basic_bindings() -> KeyBindings: key_bindings = KeyBindings() insert_mode = vi_insert_mode | emacs_insert_mode @@ -171,10 +181,6 @@ def load_basic_bindings() -> KeyBindings: # CTRL keys. - @Condition - def has_text_before_cursor() -> bool: - return bool(get_app().current_buffer.text) - handle("c-d", filter=has_text_before_cursor & insert_mode)( get_by_name("delete-char") ) @@ -240,10 +246,6 @@ def load_basic_bindings() -> KeyBindings: event.current_buffer.insert_text(data) - @Condition - def in_quoted_insert() -> bool: - return get_app().quoted_insert - @handle(Keys.Any, filter=in_quoted_insert, eager=True) def _insert_text(event: E) -> None: """ diff --git a/src/prompt_toolkit/key_binding/bindings/completion.py b/src/prompt_toolkit/key_binding/bindings/completion.py index 016821f..8c5e005 100644 --- a/src/prompt_toolkit/key_binding/bindings/completion.py +++ b/src/prompt_toolkit/key_binding/bindings/completion.py @@ -1,6 +1,7 @@ """ Key binding handlers for displaying completions. """ + from __future__ import annotations import asyncio diff --git a/src/prompt_toolkit/key_binding/bindings/emacs.py b/src/prompt_toolkit/key_binding/bindings/emacs.py index 80a66fd..207afba 100644 --- a/src/prompt_toolkit/key_binding/bindings/emacs.py +++ b/src/prompt_toolkit/key_binding/bindings/emacs.py @@ -33,6 +33,16 @@ __all__ = [ E = KeyPressEvent +@Condition +def is_returnable() -> bool: + return get_app().current_buffer.is_returnable + + +@Condition +def is_arg() -> bool: + return get_app().key_processor.arg == "-" + + def load_emacs_bindings() -> KeyBindingsBase: """ Some e-macs extensions. @@ -134,7 +144,7 @@ def load_emacs_bindings() -> KeyBindingsBase: if event._arg is None: event.append_to_arg_count("-") - @handle("-", filter=Condition(lambda: get_app().key_processor.arg == "-")) + @handle("-", filter=is_arg) def _dash(event: E) -> None: """ When '-' is typed again, after exactly '-' has been given as an @@ -142,10 +152,6 @@ def load_emacs_bindings() -> KeyBindingsBase: """ event.app.key_processor.arg = "-" - @Condition - def is_returnable() -> bool: - return get_app().current_buffer.is_returnable - # Meta + Enter: always accept input. handle("escape", "enter", filter=insert_mode & is_returnable)( get_by_name("accept-line") diff --git a/src/prompt_toolkit/key_binding/bindings/named_commands.py b/src/prompt_toolkit/key_binding/bindings/named_commands.py index d836116..8ea8dd0 100644 --- a/src/prompt_toolkit/key_binding/bindings/named_commands.py +++ b/src/prompt_toolkit/key_binding/bindings/named_commands.py @@ -3,6 +3,7 @@ Key bindings which are also known by GNU Readline by the given names. See: http://www.delorie.com/gnu/docs/readline/rlman_13.html """ + from __future__ import annotations from typing import Callable, TypeVar, Union, cast @@ -58,7 +59,7 @@ def get_by_name(name: str) -> Binding: try: return _readline_commands[name] except KeyError as e: - raise KeyError("Unknown Readline command: %r" % name) from e + raise KeyError(f"Unknown Readline command: {name!r}") from e # diff --git a/src/prompt_toolkit/key_binding/bindings/open_in_editor.py b/src/prompt_toolkit/key_binding/bindings/open_in_editor.py index d156424..26b8685 100644 --- a/src/prompt_toolkit/key_binding/bindings/open_in_editor.py +++ b/src/prompt_toolkit/key_binding/bindings/open_in_editor.py @@ -1,6 +1,7 @@ """ Open in editor key bindings. """ + from __future__ import annotations from prompt_toolkit.filters import emacs_mode, has_selection, vi_navigation_mode diff --git a/src/prompt_toolkit/key_binding/bindings/page_navigation.py b/src/prompt_toolkit/key_binding/bindings/page_navigation.py index 3918e14..c490425 100644 --- a/src/prompt_toolkit/key_binding/bindings/page_navigation.py +++ b/src/prompt_toolkit/key_binding/bindings/page_navigation.py @@ -2,6 +2,7 @@ Key bindings for extra page navigation: bindings for up/down scrolling through long pages, like in Emacs or Vi. """ + from __future__ import annotations from prompt_toolkit.filters import buffer_has_focus, emacs_mode, vi_mode diff --git a/src/prompt_toolkit/key_binding/bindings/scroll.py b/src/prompt_toolkit/key_binding/bindings/scroll.py index 83a4be1..13e44ed 100644 --- a/src/prompt_toolkit/key_binding/bindings/scroll.py +++ b/src/prompt_toolkit/key_binding/bindings/scroll.py @@ -5,6 +5,7 @@ This are separate bindings, because GNU readline doesn't have them, but they are very useful for navigating through long multiline buffers, like in Vi, Emacs, etc... """ + from __future__ import annotations from prompt_toolkit.key_binding.key_processor import KeyPressEvent diff --git a/src/prompt_toolkit/key_binding/bindings/search.py b/src/prompt_toolkit/key_binding/bindings/search.py index ba5e117..a57c52e 100644 --- a/src/prompt_toolkit/key_binding/bindings/search.py +++ b/src/prompt_toolkit/key_binding/bindings/search.py @@ -1,6 +1,7 @@ """ Search related key bindings. """ + from __future__ import annotations from prompt_toolkit import search diff --git a/src/prompt_toolkit/key_binding/bindings/vi.py b/src/prompt_toolkit/key_binding/bindings/vi.py index 5cc74b4..d68a31f 100644 --- a/src/prompt_toolkit/key_binding/bindings/vi.py +++ b/src/prompt_toolkit/key_binding/bindings/vi.py @@ -371,6 +371,35 @@ def create_operator_decorator( return operator_decorator +@Condition +def is_returnable() -> bool: + return get_app().current_buffer.is_returnable + + +@Condition +def in_block_selection() -> bool: + buff = get_app().current_buffer + return bool( + buff.selection_state and buff.selection_state.type == SelectionType.BLOCK + ) + + +@Condition +def digraph_symbol_1_given() -> bool: + return get_app().vi_state.digraph_symbol1 is not None + + +@Condition +def search_buffer_is_empty() -> bool: + "Returns True when the search buffer is empty." + return get_app().current_buffer.text == "" + + +@Condition +def tilde_operator() -> bool: + return get_app().vi_state.tilde_operator + + def load_vi_bindings() -> KeyBindingsBase: """ Vi extensions. @@ -410,7 +439,7 @@ def load_vi_bindings() -> KeyBindingsBase: (("g", "~"), Always(), lambda string: string.swapcase()), ( ("~",), - Condition(lambda: get_app().vi_state.tilde_operator), + tilde_operator, lambda string: string.swapcase(), ), ] @@ -528,10 +557,6 @@ def load_vi_bindings() -> KeyBindingsBase: """ event.current_buffer.cancel_completion() - @Condition - def is_returnable() -> bool: - return get_app().current_buffer.is_returnable - # In navigation mode, pressing enter will always return the input. handle("enter", filter=vi_navigation_mode & is_returnable)( get_by_name("accept-line") @@ -681,13 +706,6 @@ def load_vi_bindings() -> KeyBindingsBase: ) ) - @Condition - def in_block_selection() -> bool: - buff = get_app().current_buffer - return bool( - buff.selection_state and buff.selection_state.type == SelectionType.BLOCK - ) - @handle("I", filter=in_block_selection & ~is_read_only) def insert_in_block_selection(event: E, after: bool = False) -> None: """ @@ -2071,10 +2089,6 @@ def load_vi_bindings() -> KeyBindingsBase: """ event.app.vi_state.waiting_for_digraph = True - @Condition - def digraph_symbol_1_given() -> bool: - return get_app().vi_state.digraph_symbol1 is not None - @handle(Keys.Any, filter=vi_digraph_mode & ~digraph_symbol_1_given) def _digraph1(event: E) -> None: """ @@ -2180,11 +2194,6 @@ def load_vi_search_bindings() -> KeyBindingsBase: handle = key_bindings.add from . import search - @Condition - def search_buffer_is_empty() -> bool: - "Returns True when the search buffer is empty." - return get_app().current_buffer.text == "" - # Vi-style forward search. handle( "/", diff --git a/src/prompt_toolkit/key_binding/defaults.py b/src/prompt_toolkit/key_binding/defaults.py index 166da8d..6c26571 100644 --- a/src/prompt_toolkit/key_binding/defaults.py +++ b/src/prompt_toolkit/key_binding/defaults.py @@ -4,6 +4,7 @@ Default key bindings.:: key_bindings = load_key_bindings() app = Application(key_bindings=key_bindings) """ + from __future__ import annotations from prompt_toolkit.filters import buffer_has_focus diff --git a/src/prompt_toolkit/key_binding/digraphs.py b/src/prompt_toolkit/key_binding/digraphs.py index 1e8a432..f0152dc 100644 --- a/src/prompt_toolkit/key_binding/digraphs.py +++ b/src/prompt_toolkit/key_binding/digraphs.py @@ -6,6 +6,7 @@ pressing Control-K followed by to normal characters. Taken from Neovim and translated to Python: https://raw.githubusercontent.com/neovim/neovim/master/src/nvim/digraph.c """ + from __future__ import annotations __all__ = [ diff --git a/src/prompt_toolkit/key_binding/key_bindings.py b/src/prompt_toolkit/key_binding/key_bindings.py index 62530f2..854da80 100644 --- a/src/prompt_toolkit/key_binding/key_bindings.py +++ b/src/prompt_toolkit/key_binding/key_bindings.py @@ -34,6 +34,7 @@ been assigned, through the `key_binding` decorator.:: # Later, add it to the key bindings. kb.add(Keys.A, my_key_binding) """ + from __future__ import annotations from abc import ABCMeta, abstractmethod, abstractproperty @@ -140,10 +141,8 @@ class Binding: event.app.invalidate() def __repr__(self) -> str: - return "{}(keys={!r}, handler={!r})".format( - self.__class__.__name__, - self.keys, - self.handler, + return ( + f"{self.__class__.__name__}(keys={self.keys!r}, handler={self.handler!r})" ) @@ -226,9 +225,9 @@ class KeyBindings(KeyBindingsBase): def __init__(self) -> None: self._bindings: list[Binding] = [] - self._get_bindings_for_keys_cache: SimpleCache[ - KeysTuple, list[Binding] - ] = SimpleCache(maxsize=10000) + self._get_bindings_for_keys_cache: SimpleCache[KeysTuple, list[Binding]] = ( + SimpleCache(maxsize=10000) + ) self._get_bindings_starting_with_keys_cache: SimpleCache[ KeysTuple, list[Binding] ] = SimpleCache(maxsize=1000) diff --git a/src/prompt_toolkit/key_binding/key_processor.py b/src/prompt_toolkit/key_binding/key_processor.py index 4c4f0d1..e2070a1 100644 --- a/src/prompt_toolkit/key_binding/key_processor.py +++ b/src/prompt_toolkit/key_binding/key_processor.py @@ -5,6 +5,7 @@ the input in the :class:`~prompt_toolkit.inputstream.InputStream` instance. The `KeyProcessor` will according to the implemented keybindings call the correct callbacks when new key presses are feed through `feed`. """ + from __future__ import annotations import weakref @@ -450,11 +451,7 @@ class KeyPressEvent: self._app = get_app() def __repr__(self) -> str: - return "KeyPressEvent(arg={!r}, key_sequence={!r}, is_repeat={!r})".format( - self.arg, - self.key_sequence, - self.is_repeat, - ) + return f"KeyPressEvent(arg={self.arg!r}, key_sequence={self.key_sequence!r}, is_repeat={self.is_repeat!r})" @property def data(self) -> str: diff --git a/src/prompt_toolkit/layout/__init__.py b/src/prompt_toolkit/layout/__init__.py index c5fce46..7cd0c77 100644 --- a/src/prompt_toolkit/layout/__init__.py +++ b/src/prompt_toolkit/layout/__init__.py @@ -44,6 +44,7 @@ And one prepared menu: - CompletionsMenu """ + from __future__ import annotations from .containers import ( diff --git a/src/prompt_toolkit/layout/containers.py b/src/prompt_toolkit/layout/containers.py index 100d4aa..99b4534 100644 --- a/src/prompt_toolkit/layout/containers.py +++ b/src/prompt_toolkit/layout/containers.py @@ -2,6 +2,7 @@ Container for the layout. (Containers can contain other containers or user interface controls.) """ + from __future__ import annotations from abc import ABCMeta, abstractmethod @@ -156,8 +157,7 @@ if TYPE_CHECKING: Any object that implements ``__pt_container__`` represents a container. """ - def __pt_container__(self) -> AnyContainer: - ... + def __pt_container__(self) -> AnyContainer: ... AnyContainer = Union[Container, "MagicContainer"] @@ -296,9 +296,9 @@ class HSplit(_Split): self.align = align - self._children_cache: SimpleCache[ - tuple[Container, ...], list[Container] - ] = SimpleCache(maxsize=1) + self._children_cache: SimpleCache[tuple[Container, ...], list[Container]] = ( + SimpleCache(maxsize=1) + ) self._remaining_space_window = Window() # Dummy window. def preferred_width(self, max_available_width: int) -> Dimension: @@ -533,9 +533,9 @@ class VSplit(_Split): self.align = align - self._children_cache: SimpleCache[ - tuple[Container, ...], list[Container] - ] = SimpleCache(maxsize=1) + self._children_cache: SimpleCache[tuple[Container, ...], list[Container]] = ( + SimpleCache(maxsize=1) + ) self._remaining_space_window = Window() # Dummy window. def preferred_width(self, max_available_width: int) -> Dimension: @@ -1093,7 +1093,7 @@ class Float: return self.height def __repr__(self) -> str: - return "Float(content=%r)" % self.content + return f"Float(content={self.content!r})" class WindowRenderInfo: @@ -1352,12 +1352,7 @@ class ScrollOffsets: return to_int(self._right) def __repr__(self) -> str: - return "ScrollOffsets(top={!r}, bottom={!r}, left={!r}, right={!r})".format( - self._top, - self._bottom, - self._left, - self._right, - ) + return f"ScrollOffsets(top={self._top!r}, bottom={self._bottom!r}, left={self._left!r}, right={self._right!r})" class ColorColumn: @@ -1504,9 +1499,9 @@ class Window(Container): self.z_index = z_index # Cache for the screens generated by the margin. - self._ui_content_cache: SimpleCache[ - tuple[int, int, int], UIContent - ] = SimpleCache(maxsize=8) + self._ui_content_cache: SimpleCache[tuple[int, int, int], UIContent] = ( + SimpleCache(maxsize=8) + ) self._margin_width_cache: SimpleCache[tuple[Margin, int], int] = SimpleCache( maxsize=1 ) @@ -1514,7 +1509,7 @@ class Window(Container): self.reset() def __repr__(self) -> str: - return "Window(content=%r)" % self.content + return f"Window(content={self.content!r})" def reset(self) -> None: self.content.reset() diff --git a/src/prompt_toolkit/layout/controls.py b/src/prompt_toolkit/layout/controls.py index c30c0ef..222e471 100644 --- a/src/prompt_toolkit/layout/controls.py +++ b/src/prompt_toolkit/layout/controls.py @@ -1,6 +1,7 @@ """ User interface Controls for the layout. """ + from __future__ import annotations import time diff --git a/src/prompt_toolkit/layout/dimension.py b/src/prompt_toolkit/layout/dimension.py index c1f05f9..2e6f5dd 100644 --- a/src/prompt_toolkit/layout/dimension.py +++ b/src/prompt_toolkit/layout/dimension.py @@ -2,6 +2,7 @@ Layout dimensions are used to give the minimum, maximum and preferred dimensions for containers and controls. """ + from __future__ import annotations from typing import TYPE_CHECKING, Any, Callable, Union @@ -105,15 +106,15 @@ class Dimension: def __repr__(self) -> str: fields = [] if self.min_specified: - fields.append("min=%r" % self.min) + fields.append(f"min={self.min!r}") if self.max_specified: - fields.append("max=%r" % self.max) + fields.append(f"max={self.max!r}") if self.preferred_specified: - fields.append("preferred=%r" % self.preferred) + fields.append(f"preferred={self.preferred!r}") if self.weight_specified: - fields.append("weight=%r" % self.weight) + fields.append(f"weight={self.weight!r}") - return "Dimension(%s)" % ", ".join(fields) + return "Dimension({})".format(", ".join(fields)) def sum_layout_dimensions(dimensions: list[Dimension]) -> Dimension: diff --git a/src/prompt_toolkit/layout/dummy.py b/src/prompt_toolkit/layout/dummy.py index 139f311..1ee3e6c 100644 --- a/src/prompt_toolkit/layout/dummy.py +++ b/src/prompt_toolkit/layout/dummy.py @@ -2,6 +2,7 @@ Dummy layout. Used when somebody creates an `Application` without specifying a `Layout`. """ + from __future__ import annotations from prompt_toolkit.formatted_text import HTML diff --git a/src/prompt_toolkit/layout/layout.py b/src/prompt_toolkit/layout/layout.py index a5e7a80..f9b7110 100644 --- a/src/prompt_toolkit/layout/layout.py +++ b/src/prompt_toolkit/layout/layout.py @@ -1,6 +1,7 @@ """ Wrapper for the layout. """ + from __future__ import annotations from typing import Generator, Iterable, Union diff --git a/src/prompt_toolkit/layout/margins.py b/src/prompt_toolkit/layout/margins.py index cc9dd96..737a74d 100644 --- a/src/prompt_toolkit/layout/margins.py +++ b/src/prompt_toolkit/layout/margins.py @@ -1,6 +1,7 @@ """ Margin implementations for a :class:`~prompt_toolkit.layout.containers.Window`. """ + from __future__ import annotations from abc import ABCMeta, abstractmethod @@ -83,7 +84,7 @@ class NumberedMargin(Margin): def get_width(self, get_ui_content: Callable[[], UIContent]) -> int: line_count = get_ui_content().line_count - return max(3, len("%s" % line_count) + 1) + return max(3, len(f"{line_count}") + 1) def create_margin( self, window_render_info: WindowRenderInfo, width: int, height: int diff --git a/src/prompt_toolkit/layout/menus.py b/src/prompt_toolkit/layout/menus.py index 2c2ccb6..612e8ab 100644 --- a/src/prompt_toolkit/layout/menus.py +++ b/src/prompt_toolkit/layout/menus.py @@ -212,10 +212,7 @@ def _get_menu_item_fragments( width. """ if is_current_completion: - style_str = "class:completion-menu.completion.current {} {}".format( - completion.style, - completion.selected_style, - ) + style_str = f"class:completion-menu.completion.current {completion.style} {completion.selected_style}" else: style_str = "class:completion-menu.completion " + completion.style diff --git a/src/prompt_toolkit/layout/mouse_handlers.py b/src/prompt_toolkit/layout/mouse_handlers.py index 56a4edd..52deac1 100644 --- a/src/prompt_toolkit/layout/mouse_handlers.py +++ b/src/prompt_toolkit/layout/mouse_handlers.py @@ -34,9 +34,9 @@ class MouseHandlers: # over the mouse handlers of the visible region in the scrollable pane. # Map y (row) to x (column) to handlers. - self.mouse_handlers: defaultdict[ - int, defaultdict[int, MouseHandler] - ] = defaultdict(lambda: defaultdict(lambda: dummy_callback)) + self.mouse_handlers: defaultdict[int, defaultdict[int, MouseHandler]] = ( + defaultdict(lambda: defaultdict(lambda: dummy_callback)) + ) def set_mouse_handler_for_range( self, diff --git a/src/prompt_toolkit/layout/processors.py b/src/prompt_toolkit/layout/processors.py index b737611..b10ecf7 100644 --- a/src/prompt_toolkit/layout/processors.py +++ b/src/prompt_toolkit/layout/processors.py @@ -5,6 +5,7 @@ from a buffer before the BufferControl will render it to the screen. They can insert fragments before or after, or highlight fragments by replacing the fragment types. """ + from __future__ import annotations import re @@ -343,9 +344,9 @@ class HighlightMatchingBracketProcessor(Processor): self.chars = chars self.max_cursor_distance = max_cursor_distance - self._positions_cache: SimpleCache[ - Hashable, list[tuple[int, int]] - ] = SimpleCache(maxsize=8) + self._positions_cache: SimpleCache[Hashable, list[tuple[int, int]]] = ( + SimpleCache(maxsize=8) + ) def _get_positions_to_highlight(self, document: Document) -> list[tuple[int, int]]: """ @@ -924,11 +925,7 @@ class ConditionalProcessor(Processor): return Transformation(transformation_input.fragments) def __repr__(self) -> str: - return "{}(processor={!r}, filter={!r})".format( - self.__class__.__name__, - self.processor, - self.filter, - ) + return f"{self.__class__.__name__}(processor={self.processor!r}, filter={self.filter!r})" class DynamicProcessor(Processor): diff --git a/src/prompt_toolkit/layout/screen.py b/src/prompt_toolkit/layout/screen.py index 49aebbd..0f19f52 100644 --- a/src/prompt_toolkit/layout/screen.py +++ b/src/prompt_toolkit/layout/screen.py @@ -320,10 +320,4 @@ class WritePosition: self.height = height def __repr__(self) -> str: - return "{}(x={!r}, y={!r}, width={!r}, height={!r})".format( - self.__class__.__name__, - self.xpos, - self.ypos, - self.width, - self.height, - ) + return f"{self.__class__.__name__}(x={self.xpos!r}, y={self.ypos!r}, width={self.width!r}, height={self.height!r})" diff --git a/src/prompt_toolkit/layout/utils.py b/src/prompt_toolkit/layout/utils.py index 0f78f37..373fe52 100644 --- a/src/prompt_toolkit/layout/utils.py +++ b/src/prompt_toolkit/layout/utils.py @@ -36,12 +36,10 @@ class _ExplodedList(List[_T]): # TODO: When creating a copy() or [:], return also an _ExplodedList. @overload - def __setitem__(self, index: SupportsIndex, value: _T) -> None: - ... + def __setitem__(self, index: SupportsIndex, value: _T) -> None: ... @overload - def __setitem__(self, index: slice, value: Iterable[_T]) -> None: - ... + def __setitem__(self, index: slice, value: Iterable[_T]) -> None: ... def __setitem__( self, index: SupportsIndex | slice, value: _T | Iterable[_T] diff --git a/src/prompt_toolkit/lexers/__init__.py b/src/prompt_toolkit/lexers/__init__.py index 9bdc599..8f72d07 100644 --- a/src/prompt_toolkit/lexers/__init__.py +++ b/src/prompt_toolkit/lexers/__init__.py @@ -2,6 +2,7 @@ Lexer interface and implementations. Used for syntax highlighting. """ + from __future__ import annotations from .base import DynamicLexer, Lexer, SimpleLexer diff --git a/src/prompt_toolkit/lexers/base.py b/src/prompt_toolkit/lexers/base.py index 3f65f8e..c61e2b9 100644 --- a/src/prompt_toolkit/lexers/base.py +++ b/src/prompt_toolkit/lexers/base.py @@ -1,6 +1,7 @@ """ Base classes for prompt_toolkit lexers. """ + from __future__ import annotations from abc import ABCMeta, abstractmethod diff --git a/src/prompt_toolkit/lexers/pygments.py b/src/prompt_toolkit/lexers/pygments.py index 4721d73..d5a39c4 100644 --- a/src/prompt_toolkit/lexers/pygments.py +++ b/src/prompt_toolkit/lexers/pygments.py @@ -4,6 +4,7 @@ Adaptor classes for using Pygments lexers within prompt_toolkit. This includes syntax synchronization code, so that we don't have to start lexing at the beginning of a document, when displaying a very large text. """ + from __future__ import annotations import re diff --git a/src/prompt_toolkit/log.py b/src/prompt_toolkit/log.py index adb5172..2853579 100644 --- a/src/prompt_toolkit/log.py +++ b/src/prompt_toolkit/log.py @@ -1,6 +1,7 @@ """ Logging configuration. """ + from __future__ import annotations import logging diff --git a/src/prompt_toolkit/mouse_events.py b/src/prompt_toolkit/mouse_events.py index 743773b..f244f8e 100644 --- a/src/prompt_toolkit/mouse_events.py +++ b/src/prompt_toolkit/mouse_events.py @@ -15,6 +15,7 @@ through the `Window` class where the coordinates are translated from absolute coordinates to coordinates relative to the user control, and there `UIControl.mouse_handler` is called. """ + from __future__ import annotations from enum import Enum @@ -81,9 +82,4 @@ class MouseEvent: self.modifiers = modifiers def __repr__(self) -> str: - return "MouseEvent({!r},{!r},{!r},{!r})".format( - self.position, - self.event_type, - self.button, - self.modifiers, - ) + return f"MouseEvent({self.position!r},{self.event_type!r},{self.button!r},{self.modifiers!r})" diff --git a/src/prompt_toolkit/output/base.py b/src/prompt_toolkit/output/base.py index 3c38cec..6ba09fd 100644 --- a/src/prompt_toolkit/output/base.py +++ b/src/prompt_toolkit/output/base.py @@ -1,6 +1,7 @@ """ Interface for an output. """ + from __future__ import annotations from abc import ABCMeta, abstractmethod diff --git a/src/prompt_toolkit/output/vt100.py b/src/prompt_toolkit/output/vt100.py index 142deab..069636b 100644 --- a/src/prompt_toolkit/output/vt100.py +++ b/src/prompt_toolkit/output/vt100.py @@ -6,6 +6,7 @@ A lot of thanks, regarding outputting of colors, goes to the Pygments project: everything has been highly optimized.) http://pygments.org/ """ + from __future__ import annotations import io @@ -521,7 +522,7 @@ class Vt100_Output(Output): "eterm-color", ): # Not supported by the Linux console. self.write_raw( - "\x1b]2;%s\x07" % title.replace("\x1b", "").replace("\x07", "") + "\x1b]2;{}\x07".format(title.replace("\x1b", "").replace("\x07", "")) ) def clear_title(self) -> None: diff --git a/src/prompt_toolkit/output/win32.py b/src/prompt_toolkit/output/win32.py index edeca09..83ccea4 100644 --- a/src/prompt_toolkit/output/win32.py +++ b/src/prompt_toolkit/output/win32.py @@ -73,11 +73,11 @@ class NoConsoleScreenBufferError(Exception): if xterm: message = ( - "Found %s, while expecting a Windows console. " + "Found {}, while expecting a Windows console. " 'Maybe try to run this program using "winpty" ' "or run it in cmd.exe instead. Or otherwise, " "in case of Cygwin, use the Python executable " - "that is compiled for Cygwin." % os.environ["TERM"] + "that is compiled for Cygwin.".format(os.environ["TERM"]) ) else: message = "No Windows console found. Are you running cmd.exe?" @@ -163,13 +163,13 @@ class Win32Output(Output): self.flush() if _DEBUG_RENDER_OUTPUT: - self.LOG.write(("%r" % func.__name__).encode("utf-8") + b"\n") + self.LOG.write((f"{func.__name__!r}").encode() + b"\n") self.LOG.write( - b" " + ", ".join(["%r" % i for i in a]).encode("utf-8") + b"\n" + b" " + ", ".join([f"{i!r}" for i in a]).encode("utf-8") + b"\n" ) self.LOG.write( b" " - + ", ".join(["%r" % type(i) for i in a]).encode("utf-8") + + ", ".join([f"{type(i)!r}" for i in a]).encode("utf-8") + b"\n" ) self.LOG.flush() @@ -370,7 +370,7 @@ class Win32Output(Output): data = "".join(self._buffer) if _DEBUG_RENDER_OUTPUT: - self.LOG.write(("%r" % data).encode("utf-8") + b"\n") + self.LOG.write((f"{data!r}").encode() + b"\n") self.LOG.flush() # Print characters one by one. This appears to be the best solution diff --git a/src/prompt_toolkit/patch_stdout.py b/src/prompt_toolkit/patch_stdout.py index 528bec7..4958e9d 100644 --- a/src/prompt_toolkit/patch_stdout.py +++ b/src/prompt_toolkit/patch_stdout.py @@ -17,6 +17,7 @@ Usage:: Multiple applications can run in the body of the context manager, one after the other. """ + from __future__ import annotations import asyncio diff --git a/src/prompt_toolkit/renderer.py b/src/prompt_toolkit/renderer.py index 5ad1dd6..3f92303 100644 --- a/src/prompt_toolkit/renderer.py +++ b/src/prompt_toolkit/renderer.py @@ -2,6 +2,7 @@ Renders the command line on the console. (Redraws parts of the input line that were changed.) """ + from __future__ import annotations from asyncio import FIRST_COMPLETED, Future, ensure_future, sleep, wait diff --git a/src/prompt_toolkit/search.py b/src/prompt_toolkit/search.py index fd90a04..d1cf7ac 100644 --- a/src/prompt_toolkit/search.py +++ b/src/prompt_toolkit/search.py @@ -5,6 +5,7 @@ For the key bindings implementation with attached filters, check `prompt_toolkit.key_binding.bindings.search`. (Use these for new key bindings instead of calling these function directly.) """ + from __future__ import annotations from enum import Enum @@ -59,12 +60,7 @@ class SearchState: self.ignore_case = to_filter(ignore_case) def __repr__(self) -> str: - return "{}({!r}, direction={!r}, ignore_case={!r})".format( - self.__class__.__name__, - self.text, - self.direction, - self.ignore_case, - ) + return f"{self.__class__.__name__}({self.text!r}, direction={self.direction!r}, ignore_case={self.ignore_case!r})" def __invert__(self) -> SearchState: """ diff --git a/src/prompt_toolkit/selection.py b/src/prompt_toolkit/selection.py index 2158fa9..ff88535 100644 --- a/src/prompt_toolkit/selection.py +++ b/src/prompt_toolkit/selection.py @@ -1,6 +1,7 @@ """ Data structures for the selection. """ + from __future__ import annotations from enum import Enum @@ -54,8 +55,4 @@ class SelectionState: self.shift_mode = True def __repr__(self) -> str: - return "{}(original_cursor_position={!r}, type={!r})".format( - self.__class__.__name__, - self.original_cursor_position, - self.type, - ) + return f"{self.__class__.__name__}(original_cursor_position={self.original_cursor_position!r}, type={self.type!r})" diff --git a/src/prompt_toolkit/shortcuts/progress_bar/base.py b/src/prompt_toolkit/shortcuts/progress_bar/base.py index 21aa1be..a7c2a52 100644 --- a/src/prompt_toolkit/shortcuts/progress_bar/base.py +++ b/src/prompt_toolkit/shortcuts/progress_bar/base.py @@ -7,6 +7,7 @@ Progress bar implementation on top of prompt_toolkit. for item in pb(data): ... """ + from __future__ import annotations import contextvars diff --git a/src/prompt_toolkit/shortcuts/progress_bar/formatters.py b/src/prompt_toolkit/shortcuts/progress_bar/formatters.py index dd0339c..202949c 100644 --- a/src/prompt_toolkit/shortcuts/progress_bar/formatters.py +++ b/src/prompt_toolkit/shortcuts/progress_bar/formatters.py @@ -2,6 +2,7 @@ Formatter classes for the progress bar. Each progress bar consists of a list of these formatters. """ + from __future__ import annotations import datetime @@ -130,7 +131,7 @@ class Percentage(Formatter): Display the progress as a percentage. """ - template = "{percentage:>5}%" + template = HTML("{percentage:>5}%") def format( self, @@ -138,7 +139,7 @@ class Percentage(Formatter): progress: ProgressBarCounter[object], width: int, ) -> AnyFormattedText: - return HTML(self.template).format(percentage=round(progress.percentage, 1)) + return self.template.format(percentage=round(progress.percentage, 1)) def get_width(self, progress_bar: ProgressBar) -> AnyDimension: return D.exact(6) @@ -149,7 +150,9 @@ class Bar(Formatter): Display the progress bar itself. """ - template = "{start}{bar_a}{bar_b}{bar_c}{end}" + template = HTML( + "{start}{bar_a}{bar_b}{bar_c}{end}" + ) def __init__( self, @@ -202,7 +205,7 @@ class Bar(Formatter): bar_b = sym_b bar_c = sym_c * (width - pb_a) - return HTML(self.template).format( + return self.template.format( start=self.start, end=self.end, bar_a=bar_a, bar_b=bar_b, bar_c=bar_c ) @@ -215,7 +218,7 @@ class Progress(Formatter): Display the progress as text. E.g. "8/20" """ - template = "{current:>3}/{total:>3}" + template = HTML("{current:>3}/{total:>3}") def format( self, @@ -223,7 +226,7 @@ class Progress(Formatter): progress: ProgressBarCounter[object], width: int, ) -> AnyFormattedText: - return HTML(self.template).format( + return self.template.format( current=progress.items_completed, total=progress.total or "?" ) @@ -250,6 +253,8 @@ class TimeElapsed(Formatter): Display the elapsed time. """ + template = HTML("{time_elapsed}") + def format( self, progress_bar: ProgressBar, @@ -257,9 +262,7 @@ class TimeElapsed(Formatter): width: int, ) -> AnyFormattedText: text = _format_timedelta(progress.time_elapsed).rjust(width) - return HTML("{time_elapsed}").format( - time_elapsed=text - ) + return self.template.format(time_elapsed=text) def get_width(self, progress_bar: ProgressBar) -> AnyDimension: all_values = [ @@ -275,7 +278,7 @@ class TimeLeft(Formatter): Display the time left. """ - template = "{time_left}" + template = HTML("{time_left}") unknown = "?:??:??" def format( @@ -290,7 +293,7 @@ class TimeLeft(Formatter): else: formatted_time_left = self.unknown - return HTML(self.template).format(time_left=formatted_time_left.rjust(width)) + return self.template.format(time_left=formatted_time_left.rjust(width)) def get_width(self, progress_bar: ProgressBar) -> AnyDimension: all_values = [ @@ -307,7 +310,7 @@ class IterationsPerSecond(Formatter): Display the iterations per second. """ - template = ( + template = HTML( "{iterations_per_second:.2f}" ) @@ -318,7 +321,7 @@ class IterationsPerSecond(Formatter): width: int, ) -> AnyFormattedText: value = progress.items_completed / progress.time_elapsed.total_seconds() - return HTML(self.template.format(iterations_per_second=value)) + return self.template.format(iterations_per_second=value) def get_width(self, progress_bar: ProgressBar) -> AnyDimension: all_values = [ @@ -335,6 +338,7 @@ class SpinningWheel(Formatter): Display a spinning wheel. """ + template = HTML("{0}") characters = r"/-\|" def format( @@ -344,9 +348,7 @@ class SpinningWheel(Formatter): width: int, ) -> AnyFormattedText: index = int(time.time() * 3) % len(self.characters) - return HTML("{0}").format( - self.characters[index] - ) + return self.template.format(self.characters[index]) def get_width(self, progress_bar: ProgressBar) -> AnyDimension: return D.exact(1) diff --git a/src/prompt_toolkit/shortcuts/prompt.py b/src/prompt_toolkit/shortcuts/prompt.py index 7274b5f..115d890 100644 --- a/src/prompt_toolkit/shortcuts/prompt.py +++ b/src/prompt_toolkit/shortcuts/prompt.py @@ -24,6 +24,7 @@ Example:: s = PromptSession() result = s.prompt('Say something: ') """ + from __future__ import annotations from asyncio import get_running_loop diff --git a/src/prompt_toolkit/styles/__init__.py b/src/prompt_toolkit/styles/__init__.py index 23f61bb..39e97ca 100644 --- a/src/prompt_toolkit/styles/__init__.py +++ b/src/prompt_toolkit/styles/__init__.py @@ -1,6 +1,7 @@ """ Styling for prompt_toolkit applications. """ + from __future__ import annotations from .base import ( diff --git a/src/prompt_toolkit/styles/base.py b/src/prompt_toolkit/styles/base.py index b50f3b0..0657221 100644 --- a/src/prompt_toolkit/styles/base.py +++ b/src/prompt_toolkit/styles/base.py @@ -1,6 +1,7 @@ """ The base classes for the styling. """ + from __future__ import annotations from abc import ABCMeta, abstractmethod, abstractproperty diff --git a/src/prompt_toolkit/styles/defaults.py b/src/prompt_toolkit/styles/defaults.py index 75b8dd2..2faba94 100644 --- a/src/prompt_toolkit/styles/defaults.py +++ b/src/prompt_toolkit/styles/defaults.py @@ -1,6 +1,7 @@ """ The default styling. """ + from __future__ import annotations from prompt_toolkit.cache import memoized diff --git a/src/prompt_toolkit/styles/named_colors.py b/src/prompt_toolkit/styles/named_colors.py index 0395c8b..b6290a4 100644 --- a/src/prompt_toolkit/styles/named_colors.py +++ b/src/prompt_toolkit/styles/named_colors.py @@ -2,6 +2,7 @@ All modern web browsers support these 140 color names. Taken from: https://www.w3schools.com/colors/colors_names.asp """ + from __future__ import annotations __all__ = [ diff --git a/src/prompt_toolkit/styles/pygments.py b/src/prompt_toolkit/styles/pygments.py index 3e101f1..c0f6031 100644 --- a/src/prompt_toolkit/styles/pygments.py +++ b/src/prompt_toolkit/styles/pygments.py @@ -6,6 +6,7 @@ Usage:: from pygments.styles.tango import TangoStyle style = style_from_pygments_cls(pygments_style_cls=TangoStyle) """ + from __future__ import annotations from typing import TYPE_CHECKING diff --git a/src/prompt_toolkit/styles/style.py b/src/prompt_toolkit/styles/style.py index 1abee0f..fc8b31b 100644 --- a/src/prompt_toolkit/styles/style.py +++ b/src/prompt_toolkit/styles/style.py @@ -1,6 +1,7 @@ """ Tool for creating styles from a dictionary. """ + from __future__ import annotations import itertools @@ -72,7 +73,7 @@ def parse_color(text: str) -> str: elif text in ("", "default"): return text - raise ValueError("Wrong color format %r" % text) + raise ValueError(f"Wrong color format {text!r}") # Attributes, when they are not filled in by a style. None means that we take diff --git a/src/prompt_toolkit/styles/style_transformation.py b/src/prompt_toolkit/styles/style_transformation.py index fbb5a63..e8d5b0a 100644 --- a/src/prompt_toolkit/styles/style_transformation.py +++ b/src/prompt_toolkit/styles/style_transformation.py @@ -9,6 +9,7 @@ When the UI is rendered, these transformations can be applied right after the style strings are turned into `Attrs` objects that represent the actual formatting. """ + from __future__ import annotations from abc import ABCMeta, abstractmethod diff --git a/src/prompt_toolkit/token.py b/src/prompt_toolkit/token.py index a2c80e5..e97893d 100644 --- a/src/prompt_toolkit/token.py +++ b/src/prompt_toolkit/token.py @@ -1,5 +1,4 @@ -""" -""" +""" """ from __future__ import annotations diff --git a/src/prompt_toolkit/validation.py b/src/prompt_toolkit/validation.py index 127445e..2b35d1f 100644 --- a/src/prompt_toolkit/validation.py +++ b/src/prompt_toolkit/validation.py @@ -2,6 +2,7 @@ Input validation for a `Buffer`. (Validators will be called before accepting input.) """ + from __future__ import annotations from abc import ABCMeta, abstractmethod @@ -36,11 +37,7 @@ class ValidationError(Exception): self.message = message def __repr__(self) -> str: - return "{}(cursor_position={!r}, message={!r})".format( - self.__class__.__name__, - self.cursor_position, - self.message, - ) + return f"{self.__class__.__name__}(cursor_position={self.cursor_position!r}, message={self.message!r})" class Validator(metaclass=ABCMeta): diff --git a/src/prompt_toolkit/widgets/__init__.py b/src/prompt_toolkit/widgets/__init__.py index 9d1d4e3..53cc3e1 100644 --- a/src/prompt_toolkit/widgets/__init__.py +++ b/src/prompt_toolkit/widgets/__init__.py @@ -6,6 +6,7 @@ module. Most of these widgets implement the ``__pt_container__`` method, which makes it possible to embed these in the layout like any other container. """ + from __future__ import annotations from .base import ( diff --git a/src/prompt_toolkit/widgets/base.py b/src/prompt_toolkit/widgets/base.py index f36a545..709b7a9 100644 --- a/src/prompt_toolkit/widgets/base.py +++ b/src/prompt_toolkit/widgets/base.py @@ -12,6 +12,7 @@ container object. guarantees are made yet). The public API in `prompt_toolkit.shortcuts.dialogs` on the other hand is considered stable. """ + from __future__ import annotations from functools import partial diff --git a/src/prompt_toolkit/widgets/dialogs.py b/src/prompt_toolkit/widgets/dialogs.py index c47c15b..5f5f170 100644 --- a/src/prompt_toolkit/widgets/dialogs.py +++ b/src/prompt_toolkit/widgets/dialogs.py @@ -1,6 +1,7 @@ """ Collection of reusable components for building full screen applications. """ + from __future__ import annotations from typing import Sequence diff --git a/src/prompt_toolkit/widgets/toolbars.py b/src/prompt_toolkit/widgets/toolbars.py index deddf15..c5deffc 100644 --- a/src/prompt_toolkit/widgets/toolbars.py +++ b/src/prompt_toolkit/widgets/toolbars.py @@ -352,11 +352,7 @@ class ValidationToolbar: ) if show_position: - text = "{} (line={} column={})".format( - buff.validation_error.message, - row + 1, - column + 1, - ) + text = f"{buff.validation_error.message} (line={row + 1} column={column + 1})" else: text = buff.validation_error.message -- cgit v1.2.3