Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions asyncstdlib/builtins.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,14 +312,14 @@ async def _min_max(
raise ValueError(f"{name}() arg is an empty sequence")
elif key is None:
async for item in item_iter:
if invert ^ bool(item < best):
if best < item if invert else item < best:
best = item
else:
key = _awaitify(key)
best_key = await key(best)
async for item in item_iter:
item_key = await key(item)
if invert ^ (item_key < best_key):
if best_key < item_key if invert else item_key < best_key:
best = item
best_key = item_key
return best
Expand Down
45 changes: 45 additions & 0 deletions unittests/test_builtins.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import random
from functools import total_ordering
from typing import Any, Callable, Coroutine, TypeVar

import pytest
Expand Down Expand Up @@ -343,3 +344,47 @@ def collision_key(x: int) -> int:
assert await a.sorted(values, key=awaitify(collision_key)) == sorted(
values, key=collision_key
)


@total_ordering
class ComparableRecord:
def __init__(self, priority):
self.priority = priority

def __eq__(self, other):
if not isinstance(other, ComparableRecord):
return NotImplemented
return self.priority == other.priority

def __lt__(self, other):
if not isinstance(other, ComparableRecord):
return NotImplemented
return self.priority < other.priority


def record_priority(record):
return record.priority


@pytest.mark.parametrize(
"key, reference_key",
[
(None, None),
(record_priority, record_priority),
(awaitify(record_priority), record_priority),
],
)
@pytest.mark.parametrize("iterable", [iter, asyncify])
@sync
async def test_max_keeps_first_equal_item(key, reference_key, iterable):
values = [ComparableRecord(value) for value in (1, 3, 3, 2)]
assert await a.max(iterable(values), key=key) is max(values, key=reference_key)


@pytest.mark.parametrize(
"values",
[[float("nan"), 3.0], [3.0, float("nan"), 2.0], [2.0, float("nan"), 3.0]],
)
@sync
async def test_max_does_not_replace_with_unordered_values(values):
assert await a.max(asyncify(values)) is max(values)