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 --- .../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 +++-- 10 files changed, 35 insertions(+), 24 deletions(-) (limited to 'src/prompt_toolkit/contrib') 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() -- cgit v1.2.3