Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Partition #1905 #1908

Merged
merged 28 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
bad0590
add annotation
romanmatveevsky Jul 30, 2024
8e4aedb
changelog
romanmatveevsky Jul 30, 2024
268e69e
Update CHANGELOG.md
sobolevn Jul 30, 2024
4a881e3
Merge branch 'dry-python:master' into master
RomanMIzulin Aug 8, 2024
fb9c208
wip
Aug 8, 2024
966e8f4
upd CHANGELOG
Aug 8, 2024
c27144f
pr upds
Aug 8, 2024
6c7e210
upd
Aug 8, 2024
6c3de2f
fix type test... maybe
Aug 8, 2024
5f15d05
fixes
Aug 9, 2024
77f7a33
what will typesafety tell us?
Aug 9, 2024
b7a8f56
missing file
Aug 9, 2024
6a145ea
Update typesafety/test_result/test_partition.yml
RomanMIzulin Aug 12, 2024
6a5aa90
Update typesafety/test_result/test_partition.yml
RomanMIzulin Aug 12, 2024
d8369b8
mr issues
romanmatveevsky Aug 12, 2024
f1839c3
fixes
romanmatveevsky Aug 12, 2024
afe493f
fixes
romanmatveevsky Aug 12, 2024
7a2a8fc
broke brains because of typesafety
romanmatveevsky Aug 12, 2024
7b37a0f
seems like that
romanmatveevsky Aug 12, 2024
dd94a17
idk what wrong with Nothing type
romanmatveevsky Aug 13, 2024
85b98e0
change types and fix test
romanmatveevsky Aug 14, 2024
dd74a4e
fix ci
romanmatveevsky Aug 14, 2024
9b2e02b
Update returns/methods/partition.py
RomanMIzulin Aug 14, 2024
777cd5b
Update tests/test_result/test_result_methods.py
RomanMIzulin Aug 14, 2024
8f05776
Update tests/test_result/test_result_methods.py
RomanMIzulin Aug 14, 2024
dcebdf5
new days new fixes
romanmatveevsky Aug 15, 2024
0b64a3f
Merge branch 'master' into partition
RomanMIzulin Aug 15, 2024
edf92e1
Apply suggestions from code review
sobolevn Aug 15, 2024
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ See [0Ver](https://0ver.org/).
- Improve inference of `ResultLike` objects when exception catching
decorator is applied with explicit exception types
- Add picky exceptions to `impure_safe` decorator like `safe` has. Issue #1543
- Add partition function to result module. Issue #1905
- Adds `default_error` parameter to `returns.converters.maybe_to_result`,
which provides a default error value for `Failure`


### Misc

- Now requires `mypy>=1.11`
Expand Down
16 changes: 16 additions & 0 deletions docs/pages/methods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@ Here's a full example:
>>> error_handled = pointfree.bimap(lambda inr: inr + 1, lambda _: 0)(instance)
>>> assert isinstance(methods.unwrap_or_failure(error_handled), int)

partition
~~~~~~~~~

:func:`partition <returns.result.partition>` is used to convert
list of :class:`~returns.interfaces.Unwrappable`
instances like :class:`~returns.result.Result`,
:class:`~returns.io.IOResult`, and :class:`~returns.maybe.Maybe`
to a tuple of two lists: successes and failures.

.. code:: python

>>> from returns.result import Failure, Success
>>> from returns.methods import partition
>>> results = [Success(1), Failure(2), Success(3), Failure(4)]
>>> partition(results)
([1, 3], [2, 4])

API Reference
-------------
Expand Down
1 change: 1 addition & 0 deletions returns/methods/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from returns.methods.cond import cond as cond
from returns.methods.partition import partition as partition
from returns.methods.unwrap_or_failure import (
unwrap_or_failure as unwrap_or_failure,
)
38 changes: 38 additions & 0 deletions returns/methods/partition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

from typing import Iterable, List, TypeVar

from returns.interfaces.unwrappable import Unwrappable
from returns.primitives.exceptions import UnwrapFailedError

_ValueType = TypeVar('_ValueType', covariant=True)
_ErrorType = TypeVar('_ErrorType', covariant=True)


def partition(
containers: Iterable[
Unwrappable[_ValueType, _ErrorType],
],
) -> tuple[List[_ValueType], List[_ErrorType]]:
"""
Partition a list of unwrappables into successful and failed values.

Preserves order.

.. code:: python

>>> from returns.result import Failure, Success
>>> from returns.methods import partition

>>> results = [Success(1), Failure(2), Success(3), Failure(4)]
>>> partition(results)
([1, 3], [2, 4])

"""
successes: list[_ValueType] = []
failures: list[_ErrorType] = []
for container in containers:
try:
successes.append(container.unwrap())
except UnwrapFailedError:
failures.append(container.failure())
return successes, failures
32 changes: 32 additions & 0 deletions tests/test_methods/test_partition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

import pytest

from returns.io import IO, IOResult
from returns.maybe import Nothing, Some
from returns.methods import partition
from returns.result import Failure, Success


@pytest.mark.parametrize(('containers', 'expected'), [
(
(Success(1), Success(2), Failure(None), Success(3)),
([1, 2, 3], [None]),
),
(
(
IOResult.from_value(1),
IOResult.from_failure(2),
IOResult.from_value(3),
IOResult.from_failure(4),
),
([IO(1), IO(3)], [IO(2), IO(4)]),
),
(
(Some(1), Some(2), Nothing),
([1, 2], [None]),
),
((), ([], [])),
])
def test_partition(containers, expected):
"""Test partition function."""
assert partition(containers) == expected
32 changes: 32 additions & 0 deletions typesafety/test_methods/test_partition.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
- case: partition_result
disable_cache: false
main: |
from typing import List
from returns.result import Success, Failure, Result
from returns.methods import partition

x: List[Result[int, str]]
reveal_type(partition(x)) # N: Revealed type is "Tuple[builtins.list[builtins.int], builtins.list[builtins.str]]"

- case: partition_io_results
disable_cache: false
main: |
from typing import Tuple
from returns.result import Success, Failure
from returns.methods import partition
from returns.io import IO, IOResult, IOSuccess

x: Tuple[IOResult[int, str], IOResult[int, str]]
reveal_type(partition(x)) # N: Revealed type is "Tuple[builtins.list[returns.io.IO[builtins.int]], builtins.list[returns.io.IO[builtins.str]]]"

- case: partition_maybe
disable_cache: false
main: |
from typing import List, Tuple
from returns.maybe import Maybe
from returns.methods import partition

x: List[Maybe[int]]

sobolevn marked this conversation as resolved.
Show resolved Hide resolved
reveal_type(partition(x)) # N: Revealed type is "Tuple[builtins.list[builtins.int], builtins.list[None]]"