Skip to content

types(intro_sort): constrain items to Comparable - #15412

Closed
AuroraAeon wants to merge 1 commit into
TheAlgorithms:masterfrom
AuroraAeon:types/intro-sort-comparable
Closed

AuroraAeon wants to merge 1 commit into
TheAlgorithms:masterfrom
AuroraAeon:types/intro-sort-comparable

Conversation

@AuroraAeon

Copy link
Copy Markdown

Part of #15234

What

sorts/intro_sort.py — bind every function to a Comparable Protocol so the signatures state "a list of items that can be compared with each other" instead of a bare list, and keep the element type in the return:

def sort[T: Comparable](array: list[T]) -> list[T]:

Two of the hints were outright wrong rather than merely loose:

  • median_of_3 was annotated -> int but returns an element of the collection — now -> T
  • partition was annotated pivot: int but takes an element of the collection — now pivot: T

Both were only reachable with the wrong type through untyped callers, so this is a real fix rather than cosmetics.

Tests

intro_sort had no test at all before this PR.

Doctests added for a comparable non-int type (strings) and for the failure mode on insertion_sort, heap_sort, median_of_3, partition and sort: mixing non-comparable items must raise TypeError rather than silently mis-sort.

tests/test_sorts.py:

  • sort added to the shared SORTS battery (all 11 cases, including the Person and Dog dataclass cases)
  • sort added to test_sort_rejects_non_comparable_items
  • new test_intro_sort_comparable_items reaching the branches the battery cannot

That last one matters: every case in the shared CASES battery is shorter than the 16-element size_threshold, so the battery alone only ever exercises insertion_sort. The new test sorts 17/32/100/500-element int and str inputs to take the quicksort branch, and drives intro_sort with a depth budget of 0 to take the heapsort branch. The RNG is seeded (random.Random(20260923)) so the test is deterministic, and nothing depends on the current date, the machine locale, or test execution order.

Run with:

python -m pytest tests/test_sorts.py sorts/intro_sort.py -q

328 passed. ruff check and ruff format --check are clean, and the wider sorts/ tier is unaffected (90 passed).

Notes

No behaviour change — the algorithm bodies are untouched; only annotations, doctests and the module docstring were added. (median_of_3/partition now report the element type they already used.)

Bind every function in sorts/intro_sort.py to a Comparable Protocol so the
signatures say "a list of items that can be compared with each other"
instead of a bare list, and keep the element type in the return.

Two of the hints were outright wrong rather than merely loose:

- median_of_3 returned int but returns an element of the collection, so it
  is now T
- partition took pivot: int but takes an element of the collection, so it is
  now T

Both were only reachable with the wrong type through untyped callers.

Doctests added for a comparable non-int type (strings) and for the failure
mode on insertion_sort, heap_sort, median_of_3, partition and sort: mixing
non-comparable items must raise TypeError rather than silently mis-sort.

intro_sort had no test at all. tests/test_sorts.py now adds it to the shared
battery and to the rejection check, plus a dedicated test that reaches the
branches the battery cannot: every shared case is shorter than the
16-element threshold, so the battery only ever exercises insertion_sort.
The new test sorts 17/32/100/500-element int and str inputs to take the
quicksort branch, and drives intro_sort with a depth budget of 0 to take the
heapsort branch. The RNG is seeded so the test is deterministic.
Copilot AI lite review requested due to automatic review settings September 23, 2026 09:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@AuroraAeon

Copy link
Copy Markdown
Author

Closing this one myself to keep the review load down: @Felix-ming's #15403 covers sorts/intro_sort.py with the same Comparable / TypeVar pattern plus a dedicated tests/test_intro_sort.py, and it was opened before mine.

Nothing wrong with the change here — it is just redundant. #15403 is the one to review and merge. Thanks for picking this up, Felix.

@AuroraAeon AuroraAeon closed this Sep 23, 2026
@AuroraAeon
AuroraAeon deleted the types/intro-sort-comparable branch September 23, 2026 11:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants