From c867e49cef443f2e70cf620b7586dca1eb9804fc Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 1 Oct 2026 08:52:25 +0000 Subject: [PATCH 1/3] typing: bind recursive insertion sort to Comparable protocol - insert_next was missing its TypeVar bound (Pyright: '<' operator invalid on T) - Protocol __lt__ takes object, not Any; order check now relies on __lt__ only - doctests: floats+ints mix, mixed [1, 'a'] raises TypeError Part of #15234 --- sorts/recursive_insertion_sort.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/sorts/recursive_insertion_sort.py b/sorts/recursive_insertion_sort.py index 30630ce84694..15bb702790e1 100644 --- a/sorts/recursive_insertion_sort.py +++ b/sorts/recursive_insertion_sort.py @@ -5,17 +5,17 @@ from __future__ import annotations from collections.abc import MutableSequence -from typing import Any, Protocol, TypeVar +from typing import Protocol, TypeVar class Comparable(Protocol): - def __lt__(self, other: Any, /) -> bool: ... + def __lt__(self, other: object, /) -> bool: ... T = TypeVar("T", bound=Comparable) -def rec_insertion_sort[T](collection: MutableSequence[T], n: int) -> None: +def rec_insertion_sort[T: Comparable](collection: MutableSequence[T], n: int) -> None: """ Given a collection of comparable elements and its length, sorts the collection in place in ascending order. @@ -42,6 +42,17 @@ def rec_insertion_sort[T](collection: MutableSequence[T], n: int) -> None: >>> rec_insertion_sort(col, len(col)) >>> col ['a', 'b', 'c', 'd', 'e'] + + >>> col = [2.5, -1, 0.0, 1] + >>> rec_insertion_sort(col, len(col)) + >>> col + [-1, 0.0, 1, 2.5] + + >>> col = [1, "a"] + >>> rec_insertion_sort(col, len(col)) + Traceback (most recent call last): + ... + TypeError: '<' not supported between instances of 'str' and 'int' """ # Checks if the entire collection has been sorted if len(collection) <= 1 or n <= 1: @@ -51,7 +62,7 @@ def rec_insertion_sort[T](collection: MutableSequence[T], n: int) -> None: rec_insertion_sort(collection, n - 1) -def insert_next[T](collection: MutableSequence[T], index: int) -> None: +def insert_next[T: Comparable](collection: MutableSequence[T], index: int) -> None: """ Inserts the '(index-1)th' element into place @@ -71,7 +82,8 @@ def insert_next[T](collection: MutableSequence[T], index: int) -> None: [] """ # Checks order between adjacent elements - if index >= len(collection) or collection[index - 1] <= collection[index]: + # Only relies on ``__lt__`` so any Comparable works + if index >= len(collection) or not collection[index] < collection[index - 1]: return # Swaps adjacent elements since they are not in ascending order From c83121d907508aae2fed20332ca5da3a7b880339 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2026 08:53:20 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- ciphers/des_ecb.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/ciphers/des_ecb.py b/ciphers/des_ecb.py index 4c904294a2d4..5a8a289adbe6 100644 --- a/ciphers/des_ecb.py +++ b/ciphers/des_ecb.py @@ -537,21 +537,22 @@ def decrypt(key: str, cipher_text: str) -> str: if mode not in ["e", "d", "k", "q"]: print("Invalid option. Please try again.") continue - if mode == "q": - break - elif mode == "k": - print(f"Generated key: {Des.generate_key()}") - elif mode == "e": - key = input("Enter the key: ").strip() - if len(key) != 16 and not all(char in "0123456789abcdef" for char in key): - print("Invalid key. Please try again.") - continue - input_string = input("Enter the string to encrypt: ").strip() - print(f"Encrypted string: {Des.encrypt(key, input_string)}") - elif mode == "d": - key = input("Enter the key: ").strip() - if len(key) != 16 and not all(char in "0123456789abcdef" for char in key): - print("Invalid key. Please try again.") - continue - cipher_text = input("Enter the cipher text to decrypt: ").strip() - print(f"Decrypted string: {Des.decrypt(key, cipher_text)}") + match mode: + case "q": + break + case "k": + print(f"Generated key: {Des.generate_key()}") + case "e": + key = input("Enter the key: ").strip() + if len(key) != 16 and not all(char in "0123456789abcdef" for char in key): + print("Invalid key. Please try again.") + continue + input_string = input("Enter the string to encrypt: ").strip() + print(f"Encrypted string: {Des.encrypt(key, input_string)}") + case "d": + key = input("Enter the key: ").strip() + if len(key) != 16 and not all(char in "0123456789abcdef" for char in key): + print("Invalid key. Please try again.") + continue + cipher_text = input("Enter the cipher text to decrypt: ").strip() + print(f"Decrypted string: {Des.decrypt(key, cipher_text)}") From 69600e9cf8d8e66c6d8a06f89ddc4b163db1492d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2026 14:55:57 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- ciphers/des_ecb.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ciphers/des_ecb.py b/ciphers/des_ecb.py index 5a8a289adbe6..559aee9b764a 100644 --- a/ciphers/des_ecb.py +++ b/ciphers/des_ecb.py @@ -544,14 +544,18 @@ def decrypt(key: str, cipher_text: str) -> str: print(f"Generated key: {Des.generate_key()}") case "e": key = input("Enter the key: ").strip() - if len(key) != 16 and not all(char in "0123456789abcdef" for char in key): + if len(key) != 16 and not all( + char in "0123456789abcdef" for char in key + ): print("Invalid key. Please try again.") continue input_string = input("Enter the string to encrypt: ").strip() print(f"Encrypted string: {Des.encrypt(key, input_string)}") case "d": key = input("Enter the key: ").strip() - if len(key) != 16 and not all(char in "0123456789abcdef" for char in key): + if len(key) != 16 and not all( + char in "0123456789abcdef" for char in key + ): print("Invalid key. Please try again.") continue cipher_text = input("Enter the cipher text to decrypt: ").strip()