Skip to content

Commit 763b146

Browse files
5h4d0wn1kcclauss
andauthored
feat(sorts): make reversort generic over comparable items (#15402)
* feat(sorts): make reversort generic over comparable items Part of #15234 - Replace list[Any] with a Comparable-bounded TypeVar so reversort and reversort_cost sort any mutually comparable items, not just ints - Add TypeError doctests confirming mixed non-comparable input raises - Register reversort in the shared test battery covering str/float/ dataclass/NamedTuple cases and the non-comparable rejection path * style(sorts): use PEP 695 type parameters per repo convention ruff UP047 requires the sanctioned [T: Comparable] signature form used by the reference insertion_sort.py. Keep the module-level TypeVar as in the reference. * Apply batched suggestions from code review Co-authored-by: Christian Clauss <cclauss@me.com> --------- Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent 6a2ca68 commit 763b146

2 files changed

Lines changed: 18 additions & 3 deletions

File tree

‎sorts/reversort.py‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717
python reversort.py
1818
"""
1919

20-
from typing import Any
20+
from typing import Any, Protocol
2121

2222

23-
def reversort(collection: list[Any]) -> list[Any]:
23+
class Comparable(Protocol):
24+
def __lt__(self, other: Any, /) -> bool: ...
25+
26+
27+
def reversort[T: Comparable](collection: list[T]) -> list[T]:
2428
"""
2529
Sort a list using the Reversort algorithm.
2630
@@ -78,6 +82,10 @@ def reversort(collection: list[Any]) -> list[Any]:
7882
>>> collection_arg = random.choices(string.ascii_letters + string.digits, k=100)
7983
>>> reversort(collection_arg) == sorted(collection_arg)
8084
True
85+
>>> reversort([1, "a"]) # doctest: +IGNORE_EXCEPTION_DETAIL
86+
Traceback (most recent call last):
87+
...
88+
TypeError: '<' not supported between instances of 'str' and 'int'
8189
"""
8290
arr = collection[:] # Create a copy to avoid modifying the original
8391
n = len(arr)
@@ -96,7 +104,7 @@ def reversort(collection: list[Any]) -> list[Any]:
96104
return arr
97105

98106

99-
def reversort_cost(collection: list[Any]) -> int:
107+
def reversort_cost[T: Comparable](collection: list[T]) -> int:
100108
"""
101109
Calculate the cost of sorting using Reversort.
102110
@@ -119,6 +127,10 @@ def reversort_cost(collection: list[Any]) -> int:
119127
0
120128
>>> reversort_cost([])
121129
0
130+
>>> reversort_cost([1, "a"]) # doctest: +IGNORE_EXCEPTION_DETAIL
131+
Traceback (most recent call last):
132+
...
133+
TypeError: '<' not supported between instances of 'str' and 'int'
122134
"""
123135
arr = collection[:] # Create a copy to avoid modifying the original
124136
n = len(arr)

‎tests/test_sorts.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from sorts.patience_sort import patience_sort
4242
from sorts.quick_sort import quick_sort
4343
from sorts.recursive_insertion_sort import rec_insertion_sort
44+
from sorts.reversort import reversort
4445
from sorts.selection_sort import selection_sort
4546
from sorts.shell_sort import shell_sort
4647
from sorts.shrink_shell_sort import shell_sort as shrink_shell_sort
@@ -74,6 +75,7 @@ def test_heap_sort() -> None:
7475
pancake_sort,
7576
patience_sort,
7677
quick_sort,
78+
reversort,
7779
selection_sort,
7880
shell_sort,
7981
shrink_shell_sort,
@@ -141,6 +143,7 @@ def test_rec_insertion_sort(case) -> None:
141143
merge_sort,
142144
odd_even_sort,
143145
pancake_sort,
146+
reversort,
144147
selection_sort,
145148
shrink_shell_sort,
146149
strand_sort,

0 commit comments

Comments
 (0)