Skip to content

Commit c867e49

Browse files
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
1 parent 157c73d commit c867e49

1 file changed

Lines changed: 17 additions & 5 deletions

File tree

‎sorts/recursive_insertion_sort.py‎

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
from __future__ import annotations
66

77
from collections.abc import MutableSequence
8-
from typing import Any, Protocol, TypeVar
8+
from typing import Protocol, TypeVar
99

1010

1111
class Comparable(Protocol):
12-
def __lt__(self, other: Any, /) -> bool: ...
12+
def __lt__(self, other: object, /) -> bool: ...
1313

1414

1515
T = TypeVar("T", bound=Comparable)
1616

1717

18-
def rec_insertion_sort[T](collection: MutableSequence[T], n: int) -> None:
18+
def rec_insertion_sort[T: Comparable](collection: MutableSequence[T], n: int) -> None:
1919
"""
2020
Given a collection of comparable elements and its length, sorts the
2121
collection in place in ascending order.
@@ -42,6 +42,17 @@ def rec_insertion_sort[T](collection: MutableSequence[T], n: int) -> None:
4242
>>> rec_insertion_sort(col, len(col))
4343
>>> col
4444
['a', 'b', 'c', 'd', 'e']
45+
46+
>>> col = [2.5, -1, 0.0, 1]
47+
>>> rec_insertion_sort(col, len(col))
48+
>>> col
49+
[-1, 0.0, 1, 2.5]
50+
51+
>>> col = [1, "a"]
52+
>>> rec_insertion_sort(col, len(col))
53+
Traceback (most recent call last):
54+
...
55+
TypeError: '<' not supported between instances of 'str' and 'int'
4556
"""
4657
# Checks if the entire collection has been sorted
4758
if len(collection) <= 1 or n <= 1:
@@ -51,7 +62,7 @@ def rec_insertion_sort[T](collection: MutableSequence[T], n: int) -> None:
5162
rec_insertion_sort(collection, n - 1)
5263

5364

54-
def insert_next[T](collection: MutableSequence[T], index: int) -> None:
65+
def insert_next[T: Comparable](collection: MutableSequence[T], index: int) -> None:
5566
"""
5667
Inserts the '(index-1)th' element into place
5768
@@ -71,7 +82,8 @@ def insert_next[T](collection: MutableSequence[T], index: int) -> None:
7182
[]
7283
"""
7384
# Checks order between adjacent elements
74-
if index >= len(collection) or collection[index - 1] <= collection[index]:
85+
# Only relies on ``__lt__`` so any Comparable works
86+
if index >= len(collection) or not collection[index] < collection[index - 1]:
7587
return
7688

7789
# Swaps adjacent elements since they are not in ascending order

0 commit comments

Comments
 (0)