Skip to content

Support tuple items in map#17

Closed
jolovicdev wants to merge 1 commit into
masterfrom
test/map-task-options
Closed

Support tuple items in map#17
jolovicdev wants to merge 1 commit into
masterfrom
test/map-task-options

Conversation

@jolovicdev
Copy link
Copy Markdown
Owner

Summary

  • Move map() task construction into the shared batch helper
  • Allow tuple items passed to map() to be used as positional arguments
  • Add sync and async coverage for tuple-item map calls

Testing

  • uv run ruff check src/ tests/
  • uv run pyright src/
  • uv run pytest tests/ -v

Copy link
Copy Markdown

@ds-review ds-review Bot left a comment

Choose a reason for hiding this comment

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

PR Review

PR: Support tuple items in map

Important

Verdict: Request changes - 6 actionable findings, highest severity P1.

Findings (6)

P1 High Breaking change: tuple items now unpacked automatically

src/cashet/_batch.py:85

The new logic in build_map_tasks unpacks any tuple item with *item, treating each element as a separate positional argument. This silently breaks callers who previously used map with tuple items that were meant to be passed as a single argument. The old behavior treated item as a single argument regardless of type. Consider documenting this as a breaking change or adding a parameter to control unpacking.

P1 High Namedtuple items incorrectly unpacked

src/cashet/_batch.py:85

Namedtuples are instances of tuple, so isinstance(item, tuple) is True. Passing a list of namedtuples will unpack each field as separate arguments, which is probably not the intended behavior. Users might expect namedtuples to be treated as single items. Either document this as intentional or change the check to isinstance(item, tuple) and not namedtuple.

P2 Medium Empty tuple items lead to missing arguments

src/cashet/_batch.py:85

If an empty tuple () is passed as an item, *item expands to nothing, so the resulting task will have only the extra *args and kwargs, likely causing TypeError for functions that require at least one positional argument. The previous behavior passed the empty tuple as a single argument. This edge case may cause unexpected errors.

P3 Low build_map_tasks lacks docstring

src/cashet/_batch.py:78

The function should include a docstring explaining its behavior, especially the tuple unpacking logic, to help maintainability.

P3 Low Imprecise return type in build_map_tasks

src/cashet/_batch.py:83

The return type is list[Any], which loses information. Consider using list[tuple[Callable[..., Any], tuple[Any, ...], dict[str, Any]]] for better type safety.

P3 Low Missing edge case tests for tuple unpacking

tests/test_map.py:46

The new test only covers a tuple of two elements. Consider adding tests for empty tuple, single-element tuple, and mixed non-tuple/tuple items to ensure correctness.

How To Recheck

Reply @ds-review recheck under the relevant inline finding after pushing a fix.

Comment thread src/cashet/_batch.py
kwargs: dict[str, Any],
) -> list[Any]:
return [
(func, (*item, *args) if isinstance(item, tuple) else (item, *args), kwargs)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 High Breaking change: tuple items now unpacked automatically

The new logic in build_map_tasks unpacks any tuple item with *item, treating each element as a separate positional argument. This silently breaks callers who previously used map with tuple items that were meant to be passed as a single argument. The old behavior treated item as a single argument regardless of type. Consider documenting this as a breaking change or adding a parameter to control unpacking.

Comment thread src/cashet/_batch.py
kwargs: dict[str, Any],
) -> list[Any]:
return [
(func, (*item, *args) if isinstance(item, tuple) else (item, *args), kwargs)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 High Namedtuple items incorrectly unpacked

Namedtuples are instances of tuple, so isinstance(item, tuple) is True. Passing a list of namedtuples will unpack each field as separate arguments, which is probably not the intended behavior. Users might expect namedtuples to be treated as single items. Either document this as intentional or change the check to isinstance(item, tuple) and not namedtuple.

Comment thread src/cashet/_batch.py
kwargs: dict[str, Any],
) -> list[Any]:
return [
(func, (*item, *args) if isinstance(item, tuple) else (item, *args), kwargs)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Medium Empty tuple items lead to missing arguments

If an empty tuple () is passed as an item, *item expands to nothing, so the resulting task will have only the extra *args and kwargs, likely causing TypeError for functions that require at least one positional argument. The previous behavior passed the empty tuple as a single argument. This edge case may cause unexpected errors.

Comment thread src/cashet/_batch.py
return normalized


def build_map_tasks(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3 Low build_map_tasks lacks docstring

The function should include a docstring explaining its behavior, especially the tuple unpacking logic, to help maintainability.

Comment thread src/cashet/_batch.py
items: Iterable[Any],
args: tuple[Any, ...],
kwargs: dict[str, Any],
) -> list[Any]:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3 Low Imprecise return type in build_map_tasks

The return type is list[Any], which loses information. Consider using list[tuple[Callable[..., Any], tuple[Any, ...], dict[str, Any]]] for better type safety.

Suggested change
) -> list[Any]:
) -> list[tuple[Callable[..., Any], tuple[Any, ...], dict[str, Any]]]:

Comment thread tests/test_map.py
assert [r.load() for r in refs] == [11, 12, 13]

def test_map_with_tuple_items(self, client: Client) -> None:
refs = client.map(add_pair, [(1, 2), (3, 4)])
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3 Low Missing edge case tests for tuple unpacking

The new test only covers a tuple of two elements. Consider adding tests for empty tuple, single-element tuple, and mixed non-tuple/tuple items to ensure correctness.

@jolovicdev jolovicdev closed this May 8, 2026
@jolovicdev jolovicdev deleted the test/map-task-options branch May 10, 2026 23:26
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.

1 participant